Coverage Report

Created: 2026-10-16 06:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl/src/x509.c
Line
Count
Source
1
/* x509.c
2
 *
3
 * Copyright (C) 2006-2026 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
23
24
#if !defined(WOLFSSL_X509_INCLUDED)
25
    #ifndef WOLFSSL_IGNORE_FILE_WARN
26
        #warning x509.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
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
35
    #include <wolfssl/openssl/x509v3.h>
36
#endif
37
#ifdef OPENSSL_EXTRA
38
    #include <wolfssl/wolfio.h>
39
#endif
40
41
/* 16 times MAX_X509_SIZE should be more than enough to read any X509
42
 * certificate file */
43
#define MAX_BIO_READ_BUFFER (MAX_X509_SIZE * 16)
44
45
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
46
unsigned int wolfSSL_X509_get_extension_flags(WOLFSSL_X509* x509)
47
{
48
    unsigned int flags = 0;
49
50
    WOLFSSL_ENTER("wolfSSL_X509_get_extension_flags");
51
52
    if (x509 != NULL) {
53
        if (x509->keyUsageSet) {
54
            flags |= WOLFSSL_EXFLAG_KUSAGE;
55
        }
56
        if (x509->extKeyUsageSrc != NULL) {
57
            flags |= WOLFSSL_EXFLAG_XKUSAGE;
58
        }
59
    }
60
61
    WOLFSSL_LEAVE("wolfSSL_X509_get_extension_flags", flags);
62
63
    return flags;
64
}
65
66
unsigned int wolfSSL_X509_get_key_usage(WOLFSSL_X509* x509)
67
{
68
    unsigned int ret = 0;
69
70
    WOLFSSL_ENTER("wolfSSL_X509_get_key_usage");
71
72
    if (x509 == NULL) {
73
        WOLFSSL_MSG("x509 is NULL");
74
    }
75
    else {
76
        if (x509->keyUsageSet) {
77
            ret = wolfSSL_X509_get_keyUsage(x509);
78
        }
79
        else {
80
            ret = (unsigned int)-1;
81
        }
82
    }
83
84
    WOLFSSL_LEAVE("wolfSSL_X509_get_key_usage", ret);
85
86
    return ret;
87
}
88
89
unsigned int wolfSSL_X509_get_extended_key_usage(WOLFSSL_X509* x509)
90
{
91
    int ret = 0;
92
93
    WOLFSSL_ENTER("wolfSSL_X509_get_extended_key_usage");
94
95
    if (x509 != NULL) {
96
        if (x509->extKeyUsage & EXTKEYUSE_OCSP_SIGN)
97
            ret |= WOLFSSL_XKU_OCSP_SIGN;
98
        if (x509->extKeyUsage & EXTKEYUSE_TIMESTAMP)
99
            ret |= WOLFSSL_XKU_TIMESTAMP;
100
        if (x509->extKeyUsage & EXTKEYUSE_EMAILPROT)
101
            ret |= WOLFSSL_XKU_SMIME;
102
        if (x509->extKeyUsage & EXTKEYUSE_CODESIGN)
103
            ret |= WOLFSSL_XKU_CODE_SIGN;
104
        if (x509->extKeyUsage & EXTKEYUSE_CLIENT_AUTH)
105
            ret |= WOLFSSL_XKU_SSL_CLIENT;
106
        if (x509->extKeyUsage & EXTKEYUSE_SERVER_AUTH)
107
            ret |= WOLFSSL_XKU_SSL_SERVER;
108
        if (x509->extKeyUsage & EXTKEYUSE_ANY)
109
            ret |= WOLFSSL_XKU_ANYEKU;
110
    }
111
112
    WOLFSSL_LEAVE("wolfSSL_X509_get_extended_key_usage", ret);
113
114
    return (unsigned int)ret;
115
}
116
117
/* Returns the number of X509V3 extensions in X509 object, or 0 on failure */
118
int wolfSSL_X509_get_ext_count(const WOLFSSL_X509* passedCert)
119
{
120
    int extCount = 0;
121
    int length = 0;
122
    int outSz = 0;
123
    const byte* rawCert;
124
    int sz = 0;
125
    word32 idx = 0;
126
    const byte* input;
127
    WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
128
129
    WOLFSSL_ENTER("wolfSSL_X509_get_ext_count");
130
    if (passedCert == NULL) {
131
        WOLFSSL_MSG("\tNot passed a certificate");
132
        return WOLFSSL_FAILURE;
133
    }
134
135
    rawCert = wolfSSL_X509_get_der((WOLFSSL_X509*)passedCert, &outSz);
136
    if (rawCert == NULL) {
137
        WOLFSSL_MSG("\tpassedCert has no internal DerBuffer set.");
138
        return WOLFSSL_FAILURE;
139
    }
140
141
#ifdef WOLFSSL_SMALL_STACK
142
    cert = (DecodedCert *)XMALLOC(sizeof(*cert), NULL, DYNAMIC_TYPE_DCERT);
143
    if (cert == NULL) {
144
        WOLFSSL_MSG("out of memory");
145
        return WOLFSSL_FAILURE;
146
    }
147
#endif
148
149
    InitDecodedCert(cert, rawCert, (word32)outSz, 0);
150
151
    if (ParseCert(cert,
152
#ifdef WOLFSSL_CERT_REQ
153
            passedCert->isCSR ? CERTREQ_TYPE :
154
#endif
155
                    CA_TYPE,
156
            NO_VERIFY, NULL) < 0) {
157
        WOLFSSL_MSG("\tCertificate parsing failed");
158
        goto out;
159
    }
160
161
    input = cert->extensions;
162
    sz = cert->extensionsSz;
163
164
    if (input == NULL || sz == 0) {
165
        WOLFSSL_MSG("\tsz or input NULL error");
166
        goto out;
167
    }
168
169
#ifdef WOLFSSL_CERT_REQ
170
    if (!passedCert->isCSR)
171
#endif
172
    {
173
        if (input[idx++] != ASN_EXTENSIONS) {
174
            WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
175
            goto out;
176
        }
177
178
        if (GetLength(input, &idx, &length, (word32)sz) < 0) {
179
            WOLFSSL_MSG("\tfail: invalid length");
180
            goto out;
181
        }
182
    }
183
184
    if (GetSequence(input, &idx, &length, (word32)sz) < 0) {
185
        WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
186
        goto out;
187
    }
188
189
    while (idx < (word32)sz) {
190
        if (GetSequence(input, &idx, &length, (word32)sz) < 0) {
191
            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
192
            FreeDecodedCert(cert);
193
            return WOLFSSL_FAILURE;
194
        }
195
        idx += length;
196
        extCount++;
197
    }
198
199
out:
200
201
    FreeDecodedCert(cert);
202
    WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
203
    return extCount;
204
}
205
206
/* Creates and returns pointer to a new X509_EXTENSION object in memory */
207
WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_new(void)
208
{
209
    WOLFSSL_X509_EXTENSION* newExt;
210
211
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_new");
212
213
    newExt = (WOLFSSL_X509_EXTENSION*)XMALLOC(sizeof(WOLFSSL_X509_EXTENSION),
214
              NULL, DYNAMIC_TYPE_X509_EXT);
215
    if (newExt == NULL)
216
        return NULL;
217
    XMEMSET(newExt, 0, sizeof(WOLFSSL_X509_EXTENSION));
218
219
    return newExt;
220
}
221
222
223
/* Clear out and free internal pointers of ASN.1 STRING object.
224
 *
225
 * @param [in] asn1  ASN.1 STRING object.
226
 */
227
static void wolfSSL_ASN1_STRING_clear(WOLFSSL_ASN1_STRING* asn1)
228
{
229
    /* Check we have an object to free. */
230
    if (asn1 != NULL) {
231
        /* Dispose of dynamic data. */
232
        if ((asn1->length > 0) && asn1->isDynamic) {
233
            XFREE(asn1->data, NULL, DYNAMIC_TYPE_OPENSSL);
234
        }
235
        XMEMSET(asn1, 0, sizeof(WOLFSSL_ASN1_STRING));
236
    }
237
}
238
239
240
void wolfSSL_X509_EXTENSION_free(WOLFSSL_X509_EXTENSION* x)
241
{
242
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_free");
243
    if (x == NULL)
244
        return;
245
246
    if (x->obj != NULL) {
247
        wolfSSL_ASN1_OBJECT_free(x->obj);
248
    }
249
250
    wolfSSL_ASN1_STRING_clear(&x->value);
251
    wolfSSL_sk_pop_free(x->ext_sk, NULL);
252
253
    XFREE(x, NULL, DYNAMIC_TYPE_X509_EXT);
254
}
255
256
WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_dup(WOLFSSL_X509_EXTENSION* src)
257
{
258
    WOLFSSL_X509_EXTENSION* ret = NULL;
259
    int err = 0;
260
261
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_dup");
262
263
    if (src == NULL) {
264
        err = 1;
265
    }
266
267
    if (err == 0) {
268
        ret = wolfSSL_X509_EXTENSION_new();
269
        if (ret == NULL) {
270
            err = 1;
271
        }
272
    }
273
    if (err == 0 && src->obj != NULL) {
274
        ret->obj = wolfSSL_ASN1_OBJECT_dup(src->obj);
275
        if (ret->obj == NULL) {
276
            err = 1;
277
        }
278
    }
279
    if (err == 0) {
280
        ret->crit = src->crit;
281
        if (wolfSSL_ASN1_STRING_copy(&ret->value, &src->value) !=
282
                WOLFSSL_SUCCESS) {
283
            err = 1;
284
        }
285
    }
286
287
    if (err == 1 && ret != NULL) {
288
        wolfSSL_X509_EXTENSION_free(ret);
289
        ret = NULL;
290
    }
291
292
    return ret;
293
}
294
295
WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_create_by_OBJ(
296
    WOLFSSL_X509_EXTENSION* ex, WOLFSSL_ASN1_OBJECT *obj, int crit,
297
    WOLFSSL_ASN1_STRING *data)
298
{
299
    int err = 0;
300
    WOLFSSL_X509_EXTENSION *ret = ex;
301
    WOLFSSL_ASN1_OBJECT *newObj = NULL;
302
303
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_create_by_OBJ");
304
305
    if ((obj == NULL) || (data == NULL)) {
306
       return NULL;
307
    }
308
309
    if (ret == NULL) {
310
        ret = wolfSSL_X509_EXTENSION_new();
311
        if (ret == NULL) {
312
            err = 1;
313
        }
314
    }
315
316
    /* Duplicate the source object before freeing the existing one so that a
317
     * caller passing the extension's own object (e.g. obtained via
318
     * wolfSSL_X509_EXTENSION_get_object(ex)) does not read freed memory. */
319
    if (err == 0) {
320
        newObj = wolfSSL_ASN1_OBJECT_dup(obj);
321
        if (newObj == NULL) {
322
            err = 1;
323
        }
324
    }
325
326
    if ((err == 0) && (ret == ex)) {
327
        /* Prevent potential memory leaks and dangling pointers. */
328
        wolfSSL_ASN1_OBJECT_free(ret->obj);
329
        ret->obj = NULL;
330
        wolfSSL_ASN1_STRING_clear(&ret->value);
331
    }
332
333
    if (err == 0) {
334
        ret->crit = crit;
335
        ret->obj = newObj;
336
        newObj = NULL;
337
    }
338
339
    if (err == 0) {
340
        if (wolfSSL_ASN1_STRING_copy(&ret->value, data) != WOLFSSL_SUCCESS) {
341
            err = 1;
342
        }
343
    }
344
345
    if (err == 1) {
346
        /* Free the duplicate if it was created but not assigned to ret. */
347
        wolfSSL_ASN1_OBJECT_free(newObj);
348
        if (ret != ex) {
349
            wolfSSL_X509_EXTENSION_free(ret);
350
        }
351
        ret = NULL;
352
    }
353
    return ret;
354
}
355
356
/* Creates and returns a new WOLFSSL_X509_EXTENSION stack. */
357
WOLFSSL_STACK* wolfSSL_sk_new_x509_ext(void)
358
{
359
    WOLFSSL_STACK* sk;
360
    WOLFSSL_ENTER("wolfSSL_sk_new_x509_ext");
361
362
    sk = wolfSSL_sk_new_null();
363
    if (sk) {
364
        sk->type = STACK_TYPE_X509_EXT;
365
    }
366
    return sk;
367
}
368
369
/* This function does NOT return 1 on success. It returns 0 on fail, and the
370
 * number of items in the stack upon success. This is for compatibility with
371
 * OpenSSL. */
372
int wolfSSL_sk_X509_EXTENSION_push(WOLFSSL_STACK* sk,
373
    WOLFSSL_X509_EXTENSION* ext)
374
{
375
    WOLFSSL_ENTER("wolfSSL_sk_X509_EXTENSION_push");
376
377
    return wolfSSL_sk_push(sk, ext);
378
}
379
380
static WOLFSSL_STACK* generateExtStack(const WOLFSSL_X509 *x)
381
{
382
    int numOfExt, i;
383
    WOLFSSL_X509 *x509 = (WOLFSSL_X509*)x;
384
    WOLFSSL_STACK* ret;
385
    WOLFSSL_STACK* tmp;
386
387
    if (!x509) {
388
        WOLFSSL_MSG("Bad parameter");
389
        return NULL;
390
    }
391
392
    /* Save x509->ext_sk */
393
    tmp = x509->ext_sk;
394
    x509->ext_sk = NULL;
395
    numOfExt = wolfSSL_X509_get_ext_count(x509);
396
397
    for (i = 0; i < numOfExt; i++) {
398
        /* Build the extension stack */
399
        (void)wolfSSL_X509_set_ext(x509, i);
400
    }
401
402
    /* Restore */
403
    ret = x509->ext_sk;
404
    x509->ext_sk = tmp;
405
    return ret;
406
}
407
408
/**
409
 * @param x Certificate to extract extensions from
410
 * @return STACK_OF(X509_EXTENSION)*
411
 */
412
const WOLFSSL_STACK *wolfSSL_X509_get0_extensions(const WOLFSSL_X509 *x)
413
{
414
    int numOfExt;
415
    WOLFSSL_X509 *x509 = (WOLFSSL_X509*)x;
416
    WOLFSSL_ENTER("wolfSSL_X509_get0_extensions");
417
418
    if (!x509) {
419
        WOLFSSL_MSG("Bad parameter");
420
        return NULL;
421
    }
422
423
    numOfExt = wolfSSL_X509_get_ext_count(x509);
424
425
    if (numOfExt != wolfSSL_sk_num(x509->ext_sk_full)) {
426
        wolfSSL_sk_pop_free(x509->ext_sk_full, NULL);
427
        x509->ext_sk_full = generateExtStack(x);
428
    }
429
430
    return x509->ext_sk_full;
431
}
432
433
/**
434
 * Caller is responsible for freeing the returned stack.
435
 */
436
const WOLFSSL_STACK *wolfSSL_X509_REQ_get_extensions(const WOLFSSL_X509 *x)
437
{
438
    return generateExtStack(x);
439
}
440
441
/* Gets the X509_EXTENSION* ext based on it's location in WOLFSSL_X509* x509.
442
 *
443
 * x509   : The X509 structure to look for the extension.
444
 * loc    : Location of the extension. If the extension is found at the given
445
 * location, a new X509_EXTENSION structure is populated with extension-specific
446
 * data based on the extension type.
447
448
 * Returns NULL on error or pointer to X509_EXTENSION structure containing the
449
 * extension. The returned X509_EXTENSION should not be free'd by caller.
450
 * The returned X509_EXTENSION is pushed onto a stack inside the x509 argument.
451
 * This is later free'd when x509 is free'd.
452
 *
453
 * NOTE: for unknown extension NIDs, a X509_EXTENSION is populated with the
454
 * extension oid as the ASN1_OBJECT (QT compatibility)
455
 */
456
WOLFSSL_X509_EXTENSION* wolfSSL_X509_get_ext(const WOLFSSL_X509* x509, int loc)
457
{
458
    WOLFSSL_X509_EXTENSION* ext = NULL;
459
    WOLFSSL_ENTER("wolfSSL_X509_get_ext");
460
    if (x509 == NULL)
461
        return NULL;
462
463
   ext = wolfSSL_X509_set_ext((WOLFSSL_X509*) x509, loc);
464
   return ext;
465
}
466
467
int wolfSSL_X509_get_ext_by_OBJ(const WOLFSSL_X509 *x,
468
        const WOLFSSL_ASN1_OBJECT *obj, int lastpos)
469
{
470
    const WOLF_STACK_OF(WOLFSSL_X509_EXTENSION) *sk;
471
472
    if (!x || !obj) {
473
        WOLFSSL_MSG("Bad parameter");
474
        return WOLFSSL_FATAL_ERROR;
475
    }
476
477
    sk = wolfSSL_X509_get0_extensions(x);
478
    if (!sk) {
479
        WOLFSSL_MSG("No extensions");
480
        return WOLFSSL_FATAL_ERROR;
481
    }
482
    lastpos++;
483
    if (lastpos < 0)
484
        lastpos = 0;
485
    for (; lastpos < wolfSSL_sk_num(sk); lastpos++) {
486
        const WOLFSSL_X509_EXTENSION *ext =
487
            wolfSSL_sk_X509_EXTENSION_value(sk, lastpos);
488
        if (ext == NULL)
489
            continue;
490
        if (wolfSSL_OBJ_cmp(ext->obj, obj) == 0)
491
            return lastpos;
492
    }
493
    return WOLFSSL_FATAL_ERROR;
494
}
495
496
497
int wolfSSL_X509_OBJECT_set1_X509(WOLFSSL_X509_OBJECT *a, WOLFSSL_X509 *obj)
498
{
499
    WOLFSSL_STUB("wolfSSL_X509_OBJECT_set1_X509");
500
    (void)a;
501
    (void)obj;
502
    return 0;
503
}
504
505
int wolfSSL_X509_OBJECT_set1_X509_CRL(WOLFSSL_X509_OBJECT *a,
506
    WOLFSSL_X509_CRL *obj)
507
{
508
    WOLFSSL_STUB("wolfSSL_X509_OBJECT_set1_X509_CRL");
509
    (void)a;
510
    (void)obj;
511
    return 0;
512
}
513
514
#endif /* OPENSSL_ALL || OPENSSL_EXTRA */
515
516
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
517
    defined(WOLFSSL_WPAS_SMALL)
518
/* Set a general name from the DNS entry data.
519
 *
520
 * @param [in]      dns  DNS entry.
521
 * @param [in, out] gn   General name to place data in.
522
 * @return  1 on success.
523
 * @return  0 on failure.
524
 */
525
static int wolfssl_dns_entry_othername_to_gn(DNS_entry* dns,
526
    WOLFSSL_GENERAL_NAME* gn)
527
{
528
    int ret = 0;
529
    WOLFSSL_ASN1_OBJECT* obj = NULL;
530
    WOLFSSL_ASN1_TYPE* type = NULL;
531
    WOLFSSL_ASN1_STRING* str = NULL;
532
    byte tag = 0;
533
    unsigned char* p = (unsigned char *)dns->name;
534
    long len = dns->len;
535
536
#ifdef WOLFSSL_FPKI
537
    if (dns->oidSum != 0) {
538
        /* UPN OID: 1.3.6.1.4.1.311.20.2.3 */
539
        static const unsigned char upn_oid[] = {
540
            0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x03
541
        };
542
        /* FASCN OID: 2.16.840.1.101.3.6.6 */
543
        static const unsigned char fascn_oid[] = {
544
            0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x06, 0x06
545
        };
546
        const unsigned char* oid;
547
        word32 oidSz;
548
549
        if ((oid = OidFromId(dns->oidSum, oidCertAltNameType, &oidSz)) ==
550
                NULL) {
551
            if (dns->oidSum == UPN_OID) {
552
                oid = upn_oid;
553
                oidSz = (word32)sizeof(upn_oid);
554
            }
555
            else if (dns->oidSum == FASCN_OID) {
556
                oid = fascn_oid;
557
                oidSz = (word32)sizeof(fascn_oid);
558
            }
559
            else {
560
                goto err;
561
            }
562
        }
563
        if ((obj = wolfSSL_c2i_ASN1_OBJECT(NULL, &oid, oidSz)) == NULL) {
564
            goto err;
565
        }
566
567
        tag = WOLFSSL_V_ASN1_UTF8STRING;
568
    }
569
    else
570
#endif
571
    {
572
        word32 idx = 0;
573
        int nameLen;
574
575
        /* Create an object id for general name from DER encoding. */
576
        obj = wolfSSL_d2i_ASN1_OBJECT(NULL, (const unsigned char**)&p, len);
577
        if (obj == NULL)
578
            goto err;
579
        /* Pointer moved on and now update length of remaining data. */
580
        len -= (long)((size_t)p - (size_t)dns->name);
581
582
        /* Next is "value      [0] EXPLICIT ANY DEFINED BY type-id" */
583
        if (GetASNHeader(p, ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0,
584
                &idx, &nameLen, (word32)len) < 0)
585
            goto err;
586
        p += idx;
587
        len -= idx;
588
589
        /* Set the tag to object so that it gets output in raw form */
590
        tag = WOLFSSL_V_ASN1_SEQUENCE;
591
    }
592
593
    /* Create a WOLFSSL_ASN1_STRING from the DER. */
594
    str = wolfSSL_ASN1_STRING_type_new(tag);
595
    if (str == NULL) {
596
        goto err;
597
    }
598
    wolfSSL_ASN1_STRING_set(str, p, (int)len);
599
600
    /* Wrap string in a WOLFSSL_ASN1_TYPE. */
601
    type = wolfSSL_ASN1_TYPE_new();
602
    if (type == NULL)
603
        goto err;
604
    wolfSSL_ASN1_TYPE_set(type, tag, str);
605
    str = NULL; /* type now owns str */
606
607
    if (wolfSSL_GENERAL_NAME_set_type(gn, WOLFSSL_GEN_OTHERNAME)
608
            != WOLFSSL_SUCCESS) {
609
        goto err;
610
    }
611
612
    /* Store the object and string in general name. */
613
    gn->d.otherName->type_id = obj;
614
    gn->d.otherName->value = type;
615
    type = NULL; /* gn->d.otherName owns type */
616
617
    ret = 1;
618
err:
619
    if (ret != 1) {
620
        wolfSSL_ASN1_OBJECT_free(obj);
621
        wolfSSL_ASN1_TYPE_free(type);
622
        wolfSSL_ASN1_STRING_free(str);
623
    }
624
    return ret;
625
}
626
#endif /* OPENSSL_ALL || WOLFSSL_WPAS_SMALL */
627
628
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
629
static int DNS_to_GENERAL_NAME(WOLFSSL_GENERAL_NAME* gn, DNS_entry* dns)
630
{
631
    switch (dns->type) {
632
        case WOLFSSL_GEN_OTHERNAME:
633
            /* Sets gn->type internally */
634
            if (!wolfssl_dns_entry_othername_to_gn(dns, gn)) {
635
                WOLFSSL_MSG("OTHERNAME set failed");
636
                return WOLFSSL_FAILURE;
637
            }
638
            break;
639
640
        case WOLFSSL_GEN_EMAIL:
641
        case WOLFSSL_GEN_DNS:
642
        case WOLFSSL_GEN_URI:
643
        case WOLFSSL_GEN_IPADD:
644
        case WOLFSSL_GEN_IA5:
645
            gn->type = dns->type;
646
            gn->d.ia5->length = dns->len;
647
            if (wolfSSL_ASN1_STRING_set(gn->d.ia5, dns->name,
648
                    gn->d.ia5->length) != WOLFSSL_SUCCESS) {
649
                WOLFSSL_MSG("ASN1_STRING_set failed");
650
                return WOLFSSL_FAILURE;
651
            }
652
            break;
653
654
655
        case WOLFSSL_GEN_DIRNAME:
656
            gn->type = dns->type;
657
            /* wolfSSL_GENERAL_NAME_new() mallocs this by default */
658
            wolfSSL_ASN1_STRING_free(gn->d.ia5);
659
            gn->d.ia5 = NULL;
660
661
            gn->d.dirn = wolfSSL_X509_NAME_new();;
662
            /* @TODO extract dir name info from DNS_entry */
663
            break;
664
665
        case WOLFSSL_GEN_RID:
666
            /* registeredID is parsed into altNames unconditionally so
667
             * ConfirmNameConstraints can enforce RID name constraints
668
             * (RFC 5280 Sec. 4.2.1.10). The body uses only the raw OID
669
             * bytes carried in dns->name/dns->len and constructs a
670
             * proper ASN1_OBJECT, so this case is independent of
671
             * WOLFSSL_RID_ALT_NAME (which only gates the human-readable
672
             * ridString form). */
673
            gn->type = dns->type;
674
            /* wolfSSL_GENERAL_NAME_new() mallocs this by default */
675
            wolfSSL_ASN1_STRING_free(gn->d.ia5);
676
            gn->d.ia5 = NULL;
677
678
            gn->d.registeredID = wolfSSL_ASN1_OBJECT_new();
679
            if (gn->d.registeredID == NULL) {
680
                return WOLFSSL_FAILURE;
681
            }
682
            {
683
                /* Store DER-encoded OID (tag + length + content) in obj */
684
                word32 derSz = 1 + SetLength(dns->len, NULL) + dns->len;
685
                byte* der = (byte*)XMALLOC(derSz,
686
                    gn->d.registeredID->heap, DYNAMIC_TYPE_ASN1);
687
                if (der == NULL) {
688
                    return WOLFSSL_FAILURE;
689
                }
690
                {
691
                    word32 idx = 0;
692
                    der[idx++] = ASN_OBJECT_ID;
693
                    idx += SetLength(dns->len, der + idx);
694
                    XMEMCPY(der + idx, dns->name, dns->len);
695
                }
696
                gn->d.registeredID->obj = der;
697
                gn->d.registeredID->objSz = derSz;
698
            }
699
            gn->d.registeredID->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA;
700
            gn->d.registeredID->grp = oidCertExtType;
701
            break;
702
703
        case WOLFSSL_GEN_X400:
704
            /* Unsupported: fall through */
705
        case WOLFSSL_GEN_EDIPARTY:
706
            /* Unsupported: fall through */
707
        default:
708
            WOLFSSL_MSG("Unsupported type conversion");
709
            return WOLFSSL_FAILURE;
710
    }
711
    return WOLFSSL_SUCCESS;
712
}
713
714
715
static int wolfssl_x509_alt_names_to_gn(WOLFSSL_X509* x509,
716
    WOLFSSL_X509_EXTENSION* ext)
717
{
718
    int ret = 0;
719
    WOLFSSL_GENERAL_NAME* gn = NULL;
720
    DNS_entry* dns = NULL;
721
    WOLFSSL_STACK* sk;
722
723
    sk = (WOLFSSL_GENERAL_NAMES*)XMALLOC(sizeof(WOLFSSL_GENERAL_NAMES), NULL,
724
        DYNAMIC_TYPE_ASN1);
725
    if (sk == NULL) {
726
        goto err;
727
    }
728
    XMEMSET(sk, 0, sizeof(WOLFSSL_GENERAL_NAMES));
729
    sk->type = STACK_TYPE_GEN_NAME;
730
731
    if (x509->subjAltNameSet && x509->altNames != NULL) {
732
        /* alt names are DNS_entry structs */
733
        dns = x509->altNames;
734
        /* Currently only support GEN_DNS type */
735
        while (dns != NULL) {
736
            gn = wolfSSL_GENERAL_NAME_new();
737
            if (gn == NULL) {
738
                WOLFSSL_MSG("Error creating GENERAL_NAME");
739
                wolfSSL_sk_pop_free(sk, NULL);
740
                goto err;
741
            }
742
743
            if (DNS_to_GENERAL_NAME(gn, dns) != WOLFSSL_SUCCESS) {
744
                wolfSSL_GENERAL_NAME_free(gn);
745
                wolfSSL_sk_pop_free(sk, NULL);
746
                goto err;
747
            }
748
749
            if (wolfSSL_sk_GENERAL_NAME_push(sk, gn) <= 0) {
750
                WOLFSSL_MSG("Error pushing onto stack");
751
                wolfSSL_GENERAL_NAME_free(gn);
752
                wolfSSL_sk_pop_free(sk, NULL);
753
                goto err;
754
            }
755
756
            dns = dns->next;
757
        }
758
    }
759
    ext->ext_sk = sk;
760
    ext->crit = x509->subjAltNameCrit;
761
762
    ret = 1;
763
err:
764
    return ret;
765
}
766
767
/* Pushes a new X509_EXTENSION* ext onto the stack inside WOLFSSL_X509* x509.
768
 * This is currently a helper function for wolfSSL_X509_get_ext
769
 * Caller does not free the returned WOLFSSL_X509_EXTENSION*
770
 */
771
WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc)
772
{
773
    int extCount = 0, length = 0, outSz = 0, sz = 0, ret = 0;
774
    int objSz = 0, isSet = 0;
775
    const byte* rawCert;
776
    const byte* input;
777
    byte* oidBuf;
778
    word32 oid, idx = 0, tmpIdx = 0, nid;
779
    WOLFSSL_X509_EXTENSION* ext = NULL;
780
    WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
781
782
    WOLFSSL_ENTER("wolfSSL_X509_set_ext");
783
784
    if (x509 == NULL) {
785
        WOLFSSL_MSG("\tNot passed a certificate");
786
        return NULL;
787
    }
788
789
    if (loc < 0 || (loc > wolfSSL_X509_get_ext_count(x509))) {
790
        WOLFSSL_MSG("\tBad location argument");
791
        return NULL;
792
    }
793
794
    ext = wolfSSL_X509_EXTENSION_new();
795
    if (ext == NULL) {
796
        WOLFSSL_MSG("\tX509_EXTENSION_new() failed");
797
        return NULL;
798
    }
799
800
    rawCert = wolfSSL_X509_get_der((WOLFSSL_X509*)x509, &outSz);
801
    if (rawCert == NULL) {
802
        WOLFSSL_MSG("\tX509_get_der() failed");
803
        wolfSSL_X509_EXTENSION_free(ext);
804
        return NULL;
805
    }
806
807
#ifdef WOLFSSL_SMALL_STACK
808
    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT);
809
    if (cert == NULL) {
810
        WOLFSSL_MSG("Failed to allocate memory for DecodedCert");
811
        wolfSSL_X509_EXTENSION_free(ext);
812
        return NULL;
813
    }
814
#endif
815
816
    InitDecodedCert(cert, rawCert, (word32)outSz, 0);
817
818
    if (ParseCert(cert,
819
#ifdef WOLFSSL_CERT_REQ
820
            x509->isCSR ? CERTREQ_TYPE :
821
#endif
822
                    CA_TYPE,
823
            NO_VERIFY, NULL) < 0) {
824
        WOLFSSL_MSG("\tCertificate parsing failed");
825
        wolfSSL_X509_EXTENSION_free(ext);
826
        FreeDecodedCert(cert);
827
        WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
828
        return NULL;
829
    }
830
831
    input = cert->extensions;
832
    sz = cert->extensionsSz;
833
834
    if (input == NULL || sz == 0) {
835
        WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
836
        wolfSSL_X509_EXTENSION_free(ext);
837
        FreeDecodedCert(cert);
838
        WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
839
        return NULL;
840
    }
841
842
#ifdef WOLFSSL_CERT_REQ
843
    if (!x509->isCSR)
844
#endif
845
    {
846
        if (input[idx++] != ASN_EXTENSIONS) {
847
            WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
848
            wolfSSL_X509_EXTENSION_free(ext);
849
            FreeDecodedCert(cert);
850
            WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
851
            return NULL;
852
        }
853
854
        if (GetLength(input, &idx, &length, (word32)sz) < 0) {
855
            WOLFSSL_MSG("\tfail: invalid length");
856
            wolfSSL_X509_EXTENSION_free(ext);
857
            FreeDecodedCert(cert);
858
            WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
859
            return NULL;
860
        }
861
    }
862
863
    if (GetSequence(input, &idx, &length, (word32)sz) < 0) {
864
        WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
865
        wolfSSL_X509_EXTENSION_free(ext);
866
        FreeDecodedCert(cert);
867
        WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
868
        return NULL;
869
    }
870
871
    while (idx < (word32)sz) {
872
        oid = 0;
873
874
        if (GetSequence(input, &idx, &length, (word32)sz) < 0) {
875
            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
876
            wolfSSL_X509_EXTENSION_free(ext);
877
            FreeDecodedCert(cert);
878
            WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
879
            return NULL;
880
        }
881
882
        tmpIdx = idx;
883
        ret = GetObjectId(input, &idx, &oid, oidCertExtType, (word32)sz);
884
        if (ret < 0) {
885
            WOLFSSL_MSG("\tfail: OBJECT ID");
886
            wolfSSL_X509_EXTENSION_free(ext);
887
            FreeDecodedCert(cert);
888
            WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
889
            return NULL;
890
        }
891
        idx = tmpIdx;
892
        nid = (word32)oid2nid(oid, oidCertExtType);
893
894
        /* Continue while loop until extCount == loc or idx > sz */
895
        if (extCount != loc) {
896
            idx += length;
897
            extCount++;
898
            continue;
899
        }
900
        /* extCount == loc. Now get the extension. */
901
        /* Check if extension has been set */
902
        isSet = wolfSSL_X509_ext_isSet_by_NID((WOLFSSL_X509*)x509, (int)nid);
903
904
        if (wolfSSL_OBJ_nid2ln((int)nid) != NULL) {
905
            /* This is NOT an unknown OID. */
906
            ext->obj = wolfSSL_OBJ_nid2obj((int)nid);
907
            if (ext->obj == NULL) {
908
                WOLFSSL_MSG("\tfail: Invalid OBJECT");
909
                wolfSSL_X509_EXTENSION_free(ext);
910
                FreeDecodedCert(cert);
911
                WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
912
                return NULL;
913
            }
914
        }
915
916
        if (ext->obj) {
917
            ext->obj->nid = (int)nid;
918
        }
919
920
        switch (oid) {
921
            case BASIC_CA_OID:
922
            {
923
                WOLFSSL_ASN1_INTEGER* a;
924
                word32 dataIdx = idx;
925
                word32 dummyOid;
926
                int dataLen = 0;
927
928
                if (!isSet)
929
                    break;
930
931
                /* Set pathlength */
932
                a = wolfSSL_ASN1_INTEGER_new();
933
934
                /* Set the data */
935
                ret = GetObjectId(input, &dataIdx, &dummyOid, oidCertExtType,
936
                        (word32)sz) == 0;
937
                if (ret && dataIdx < (word32)sz) {
938
                    /* Skip the critical information */
939
                    if (input[dataIdx] == ASN_BOOLEAN) {
940
                        dataIdx++;
941
                        ret = GetLength(input, &dataIdx, &dataLen, sz) >= 0;
942
                        dataIdx += dataLen;
943
                    }
944
                }
945
                if (ret) {
946
                    ret = GetOctetString(input, &dataIdx, &dataLen,
947
                            (word32)sz) > 0;
948
                }
949
                if (ret) {
950
                    ret = wolfSSL_ASN1_STRING_set(&ext->value, input + dataIdx,
951
                            dataLen) == 1;
952
                }
953
954
                if (a == NULL || !ret) {
955
                    wolfSSL_X509_EXTENSION_free(ext);
956
                    FreeDecodedCert(cert);
957
                    WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
958
                    return NULL;
959
                }
960
                /* RFC 5280 4.2.1.9: only populate pathLen when the
961
                 * pathLenConstraint field was actually present. When it is
962
                 * absent no limit is imposed, and pathlen must remain NULL so
963
                 * it is distinguishable from a pathLenConstraint of 0. */
964
                if (x509->basicConstPlSet) {
965
                    a->length = (int)x509->pathLength;
966
967
                    /* Save ASN1_INTEGER in x509 extension */
968
                    ext->obj->pathlen = a;
969
                }
970
                else {
971
                    wolfSSL_ASN1_INTEGER_free(a);
972
                    ext->obj->pathlen = NULL;
973
                }
974
975
                ext->obj->ca = x509->isCa;
976
                break;
977
            }
978
979
            case AUTH_INFO_OID:
980
            {
981
                WOLFSSL_STACK* sk;
982
983
                if (!isSet)
984
                    break;
985
986
                /* Create a stack to hold both the caIssuer and ocsp objects
987
                    in X509_EXTENSION structure */
988
                sk = wolfSSL_sk_new_asn1_obj();
989
                if (sk == NULL) {
990
                    WOLFSSL_MSG("Failed to malloc stack");
991
                    wolfSSL_X509_EXTENSION_free(ext);
992
                    FreeDecodedCert(cert);
993
                    WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
994
                    return NULL;
995
                }
996
997
                /* Add CaIssuers object to stack */
998
                if (x509->authInfoCaIssuer != NULL &&
999
                    x509->authInfoCaIssuerSz > 0)
1000
                {
1001
                    WOLFSSL_ASN1_OBJECT* obj;
1002
                    obj = wolfSSL_ASN1_OBJECT_new();
1003
                    if (obj == NULL) {
1004
                        WOLFSSL_MSG("Error creating ASN1 object");
1005
                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
1006
                        wolfSSL_X509_EXTENSION_free(ext);
1007
                        FreeDecodedCert(cert);
1008
                        WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
1009
                        return NULL;
1010
                    }
1011
                    obj->obj = (byte*)x509->authInfoCaIssuer;
1012
                    obj->objSz = (unsigned int)x509->authInfoCaIssuerSz;
1013
                    obj->grp = oidCertAuthInfoType;
1014
                    obj->nid = WC_NID_ad_ca_issuers;
1015
1016
                    ret = wolfSSL_sk_ASN1_OBJECT_push(sk, obj) > 0
1017
                            ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
1018
                    if (ret != WOLFSSL_SUCCESS) {
1019
                        WOLFSSL_MSG("Error pushing ASN1 object onto stack");
1020
                        wolfSSL_ASN1_OBJECT_free(obj);
1021
                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
1022
                        wolfSSL_X509_EXTENSION_free(ext);
1023
                        FreeDecodedCert(cert);
1024
                        WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
1025
                        return NULL;
1026
                    }
1027
                }
1028
1029
                /* Add OCSP object to stack */
1030
                if (x509->authInfo != NULL &&
1031
                    x509->authInfoSz > 0)
1032
                {
1033
                    WOLFSSL_ASN1_OBJECT* obj;
1034
                    obj = wolfSSL_ASN1_OBJECT_new();
1035
                    if (obj == NULL) {
1036
                        WOLFSSL_MSG("Error creating ASN1 object");
1037
                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
1038
                        wolfSSL_X509_EXTENSION_free(ext);
1039
                        FreeDecodedCert(cert);
1040
                        WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
1041
                        return NULL;
1042
                    }
1043
                    obj->obj = x509->authInfo;
1044
                    obj->objSz = (unsigned int)x509->authInfoSz;
1045
                    obj->grp = oidCertAuthInfoType;
1046
                    obj->nid = WC_NID_ad_OCSP;
1047
1048
                    ret = wolfSSL_sk_ASN1_OBJECT_push(sk, obj) > 0
1049
                            ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
1050
                    if (ret != WOLFSSL_SUCCESS) {
1051
                        WOLFSSL_MSG("Error pushing ASN1 object onto stack");
1052
                        wolfSSL_ASN1_OBJECT_free(obj);
1053
                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
1054
                        wolfSSL_X509_EXTENSION_free(ext);
1055
                        FreeDecodedCert(cert);
1056
                        WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
1057
                        return NULL;
1058
                    }
1059
                }
1060
                ext->ext_sk = sk;
1061
                break;
1062
            }
1063
1064
            case ALT_NAMES_OID:
1065
                if (!isSet)
1066
                    break;
1067
                if (!wolfssl_x509_alt_names_to_gn(x509, ext)) {
1068
                    wolfSSL_X509_EXTENSION_free(ext);
1069
                    FreeDecodedCert(cert);
1070
                    WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
1071
                    return NULL;
1072
                }
1073
                break;
1074
        }
1075
1076
        /* The ASN1_OBJECT in the extension is set in the same way
1077
         * for recognized and for unrecognized extension types, as
1078
         * the full OCTET STRING */
1079
1080
        /* Get OID from input */
1081
        if (GetASNObjectId(input, &idx, &length, (word32)sz) != 0) {
1082
            WOLFSSL_MSG("Failed to Get ASN Object Id");
1083
            wolfSSL_X509_EXTENSION_free(ext);
1084
            FreeDecodedCert(cert);
1085
            WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
1086
            return NULL;
1087
        }
1088
        oidBuf = (byte*)XMALLOC(length+1+MAX_LENGTH_SZ, NULL,
1089
                            DYNAMIC_TYPE_TMP_BUFFER);
1090
        if (oidBuf == NULL) {
1091
            WOLFSSL_MSG("Failed to malloc tmp buffer");
1092
            wolfSSL_X509_EXTENSION_free(ext);
1093
            FreeDecodedCert(cert);
1094
            WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
1095
            return NULL;
1096
        }
1097
        oidBuf[0] = ASN_OBJECT_ID;
1098
        objSz++;
1099
        objSz += SetLength(length, oidBuf + 1);
1100
        objSz += length;
1101
1102
        /* Set object size and reallocate space in object buffer */
1103
        if (ext->obj == NULL) {
1104
            ext->obj = wolfSSL_ASN1_OBJECT_new();
1105
            if (ext->obj == NULL) {
1106
                XFREE(oidBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1107
                wolfSSL_X509_EXTENSION_free(ext);
1108
                FreeDecodedCert(cert);
1109
                WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
1110
                return NULL;
1111
            }
1112
        }
1113
1114
        if (((ext->obj->dynamic & WOLFSSL_ASN1_DYNAMIC_DATA) != 0) ||
1115
            (ext->obj->obj == NULL)) {
1116
            byte* tmp;
1117
        #ifdef WOLFSSL_NO_REALLOC
1118
            /* Don't carry the old OID over: objSz is the mapped NID's
1119
             * canonical length, which can exceed the certificate's OID. The
1120
             * buffer is rewritten from oidBuf below. */
1121
            tmp = (byte*)XMALLOC(objSz, NULL, DYNAMIC_TYPE_ASN1);
1122
            if (ext->obj->obj != NULL) {
1123
                XFREE((byte*)ext->obj->obj, NULL, DYNAMIC_TYPE_ASN1);
1124
            }
1125
            ext->obj->obj = tmp;
1126
        #else
1127
            tmp = (byte*)XREALLOC((byte*)ext->obj->obj, objSz, NULL,
1128
                                  DYNAMIC_TYPE_ASN1);
1129
            if (tmp == NULL)
1130
                XFREE((byte*)ext->obj->obj, NULL, DYNAMIC_TYPE_ASN1);
1131
            ext->obj->obj = tmp;
1132
        #endif
1133
            if (ext->obj->obj == NULL) {
1134
                wolfSSL_X509_EXTENSION_free(ext);
1135
                FreeDecodedCert(cert);
1136
                XFREE(oidBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1137
                WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
1138
                return NULL;
1139
            }
1140
            ext->obj->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA;
1141
        }
1142
        else {
1143
            ext->obj->dynamic &= ~WOLFSSL_ASN1_DYNAMIC_DATA;
1144
        }
1145
        ext->obj->objSz = (unsigned int)objSz;
1146
1147
        /* Get OID from input and copy to ASN1_OBJECT buffer */
1148
        XMEMCPY(oidBuf+2, input+idx, length);
1149
        XMEMCPY((byte*)ext->obj->obj, oidBuf, ext->obj->objSz);
1150
        XFREE(oidBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1151
        oidBuf = NULL;
1152
        ext->obj->grp = oidCertExtType;
1153
        ext->crit = 0;
1154
1155
        tmpIdx = idx + length;
1156
1157
        /* Get CRITICAL. If not present, defaults to false.
1158
         * It present, must be a valid TRUE */
1159
        if ((tmpIdx < (word32)sz) &&
1160
            (input[tmpIdx] == ASN_BOOLEAN))
1161
        {
1162
            if (((tmpIdx + 2) >= (word32)sz) ||
1163
                /* Check bool length */
1164
                (input[tmpIdx+1] != 1) ||
1165
                /* Assert true if CRITICAL present */
1166
                (input[tmpIdx+2] != 0xff))
1167
            {
1168
                WOLFSSL_MSG("Error decoding unknown extension data");
1169
                wolfSSL_X509_EXTENSION_free(ext);
1170
                FreeDecodedCert(cert);
1171
                WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
1172
                return NULL;
1173
            }
1174
1175
            ext->crit = 1;
1176
            tmpIdx += 3;
1177
        }
1178
1179
        /* Get extension data and copy as ASN1_STRING */
1180
        if ((tmpIdx >= (word32)sz) ||
1181
            (input[tmpIdx] != ASN_OCTET_STRING))
1182
        {
1183
            WOLFSSL_MSG("Error decoding unknown extension data");
1184
            wolfSSL_X509_EXTENSION_free(ext);
1185
            FreeDecodedCert(cert);
1186
            WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
1187
            return NULL;
1188
        }
1189
1190
        tmpIdx++;
1191
1192
        if (GetLength(input, &tmpIdx, &length, (word32)sz) <= 0) {
1193
            WOLFSSL_MSG("Error: Invalid Input Length.");
1194
            wolfSSL_X509_EXTENSION_free(ext);
1195
            FreeDecodedCert(cert);
1196
            WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
1197
            return NULL;
1198
        }
1199
        ext->value.data = (char*)XMALLOC(length, NULL,
1200
            DYNAMIC_TYPE_ASN1);
1201
        ext->value.isDynamic = 1;
1202
        if (ext->value.data == NULL) {
1203
            WOLFSSL_MSG("Failed to malloc ASN1_STRING data");
1204
            wolfSSL_X509_EXTENSION_free(ext);
1205
            FreeDecodedCert(cert);
1206
            WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
1207
            return NULL;
1208
        }
1209
        XMEMCPY(ext->value.data,input+tmpIdx,length);
1210
        ext->value.length = length;
1211
1212
        break; /* Got the Extension. Now exit while loop. */
1213
1214
    } /* while(idx < sz) */
1215
1216
    /* Store the new extension in a stack inside x509
1217
     * The extensions on the stack are free'd internally when FreeX509 is called
1218
     */
1219
    if (x509->ext_sk == NULL)
1220
        x509->ext_sk = wolfSSL_sk_new_x509_ext();
1221
    if (wolfSSL_sk_insert(x509->ext_sk, ext, -1) <= 0) {
1222
        wolfSSL_X509_EXTENSION_free(ext);
1223
        ext = NULL;
1224
    }
1225
1226
    FreeDecodedCert(cert);
1227
    WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
1228
    return ext;
1229
}
1230
1231
/**
1232
 * @param str String to copy
1233
 * @param buf Output buffer. If this contains a pointer then it is free'd
1234
 *            with the DYNAMIC_TYPE_X509_EXT hint.
1235
 * @param len Output length
1236
 * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on error
1237
 */
1238
static int asn1_string_copy_to_buffer(WOLFSSL_ASN1_STRING* str, byte** buf,
1239
        word32* len, void* heap)
1240
{
1241
    if (str->data && str->length > 0) {
1242
        if (*buf)
1243
            XFREE(*buf, heap, DYNAMIC_TYPE_X509_EXT);
1244
        *len = 0;
1245
        *buf = (byte*)XMALLOC(str->length, heap, DYNAMIC_TYPE_X509_EXT);
1246
        if (!*buf) {
1247
            WOLFSSL_MSG("malloc error");
1248
            return WOLFSSL_FAILURE;
1249
        }
1250
        *len = (word32)str->length;
1251
        XMEMCPY(*buf, str->data, str->length);
1252
    }
1253
1254
    (void)heap;
1255
    return WOLFSSL_SUCCESS;
1256
}
1257
1258
/* Handle WC_NID_subject_alt_name for wolfSSL_X509_add_ext: iterate the
1259
 * GENERAL_NAME stack on the extension and add each entry to x509->altNames.
1260
 * Only types whose union member is WOLFSSL_ASN1_STRING* (DNS/RFC822/URI/IP/
1261
 * IA5) are read via gn->d.ia5; ASN_OTHER_TYPE is handled via SetOthername.
1262
 * Other types (DIRNAME/RID/X400/EDIPARTY) are rejected to avoid the
1263
 * type-confused union access that would XMEMCPY from a wild pointer in
1264
 * wolfSSL_X509_add_altname_ex. */
1265
static int wolfssl_x509_add_subj_alt_name_ext(WOLFSSL_X509 *x509,
1266
    WOLFSSL_X509_EXTENSION *ext)
1267
{
1268
    WOLFSSL_GENERAL_NAMES* gns = ext->ext_sk;
1269
    while (gns) {
1270
        WOLFSSL_GENERAL_NAME* gn = gns->data.gn;
1271
        if ((gn != NULL) && (gn->type == ASN_OTHER_TYPE)) {
1272
            char *buf = NULL;
1273
            int ret = 0;
1274
            word32 len = 0;
1275
1276
            len = SetOthername(gn->d.otherName, NULL);
1277
            if (len == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
1278
                return WOLFSSL_FAILURE;
1279
            }
1280
1281
            buf = (char*)XMALLOC(len, x509->heap, DYNAMIC_TYPE_X509_EXT);
1282
            if (buf == NULL) {
1283
                WOLFSSL_MSG("Couldn't allocate memory for othername");
1284
                return WOLFSSL_FAILURE;
1285
            }
1286
1287
            /* SetOthername() cannot fail; already passed above. */
1288
            SetOthername(gn->d.otherName, (byte*)buf);
1289
1290
            ret = wolfSSL_X509_add_altname_ex(x509, buf, len,
1291
                                              ASN_OTHER_TYPE);
1292
            XFREE(buf, x509->heap, DYNAMIC_TYPE_X509_EXT);
1293
            if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
1294
                 WOLFSSL_MSG("wolfSSL_X509_add_altname_ex() failed");
1295
                 return WOLFSSL_FAILURE;
1296
            }
1297
        }
1298
        /* Only types whose union member are WOLFSSL_ASN1_STRING. */
1299
        else if (gn == NULL) {
1300
            WOLFSSL_MSG("Subject alternative name missing");
1301
            return WOLFSSL_FAILURE;
1302
        }
1303
        else {
1304
            if ((gn->type != ASN_RFC822_TYPE && gn->type != ASN_DNS_TYPE &&
1305
                 gn->type != ASN_URI_TYPE && gn->type != ASN_IP_TYPE &&
1306
                 gn->type != WOLFSSL_GEN_IA5) || (gn->d.ia5 == NULL)) {
1307
                WOLFSSL_MSG("Subject alternative name unsupported "
1308
                            "GeneralName type or missing name");
1309
                return WOLFSSL_FAILURE;
1310
            }
1311
            if (wolfSSL_X509_add_altname_ex(x509, gn->d.ia5->data,
1312
                         gn->d.ia5->length, gn->type) != WOLFSSL_SUCCESS) {
1313
                WOLFSSL_MSG("Failed to add subject alternative name");
1314
                return WOLFSSL_FAILURE;
1315
            }
1316
        }
1317
        gns = gns->next;
1318
    }
1319
    x509->subjAltNameSet = 1;
1320
    x509->subjAltNameCrit = (byte)ext->crit;
1321
    return WOLFSSL_SUCCESS;
1322
}
1323
1324
#ifdef WOLFSSL_CUSTOM_OID
1325
/* Handle the default (unrecognized NID) case of wolfSSL_X509_add_ext when
1326
 * custom-OID extensions are enabled: copy the extension OID text and value
1327
 * into the next free slot in x509->custom_exts, taking ownership of the
1328
 * allocations on success. */
1329
static int wolfssl_x509_add_custom_ext(WOLFSSL_X509 *x509,
1330
    WOLFSSL_X509_EXTENSION *ext)
1331
{
1332
    char *oid = NULL;
1333
    byte *val = NULL;
1334
    int err = 0;
1335
1336
    if ((ext->obj == NULL) || (ext->value.length == 0) ||
1337
        (ext->value.data == NULL)) {
1338
        WOLFSSL_MSG("Extension has insufficient information.");
1339
        return WOLFSSL_FAILURE;
1340
    }
1341
1342
    if ((x509->customExtCount < 0) ||
1343
        (x509->customExtCount >= NUM_CUSTOM_EXT)) {
1344
        WOLFSSL_MSG("Bad value for customExtCount.");
1345
        return WOLFSSL_FAILURE;
1346
    }
1347
1348
    /* This is a viable custom extension. */
1349
    oid = (char*)XMALLOC(MAX_OID_STRING_SZ, x509->heap,
1350
        DYNAMIC_TYPE_X509_EXT);
1351
    val = (byte*)XMALLOC(ext->value.length, x509->heap,
1352
        DYNAMIC_TYPE_X509_EXT);
1353
    if ((oid == NULL) || (val == NULL)) {
1354
        WOLFSSL_MSG("Memory allocation failure.\n");
1355
        err = 1;
1356
    }
1357
1358
    if (err == 0) {
1359
        XMEMCPY(val, ext->value.data, ext->value.length);
1360
        if (wolfSSL_OBJ_obj2txt(oid, MAX_OID_STRING_SZ, ext->obj, 1) < 0) {
1361
            err = 1;
1362
        }
1363
    }
1364
1365
    if (err == 1) {
1366
        XFREE(val, x509->heap, DYNAMIC_TYPE_X509_EXT);
1367
        XFREE(oid, x509->heap, DYNAMIC_TYPE_X509_EXT);
1368
        return WOLFSSL_FAILURE;
1369
    }
1370
1371
    /* ext->crit is WOLFSSL_ASN1_BOOLEAN */
1372
    if (ext->crit != 0 && ext->crit != -1) {
1373
        XFREE(val, x509->heap, DYNAMIC_TYPE_X509_EXT);
1374
        XFREE(oid, x509->heap, DYNAMIC_TYPE_X509_EXT);
1375
        return WOLFSSL_FAILURE;
1376
    }
1377
1378
    /* x509->custom_exts now owns the buffers and they must be managed. */
1379
    x509->custom_exts[x509->customExtCount].oid = oid;
1380
    x509->custom_exts[x509->customExtCount].crit = (byte)ext->crit;
1381
    x509->custom_exts[x509->customExtCount].val = val;
1382
    x509->custom_exts[x509->customExtCount].valSz = ext->value.length;
1383
    x509->customExtCount++;
1384
    return WOLFSSL_SUCCESS;
1385
}
1386
#endif /* WOLFSSL_CUSTOM_OID */
1387
1388
/* Map a DER encoded KeyPurposeId to its EXTKEYUSE_* bit.
1389
 *
1390
 * @param [in]  der    DER encoded OBJECT IDENTIFIER.
1391
 * @param [in]  derSz  Length of @der in bytes.
1392
 * @param [out] bit    Usage bit, 0 when wolfSSL tracks no bit for the OID.
1393
 * @return  0 on success, ASN_PARSE_E when @der is not one OBJECT IDENTIFIER.
1394
 */
1395
static int wolfssl_eku_der_to_bit(const byte* der, word32 derSz, byte* bit)
1396
{
1397
    word32 idx = 0;
1398
    word32 oid = 0;
1399
1400
    *bit = 0;
1401
1402
    /* wolfSSL_d2i_ASN1_OBJECT() reads back at most this much. */
1403
    if (derSz > (word32)(MAX_OID_SZ + 2)) {
1404
        return ASN_PARSE_E;
1405
    }
1406
    if (GetObjectId(der, &idx, &oid, oidIgnoreType, derSz) != 0) {
1407
        return ASN_PARSE_E;
1408
    }
1409
    /* One OID, no trailing bytes. */
1410
    if (idx != derSz) {
1411
        return ASN_PARSE_E;
1412
    }
1413
1414
    switch (oid) {
1415
    case EKU_ANY_OID:
1416
        *bit = EXTKEYUSE_ANY;
1417
        break;
1418
    case EKU_SERVER_AUTH_OID:
1419
        *bit = EXTKEYUSE_SERVER_AUTH;
1420
        break;
1421
    case EKU_CLIENT_AUTH_OID:
1422
        *bit = EXTKEYUSE_CLIENT_AUTH;
1423
        break;
1424
    case EKU_CODESIGNING_OID:
1425
        *bit = EXTKEYUSE_CODESIGN;
1426
        break;
1427
    case EKU_EMAILPROTECT_OID:
1428
        *bit = EXTKEYUSE_EMAILPROT;
1429
        break;
1430
    case EKU_TIMESTAMP_OID:
1431
        *bit = EXTKEYUSE_TIMESTAMP;
1432
        break;
1433
    case EKU_OCSP_SIGN_OID:
1434
        *bit = EXTKEYUSE_OCSP_SIGN;
1435
        break;
1436
    default:
1437
        /* Unknown OID: kept in the list, no bit. */
1438
        break;
1439
    }
1440
1441
    return 0;
1442
}
1443
1444
/* Check that every entry of a KeyPurposeId stack is one DER OBJECT
1445
 * IDENTIFIER, reporting the size of the encoded list and the usage bits.
1446
 *
1447
 * @return  WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE otherwise.
1448
 */
1449
static int wolfssl_x509_eku_sk_check(WOLFSSL_STACK* sk, word32* derSz,
1450
    byte* usage)
1451
{
1452
    int i;
1453
    int num;
1454
    word32 sz = 0;
1455
    byte bits = 0;
1456
    byte bit = 0;
1457
1458
    num = wolfSSL_sk_num(sk);
1459
    if (num <= 0) {
1460
        WOLFSSL_MSG("extKeyUsage object stack is empty");
1461
        return WOLFSSL_FAILURE;
1462
    }
1463
1464
    for (i = 0; i < num; i++) {
1465
        WOLFSSL_ASN1_OBJECT* obj = (WOLFSSL_ASN1_OBJECT*)wolfSSL_sk_value(sk,
1466
            i);
1467
1468
        if ((obj == NULL) || (obj->obj == NULL) || (obj->objSz == 0)) {
1469
            WOLFSSL_MSG("extKeyUsage entry has no OID encoding");
1470
            return WOLFSSL_FAILURE;
1471
        }
1472
        if (wolfssl_eku_der_to_bit(obj->obj, obj->objSz, &bit) != 0) {
1473
            WOLFSSL_MSG("extKeyUsage entry is not a KeyPurposeId");
1474
            return WOLFSSL_FAILURE;
1475
        }
1476
        bits |= bit;
1477
        sz += obj->objSz;
1478
    }
1479
1480
    *derSz = sz;
1481
    *usage = bits;
1482
1483
    return WOLFSSL_SUCCESS;
1484
}
1485
1486
/* Set the extKeyUsage of @x509 from the stack of ASN.1 OBJECTs that
1487
 * wolfSSL_X509V3_EXT_i2d() builds for WC_NID_ext_key_usage.
1488
 *
1489
 * The KeyPurposeId list is stored as the bare concatenation of its DER
1490
 * OBJECT IDENTIFIERs, the layout DecodeExtKeyUsage() hands to WOLFSSL_X509,
1491
 * so that wolfSSL_X509_get_ext_d2i() reads it back. OIDs wolfSSL has no bit
1492
 * for stay in the list.
1493
 *
1494
 * @return  WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE otherwise.
1495
 */
1496
static int wolfssl_x509_add_ext_key_usage_sk(WOLFSSL_X509* x509,
1497
    WOLFSSL_X509_EXTENSION* ext)
1498
{
1499
    int i;
1500
    int num;
1501
    byte* der;
1502
    word32 derSz = 0;
1503
    word32 idx = 0;
1504
    byte usage = 0;
1505
1506
    /* Validate before allocating so a bad entry changes nothing. */
1507
    if (wolfssl_x509_eku_sk_check(ext->ext_sk, &derSz, &usage) !=
1508
            WOLFSSL_SUCCESS) {
1509
        return WOLFSSL_FAILURE;
1510
    }
1511
    num = wolfSSL_sk_num(ext->ext_sk);
1512
1513
    der = (byte*)XMALLOC(derSz, x509->heap, DYNAMIC_TYPE_X509_EXT);
1514
    if (der == NULL) {
1515
        WOLFSSL_MSG("Memory allocation failure");
1516
        return WOLFSSL_FAILURE;
1517
    }
1518
1519
    for (i = 0; i < num; i++) {
1520
        WOLFSSL_ASN1_OBJECT* obj = (WOLFSSL_ASN1_OBJECT*)wolfSSL_sk_value(
1521
            ext->ext_sk, i);
1522
1523
        XMEMCPY(der + idx, obj->obj, obj->objSz);
1524
        idx += obj->objSz;
1525
    }
1526
1527
    XFREE(x509->extKeyUsageSrc, x509->heap, DYNAMIC_TYPE_X509_EXT);
1528
    x509->extKeyUsageSrc   = der;
1529
    x509->extKeyUsageSz    = derSz;
1530
    x509->extKeyUsageCount = (word32)num;
1531
    x509->extKeyUsage      = usage;
1532
    x509->extKeyUsageCrit  = (byte)ext->crit;
1533
1534
    return WOLFSSL_SUCCESS;
1535
}
1536
1537
int wolfSSL_X509_add_ext(WOLFSSL_X509 *x509, WOLFSSL_X509_EXTENSION *ext,
1538
    int loc)
1539
{
1540
    int nid;
1541
1542
    WOLFSSL_ENTER("wolfSSL_X509_add_ext");
1543
1544
    if (!x509 || !ext || loc >= 0) {
1545
        WOLFSSL_MSG("Bad parameter");
1546
        return WOLFSSL_FAILURE;
1547
    }
1548
    nid = (ext->obj != NULL) ? ext->obj->type : ext->value.nid;
1549
1550
    switch (nid) {
1551
    case WC_NID_authority_key_identifier:
1552
        if (x509->authKeyIdSrc != NULL) {
1553
            /* If authKeyId points into authKeyIdSrc then free it and
1554
             * revert to old functionality */
1555
            XFREE(x509->authKeyIdSrc, x509->heap, DYNAMIC_TYPE_X509_EXT);
1556
            x509->authKeyIdSrc = NULL;
1557
            x509->authKeyId = NULL;
1558
        }
1559
        if (asn1_string_copy_to_buffer(&ext->value, &x509->authKeyId,
1560
                &x509->authKeyIdSz, x509->heap) != WOLFSSL_SUCCESS) {
1561
            WOLFSSL_MSG("asn1_string_copy_to_buffer error");
1562
            return WOLFSSL_FAILURE;
1563
        }
1564
        x509->authKeyIdCrit = (byte)ext->crit;
1565
        break;
1566
    case WC_NID_subject_key_identifier:
1567
        if (asn1_string_copy_to_buffer(&ext->value, &x509->subjKeyId,
1568
                &x509->subjKeyIdSz, x509->heap) != WOLFSSL_SUCCESS) {
1569
            WOLFSSL_MSG("asn1_string_copy_to_buffer error");
1570
            return WOLFSSL_FAILURE;
1571
        }
1572
        x509->subjKeyIdCrit = (byte)ext->crit;
1573
        break;
1574
    case WC_NID_subject_alt_name:
1575
        if (wolfssl_x509_add_subj_alt_name_ext(x509, ext) != WOLFSSL_SUCCESS) {
1576
            return WOLFSSL_FAILURE;
1577
        }
1578
        break;
1579
    case WC_NID_key_usage:
1580
        if (ext && ext->value.data) {
1581
            if (ext->value.length == sizeof(word16)) {
1582
                /* if ext->value is already word16, set directly */
1583
                word16 ku;
1584
                XMEMCPY(&ku, ext->value.data, sizeof(word16));
1585
                x509->keyUsage = ku;
1586
#ifdef BIG_ENDIAN_ORDER
1587
                x509->keyUsage = rotlFixed16(x509->keyUsage, 8U);
1588
#endif
1589
                x509->keyUsageCrit = (byte)ext->crit;
1590
                x509->keyUsageSet = 1;
1591
            }
1592
            else if (ext->value.length > 0) {
1593
                /* ext->value is comma-delimited string, convert to word16 */
1594
                if (ParseKeyUsageStr(ext->value.data, &x509->keyUsage,
1595
                                     x509->heap) != 0) {
1596
                    return WOLFSSL_FAILURE;
1597
                }
1598
                x509->keyUsageCrit = (byte)ext->crit;
1599
                x509->keyUsageSet = 1;
1600
            }
1601
            else {
1602
                return WOLFSSL_FAILURE;
1603
            }
1604
        }
1605
        break;
1606
    case WC_NID_ext_key_usage:
1607
        if (ext && ext->value.data) {
1608
            if (ext->value.length == sizeof(byte)) {
1609
                /* if ext->value is already 1 byte, set directly */
1610
                x509->extKeyUsage = *(byte*)ext->value.data;
1611
                x509->extKeyUsageCrit = (byte)ext->crit;
1612
            }
1613
            else if (ext->value.length > 0) {
1614
                /* ext->value is comma-delimited string, convert to word16 */
1615
                if (ParseExtKeyUsageStr(ext->value.data, &x509->extKeyUsage,
1616
                                        x509->heap) != 0) {
1617
                    return WOLFSSL_FAILURE;
1618
                }
1619
                x509->extKeyUsageCrit = (byte)ext->crit;
1620
            }
1621
            else {
1622
                return WOLFSSL_FAILURE;
1623
            }
1624
        }
1625
        else if (ext && ext->ext_sk != NULL) {
1626
            if (wolfssl_x509_add_ext_key_usage_sk(x509, ext) !=
1627
                    WOLFSSL_SUCCESS) {
1628
                return WOLFSSL_FAILURE;
1629
            }
1630
        }
1631
        /* No data and no object stack: nothing to set, treat as no-op like the
1632
         * WC_NID_key_usage case above. */
1633
        break;
1634
    case WC_NID_basic_constraints:
1635
        if (ext->obj) {
1636
            x509->isCa = (byte)ext->obj->ca;
1637
            x509->basicConstCrit = (byte)ext->crit;
1638
            if (ext->obj->pathlen) {
1639
                x509->pathLength = (word32)ext->obj->pathlen->length;
1640
                x509->basicConstPlSet = 1;
1641
                x509->pathLengthSet = 1;
1642
            }
1643
            x509->basicConstSet = 1;
1644
        }
1645
        break;
1646
    default:
1647
#ifdef WOLFSSL_CUSTOM_OID
1648
        if (wolfssl_x509_add_custom_ext(x509, ext) != WOLFSSL_SUCCESS) {
1649
            return WOLFSSL_FAILURE;
1650
        }
1651
        break;
1652
#else
1653
        WOLFSSL_MSG("Unsupported extension to add");
1654
        return WOLFSSL_FAILURE;
1655
#endif /* WOLFSSL_CUSTOM_OID */
1656
    } /* switch (nid) */
1657
1658
    return WOLFSSL_SUCCESS;
1659
}
1660
1661
/* Returns pointer to ASN1_STRING in X509_EXTENSION object */
1662
static WOLFSSL_ASN1_STRING* wolfSSL_X509_EXTENSION_get_data_internal(
1663
    WOLFSSL_X509_EXTENSION* ext)
1664
{
1665
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_get_data_internal");
1666
    if (ext == NULL)
1667
        return NULL;
1668
1669
    return &ext->value;
1670
}
1671
1672
1673
#ifndef NO_BIO
1674
1675
#ifndef MAX_INDENT
1676
    #define MAX_INDENT 40
1677
#endif
1678
1679
1680
/* Return 0 on success and 1 on failure. Copies ext data to bio, using indent
1681
 *  to pad the output. flag is ignored. */
1682
int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, WOLFSSL_X509_EXTENSION *ext,
1683
        unsigned long flag, int indent)
1684
{
1685
    WOLFSSL_ASN1_OBJECT* obj;
1686
    WOLFSSL_ASN1_STRING* str;
1687
    int nid;
1688
    int rc = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
1689
    char tmp[CTC_NAME_SIZE*2 + 1];
1690
    const int tmpSz = sizeof(tmp);
1691
    int tmpLen = 0;
1692
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_print");
1693
1694
    if (indent < 0) indent = 0;
1695
    if (indent > MAX_INDENT) indent = MAX_INDENT;
1696
1697
    if ((out == NULL) || (ext == NULL)) {
1698
        WOLFSSL_MSG("NULL parameter error");
1699
        return rc;
1700
    }
1701
1702
    obj = wolfSSL_X509_EXTENSION_get_object(ext);
1703
    if (obj == NULL) {
1704
        WOLFSSL_MSG("Error getting ASN1_OBJECT from X509_EXTENSION");
1705
        return rc;
1706
    }
1707
1708
    str = wolfSSL_X509_EXTENSION_get_data_internal(ext);
1709
    if (str == NULL) {
1710
        WOLFSSL_MSG("Error getting ASN1_STRING from X509_EXTENSION");
1711
        return rc;
1712
    }
1713
1714
    /* Print extension based on the type */
1715
    nid = wolfSSL_OBJ_obj2nid(obj);
1716
    switch (nid) {
1717
        case BASIC_CA_OID:
1718
        {
1719
            char isCa[] = "TRUE";
1720
            char notCa[] = "FALSE";
1721
            if ((tmpLen = XSNPRINTF(tmp, tmpSz, "%*sCA:%s", indent, "",
1722
                                     obj->ca ? isCa : notCa))
1723
                >= tmpSz)
1724
                return rc;
1725
            break;
1726
        }
1727
        case ALT_NAMES_OID:
1728
        {
1729
            WOLFSSL_STACK* sk;
1730
            char* val;
1731
            int valLen;
1732
            int len;
1733
1734
            sk = ext->ext_sk;
1735
            while (sk != NULL) {
1736
                if (sk->type == STACK_TYPE_GEN_NAME && sk->data.gn) {
1737
                    /* str is GENERAL_NAME for subject alternative name ext */
1738
                    str = sk->data.gn->d.ia5;
1739
                    len = str->length + 2; /* + 2 for NULL char and "," */
1740
                    if (len > tmpSz) {
1741
                        WOLFSSL_MSG("len greater than buffer size");
1742
                        return rc;
1743
                    }
1744
1745
                    val = (char*)XMALLOC(len + indent, NULL,
1746
                                                       DYNAMIC_TYPE_TMP_BUFFER);
1747
                    if (val == NULL) {
1748
                        WOLFSSL_MSG("Memory error");
1749
                        return rc;
1750
                    }
1751
                    valLen = XSNPRINTF(val, (size_t)len + indent,
1752
                            "%*s%.*s", indent, "", str->length, str->data);
1753
                    if ((valLen < 0) || (valLen >= len + indent)
1754
                            || ((tmpLen + valLen) >= tmpSz)) {
1755
                        XFREE(val, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1756
                        return rc;
1757
                    }
1758
                    XMEMCPY(tmp + tmpLen, val, valLen);
1759
                    tmpLen += valLen;
1760
                    XFREE(val, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1761
                }
1762
                sk = sk->next;
1763
            }
1764
            break;
1765
        }
1766
        case AUTH_KEY_OID:
1767
        case SUBJ_KEY_OID:
1768
        {
1769
            char* asn1str;
1770
            asn1str = wolfSSL_i2s_ASN1_STRING(NULL, str);
1771
            if (asn1str == NULL) {
1772
                WOLFSSL_MSG("wolfSSL_i2s_ASN1_STRING returned NULL");
1773
                return rc;
1774
            }
1775
            tmpLen = XSNPRINTF(tmp, tmpSz, "%*s%s", indent, "", asn1str);
1776
            XFREE(asn1str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1777
            if (tmpLen >= tmpSz)
1778
                tmpLen = tmpSz - 1;
1779
            break;
1780
        }
1781
        case AUTH_INFO_OID:
1782
        case CERT_POLICY_OID:
1783
        case CRL_DIST_OID:
1784
        case KEY_USAGE_OID:
1785
            WOLFSSL_MSG("X509V3_EXT_print not yet implemented for ext type");
1786
            break;
1787
1788
        default:
1789
            if ((tmpLen = XSNPRINTF(
1790
                     tmp, tmpSz, "%*s%s", indent, "", str->strData))
1791
                >= tmpSz)
1792
                return rc;
1793
    }
1794
1795
    if (wolfSSL_BIO_write(out, tmp, tmpLen) == tmpLen) {
1796
        rc = WOLFSSL_SUCCESS;
1797
    }
1798
    (void) flag;
1799
1800
    return rc;
1801
}
1802
#endif /* !NO_BIO */
1803
1804
#ifndef NO_WOLFSSL_STUB
1805
int wolfSSL_X509V3_EXT_add_nconf(WOLFSSL_CONF *conf, WOLFSSL_X509V3_CTX *ctx,
1806
        const char *section, WOLFSSL_X509 *cert)
1807
{
1808
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_add_nconf");
1809
    WOLFSSL_STUB("wolfSSL_X509V3_EXT_add_nconf");
1810
    (void)conf;
1811
    (void)ctx;
1812
    (void)section;
1813
    (void)cert;
1814
    return WOLFSSL_SUCCESS;
1815
}
1816
#endif
1817
1818
/* Find extension by NID in a stack of extensions.
1819
 *
1820
 * @param sk Stack of extensions
1821
 * @param nid ID to search for
1822
 * @param lastpos Start search from this position (not inclusive, -1 means start from beginning)
1823
 * @return Index of matching extension or -1 on error/not found
1824
 */
1825
int wolfSSL_X509v3_get_ext_by_NID(const WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk,
1826
                                 int nid, int lastpos)
1827
{
1828
    int i;
1829
    WOLFSSL_ENTER("wolfSSL_X509v3_get_ext_by_NID");
1830
1831
    if (sk == NULL) {
1832
        WOLFSSL_MSG("Stack pointer is NULL");
1833
        return WOLFSSL_FATAL_ERROR;
1834
    }
1835
1836
    if (lastpos < -1 || lastpos >= wolfSSL_sk_num(sk)) {
1837
        WOLFSSL_MSG("Invalid position argument");
1838
        return WOLFSSL_FATAL_ERROR;
1839
    }
1840
1841
    for (i = lastpos + 1; i < wolfSSL_sk_num(sk); i++) {
1842
        WOLFSSL_X509_EXTENSION* ext = wolfSSL_sk_X509_EXTENSION_value(sk, i);
1843
        if (ext && ext->obj) {
1844
            if (wolfSSL_OBJ_obj2nid(ext->obj) == nid)
1845
                return i;
1846
        }
1847
    }
1848
1849
    /* Not found */
1850
    return -1;
1851
}
1852
1853
/* Get extension from a stack of extensions by location.
1854
 *
1855
 * @param sk Stack of extensions
1856
 * @param loc Index of extension to retrieve
1857
 * @return Pointer to extension or NULL on error
1858
 */
1859
WOLFSSL_X509_EXTENSION* wolfSSL_X509v3_get_ext(
1860
    const WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk, int loc)
1861
{
1862
    WOLFSSL_ENTER("wolfSSL_X509v3_get_ext");
1863
1864
    if (sk == NULL) {
1865
        WOLFSSL_MSG("Stack pointer is NULL");
1866
        return NULL;
1867
    }
1868
1869
    if (loc < 0 || loc >= wolfSSL_sk_num(sk)) {
1870
        WOLFSSL_MSG("Invalid location argument");
1871
        return NULL;
1872
    }
1873
1874
    return wolfSSL_sk_X509_EXTENSION_value(sk, loc);
1875
}
1876
1877
/* Returns crit flag in X509_EXTENSION object */
1878
int wolfSSL_X509_EXTENSION_get_critical(const WOLFSSL_X509_EXTENSION* ex)
1879
{
1880
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_get_critical");
1881
    if (ex == NULL)
1882
        return BAD_FUNC_ARG;
1883
    return ex->crit;
1884
}
1885
1886
/* Sets if the extension is critical
1887
 * returns WOLFSSL_SUCCESS on success
1888
 */
1889
int wolfSSL_X509_EXTENSION_set_critical(WOLFSSL_X509_EXTENSION* ex, int crit)
1890
{
1891
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_set_critical");
1892
    if (ex == NULL)
1893
        return WOLFSSL_FAILURE;
1894
    ex->crit = crit;
1895
    return WOLFSSL_SUCCESS;
1896
}
1897
1898
/* Creates v3_ext_method for a given X509v3 extension
1899
 *
1900
 * ex   : The X509_EXTENSION used to create v3_ext_method. If the extension is
1901
 * not NULL, get the NID of the extension object and populate the
1902
 * extension type-specific X509V3_EXT_* function(s) in v3_ext_method.
1903
 *
1904
 * Returns NULL on error or pointer to the v3_ext_method populated with
1905
 * extension type-specific X509V3_EXT_* function(s).
1906
 *
1907
 * NOTE: WC_NID_subject_key_identifier is currently the only extension
1908
 * implementing the X509V3_EXT_* functions, as it is the only type called
1909
 * directly by QT. The other extension types return a pointer to a
1910
 * v3_ext_method struct that contains only the NID.
1911
 */
1912
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
1913
const WOLFSSL_v3_ext_method* wolfSSL_X509V3_EXT_get(WOLFSSL_X509_EXTENSION* ex)
1914
#else
1915
WOLFSSL_v3_ext_method* wolfSSL_X509V3_EXT_get(WOLFSSL_X509_EXTENSION* ex)
1916
#endif
1917
{
1918
    int nid;
1919
    WOLFSSL_v3_ext_method method;
1920
1921
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_get");
1922
    if ((ex == NULL) || (ex->obj == NULL)) {
1923
        WOLFSSL_MSG("Passed an invalid X509_EXTENSION*");
1924
        return NULL;
1925
    }
1926
    /* Initialize method to 0 */
1927
    XMEMSET(&method, 0, sizeof(struct WOLFSSL_v3_ext_method));
1928
1929
    nid = ex->obj->nid;
1930
    if (nid <= 0) {
1931
        WOLFSSL_MSG("Failed to get nid from passed extension object");
1932
        return NULL;
1933
    }
1934
    switch (nid) {
1935
        case WC_NID_basic_constraints:
1936
            break;
1937
        case WC_NID_subject_key_identifier:
1938
            method.i2s = (WOLFSSL_X509V3_EXT_I2S)wolfSSL_i2s_ASN1_STRING;
1939
            break;
1940
        case WC_NID_subject_alt_name:
1941
            WOLFSSL_MSG("i2v function not yet implemented for Subject "
1942
                        "Alternative Name");
1943
            break;
1944
        case WC_NID_key_usage:
1945
            WOLFSSL_MSG("i2v function not yet implemented for Key Usage");
1946
            break;
1947
        case WC_NID_authority_key_identifier:
1948
            WOLFSSL_MSG("i2v function not yet implemented for Auth Key Id");
1949
            break;
1950
        case WC_NID_info_access:
1951
            WOLFSSL_MSG("i2v function not yet implemented for Info Access");
1952
            break;
1953
        case WC_NID_ext_key_usage:
1954
            WOLFSSL_MSG("i2v function not yet implemented for Ext Key Usage");
1955
            break;
1956
        case WC_NID_certificate_policies:
1957
            WOLFSSL_MSG("r2i function not yet implemented for Cert Policies");
1958
            break;
1959
        case WC_NID_crl_distribution_points:
1960
            WOLFSSL_MSG("r2i function not yet implemented for CRL Dist Points");
1961
            break;
1962
        default:
1963
            /* If extension type is unknown, return NULL -- QT makes call to
1964
                X509_EXTENSION_get_data() if there is no v3_ext_method */
1965
            WOLFSSL_MSG("X509V3_EXT_get(): Unknown extension type found");
1966
            return NULL;
1967
    }
1968
1969
    method.ext_nid = nid;
1970
    ex->ext_method = method;
1971
1972
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
1973
    return (const WOLFSSL_v3_ext_method*)&ex->ext_method;
1974
#else
1975
    return (WOLFSSL_v3_ext_method*)&ex->ext_method;
1976
#endif
1977
}
1978
1979
/* Create an Authority Info Access (AIA) from the contents of the extension.
1980
 *
1981
 * AIA is a stack of Access Descriptions.
1982
 *
1983
 * RFC 5280: 4.2.2.1
1984
 *
1985
 * @param [in] ext  X509v3 extension.
1986
 * @return  Stack of Access Descriptions as an AIA on success.
1987
 * @return  NULL on error.
1988
 */
1989
static WOLFSSL_AUTHORITY_INFO_ACCESS* wolfssl_x509v3_ext_aia_d2i(
1990
    WOLFSSL_X509_EXTENSION* ext)
1991
{
1992
    int err = 0;
1993
    int ret;
1994
    WOLFSSL_AUTHORITY_INFO_ACCESS* aia = NULL;
1995
    WOLFSSL_STACK* sk;
1996
    WOLFSSL_ACCESS_DESCRIPTION* ad = NULL;
1997
1998
    /* Get the type specific data of this extension. */
1999
    sk = ext->ext_sk;
2000
    if (sk == NULL) {
2001
        WOLFSSL_MSG("ACCESS_DESCRIPTION stack NULL");
2002
        err = 1;
2003
    }
2004
2005
    if (!err) {
2006
        /* AUTHORITY_INFO_ACCESS is a stack of ACCESS_DESCRIPTION entries. */
2007
        aia = wolfSSL_sk_new_null();
2008
        if (aia == NULL) {
2009
            WOLFSSL_MSG("Failed to malloc AUTHORITY_INFO_ACCESS");
2010
            err = 1;
2011
        }
2012
    }
2013
    if (!err) {
2014
        /* AIA is a stack of Access Descriptions. */
2015
        aia->type = STACK_TYPE_ACCESS_DESCRIPTION;
2016
    }
2017
2018
    while ((!err) && (sk != NULL)) {
2019
        WOLFSSL_ASN1_OBJECT* aiaEntry;
2020
2021
        /* Looking for objects in extension's data. */
2022
        if (sk->type != STACK_TYPE_OBJ) {
2023
            sk = sk->next;
2024
            continue;
2025
        }
2026
2027
        /* Get ASN.1 Object from the stack entry's data. */
2028
        aiaEntry = sk->data.obj;
2029
2030
        /* ACCESS_DESCRIPTION has two members: method and location.
2031
         *  method: ASN1_OBJECT as either AIA_OCSP_OID or AIA_CA_ISSUER_OID
2032
         *  location: GENERAL_NAME structure containing the URI.
2033
         */
2034
2035
        /* Allocate a new Access Description. */
2036
        ad = (WOLFSSL_ACCESS_DESCRIPTION*)XMALLOC(
2037
            sizeof(WOLFSSL_ACCESS_DESCRIPTION), NULL, DYNAMIC_TYPE_X509_EXT);
2038
        if (ad == NULL) {
2039
            WOLFSSL_MSG("Failed to malloc ACCESS_DESCRIPTION");
2040
            err = 1;
2041
            break;
2042
        }
2043
        XMEMSET(ad, 0, sizeof(WOLFSSL_ACCESS_DESCRIPTION));
2044
2045
        /* Create new ASN1_OBJECT from NID. */
2046
        ad->method = wolfSSL_OBJ_nid2obj(aiaEntry->nid);
2047
        if (ad->method == NULL) {
2048
            WOLFSSL_MSG("OBJ_nid2obj() failed");
2049
            err = 1;
2050
            break;
2051
        }
2052
2053
        /* Allocate memory for GENERAL NAME. */
2054
        ad->location = wolfSSL_GENERAL_NAME_new();
2055
        if (ad->location == NULL) {
2056
            WOLFSSL_MSG("Failed to malloc GENERAL_NAME");
2057
            err = 1;
2058
            break;
2059
        }
2060
2061
        /* Set the type of general name to URI (only type supported). */
2062
        ret = wolfSSL_GENERAL_NAME_set_type(ad->location, WOLFSSL_GEN_URI);
2063
        if (ret != WOLFSSL_SUCCESS) {
2064
            err = 1;
2065
            break;
2066
        }
2067
2068
        /* Set the URI into GENERAL_NAME. */
2069
        ret = wolfSSL_ASN1_STRING_set(ad->location->d.uniformResourceIdentifier,
2070
            aiaEntry->obj, aiaEntry->objSz);
2071
        if (ret != WOLFSSL_SUCCESS) {
2072
            WOLFSSL_MSG("ASN1_STRING_set() failed");
2073
            err = 1;
2074
            break;
2075
        }
2076
        /* Push onto AUTHORITY_INFO_ACCESS stack. */
2077
        ret = wolfSSL_sk_ACCESS_DESCRIPTION_push(aia, ad) > 0
2078
                ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
2079
        if (ret != WOLFSSL_SUCCESS) {
2080
            WOLFSSL_MSG("Error pushing ASN1 AD onto stack");
2081
            err = 1;
2082
            break;
2083
        }
2084
        /* Set to NULL so that it doesn't get freed now it is in AIA stack. */
2085
        ad = NULL;
2086
2087
        sk = sk->next;
2088
    }
2089
2090
    if (err) {
2091
        /* Dispose of Access Description if not put in stack. */
2092
        if (ad != NULL) {
2093
            wolfSSL_ASN1_OBJECT_free(ad->method);
2094
            wolfSSL_GENERAL_NAME_free(ad->location);
2095
            XFREE(ad, NULL, DYNAMIC_TYPE_X509_EXT);
2096
        }
2097
        /* Dispose of incomplete Access Description stack. */
2098
        wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(aia, NULL);
2099
        aia = NULL;
2100
    }
2101
    return aia;
2102
}
2103
2104
/* Parses and returns an x509v3 extension internal structure.
2105
 *
2106
 * ext   : The X509_EXTENSION for parsing internal structure. If extension is
2107
 * not NULL, get the NID of the extension object and create a new
2108
 * extension-specific internal structure based on the extension type.
2109
 *
2110
 * Returns NULL on error or if NID is not found, otherwise returns a pointer to
2111
 * the extension type-specific X509_EXTENSION internal structure.
2112
 * Return is expected to be free'd by caller.
2113
 */
2114
void* wolfSSL_X509V3_EXT_d2i(WOLFSSL_X509_EXTENSION* ext)
2115
{
2116
    const WOLFSSL_v3_ext_method* method;
2117
    int ret;
2118
    WOLFSSL_ASN1_OBJECT* object;
2119
    WOLFSSL_BASIC_CONSTRAINTS* bc;
2120
    WOLFSSL_AUTHORITY_KEYID* akey;
2121
    WOLFSSL_ASN1_STRING* asn1String = NULL, *newString = NULL;
2122
    WOLFSSL_STACK* sk;
2123
    void *data = NULL;
2124
    WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
2125
2126
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_d2i");
2127
2128
    if (ext == NULL) {
2129
        WOLFSSL_MSG("Bad function Argument");
2130
        return NULL;
2131
    }
2132
2133
    object = wolfSSL_X509_EXTENSION_get_object(ext);
2134
    if (object == NULL) {
2135
        WOLFSSL_MSG("X509_EXTENSION_get_object failed");
2136
        return NULL;
2137
    }
2138
    /* extract extension info */
2139
    method = wolfSSL_X509V3_EXT_get(ext);
2140
    if (method == NULL) {
2141
        WOLFSSL_MSG("wolfSSL_X509V3_EXT_get error");
2142
        return NULL;
2143
    }
2144
2145
#ifdef WOLFSSL_SMALL_STACK
2146
    cert = (DecodedCert *)XMALLOC(sizeof(*cert), NULL,
2147
            DYNAMIC_TYPE_X509_EXT);
2148
    if (cert == NULL) {
2149
        WOLFSSL_MSG("\tout of memory");
2150
        return NULL;
2151
    }
2152
#endif
2153
2154
    InitDecodedCert(cert, NULL, 0, NULL);
2155
2156
    if ((object->type != WC_NID_basic_constraints) &&
2157
        (object->type != WC_NID_subject_alt_name) &&
2158
        (object->type != WC_NID_info_access)) {
2159
2160
        asn1String = wolfSSL_X509_EXTENSION_get_data_internal(ext);
2161
        if (asn1String == NULL) {
2162
            WOLFSSL_MSG("X509_EXTENSION_get_data() failed");
2163
            goto out;
2164
        }
2165
2166
        ret = DecodeExtensionType((const byte*)asn1String->data,
2167
                asn1String->length, object->type, (byte)ext->crit, cert, NULL);
2168
        if (ret != 0) {
2169
            WOLFSSL_MSG("DecodeExtensionType() failed");
2170
            goto out;
2171
        }
2172
    }
2173
2174
    /* Return pointer to proper internal structure based on NID */
2175
    switch (object->type) {
2176
        /* basicConstraints */
2177
        case WC_NID_basic_constraints:
2178
            WOLFSSL_MSG("basicConstraints");
2179
            /* Allocate new BASIC_CONSTRAINTS structure */
2180
            bc = wolfSSL_BASIC_CONSTRAINTS_new();
2181
            if (bc == NULL) {
2182
                WOLFSSL_MSG("Failed to malloc basic constraints");
2183
                break;
2184
            }
2185
            /* Copy pathlen and CA into BASIC_CONSTRAINTS from object */
2186
            bc->ca = object->ca;
2187
            /* RFC 5280 4.2.1.9:
2188
             *   "A pathLenConstraint of zero indicates that no non-self-issued
2189
             *    intermediate CA certificates may follow in a valid
2190
             *    certification path."
2191
             * Check for length of 0 or greater.
2192
             */
2193
            if ((object->pathlen != NULL) && (object->pathlen->length >= 0)) {
2194
                bc->pathlen = wolfSSL_ASN1_INTEGER_dup(object->pathlen);
2195
                if (bc->pathlen == NULL) {
2196
                    WOLFSSL_MSG("Failed to duplicate ASN1_INTEGER");
2197
                    wolfSSL_BASIC_CONSTRAINTS_free(bc);
2198
                    break;
2199
                }
2200
            }
2201
            else
2202
                bc->pathlen = NULL;
2203
2204
            data = bc;
2205
            break;
2206
2207
        /* subjectKeyIdentifier */
2208
        case WC_NID_subject_key_identifier:
2209
        {
2210
            WOLFSSL_MSG("subjectKeyIdentifier");
2211
2212
            newString = wolfSSL_ASN1_STRING_new();
2213
            if (newString == NULL) {
2214
                WOLFSSL_MSG("Failed to malloc ASN1_STRING");
2215
                break;
2216
            }
2217
            ret = wolfSSL_ASN1_STRING_set(newString, cert->extSubjKeyId,
2218
                                          cert->extSubjKeyIdSz);
2219
            if (ret != WOLFSSL_SUCCESS) {
2220
                WOLFSSL_MSG("ASN1_STRING_set() failed");
2221
                wolfSSL_ASN1_STRING_free(newString);
2222
                break;
2223
            };
2224
2225
            newString->type = asn1String->type;
2226
            data = newString;
2227
            break;
2228
        }
2229
2230
        /* authorityKeyIdentifier */
2231
        case WC_NID_authority_key_identifier:
2232
        {
2233
            WOLFSSL_MSG("AuthorityKeyIdentifier");
2234
2235
            akey = (WOLFSSL_AUTHORITY_KEYID*)
2236
                    XMALLOC(sizeof(WOLFSSL_AUTHORITY_KEYID), NULL,
2237
                    DYNAMIC_TYPE_X509_EXT);
2238
            if (akey == NULL) {
2239
                WOLFSSL_MSG("Failed to malloc authority key id");
2240
                break;
2241
            }
2242
2243
            XMEMSET(akey, 0, sizeof(WOLFSSL_AUTHORITY_KEYID));
2244
2245
            akey->keyid = wolfSSL_ASN1_STRING_new();
2246
            if (akey->keyid == NULL) {
2247
                WOLFSSL_MSG("ASN1_STRING_new() failed");
2248
                wolfSSL_AUTHORITY_KEYID_free(akey);
2249
                break;
2250
            }
2251
2252
            ret = wolfSSL_ASN1_STRING_set(akey->keyid, cert->extAuthKeyId,
2253
                                          cert->extAuthKeyIdSz);
2254
            if (ret != WOLFSSL_SUCCESS) {
2255
                WOLFSSL_MSG("ASN1_STRING_set() failed");
2256
                wolfSSL_AUTHORITY_KEYID_free(akey);
2257
                break;
2258
            };
2259
            akey->keyid->type   = asn1String->type;
2260
2261
            /* For now, set issuer and serial to NULL. This may need to be
2262
                updated for future use */
2263
            akey->issuer = NULL;
2264
            akey->serial = NULL;
2265
2266
            data = akey;
2267
            break;
2268
        }
2269
2270
        /* keyUsage */
2271
        case WC_NID_key_usage:
2272
        {
2273
            WOLFSSL_MSG("keyUsage");
2274
2275
            /* This may need to be updated for future use. The i2v method for
2276
                keyUsage is not currently set. For now, return the ASN1_STRING
2277
                representation of KeyUsage bit string */
2278
            newString = wolfSSL_ASN1_STRING_new();
2279
            if (newString == NULL) {
2280
                WOLFSSL_MSG("Failed to malloc ASN1_STRING");
2281
                break;
2282
            }
2283
            ret = wolfSSL_ASN1_STRING_set(newString, (byte*)&cert->extKeyUsage,
2284
                                                                sizeof(word16));
2285
            if (ret != WOLFSSL_SUCCESS) {
2286
                WOLFSSL_MSG("ASN1_STRING_set() failed");
2287
                wolfSSL_ASN1_STRING_free(newString);
2288
                break;
2289
            };
2290
            newString->type = asn1String->type;
2291
            data = newString;
2292
            break;
2293
        }
2294
2295
        /* extKeyUsage */
2296
        case WC_NID_ext_key_usage:
2297
            WOLFSSL_MSG("extKeyUsage not supported yet");
2298
            break;
2299
2300
        /* certificatePolicies */
2301
        case WC_NID_certificate_policies:
2302
            WOLFSSL_MSG("certificatePolicies not supported yet");
2303
            break;
2304
2305
        /* cRLDistributionPoints */
2306
        case WC_NID_crl_distribution_points:
2307
            WOLFSSL_MSG("cRLDistributionPoints not supported yet");
2308
            break;
2309
2310
        case WC_NID_subject_alt_name:
2311
            if (ext->ext_sk == NULL) {
2312
                WOLFSSL_MSG("Subject alt name stack NULL");
2313
                break;
2314
            }
2315
            sk = wolfSSL_sk_dup(ext->ext_sk);
2316
            if (sk == NULL) {
2317
                WOLFSSL_MSG("Failed to duplicate subject alt names stack.");
2318
                break;
2319
            }
2320
            data = sk;
2321
            break;
2322
2323
        /* authorityInfoAccess */
2324
        case WC_NID_info_access:
2325
            WOLFSSL_MSG("AuthorityInfoAccess");
2326
            data = wolfssl_x509v3_ext_aia_d2i(ext);
2327
            break;
2328
2329
        default:
2330
            WOLFSSL_MSG("Extension NID not in table, returning NULL");
2331
            break;
2332
    }
2333
2334
out:
2335
2336
    FreeDecodedCert(cert);
2337
    WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_X509_EXT);
2338
2339
    return data;
2340
}
2341
2342
/* Looks for the extension matching the passed in nid
2343
 *
2344
 * x509 : certificate to get parse through for extension.
2345
 * nid : Extension OID to be found.
2346
 * lastPos : Start search from extension after lastPos.
2347
 *           Set to -1 to search from index 0.
2348
 * return >= 0 If successful the extension index is returned.
2349
 * return WOLFSSL_FATAL_ERROR If extension is not found or error is encountered.
2350
 */
2351
int wolfSSL_X509_get_ext_by_NID(const WOLFSSL_X509* x509, int nid, int lastPos)
2352
{
2353
    int extCount = 0, length = 0, outSz = 0, sz = 0, ret = 0;
2354
    int isSet = 0, found = 0, loc;
2355
    const byte* rawCert;
2356
    const byte* input;
2357
    word32 oid, idx = 0, tmpIdx = 0, foundNID;
2358
    WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
2359
2360
    WOLFSSL_ENTER("wolfSSL_X509_get_ext_by_NID");
2361
2362
    if (x509 == NULL) {
2363
        WOLFSSL_MSG("\tNot passed a certificate");
2364
        return WOLFSSL_FATAL_ERROR;
2365
    }
2366
2367
    if (lastPos < -1 || (lastPos > (wolfSSL_X509_get_ext_count(x509) - 1))) {
2368
        WOLFSSL_MSG("\tBad location argument");
2369
        return WOLFSSL_FATAL_ERROR;
2370
    }
2371
2372
    loc = lastPos + 1;
2373
2374
    rawCert = wolfSSL_X509_get_der((WOLFSSL_X509*)x509, &outSz);
2375
    if (rawCert == NULL) {
2376
        WOLFSSL_MSG("\tX509_get_der() failed");
2377
        return WOLFSSL_FATAL_ERROR;
2378
    }
2379
2380
#ifdef WOLFSSL_SMALL_STACK
2381
    cert = (DecodedCert *)XMALLOC(sizeof(*cert), x509->heap,
2382
                                  DYNAMIC_TYPE_DCERT);
2383
    if (cert == NULL) {
2384
        WOLFSSL_MSG("\tout of memory");
2385
        return WOLFSSL_FATAL_ERROR;
2386
    }
2387
#endif
2388
2389
    InitDecodedCert( cert, rawCert, (word32)outSz, 0);
2390
2391
    if (ParseCert(cert,
2392
#ifdef WOLFSSL_CERT_REQ
2393
            x509->isCSR ? CERTREQ_TYPE :
2394
#endif
2395
            CA_TYPE,
2396
            NO_VERIFY, NULL) < 0) {
2397
        WOLFSSL_MSG("\tCertificate parsing failed");
2398
        goto out;
2399
    }
2400
2401
    input = cert->extensions;
2402
    sz = cert->extensionsSz;
2403
2404
    if (input == NULL || sz == 0) {
2405
        WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
2406
        goto out;
2407
    }
2408
2409
#ifdef WOLFSSL_CERT_REQ
2410
    if (!x509->isCSR)
2411
#endif
2412
    {
2413
        if (input[idx++] != ASN_EXTENSIONS) {
2414
            WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
2415
            goto out;
2416
        }
2417
2418
        if (GetLength(input, &idx, &length, (word32)sz) < 0) {
2419
            WOLFSSL_MSG("\tfail: invalid length");
2420
            goto out;
2421
        }
2422
    }
2423
2424
    if (GetSequence(input, &idx, &length, (word32)sz) < 0) {
2425
        WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
2426
        goto out;
2427
    }
2428
2429
    while (idx < (word32)sz) {
2430
        oid = 0;
2431
2432
        if (GetSequence(input, &idx, &length, (word32)sz) < 0) {
2433
            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
2434
            goto out;
2435
        }
2436
2437
        tmpIdx = idx;
2438
        ret = GetObjectId(input, &idx, &oid, oidCertExtType, (word32)sz);
2439
        if (ret < 0) {
2440
            WOLFSSL_MSG("\tfail: OBJECT ID");
2441
            goto out;
2442
        }
2443
        idx = tmpIdx;
2444
        foundNID = (word32)oid2nid(oid, oidCertExtType);
2445
2446
        if (extCount >= loc) {
2447
            /* extCount >= loc. Now check if extension has been set */
2448
            isSet = wolfSSL_X509_ext_isSet_by_NID((WOLFSSL_X509*)x509,
2449
                (int)foundNID);
2450
            if (isSet && ((word32)nid == foundNID)) {
2451
                found = 1;
2452
                break;
2453
            }
2454
        }
2455
2456
        idx += length;
2457
        extCount++;
2458
    } /* while(idx < sz) */
2459
2460
out:
2461
2462
    FreeDecodedCert(cert);
2463
    WC_FREE_VAR_EX(cert, x509->heap, DYNAMIC_TYPE_DCERT);
2464
2465
    return found ? extCount : WOLFSSL_FATAL_ERROR;
2466
}
2467
2468
#endif /* OPENSSL_ALL || OPENSSL_EXTRA */
2469
2470
#if defined(OPENSSL_EXTRA) && !defined(IGNORE_NAME_CONSTRAINTS)
2471
/*
2472
 * Convert a Base_entry linked list to a STACK of GENERAL_SUBTREE.
2473
 *
2474
 * Base_entry stores name constraint data from DecodedCert. This function
2475
 * converts it to GENERAL_SUBTREE format.
2476
 *
2477
 * Supported types: ASN_DNS_TYPE, ASN_RFC822_TYPE, ASN_DIR_TYPE, ASN_IP_TYPE,
2478
 *                  ASN_URI_TYPE
2479
 *
2480
 * Returns 0 on success, negative on error.
2481
 */
2482
static int ConvertBaseEntryToSubtreeStack(Base_entry* list, WOLFSSL_STACK* sk,
2483
                                          void* heap)
2484
{
2485
    Base_entry* entry = list;
2486
    WOLFSSL_GENERAL_SUBTREE* subtree = NULL;
2487
    WOLFSSL_GENERAL_NAME* gn = NULL;
2488
    (void)heap;
2489
2490
    while (entry != NULL) {
2491
2492
        if (entry->type != ASN_DNS_TYPE && entry->type != ASN_RFC822_TYPE &&
2493
            entry->type != ASN_DIR_TYPE && entry->type != ASN_IP_TYPE &&
2494
            entry->type != ASN_URI_TYPE) {
2495
            entry = entry->next;
2496
            continue;
2497
        }
2498
2499
        /* Allocate subtree and general name */
2500
        subtree = (WOLFSSL_GENERAL_SUBTREE*)XMALLOC(
2501
            sizeof(WOLFSSL_GENERAL_SUBTREE), heap, DYNAMIC_TYPE_OPENSSL);
2502
        if (subtree == NULL) {
2503
            WOLFSSL_MSG("Failed to allocate GENERAL_SUBTREE");
2504
            return MEMORY_E;
2505
        }
2506
        XMEMSET(subtree, 0, sizeof(WOLFSSL_GENERAL_SUBTREE));
2507
2508
        gn = wolfSSL_GENERAL_NAME_new();
2509
        if (gn == NULL) {
2510
            WOLFSSL_MSG("Failed to allocate GENERAL_NAME");
2511
            XFREE(subtree, heap, DYNAMIC_TYPE_OPENSSL);
2512
            return MEMORY_E;
2513
        }
2514
2515
        /* Free default ia5 string allocated by GENERAL_NAME_new */
2516
        wolfSSL_ASN1_STRING_free(gn->d.ia5);
2517
        gn->d.ia5 = NULL;
2518
2519
        switch (entry->type) {
2520
            case ASN_DNS_TYPE:
2521
            case ASN_RFC822_TYPE:
2522
            case ASN_URI_TYPE:
2523
            {
2524
                if (entry->type == ASN_DNS_TYPE) {
2525
                    gn->type = WOLFSSL_GEN_DNS;
2526
                }
2527
                else if (entry->type == ASN_RFC822_TYPE) {
2528
                    gn->type = WOLFSSL_GEN_EMAIL;
2529
                }
2530
                else {
2531
                    gn->type = WOLFSSL_GEN_URI;
2532
                }
2533
                gn->d.ia5 = wolfSSL_ASN1_STRING_new();
2534
                if (gn->d.ia5 == NULL) {
2535
                    WOLFSSL_MSG("Failed to allocate ASN1_STRING");
2536
                    wolfSSL_GENERAL_NAME_free(gn);
2537
                    XFREE(subtree, heap, DYNAMIC_TYPE_OPENSSL);
2538
                    return MEMORY_E;
2539
                }
2540
                if (wolfSSL_ASN1_STRING_set(gn->d.ia5, entry->name,
2541
                        entry->nameSz) != WOLFSSL_SUCCESS) {
2542
                    WOLFSSL_MSG("Failed to set ASN1_STRING");
2543
                    wolfSSL_GENERAL_NAME_free(gn);
2544
                    XFREE(subtree, heap, DYNAMIC_TYPE_OPENSSL);
2545
                    return MEMORY_E;
2546
                }
2547
                gn->d.ia5->type = WOLFSSL_V_ASN1_IA5STRING;
2548
                break;
2549
            }
2550
2551
            case ASN_DIR_TYPE:
2552
            {
2553
                byte* seqBuf = NULL;
2554
                unsigned char* p = NULL;
2555
                int seqLen = 0;
2556
2557
                /* Wrap in SEQUENCE and parse as X509_NAME */
2558
                gn->type = WOLFSSL_GEN_DIRNAME;
2559
                seqBuf = (byte*)XMALLOC((word32)entry->nameSz + MAX_SEQ_SZ,
2560
                                        heap, DYNAMIC_TYPE_TMP_BUFFER);
2561
                if (seqBuf == NULL) {
2562
                    WOLFSSL_MSG("Failed to allocate sequence buffer");
2563
                    wolfSSL_GENERAL_NAME_free(gn);
2564
                    XFREE(subtree, heap, DYNAMIC_TYPE_OPENSSL);
2565
                    return MEMORY_E;
2566
                }
2567
2568
                seqLen = SetSequence(entry->nameSz, seqBuf);
2569
                XMEMCPY(seqBuf + seqLen, entry->name, entry->nameSz);
2570
2571
                p = seqBuf;
2572
                gn->d.directoryName = wolfSSL_d2i_X509_NAME(NULL, &p,
2573
                    (long)entry->nameSz + seqLen);
2574
                XFREE(seqBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
2575
2576
                if (gn->d.directoryName == NULL) {
2577
                    WOLFSSL_MSG("Failed to parse directoryName");
2578
                    wolfSSL_GENERAL_NAME_free(gn);
2579
                    XFREE(subtree, heap, DYNAMIC_TYPE_OPENSSL);
2580
                    return ASN_PARSE_E;
2581
                }
2582
                break;
2583
            }
2584
2585
            case ASN_IP_TYPE:
2586
            {
2587
                /* For IP address, store raw bytes as OCTET_STRING. */
2588
                gn->type = WOLFSSL_GEN_IPADD;
2589
                gn->d.iPAddress = wolfSSL_ASN1_STRING_new();
2590
                if (gn->d.iPAddress == NULL) {
2591
                    WOLFSSL_MSG("Failed to allocate ASN1_STRING for IP");
2592
                    wolfSSL_GENERAL_NAME_free(gn);
2593
                    XFREE(subtree, heap, DYNAMIC_TYPE_OPENSSL);
2594
                    return MEMORY_E;
2595
                }
2596
                if (wolfSSL_ASN1_STRING_set(gn->d.iPAddress, entry->name,
2597
                        entry->nameSz) != WOLFSSL_SUCCESS) {
2598
                    WOLFSSL_MSG("Failed to set IP ASN1_STRING");
2599
                    wolfSSL_GENERAL_NAME_free(gn);
2600
                    XFREE(subtree, heap, DYNAMIC_TYPE_OPENSSL);
2601
                    return MEMORY_E;
2602
                }
2603
                gn->d.iPAddress->type = WOLFSSL_V_ASN1_OCTET_STRING;
2604
                break;
2605
            }
2606
        }
2607
2608
        subtree->base = gn;
2609
2610
        if (wolfSSL_sk_push(sk, subtree) <= 0) {
2611
            WOLFSSL_MSG("Failed to push subtree onto stack");
2612
            wolfSSL_GENERAL_NAME_free(gn);
2613
            XFREE(subtree, heap, DYNAMIC_TYPE_OPENSSL);
2614
            return MEMORY_E;
2615
        }
2616
        entry = entry->next;
2617
    }
2618
2619
    return 0;
2620
}
2621
#endif /* OPENSSL_EXTRA && !IGNORE_NAME_CONSTRAINTS */
2622
2623
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
2624
/* Looks for the extension matching the passed in nid
2625
 *
2626
 * c   : if not null then is set to status value -2 if multiple occurrences
2627
 *       of the extension are found, -1 if not found, 0 if found and not
2628
 *       critical, and 1 if found and critical.
2629
 * nid : Extension OID to be found.
2630
 * idx : if NULL return first extension found match, otherwise start search at
2631
 *       idx location and set idx to the location of extension returned.
2632
 * returns NULL or a pointer to an WOLFSSL_ASN1_BIT_STRING (for KEY_USAGE_OID)
2633
 * or WOLFSSL_STACK (for other)
2634
 * holding extension structure
2635
 *
2636
 * NOTE code for decoding extensions is in asn.c DecodeCertExtensions --
2637
 * use already decoded extension in this function to avoid decoding twice.
2638
 * Currently we do not make use of idx since getting pre decoded extensions.
2639
 */
2640
void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c,
2641
    int* idx)
2642
{
2643
    void* ret = NULL;
2644
    WOLFSSL_STACK* sk = NULL;
2645
    WOLFSSL_ASN1_OBJECT* obj = NULL;
2646
    WOLFSSL_GENERAL_NAME* gn = NULL;
2647
#ifdef OPENSSL_EXTRA
2648
    WOLFSSL_DIST_POINT* dp = NULL;
2649
#endif
2650
    WOLFSSL_BASIC_CONSTRAINTS* bc = NULL;
2651
2652
    WOLFSSL_ENTER("wolfSSL_X509_get_ext_d2i");
2653
2654
    if (x509 == NULL) {
2655
        return NULL;
2656
    }
2657
2658
    if (c != NULL) {
2659
        *c = -1; /* default to not found */
2660
    }
2661
2662
    switch (nid) {
2663
        case BASIC_CA_OID:
2664
            if (x509->basicConstSet) {
2665
                bc = wolfSSL_BASIC_CONSTRAINTS_new();
2666
                if (!bc) {
2667
                    WOLFSSL_MSG("wolfSSL_BASIC_CONSTRAINTS_new error");
2668
                    return NULL;
2669
                }
2670
2671
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) || \
2672
        defined(WOLFSSL_APACHE_HTTPD)
2673
                bc->ca = x509->isCa;
2674
#endif
2675
                /* RFC 5280 4.2.1.9: only populate pathLen when the
2676
                 * pathLenConstraint field was present. When absent, no limit
2677
                 * is imposed and pathlen must remain NULL so it is
2678
                 * distinguishable from a pathLenConstraint of 0. */
2679
                if (x509->basicConstPlSet) {
2680
                    WOLFSSL_ASN1_INTEGER* a = wolfSSL_ASN1_INTEGER_new();
2681
                    if (a == NULL) {
2682
                        WOLFSSL_MSG("wolfSSL_ASN1_INTEGER_new error");
2683
                        wolfSSL_BASIC_CONSTRAINTS_free(bc);
2684
                        return NULL;
2685
                    }
2686
                    a->length = (int)x509->pathLength;
2687
                    bc->pathlen = a;
2688
                }
2689
2690
                if (c != NULL) {
2691
                    *c = x509->basicConstCrit;
2692
                }
2693
            }
2694
            else {
2695
                WOLFSSL_MSG("No Basic Constraint set");
2696
            }
2697
            return bc;
2698
2699
        case ALT_NAMES_OID:
2700
        {
2701
            DNS_entry* dns = NULL;
2702
2703
            if (x509->subjAltNameSet && x509->altNames != NULL) {
2704
                /* Malloc GENERAL_NAME stack */
2705
                sk = wolfSSL_sk_new_null();
2706
                if (sk == NULL)
2707
                    return NULL;
2708
                sk->type = STACK_TYPE_GEN_NAME;
2709
2710
                /* alt names are DNS_entry structs */
2711
                if (c != NULL) {
2712
                    if (x509->altNames->next != NULL) {
2713
                        *c = -2; /* more then one found */
2714
                    }
2715
                    else {
2716
                        *c = x509->subjAltNameCrit;
2717
                    }
2718
                }
2719
2720
                dns = x509->altNames;
2721
                /* Currently only support GEN_DNS type */
2722
                while (dns != NULL) {
2723
                    gn = wolfSSL_GENERAL_NAME_new();
2724
                    if (gn == NULL) {
2725
                        WOLFSSL_MSG("Error creating GENERAL_NAME");
2726
                        goto err;
2727
                    }
2728
2729
                    switch (dns->type) {
2730
                        case ASN_DIR_TYPE:
2731
                            gn->type = dns->type;
2732
                            {
2733
                                int localIdx = 0;
2734
                                unsigned char* n = (unsigned char*)XMALLOC(
2735
                                        dns->len + MAX_SEQ_SZ, x509->heap,
2736
                                        DYNAMIC_TYPE_TMP_BUFFER);
2737
                                if (n == NULL) {
2738
                                    goto err;
2739
                                }
2740
2741
                                localIdx += SetSequence(dns->len, n);
2742
                                XMEMCPY(n + localIdx, dns->name, dns->len);
2743
                                gn->d.dirn =  wolfSSL_d2i_X509_NAME(NULL, &n,
2744
                                        dns->len + localIdx);
2745
                                XFREE(n, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
2746
                                if (gn->d.dirn == NULL) {
2747
                                    WOLFSSL_MSG("Convert altDirName to X509 "
2748
                                            "NAME failed");
2749
                                    goto err;
2750
                                }
2751
                            }
2752
                            break;
2753
2754
                        case ASN_OTHER_TYPE:
2755
                            /* gn->type set internally */
2756
                            if (!wolfssl_dns_entry_othername_to_gn(dns, gn)) {
2757
                                goto err;
2758
                            }
2759
                            break;
2760
2761
                        case ASN_IP_TYPE:
2762
                            gn->type = dns->type;
2763
                            if (wolfSSL_ASN1_STRING_set(gn->d.iPAddress,
2764
                                    dns->name, dns->len) != WOLFSSL_SUCCESS) {
2765
                                WOLFSSL_MSG("ASN1_STRING_set failed");
2766
                                goto err;
2767
                            }
2768
                            gn->d.iPAddress->type = WOLFSSL_V_ASN1_OCTET_STRING;
2769
                            break;
2770
2771
                        case ASN_RID_TYPE:
2772
                            /* Always handle registeredID: the union
2773
                             * member d.registeredID is populated from
2774
                             * raw OID body bytes. WOLFSSL_RID_ALT_NAME
2775
                             * only gates the human-readable ridString,
2776
                             * which this path does not need. */
2777
                            gn->type = dns->type;
2778
                            /* Free ia5 before using union for registeredID */
2779
                            wolfSSL_ASN1_STRING_free(gn->d.ia5);
2780
                            gn->d.ia5 = NULL;
2781
2782
                            gn->d.registeredID = wolfSSL_ASN1_OBJECT_new();
2783
                            if (gn->d.registeredID == NULL) {
2784
                                goto err;
2785
                            }
2786
                            {
2787
                                /* Store DER-encoded OID (tag+length+content) */
2788
                                word32 derSz = 1 + SetLength(dns->len, NULL)
2789
                                               + dns->len;
2790
                                byte* der = (byte*)XMALLOC(derSz,
2791
                                    gn->d.registeredID->heap,
2792
                                    DYNAMIC_TYPE_ASN1);
2793
                                if (der == NULL) {
2794
                                    goto err;
2795
                                }
2796
                                {
2797
                                    word32 derIdx = 0;
2798
                                    der[derIdx++] = ASN_OBJECT_ID;
2799
                                    derIdx += SetLength(dns->len, der + derIdx);
2800
                                    XMEMCPY(der + derIdx, dns->name, dns->len);
2801
                                }
2802
                                gn->d.registeredID->obj = der;
2803
                                gn->d.registeredID->objSz = derSz;
2804
                            }
2805
                            gn->d.registeredID->dynamic |=
2806
                                WOLFSSL_ASN1_DYNAMIC_DATA;
2807
                            gn->d.registeredID->grp = oidCertExtType;
2808
                            break;
2809
2810
                        default:
2811
                            gn->type = dns->type;
2812
                            if (wolfSSL_ASN1_STRING_set(gn->d.dNSName,
2813
                                    dns->name, dns->len) != WOLFSSL_SUCCESS) {
2814
                                WOLFSSL_MSG("ASN1_STRING_set failed");
2815
                                goto err;
2816
                            }
2817
                            gn->d.dNSName->type = WOLFSSL_V_ASN1_IA5STRING;
2818
                    }
2819
2820
                    dns = dns->next;
2821
                    /* Using wolfSSL_sk_insert to maintain backwards
2822
                     * compatibility with earlier versions of _push API that
2823
                     * pushed items to the start of the list instead of the
2824
                     * end. */
2825
                    if (wolfSSL_sk_insert(sk, gn, 0) <= 0) {
2826
                        WOLFSSL_MSG("Error pushing ASN1 object onto stack");
2827
                        goto err;
2828
                    }
2829
                    /* null so that it doesn't get pushed again after switch */
2830
                    gn = NULL;
2831
                }
2832
            }
2833
            else {
2834
                WOLFSSL_MSG("No Alt Names set");
2835
            }
2836
2837
            break;
2838
        }
2839
2840
        case CRL_DIST_OID:
2841
    #if defined(OPENSSL_EXTRA)
2842
            if (x509->CRLdistSet && x509->CRLInfo != NULL) {
2843
                if (c != NULL) {
2844
                    *c = x509->CRLdistCrit;
2845
                }
2846
2847
                sk = wolfSSL_sk_new_null();
2848
                if (sk == NULL) {
2849
                    return NULL;
2850
                }
2851
                sk->type = STACK_TYPE_DIST_POINT;
2852
2853
                gn = wolfSSL_GENERAL_NAME_new();
2854
                if (gn == NULL) {
2855
                    WOLFSSL_MSG("Error creating GENERAL_NAME");
2856
                    goto err;
2857
                }
2858
2859
                if (wolfSSL_GENERAL_NAME_set_type(gn, WOLFSSL_GEN_URI) !=
2860
                        WOLFSSL_SUCCESS) {
2861
                    WOLFSSL_MSG("Error setting GENERAL_NAME type");
2862
                    goto err;
2863
                }
2864
2865
                if (wolfSSL_ASN1_STRING_set(gn->d.uniformResourceIdentifier,
2866
                        x509->CRLInfo, x509->CRLInfoSz) != WOLFSSL_SUCCESS) {
2867
                    WOLFSSL_MSG("ASN1_STRING_set failed");
2868
                    goto err;
2869
                }
2870
2871
                /* wolfSSL only decodes one dist point */
2872
                dp = wolfSSL_DIST_POINT_new();
2873
                if (dp == NULL) {
2874
                    WOLFSSL_MSG("Error creating DIST_POINT");
2875
                    goto err;
2876
                }
2877
2878
                /* push GENERAL_NAME onto fullname stack */
2879
                if (wolfSSL_sk_GENERAL_NAME_push(dp->distpoint->name.fullname,
2880
                                                 gn) <= 0) {
2881
                    WOLFSSL_MSG("wolfSSL_sk_GENERAL_NAME_push error");
2882
                    goto err;
2883
                }
2884
                /* gn now owned by stack. */
2885
                gn = NULL;
2886
2887
                /* push DIST_POINT onto stack */
2888
                if (wolfSSL_sk_DIST_POINT_push(sk, dp) <= 0) {
2889
                    WOLFSSL_MSG("Error pushing DIST_POINT onto stack");
2890
                    goto err;
2891
                }
2892
                /* dp now owned by stack. */
2893
                dp = NULL;
2894
2895
            }
2896
            else {
2897
                WOLFSSL_MSG("No CRL dist set");
2898
            }
2899
    #endif /* OPENSSL_EXTRA */
2900
            break;
2901
2902
        case AUTH_INFO_OID:
2903
            if (x509->authInfoSet && x509->authInfo != NULL) {
2904
                if (c != NULL) {
2905
                    *c = x509->authInfoCrit;
2906
                }
2907
                obj = wolfSSL_ASN1_OBJECT_new();
2908
                if (obj == NULL) {
2909
                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
2910
                    return NULL;
2911
                }
2912
                obj->type  = AUTH_INFO_OID;
2913
                obj->grp   = oidCertExtType;
2914
                obj->obj   = x509->authInfo;
2915
                obj->objSz = (unsigned int)x509->authInfoSz;
2916
            }
2917
            else {
2918
                WOLFSSL_MSG("No Auth Info set");
2919
            }
2920
            break;
2921
2922
        case AUTH_KEY_OID:
2923
            if (x509->authKeyIdSet) {
2924
                WOLFSSL_AUTHORITY_KEYID* akey = wolfSSL_AUTHORITY_KEYID_new();
2925
                if (!akey) {
2926
                    WOLFSSL_MSG(
2927
                        "Issue creating WOLFSSL_AUTHORITY_KEYID struct");
2928
                    return NULL;
2929
                }
2930
2931
                if (c != NULL) {
2932
                    *c = x509->authKeyIdCrit;
2933
                }
2934
                obj = wolfSSL_ASN1_OBJECT_new();
2935
                if (obj == NULL) {
2936
                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
2937
                    wolfSSL_AUTHORITY_KEYID_free(akey);
2938
                    return NULL;
2939
                }
2940
                obj->type  = AUTH_KEY_OID;
2941
                obj->grp   = oidCertExtType;
2942
                obj->obj   = x509->authKeyId;
2943
                obj->objSz = x509->authKeyIdSz;
2944
                akey->issuer = obj;
2945
                return akey;
2946
            }
2947
            else {
2948
                WOLFSSL_MSG("No Auth Key set");
2949
            }
2950
            break;
2951
2952
        case SUBJ_KEY_OID:
2953
            if (x509->subjKeyIdSet) {
2954
                if (c != NULL) {
2955
                    *c = x509->subjKeyIdCrit;
2956
                }
2957
                obj = wolfSSL_ASN1_OBJECT_new();
2958
                if (obj == NULL) {
2959
                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
2960
                    return NULL;
2961
                }
2962
                obj->type  = SUBJ_KEY_OID;
2963
                obj->grp   = oidCertExtType;
2964
                obj->obj   = x509->subjKeyId;
2965
                obj->objSz = x509->subjKeyIdSz;
2966
            }
2967
            else {
2968
                WOLFSSL_MSG("No Subject Key set");
2969
            }
2970
            break;
2971
2972
        case CERT_POLICY_OID:
2973
        {
2974
        #ifdef WOLFSSL_CERT_EXT
2975
            int i;
2976
2977
            if (x509->certPoliciesNb > 0) {
2978
                if (c != NULL) {
2979
                    if (x509->certPoliciesNb > 1) {
2980
                        *c = -2;
2981
                    }
2982
                    else {
2983
                        *c = 0;
2984
                    }
2985
                }
2986
2987
                sk = wolfSSL_sk_new_asn1_obj();
2988
                if (sk == NULL) {
2989
                    return NULL;
2990
                }
2991
2992
                for (i = 0; i < x509->certPoliciesNb - 1; i++) {
2993
                    obj = wolfSSL_ASN1_OBJECT_new();
2994
                    if (obj == NULL) {
2995
                        WOLFSSL_MSG(
2996
                            "Issue creating WOLFSSL_ASN1_OBJECT struct");
2997
                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
2998
                        return NULL;
2999
                    }
3000
                    obj->type  = CERT_POLICY_OID;
3001
                    obj->grp   = oidCertExtType;
3002
                    obj->obj   = (byte*)(x509->certPolicies[i]);
3003
                    obj->objSz = MAX_CERTPOL_SZ;
3004
                    if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) <= 0) {
3005
                        WOLFSSL_MSG("Error pushing ASN1 object onto stack");
3006
                        wolfSSL_ASN1_OBJECT_free(obj);
3007
                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
3008
                        sk = NULL;
3009
                    }
3010
                }
3011
3012
                obj = wolfSSL_ASN1_OBJECT_new();
3013
                if (obj == NULL) {
3014
                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
3015
                    wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
3016
                    return NULL;
3017
                }
3018
                obj->type  = CERT_POLICY_OID;
3019
                obj->grp   = oidCertExtType;
3020
                obj->obj   = (byte*)(x509->certPolicies[i]);
3021
                obj->objSz = MAX_CERTPOL_SZ;
3022
3023
                if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) <= 0) {
3024
                    WOLFSSL_MSG("Error pushing ASN1 object onto stack");
3025
                    wolfSSL_ASN1_OBJECT_free(obj);
3026
                    wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
3027
                    sk = NULL;
3028
                }
3029
3030
                obj = NULL;
3031
            }
3032
            else {
3033
                WOLFSSL_MSG("No Cert Policy set");
3034
            }
3035
        #endif /* WOLFSSL_CERT_EXT */
3036
        #ifdef WOLFSSL_SEP
3037
            if (x509->certPolicySet) {
3038
                if (c != NULL) {
3039
                    *c = x509->certPolicyCrit;
3040
                }
3041
                obj = wolfSSL_ASN1_OBJECT_new();
3042
                if (obj == NULL) {
3043
                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
3044
                    return NULL;
3045
                }
3046
                obj->type  = CERT_POLICY_OID;
3047
                obj->grp   = oidCertExtType;
3048
            }
3049
            else {
3050
                WOLFSSL_MSG("No Cert Policy set");
3051
            }
3052
        #endif
3053
            break;
3054
        }
3055
        case KEY_USAGE_OID:
3056
        {
3057
            WOLFSSL_ASN1_STRING* asn1str = NULL;
3058
            if (x509->keyUsageSet) {
3059
                if (c != NULL) {
3060
                    *c = x509->keyUsageCrit;
3061
                }
3062
3063
                asn1str = wolfSSL_ASN1_STRING_new();
3064
                if (asn1str == NULL) {
3065
                    WOLFSSL_MSG("Failed to malloc ASN1_STRING");
3066
                    return NULL;
3067
                }
3068
3069
                if (wolfSSL_ASN1_STRING_set(asn1str, &x509->keyUsage,
3070
                        sizeof(word16)) != WOLFSSL_SUCCESS) {
3071
                    WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
3072
                    wolfSSL_ASN1_STRING_free(asn1str);
3073
                    return NULL;
3074
                }
3075
3076
                asn1str->type = KEY_USAGE_OID;
3077
            }
3078
            else {
3079
                WOLFSSL_MSG("No Key Usage set");
3080
            }
3081
            /* don't add stack of and return bit string directly */
3082
            return asn1str;
3083
        }
3084
        case INHIBIT_ANY_OID:
3085
            WOLFSSL_MSG("INHIBIT ANY extension not supported");
3086
            break;
3087
3088
        case EXT_KEY_USAGE_OID:
3089
            if (x509->extKeyUsageSrc != NULL) {
3090
                const byte* ekuSrc = x509->extKeyUsageSrc;
3091
                word32 i;
3092
3093
                sk = wolfSSL_sk_new_asn1_obj();
3094
                if (sk == NULL) {
3095
                    WOLFSSL_MSG("Issue creating stack");
3096
                    return NULL;
3097
                }
3098
3099
                for (i = 0; i < x509->extKeyUsageCount; i++) {
3100
                    long ekuSrcLen = (long)(x509->extKeyUsageSz -
3101
                            (word32)(ekuSrc - x509->extKeyUsageSrc));
3102
                    WOLFSSL_ASN1_OBJECT* ekuObj = wolfSSL_d2i_ASN1_OBJECT(NULL,
3103
                            &ekuSrc, ekuSrcLen);
3104
                    if (ekuObj == NULL) {
3105
                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
3106
                        WOLFSSL_MSG("d2i obj error");
3107
                        return NULL;
3108
                    }
3109
                    ekuObj->type  = EXT_KEY_USAGE_OID;
3110
                    ekuObj->grp   = oidCertExtType;
3111
                    /* Push to end to maintain order */
3112
                    if (wolfSSL_sk_insert(sk, ekuObj, -1) <= 0) {
3113
                        wolfSSL_ASN1_OBJECT_free(ekuObj);
3114
                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
3115
                        WOLFSSL_MSG("d2i obj error");
3116
                        return NULL;
3117
                    }
3118
                }
3119
3120
                if ((word32)(ekuSrc - x509->extKeyUsageSrc)
3121
                        != x509->extKeyUsageSz ||
3122
                        i != x509->extKeyUsageCount) {
3123
                    wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
3124
                    WOLFSSL_MSG("incorrect eku count or buffer not exhausted");
3125
                    return NULL;
3126
                }
3127
3128
                if (c != NULL) {
3129
                    if (x509->extKeyUsageCount > 1) {
3130
                        *c = -2;
3131
                    }
3132
                    else {
3133
                        *c = x509->extKeyUsageCrit;
3134
                    }
3135
                }
3136
            }
3137
            else {
3138
                WOLFSSL_MSG("No Extended Key Usage set");
3139
            }
3140
            break;
3141
3142
    #if defined(OPENSSL_EXTRA) && !defined(IGNORE_NAME_CONSTRAINTS)
3143
        case NAME_CONS_OID:
3144
        {
3145
            WOLFSSL_NAME_CONSTRAINTS* nc = NULL;
3146
3147
            /* Check if name constraints exist in stored X509 */
3148
            if (x509->permittedNames == NULL && x509->excludedNames == NULL) {
3149
                WOLFSSL_MSG("No Name Constraints set");
3150
                break;
3151
            }
3152
3153
            if (c != NULL) {
3154
                *c = x509->nameConstraintCrit;
3155
            }
3156
3157
            nc = (WOLFSSL_NAME_CONSTRAINTS*)XMALLOC(
3158
                sizeof(WOLFSSL_NAME_CONSTRAINTS), x509->heap,
3159
                DYNAMIC_TYPE_OPENSSL);
3160
            if (nc == NULL) {
3161
                WOLFSSL_MSG("Failed to allocate NAME_CONSTRAINTS");
3162
                break;
3163
            }
3164
            XMEMSET(nc, 0, sizeof(WOLFSSL_NAME_CONSTRAINTS));
3165
3166
            /* Convert permitted names */
3167
            if (x509->permittedNames != NULL) {
3168
                nc->permittedSubtrees = wolfSSL_sk_new_null();
3169
                if (nc->permittedSubtrees == NULL) {
3170
                    WOLFSSL_MSG("Failed to allocate permitted stack");
3171
                    wolfSSL_NAME_CONSTRAINTS_free(nc);
3172
                    break;
3173
                }
3174
                nc->permittedSubtrees->type = STACK_TYPE_GENERAL_SUBTREE;
3175
3176
                if (ConvertBaseEntryToSubtreeStack(x509->permittedNames,
3177
                        nc->permittedSubtrees, x509->heap) != 0) {
3178
                    WOLFSSL_MSG("Failed to convert permitted names");
3179
                    wolfSSL_NAME_CONSTRAINTS_free(nc);
3180
                    break;
3181
                }
3182
            }
3183
3184
            /* Convert excluded names */
3185
            if (x509->excludedNames != NULL) {
3186
                nc->excludedSubtrees = wolfSSL_sk_new_null();
3187
                if (nc->excludedSubtrees == NULL) {
3188
                    WOLFSSL_MSG("Failed to allocate excluded stack");
3189
                    wolfSSL_NAME_CONSTRAINTS_free(nc);
3190
                    break;
3191
                }
3192
                nc->excludedSubtrees->type = STACK_TYPE_GENERAL_SUBTREE;
3193
3194
                if (ConvertBaseEntryToSubtreeStack(x509->excludedNames,
3195
                        nc->excludedSubtrees, x509->heap) != 0) {
3196
                    WOLFSSL_MSG("Failed to convert excluded names");
3197
                    wolfSSL_NAME_CONSTRAINTS_free(nc);
3198
                    break;
3199
                }
3200
            }
3201
3202
            return nc;
3203
        }
3204
    #endif /* OPENSSL_EXTRA && !IGNORE_NAME_CONSTRAINTS */
3205
3206
        case PRIV_KEY_USAGE_PERIOD_OID:
3207
            WOLFSSL_MSG("Private Key Usage Period extension not supported");
3208
            break;
3209
3210
        case SUBJ_INFO_ACC_OID:
3211
            WOLFSSL_MSG("Subject Info Access extension not supported");
3212
            break;
3213
3214
        case POLICY_MAP_OID:
3215
            WOLFSSL_MSG("Policy Map extension not supported");
3216
            break;
3217
3218
        case POLICY_CONST_OID:
3219
            WOLFSSL_MSG("Policy Constraint extension not supported");
3220
            break;
3221
3222
        case ISSUE_ALT_NAMES_OID:
3223
            WOLFSSL_MSG("Issue Alt Names extension not supported");
3224
            break;
3225
3226
        case TLS_FEATURE_OID:
3227
            WOLFSSL_MSG("TLS Feature extension not supported");
3228
            break;
3229
3230
        default:
3231
            WOLFSSL_MSG("Unsupported/Unknown extension OID");
3232
    }
3233
3234
    /* make sure stack of is allocated */
3235
    if ((obj || gn) && sk == NULL) {
3236
        sk = wolfSSL_sk_new_asn1_obj();
3237
        if (sk == NULL) {
3238
            goto err;
3239
        }
3240
    }
3241
    if (obj) {
3242
        if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) <= 0) {
3243
            WOLFSSL_MSG("Error pushing ASN1_OBJECT object onto "
3244
                        "stack.");
3245
            goto err;
3246
        }
3247
    }
3248
3249
    ret = sk;
3250
3251
    (void)idx;
3252
3253
    return ret;
3254
3255
err:
3256
    if (obj) {
3257
        wolfSSL_ASN1_OBJECT_free(obj);
3258
    }
3259
    if (gn) {
3260
        wolfSSL_GENERAL_NAME_free(gn);
3261
    }
3262
    #ifdef OPENSSL_EXTRA
3263
    if (dp) {
3264
        wolfSSL_DIST_POINT_free(dp);
3265
    }
3266
    #endif
3267
    if (sk) {
3268
        wolfSSL_sk_pop_free(sk, NULL);
3269
    }
3270
    return NULL;
3271
}
3272
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
3273
3274
#ifdef OPENSSL_EXTRA
3275
int wolfSSL_X509_add_altname_ex(WOLFSSL_X509* x509, const char* name,
3276
        word32 nameSz, int type)
3277
{
3278
    DNS_entry* newAltName = NULL;
3279
3280
    if (x509 == NULL)
3281
        return WOLFSSL_FAILURE;
3282
3283
    if ((name == NULL) || (nameSz == 0))
3284
        return WOLFSSL_SUCCESS;
3285
3286
    /* AltNameNewEx() takes a signed length. */
3287
    if (nameSz > (word32)INT_MAX)
3288
        return WOLFSSL_FAILURE;
3289
3290
    /* One block, so nothing to unwind on failure. */
3291
    newAltName = AltNameNewEx(name, (int)nameSz, x509->heap);
3292
    if (newAltName == NULL)
3293
        return WOLFSSL_FAILURE;
3294
3295
    newAltName->next = x509->altNames;
3296
    newAltName->type = type;
3297
    x509->altNames = newAltName;
3298
3299
    return WOLFSSL_SUCCESS;
3300
}
3301
3302
int wolfSSL_X509_add_altname(WOLFSSL_X509* x509, const char* name, int type)
3303
{
3304
    word32 nameSz;
3305
3306
    if (name == NULL)
3307
        return WOLFSSL_SUCCESS;
3308
3309
    nameSz = (word32)XSTRLEN(name);
3310
    if (nameSz == 0)
3311
        return WOLFSSL_SUCCESS;
3312
3313
    if (type == ASN_IP_TYPE) {
3314
#ifdef WOLFSSL_IP_ALT_NAME
3315
        byte ip4[4];
3316
        byte ip6[16];
3317
        int ptonRet;
3318
3319
        /* Check if this is an ip4 address */
3320
    #ifdef FREESCALE_MQX
3321
        ptonRet = XINET_PTON(WOLFSSL_IP4, name, ip4, sizeof(ip4));
3322
        if (ptonRet == RTCS_OK) {
3323
    #else
3324
        ptonRet = XINET_PTON(WOLFSSL_IP4, name, ip4);
3325
        if (ptonRet == 1) {
3326
    #endif
3327
            return wolfSSL_X509_add_altname_ex(x509, (const char*)ip4, 4,
3328
                type);
3329
        }
3330
3331
        /* Check for ip6 */
3332
    #ifdef FREESCALE_MQX
3333
        ptonRet = XINET_PTON(WOLFSSL_IP6, name, ip6, sizeof(ip6));
3334
        if (ptonRet == RTCS_OK) {
3335
    #else
3336
        ptonRet = XINET_PTON(WOLFSSL_IP6, name, ip6);
3337
        if (ptonRet == 1) {
3338
    #endif
3339
            return wolfSSL_X509_add_altname_ex(x509, (const char*)ip6, 16,
3340
                type);
3341
        }
3342
3343
        WOLFSSL_MSG("IP address parse failed");
3344
        return WOLFSSL_FAILURE;
3345
#else
3346
        WOLFSSL_MSG("WOLFSSL_IP_ALT_NAME not enabled");
3347
        return WOLFSSL_FAILURE;
3348
#endif
3349
    }
3350
3351
    return wolfSSL_X509_add_altname_ex(x509, name, nameSz, type);
3352
}
3353
3354
#ifndef NO_WOLFSSL_STUB
3355
WOLFSSL_X509_EXTENSION *wolfSSL_X509_delete_ext(WOLFSSL_X509 *x509, int loc)
3356
{
3357
    WOLFSSL_STUB("wolfSSL_X509_delete_ext");
3358
    (void)x509;
3359
    (void)loc;
3360
    return NULL;
3361
}
3362
3363
/* currently LHASH is not implemented (and not needed for Apache port) */
3364
WOLFSSL_X509_EXTENSION* wolfSSL_X509V3_EXT_conf_nid(
3365
        WOLF_LHASH_OF(CONF_VALUE)* conf, WOLFSSL_X509V3_CTX* ctx, int nid,
3366
        char* value)
3367
{
3368
    WOLFSSL_STUB("wolfSSL_X509V3_EXT_conf_nid");
3369
3370
    if (conf != NULL) {
3371
        WOLFSSL_MSG("Handling LHASH not implemented yet");
3372
        return NULL;
3373
    }
3374
3375
    (void)conf;
3376
    (void)ctx;
3377
    (void)nid;
3378
    (void)value;
3379
    return NULL;
3380
}
3381
3382
void wolfSSL_X509V3_set_ctx_nodb(WOLFSSL_X509V3_CTX* ctx)
3383
{
3384
    WOLFSSL_STUB("wolfSSL_X509V3_set_ctx_nodb");
3385
    (void)ctx;
3386
}
3387
#endif /* !NO_WOLFSSL_STUB */
3388
3389
#ifdef OPENSSL_EXTRA
3390
static WOLFSSL_X509_EXTENSION* createExtFromStr(int nid, const char *value)
3391
{
3392
    WOLFSSL_X509_EXTENSION* ext;
3393
3394
    ext = wolfSSL_X509_EXTENSION_new();
3395
    if (ext == NULL) {
3396
        WOLFSSL_MSG("memory error");
3397
        return NULL;
3398
    }
3399
    ext->value.nid = nid;
3400
3401
    switch (nid) {
3402
        case WC_NID_subject_key_identifier:
3403
        case WC_NID_authority_key_identifier:
3404
            if (wolfSSL_ASN1_STRING_set(&ext->value, value, -1)
3405
                    != WOLFSSL_SUCCESS) {
3406
                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
3407
                goto err_cleanup;
3408
            }
3409
            ext->value.type = CTC_UTF8;
3410
            break;
3411
        case WC_NID_subject_alt_name:
3412
        {
3413
            WOLFSSL_GENERAL_NAMES* gns;
3414
            WOLFSSL_GENERAL_NAME* gn;
3415
3416
            if (wolfSSL_ASN1_STRING_set(&ext->value, value, -1)
3417
                    != WOLFSSL_SUCCESS) {
3418
                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
3419
                goto err_cleanup;
3420
            }
3421
            ext->value.type = ASN_DNS_TYPE;
3422
3423
            /* add stack of general names */
3424
            gns = wolfSSL_sk_new_null();
3425
            if (gns == NULL) {
3426
                WOLFSSL_MSG("wolfSSL_sk_new_null error");
3427
                goto err_cleanup;
3428
            }
3429
            ext->ext_sk = gns; /* wolfSSL_X509_EXTENSION_free will handle
3430
                                * free'ing gns */
3431
            gns->type = STACK_TYPE_GEN_NAME;
3432
            gn = wolfSSL_GENERAL_NAME_new();
3433
            if (gn == NULL) {
3434
                WOLFSSL_MSG("wolfSSL_GENERAL_NAME_new error");
3435
                goto err_cleanup;
3436
            }
3437
            if (wolfSSL_sk_GENERAL_NAME_push(gns, gn) <= 0) {
3438
                WOLFSSL_MSG("wolfSSL_sk_GENERAL_NAME_push error");
3439
                wolfSSL_GENERAL_NAME_free(gn);
3440
                goto err_cleanup;
3441
            }
3442
            if (wolfSSL_ASN1_STRING_set(gn->d.ia5, value, -1)
3443
                    != WOLFSSL_SUCCESS) {
3444
                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set failed");
3445
                goto err_cleanup;
3446
            }
3447
            gn->type = ASN_DNS_TYPE;
3448
            break;
3449
        }
3450
        case WC_NID_key_usage:
3451
            if (wolfSSL_ASN1_STRING_set(&ext->value, value, -1)
3452
                    != WOLFSSL_SUCCESS) {
3453
                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
3454
                goto err_cleanup;
3455
            }
3456
            ext->value.type = KEY_USAGE_OID;
3457
            break;
3458
        case WC_NID_ext_key_usage:
3459
            if (wolfSSL_ASN1_STRING_set(&ext->value, value, -1)
3460
                    != WOLFSSL_SUCCESS) {
3461
                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
3462
                goto err_cleanup;
3463
            }
3464
            ext->value.type = EXT_KEY_USAGE_OID;
3465
            break;
3466
        default:
3467
            WOLFSSL_MSG("invalid or unsupported NID");
3468
            goto err_cleanup;
3469
    }
3470
    return ext;
3471
err_cleanup:
3472
    wolfSSL_X509_EXTENSION_free(ext);
3473
    return NULL;
3474
}
3475
3476
/**
3477
 * Create a WOLFSSL_X509_EXTENSION from the input arguments.
3478
 * @param conf  Not used
3479
 * @param ctx   Not used
3480
 * @param nid   Interprets the value parameter as the x509 extension that
3481
 *              corresponds to this NID.
3482
 * @param value A NULL terminated string that is taken as the value of the
3483
 *              newly created extension object.
3484
 * @return WOLFSSL_X509_EXTENSION* on success or NULL on failure.
3485
 */
3486
WOLFSSL_X509_EXTENSION* wolfSSL_X509V3_EXT_nconf_nid(WOLFSSL_CONF* conf,
3487
        WOLFSSL_X509V3_CTX *ctx, int nid, const char *value)
3488
{
3489
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_nconf_nid");
3490
3491
    if (value == NULL) {
3492
        WOLFSSL_MSG("value NULL parameter");
3493
        return NULL;
3494
    }
3495
3496
    if (conf != NULL || ctx != NULL) {
3497
        WOLFSSL_MSG("wolfSSL_X509V3_EXT_nconf_nid does not handle either "
3498
                    "conf or ctx parameters");
3499
    }
3500
3501
    return createExtFromStr(nid, value);
3502
}
3503
3504
/**
3505
 * Create a WOLFSSL_X509_EXTENSION from the input arguments.
3506
 * @param conf  Not used
3507
 * @param ctx   Not used
3508
 * @param sName The textual representation of the NID that the value parameter
3509
 *              should be interpreted as.
3510
 * @param value A NULL terminated string that is taken as the value of the
3511
 *              newly created extension object.
3512
 * @return WOLFSSL_X509_EXTENSION* on success or NULL on failure.
3513
 */
3514
WOLFSSL_X509_EXTENSION* wolfSSL_X509V3_EXT_nconf(WOLFSSL_CONF *conf,
3515
        WOLFSSL_X509V3_CTX *ctx, const char *sName, const char *value)
3516
{
3517
    const WOLFSSL_ObjectInfo* info = wolfssl_object_info;
3518
    size_t i;
3519
3520
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_nconf");
3521
3522
    if (value == NULL || sName == NULL) {
3523
        WOLFSSL_MSG("NULL parameter");
3524
        return NULL;
3525
    }
3526
3527
    if (conf != NULL || ctx != NULL) {
3528
        WOLFSSL_MSG("wolfSSL_X509V3_EXT_nconf does not handle either "
3529
                    "conf or ctx parameters");
3530
    }
3531
3532
    for (i = 0; i < wolfssl_object_info_sz; i++, info++) {
3533
        if (XSTRCMP(info->sName, sName) == 0)
3534
            return createExtFromStr(info->nid, value);
3535
    }
3536
3537
    WOLFSSL_MSG("value didn't match any known NID");
3538
    return NULL;
3539
}
3540
3541
static void wolfSSL_X509V3_EXT_METHOD_populate(WOLFSSL_v3_ext_method *method,
3542
                                               int nid)
3543
{
3544
    if (!method)
3545
        return;
3546
3547
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_METHOD_populate");
3548
    switch (nid) {
3549
    case WC_NID_subject_key_identifier:
3550
        method->i2s = (WOLFSSL_X509V3_EXT_I2S)wolfSSL_i2s_ASN1_STRING;
3551
        FALL_THROUGH;
3552
    case WC_NID_authority_key_identifier:
3553
    case WC_NID_key_usage:
3554
    case WC_NID_certificate_policies:
3555
    case WC_NID_policy_mappings:
3556
    case WC_NID_subject_alt_name:
3557
    case WC_NID_issuer_alt_name:
3558
    case WC_NID_basic_constraints:
3559
    case WC_NID_name_constraints:
3560
    case WC_NID_policy_constraints:
3561
    case WC_NID_ext_key_usage:
3562
    case WC_NID_crl_distribution_points:
3563
    case WC_NID_inhibit_any_policy:
3564
    case WC_NID_info_access:
3565
        WOLFSSL_MSG("Nothing to populate for current NID");
3566
        break;
3567
    default:
3568
        WOLFSSL_MSG("Unknown or unsupported NID");
3569
        break;
3570
    }
3571
3572
    return;
3573
}
3574
3575
/**
3576
 * @param nid One of the WC_NID_* constants defined in asn.h
3577
 * @param crit
3578
 * @param data This data is copied to the returned extension.
3579
 * @return
3580
 */
3581
WOLFSSL_X509_EXTENSION *wolfSSL_X509V3_EXT_i2d(int nid, int crit,
3582
                                               void *data)
3583
{
3584
    WOLFSSL_X509_EXTENSION *ext = NULL;
3585
    WOLFSSL_ASN1_STRING* asn1str = NULL;
3586
3587
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_i2d");
3588
3589
    if (!data) {
3590
        return NULL;
3591
    }
3592
3593
    if (!(ext = wolfSSL_X509_EXTENSION_new())) {
3594
        return NULL;
3595
    }
3596
3597
    wolfSSL_X509V3_EXT_METHOD_populate(&ext->ext_method, nid);
3598
3599
    switch (nid) {
3600
    case WC_NID_subject_key_identifier:
3601
        /* WOLFSSL_ASN1_STRING */
3602
    case WC_NID_key_usage:
3603
        /* WOLFSSL_ASN1_STRING */
3604
    {
3605
        asn1str = (WOLFSSL_ASN1_STRING*)data;
3606
        ext->value = *asn1str;
3607
        if (asn1str->isDynamic) {
3608
            ext->value.data = (char*)XMALLOC(asn1str->length, NULL,
3609
                                             DYNAMIC_TYPE_OPENSSL);
3610
            if (!ext->value.data) {
3611
                WOLFSSL_MSG("malloc failed");
3612
                /* Zero so that no existing memory is freed */
3613
                XMEMSET(&ext->value, 0, sizeof(WOLFSSL_ASN1_STRING));
3614
                goto err_cleanup;
3615
            }
3616
            XMEMCPY(ext->value.data, asn1str->data, asn1str->length);
3617
        }
3618
        else {
3619
            ext->value.data = ext->value.strData;
3620
        }
3621
3622
        if (!(ext->obj = wolfSSL_OBJ_nid2obj(nid))) {
3623
            WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new failed");
3624
            goto err_cleanup;
3625
        }
3626
3627
        break;
3628
    }
3629
    case WC_NID_subject_alt_name:
3630
        /* typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES */
3631
    case WC_NID_issuer_alt_name:
3632
        /* typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES */
3633
    case WC_NID_ext_key_usage:
3634
        /* typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE */
3635
    case WC_NID_info_access:
3636
        /* typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS */
3637
    {
3638
        WOLFSSL_STACK* sk = (WOLFSSL_STACK*)data;
3639
3640
        if (ext->ext_sk) {
3641
            wolfSSL_sk_pop_free(ext->ext_sk, NULL);
3642
        }
3643
3644
        if (!(ext->ext_sk = wolfSSL_sk_dup(sk))) {
3645
            WOLFSSL_MSG("wolfSSL_sk_dup failed");
3646
            goto err_cleanup;
3647
        }
3648
3649
        if (!(ext->obj = wolfSSL_OBJ_nid2obj(nid))) {
3650
            WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new failed");
3651
            goto err_cleanup;
3652
        }
3653
3654
        break;
3655
    }
3656
    case WC_NID_basic_constraints:
3657
    {
3658
        /* WOLFSSL_BASIC_CONSTRAINTS */
3659
        WOLFSSL_BASIC_CONSTRAINTS* bc = (WOLFSSL_BASIC_CONSTRAINTS*)data;
3660
3661
        /* Build from the NID like the other cases: a bare ASN1_OBJECT has
3662
         * type 0, which wolfSSL_X509_add_ext() rejects. */
3663
        if (!(ext->obj = wolfSSL_OBJ_nid2obj(nid))) {
3664
            WOLFSSL_MSG("wolfSSL_OBJ_nid2obj failed");
3665
            goto err_cleanup;
3666
        }
3667
3668
        ext->obj->ca = bc->ca;
3669
        if (bc->pathlen) {
3670
            ext->obj->pathlen = wolfSSL_ASN1_INTEGER_dup(bc->pathlen);
3671
            if (!ext->obj->pathlen) {
3672
                WOLFSSL_MSG("wolfSSL_ASN1_INTEGER_dup failed");
3673
                goto err_cleanup;
3674
            }
3675
        }
3676
        break;
3677
    }
3678
    case WC_NID_authority_key_identifier:
3679
    {
3680
        /* AUTHORITY_KEYID */
3681
        WOLFSSL_AUTHORITY_KEYID* akey = (WOLFSSL_AUTHORITY_KEYID*)data;
3682
3683
        if (akey->keyid) {
3684
            if (wolfSSL_ASN1_STRING_set(&ext->value, akey->keyid->data,
3685
                                    akey->keyid->length) != WOLFSSL_SUCCESS) {
3686
                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set failed");
3687
                goto err_cleanup;
3688
            }
3689
            ext->value.type = akey->keyid->type;
3690
3691
            if (!(ext->obj = wolfSSL_OBJ_nid2obj(nid))) {
3692
                WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new failed");
3693
                goto err_cleanup;
3694
            }
3695
3696
        }
3697
        else if (akey->issuer) {
3698
            ext->obj = wolfSSL_ASN1_OBJECT_dup(akey->issuer);
3699
            if (!ext->obj) {
3700
                WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_dup failed");
3701
                goto err_cleanup;
3702
            }
3703
        }
3704
        else {
3705
            WOLFSSL_MSG("WC_NID_authority_key_identifier empty data");
3706
            goto err_cleanup;
3707
        }
3708
        break;
3709
    }
3710
    case WC_NID_inhibit_any_policy:
3711
        /* ASN1_INTEGER */
3712
    case WC_NID_certificate_policies:
3713
        /* STACK_OF(POLICYINFO) */
3714
    case WC_NID_policy_mappings:
3715
        /* STACK_OF(POLICY_MAPPING) */
3716
    case WC_NID_name_constraints:
3717
        /* NAME_CONSTRAINTS */
3718
    case WC_NID_policy_constraints:
3719
        /* POLICY_CONSTRAINTS */
3720
    case WC_NID_crl_distribution_points:
3721
        /* typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS */
3722
    default:
3723
        WOLFSSL_MSG("Unknown or unsupported NID");
3724
        break;
3725
    }
3726
3727
    ext->crit = crit;
3728
3729
    return ext;
3730
err_cleanup:
3731
    if (ext) {
3732
        wolfSSL_X509_EXTENSION_free(ext);
3733
    }
3734
    return NULL;
3735
}
3736
3737
/* Report whether an extension of type @nid is present in the in-memory @x509,
3738
 * based on wolfSSL's typed extension storage. Only the NIDs that
3739
 * wolfSSL_X509_add_ext() can consume have such storage.
3740
 *
3741
 * @return 1 when present, 0 when absent and -1 when @nid has no typed storage
3742
 * and presence therefore cannot be determined. */
3743
static int wolfssl_x509_ext_is_set(const WOLFSSL_X509 *x509, int nid)
3744
{
3745
    switch (nid) {
3746
    case WC_NID_subject_alt_name:
3747
        return (x509->subjAltNameSet != 0) || (x509->altNames != NULL);
3748
    case WC_NID_key_usage:
3749
        return x509->keyUsageSet != 0;
3750
    case WC_NID_ext_key_usage:
3751
        return (x509->extKeyUsage != 0) || (x509->extKeyUsageSrc != NULL);
3752
    case WC_NID_basic_constraints:
3753
        return x509->basicConstSet != 0;
3754
    case WC_NID_subject_key_identifier:
3755
        return (x509->subjKeyId != NULL) || (x509->subjKeyIdSet != 0);
3756
    case WC_NID_authority_key_identifier:
3757
        return (x509->authKeyId != NULL) || (x509->authKeyIdSet != 0);
3758
    default:
3759
        return -1;
3760
    }
3761
}
3762
3763
/* Remove the extension of type @nid from the in-memory @x509 by clearing the
3764
 * matching typed storage (mirrors the frees in FreeX509()). Every field the
3765
 * accessors for @nid look at has to be cleared, including the cached and
3766
 * "is set" flags, or the removed extension stays observable.
3767
 *
3768
 * The encoded certificate (x509->derCert) is not re-generated, so APIs that
3769
 * decode the DER again - wolfSSL_X509_get_ext_count(),
3770
 * wolfSSL_X509_get_ext_by_NID() - keep reporting the original extensions.
3771
 * That limitation is shared with wolfSSL_X509_add_ext().
3772
 *
3773
 * Returns WOLFSSL_SUCCESS if @nid is a supported, removable extension,
3774
 * otherwise WOLFSSL_FAILURE. */
3775
static int wolfssl_x509_remove_ext(WOLFSSL_X509 *x509, int nid)
3776
{
3777
    switch (nid) {
3778
    case WC_NID_subject_alt_name:
3779
        if (x509->altNames != NULL) {
3780
            FreeAltNames(x509->altNames, x509->heap);
3781
            x509->altNames = NULL;
3782
        }
3783
        /* Retrieval hint indexes into the list just freed. */
3784
        x509->altNamesNext = NULL;
3785
    #ifdef OPENSSL_ALL
3786
        XFREE(x509->subjAltNameSrc, x509->heap, DYNAMIC_TYPE_X509_EXT);
3787
        x509->subjAltNameSrc = NULL;
3788
        x509->subjAltNameSz = 0;
3789
    #endif
3790
        x509->subjAltNameSet = 0;
3791
        x509->subjAltNameCrit = 0;
3792
        break;
3793
    case WC_NID_key_usage:
3794
        x509->keyUsage = 0;
3795
        x509->keyUsageCrit = 0;
3796
        x509->keyUsageSet = 0;
3797
        break;
3798
    case WC_NID_ext_key_usage:
3799
        XFREE(x509->extKeyUsageSrc, x509->heap, DYNAMIC_TYPE_X509_EXT);
3800
        x509->extKeyUsageSrc = NULL;
3801
        x509->extKeyUsageSz = 0;
3802
        x509->extKeyUsageCount = 0;
3803
        x509->extKeyUsage = 0;
3804
        x509->extKeyUsageCrit = 0;
3805
        break;
3806
    case WC_NID_basic_constraints:
3807
        x509->isCa = 0;
3808
        x509->pathLength = 0;
3809
        x509->basicConstCrit = 0;
3810
        x509->basicConstSet = 0;
3811
        x509->basicConstPlSet = 0;
3812
        x509->pathLengthSet = 0;
3813
        break;
3814
    case WC_NID_subject_key_identifier:
3815
        XFREE(x509->subjKeyId, x509->heap, DYNAMIC_TYPE_X509_EXT);
3816
        x509->subjKeyId = NULL;
3817
        x509->subjKeyIdSz = 0;
3818
        /* Cached ASN1_STRING handed out by get0_subject_key_id(). */
3819
        wolfSSL_ASN1_STRING_free(x509->subjKeyIdStr);
3820
        x509->subjKeyIdStr = NULL;
3821
        x509->subjKeyIdSet = 0;
3822
        x509->subjKeyIdCrit = 0;
3823
        break;
3824
    case WC_NID_authority_key_identifier:
3825
        /* authKeyId may point into authKeyIdSrc; free the source first. */
3826
        if (x509->authKeyIdSrc != NULL) {
3827
            XFREE(x509->authKeyIdSrc, x509->heap, DYNAMIC_TYPE_X509_EXT);
3828
            x509->authKeyIdSrc = NULL;
3829
        }
3830
        else {
3831
            XFREE(x509->authKeyId, x509->heap, DYNAMIC_TYPE_X509_EXT);
3832
        }
3833
        x509->authKeyId = NULL;
3834
        x509->authKeyIdSz = 0;
3835
        x509->authKeyIdSrcSz = 0;
3836
        x509->authKeyIdSet = 0;
3837
        x509->authKeyIdCrit = 0;
3838
        break;
3839
    default:
3840
        WOLFSSL_MSG("Extension NID not supported for removal");
3841
        return WOLFSSL_FAILURE;
3842
    }
3843
    return WOLFSSL_SUCCESS;
3844
}
3845
3846
/**
3847
 * Encode @value as an extension of type @nid and add it to @x, honoring the
3848
 * OpenSSL X509V3_ADD_* operation selected by the low nibble of @flags:
3849
 *   X509V3_ADD_DEFAULT          - add, fail if already present
3850
 *   X509V3_ADD_APPEND           - add without checking for an existing one
3851
 *   X509V3_ADD_REPLACE          - replace any existing, else add
3852
 *   X509V3_ADD_REPLACE_EXISTING - replace, fail if not already present
3853
 *   X509V3_ADD_KEEP_EXISTING    - keep existing (no-op if present), else add
3854
 *   X509V3_ADD_DELETE           - delete existing, fail if not present
3855
 * X509V3_ADD_SILENT is accepted but inert: this function reports nothing that
3856
 * could be suppressed, and the flag never changes the result.
3857
 *
3858
 * Presence can only be determined for the extensions wolfSSL_X509_add_ext()
3859
 * stores in typed fields. For any other NID every operation except
3860
 * X509V3_ADD_APPEND - the one defined as not checking - fails.
3861
 *
3862
 * @return WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE otherwise.
3863
 */
3864
int wolfSSL_X509_add1_ext_i2d(WOLFSSL_X509 *x, int nid, void *value,
3865
                              int crit, unsigned long flags)
3866
{
3867
    WOLFSSL_X509_EXTENSION *ext = NULL;
3868
    int ret;
3869
    unsigned long op;
3870
    int exists;
3871
3872
    WOLFSSL_ENTER("wolfSSL_X509_add1_ext_i2d");
3873
3874
    if (x == NULL) {
3875
        WOLFSSL_MSG("Bad parameter");
3876
        return WOLFSSL_FAILURE;
3877
    }
3878
3879
    op = flags & WOLFSSL_X509V3_ADD_OP_MASK;
3880
    exists = wolfssl_x509_ext_is_set(x, nid);
3881
    if (exists < 0) {
3882
        if (op != WOLFSSL_X509V3_ADD_APPEND) {
3883
            WOLFSSL_MSG("Extension presence not tracked for this NID");
3884
            return WOLFSSL_FAILURE;
3885
        }
3886
        exists = 0;
3887
    }
3888
3889
    switch (op) {
3890
    case WOLFSSL_X509V3_ADD_DELETE:
3891
        if (!exists) {
3892
            WOLFSSL_MSG("No extension to delete (X509V3_ADD_DELETE)");
3893
            return WOLFSSL_FAILURE;
3894
        }
3895
        return wolfssl_x509_remove_ext(x, nid);
3896
    case WOLFSSL_X509V3_ADD_DEFAULT:
3897
        if (exists) {
3898
            WOLFSSL_MSG("Extension already present (X509V3_ADD_DEFAULT)");
3899
            return WOLFSSL_FAILURE;
3900
        }
3901
        break;
3902
    case WOLFSSL_X509V3_ADD_APPEND:
3903
    case WOLFSSL_X509V3_ADD_REPLACE:
3904
        break;
3905
    case WOLFSSL_X509V3_ADD_REPLACE_EXISTING:
3906
        if (!exists) {
3907
            WOLFSSL_MSG("No extension to replace "
3908
                        "(X509V3_ADD_REPLACE_EXISTING)");
3909
            return WOLFSSL_FAILURE;
3910
        }
3911
        break;
3912
    case WOLFSSL_X509V3_ADD_KEEP_EXISTING:
3913
        if (exists) {
3914
            /* Keep the existing extension; nothing to add. */
3915
            return WOLFSSL_SUCCESS;
3916
        }
3917
        break;
3918
    default:
3919
        WOLFSSL_MSG("Unsupported X509V3_ADD_* operation");
3920
        return WOLFSSL_FAILURE;
3921
    }
3922
3923
    if (value == NULL) {
3924
        WOLFSSL_MSG("Bad parameter");
3925
        return WOLFSSL_FAILURE;
3926
    }
3927
3928
    /* Encode the new extension before dropping the old one so that a failure
3929
     * leaves the certificate untouched. */
3930
    ext = wolfSSL_X509V3_EXT_i2d(nid, crit, value);
3931
    if (ext == NULL) {
3932
        return WOLFSSL_FAILURE;
3933
    }
3934
3935
    /* wolfSSL_X509_add_ext() dispatches on the encoded object, which for an
3936
     * authorityKeyIdentifier built from an issuer name is caller supplied.
3937
     * Refuse here rather than remove one extension and write another. */
3938
    if (((ext->obj != NULL) ? ext->obj->type : ext->value.nid) != nid) {
3939
        WOLFSSL_MSG("Encoded extension is not the requested NID");
3940
        wolfSSL_X509_EXTENSION_free(ext);
3941
        return WOLFSSL_FAILURE;
3942
    }
3943
3944
    /* wolfSSL_X509V3_EXT_i2d() copies an extKeyUsage stack without looking
3945
     * inside it, so encoding is not the check that matters here. Reject a bad
3946
     * stack before the existing extension is dropped for it. */
3947
    if ((nid == WC_NID_ext_key_usage) && (ext->value.data == NULL) &&
3948
            (ext->ext_sk != NULL)) {
3949
        word32 ekuSz = 0;
3950
        byte ekuUsage = 0;
3951
3952
        if (wolfssl_x509_eku_sk_check(ext->ext_sk, &ekuSz, &ekuUsage) !=
3953
                WOLFSSL_SUCCESS) {
3954
            wolfSSL_X509_EXTENSION_free(ext);
3955
            return WOLFSSL_FAILURE;
3956
        }
3957
    }
3958
3959
    if (exists && ((op == WOLFSSL_X509V3_ADD_REPLACE) ||
3960
                   (op == WOLFSSL_X509V3_ADD_REPLACE_EXISTING))) {
3961
        if (wolfssl_x509_remove_ext(x, nid) != WOLFSSL_SUCCESS) {
3962
            wolfSSL_X509_EXTENSION_free(ext);
3963
            return WOLFSSL_FAILURE;
3964
        }
3965
    }
3966
3967
    ret = wolfSSL_X509_add_ext(x, ext, -1);
3968
    wolfSSL_X509_EXTENSION_free(ext);
3969
3970
    return ret;
3971
}
3972
3973
/* Returns pointer to ASN1_OBJECT from an X509_EXTENSION object */
3974
WOLFSSL_ASN1_OBJECT* wolfSSL_X509_EXTENSION_get_object(
3975
    WOLFSSL_X509_EXTENSION* ext)
3976
{
3977
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_get_object");
3978
    if (ext == NULL)
3979
        return NULL;
3980
    return ext->obj;
3981
}
3982
3983
3984
/**
3985
 * duplicates the 'obj' input and sets it into the 'ext' structure
3986
 * returns WOLFSSL_SUCCESS on success
3987
 */
3988
int wolfSSL_X509_EXTENSION_set_object(WOLFSSL_X509_EXTENSION* ext,
3989
        const WOLFSSL_ASN1_OBJECT* obj)
3990
{
3991
    WOLFSSL_ASN1_OBJECT *current;
3992
3993
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_set_object");
3994
    if (ext == NULL)
3995
        return WOLFSSL_FAILURE;
3996
3997
    current = wolfSSL_X509_EXTENSION_get_object(ext);
3998
    if (current != NULL) {
3999
        wolfSSL_ASN1_OBJECT_free(current);
4000
    }
4001
    ext->obj = wolfSSL_ASN1_OBJECT_dup((WOLFSSL_ASN1_OBJECT*)obj);
4002
    return WOLFSSL_SUCCESS;
4003
}
4004
#endif /* OPENSSL_ALL */
4005
4006
#ifdef WOLFSSL_OLD_EXTDATA_FMT
4007
/*
4008
 * Replace the current string in 'asn1str', which is the full X.509
4009
 * extension octet string with some data specific for the extension
4010
 * type. The extension is the one given in 'oid'.
4011
 * Return 0 in case of success, or a negative error code.
4012
 */
4013
static int wolfSSL_ASN1_STRING_into_old_ext_fmt(WOLFSSL_ASN1_STRING *asn1str,
4014
                                                word32 oid)
4015
{
4016
    switch (oid)
4017
    {
4018
        case AUTH_INFO_OID:
4019
            wolfSSL_ASN1_STRING_clear(asn1str);
4020
            asn1str->data = NULL;
4021
            asn1str->length = 0;
4022
            return 0;
4023
4024
        case AUTH_KEY_OID:
4025
        {
4026
            int ret = 0;
4027
            const byte *extAuthKeyId = NULL;
4028
            word32 extAuthKeyIdSz = 0;
4029
            char *data = NULL;
4030
4031
            ret = DecodeAuthKeyId((const byte *)asn1str->data, asn1str->length,
4032
                    &extAuthKeyId, &extAuthKeyIdSz, NULL, NULL, NULL, NULL);
4033
4034
            if (ret != 0)
4035
                return ret;
4036
4037
            data = (char*)XMALLOC((size_t)(extAuthKeyIdSz), NULL,
4038
                                  DYNAMIC_TYPE_OPENSSL);
4039
            if (data == NULL)
4040
                return MEMORY_ERROR;
4041
4042
            XMEMCPY(data, extAuthKeyId, (size_t)extAuthKeyIdSz);
4043
            wolfSSL_ASN1_STRING_set(asn1str, data, extAuthKeyIdSz);
4044
            XFREE(data, NULL, DYNAMIC_TYPE_OPENSSL);
4045
            return 0;
4046
        }
4047
4048
        case SUBJ_KEY_OID:
4049
        {
4050
            int ret = 0;
4051
            const byte *extSubjKeyId = NULL;
4052
            word32 extSubjKeyIdSz = 0;
4053
            char *data = NULL;
4054
4055
            ret = DecodeSubjKeyId((const byte *)asn1str->data, asn1str->length,
4056
                    &extSubjKeyId, &extSubjKeyIdSz);
4057
            if (ret != 0)
4058
                return ret;
4059
4060
            data = (char*)XMALLOC((size_t)(extSubjKeyIdSz), NULL,
4061
                                  DYNAMIC_TYPE_OPENSSL);
4062
            if (data == NULL)
4063
                return MEMORY_ERROR;
4064
4065
            XMEMCPY(data, extSubjKeyId, (size_t)extSubjKeyIdSz);
4066
            wolfSSL_ASN1_STRING_set(asn1str, data, extSubjKeyIdSz);
4067
            XFREE(data, NULL, DYNAMIC_TYPE_OPENSSL);
4068
            return 0;
4069
        }
4070
4071
        case CERT_POLICY_OID:
4072
            wolfSSL_ASN1_STRING_clear(asn1str);
4073
            asn1str->data = NULL;
4074
            asn1str->length = 0;
4075
            return 0;
4076
4077
        case KEY_USAGE_OID:
4078
        {
4079
            int ret = 0;
4080
            word16 extKeyUsage = 0;
4081
4082
            ret = DecodeKeyUsage((const byte *)asn1str->data, asn1str->length,
4083
                    &extKeyUsage);
4084
            if (ret != 0)
4085
                return ret;
4086
4087
            wolfSSL_ASN1_STRING_set(asn1str, (byte*)&extKeyUsage,
4088
                                    sizeof(extKeyUsage));
4089
            return 0;
4090
        }
4091
4092
        case EXT_KEY_USAGE_OID:
4093
        {
4094
            int ret = 0;
4095
            const byte *extExtKeyUsageSrc = NULL;
4096
            word32 extExtKeyUsageSz = 0;
4097
            word32 extExtKeyUsageCount = 0;
4098
            byte extExtKeyUsage = 0;
4099
            byte extExtKeyUsageSsh = 0;
4100
            char *data = NULL;
4101
4102
            ret = DecodeExtKeyUsage((const byte*)asn1str->data, asn1str->length,
4103
                    &extExtKeyUsageSrc, &extExtKeyUsageSz, &extExtKeyUsageCount,
4104
                    &extExtKeyUsage, &extExtKeyUsageSsh, NULL);
4105
            if (ret != 0)
4106
                return ret;
4107
4108
            data = (char*)XMALLOC((size_t)(extExtKeyUsageSz), NULL,
4109
                                  DYNAMIC_TYPE_OPENSSL);
4110
            if (data == NULL)
4111
                return MEMORY_ERROR;
4112
4113
            XMEMCPY(data, extExtKeyUsageSrc, (size_t)extExtKeyUsageSz);
4114
            wolfSSL_ASN1_STRING_set(asn1str, data, extExtKeyUsageSz);
4115
            XFREE(data, NULL, DYNAMIC_TYPE_OPENSSL);
4116
            return 0;
4117
        }
4118
4119
        case CRL_DIST_OID:
4120
            wolfSSL_ASN1_STRING_clear(asn1str);
4121
            asn1str->data = NULL;
4122
            asn1str->length = 0;
4123
            return 0;
4124
4125
        default:
4126
            /* Do nothing, it is already set */
4127
            return 0;
4128
    }
4129
}
4130
#endif /* WOLFSSL_OLD_EXTDATA_FMT */
4131
4132
/* Returns pointer to ASN1_STRING in X509_EXTENSION object */
4133
WOLFSSL_ASN1_STRING* wolfSSL_X509_EXTENSION_get_data(
4134
    WOLFSSL_X509_EXTENSION* ext)
4135
{
4136
    WOLFSSL_ASN1_STRING *ret;
4137
4138
    ret =  wolfSSL_X509_EXTENSION_get_data_internal(ext);
4139
4140
#ifdef WOLFSSL_OLD_EXTDATA_FMT
4141
    if (ret)
4142
    {
4143
        int error;
4144
        error = wolfSSL_ASN1_STRING_into_old_ext_fmt (ret, ext->obj->type);
4145
        if (error != 0)
4146
        {
4147
            WOLFSSL_MSG("Error calling wolfSSL_ASN1_STRING_into_old_ext_fmt");
4148
            return NULL;
4149
        }
4150
    }
4151
#endif
4152
4153
    return ret;
4154
}
4155
4156
4157
/**
4158
 * Creates a duplicate of input 'data' and sets it into 'ext' structure
4159
 * returns WOLFSSL_SUCCESS on success
4160
 */
4161
int wolfSSL_X509_EXTENSION_set_data(WOLFSSL_X509_EXTENSION* ext,
4162
        WOLFSSL_ASN1_STRING* data)
4163
{
4164
    if (ext == NULL || data == NULL)
4165
        return WOLFSSL_FAILURE;
4166
4167
    /* wolfSSL_ASN1_STRING_copy() defers to wolfSSL_ASN1_STRING_set(), which
4168
     * owns the free of any existing dynamic buffer and only releases it once
4169
     * the new contents have been copied.  Freeing it here as well would leave
4170
     * ext->value.data dangling for that copy, so leave the buffer alone; the
4171
     * self-aliased case (data == &ext->value) keeps working too. */
4172
    return wolfSSL_ASN1_STRING_copy(&ext->value, data);
4173
}
4174
4175
int wolfSSL_X509_digest(const WOLFSSL_X509* x509, const WOLFSSL_EVP_MD* digest,
4176
        unsigned char* buf, unsigned int* len)
4177
{
4178
    int ret;
4179
4180
    WOLFSSL_ENTER("wolfSSL_X509_digest");
4181
4182
    if (x509 == NULL || digest == NULL) {
4183
        WOLFSSL_MSG("Null argument found");
4184
        return WOLFSSL_FAILURE;
4185
    }
4186
4187
    if (x509->derCert == NULL) {
4188
        WOLFSSL_MSG("No DER certificate stored in X509");
4189
        return WOLFSSL_FAILURE;
4190
    }
4191
4192
    ret = wolfSSL_EVP_Digest(x509->derCert->buffer, x509->derCert->length, buf,
4193
                              len, digest, NULL);
4194
    WOLFSSL_LEAVE("wolfSSL_X509_digest", ret);
4195
    return ret;
4196
}
4197
4198
int wolfSSL_X509_pubkey_digest(const WOLFSSL_X509 *x509,
4199
        const WOLFSSL_EVP_MD *digest, unsigned char* buf, unsigned int* len)
4200
{
4201
    int ret;
4202
4203
    WOLFSSL_ENTER("wolfSSL_X509_pubkey_digest");
4204
4205
    if (x509 == NULL || digest == NULL) {
4206
        WOLFSSL_MSG("Null argument found");
4207
        return WOLFSSL_FAILURE;
4208
    }
4209
4210
    if (x509->pubKey.buffer == NULL || x509->pubKey.length == 0) {
4211
        WOLFSSL_MSG("No DER public key stored in X509");
4212
        return WOLFSSL_FAILURE;
4213
    }
4214
4215
    ret = wolfSSL_EVP_Digest(x509->pubKey.buffer, x509->pubKey.length, buf,
4216
                              len, digest, NULL);
4217
    WOLFSSL_LEAVE("wolfSSL_X509_pubkey_digest", ret);
4218
    return ret;
4219
}
4220
4221
#endif /* OPENSSL_EXTRA */
4222
4223
#ifdef OPENSSL_EXTRA
4224
4225
    #ifndef NO_WOLFSSL_STUB
4226
    const char* wolfSSL_X509_get_default_cert_file_env(void)
4227
    {
4228
        WOLFSSL_STUB("X509_get_default_cert_file_env");
4229
        return "";
4230
    }
4231
4232
    const char* wolfSSL_X509_get_default_cert_file(void)
4233
    {
4234
        WOLFSSL_STUB("X509_get_default_cert_file");
4235
        return "";
4236
    }
4237
4238
    const char* wolfSSL_X509_get_default_cert_dir_env(void)
4239
    {
4240
        WOLFSSL_STUB("X509_get_default_cert_dir_env");
4241
        return "";
4242
    }
4243
4244
    const char* wolfSSL_X509_get_default_cert_dir(void)
4245
    {
4246
        WOLFSSL_STUB("X509_get_default_cert_dir");
4247
        return "";
4248
    }
4249
    #endif
4250
4251
#endif /* OPENSSL_EXTRA */
4252
4253
#if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS) || \
4254
    defined(KEEP_OUR_CERT) || \
4255
    defined(OPENSSL_EXTRA)  || defined(OPENSSL_EXTRA_X509_SMALL)
4256
4257
/* user externally called free X509, if dynamic go ahead with free, otherwise
4258
 * don't */
4259
static void ExternalFreeX509(WOLFSSL_X509* x509)
4260
{
4261
#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA)
4262
    int doFree = 0;
4263
#endif
4264
4265
    WOLFSSL_ENTER("ExternalFreeX509");
4266
    if (x509) {
4267
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
4268
        wolfSSL_CRYPTO_cleanup_ex_data(&x509->ex_data);
4269
#endif
4270
        if (x509->dynamicMemory) {
4271
        #if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA)
4272
            int ret;
4273
            wolfSSL_RefDec(&x509->ref, &doFree, &ret);
4274
            if (ret != 0) {
4275
                WOLFSSL_MSG("Couldn't lock x509 mutex");
4276
            }
4277
            if (doFree)
4278
        #endif /* OPENSSL_EXTRA_X509_SMALL || OPENSSL_EXTRA */
4279
            {
4280
                FreeX509(x509);
4281
                XFREE(x509, x509->heap, DYNAMIC_TYPE_X509);
4282
            }
4283
        }
4284
        else {
4285
            WOLFSSL_MSG("free called on non dynamic object, not freeing");
4286
        }
4287
    }
4288
}
4289
4290
/* Frees an external WOLFSSL_X509 structure */
4291
WOLFSSL_ABI
4292
void wolfSSL_X509_free(WOLFSSL_X509* x509)
4293
{
4294
    WOLFSSL_ENTER("wolfSSL_X509_free");
4295
    ExternalFreeX509(x509);
4296
}
4297
#endif
4298
4299
#if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS) || \
4300
    defined(OPENSSL_EXTRA)  || defined(OPENSSL_EXTRA_X509_SMALL)
4301
4302
/* copy name into in buffer, at most sz bytes, if buffer is null will
4303
   malloc buffer, call responsible for freeing                     */
4304
WOLFSSL_ABI
4305
char* wolfSSL_X509_NAME_oneline(WOLFSSL_X509_NAME* name, char* in, int sz)
4306
{
4307
    int copySz;
4308
4309
    WOLFSSL_ENTER("wolfSSL_X509_NAME_oneline");
4310
4311
    if (name == NULL) {
4312
        WOLFSSL_MSG("WOLFSSL_X509_NAME pointer was NULL");
4313
        return NULL;
4314
    }
4315
4316
    if (name->sz == 0)
4317
        return in;
4318
4319
    if (!in) {
4320
    #ifdef WOLFSSL_STATIC_MEMORY
4321
        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
4322
        return NULL;
4323
    #else
4324
        in = (char*)XMALLOC(name->sz, NULL, DYNAMIC_TYPE_OPENSSL);
4325
        if (!in)
4326
            return in;
4327
        copySz = name->sz;
4328
    #endif
4329
    }
4330
    else {
4331
        copySz = (int)min((word32)sz, (word32)name->sz);
4332
        if (copySz <= 0)
4333
            return in;
4334
    }
4335
4336
    XMEMCPY(in, name->name, copySz - 1);
4337
    in[copySz - 1] = 0;
4338
4339
    return in;
4340
}
4341
4342
#ifdef OPENSSL_EXTRA
4343
/* Given an X509_NAME, convert it to canonical form and then hash
4344
 * with the provided hash type. Returns the first 4 bytes of the hash
4345
 * as unsigned long on success, and 0 otherwise. */
4346
static unsigned long X509NameHash(WOLFSSL_X509_NAME* name,
4347
    enum wc_HashType hashType)
4348
{
4349
    unsigned long  hash = 0;
4350
    unsigned char* canonName = NULL;
4351
    byte           digest[WC_MAX_DIGEST_SIZE];
4352
    int            size = 0;
4353
    int            rc;
4354
4355
    WOLFSSL_ENTER("X509NameHash");
4356
4357
    if (name == NULL) {
4358
        WOLFSSL_ERROR_MSG("WOLFSSL_X509_NAME pointer was NULL");
4359
        return 0;
4360
    }
4361
4362
    if (name->sz == 0) {
4363
        WOLFSSL_ERROR_MSG("Nothing to hash in WOLFSSL_X509_NAME");
4364
        return 0;
4365
    }
4366
4367
    size = wolfSSL_i2d_X509_NAME_canon(name, &canonName);
4368
4369
    if (size <= 0 || canonName == NULL) {
4370
        WOLFSSL_ERROR_MSG("wolfSSL_i2d_X509_NAME_canon error");
4371
        return 0;
4372
    }
4373
4374
    rc = wc_Hash(hashType, (const byte*)canonName, (word32)size, digest,
4375
        sizeof(digest));
4376
4377
    if (rc == 0) {
4378
        hash = (((unsigned long)digest[3] << 24) |
4379
                ((unsigned long)digest[2] << 16) |
4380
                ((unsigned long)digest[1] <<  8) |
4381
                ((unsigned long)digest[0]));
4382
    }
4383
    else if (rc == WC_NO_ERR_TRACE(HASH_TYPE_E)) {
4384
        WOLFSSL_ERROR_MSG("Hash function not compiled in");
4385
    }
4386
    else {
4387
        WOLFSSL_ERROR_MSG("Error hashing name");
4388
    }
4389
4390
    XFREE(canonName, NULL, DYNAMIC_TYPE_OPENSSL);
4391
    return hash;
4392
}
4393
4394
unsigned long wolfSSL_X509_NAME_hash(WOLFSSL_X509_NAME* name)
4395
{
4396
    return X509NameHash(name, WC_HASH_TYPE_SHA);
4397
}
4398
4399
/******************************************************************************
4400
* wolfSSL_X509_subject_name_hash
4401
* wolfSSL_X509_issuer_name_hash
4402
* Compute the hash digest of the subject / issuer name.
4403
* These functions prefer SHA-1 (if available) for compatibility. Otherwise
4404
* they use SHA-256.
4405
*
4406
* RETURNS:
4407
* The first 4 bytes of SHA-1 (or SHA-256) hash in little endian order as
4408
* unsigned long.
4409
* Otherwise, returns zero.
4410
*
4411
* Note:
4412
* Returns the same hash value as OpenSSL's X509_X_name_hash() API
4413
* if SHA-1 support is compiled in. SHA-256 will be used if SHA-1 is
4414
* not available.
4415
*/
4416
unsigned long wolfSSL_X509_subject_name_hash(const WOLFSSL_X509* x509)
4417
{
4418
    if (x509 == NULL) {
4419
        WOLFSSL_ERROR_MSG("WOLFSSL_X509 pointer was NULL");
4420
        return 0;
4421
    }
4422
4423
    #ifndef NO_SHA
4424
    return X509NameHash((WOLFSSL_X509_NAME*) &x509->subject, WC_HASH_TYPE_SHA);
4425
    #elif !defined(NO_SHA256)
4426
    return X509NameHash((WOLFSSL_X509_NAME*) &x509->subject,
4427
                        WC_HASH_TYPE_SHA256);
4428
    #else
4429
    WOLFSSL_ERROR_MSG("Hash function not compiled in");
4430
    return 0;
4431
    #endif
4432
}
4433
4434
unsigned long wolfSSL_X509_issuer_name_hash(const WOLFSSL_X509* x509)
4435
{
4436
    if (x509 == NULL) {
4437
        WOLFSSL_ERROR_MSG("WOLFSSL_X509 pointer was NULL");
4438
        return 0;
4439
    }
4440
4441
    #ifndef NO_SHA
4442
    return X509NameHash((WOLFSSL_X509_NAME*) &x509->issuer, WC_HASH_TYPE_SHA);
4443
    #elif !defined(NO_SHA256)
4444
    return X509NameHash((WOLFSSL_X509_NAME*) &x509->issuer,
4445
                        WC_HASH_TYPE_SHA256);
4446
    #else
4447
    WOLFSSL_ERROR_MSG("Hash function not compiled in");
4448
    return 0;
4449
    #endif
4450
}
4451
#endif /* OPENSSL_EXTRA */
4452
4453
#if defined(OPENSSL_EXTRA) && defined(XSNPRINTF)
4454
/* Copies X509 subject name into a buffer, with comma-separated name entries
4455
 *   (matching OpenSSL v1.0.0 format)
4456
 * Example Output for Issuer:
4457
 *
4458
 * C=US, ST=Montana, L=Bozeman, O=Sawtooth, OU=Consulting,
4459
 *  CN=www.wolfssl.com, emailAddress=facts@wolfssl.com
4460
 */
4461
char* wolfSSL_X509_get_name_oneline(WOLFSSL_X509_NAME* name, char* in, int sz)
4462
{
4463
    int count, i;
4464
    int totalLen = 0;
4465
    char tmpBuf[256];
4466
    WOLFSSL_ENTER("wolfSSL_X509_get_name_oneline");
4467
4468
    if (name == NULL) {
4469
        WOLFSSL_MSG("wolfSSL_X509_get_name_oneline failed");
4470
        return NULL;
4471
    }
4472
    #ifdef WOLFSSL_STATIC_MEMORY
4473
    if (!in) {
4474
        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
4475
        return NULL;
4476
    }
4477
    #endif
4478
4479
    /* Loop through X509 name entries and copy new format to buffer */
4480
    count = wolfSSL_X509_NAME_entry_count(name);
4481
    for (i = 0; i < count; i++) {
4482
        WOLFSSL_X509_NAME_ENTRY* entry;
4483
        int nameSz;
4484
        int strSz;
4485
        int strLen;
4486
        char *str;
4487
        const int tmpBufSz = sizeof(tmpBuf);
4488
        char buf[80];
4489
        const char* sn;
4490
4491
        /* Get name entry and size */
4492
        entry = wolfSSL_X509_NAME_get_entry(name, i);
4493
        if (entry == NULL) {
4494
            WOLFSSL_MSG("wolfSSL_X509_NAME_get_entry failed");
4495
            return NULL;
4496
        }
4497
        nameSz = wolfSSL_X509_NAME_get_text_by_NID(name, entry->nid, buf,
4498
                                                                   sizeof(buf));
4499
        if (nameSz < 0) {
4500
            WOLFSSL_MSG("wolfSSL_X509_NAME_get_text_by_NID failed");
4501
            return NULL;
4502
        }
4503
4504
        /* Get short name */
4505
        sn = wolfSSL_OBJ_nid2sn(entry->nid);
4506
        if (sn == NULL) {
4507
            WOLFSSL_MSG("OBJ_nid2sn failed");
4508
            return NULL;
4509
        }
4510
4511
        /* Copy sn and name text to buffer
4512
         * Add extra strSz for '=', ',', ' ' and '\0' characters in XSNPRINTF.
4513
         */
4514
        if (i != count - 1) {
4515
            strSz = (int)XSTRLEN(sn) + nameSz + 4;
4516
            str = (char*)XMALLOC(strSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4517
            if (str == NULL) {
4518
                WOLFSSL_MSG("Memory error");
4519
                return NULL;
4520
            }
4521
            strLen = XSNPRINTF(str, (size_t)strSz, "%s=%s, ", sn, buf);
4522
            if ((strLen  < 0) || (strLen  >= strSz)) {
4523
                WOLFSSL_MSG("buffer overrun");
4524
                XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4525
                return NULL;
4526
            }
4527
        }
4528
        else {
4529
            /* Copy last name entry
4530
            * Add extra strSz for '=' and '\0' characters in XSNPRINTF.
4531
            */
4532
            strSz = (int)XSTRLEN(sn) + nameSz + 2;
4533
            str = (char*)XMALLOC(strSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4534
            if (str == NULL) {
4535
                WOLFSSL_MSG("Memory error");
4536
                return NULL;
4537
            }
4538
            strLen = XSNPRINTF(str, (size_t)strSz, "%s=%s", sn, buf);
4539
            if ((strLen  < 0) || (strLen  >= strSz)) {
4540
                WOLFSSL_MSG("buffer overrun");
4541
                XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4542
                return NULL;
4543
            }
4544
        }
4545
        /* Copy string to tmpBuf */
4546
        if (totalLen + strLen > tmpBufSz) {
4547
            WOLFSSL_MSG("buffer overrun");
4548
            XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4549
            return NULL;
4550
        }
4551
        XMEMCPY(tmpBuf + totalLen, str, strLen);
4552
        totalLen += strLen;
4553
        XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4554
    }
4555
4556
    /* Allocate space based on total string size if no buffer was provided */
4557
    if (!in) {
4558
        in = (char*)XMALLOC(totalLen+1, NULL, DYNAMIC_TYPE_OPENSSL);
4559
        if (in == NULL) {
4560
            WOLFSSL_MSG("Memory error");
4561
            return in;
4562
        }
4563
    }
4564
    else {
4565
        if (totalLen + 1 > sz) {
4566
            WOLFSSL_MSG("buffer overrun");
4567
            return NULL;
4568
        }
4569
    }
4570
4571
    XMEMCPY(in, tmpBuf, totalLen); /* cppcheck-suppress uninitvar */
4572
    in[totalLen] = '\0';
4573
4574
    return in;
4575
}
4576
#endif
4577
4578
4579
/* Wraps wolfSSL_X509_d2i
4580
 *
4581
 * returns a WOLFSSL_X509 structure pointer on success and NULL on fail
4582
 */
4583
WOLFSSL_X509* wolfSSL_d2i_X509(WOLFSSL_X509** x509, const unsigned char** in,
4584
        int len)
4585
{
4586
    WOLFSSL_X509* newX509 = NULL;
4587
    WOLFSSL_ENTER("wolfSSL_d2i_X509");
4588
4589
    if (in == NULL) {
4590
        WOLFSSL_MSG("NULL input for wolfSSL_d2i_X509");
4591
        return NULL;
4592
    }
4593
4594
    newX509 = wolfSSL_X509_d2i(x509, *in, len);
4595
    if (newX509 != NULL) {
4596
        *in += newX509->derCert->length;
4597
    }
4598
    return newX509;
4599
}
4600
4601
static WOLFSSL_X509* d2i_X509orX509REQ(WOLFSSL_X509** x509,
4602
                                  const byte* in, int len, int req, void* heap)
4603
{
4604
    WOLFSSL_X509 *newX509 = NULL;
4605
    int type = req ? CERTREQ_TYPE : CERT_TYPE;
4606
4607
    WOLFSSL_ENTER("wolfSSL_X509_d2i");
4608
4609
    if (in != NULL && len > 0
4610
    #ifndef WOLFSSL_CERT_REQ
4611
            && req == 0
4612
    #else
4613
            && (req == 0 || req == 1)
4614
    #endif
4615
            ) {
4616
        WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
4617
4618
        WC_ALLOC_VAR_EX(cert, DecodedCert, 1, NULL, DYNAMIC_TYPE_DCERT,
4619
            return NULL);
4620
4621
        InitDecodedCert(cert, (byte*)in, (word32)len, heap);
4622
    #ifdef WOLFSSL_CERT_REQ
4623
        cert->isCSR = (byte)req;
4624
    #endif
4625
        if (ParseCertRelative(cert, type, 0, NULL, NULL) == 0) {
4626
            newX509 = wolfSSL_X509_new_ex(heap);
4627
            if (newX509 != NULL) {
4628
                if (CopyDecodedToX509(newX509, cert) != 0) {
4629
                    wolfSSL_X509_free(newX509);
4630
                    newX509 = NULL;
4631
                }
4632
            }
4633
        }
4634
        FreeDecodedCert(cert);
4635
        WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
4636
    }
4637
4638
    if (x509 != NULL)
4639
        *x509 = newX509;
4640
4641
    return newX509;
4642
}
4643
4644
int wolfSSL_X509_get_isCA(WOLFSSL_X509* x509)
4645
{
4646
    int isCA = 0;
4647
4648
    WOLFSSL_ENTER("wolfSSL_X509_get_isCA");
4649
4650
    if (x509 != NULL)
4651
        isCA = x509->isCa;
4652
4653
    WOLFSSL_LEAVE("wolfSSL_X509_get_isCA", isCA);
4654
4655
    return isCA;
4656
}
4657
4658
WOLFSSL_X509* wolfSSL_X509_d2i_ex(WOLFSSL_X509** x509, const byte* in, int len,
4659
    void* heap)
4660
{
4661
    return d2i_X509orX509REQ(x509, in, len, 0, heap);
4662
}
4663
4664
WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len)
4665
{
4666
    return wolfSSL_X509_d2i_ex(x509, in, len, NULL);
4667
}
4668
4669
#ifdef WOLFSSL_CERT_REQ
4670
WOLFSSL_X509* wolfSSL_X509_REQ_d2i(WOLFSSL_X509** x509,
4671
        const unsigned char* in, int len)
4672
{
4673
    return d2i_X509orX509REQ(x509, in, len, 1, NULL);
4674
}
4675
4676
WOLFSSL_X509* wolfSSL_d2i_X509_REQ_INFO(WOLFSSL_X509** req,
4677
        const unsigned char** in, int len)
4678
{
4679
    WOLFSSL_X509* ret = NULL;
4680
    WOLFSSL_ENTER("wolfSSL_d2i_X509_REQ_INFO");
4681
4682
    if (in == NULL) {
4683
        WOLFSSL_MSG("NULL input for wolfSSL_d2i_X509");
4684
        return NULL;
4685
    }
4686
4687
    ret = wolfSSL_X509_REQ_d2i(req, *in, len);
4688
    if (ret != NULL) {
4689
        *in += ret->derCert->length;
4690
    }
4691
    return ret;
4692
}
4693
#endif
4694
4695
#endif /* KEEP_PEER_CERT || SESSION_CERTS || OPENSSL_EXTRA ||
4696
          OPENSSL_EXTRA_X509_SMALL */
4697
4698
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
4699
/* returns the number of entries in the WOLFSSL_X509_NAME */
4700
int wolfSSL_X509_NAME_entry_count(WOLFSSL_X509_NAME* name)
4701
{
4702
    int count = 0;
4703
4704
    WOLFSSL_ENTER("wolfSSL_X509_NAME_entry_count");
4705
4706
    if (name != NULL)
4707
        count = name->entrySz;
4708
4709
    WOLFSSL_LEAVE("wolfSSL_X509_NAME_entry_count", count);
4710
    return count;
4711
}
4712
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
4713
4714
#if defined(OPENSSL_EXTRA) || \
4715
    defined(KEEP_OUR_CERT) || defined(KEEP_PEER_CERT)
4716
4717
/* return the next, if any, altname from the peer cert */
4718
WOLFSSL_ABI
4719
char* wolfSSL_X509_get_next_altname(WOLFSSL_X509* cert)
4720
{
4721
    char* ret = NULL;
4722
    WOLFSSL_ENTER("wolfSSL_X509_get_next_altname");
4723
4724
    /* don't have any to work with */
4725
    if (cert == NULL || cert->altNames == NULL)
4726
        return NULL;
4727
4728
    /* already went through them */
4729
    if (cert->altNamesNext == NULL) {
4730
#ifdef WOLFSSL_MULTICIRCULATE_ALTNAMELIST
4731
        /* Reset altNames List to head
4732
         * so that caller can circulate the list again
4733
         */
4734
        cert->altNamesNext = cert->altNames;
4735
#endif
4736
        return NULL;
4737
    }
4738
4739
    /* In default builds iPAddress entries hold raw 4/16 octet payloads
4740
     * and registeredID entries hold raw OID body bytes (no human-readable
4741
     * ipString/ridString), so returning them as a C string would truncate
4742
     * at any embedded NUL byte. Such entries are still parsed into
4743
     * altNames for name-constraint enforcement; skip them here so
4744
     * string-iteration callers see the same set of entries as before.
4745
     *
4746
     * With WOLFSSL_MULTICIRCULATE_ALTNAMELIST, a list consisting only of
4747
     * skipped entries collapses to "no entries" on the first pass and
4748
     * resets to head on the next call; the cycle shape matches the
4749
     * pre-fix behavior where such entries were never parsed. */
4750
#if !defined(WOLFSSL_IP_ALT_NAME) || !defined(WOLFSSL_RID_ALT_NAME)
4751
    while (cert->altNamesNext != NULL) {
4752
        int skip = 0;
4753
#ifndef WOLFSSL_IP_ALT_NAME
4754
        if (cert->altNamesNext->type == ASN_IP_TYPE)
4755
            skip = 1;
4756
#endif
4757
#ifndef WOLFSSL_RID_ALT_NAME
4758
        if (cert->altNamesNext->type == ASN_RID_TYPE)
4759
            skip = 1;
4760
#endif
4761
        if (!skip)
4762
            break;
4763
        cert->altNamesNext = cert->altNamesNext->next;
4764
    }
4765
    if (cert->altNamesNext == NULL)
4766
        return NULL;
4767
#endif /* !WOLFSSL_IP_ALT_NAME || !WOLFSSL_RID_ALT_NAME */
4768
4769
    /* unsafe cast required for ABI compatibility. */
4770
    ret = (char *)(wc_ptr_t)cert->altNamesNext->name;
4771
#ifdef WOLFSSL_IP_ALT_NAME
4772
    /* return the IP address as a string */
4773
    if (cert->altNamesNext->type == ASN_IP_TYPE) {
4774
        ret = cert->altNamesNext->ipString;
4775
    }
4776
#endif
4777
#ifdef WOLFSSL_RID_ALT_NAME
4778
    /* return the registeredID as a string */
4779
    if (cert->altNamesNext->type == ASN_RID_TYPE) {
4780
        ret = cert->altNamesNext->ridString;
4781
    }
4782
#endif
4783
    cert->altNamesNext = cert->altNamesNext->next;
4784
4785
    return ret;
4786
}
4787
4788
int wolfSSL_X509_get_signature(WOLFSSL_X509* x509,
4789
                                                unsigned char* buf, int* bufSz)
4790
{
4791
    WOLFSSL_ENTER("wolfSSL_X509_get_signature");
4792
    if (x509 == NULL || bufSz == NULL || (*bufSz < (int)x509->sig.length &&
4793
                buf != NULL))
4794
        return WOLFSSL_FATAL_ERROR;
4795
4796
    if (buf != NULL)
4797
        XMEMCPY(buf, x509->sig.buffer, x509->sig.length);
4798
    *bufSz = (int)x509->sig.length;
4799
4800
    return WOLFSSL_SUCCESS;
4801
}
4802
4803
4804
/* Getter function that copies over the DER public key buffer to "buf" and
4805
    * sets the size in bufSz. If "buf" is NULL then just bufSz is set to needed
4806
    * buffer size. "bufSz" passed in should initially be set by the user to be
4807
    * the size of "buf". This gets checked to make sure the buffer is large
4808
    * enough to hold the public key.
4809
    *
4810
    * Note: this is the X.509 form of key with "header" info.
4811
    * return WOLFSSL_SUCCESS on success
4812
    */
4813
int wolfSSL_X509_get_pubkey_buffer(WOLFSSL_X509* x509,
4814
                                            unsigned char* buf, int* bufSz)
4815
{
4816
    WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
4817
    const byte*  der;
4818
    int length = 0;
4819
    int    ret = 0, derSz = 0;
4820
    int badDate = 0;
4821
    const byte* pubKeyX509 = NULL;
4822
    int   pubKeyX509Sz = 0;
4823
4824
    WOLFSSL_ENTER("wolfSSL_X509_get_pubkey_buffer");
4825
    if (x509 == NULL || bufSz == NULL) {
4826
        WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", BAD_FUNC_ARG);
4827
        return WOLFSSL_FATAL_ERROR;
4828
    }
4829
4830
4831
#ifdef WOLFSSL_SMALL_STACK
4832
    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert),
4833
                                    x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
4834
    if (cert == NULL) {
4835
        WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", MEMORY_E);
4836
        return WOLFSSL_FATAL_ERROR;
4837
    }
4838
#endif
4839
4840
    der = wolfSSL_X509_get_der(x509, &derSz);
4841
    if (der != NULL) {
4842
        InitDecodedCert(cert, der, (word32)derSz, NULL);
4843
        ret = wc_GetPubX509(cert, 0, &badDate);
4844
        if (ret >= 0) {
4845
            word32 idx = cert->srcIdx;
4846
            pubKeyX509 = cert->source + cert->srcIdx;
4847
            ret = GetSequence(cert->source, &cert->srcIdx, &length,
4848
                    cert->maxIdx);
4849
            pubKeyX509Sz = length + (cert->srcIdx - idx);
4850
        }
4851
        FreeDecodedCert(cert);
4852
    }
4853
    WC_FREE_VAR_EX(cert, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
4854
4855
    if (ret < 0) {
4856
        WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", ret);
4857
        return WOLFSSL_FATAL_ERROR;
4858
    }
4859
4860
    if (buf != NULL && pubKeyX509 != NULL) {
4861
        if (pubKeyX509Sz > *bufSz) {
4862
            WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", BUFFER_E);
4863
            return WOLFSSL_FATAL_ERROR;
4864
        }
4865
        XMEMCPY(buf, pubKeyX509, pubKeyX509Sz);
4866
    }
4867
    *bufSz = pubKeyX509Sz;
4868
4869
    return WOLFSSL_SUCCESS;
4870
}
4871
4872
4873
/* Getter function for the public key OID value
4874
    * return public key OID stored in WOLFSSL_X509 structure */
4875
int wolfSSL_X509_get_pubkey_type(WOLFSSL_X509* x509)
4876
{
4877
    if (x509 == NULL)
4878
        return WOLFSSL_FAILURE;
4879
    return x509->pubKeyOID;
4880
}
4881
4882
#endif /* OPENSSL_EXTRA || KEEP_OUR_CERT || KEEP_PEER_CERT || SESSION_CERTS */
4883
4884
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
4885
    defined(KEEP_OUR_CERT) || defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
4886
4887
/* write X509 serial number in unsigned binary to buffer
4888
    buffer needs to be at least EXTERNAL_SERIAL_SIZE (32) for all cases
4889
    return WOLFSSL_SUCCESS on success */
4890
int wolfSSL_X509_get_serial_number(WOLFSSL_X509* x509,
4891
                                    byte* in, int* inOutSz)
4892
{
4893
    WOLFSSL_ENTER("wolfSSL_X509_get_serial_number");
4894
    if (x509 == NULL || inOutSz == NULL) {
4895
        WOLFSSL_MSG("Null argument passed in");
4896
        return BAD_FUNC_ARG;
4897
    }
4898
4899
    if (in != NULL) {
4900
        if (*inOutSz < x509->serialSz) {
4901
            WOLFSSL_MSG("Serial buffer too small");
4902
            return BUFFER_E;
4903
        }
4904
        XMEMCPY(in, x509->serial, x509->serialSz);
4905
    }
4906
    *inOutSz = x509->serialSz;
4907
4908
    return WOLFSSL_SUCCESS;
4909
}
4910
4911
/* not an openssl compatibility function - getting for derCert */
4912
const byte* wolfSSL_X509_get_der(WOLFSSL_X509* x509, int* outSz)
4913
{
4914
    WOLFSSL_ENTER("wolfSSL_X509_get_der");
4915
4916
    if (x509 == NULL || x509->derCert == NULL || outSz == NULL)
4917
        return NULL;
4918
4919
    if (x509->derCert->length > (word32)INT_MAX) {
4920
        return NULL;
4921
    }
4922
4923
    *outSz = (int)x509->derCert->length;
4924
    return x509->derCert->buffer;
4925
}
4926
4927
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || KEEP_OUR_CERT ||
4928
        * KEEP_PEER_CERT || SESSION_CERTS */
4929
4930
#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) || \
4931
    defined(OPENSSL_ALL) || defined(KEEP_OUR_CERT) || \
4932
    defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
4933
4934
/* used by JSSE (not a standard compatibility function) */
4935
WOLFSSL_ABI
4936
const byte* wolfSSL_X509_notBefore(WOLFSSL_X509* x509)
4937
{
4938
    WOLFSSL_ENTER("wolfSSL_X509_notBefore");
4939
4940
    if (x509 == NULL) {
4941
        return NULL;
4942
    }
4943
4944
    if (x509->notBefore.length < 0 ||
4945
            x509->notBefore.length > (int)sizeof(x509->notBeforeData) - 2) {
4946
        return NULL;
4947
    }
4948
4949
    XMEMSET(x509->notBeforeData, 0, sizeof(x509->notBeforeData));
4950
    x509->notBeforeData[0] = (byte)x509->notBefore.type;
4951
    x509->notBeforeData[1] = (byte)x509->notBefore.length;
4952
    XMEMCPY(&x509->notBeforeData[2], x509->notBefore.data,
4953
        x509->notBefore.length);
4954
4955
    return x509->notBeforeData;
4956
}
4957
4958
/* used by JSSE (not a standard compatibility function) */
4959
WOLFSSL_ABI
4960
const byte* wolfSSL_X509_notAfter(WOLFSSL_X509* x509)
4961
{
4962
    WOLFSSL_ENTER("wolfSSL_X509_notAfter");
4963
4964
    if (x509 == NULL) {
4965
        return NULL;
4966
    }
4967
4968
    if (x509->notAfter.length < 0 ||
4969
            x509->notAfter.length > (int)sizeof(x509->notAfterData) - 2) {
4970
        return NULL;
4971
    }
4972
4973
    XMEMSET(x509->notAfterData, 0, sizeof(x509->notAfterData));
4974
    x509->notAfterData[0] = (byte)x509->notAfter.type;
4975
    x509->notAfterData[1] = (byte)x509->notAfter.length;
4976
    XMEMCPY(&x509->notAfterData[2], x509->notAfter.data, x509->notAfter.length);
4977
4978
    return x509->notAfterData;
4979
}
4980
4981
int wolfSSL_X509_version(WOLFSSL_X509* x509)
4982
{
4983
    WOLFSSL_ENTER("wolfSSL_X509_version");
4984
4985
    if (x509 == NULL)
4986
        return 0;
4987
4988
    return x509->version;
4989
}
4990
#endif
4991
4992
#ifdef OPENSSL_EXTRA
4993
4994
/* get the buffer to be signed (tbs) from the WOLFSSL_X509 certificate
4995
    *
4996
    * outSz : gets set to the size of the buffer
4997
    * returns a pointer to the internal buffer at the location of TBS on
4998
    *         on success and NULL on failure.
4999
    */
5000
const unsigned char* wolfSSL_X509_get_tbs(WOLFSSL_X509* x509, int* outSz)
5001
{
5002
    int sz = 0, len;
5003
    unsigned int idx = 0, tmpIdx;
5004
    const unsigned char* der = NULL;
5005
    const unsigned char* tbs = NULL;
5006
5007
    if (x509 == NULL || outSz == NULL) {
5008
        return NULL;
5009
    }
5010
5011
    der = wolfSSL_X509_get_der(x509, &sz);
5012
    if (der == NULL) {
5013
        return NULL;
5014
    }
5015
5016
    if (GetSequence(der, &idx, &len, (word32)sz) < 0) {
5017
        return NULL;
5018
    }
5019
    tbs = der + idx;
5020
    tmpIdx = idx;
5021
    if (GetSequence(der, &idx, &len, (word32)sz) < 0) {
5022
        return NULL;
5023
    }
5024
    *outSz = len + (idx - tmpIdx);
5025
    return tbs;
5026
}
5027
5028
#ifdef WOLFSSL_SEP
5029
5030
/* copy oid into in buffer, at most *inOutSz bytes, if buffer is null will
5031
   malloc buffer, call responsible for freeing. Actual size returned in
5032
   *inOutSz. Requires inOutSz be non-null */
5033
byte* wolfSSL_X509_get_device_type(WOLFSSL_X509* x509, byte* in, int *inOutSz)
5034
{
5035
    int copySz;
5036
5037
    WOLFSSL_ENTER("wolfSSL_X509_get_dev_type");
5038
    if (x509 == NULL) return NULL;
5039
    if (inOutSz == NULL) return NULL;
5040
    if (!x509->deviceTypeSz) return in;
5041
5042
    copySz = min(*inOutSz, x509->deviceTypeSz);
5043
5044
    if (!in) {
5045
    #ifdef WOLFSSL_STATIC_MEMORY
5046
        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
5047
        return NULL;
5048
    #else
5049
        in = (byte*)XMALLOC(x509->deviceTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
5050
        if (!in) return in;
5051
        copySz = x509->deviceTypeSz;
5052
    #endif
5053
    }
5054
5055
    XMEMCPY(in, x509->deviceType, copySz);
5056
    *inOutSz = copySz;
5057
5058
    return in;
5059
}
5060
5061
5062
byte* wolfSSL_X509_get_hw_type(WOLFSSL_X509* x509, byte* in, int* inOutSz)
5063
{
5064
    int copySz;
5065
5066
    WOLFSSL_ENTER("wolfSSL_X509_get_hw_type");
5067
    if (x509 == NULL) return NULL;
5068
    if (inOutSz == NULL) return NULL;
5069
    if (!x509->hwTypeSz) return in;
5070
5071
    copySz = min(*inOutSz, x509->hwTypeSz);
5072
5073
    if (!in) {
5074
    #ifdef WOLFSSL_STATIC_MEMORY
5075
        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
5076
        return NULL;
5077
    #else
5078
        in = (byte*)XMALLOC(x509->hwTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
5079
        if (!in) return in;
5080
        copySz = x509->hwTypeSz;
5081
    #endif
5082
    }
5083
5084
    XMEMCPY(in, x509->hwType, copySz);
5085
    *inOutSz = copySz;
5086
5087
    return in;
5088
}
5089
5090
5091
byte* wolfSSL_X509_get_hw_serial_number(WOLFSSL_X509* x509,byte* in,
5092
                                        int* inOutSz)
5093
{
5094
    int copySz;
5095
5096
    WOLFSSL_ENTER("wolfSSL_X509_get_hw_serial_number");
5097
    if (x509 == NULL) return NULL;
5098
    if (inOutSz == NULL) return NULL;
5099
    if (!x509->hwTypeSz) return in;
5100
5101
    copySz = min(*inOutSz, x509->hwSerialNumSz);
5102
5103
    if (!in) {
5104
    #ifdef WOLFSSL_STATIC_MEMORY
5105
        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
5106
        return NULL;
5107
    #else
5108
        in = (byte*)XMALLOC(x509->hwSerialNumSz, 0, DYNAMIC_TYPE_OPENSSL);
5109
        if (!in) return in;
5110
        copySz = x509->hwSerialNumSz;
5111
    #endif
5112
    }
5113
5114
    XMEMCPY(in, x509->hwSerialNum, copySz);
5115
    *inOutSz = copySz;
5116
5117
    return in;
5118
}
5119
5120
#endif /* WOLFSSL_SEP */
5121
#endif /* OPENSSL_EXTRA */
5122
5123
/* require OPENSSL_EXTRA since wolfSSL_X509_free is wrapped by OPENSSL_EXTRA */
5124
#if defined(OPENSSL_EXTRA)
5125
5126
WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notBefore(const WOLFSSL_X509* x509)
5127
{
5128
    WOLFSSL_ENTER("wolfSSL_X509_get_notBefore");
5129
5130
    if (x509 == NULL)
5131
        return NULL;
5132
5133
    return (WOLFSSL_ASN1_TIME*)&x509->notBefore;
5134
}
5135
5136
5137
WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notAfter(const WOLFSSL_X509* x509)
5138
{
5139
    WOLFSSL_ENTER("wolfSSL_X509_get_notAfter");
5140
5141
    if (x509 == NULL)
5142
        return NULL;
5143
5144
    return (WOLFSSL_ASN1_TIME*)&x509->notAfter;
5145
}
5146
5147
5148
/* return number of elements on success 0 on fail */
5149
int wolfSSL_sk_X509_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk,
5150
    WOLFSSL_X509* x509)
5151
{
5152
    WOLFSSL_ENTER("wolfSSL_sk_X509_push");
5153
5154
    if (sk == NULL || x509 == NULL) {
5155
        return WOLFSSL_FAILURE;
5156
    }
5157
5158
    return wolfSSL_sk_push(sk, x509);
5159
}
5160
5161
5162
/* Return and remove the last x509 pushed on stack */
5163
WOLFSSL_X509* wolfSSL_sk_X509_pop(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk)
5164
{
5165
    return (WOLFSSL_X509*)wolfSSL_sk_pop(sk);
5166
}
5167
5168
/* Getter function for WOLFSSL_X509 pointer
5169
 *
5170
 * sk is the stack to retrieve pointer from
5171
 * i  is the index value in stack
5172
 *
5173
 * returns a pointer to a WOLFSSL_X509 structure on success and NULL on
5174
 *         fail
5175
 */
5176
WOLFSSL_X509* wolfSSL_sk_X509_value(WOLF_STACK_OF(WOLFSSL_X509)* sk, int i)
5177
{
5178
    WOLFSSL_ENTER("wolfSSL_sk_X509_value");
5179
5180
    for (; sk != NULL && i > 0; i--)
5181
        sk = sk->next;
5182
5183
    if (i != 0 || sk == NULL)
5184
        return NULL;
5185
    return sk->data.x509;
5186
}
5187
5188
5189
/* Return and remove the first x509 pushed on stack */
5190
WOLFSSL_X509* wolfSSL_sk_X509_shift(WOLF_STACK_OF(WOLFSSL_X509)* sk)
5191
{
5192
    return (WOLFSSL_X509*)wolfSSL_sk_pop_node(sk, 0);
5193
}
5194
5195
#endif /* OPENSSL_EXTRA */
5196
5197
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
5198
/* Free's all nodes in X509 stack. This is different then wolfSSL_sk_X509_free
5199
 * in that it free's the underlying objects pushed to the stack.
5200
 *
5201
 * sk  stack to free nodes in
5202
 * f   X509 free function
5203
 */
5204
void wolfSSL_sk_X509_pop_free(WOLF_STACK_OF(WOLFSSL_X509)* sk,
5205
    void (*f) (WOLFSSL_X509*))
5206
{
5207
    WOLFSSL_ENTER("wolfSSL_sk_X509_pop_free");
5208
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
5209
}
5210
5211
5212
/* free just the stack structure */
5213
void wolfSSL_sk_X509_free(WOLF_STACK_OF(WOLFSSL_X509)* sk)
5214
{
5215
    wolfSSL_sk_free(sk);
5216
}
5217
5218
#ifdef HAVE_CRL
5219
WOLFSSL_STACK* wolfSSL_sk_X509_CRL_new(void)
5220
{
5221
    WOLFSSL_STACK* s = wolfSSL_sk_new_node(NULL);
5222
    if (s != NULL)
5223
        s->type = STACK_TYPE_X509_CRL;
5224
    return s;
5225
}
5226
5227
WOLFSSL_STACK* wolfSSL_sk_X509_CRL_new_null(void)
5228
{
5229
    WOLFSSL_STACK* s = wolfSSL_sk_new_null();
5230
    if (s != NULL)
5231
        s->type = STACK_TYPE_X509_CRL;
5232
    return s;
5233
}
5234
5235
void wolfSSL_sk_X509_CRL_pop_free(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk,
5236
    void (*f) (WOLFSSL_X509_CRL*))
5237
{
5238
    WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_pop_free");
5239
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
5240
}
5241
5242
void wolfSSL_sk_X509_CRL_free(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk)
5243
{
5244
    wolfSSL_sk_X509_CRL_pop_free(sk, NULL);
5245
}
5246
5247
/* return number of elements on success 0 on fail */
5248
int wolfSSL_sk_X509_CRL_push(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk,
5249
    WOLFSSL_X509_CRL* crl)
5250
{
5251
    WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_push");
5252
5253
    if (sk == NULL || crl == NULL) {
5254
        return WOLFSSL_FAILURE;
5255
    }
5256
5257
    return wolfSSL_sk_push(sk, crl);
5258
}
5259
5260
WOLFSSL_X509_CRL* wolfSSL_sk_X509_CRL_value(WOLF_STACK_OF(WOLFSSL_X509)* sk,
5261
                                            int i)
5262
{
5263
    WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_value");
5264
    if (sk)
5265
        return (WOLFSSL_X509_CRL*)wolfSSL_sk_value(sk, i);
5266
    return NULL;
5267
}
5268
5269
int wolfSSL_sk_X509_CRL_num(WOLF_STACK_OF(WOLFSSL_X509)* sk)
5270
{
5271
    WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_num");
5272
    if (sk)
5273
        return wolfSSL_sk_num(sk);
5274
    return 0;
5275
}
5276
#endif /* HAVE_CRL */
5277
5278
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
5279
5280
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_QT)
5281
/* return number of elements on success 0 on fail */
5282
int wolfSSL_sk_ACCESS_DESCRIPTION_push(WOLF_STACK_OF(ACCESS_DESCRIPTION)* sk,
5283
                                              WOLFSSL_ACCESS_DESCRIPTION* a)
5284
{
5285
    WOLFSSL_ENTER("wolfSSL_sk_ACCESS_DESCRIPTION_push");
5286
5287
    return wolfSSL_sk_push(sk, a);
5288
}
5289
5290
/* Frees all nodes in ACCESS_DESCRIPTION stack
5291
*
5292
* sk stack of nodes to free
5293
* f  free function to use
5294
*/
5295
void wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(WOLFSSL_STACK* sk,
5296
    void (*f) (WOLFSSL_ACCESS_DESCRIPTION*))
5297
{
5298
   WOLFSSL_ENTER("wolfSSL_sk_ACCESS_DESCRIPTION_pop_free");
5299
   wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
5300
}
5301
5302
void wolfSSL_sk_ACCESS_DESCRIPTION_free(WOLFSSL_STACK* sk)
5303
{
5304
    wolfSSL_sk_free(sk);
5305
}
5306
5307
5308
/* AUTHORITY_INFO_ACCESS object is a stack of ACCESS_DESCRIPTION objects,
5309
 * to free the stack the WOLFSSL_ACCESS_DESCRIPTION stack free function is
5310
 * used */
5311
void wolfSSL_AUTHORITY_INFO_ACCESS_free(
5312
        WOLF_STACK_OF(WOLFSSL_ACCESS_DESCRIPTION)* sk)
5313
{
5314
    WOLFSSL_ENTER("wolfSSL_AUTHORITY_INFO_ACCESS_free");
5315
    wolfSSL_sk_ACCESS_DESCRIPTION_free(sk);
5316
}
5317
5318
void wolfSSL_AUTHORITY_INFO_ACCESS_pop_free(
5319
        WOLF_STACK_OF(WOLFSSL_ACCESS_DESCRIPTION)* sk,
5320
        void (*f) (WOLFSSL_ACCESS_DESCRIPTION*))
5321
{
5322
    WOLFSSL_ENTER("wolfSSL_AUTHORITY_INFO_ACCESS_free");
5323
    wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(sk, f);
5324
}
5325
5326
5327
void wolfSSL_ACCESS_DESCRIPTION_free(WOLFSSL_ACCESS_DESCRIPTION* a)
5328
{
5329
    WOLFSSL_ENTER("wolfSSL_ACCESS_DESCRIPTION_free");
5330
    if (a == NULL)
5331
        return;
5332
5333
    if (a->method)
5334
        wolfSSL_ASN1_OBJECT_free(a->method);
5335
    if (a->location)
5336
        wolfSSL_GENERAL_NAME_free(a->location);
5337
    XFREE(a, NULL, DYNAMIC_TYPE_X509_EXT);
5338
5339
    /* a = NULL, don't try to a or double free it */
5340
}
5341
#endif /* OPENSSL_EXTRA || WOLFSSL_QT */
5342
5343
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
5344
5345
/* Creates and returns new GENERAL_NAME structure */
5346
WOLFSSL_GENERAL_NAME* wolfSSL_GENERAL_NAME_new(void)
5347
{
5348
    WOLFSSL_GENERAL_NAME* gn;
5349
    WOLFSSL_ENTER("GENERAL_NAME_new");
5350
5351
    gn = (WOLFSSL_GENERAL_NAME*)XMALLOC(sizeof(WOLFSSL_GENERAL_NAME), NULL,
5352
                                                             DYNAMIC_TYPE_ASN1);
5353
    if (gn == NULL) {
5354
        return NULL;
5355
    }
5356
    XMEMSET(gn, 0, sizeof(WOLFSSL_GENERAL_NAME));
5357
5358
    gn->d.ia5 = wolfSSL_ASN1_STRING_new();
5359
    if (gn->d.ia5 == NULL) {
5360
        WOLFSSL_MSG("Issue creating ASN1_STRING struct");
5361
        wolfSSL_GENERAL_NAME_free(gn);
5362
        return NULL;
5363
    }
5364
    gn->type = WOLFSSL_GEN_IA5;
5365
    return gn;
5366
}
5367
5368
WOLFSSL_GENERAL_NAME* wolfSSL_GENERAL_NAME_dup(WOLFSSL_GENERAL_NAME* gn)
5369
{
5370
    WOLFSSL_GENERAL_NAME* dupl = NULL;
5371
5372
    WOLFSSL_ENTER("wolfSSL_GENERAL_NAME_dup");
5373
5374
    if (!gn) {
5375
        WOLFSSL_MSG("Bad parameter");
5376
        return NULL;
5377
    }
5378
5379
    if (!(dupl = wolfSSL_GENERAL_NAME_new())) {
5380
        WOLFSSL_MSG("wolfSSL_GENERAL_NAME_new error");
5381
        return NULL;
5382
    }
5383
5384
    wolfSSL_ASN1_STRING_free(dupl->d.ia5);
5385
    dupl->d.ia5 = NULL;
5386
    switch (gn->type) {
5387
    /* WOLFSSL_ASN1_STRING types */
5388
    case WOLFSSL_GEN_DNS:
5389
        if (!(dupl->d.dNSName = wolfSSL_ASN1_STRING_dup(gn->d.dNSName))) {
5390
            WOLFSSL_MSG("wolfSSL_ASN1_STRING_dup error");
5391
            goto error;
5392
        }
5393
        break;
5394
    case WOLFSSL_GEN_IPADD:
5395
        if (!(dupl->d.iPAddress = wolfSSL_ASN1_STRING_dup(gn->d.iPAddress))) {
5396
            WOLFSSL_MSG("wolfSSL_ASN1_STRING_dup error");
5397
            goto error;
5398
        }
5399
        break;
5400
    case WOLFSSL_GEN_EMAIL:
5401
        if (!(dupl->d.rfc822Name = wolfSSL_ASN1_STRING_dup(gn->d.rfc822Name))) {
5402
            WOLFSSL_MSG("wolfSSL_ASN1_STRING_dup error");
5403
            goto error;
5404
        }
5405
        break;
5406
    case WOLFSSL_GEN_URI:
5407
        if (!(dupl->d.uniformResourceIdentifier =
5408
                wolfSSL_ASN1_STRING_dup(gn->d.uniformResourceIdentifier))) {
5409
            WOLFSSL_MSG("wolfSSL_ASN1_STRING_dup error");
5410
            goto error;
5411
        }
5412
        break;
5413
    case WOLFSSL_GEN_OTHERNAME:
5414
        if (gn->d.otherName->value->type != WOLFSSL_V_ASN1_UTF8STRING) {
5415
            WOLFSSL_MSG("Unsupported othername value type");
5416
            goto error;
5417
        }
5418
        dupl->d.otherName = (WOLFSSL_ASN1_OTHERNAME*)XMALLOC(
5419
            sizeof(WOLFSSL_ASN1_OTHERNAME), NULL, DYNAMIC_TYPE_ASN1);
5420
        if (dupl->d.otherName == NULL) {
5421
            WOLFSSL_MSG("XMALLOC error");
5422
            goto error;
5423
        }
5424
        dupl->d.otherName->type_id = wolfSSL_ASN1_OBJECT_dup(
5425
            gn->d.otherName->type_id);
5426
        dupl->d.otherName->value = (WOLFSSL_ASN1_TYPE*)XMALLOC(
5427
            sizeof(WOLFSSL_ASN1_TYPE), NULL, DYNAMIC_TYPE_ASN1);
5428
        if (dupl->d.otherName->value != NULL) {
5429
            dupl->d.otherName->value->type = gn->d.otherName->value->type;
5430
            dupl->d.otherName->value->value.utf8string =
5431
                wolfSSL_ASN1_STRING_dup(
5432
                                      gn->d.otherName->value->value.utf8string);
5433
        }
5434
        if ((dupl->d.otherName->type_id == NULL) ||
5435
            (dupl->d.otherName->value == NULL) ||
5436
            (dupl->d.otherName->value->value.utf8string == NULL)) {
5437
            wolfSSL_ASN1_OBJECT_free(dupl->d.otherName->type_id);
5438
            wolfSSL_ASN1_TYPE_free(dupl->d.otherName->value);
5439
            XFREE(dupl->d.otherName, NULL, DYNAMIC_TYPE_ASN1);
5440
            dupl->d.otherName = NULL;
5441
            WOLFSSL_MSG("error duping othername");
5442
            goto error;
5443
        }
5444
        break;
5445
    case WOLFSSL_GEN_X400:
5446
    case WOLFSSL_GEN_DIRNAME:
5447
    case WOLFSSL_GEN_EDIPARTY:
5448
    case WOLFSSL_GEN_RID:
5449
    default:
5450
        WOLFSSL_MSG("Unrecognized or unsupported GENERAL_NAME type");
5451
        goto error;
5452
    }
5453
    dupl->type = gn->type;
5454
5455
    return dupl;
5456
error:
5457
    wolfSSL_GENERAL_NAME_free(dupl);
5458
    return NULL;
5459
}
5460
5461
/* Set an Othername in a general name.
5462
 *
5463
 * @param [out] gen     Pointer to the GENERAL_NAME where the othername is set.
5464
 * @param [in]  oid     Object ID (ie UPN).
5465
 * @param [in]  name    The actual name.
5466
 * @return  WOLFSSL_FAILURE on invalid parameter or memory error,
5467
 *          WOLFSSL_SUCCESS otherwise.
5468
 */
5469
int wolfSSL_GENERAL_NAME_set0_othername(WOLFSSL_GENERAL_NAME* gen,
5470
                                        WOLFSSL_ASN1_OBJECT* oid,
5471
                                        WOLFSSL_ASN1_TYPE* value)
5472
{
5473
    WOLFSSL_ASN1_OBJECT *x = NULL;
5474
5475
    if ((gen == NULL) || (oid == NULL) || (value == NULL)) {
5476
        return WOLFSSL_FAILURE;
5477
    }
5478
5479
    x = wolfSSL_ASN1_OBJECT_dup(oid);
5480
    if (x == NULL) {
5481
        WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_dup() failed");
5482
        return WOLFSSL_FAILURE;
5483
    }
5484
5485
    if (wolfSSL_GENERAL_NAME_set_type(gen, WOLFSSL_GEN_OTHERNAME)
5486
            != WOLFSSL_SUCCESS) {
5487
        wolfSSL_ASN1_OBJECT_free(x);
5488
        return WOLFSSL_FAILURE;
5489
    }
5490
5491
    gen->d.otherName->type_id = x;
5492
    gen->d.otherName->value = value;
5493
    return WOLFSSL_SUCCESS;
5494
}
5495
5496
/* return number of elements on success 0 on fail */
5497
int wolfSSL_sk_GENERAL_NAME_push(WOLFSSL_GENERAL_NAMES* sk,
5498
                                 WOLFSSL_GENERAL_NAME* gn)
5499
{
5500
    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_push");
5501
5502
    return wolfSSL_sk_push(sk, gn);
5503
}
5504
5505
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
5506
5507
#ifdef OPENSSL_EXTRA
5508
5509
/* Returns the general name at index i from the stack
5510
 *
5511
 * sk  stack to get general name from
5512
 * idx index to get
5513
 *
5514
 * return a pointer to the internal node of the stack
5515
 */
5516
WOLFSSL_GENERAL_NAME* wolfSSL_sk_GENERAL_NAME_value(WOLFSSL_STACK* sk, int idx)
5517
{
5518
    return (WOLFSSL_GENERAL_NAME*)wolfSSL_sk_value(sk, idx);
5519
}
5520
5521
/* Gets the number of nodes in the stack
5522
 *
5523
 * sk  stack to get the number of nodes from
5524
 *
5525
 * returns the number of nodes, -1 if no nodes
5526
 */
5527
int wolfSSL_sk_GENERAL_NAME_num(WOLFSSL_STACK* sk)
5528
{
5529
    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_num");
5530
5531
    return wolfSSL_sk_num(sk);
5532
}
5533
5534
/* Allocates an empty GENERAL NAME stack */
5535
WOLFSSL_STACK* wolfSSL_sk_GENERAL_NAME_new(void *cmpFunc) {
5536
    WOLFSSL_STACK* sk = NULL;
5537
    (void)cmpFunc;
5538
    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_new");
5539
5540
    sk = wolfSSL_sk_new_null();
5541
    if (sk != NULL) {
5542
        sk->type = STACK_TYPE_GEN_NAME;
5543
    }
5544
5545
    return sk;
5546
}
5547
#endif /* OPENSSL_EXTRA */
5548
5549
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
5550
5551
/* Frees all nodes in a GENERAL NAME stack
5552
 *
5553
 * sk stack of nodes to free
5554
 * f  free function to use, not called with wolfSSL
5555
 */
5556
void wolfSSL_sk_GENERAL_NAME_pop_free(WOLFSSL_STACK* sk,
5557
        void (*f) (WOLFSSL_GENERAL_NAME*))
5558
{
5559
    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_pop_free");
5560
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
5561
}
5562
5563
void wolfSSL_sk_GENERAL_NAME_free(WOLFSSL_STACK* sk)
5564
{
5565
    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_free");
5566
    wolfSSL_sk_X509_pop_free(sk, NULL);
5567
}
5568
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
5569
5570
#ifdef OPENSSL_EXTRA
5571
static void wolfSSL_DIST_POINT_NAME_free(WOLFSSL_DIST_POINT_NAME* dpn)
5572
{
5573
    if (dpn != NULL) {
5574
        if (dpn->name.fullname != NULL) {
5575
            wolfSSL_sk_X509_pop_free(dpn->name.fullname, NULL);
5576
        }
5577
        XFREE(dpn, NULL, DYNAMIC_TYPE_OPENSSL);
5578
    }
5579
}
5580
5581
5582
/* returns new pointer on success and NULL on fail */
5583
static WOLFSSL_DIST_POINT_NAME* wolfSSL_DIST_POINT_NAME_new(void)
5584
{
5585
    WOLFSSL_DIST_POINT_NAME* dpn = NULL;
5586
    WOLFSSL_GENERAL_NAMES* gns = NULL;
5587
5588
    dpn = (WOLFSSL_DIST_POINT_NAME*)XMALLOC(sizeof(WOLFSSL_DIST_POINT_NAME),
5589
                                            NULL, DYNAMIC_TYPE_OPENSSL);
5590
    if (dpn == NULL) {
5591
        return NULL;
5592
    }
5593
    XMEMSET(dpn, 0, sizeof(WOLFSSL_DIST_POINT_NAME));
5594
5595
    gns = wolfSSL_sk_new_null();
5596
    if (gns == NULL) {
5597
        WOLFSSL_MSG("wolfSSL_sk_new_null error");
5598
        XFREE(dpn, NULL, DYNAMIC_TYPE_OPENSSL);
5599
        return NULL;
5600
    }
5601
    gns->type = STACK_TYPE_GEN_NAME;
5602
5603
    /* DIST_POINT_NAME type may be 0 or 1, indicating whether fullname or
5604
     * relativename is used. See: RFC 5280 section 4.2.1.13 */
5605
    dpn->name.fullname = gns;
5606
    dpn->type = 0;
5607
5608
    return dpn;
5609
}
5610
5611
5612
/* Creates and returns new DIST_POINT structure */
5613
WOLFSSL_DIST_POINT* wolfSSL_DIST_POINT_new(void)
5614
{
5615
    WOLFSSL_DIST_POINT* dp = NULL;
5616
    WOLFSSL_DIST_POINT_NAME* dpn = NULL;
5617
5618
    WOLFSSL_ENTER("wolfSSL_DIST_POINT_new");
5619
5620
    dp = (WOLFSSL_DIST_POINT*)XMALLOC(sizeof(WOLFSSL_DIST_POINT), NULL,
5621
                                      DYNAMIC_TYPE_OPENSSL);
5622
    if (dp == NULL) {
5623
        return NULL;
5624
    }
5625
    XMEMSET(dp, 0, sizeof(WOLFSSL_DIST_POINT));
5626
5627
    dpn = wolfSSL_DIST_POINT_NAME_new();
5628
    if (dpn == NULL) {
5629
        XFREE(dp, NULL, DYNAMIC_TYPE_OPENSSL);
5630
        return NULL;
5631
    }
5632
    dp->distpoint = dpn;
5633
5634
    return dp;
5635
}
5636
5637
5638
/* Frees DIST_POINT objects.
5639
*/
5640
void wolfSSL_DIST_POINT_free(WOLFSSL_DIST_POINT* dp)
5641
{
5642
    WOLFSSL_ENTER("wolfSSL_DIST_POINT_free");
5643
    if (dp != NULL) {
5644
        wolfSSL_DIST_POINT_NAME_free(dp->distpoint);
5645
        XFREE(dp, NULL, DYNAMIC_TYPE_OPENSSL);
5646
    }
5647
}
5648
5649
void wolfSSL_DIST_POINTS_free(WOLFSSL_DIST_POINTS *dps)
5650
{
5651
    WOLFSSL_ENTER("wolfSSL_DIST_POINTS_free");
5652
5653
    if (dps == NULL) {
5654
        return;
5655
    }
5656
5657
    wolfSSL_sk_free(dps);
5658
}
5659
5660
/* return number of elements on success 0 on fail */
5661
int wolfSSL_sk_DIST_POINT_push(WOLFSSL_DIST_POINTS* sk, WOLFSSL_DIST_POINT* dp)
5662
{
5663
    WOLFSSL_ENTER("wolfSSL_sk_DIST_POINT_push");
5664
5665
    if (sk == NULL || dp == NULL) {
5666
        return WOLFSSL_FAILURE;
5667
    }
5668
5669
    return wolfSSL_sk_push(sk, dp);
5670
}
5671
5672
/* Returns the CRL dist point at index i from the stack
5673
 *
5674
 * sk  stack to get general name from
5675
 * idx index to get
5676
 *
5677
 * return a pointer to the internal node of the stack
5678
 */
5679
WOLFSSL_DIST_POINT* wolfSSL_sk_DIST_POINT_value(WOLFSSL_STACK* sk, int idx)
5680
{
5681
    if (sk == NULL) {
5682
        return NULL;
5683
    }
5684
5685
    return (WOLFSSL_DIST_POINT*)wolfSSL_sk_value(sk, idx);
5686
}
5687
5688
/* Gets the number of nodes in the stack
5689
 *
5690
 * sk  stack to get the number of nodes from
5691
 *
5692
 * returns the number of nodes, -1 if no nodes
5693
 */
5694
int wolfSSL_sk_DIST_POINT_num(WOLFSSL_STACK* sk)
5695
{
5696
    WOLFSSL_ENTER("wolfSSL_sk_DIST_POINT_num");
5697
5698
    if (sk == NULL) {
5699
        return WOLFSSL_FATAL_ERROR;
5700
    }
5701
5702
    return wolfSSL_sk_num(sk);
5703
}
5704
5705
/* Frees all nodes in a DIST_POINT stack
5706
 *
5707
 * sk stack of nodes to free
5708
 * f  free function to use
5709
 */
5710
void wolfSSL_sk_DIST_POINT_pop_free(WOLFSSL_STACK* sk,
5711
        void (*f) (WOLFSSL_DIST_POINT*))
5712
{
5713
    WOLFSSL_ENTER("wolfSSL_sk_DIST_POINT_pop_free");
5714
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
5715
}
5716
5717
void wolfSSL_sk_DIST_POINT_free(WOLFSSL_STACK* sk)
5718
{
5719
    WOLFSSL_ENTER("wolfSSL_sk_DIST_POINT_free");
5720
    wolfSSL_sk_free(sk);
5721
}
5722
5723
/* returns the number of nodes in stack on success and WOLFSSL_FATAL_ERROR
5724
 * on fail */
5725
int wolfSSL_sk_ACCESS_DESCRIPTION_num(WOLFSSL_STACK* sk)
5726
{
5727
    if (sk == NULL) {
5728
        return WOLFSSL_FATAL_ERROR;
5729
    }
5730
5731
    return (int)sk->num;
5732
}
5733
5734
/* returns NULL on fail and pointer to internal data on success */
5735
WOLFSSL_ACCESS_DESCRIPTION* wolfSSL_sk_ACCESS_DESCRIPTION_value(
5736
        WOLFSSL_STACK* sk, int idx)
5737
{
5738
    WOLFSSL_STACK* ret;
5739
5740
    if (sk == NULL) {
5741
        return NULL;
5742
    }
5743
5744
    ret = wolfSSL_sk_get_node(sk, idx);
5745
    if (ret != NULL) {
5746
        return ret->data.access;
5747
    }
5748
    return NULL;
5749
}
5750
#endif /* OPENSSL_EXTRA */
5751
5752
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
5753
/* free's the internal type for the general name */
5754
static void wolfSSL_GENERAL_NAME_type_free(WOLFSSL_GENERAL_NAME* name)
5755
{
5756
    if (name != NULL) {
5757
        switch (name->type) {
5758
        case WOLFSSL_GEN_IA5:
5759
            wolfSSL_ASN1_STRING_free(name->d.ia5);
5760
            name->d.ia5 = NULL;
5761
            break;
5762
        case WOLFSSL_GEN_EMAIL:
5763
            wolfSSL_ASN1_STRING_free(name->d.rfc822Name);
5764
            name->d.rfc822Name = NULL;
5765
            break;
5766
        case WOLFSSL_GEN_DNS:
5767
            wolfSSL_ASN1_STRING_free(name->d.dNSName);
5768
            name->d.dNSName = NULL;
5769
            break;
5770
        case WOLFSSL_GEN_DIRNAME:
5771
            wolfSSL_X509_NAME_free(name->d.dirn);
5772
            name->d.dirn = NULL;
5773
            break;
5774
        case WOLFSSL_GEN_URI:
5775
            wolfSSL_ASN1_STRING_free(name->d.uniformResourceIdentifier);
5776
            name->d.uniformResourceIdentifier = NULL;
5777
            break;
5778
        case WOLFSSL_GEN_IPADD:
5779
            wolfSSL_ASN1_STRING_free(name->d.iPAddress);
5780
            name->d.iPAddress = NULL;
5781
            break;
5782
        case WOLFSSL_GEN_RID:
5783
            wolfSSL_ASN1_OBJECT_free(name->d.registeredID);
5784
            name->d.registeredID = NULL;
5785
            break;
5786
        case WOLFSSL_GEN_OTHERNAME:
5787
            if (name->d.otherName != NULL) {
5788
                wolfSSL_ASN1_OBJECT_free(name->d.otherName->type_id);
5789
                wolfSSL_ASN1_TYPE_free(name->d.otherName->value);
5790
                XFREE(name->d.otherName, NULL, DYNAMIC_TYPE_ASN1);
5791
                name->d.otherName = NULL;
5792
            }
5793
            break;
5794
        case WOLFSSL_GEN_X400:
5795
            /* Unsupported: fall through */
5796
        case WOLFSSL_GEN_EDIPARTY:
5797
            /* Unsupported: fall through */
5798
        default:
5799
            WOLFSSL_MSG("wolfSSL_GENERAL_NAME_type_free: possible leak");
5800
            break;
5801
        }
5802
    }
5803
}
5804
5805
/* sets the general name type and free's the existing one
5806
 * can fail with a memory error if malloc fails or bad arg error
5807
 * otherwise return WOLFSSL_SUCCESS */
5808
int wolfSSL_GENERAL_NAME_set_type(WOLFSSL_GENERAL_NAME* name, int typ)
5809
{
5810
    int ret = WOLFSSL_SUCCESS;
5811
5812
    if (name != NULL) {
5813
        wolfSSL_GENERAL_NAME_type_free(name);
5814
        name->type = typ;
5815
5816
        switch (typ) {
5817
            case WOLFSSL_GEN_URI:
5818
                name->d.uniformResourceIdentifier = wolfSSL_ASN1_STRING_new();
5819
                if (name->d.uniformResourceIdentifier == NULL)
5820
                    ret = MEMORY_E;
5821
                break;
5822
            case WOLFSSL_GEN_OTHERNAME:
5823
                name->d.otherName = (WOLFSSL_ASN1_OTHERNAME*)XMALLOC(
5824
                    sizeof(WOLFSSL_ASN1_OTHERNAME), NULL, DYNAMIC_TYPE_ASN1);
5825
                if (name->d.otherName == NULL) {
5826
                    ret = MEMORY_E;
5827
                }
5828
                else {
5829
                    XMEMSET(name->d.otherName, 0, sizeof(WOLFSSL_ASN1_OTHERNAME));
5830
                }
5831
                break;
5832
            default:
5833
                name->type = WOLFSSL_GEN_IA5;
5834
                name->d.ia5 = wolfSSL_ASN1_STRING_new();
5835
                if (name->d.ia5 == NULL)
5836
                    ret = MEMORY_E;
5837
        }
5838
    }
5839
    else {
5840
        ret = BAD_FUNC_ARG;
5841
    }
5842
5843
    return ret;
5844
}
5845
5846
/* Set the value in a general name. This is a compat layer API.
5847
 *
5848
 * @param [out] a       Pointer to the GENERAL_NAME where the othername is set.
5849
 * @param [in]  type    The type of this general name.
5850
 * @param [in]  value   The ASN.1 string that is the value.
5851
 * @return none
5852
 * @note the set0 indicates we take ownership so the user does NOT free value.
5853
 */
5854
void wolfSSL_GENERAL_NAME_set0_value(WOLFSSL_GENERAL_NAME *a, int type,
5855
                                     void *value)
5856
{
5857
    WOLFSSL_ASN1_STRING *val = (WOLFSSL_ASN1_STRING *)value;
5858
    if (a == NULL) {
5859
        WOLFSSL_MSG("a is NULL");
5860
        return;
5861
    }
5862
5863
    if (val == NULL) {
5864
        WOLFSSL_MSG("value is NULL");
5865
        return;
5866
    }
5867
5868
    if (type != WOLFSSL_GEN_DNS) {
5869
        WOLFSSL_MSG("Only WOLFSSL_GEN_DNS is supported");
5870
        return;
5871
    }
5872
5873
    wolfSSL_GENERAL_NAME_type_free(a);
5874
    a->type = type;
5875
    /* Only when WOLFSSL_GEN_DNS. */
5876
    a->d.dNSName = val;
5877
}
5878
5879
/* Frees GENERAL_NAME objects.
5880
*/
5881
void wolfSSL_GENERAL_NAME_free(WOLFSSL_GENERAL_NAME* name)
5882
{
5883
    WOLFSSL_ENTER("wolfSSL_GENERAL_NAME_Free");
5884
    if (name != NULL) {
5885
        wolfSSL_GENERAL_NAME_type_free(name);
5886
        XFREE(name, NULL, DYNAMIC_TYPE_OPENSSL);
5887
    }
5888
}
5889
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL*/
5890
5891
#ifdef OPENSSL_EXTRA
5892
void wolfSSL_GENERAL_NAMES_free(WOLFSSL_GENERAL_NAMES *gens)
5893
{
5894
    WOLFSSL_ENTER("wolfSSL_GENERAL_NAMES_free");
5895
5896
    if (gens == NULL) {
5897
        return;
5898
    }
5899
5900
    wolfSSL_sk_GENERAL_NAME_free(gens);
5901
}
5902
5903
void wolfSSL_EXTENDED_KEY_USAGE_free(WOLFSSL_STACK * sk)
5904
{
5905
    WOLFSSL_ENTER("wolfSSL_EXTENDED_KEY_USAGE_free");
5906
5907
    if (sk == NULL) {
5908
        return;
5909
    }
5910
5911
    wolfSSL_sk_X509_pop_free(sk, NULL);
5912
}
5913
5914
#if !defined(IGNORE_NAME_CONSTRAINTS)
5915
/*
5916
 * Allocate and initialize an empty GENERAL_SUBTREE structure.
5917
 * Returns NULL on allocation failure.
5918
 */
5919
WOLFSSL_GENERAL_SUBTREE* wolfSSL_GENERAL_SUBTREE_new(void)
5920
{
5921
    WOLFSSL_GENERAL_SUBTREE* subtree;
5922
5923
    WOLFSSL_ENTER("wolfSSL_GENERAL_SUBTREE_new");
5924
5925
    subtree = (WOLFSSL_GENERAL_SUBTREE*)XMALLOC(sizeof(WOLFSSL_GENERAL_SUBTREE),
5926
                                                NULL, DYNAMIC_TYPE_OPENSSL);
5927
    if (subtree == NULL) {
5928
        WOLFSSL_MSG("Failed to allocate GENERAL_SUBTREE");
5929
        return NULL;
5930
    }
5931
    XMEMSET(subtree, 0, sizeof(WOLFSSL_GENERAL_SUBTREE));
5932
    return subtree;
5933
}
5934
5935
/*
5936
 * Create an empty NAME_CONSTRAINTS structure.
5937
 * Returns NULL on allocation failure.
5938
 */
5939
WOLFSSL_NAME_CONSTRAINTS* wolfSSL_NAME_CONSTRAINTS_new(void)
5940
{
5941
    WOLFSSL_NAME_CONSTRAINTS* nc;
5942
5943
    WOLFSSL_ENTER("wolfSSL_NAME_CONSTRAINTS_new");
5944
5945
    nc = (WOLFSSL_NAME_CONSTRAINTS*)XMALLOC(sizeof(WOLFSSL_NAME_CONSTRAINTS),
5946
                                            NULL, DYNAMIC_TYPE_OPENSSL);
5947
    if (nc == NULL) {
5948
        WOLFSSL_MSG("Failed to allocate NAME_CONSTRAINTS");
5949
        return NULL;
5950
    }
5951
    XMEMSET(nc, 0, sizeof(WOLFSSL_NAME_CONSTRAINTS));
5952
    return nc;
5953
}
5954
5955
/* Free a GENERAL_SUBTREE and its contents. */
5956
void wolfSSL_GENERAL_SUBTREE_free(WOLFSSL_GENERAL_SUBTREE* subtree)
5957
{
5958
    if (subtree == NULL) {
5959
        return;
5960
    }
5961
    wolfSSL_GENERAL_NAME_free(subtree->base);
5962
    XFREE(subtree, NULL, DYNAMIC_TYPE_OPENSSL);
5963
}
5964
5965
/* Free a NAME_CONSTRAINTS structure and all its contents. */
5966
void wolfSSL_NAME_CONSTRAINTS_free(WOLFSSL_NAME_CONSTRAINTS* nc)
5967
{
5968
    WOLFSSL_ENTER("wolfSSL_NAME_CONSTRAINTS_free");
5969
5970
    if (nc == NULL) {
5971
        return;
5972
    }
5973
5974
    if (nc->permittedSubtrees != NULL) {
5975
        wolfSSL_sk_pop_free(nc->permittedSubtrees,
5976
            (wolfSSL_sk_freefunc)wolfSSL_GENERAL_SUBTREE_free);
5977
    }
5978
5979
    if (nc->excludedSubtrees != NULL) {
5980
        wolfSSL_sk_pop_free(nc->excludedSubtrees,
5981
            (wolfSSL_sk_freefunc)wolfSSL_GENERAL_SUBTREE_free);
5982
    }
5983
5984
    XFREE(nc, NULL, DYNAMIC_TYPE_OPENSSL);
5985
}
5986
5987
/* Get number of items in GENERAL_SUBTREE stack. */
5988
int wolfSSL_sk_GENERAL_SUBTREE_num(const WOLFSSL_STACK* sk)
5989
{
5990
    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_SUBTREE_num");
5991
5992
    return wolfSSL_sk_num(sk);
5993
}
5994
5995
/* Get GENERAL_SUBTREE at index from stack. */
5996
WOLFSSL_GENERAL_SUBTREE* wolfSSL_sk_GENERAL_SUBTREE_value(
5997
    const WOLFSSL_STACK* sk, int idx)
5998
{
5999
    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_SUBTREE_value");
6000
6001
    return (WOLFSSL_GENERAL_SUBTREE*)wolfSSL_sk_value(sk, idx);
6002
}
6003
6004
/* Check IP address string matches constraint.
6005
 *
6006
 * name: IP address string (ex "192.168.1.50")
6007
 * nameSz: length of name string
6008
 * gn: GENERAL_NAME containing IP constraint (IP + mask bytes)
6009
 *
6010
 * Return 1 on match, otherwise 0
6011
 */
6012
static int MatchIpName(const char* name, int nameSz, WOLFSSL_GENERAL_NAME* gn)
6013
{
6014
    int ipLen = 0;
6015
    int constraintLen;
6016
    char ipStr[WOLFSSL_MAX_IPSTR];
6017
    unsigned char ipBytes[16]; /* Max 16 bytes for IPv6 */
6018
    const unsigned char* constraintData;
6019
6020
    if (name == NULL || nameSz <= 0 || gn == NULL || gn->d.iPAddress == NULL) {
6021
        return 0;
6022
    }
6023
6024
    constraintData = wolfSSL_ASN1_STRING_get0_data(gn->d.iPAddress);
6025
    constraintLen = wolfSSL_ASN1_STRING_length(gn->d.iPAddress);
6026
    if (constraintData == NULL || constraintLen <= 0) {
6027
        return 0;
6028
    }
6029
6030
    /* Null-terminate IP string */
6031
    if (nameSz >= (int)sizeof(ipStr)) {
6032
        return 0;
6033
    }
6034
    XMEMCPY(ipStr, name, nameSz);
6035
    ipStr[nameSz] = '\0';
6036
6037
    /* IPv4 constraint 8 bytes (IP + mask),
6038
     * IPv6 constraint 32 bytes (IP + mask) */
6039
    if (constraintLen == 8) {
6040
    #ifdef FREESCALE_MQX
6041
        if (XINET_PTON(WOLFSSL_IP4, ipStr, ipBytes, sizeof(ipBytes)) == RTCS_OK) {
6042
    #else
6043
        if (XINET_PTON(WOLFSSL_IP4, ipStr, ipBytes) == 1) {
6044
    #endif
6045
            ipLen = 4;
6046
        }
6047
    }
6048
    else if (constraintLen == 32) {
6049
    #ifdef FREESCALE_MQX
6050
        if (XINET_PTON(WOLFSSL_IP6, ipStr, ipBytes, sizeof(ipBytes)) == RTCS_OK) {
6051
    #else
6052
        if (XINET_PTON(WOLFSSL_IP6, ipStr, ipBytes) == 1) {
6053
    #endif
6054
            ipLen = 16;
6055
        }
6056
    }
6057
6058
    if (ipLen == 0) {
6059
        return 0;
6060
    }
6061
6062
    return wolfssl_local_MatchIpSubnet(ipBytes, ipLen,
6063
        constraintData, constraintLen);
6064
}
6065
6066
/* Helper to check if name string matches a single GENERAL_NAME constraint.
6067
 * permitted selects subtree semantics for wildcard DNS names: containment
6068
 * for permitted subtrees, intersection for excluded subtrees.
6069
 * Returns 1 if matches, 0 if not. */
6070
static int MatchNameConstraint(int type, const char* name, int nameSz,
6071
    WOLFSSL_GENERAL_NAME* gn, int permitted)
6072
{
6073
    const char* baseStr;
6074
    int baseLen;
6075
6076
    if (gn == NULL || gn->type != type) {
6077
        return 0;
6078
    }
6079
6080
    switch (type) {
6081
        case WOLFSSL_GEN_IPADD:
6082
            return MatchIpName(name, nameSz, gn);
6083
6084
        case WOLFSSL_GEN_DNS:
6085
        case WOLFSSL_GEN_EMAIL:
6086
        case WOLFSSL_GEN_URI:
6087
            if (gn->d.ia5 == NULL) {
6088
                return 0;
6089
            }
6090
            baseStr = (const char*)wolfSSL_ASN1_STRING_get0_data(gn->d.ia5);
6091
            baseLen = wolfSSL_ASN1_STRING_length(gn->d.ia5);
6092
            if (baseStr == NULL || baseLen <= 0) {
6093
                return 0;
6094
            }
6095
6096
            if (type == WOLFSSL_GEN_EMAIL) {
6097
                return wolfssl_local_MatchBaseName(ASN_RFC822_TYPE, name,
6098
                    nameSz, baseStr, baseLen);
6099
            }
6100
            else if (type == WOLFSSL_GEN_URI) {
6101
                return wolfssl_local_MatchUriNameConstraint(name, nameSz,
6102
                    baseStr, baseLen);
6103
            }
6104
            else {
6105
                /* WOLFSSL_GEN_DNS uses DNS-style matching */
6106
                return wolfssl_local_MatchDnsNameConstraint(name, nameSz,
6107
                    baseStr, baseLen, permitted);
6108
            }
6109
6110
        default:
6111
            /* Unsupported type */
6112
            return 0;
6113
    }
6114
}
6115
6116
static int NameConstraintsHasType(const WOLFSSL_STACK* sk, int type)
6117
{
6118
    int i;
6119
    int num;
6120
6121
    if (sk == NULL) {
6122
        return 0;
6123
    }
6124
6125
    num = wolfSSL_sk_GENERAL_SUBTREE_num(sk);
6126
    for (i = 0; i < num; i++) {
6127
        WOLFSSL_GENERAL_SUBTREE* subtree;
6128
6129
        subtree = wolfSSL_sk_GENERAL_SUBTREE_value(sk, i);
6130
        if (subtree != NULL && subtree->base != NULL &&
6131
                subtree->base->type == type) {
6132
            return 1;
6133
        }
6134
    }
6135
6136
    return 0;
6137
}
6138
6139
/*
6140
 * Check if a name string satisfies given name constraints.
6141
 *
6142
 * nc: NAME_CONSTRAINTS struct containing permitted/excluded subtrees
6143
 * type: GeneralName type (WOLFSSL_GEN_DNS, WOLFSSL_GEN_EMAIL, etc.)
6144
 * name: The name string to check
6145
 * nameSz: Length of name string
6146
 *
6147
 * Returns 1 if name satisfies constraints (permitted and not excluded),
6148
 * otherwise 0 if name does not satisfy constraints or on error
6149
 *
6150
 * A name satisfies constraints if permitted subtrees exist for the type,
6151
 * name matches at least one, and name does not match any excluded subtree.
6152
 */
6153
int wolfSSL_NAME_CONSTRAINTS_check_name(WOLFSSL_NAME_CONSTRAINTS* nc,
6154
    int type, const char* name, int nameSz)
6155
{
6156
    int i, num;
6157
    int hasPermittedType = 0;
6158
    int matchedPermitted = 0;
6159
    WOLFSSL_GENERAL_SUBTREE* subtree;
6160
    WOLFSSL_GENERAL_NAME* gn;
6161
6162
    WOLFSSL_ENTER("wolfSSL_NAME_CONSTRAINTS_check_name");
6163
6164
    if (nc == NULL || name == NULL || nameSz <= 0) {
6165
        WOLFSSL_MSG("Bad argument to NAME_CONSTRAINTS_check_name");
6166
        return 0;
6167
    }
6168
6169
    if (type == WOLFSSL_GEN_URI &&
6170
            (NameConstraintsHasType(nc->permittedSubtrees, type) ||
6171
             NameConstraintsHasType(nc->excludedSubtrees, type)) &&
6172
            !wolfssl_local_UriNameHasDnsHost(name, nameSz)) {
6173
        WOLFSSL_MSG("URI name constraint applied to URI without DNS host");
6174
        return 0;
6175
    }
6176
6177
    /* Check permitted subtrees */
6178
    if (nc->permittedSubtrees != NULL) {
6179
        num = wolfSSL_sk_GENERAL_SUBTREE_num(nc->permittedSubtrees);
6180
        for (i = 0; i < num; i++) {
6181
            subtree = wolfSSL_sk_GENERAL_SUBTREE_value(
6182
                nc->permittedSubtrees, i);
6183
            if (subtree == NULL || subtree->base == NULL) {
6184
                continue;
6185
            }
6186
6187
            gn = subtree->base;
6188
            if (gn->type != type) {
6189
                continue;
6190
            }
6191
            hasPermittedType = 1;
6192
6193
            if (MatchNameConstraint(type, name, nameSz, gn, 1)) {
6194
                matchedPermitted = 1;
6195
                break;
6196
            }
6197
        }
6198
    }
6199
6200
    /* If permitted constraints exist for this type but none matched, fail */
6201
    if (hasPermittedType && !matchedPermitted) {
6202
        WOLFSSL_MSG("Name not in permitted subtrees");
6203
        return 0;
6204
    }
6205
6206
    /* Check excluded subtrees */
6207
    if (nc->excludedSubtrees != NULL) {
6208
        num = wolfSSL_sk_GENERAL_SUBTREE_num(nc->excludedSubtrees);
6209
        for (i = 0; i < num; i++) {
6210
            subtree = wolfSSL_sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i);
6211
            if (subtree == NULL || subtree->base == NULL) {
6212
                continue;
6213
            }
6214
6215
            gn = subtree->base;
6216
            if (gn->type != type) {
6217
                continue;
6218
            }
6219
6220
            if (MatchNameConstraint(type, name, nameSz, gn, 0)) {
6221
                WOLFSSL_MSG("Name in excluded subtrees");
6222
                return 0;
6223
            }
6224
        }
6225
    }
6226
6227
    return 1;
6228
}
6229
#endif /* !IGNORE_NAME_CONSTRAINTS */
6230
6231
#ifndef NO_BIO
6232
static int wolfssl_x509_name_esc_value(const char* in, int inSz,
6233
                                       unsigned long flags, char* out);
6234
6235
/* Write pfx then val to bio with control characters escaped.
6236
 *
6237
 * Returns WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure.
6238
 */
6239
static int X509PrintEscStr(WOLFSSL_BIO* bio, const char* pfx,
6240
                           const char* val, int valSz)
6241
{
6242
    char buf[96];
6243
    int  ret = WOLFSSL_SUCCESS;
6244
    int  pfxSz = (int)XSTRLEN(pfx);
6245
    int  inSz = 0;
6246
    int  escSz;
6247
    int  i;
6248
6249
    if ((pfxSz > 0) && (wolfSSL_BIO_write(bio, pfx, pfxSz) != pfxSz)) {
6250
        ret = WOLFSSL_FAILURE;
6251
    }
6252
    /* ESC_CTRL ignores position and at most triples a byte, so chunk it. */
6253
    for (i = 0; (ret == WOLFSSL_SUCCESS) && (i < valSz); i += inSz) {
6254
        inSz = valSz - i;
6255
        if (inSz > (int)sizeof(buf) / 3) {
6256
            inSz = (int)sizeof(buf) / 3;
6257
        }
6258
        escSz = wolfssl_x509_name_esc_value(val + i, inSz,
6259
                    WOLFSSL_ASN1_STRFLGS_ESC_CTRL, buf);
6260
        if (wolfSSL_BIO_write(bio, buf, escSz) != escSz) {
6261
            ret = WOLFSSL_FAILURE;
6262
        }
6263
    }
6264
6265
    return ret;
6266
}
6267
#endif /* !NO_BIO */
6268
6269
#if defined(OPENSSL_ALL) && !defined(NO_BIO)
6270
/* Outputs name string of the given WOLFSSL_GENERAL_NAME_OBJECT to WOLFSSL_BIO.
6271
 * Can handle following GENERAL_NAME_OBJECT types:
6272
 *  - GEN_OTHERNAME #
6273
 *  - GEN_EMAIL
6274
 *  - GEN_DNS
6275
 *  - GEN_X400  #
6276
 *  - GEN_DIRNAME
6277
 *  - GEN_EDIPARTY #
6278
 *  - GEN_URI
6279
 *  - GEN_RID
6280
 * The each name string to be output has "typename:namestring" format.
6281
 * For instance, email name string will be output as "email:facts@wolfssl.com".
6282
 * However,some types above marked with "#" will be output with
6283
 * "typename:<unsupported>".
6284
 *
6285
 * Parameters:
6286
 *  - out: WOLFSSL_BIO object which is the output destination
6287
 *  - gen: WOLFSSL_GENERAL_NAME object to be output its name
6288
 *
6289
 * Returns WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure.
6290
 */
6291
int wolfSSL_GENERAL_NAME_print(WOLFSSL_BIO* out, WOLFSSL_GENERAL_NAME* gen)
6292
{
6293
    int ret, i;
6294
    unsigned int wd;
6295
    unsigned char* p;
6296
    (void)wd;
6297
    (void)p;
6298
    (void)i;
6299
    WOLFSSL_ENTER("wolfSSL_GENERAL_NAME_print");
6300
6301
    if (out == NULL || gen == NULL)
6302
        return WOLFSSL_FAILURE;
6303
6304
    ret = WOLFSSL_FAILURE;
6305
    switch (gen->type)
6306
    {
6307
    case GEN_OTHERNAME:
6308
        ret = wolfSSL_BIO_printf(out, "othername:<unsupported>");
6309
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
6310
        break;
6311
6312
    case GEN_EMAIL:
6313
        if (gen->d.rfc822Name != NULL) {
6314
            ret = X509PrintEscStr(out, "email:", gen->d.rfc822Name->data,
6315
                                  gen->d.rfc822Name->length);
6316
        }
6317
        break;
6318
6319
    case GEN_DNS:
6320
        if (gen->d.dNSName != NULL) {
6321
            ret = X509PrintEscStr(out, "DNS:", gen->d.dNSName->data,
6322
                                  gen->d.dNSName->length);
6323
        }
6324
        break;
6325
6326
    case GEN_X400:
6327
        ret = wolfSSL_BIO_printf(out, "X400Name:<unsupported>");
6328
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
6329
        break;
6330
6331
    case GEN_DIRNAME:
6332
        ret = wolfSSL_BIO_printf(out, "DirName:");
6333
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
6334
        if (ret == WOLFSSL_SUCCESS) {
6335
            ret = wolfSSL_X509_NAME_print_ex(out, gen->d.directoryName, 0,
6336
                                                         XN_FLAG_ONELINE);
6337
        }
6338
        break;
6339
6340
    case GEN_EDIPARTY:
6341
        ret = wolfSSL_BIO_printf(out, "EdiPartyName:<unsupported>");
6342
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
6343
        break;
6344
6345
    case GEN_URI:
6346
        if (gen->d.uniformResourceIdentifier != NULL) {
6347
            ret = X509PrintEscStr(out, "URI:",
6348
                                  gen->d.uniformResourceIdentifier->data,
6349
                                  gen->d.uniformResourceIdentifier->length);
6350
        }
6351
        break;
6352
6353
    case GEN_IPADD:
6354
        ret = wolfSSL_BIO_printf(out, "IP Address");
6355
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
6356
        if (ret == WOLFSSL_SUCCESS) {
6357
6358
            if (!gen->d.iPAddress->length) {
6359
                ret = WOLFSSL_FAILURE;
6360
                break;
6361
            }
6362
            p = (unsigned char*)gen->d.iPAddress->strData;
6363
6364
            if (gen->d.iPAddress->length == 4) {
6365
                ret = wolfSSL_BIO_printf(out, ":%d.%d.%d.%d",
6366
                                  p[0],p[1],p[2],p[3]);
6367
            }
6368
            else if (gen->d.iPAddress->length == 16) {
6369
6370
                for (i = 0; i < 16 && ret == WOLFSSL_SUCCESS;) {
6371
                    wd = p[i] << 8 | p[i+1];
6372
6373
                    i += 2;
6374
                    ret = wolfSSL_BIO_printf(out, ":%X", wd);
6375
                    ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
6376
                }
6377
            }
6378
            else {
6379
                ret = wolfSSL_BIO_printf(out, "<unsupported>");
6380
            }
6381
            ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
6382
        }
6383
        break;
6384
6385
    case GEN_RID:
6386
        ret = wolfSSL_BIO_printf(out, "Registered ID:");
6387
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
6388
        if (ret == WOLFSSL_SUCCESS) {
6389
            ret = wolfSSL_i2a_ASN1_OBJECT(out, gen->d.registeredID);
6390
        }
6391
        break;
6392
6393
    default:
6394
        /* unsupported type */
6395
        break;
6396
    }
6397
6398
    if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
6399
        return WOLFSSL_FAILURE;
6400
    else
6401
        return WOLFSSL_SUCCESS;
6402
}
6403
#endif /* OPENSSL_ALL */
6404
6405
WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* wolfSSL_sk_X509_EXTENSION_new_null(void)
6406
{
6407
    WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL);
6408
    if (sk) {
6409
        sk->type = STACK_TYPE_X509_EXT;
6410
    }
6411
6412
    return (WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)*)sk;;
6413
}
6414
6415
/* returns the number of nodes on the stack */
6416
int wolfSSL_sk_X509_EXTENSION_num(WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk)
6417
{
6418
    if (sk != NULL) {
6419
        return (int)sk->num;
6420
    }
6421
    return WOLFSSL_FATAL_ERROR;
6422
}
6423
6424
6425
/* returns null on failure and pointer to internal value on success */
6426
WOLFSSL_X509_EXTENSION* wolfSSL_sk_X509_EXTENSION_value(
6427
        const WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk, int idx)
6428
{
6429
    return (WOLFSSL_X509_EXTENSION*)wolfSSL_sk_value(sk, idx);
6430
}
6431
6432
/* frees all of the nodes and the values in stack */
6433
void wolfSSL_sk_X509_EXTENSION_pop_free(
6434
        WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk,
6435
        void (*f) (WOLFSSL_X509_EXTENSION*))
6436
{
6437
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
6438
}
6439
6440
void wolfSSL_sk_X509_EXTENSION_free(WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk)
6441
{
6442
    wolfSSL_sk_pop_free(sk, NULL);
6443
}
6444
6445
#endif /* OPENSSL_EXTRA */
6446
6447
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && \
6448
    !defined(NO_STDIO_FILESYSTEM)
6449
6450
WOLFSSL_X509* wolfSSL_X509_d2i_fp(WOLFSSL_X509** x509, XFILE file)
6451
{
6452
    WOLFSSL_X509* newX509 = NULL;
6453
6454
    WOLFSSL_ENTER("wolfSSL_X509_d2i_fp");
6455
6456
    if (file != XBADFILE) {
6457
        byte* fileBuffer = NULL;
6458
        long sz = 0;
6459
6460
        if (XFSEEK(file, 0, XSEEK_END) != 0)
6461
            return NULL;
6462
        sz = XFTELL(file);
6463
        if (XFSEEK(file, 0, XSEEK_SET) != 0)
6464
            return NULL;
6465
6466
        if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
6467
            WOLFSSL_MSG("X509_d2i file size error");
6468
            return NULL;
6469
        }
6470
6471
        fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
6472
        if (fileBuffer != NULL) {
6473
            int ret = (int)XFREAD(fileBuffer, 1, (size_t)sz, file);
6474
            if (ret == sz) {
6475
                newX509 = wolfSSL_X509_d2i(NULL, fileBuffer, (int)sz);
6476
            }
6477
            XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
6478
        }
6479
    }
6480
6481
    if (x509 != NULL)
6482
        *x509 = newX509;
6483
6484
    return newX509;
6485
}
6486
6487
#endif /* OPENSSL_EXTRA && !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM */
6488
6489
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
6490
    defined(WOLFSSL_WPAS_SMALL) || defined(KEEP_PEER_CERT) || \
6491
    defined(SESSION_CERTS)
6492
6493
#ifndef NO_FILESYSTEM
6494
WOLFSSL_ABI
6495
WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format)
6496
{
6497
#ifdef WOLFSSL_SMALL_STACK
6498
    byte  staticBuffer[1]; /* force heap usage */
6499
#else
6500
    byte  staticBuffer[FILE_BUFFER_SIZE];
6501
#endif
6502
    byte* fileBuffer = staticBuffer;
6503
    int   dynamic = 0;
6504
    int   ret;
6505
    long  sz = 0;
6506
    XFILE file;
6507
6508
    WOLFSSL_X509* x509 = NULL;
6509
6510
    /* Check the inputs */
6511
    if ((fname == NULL) ||
6512
        (format != WOLFSSL_FILETYPE_ASN1 && format != WOLFSSL_FILETYPE_PEM))
6513
        return NULL;
6514
6515
    file = XFOPEN(fname, "rb");
6516
    if (file == XBADFILE)
6517
        return NULL;
6518
6519
    if (XFSEEK(file, 0, XSEEK_END) != 0) {
6520
        XFCLOSE(file);
6521
        return NULL;
6522
    }
6523
    sz = XFTELL(file);
6524
    if (XFSEEK(file, 0, XSEEK_SET) != 0) {
6525
        XFCLOSE(file);
6526
        return NULL;
6527
    }
6528
6529
    if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
6530
        WOLFSSL_MSG("X509_load_certificate_file size error");
6531
        XFCLOSE(file);
6532
        return NULL;
6533
    }
6534
6535
    if (sz > (long)sizeof(staticBuffer)) {
6536
        fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
6537
        if (fileBuffer == NULL) {
6538
            XFCLOSE(file);
6539
            return NULL;
6540
        }
6541
        dynamic = 1;
6542
    }
6543
6544
    ret = (int)XFREAD(fileBuffer, 1, (size_t)sz, file);
6545
    if (ret != sz) {
6546
        XFCLOSE(file);
6547
        if (dynamic)
6548
            XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
6549
        return NULL;
6550
    }
6551
6552
    XFCLOSE(file);
6553
6554
    x509 = wolfSSL_X509_load_certificate_buffer(fileBuffer, (int)sz, format);
6555
6556
    if (dynamic)
6557
        XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
6558
6559
    return x509;
6560
}
6561
#endif /* !NO_FILESYSTEM */
6562
6563
static WOLFSSL_X509* loadX509orX509REQFromBuffer(
6564
    const unsigned char* buf, int sz, int format, int type,
6565
    wc_pem_password_cb *cb, void *u)
6566
{
6567
6568
    int ret = 0;
6569
    WOLFSSL_X509* x509 = NULL;
6570
    DerBuffer* der = NULL;
6571
6572
    WOLFSSL_ENTER("wolfSSL_X509_load_certificate_ex");
6573
6574
    if (format == WOLFSSL_FILETYPE_PEM) {
6575
        EncryptedInfo info;
6576
        XMEMSET(&info, 0, sizeof(EncryptedInfo));
6577
    #ifdef WOLFSSL_ENCRYPTED_KEYS
6578
        info.passwd_cb       = cb;
6579
        info.passwd_userdata = u;
6580
    #endif
6581
6582
    #ifdef WOLFSSL_PEM_TO_DER
6583
        ret = PemToDer(buf, sz, type, &der, NULL, &info, NULL);
6584
        if (ret != 0) {
6585
            FreeDer(&der);
6586
        }
6587
    #else
6588
        ret = NOT_COMPILED_IN;
6589
    #endif
6590
    }
6591
    else {
6592
        ret = AllocDer(&der, (word32)sz, type, NULL);
6593
        if (ret == 0) {
6594
            XMEMCPY(der->buffer, buf, sz);
6595
        }
6596
    }
6597
6598
    /* At this point we want `der` to have the certificate in DER format */
6599
    /* ready to be decoded. */
6600
    if (der != NULL && der->buffer != NULL) {
6601
        WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
6602
6603
        WC_ALLOC_VAR_EX(cert, DecodedCert, 1, NULL, DYNAMIC_TYPE_DCERT,
6604
            ret=MEMORY_ERROR);
6605
        if (WC_VAR_OK(cert))
6606
        {
6607
            InitDecodedCert(cert, der->buffer, der->length, NULL);
6608
            /* For TRUSTED_CERT_TYPE the DER buffer holds the certificate
6609
             * followed by auxiliary trust info. ParseCertRelative() recognizes
6610
             * the type: it parses only the certificate, permits the trailing
6611
             * aux data, and treats it as CERT_TYPE for verification.
6612
             * CopyDecodedToX509() bounds the stored DER to the certificate. */
6613
            ret = ParseCertRelative(cert, type, 0, NULL, NULL);
6614
            if (ret == 0) {
6615
                x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
6616
                                                             DYNAMIC_TYPE_X509);
6617
                if (x509 != NULL) {
6618
                    InitX509(x509, 1, NULL);
6619
                    ret = CopyDecodedToX509(x509, cert);
6620
                    if (ret != 0) {
6621
                        wolfSSL_X509_free(x509);
6622
                        x509 = NULL;
6623
                    }
6624
                }
6625
                else {
6626
                    ret = MEMORY_ERROR;
6627
                }
6628
            }
6629
6630
            FreeDecodedCert(cert);
6631
            WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
6632
        }
6633
6634
        FreeDer(&der);
6635
    }
6636
6637
    if (ret != 0) {
6638
        WOLFSSL_ERROR(ret);
6639
    }
6640
6641
    /* unused parameter when built without WOLFSSL_ENCRYPTED_KEYS */
6642
    (void)cb;
6643
    (void)u;
6644
    return x509;
6645
}
6646
6647
WOLFSSL_X509* wolfSSL_X509_load_certificate_buffer(
6648
    const unsigned char* buf, int sz, int format)
6649
{
6650
    return loadX509orX509REQFromBuffer(buf, sz,
6651
            format, CERT_TYPE, NULL, NULL);
6652
}
6653
6654
#ifdef WOLFSSL_CERT_REQ
6655
WOLFSSL_X509* wolfSSL_X509_REQ_load_certificate_buffer(
6656
    const unsigned char* buf, int sz, int format)
6657
{
6658
    return loadX509orX509REQFromBuffer(buf, sz,
6659
            format, CERTREQ_TYPE, NULL, NULL);
6660
}
6661
#endif
6662
6663
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || KEEP_PEER_CERT || \
6664
          SESSION_CERTS */
6665
6666
#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(KEEP_PEER_CERT) || \
6667
    defined(SESSION_CERTS)
6668
/* Smaller subset of X509 compatibility functions. Avoid increasing the size of
6669
 * this subset and its memory usage */
6670
6671
/* returns a pointer to a new WOLFSSL_X509 structure on success and NULL on
6672
 * fail
6673
 */
6674
WOLFSSL_X509* wolfSSL_X509_new_ex(void* heap)
6675
{
6676
    WOLFSSL_X509* x509;
6677
6678
    x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), heap,
6679
            DYNAMIC_TYPE_X509);
6680
    if (x509 != NULL) {
6681
        InitX509(x509, 1, heap);
6682
    }
6683
6684
    return x509;
6685
}
6686
6687
WOLFSSL_X509* wolfSSL_X509_new(void)
6688
{
6689
    return wolfSSL_X509_new_ex(NULL);
6690
}
6691
6692
WOLFSSL_ABI
6693
WOLFSSL_X509_NAME* wolfSSL_X509_get_subject_name(WOLFSSL_X509* cert)
6694
{
6695
    WOLFSSL_ENTER("wolfSSL_X509_get_subject_name");
6696
    if (cert)
6697
        return &cert->subject;
6698
    return NULL;
6699
}
6700
6701
WOLFSSL_ABI
6702
WOLFSSL_X509_NAME* wolfSSL_X509_get_issuer_name(WOLFSSL_X509* cert)
6703
{
6704
    WOLFSSL_ENTER("wolfSSL_X509_get_issuer_name");
6705
    if (cert)
6706
        return &cert->issuer;
6707
    return NULL;
6708
}
6709
6710
6711
int wolfSSL_X509_get_signature_type(WOLFSSL_X509* x509)
6712
{
6713
    int type = 0;
6714
6715
    WOLFSSL_ENTER("wolfSSL_X509_get_signature_type");
6716
6717
    if (x509 != NULL)
6718
        type = x509->sigOID;
6719
6720
    return type;
6721
}
6722
6723
#if defined(OPENSSL_EXTRA_X509_SMALL)
6724
6725
int wolfSSL_X509_NAME_get_sz(WOLFSSL_X509_NAME* name)
6726
{
6727
    WOLFSSL_ENTER("wolfSSL_X509_NAME_get_sz");
6728
    if (!name)
6729
        return WOLFSSL_FATAL_ERROR;
6730
    return name->sz;
6731
}
6732
6733
/* Searches for the first ENTRY of type NID
6734
 * idx is the location to start searching from, the value at when the entry was
6735
 *     found is stored into idx
6736
 * returns a pointer to the entry on success and null on fail */
6737
static WOLFSSL_X509_NAME_ENTRY* GetEntryByNID(WOLFSSL_X509_NAME* name, int nid,
6738
        int* idx)
6739
{
6740
    int i;
6741
    WOLFSSL_X509_NAME_ENTRY* ret = NULL;
6742
6743
    for (i = *idx; i < MAX_NAME_ENTRIES; i++) {
6744
        if (name->entry[i].nid == nid) {
6745
            ret = &name->entry[i];
6746
            *idx = i;
6747
            break;
6748
        }
6749
    }
6750
    return ret;
6751
}
6752
6753
6754
/* Used to get a string from the WOLFSSL_X509_NAME structure that
6755
 * corresponds with the NID value passed in. This finds the first entry with
6756
 * matching NID value, if searching for the case where there is multiple
6757
 * entries with the same NID value than other functions should be used
6758
 * (i.e. wolfSSL_X509_NAME_get_index_by_NID, wolfSSL_X509_NAME_get_entry)
6759
 *
6760
 * name structure to get string from
6761
 * nid  NID value to search for
6762
 * buf  [out] buffer to hold results. If NULL then the buffer size minus the
6763
 *      null char is returned.
6764
 * len  size of "buf" passed in
6765
 *
6766
 * returns the length of string found, not including the NULL terminator.
6767
 *         It's possible the function could return a negative value in the
6768
 *         case that len is less than or equal to 0. A negative value is
6769
 *         considered an error case.
6770
 */
6771
int wolfSSL_X509_NAME_get_text_by_NID(WOLFSSL_X509_NAME* name,
6772
                                      int nid, char* buf, int len)
6773
{
6774
    WOLFSSL_X509_NAME_ENTRY* e;
6775
    unsigned char *text = NULL;
6776
    int textSz = 0;
6777
    int idx    = 0;
6778
6779
    WOLFSSL_ENTER("wolfSSL_X509_NAME_get_text_by_NID");
6780
6781
    if (name == NULL) {
6782
        WOLFSSL_MSG("NULL argument passed in");
6783
        return WOLFSSL_FATAL_ERROR;
6784
    }
6785
6786
    e = GetEntryByNID(name, nid, &idx);
6787
    if (e == NULL) {
6788
        WOLFSSL_MSG("Entry type not found");
6789
        return WOLFSSL_FATAL_ERROR;
6790
    }
6791
    text   = wolfSSL_ASN1_STRING_data(e->value);
6792
    textSz = wolfSSL_ASN1_STRING_length(e->value);
6793
6794
    if (text == NULL) {
6795
        WOLFSSL_MSG("Unable to get entry text");
6796
        return WOLFSSL_FATAL_ERROR;
6797
    }
6798
6799
    /* if buf is NULL return size of buffer needed (minus null char) */
6800
    if (buf == NULL) {
6801
        WOLFSSL_MSG("Buffer is NULL, returning buffer size only");
6802
        return textSz;
6803
    }
6804
    if (len <= 0) {
6805
        return 0;
6806
    }
6807
6808
    /* + 1 to account for null char */
6809
    textSz = (int)min((word32)textSz + 1, (word32)len);
6810
    if (textSz > 0) {
6811
        XMEMCPY(buf, text, textSz - 1);
6812
        buf[textSz - 1] = '\0';
6813
    }
6814
6815
    WOLFSSL_LEAVE("wolfSSL_X509_NAME_get_text_by_NID", textSz);
6816
    return (textSz - 1); /* do not include null character in size */
6817
}
6818
6819
/* Creates a new WOLFSSL_EVP_PKEY structure that has the public key from x509
6820
 *
6821
 * returns a pointer to the created WOLFSSL_EVP_PKEY on success and NULL on fail
6822
 */
6823
WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
6824
{
6825
    WOLFSSL_EVP_PKEY* key = NULL;
6826
    int ret = 0;
6827
6828
    (void)ret;
6829
6830
    WOLFSSL_ENTER("wolfSSL_X509_get_pubkey");
6831
    if (x509 != NULL) {
6832
        key = wolfSSL_EVP_PKEY_new_ex(x509->heap);
6833
        if (key != NULL) {
6834
            if (x509->pubKeyOID == RSAk) {
6835
                key->type = WC_EVP_PKEY_RSA;
6836
            }
6837
            else if (x509->pubKeyOID == DSAk) {
6838
                key->type = WC_EVP_PKEY_DSA;
6839
            }
6840
        #ifdef WOLFSSL_HAVE_MLDSA
6841
            else if (x509->pubKeyOID == ML_DSA_44k ||
6842
                     x509->pubKeyOID == ML_DSA_65k ||
6843
                     x509->pubKeyOID == ML_DSA_87k
6844
        #ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
6845
                     || x509->pubKeyOID == DILITHIUM_LEVEL2k ||
6846
                     x509->pubKeyOID == DILITHIUM_LEVEL3k ||
6847
                     x509->pubKeyOID == DILITHIUM_LEVEL5k
6848
        #endif
6849
                     ) {
6850
                key->type = WC_EVP_PKEY_DILITHIUM;
6851
                WOLFSSL_ATOMIC_STORE(key->mldsaOID, x509->pubKeyOID);
6852
            }
6853
        #endif
6854
        #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
6855
            else if (x509->pubKeyOID == ED25519k) {
6856
                key->type = WC_EVP_PKEY_ED25519;
6857
            }
6858
        #endif
6859
            else {
6860
                key->type = WC_EVP_PKEY_EC;
6861
            }
6862
            key->save_type = 0;
6863
            key->pkey.ptr = (char*)XMALLOC(
6864
                        x509->pubKey.length, x509->heap,
6865
                                                       DYNAMIC_TYPE_PUBLIC_KEY);
6866
            if (key->pkey.ptr == NULL) {
6867
                wolfSSL_EVP_PKEY_free(key);
6868
                return NULL;
6869
            }
6870
            XMEMCPY(key->pkey.ptr, x509->pubKey.buffer, x509->pubKey.length);
6871
            key->pkey_sz = (int)x509->pubKey.length;
6872
6873
            #ifdef HAVE_ECC
6874
                key->pkey_curve = (int)x509->pkCurveOID;
6875
            #endif /* HAVE_ECC */
6876
6877
            /* decode RSA key */
6878
            #ifndef NO_RSA
6879
            if (key->type == WC_EVP_PKEY_RSA) {
6880
                key->ownRsa = 1;
6881
                key->rsa = wolfSSL_RSA_new();
6882
                if (key->rsa == NULL) {
6883
                    wolfSSL_EVP_PKEY_free(key);
6884
                    return NULL;
6885
                }
6886
6887
                if (wolfSSL_RSA_LoadDer_ex(key->rsa,
6888
                            (const unsigned char*)key->pkey.ptr, key->pkey_sz,
6889
                            WOLFSSL_RSA_LOAD_PUBLIC) != WOLFSSL_SUCCESS) {
6890
                    wolfSSL_EVP_PKEY_free(key);
6891
                    return NULL;
6892
                }
6893
            }
6894
            #endif /* NO_RSA */
6895
6896
            /* decode ECC key */
6897
            #if defined(HAVE_ECC) && defined(OPENSSL_EXTRA)
6898
            if (key->type == WC_EVP_PKEY_EC) {
6899
                word32 idx = 0;
6900
6901
                key->ownEcc = 1;
6902
                key->ecc = wolfSSL_EC_KEY_new();
6903
                if (key->ecc == NULL || key->ecc->internal == NULL) {
6904
                    wolfSSL_EVP_PKEY_free(key);
6905
                    return NULL;
6906
                }
6907
6908
                /* not using wolfSSL_EC_KEY_LoadDer because public key in x509
6909
                 * is in the format of x963 (no sequence at start of buffer) */
6910
                ret = wc_EccPublicKeyDecode((const unsigned char*)key->pkey.ptr,
6911
                                            &idx, (ecc_key*)key->ecc->internal,
6912
                                            key->pkey_sz);
6913
                if (ret < 0) {
6914
                    WOLFSSL_ERROR_VERBOSE(ret);
6915
                    WOLFSSL_MSG("wc_EccPublicKeyDecode failed");
6916
                    wolfSSL_EVP_PKEY_free(key);
6917
                    return NULL;
6918
                }
6919
6920
                if (SetECKeyExternal(key->ecc) != WOLFSSL_SUCCESS) {
6921
                    WOLFSSL_MSG("SetECKeyExternal failed");
6922
                    wolfSSL_EVP_PKEY_free(key);
6923
                    return NULL;
6924
                }
6925
6926
                key->ecc->inSet = 1;
6927
            }
6928
            #endif /* HAVE_ECC && OPENSSL_EXTRA */
6929
6930
            #ifndef NO_DSA
6931
            if (key->type == WC_EVP_PKEY_DSA) {
6932
                key->ownDsa = 1;
6933
                key->dsa = wolfSSL_DSA_new();
6934
                if (key->dsa == NULL) {
6935
                    wolfSSL_EVP_PKEY_free(key);
6936
                    return NULL;
6937
                }
6938
6939
                if (wolfSSL_DSA_LoadDer_ex(key->dsa,
6940
                            (const unsigned char*)key->pkey.ptr, key->pkey_sz, \
6941
                            WOLFSSL_DSA_LOAD_PUBLIC) != WOLFSSL_SUCCESS) {
6942
                    wolfSSL_DSA_free(key->dsa);
6943
                    key->dsa = NULL;
6944
                    wolfSSL_EVP_PKEY_free(key);
6945
                    return NULL;
6946
                }
6947
            }
6948
            #endif /* NO_DSA */
6949
6950
            /* decode Ed25519 key */
6951
            #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
6952
            if (key->type == WC_EVP_PKEY_ED25519) {
6953
                key->ed25519 = wolfSSL_ED25519_new(x509->heap, INVALID_DEVID);
6954
                if (key->ed25519 == NULL) {
6955
                    wolfSSL_EVP_PKEY_free(key);
6956
                    return NULL;
6957
                }
6958
                key->ownEd25519 = 1;
6959
6960
                /* The X.509 public key buffer holds the raw Ed25519 key
6961
                 * (CopyDecodedToX509 / StoreKey store the BIT STRING
6962
                 * contents), so import it directly. */
6963
                if (wc_ed25519_import_public(
6964
                            (const unsigned char*)key->pkey.ptr,
6965
                            (word32)key->pkey_sz, key->ed25519) != 0) {
6966
                    WOLFSSL_MSG("wc_ed25519_import_public failed");
6967
                    wolfSSL_EVP_PKEY_free(key);
6968
                    return NULL;
6969
                }
6970
            }
6971
            #endif /* HAVE_ED25519 */
6972
6973
            /* re-encode ML-DSA key */
6974
            #if defined(WOLFSSL_HAVE_MLDSA) && \
6975
                defined(WOLFSSL_MLDSA_PUBLIC_KEY) && \
6976
                !defined(WOLFSSL_MLDSA_NO_ASN1) && \
6977
                defined(WC_ENABLE_ASYM_KEY_EXPORT) && \
6978
                (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL))
6979
            if (key->type == WC_EVP_PKEY_DILITHIUM) {
6980
                byte* spki = NULL;
6981
                word32 spkiSz = 0;
6982
6983
                /* The buffer holds the raw key. Encode to SPKI so the i2d
6984
                 * functions work fine */
6985
                if (wolfssl_i_mldsa_raw_pub_to_der((const byte*)key->pkey.ptr,
6986
                        (word32)key->pkey_sz, x509->pubKeyOID, &spki, &spkiSz,
6987
                        x509->heap) != 0) {
6988
                    WOLFSSL_MSG("wolfssl_i_mldsa_raw_pub_to_der failed");
6989
                    wolfSSL_EVP_PKEY_free(key);
6990
                    return NULL;
6991
                }
6992
                XFREE(key->pkey.ptr, x509->heap, DYNAMIC_TYPE_PUBLIC_KEY);
6993
                key->pkey.ptr = (char*)spki;
6994
                key->pkey_sz = (int)spkiSz;
6995
            }
6996
            #endif /* WOLFSSL_HAVE_MLDSA */
6997
        }
6998
    }
6999
    return key;
7000
}
7001
#endif /* OPENSSL_EXTRA_X509_SMALL */
7002
7003
/* End of smaller subset of X509 compatibility functions. Avoid increasing the
7004
 * size of this subset and its memory usage */
7005
#endif /* OPENSSL_EXTRA_X509_SMALL || KEEP_PEER_CERT || SESSION_CERTS */
7006
7007
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
7008
/*
7009
 * Converts a and b to DER and then does an XMEMCMP to check if they match.
7010
 * Returns 0 when certificates match and WOLFSSL_FATAL_ERROR when they don't.
7011
 */
7012
int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b)
7013
{
7014
        const byte* derA;
7015
        const byte* derB;
7016
        int outSzA = 0;
7017
        int outSzB = 0;
7018
7019
        if (a == NULL || b == NULL) {
7020
            return BAD_FUNC_ARG;
7021
        }
7022
7023
        derA = wolfSSL_X509_get_der((WOLFSSL_X509*)a, &outSzA);
7024
        if (derA == NULL) {
7025
            WOLFSSL_MSG("wolfSSL_X509_get_der - certificate A has failed");
7026
            return WOLFSSL_FATAL_ERROR;
7027
        }
7028
        derB = wolfSSL_X509_get_der((WOLFSSL_X509*)b, &outSzB);
7029
        if (derB == NULL) {
7030
            WOLFSSL_MSG("wolfSSL_X509_get_der - certificate B has failed");
7031
            return WOLFSSL_FATAL_ERROR;
7032
        }
7033
7034
        if (outSzA != outSzB || XMEMCMP(derA, derB, outSzA) != 0) {
7035
            WOLFSSL_LEAVE("wolfSSL_X509_cmp", WOLFSSL_FATAL_ERROR);
7036
            return WOLFSSL_FATAL_ERROR;
7037
        }
7038
7039
        WOLFSSL_LEAVE("wolfSSL_X509_cmp", 0);
7040
7041
        return 0;
7042
    }
7043
#endif /* OPENSSL_ALL */
7044
7045
#if defined(OPENSSL_EXTRA)
7046
    int wolfSSL_X509_ext_isSet_by_NID(WOLFSSL_X509* x509, int nid)
7047
    {
7048
        int isSet = 0;
7049
7050
        WOLFSSL_ENTER("wolfSSL_X509_ext_isSet_by_NID");
7051
7052
        if (x509 != NULL) {
7053
            switch (nid) {
7054
                case WC_NID_basic_constraints:
7055
                    isSet = x509->basicConstSet; break;
7056
                case WC_NID_subject_alt_name:
7057
                    isSet = x509->subjAltNameSet; break;
7058
                case WC_NID_authority_key_identifier:
7059
                    isSet = x509->authKeyIdSet; break;
7060
                case WC_NID_subject_key_identifier:
7061
                    isSet = x509->subjKeyIdSet; break;
7062
                case WC_NID_key_usage:
7063
                    isSet = x509->keyUsageSet; break;
7064
                case WC_NID_crl_distribution_points:
7065
                    isSet = x509->CRLdistSet; break;
7066
                case WC_NID_ext_key_usage:
7067
                    isSet = ((x509->extKeyUsageSrc) ? 1 : 0); break;
7068
                case WC_NID_info_access:
7069
                    isSet = x509->authInfoSet; break;
7070
            #if defined(WOLFSSL_SEP) || defined(WOLFSSL_QT)
7071
                case WC_NID_certificate_policies:
7072
                    isSet = x509->certPolicySet; break;
7073
            #endif /* WOLFSSL_SEP || WOLFSSL_QT */
7074
                default:
7075
                    WOLFSSL_MSG("NID not in table");
7076
            }
7077
        }
7078
7079
        WOLFSSL_LEAVE("wolfSSL_X509_ext_isSet_by_NID", isSet);
7080
7081
        return isSet;
7082
    }
7083
7084
7085
    int wolfSSL_X509_ext_get_critical_by_NID(WOLFSSL_X509* x509, int nid)
7086
    {
7087
        int crit = 0;
7088
7089
        WOLFSSL_ENTER("wolfSSL_X509_ext_get_critical_by_NID");
7090
7091
        if (x509 != NULL) {
7092
            switch (nid) {
7093
                case WC_NID_basic_constraints:
7094
                    crit = x509->basicConstCrit; break;
7095
                case WC_NID_subject_alt_name:
7096
                    crit = x509->subjAltNameCrit; break;
7097
                case WC_NID_authority_key_identifier:
7098
                    crit = x509->authKeyIdCrit; break;
7099
                case WC_NID_subject_key_identifier:
7100
                    crit = x509->subjKeyIdCrit; break;
7101
                case WC_NID_key_usage:
7102
                    crit = x509->keyUsageCrit; break;
7103
                case WC_NID_crl_distribution_points:
7104
                    crit= x509->CRLdistCrit; break;
7105
                case WC_NID_ext_key_usage:
7106
                    crit= x509->extKeyUsageCrit; break;
7107
            #ifdef WOLFSSL_SEP
7108
                case WC_NID_certificate_policies:
7109
                    crit = x509->certPolicyCrit; break;
7110
            #endif /* WOLFSSL_SEP */
7111
            }
7112
        }
7113
7114
        WOLFSSL_LEAVE("wolfSSL_X509_ext_get_critical_by_NID", crit);
7115
7116
        return crit;
7117
    }
7118
7119
7120
    int wolfSSL_X509_get_isSet_pathLength(WOLFSSL_X509* x509)
7121
    {
7122
        int isSet = 0;
7123
7124
        WOLFSSL_ENTER("wolfSSL_X509_get_isSet_pathLength");
7125
7126
        if (x509 != NULL)
7127
            isSet = x509->basicConstPlSet;
7128
7129
        WOLFSSL_LEAVE("wolfSSL_X509_get_isSet_pathLength", isSet);
7130
7131
        return isSet;
7132
    }
7133
7134
7135
    word32 wolfSSL_X509_get_pathLength(WOLFSSL_X509* x509)
7136
    {
7137
        word32 pathLength = 0;
7138
7139
        WOLFSSL_ENTER("wolfSSL_X509_get_pathLength");
7140
7141
        if (x509 != NULL)
7142
            pathLength = x509->pathLength;
7143
7144
        WOLFSSL_LEAVE("wolfSSL_X509_get_pathLength", pathLength);
7145
7146
        return pathLength;
7147
    }
7148
7149
7150
    unsigned int wolfSSL_X509_get_keyUsage(WOLFSSL_X509* x509)
7151
    {
7152
        word16 usage = 0;
7153
7154
        WOLFSSL_ENTER("wolfSSL_X509_get_keyUsage");
7155
7156
        if (x509 != NULL)
7157
            usage = x509->keyUsage;
7158
7159
        WOLFSSL_LEAVE("wolfSSL_X509_get_keyUsage", usage);
7160
7161
        return usage;
7162
    }
7163
7164
7165
    byte* wolfSSL_X509_get_authorityKeyID(WOLFSSL_X509* x509,
7166
                                          byte* dst, int* dstLen)
7167
    {
7168
        byte *id = NULL;
7169
        int copySz = 0;
7170
7171
        WOLFSSL_ENTER("wolfSSL_X509_get_authorityKeyID");
7172
7173
        if (x509 != NULL) {
7174
            if (x509->authKeyIdSet) {
7175
                copySz = (int)min(dstLen != NULL ? (word32)*dstLen : 0,
7176
                                  x509->authKeyIdSz);
7177
                id = x509->authKeyId;
7178
            }
7179
7180
            if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
7181
                XMEMCPY(dst, id, copySz);
7182
                id = dst;
7183
                *dstLen = copySz;
7184
            }
7185
        }
7186
7187
        WOLFSSL_LEAVE("wolfSSL_X509_get_authorityKeyID", copySz);
7188
7189
        return id;
7190
    }
7191
7192
    byte* wolfSSL_X509_get_subjectKeyID(WOLFSSL_X509* x509,
7193
                                        byte* dst, int* dstLen)
7194
    {
7195
        byte *id = NULL;
7196
        int copySz = 0;
7197
7198
        WOLFSSL_ENTER("wolfSSL_X509_get_subjectKeyID");
7199
7200
        if (x509 != NULL) {
7201
            if (x509->subjKeyIdSet) {
7202
                copySz = (int)min(dstLen != NULL ? (word32) *dstLen : 0,
7203
                                  x509->subjKeyIdSz);
7204
                id = x509->subjKeyId;
7205
            }
7206
7207
            if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
7208
                XMEMCPY(dst, id, copySz);
7209
                id = dst;
7210
                *dstLen = copySz;
7211
            }
7212
        }
7213
7214
        WOLFSSL_LEAVE("wolfSSL_X509_get_subjectKeyID", copySz);
7215
7216
        return id;
7217
    }
7218
7219
    const WOLFSSL_ASN1_STRING *wolfSSL_X509_get0_subject_key_id(
7220
            WOLFSSL_X509 *x509)
7221
    {
7222
        WOLFSSL_ASN1_STRING* ret = NULL;
7223
7224
        WOLFSSL_ENTER("wolfSSL_X509_get0_subject_key_id");
7225
7226
        if (x509 != NULL && x509->subjKeyIdSet) {
7227
            if (x509->subjKeyIdStr == NULL) {
7228
                x509->subjKeyIdStr = wolfSSL_ASN1_STRING_new();
7229
                if (x509->subjKeyIdStr != NULL) {
7230
                    if (wolfSSL_ASN1_STRING_set(x509->subjKeyIdStr,
7231
                            x509->subjKeyId, x509->subjKeyIdSz) == 1) {
7232
                    }
7233
                    else {
7234
                        wolfSSL_ASN1_STRING_free(x509->subjKeyIdStr);
7235
                        x509->subjKeyIdStr = NULL;
7236
                    }
7237
                }
7238
            }
7239
            ret = x509->subjKeyIdStr;
7240
        }
7241
7242
        WOLFSSL_LEAVE("wolfSSL_X509_get0_subject_key_id", ret != NULL);
7243
7244
        return ret;
7245
    }
7246
#endif /* OPENSSL_EXTRA */
7247
7248
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
7249
    defined(OPENSSL_EXTRA_X509_SMALL)
7250
7251
    /* Looks up the index of the first entry encountered with matching NID
7252
     * The search starts from index 'pos'
7253
     * returns a negative value on failure and positive index value on success*/
7254
    int wolfSSL_X509_NAME_get_index_by_NID(WOLFSSL_X509_NAME* name,
7255
                                          int nid, int pos)
7256
    {
7257
        int value = nid, i;
7258
7259
        WOLFSSL_ENTER("wolfSSL_X509_NAME_get_index_by_NID");
7260
7261
        if (name == NULL) {
7262
            return BAD_FUNC_ARG;
7263
        }
7264
7265
        i = pos + 1; /* start search after index passed in */
7266
        if (i < 0) {
7267
            i = 0;
7268
        }
7269
7270
        for (;i < name->entrySz && i < MAX_NAME_ENTRIES; i++) {
7271
            if (name->entry[i].nid == value) {
7272
                return i;
7273
            }
7274
        }
7275
        return WOLFSSL_FATAL_ERROR;
7276
    }
7277
7278
7279
    WOLFSSL_ASN1_STRING*  wolfSSL_X509_NAME_ENTRY_get_data(
7280
                                                    WOLFSSL_X509_NAME_ENTRY* in)
7281
    {
7282
        WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_get_data");
7283
        if (in == NULL)
7284
            return NULL;
7285
7286
        return in->value;
7287
    }
7288
7289
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
7290
7291
#ifdef OPENSSL_EXTRA
7292
#ifndef NO_BIO
7293
7294
#ifndef MAX_WIDTH
7295
    #define MAX_WIDTH 80
7296
#endif
7297
7298
#define ACERT_NUM_DIR_TAGS 4
7299
7300
/* Convenience struct and function for printing the Holder sub fields
7301
 * of an X509 Attribute struct. */
7302
struct acert_dir_print_t {
7303
    const char * pfx;
7304
    const byte   tag[3];
7305
};
7306
7307
static struct acert_dir_print_t acert_dir_print[ACERT_NUM_DIR_TAGS] =
7308
{
7309
    { "C=", {0x55, 0x04, ASN_COUNTRY_NAME} },
7310
    { "O=", {0x55, 0x04, ASN_ORG_NAME} },
7311
    { "OU=", {0x55, 0x04, ASN_ORGUNIT_NAME} },
7312
    { "CN=", {0x55, 0x04, ASN_COMMON_NAME} },
7313
};
7314
7315
/* Print an entry of ASN_DIR_TYPE to bio.
7316
 *
7317
 * Returns WOLFSSL_SUCCESS on success.
7318
 * Returns WOLFSSL_FAILURE on failure.
7319
 * */
7320
static int X509PrintDirType(WOLFSSL_BIO* bio, const DNS_entry * entry)
7321
{
7322
    word32       k = 0;
7323
    word32       i = 0;
7324
    const char * src = entry->name;
7325
    word32       src_len = 0;
7326
    int          fld_len = 0;
7327
    int          ret = WOLFSSL_SUCCESS;
7328
    int          match_found = 0;
7329
7330
    /* The entry holds raw DER which may contain zero bytes, and under
7331
     * WC_ASN_NO_HEAP it is not NUL terminated, so use the stored length. */
7332
    if (entry->len > 0) {
7333
        src_len = (word32)entry->len;
7334
    }
7335
7336
    /* loop over printable DIR tags. */
7337
    for (k = 0; (ret == WOLFSSL_SUCCESS) && (k < ACERT_NUM_DIR_TAGS); ++k) {
7338
        const char * pfx = acert_dir_print[k].pfx;
7339
        const byte * tag = acert_dir_print[k].tag;
7340
        byte         asn_tag;
7341
7342
        /* Walk through entry looking for matches. A match needs three bytes
7343
         * of name OID plus a tag and a length, so the last offset worth
7344
         * testing is the one with exactly five bytes left. Written as an
7345
         * addition so a short entry simply skips the loop rather than
7346
         * underflowing the bound. */
7347
        for (i = 0; i + 5 <= src_len; ++i) {
7348
            if (XMEMCMP(tag, &src[i], 3) == 0) {
7349
                i += 3;
7350
7351
                /* Get the ASN Tag. */
7352
                if (GetASNTag((const byte *)src, &i, &asn_tag, src_len) < 0) {
7353
                    WOLFSSL_MSG("error: GetASNTag failed");
7354
                    break;
7355
                }
7356
7357
                /* Check it is printable. */
7358
                if ((asn_tag != ASN_PRINTABLE_STRING) &&
7359
                    (asn_tag != ASN_IA5_STRING) &&
7360
                    (asn_tag != ASN_UTF8STRING)) {
7361
                    /* Don't know what this is but we can't print it. */
7362
                    WOLFSSL_MSG("error: asn tag not printable string");
7363
                    break;
7364
                }
7365
7366
                /* Now get the length of the printable string. */
7367
                if (GetLength((const byte *)src, &i, &fld_len, src_len) < 0) {
7368
                    break;
7369
                }
7370
7371
                if (match_found && (wolfSSL_BIO_puts(bio, ", ") <= 0)) {
7372
                    ret = WOLFSSL_FAILURE;
7373
                }
7374
                if (ret == WOLFSSL_SUCCESS) {
7375
                    ret = X509PrintEscStr(bio, pfx, &src[i], fld_len);
7376
                }
7377
                if (ret != WOLFSSL_SUCCESS) {
7378
                    break;
7379
                }
7380
                i += fld_len;
7381
7382
                match_found = 1;
7383
            }
7384
        }
7385
    }
7386
7387
    if ((ret == WOLFSSL_SUCCESS) && !match_found) {
7388
        /* Nothing in the encoding was printable. Emit a placeholder, as the
7389
         * other unsupported entry types do, rather than failing the print of
7390
         * the whole certificate. */
7391
        if (wolfSSL_BIO_puts(bio, "DirName:<unprintable>") <= 0) {
7392
            ret = WOLFSSL_FAILURE;
7393
        }
7394
    }
7395
7396
    return ret;
7397
}
7398
static int X509_print_name_entry(WOLFSSL_BIO* bio,
7399
                                 const DNS_entry* entry, int indent)
7400
{
7401
    int  ret = WOLFSSL_SUCCESS;
7402
    int  nameCount = 0;
7403
    char scratch[MAX_WIDTH];
7404
    int  len;
7405
7406
    if (bio == NULL || entry == NULL) {
7407
        return WOLFSSL_FAILURE;
7408
    }
7409
7410
    len = XSNPRINTF(scratch, MAX_WIDTH, "%*s", indent, "");
7411
    if (len >= MAX_WIDTH) {
7412
        return WOLFSSL_FAILURE;
7413
    }
7414
7415
    if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) {
7416
        return WOLFSSL_FAILURE;
7417
    }
7418
7419
    while (entry != NULL) {
7420
        ++nameCount;
7421
        if (nameCount > 1) {
7422
            if (wolfSSL_BIO_write(bio, ", ", 2) <= 0) {
7423
                ret = WOLFSSL_FAILURE;
7424
                break;
7425
            }
7426
        }
7427
7428
        /* Escaped values go straight to bio, the rest through scratch. */
7429
        len = 0;
7430
        if (entry->type == ASN_DNS_TYPE) {
7431
            ret = X509PrintEscStr(bio, "DNS:", entry->name, entry->len);
7432
        }
7433
    #if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
7434
        else if (entry->type == ASN_IP_TYPE) {
7435
            len = XSNPRINTF(scratch, MAX_WIDTH, "IP Address:%s",
7436
                    entry->ipString);
7437
        }
7438
    #else
7439
        else if (entry->type == ASN_IP_TYPE) {
7440
            /* iPAddress entries are now always parsed into altNames so
7441
             * name constraints can be enforced. Without the
7442
             * human-readable ipString field, emit a fixed label so this
7443
             * print path does not fail. */
7444
            len = XSNPRINTF(scratch, MAX_WIDTH, "IP Address:<unavailable>");
7445
        }
7446
    #endif /* OPENSSL_ALL || WOLFSSL_IP_ALT_NAME */
7447
        else if (entry->type == ASN_RFC822_TYPE) {
7448
            ret = X509PrintEscStr(bio, "email:", entry->name, entry->len);
7449
        }
7450
        else if (entry->type == ASN_DIR_TYPE) {
7451
            ret = X509PrintDirType(bio, entry);
7452
        }
7453
        else if (entry->type == ASN_URI_TYPE) {
7454
            ret = X509PrintEscStr(bio, "URI:", entry->name, entry->len);
7455
        }
7456
    #ifdef WOLFSSL_RID_ALT_NAME
7457
        else if (entry->type == ASN_RID_TYPE) {
7458
            len = XSNPRINTF(scratch, MAX_WIDTH, "Registered ID:%s",
7459
                entry->ridString);
7460
        }
7461
    #else
7462
        else if (entry->type == ASN_RID_TYPE) {
7463
            /* registeredID entries are now always parsed into altNames
7464
             * so name constraints can be enforced. Without the
7465
             * human-readable ridString field, emit a fixed label so
7466
             * this print path does not fail. */
7467
            len = XSNPRINTF(scratch, MAX_WIDTH, "Registered ID:<unavailable>");
7468
        }
7469
    #endif /* WOLFSSL_RID_ALT_NAME */
7470
        else if (entry->type == ASN_OTHER_TYPE) {
7471
            len = XSNPRINTF(scratch, MAX_WIDTH,
7472
                "othername <unsupported>");
7473
        }
7474
        else {
7475
            WOLFSSL_MSG("Bad alt name type.");
7476
            ret = WOLFSSL_FAILURE;
7477
            break;
7478
        }
7479
        if ((ret != WOLFSSL_SUCCESS) || (len < 0) || (len >= MAX_WIDTH)) {
7480
            ret = WOLFSSL_FAILURE;
7481
            break;
7482
        }
7483
        if ((len > 0) && (wolfSSL_BIO_write(bio, scratch, len) <= 0)) {
7484
            ret = WOLFSSL_FAILURE;
7485
            break;
7486
        }
7487
7488
        entry = entry->next;
7489
    }
7490
7491
    if (ret == WOLFSSL_SUCCESS && wolfSSL_BIO_write(bio, "\n", 1) <= 0) {
7492
        ret = WOLFSSL_FAILURE;
7493
    }
7494
7495
    return ret;
7496
}
7497
7498
#ifdef XSNPRINTF
7499
static int X509PrintKeyUsage(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
7500
{
7501
    int ret = WOLFSSL_SUCCESS;
7502
    const int usages[] = {
7503
        KEYUSE_DIGITAL_SIG,
7504
        KEYUSE_CONTENT_COMMIT,
7505
        KEYUSE_KEY_ENCIPHER,
7506
        KEYUSE_DATA_ENCIPHER,
7507
        KEYUSE_KEY_AGREE,
7508
        KEYUSE_KEY_CERT_SIGN,
7509
        KEYUSE_CRL_SIGN,
7510
        KEYUSE_ENCIPHER_ONLY,
7511
        KEYUSE_DECIPHER_ONLY
7512
    };
7513
    const char* usageStrs[] = {
7514
        "Digital Signature",
7515
        "Non Repudiation",
7516
        "Key Encipherment",
7517
        "Data Encipherment",
7518
        "Key Agreement",
7519
        "Certificate Sign",
7520
        "CRL Sign",
7521
        "Encipher Only",
7522
        "Decipher Only"
7523
    };
7524
7525
    if (indent < 0) indent = 0;
7526
    if (indent > MAX_INDENT) indent = MAX_INDENT;
7527
7528
    if (bio == NULL || x509 == NULL) {
7529
        ret = WOLFSSL_FAILURE;
7530
    }
7531
7532
    if (ret == WOLFSSL_SUCCESS && x509->keyUsageSet && x509->keyUsage != 0) {
7533
        char scratch[MAX_WIDTH];
7534
        int len;
7535
        word32 i = 0;
7536
        int usageCount = 0;
7537
7538
        len = XSNPRINTF(scratch, MAX_WIDTH, "%*s", indent, "");
7539
        if (len >= MAX_WIDTH)
7540
            ret = WOLFSSL_FAILURE;
7541
        if (ret == WOLFSSL_SUCCESS) {
7542
            if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) {
7543
                ret = WOLFSSL_FAILURE;
7544
            }
7545
        }
7546
        for (; ret == WOLFSSL_SUCCESS && i < sizeof(usages) / sizeof(usages[i]);
7547
             i++) {
7548
            if (x509->keyUsage & usages[i]) {
7549
                ++usageCount;
7550
                if (usageCount > 1 && wolfSSL_BIO_write(bio, ", ", 2) <= 0) {
7551
                    ret = WOLFSSL_FAILURE;
7552
                    break;
7553
                }
7554
                if (wolfSSL_BIO_write(bio, usageStrs[i],
7555
                                      (int)XSTRLEN(usageStrs[i])) <= 0) {
7556
                    ret = WOLFSSL_FAILURE;
7557
                    break;
7558
                }
7559
            }
7560
        }
7561
        if (ret == WOLFSSL_SUCCESS && wolfSSL_BIO_write(bio, "\n", 1) <= 0) {
7562
            ret = WOLFSSL_FAILURE;
7563
        }
7564
    }
7565
7566
    return ret;
7567
}
7568
7569
static int X509PrintExtendedKeyUsage(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
7570
        int indent)
7571
{
7572
    int ret = WOLFSSL_SUCCESS;
7573
    const int usages[] = {
7574
        EXTKEYUSE_OCSP_SIGN,
7575
        EXTKEYUSE_TIMESTAMP,
7576
        EXTKEYUSE_EMAILPROT,
7577
        EXTKEYUSE_CODESIGN,
7578
        EXTKEYUSE_CLIENT_AUTH,
7579
        EXTKEYUSE_SERVER_AUTH,
7580
        EXTKEYUSE_ANY
7581
    };
7582
    const char* usageStrs[] = {
7583
        "OCSP Signing",
7584
        "Time Stamping",
7585
        "E-mail Protection",
7586
        "Code Signing",
7587
        "TLS Web Client Authentication",
7588
        "TLS Web Server Authentication",
7589
        "Any Extended Key Usage"
7590
    };
7591
7592
    if (bio == NULL || x509 == NULL) {
7593
        ret = WOLFSSL_FAILURE;
7594
    }
7595
7596
    if (ret == WOLFSSL_SUCCESS && x509->extKeyUsageCount > 0
7597
            && x509->extKeyUsage != 0) {
7598
        char scratch[MAX_WIDTH];
7599
        int len;
7600
        word32 i = 0;
7601
        int usageCount = 0;
7602
7603
        len = XSNPRINTF(scratch, MAX_WIDTH, "%*s", indent, "");
7604
        if (len >= MAX_WIDTH)
7605
            ret = WOLFSSL_FAILURE;
7606
        if (ret == WOLFSSL_SUCCESS) {
7607
            if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) {
7608
                ret = WOLFSSL_FAILURE;
7609
            }
7610
        }
7611
        for (; ret == WOLFSSL_SUCCESS && i < sizeof(usages) / sizeof(usages[i]);
7612
             i++) {
7613
            if (x509->extKeyUsage & usages[i]) {
7614
                ++usageCount;
7615
                if (usageCount > 1 && wolfSSL_BIO_write(bio, ", ", 2) <= 0) {
7616
                    ret = WOLFSSL_FAILURE;
7617
                    break;
7618
                }
7619
                if (wolfSSL_BIO_write(bio, usageStrs[i],
7620
                                      (int)XSTRLEN(usageStrs[i])) <= 0) {
7621
                    ret = WOLFSSL_FAILURE;
7622
                    break;
7623
                }
7624
            }
7625
        }
7626
        if (ret == WOLFSSL_SUCCESS && wolfSSL_BIO_write(bio, "\n", 1) <= 0) {
7627
            ret = WOLFSSL_FAILURE;
7628
        }
7629
    }
7630
7631
    return ret;
7632
}
7633
7634
7635
/* print serial number out
7636
 * return WOLFSSL_SUCCESS on success
7637
 */
7638
static int X509PrintSerial_ex(WOLFSSL_BIO* bio, byte* serial, int sz,
7639
        int delimiter, int indent)
7640
{
7641
    char scratch[MAX_WIDTH];
7642
    const int scratchSz = sizeof(scratch);
7643
    int scratchLen;
7644
7645
    if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*sSerial Number:",
7646
                                 indent, "")) >= MAX_WIDTH) {
7647
        WOLFSSL_MSG("buffer overrun");
7648
        return WOLFSSL_FAILURE;
7649
    }
7650
    if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
7651
        return WOLFSSL_FAILURE;
7652
    }
7653
7654
    if (sz > (int)sizeof(byte)) {
7655
        int i;
7656
7657
        /* serial is larger than int size so print off hex values */
7658
        if ((scratchLen = XSNPRINTF(
7659
                 scratch, MAX_WIDTH, "\n%*s", indent + 4, ""))
7660
                >= MAX_WIDTH) {
7661
            WOLFSSL_MSG("buffer overrun");
7662
            return WOLFSSL_FAILURE;
7663
        }
7664
        for (i = 0; i < sz; i++) {
7665
            int valLen;
7666
7667
            if ((valLen = XSNPRINTF(
7668
                     scratch + scratchLen, scratchSz - scratchLen,
7669
                     "%02x%s", serial[i], (i < sz - 1) ?
7670
                     (delimiter ? ":" : "") : "\n"))
7671
                >= scratchSz - scratchLen) {
7672
                WOLFSSL_MSG("buffer overrun");
7673
                return WOLFSSL_FAILURE;
7674
            }
7675
            scratchLen += valLen;
7676
        }
7677
        if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
7678
            return WOLFSSL_FAILURE;
7679
        }
7680
    }
7681
7682
    /* if serial can fit into byte then print on the same line */
7683
    else  {
7684
        if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, " %d (0x%x)\n",
7685
                (char)serial[0], serial[0])) >= MAX_WIDTH) {
7686
            WOLFSSL_MSG("buffer overrun");
7687
            return WOLFSSL_FAILURE;
7688
        }
7689
        if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
7690
            return WOLFSSL_FAILURE;
7691
        }
7692
    }
7693
    return WOLFSSL_SUCCESS;
7694
}
7695
7696
static int X509PrintSerial(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
7697
{
7698
    unsigned char serial[32];
7699
    int  sz = sizeof(serial);
7700
7701
    if (indent < 0) indent = 0;
7702
    if (indent > MAX_INDENT) indent = MAX_INDENT;
7703
7704
    XMEMSET(serial, 0, sz);
7705
    if (wolfSSL_X509_get_serial_number(x509, serial, &sz) == WOLFSSL_SUCCESS) {
7706
        X509PrintSerial_ex(bio, serial, sz, 1, indent);
7707
    }
7708
    return WOLFSSL_SUCCESS;
7709
}
7710
7711
#ifndef NO_ASN_TIME
7712
static int X509PrintValidity(WOLFSSL_BIO* bio, WOLFSSL_ASN1_TIME * notBefore,
7713
                             WOLFSSL_ASN1_TIME * notAfter, int indent)
7714
{
7715
    char tmp[80];
7716
    (void) indent;
7717
7718
    if (wolfSSL_BIO_write(bio, "        Validity\n",
7719
                  (int)XSTRLEN("        Validity\n")) <= 0) {
7720
        return WOLFSSL_FAILURE;
7721
    }
7722
7723
    if (wolfSSL_BIO_write(bio, "            Not Before: ",
7724
                  (int)XSTRLEN("            Not Before: ")) <= 0) {
7725
        return WOLFSSL_FAILURE;
7726
    }
7727
    if (notBefore->length > 0) {
7728
        if (GetTimeString(notBefore->data, ASN_UTC_TIME,
7729
            tmp, sizeof(tmp), notBefore->length) != WOLFSSL_SUCCESS) {
7730
            if (GetTimeString(notBefore->data, ASN_GENERALIZED_TIME,
7731
            tmp, sizeof(tmp), notBefore->length) != WOLFSSL_SUCCESS) {
7732
                WOLFSSL_MSG("Error getting not before date");
7733
                return WOLFSSL_FAILURE;
7734
            }
7735
        }
7736
    }
7737
    else {
7738
        XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
7739
    }
7740
    tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
7741
    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
7742
        return WOLFSSL_FAILURE;
7743
    }
7744
7745
    if (wolfSSL_BIO_write(bio, "\n            Not After : ",
7746
                  (int)XSTRLEN("\n            Not After : ")) <= 0) {
7747
        return WOLFSSL_FAILURE;
7748
    }
7749
    if (notAfter->length > 0) {
7750
        if (GetTimeString(notAfter->data, ASN_UTC_TIME,
7751
            tmp, sizeof(tmp), notAfter->length) != WOLFSSL_SUCCESS) {
7752
            if (GetTimeString(notAfter->data, ASN_GENERALIZED_TIME,
7753
                tmp, sizeof(tmp), notAfter->length) != WOLFSSL_SUCCESS) {
7754
                WOLFSSL_MSG("Error getting not after date");
7755
                return WOLFSSL_FAILURE;
7756
            }
7757
        }
7758
    }
7759
    else {
7760
        XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
7761
    }
7762
    tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
7763
    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
7764
        return WOLFSSL_FAILURE;
7765
    }
7766
7767
    if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
7768
        return WOLFSSL_FAILURE;
7769
    }
7770
7771
    return WOLFSSL_SUCCESS;
7772
}
7773
#endif /* ifndef NO_ASN_TIME */
7774
7775
static int X509PrintSubjAltName(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
7776
                                int indent)
7777
{
7778
    if (!x509 || !x509->altNames || !x509->subjAltNameSet)
7779
        return WOLFSSL_FAILURE;
7780
    return X509_print_name_entry(bio, x509->altNames, indent);
7781
}
7782
7783
/* print out the signature value in human readable format for use with
7784
 * X509PrintSignature_ex() and X509PrintAltSigVal()
7785
 *
7786
 * return WOLFSSL_SUCCESS on success
7787
 */
7788
static int X509PrintSigHex(WOLFSSL_BIO* bio, byte* sig, int sigSz,
7789
        int indent)
7790
{
7791
    int i;
7792
    int tmpLen = 0;
7793
    char tmp[100];
7794
7795
    if ((tmpLen = XSNPRINTF(tmp, sizeof(tmp), "%*s", indent, ""))
7796
            >= (int)sizeof(tmp) || tmpLen < 0) {
7797
        return WOLFSSL_FAILURE;
7798
    }
7799
7800
    for (i = 0; i < sigSz; i++) {
7801
        char val[6];
7802
        int valLen;
7803
7804
        if (i == 0) {
7805
            if ((valLen = XSNPRINTF(val, sizeof(val), "%02x", sig[i]))
7806
                    >= (int)sizeof(val)) {
7807
                return WOLFSSL_FAILURE;
7808
            }
7809
        }
7810
        else if (((i % 18) == 0)) {
7811
            if (wolfSSL_BIO_write(bio, tmp, tmpLen)
7812
                    <= 0) {
7813
                return WOLFSSL_FAILURE;
7814
            }
7815
            if ((tmpLen = XSNPRINTF(tmp, sizeof(tmp), ":\n%*s",
7816
                    indent, "")) >= (int)sizeof(tmp)) {
7817
                return WOLFSSL_FAILURE;
7818
            }
7819
            if ((valLen = XSNPRINTF(val, sizeof(val), "%02x", sig[i]))
7820
                    >= (int)sizeof(val)) {
7821
                return WOLFSSL_FAILURE;
7822
            }
7823
        }
7824
        else {
7825
            if ((valLen = XSNPRINTF(val, sizeof(val), ":%02x", sig[i]))
7826
                    >= (int)sizeof(val)) {
7827
                return WOLFSSL_FAILURE;
7828
            }
7829
        }
7830
        if ((tmpLen < 0) || (valLen < 0) ||
7831
                (valLen >= ((int)sizeof(tmp) - tmpLen - 1))) {
7832
            return WOLFSSL_FAILURE;
7833
        }
7834
        XMEMCPY(tmp + tmpLen, val, valLen);
7835
        tmpLen += valLen;
7836
        tmp[tmpLen] = 0;
7837
    }
7838
7839
    /* print out remaining sig values */
7840
    if (tmpLen > 0 && wolfSSL_BIO_write(bio, tmp, tmpLen) <= 0) {
7841
        return WOLFSSL_FAILURE;
7842
    }
7843
7844
    return WOLFSSL_SUCCESS;
7845
}
7846
7847
#ifdef WOLFSSL_DUAL_ALG_CERTS
7848
/* print the OID of an unsupported algorithm
7849
 * return WOLFSSL_SUCCESS on success
7850
 */
7851
static int X509PrintAlgOid(WOLFSSL_BIO* bio, const byte* algId, int algIdSz,
7852
        int indent)
7853
{
7854
    char scratch[MAX_WIDTH];
7855
    word32 idx = 0;
7856
    int len;
7857
    int oidSz;
7858
    byte tag;
7859
7860
    /* AlgorithmIdentifier ::= SEQUENCE { algorithm OBJECT IDENTIFIER, ... } */
7861
    if (GetSequence(algId, &idx, &oidSz, (word32)algIdSz) < 0) {
7862
        return WOLFSSL_FAILURE;
7863
    }
7864
    if ((GetASNTag(algId, &idx, &tag, (word32)algIdSz) != 0) ||
7865
            (tag != ASN_OBJECT_ID)) {
7866
        return WOLFSSL_FAILURE;
7867
    }
7868
    if (GetLength(algId, &idx, &oidSz, (word32)algIdSz) < 0) {
7869
        return WOLFSSL_FAILURE;
7870
    }
7871
7872
    /* indent buffer so the OID can be decoded into scratch */
7873
    len = XSNPRINTF(scratch, MAX_WIDTH, "%*s", indent, "");
7874
    if (len < 0 || len >= MAX_WIDTH) {
7875
        return WOLFSSL_FAILURE;
7876
    }
7877
7878
    oidSz = DecodePolicyOID(scratch + len, (word32)(MAX_WIDTH - len),
7879
        algId + idx, (word32)oidSz);
7880
    if (oidSz <= 0) {
7881
        return WOLFSSL_FAILURE;
7882
    }
7883
    len += oidSz;
7884
7885
    if (len + 1 >= MAX_WIDTH) {
7886
        return WOLFSSL_FAILURE;
7887
    }
7888
    scratch[len++] = '\n';
7889
7890
    if (wolfSSL_BIO_write(bio, scratch, len) <= 0) {
7891
        return WOLFSSL_FAILURE;
7892
    }
7893
7894
    return WOLFSSL_SUCCESS;
7895
}
7896
7897
/* print out the alternative public key in human readable format for use with
7898
 * wolfSSL_X509_print()
7899
 * return WOLFSSL_SUCCESS on success
7900
 */
7901
static int X509PrintAltPubKey(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
7902
{
7903
    const unsigned char* der;
7904
    WOLFSSL_EVP_PKEY* pubKey;
7905
    char scratch[MAX_WIDTH];
7906
    int len;
7907
    int ret;
7908
7909
    if (x509->sapkiDer == NULL || x509->sapkiLen <= 0) {
7910
        return WOLFSSL_FAILURE;
7911
    }
7912
7913
    /* convert der to pkey for printing */
7914
    der = (const unsigned char*)x509->sapkiDer;
7915
    pubKey = wolfSSL_d2i_PUBKEY(NULL, &der, x509->sapkiLen);
7916
    if (pubKey != NULL) {
7917
        ret = wolfSSL_EVP_PKEY_print_public(bio, pubKey, indent, NULL);
7918
7919
        wolfSSL_EVP_PKEY_free(pubKey);
7920
7921
        if (ret == WOLFSSL_SUCCESS) {
7922
            return WOLFSSL_SUCCESS;
7923
        }
7924
        if (ret != WC_NO_ERR_TRACE(WOLFSSL_UNKNOWN)) {
7925
            return WOLFSSL_FAILURE;
7926
        }
7927
    }
7928
7929
    /* if the alg is unhandled then still try to print the rest of the cert */
7930
    len = XSNPRINTF(scratch, MAX_WIDTH, "%*sprint not supported\n", indent, "");
7931
    if (len < 0 || len >= MAX_WIDTH) {
7932
        return WOLFSSL_FAILURE;
7933
    }
7934
    if (wolfSSL_BIO_write(bio, scratch, len) <= 0) {
7935
        return WOLFSSL_FAILURE;
7936
    }
7937
7938
    return WOLFSSL_SUCCESS;
7939
}
7940
7941
/* print out the alternative signature algorithm in human readable format for
7942
 * use with wolfSSL_X509_print()
7943
 * return WOLFSSL_SUCCESS on success
7944
 */
7945
static int X509PrintAltSigAlg(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
7946
{
7947
    char scratch[MAX_WIDTH];
7948
    const char* nameStr;
7949
    word32 idx = 0;
7950
    word32 oid = 0;
7951
    int len;
7952
    int ret;
7953
7954
    if (x509->altSigAlgDer == NULL || x509->altSigAlgLen <= 0) {
7955
        return WOLFSSL_FAILURE;
7956
    }
7957
7958
    /* have an AlgorithmIdentifier, so look up the algo name */
7959
    ret = GetAlgoId(x509->altSigAlgDer, &idx, &oid, oidSigType,
7960
            (word32)x509->altSigAlgLen);
7961
    if (ret == WC_NO_ERR_TRACE(ASN_UNKNOWN_OID_E)) {
7962
        /* encoding is well formed, so print the OID */
7963
        return X509PrintAlgOid(bio, x509->altSigAlgDer, x509->altSigAlgLen,
7964
            indent);
7965
    }
7966
    if (ret < 0) {
7967
        return WOLFSSL_FAILURE;
7968
    }
7969
7970
    nameStr = wolfSSL_OBJ_nid2ln(oid2nid(oid, oidSigType));
7971
    if (nameStr == NULL) {
7972
        /* no name, so print the OID instead */
7973
        return X509PrintAlgOid(bio, x509->altSigAlgDer, x509->altSigAlgLen,
7974
            indent);
7975
    }
7976
7977
    len = XSNPRINTF(scratch, MAX_WIDTH, "%*s%s\n", indent, "", nameStr);
7978
    if (len < 0 || len >= MAX_WIDTH) {
7979
        return WOLFSSL_FAILURE;
7980
    }
7981
    if (wolfSSL_BIO_write(bio, scratch, len) <= 0) {
7982
        return WOLFSSL_FAILURE;
7983
    }
7984
7985
    return WOLFSSL_SUCCESS;
7986
}
7987
7988
/* print out the alternative signature value in human readable format for use
7989
 * with wolfSSL_X509_print()
7990
 * return WOLFSSL_SUCCESS on success
7991
 */
7992
static int X509PrintAltSigVal(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
7993
{
7994
    if (x509->altSigValDer == NULL || x509->altSigValLen <= 0) {
7995
        return WOLFSSL_FAILURE;
7996
    }
7997
7998
    /* DecodeAltSigVal() already stepped over the BIT STRING header */
7999
    if (X509PrintSigHex(bio, x509->altSigValDer, x509->altSigValLen, indent)
8000
            != WOLFSSL_SUCCESS) {
8001
        return WOLFSSL_FAILURE;
8002
    }
8003
8004
    /* X509PrintSigHex omits the trailing newline */
8005
    if (wolfSSL_BIO_write(bio, "\n", 1) <= 0) {
8006
        return WOLFSSL_FAILURE;
8007
    }
8008
8009
    return WOLFSSL_SUCCESS;
8010
}
8011
#endif /* WOLFSSL_DUAL_ALG_CERTS */
8012
8013
/* iterate through certificate extensions printing them out in human readable
8014
 * form
8015
 * return WOLFSSL_SUCCESS on success
8016
 */
8017
static int X509PrintExtensions(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
8018
{
8019
    int  ret = WOLFSSL_SUCCESS;
8020
    char scratch[MAX_WIDTH];
8021
    const int scratchSz = sizeof(scratch);
8022
    int scratchLen;
8023
    int  count, i;
8024
    char* buf = NULL;
8025
8026
    if (indent < 0) indent = 0;
8027
    if (indent > MAX_INDENT) indent = MAX_INDENT;
8028
8029
    count = wolfSSL_X509_get_ext_count(x509);
8030
    if (count <= 0)
8031
        return WOLFSSL_SUCCESS;
8032
8033
#ifdef WOLFSSL_CERT_REQ
8034
    if (x509->isCSR) {
8035
        if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*s%s\n", indent, "",
8036
                      "Requested extensions:")) >= MAX_WIDTH) {
8037
            return WOLFSSL_FAILURE;
8038
        }
8039
    }
8040
    else
8041
#endif
8042
    {
8043
        if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*s%s\n", indent, "",
8044
                                     "X509v3 extensions:")) >= MAX_WIDTH) {
8045
            return WOLFSSL_FAILURE;
8046
        }
8047
    }
8048
    if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
8049
        return WOLFSSL_FAILURE;
8050
    }
8051
8052
    buf = (char*)XMALLOC(MAX_WIDTH, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
8053
    if (buf == NULL) {
8054
        return WOLFSSL_FAILURE;
8055
    }
8056
8057
    for (i = 0; (i < count) && (ret != WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); i++) {
8058
        WOLFSSL_X509_EXTENSION* ext;
8059
8060
        ext = wolfSSL_X509_get_ext(x509, i);
8061
        if (ext != NULL) {
8062
            WOLFSSL_ASN1_OBJECT* obj;
8063
            int nid;
8064
            char val[6];
8065
            int valLen;
8066
            word32 j;
8067
8068
            obj = wolfSSL_X509_EXTENSION_get_object(ext);
8069
            if (obj == NULL) {
8070
                ret = WOLFSSL_FAILURE;
8071
                break;
8072
            }
8073
            if (wolfSSL_OBJ_obj2txt(buf, MAX_WIDTH, obj, 0)
8074
                == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
8075
            {
8076
                ret = WOLFSSL_FAILURE;
8077
                break;
8078
            }
8079
            if ((scratchLen = XSNPRINTF(
8080
                     scratch, MAX_WIDTH, "%*s%s%s\n", indent + 4, "",
8081
                     buf,
8082
                     (wolfSSL_X509_EXTENSION_get_critical(ext)
8083
                      ? ": critical"
8084
                      : ": ")))
8085
                >= MAX_WIDTH)
8086
            {
8087
                ret = WOLFSSL_FAILURE;
8088
                break;
8089
            }
8090
8091
            if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
8092
                ret = WOLFSSL_FAILURE;
8093
                break;
8094
            }
8095
            nid = wolfSSL_OBJ_obj2nid(obj);
8096
            switch (nid) {
8097
            case WC_NID_subject_alt_name:
8098
                ret = X509PrintSubjAltName(bio, x509, indent + 8);
8099
                break;
8100
8101
            case WC_NID_subject_key_identifier:
8102
                if (!x509->subjKeyIdSet || x509->subjKeyId == NULL ||
8103
                    x509->subjKeyIdSz == 0)
8104
                {
8105
                    ret = WOLFSSL_FAILURE;
8106
                    break;
8107
                }
8108
8109
                if ((scratchLen = XSNPRINTF(
8110
                         scratch, scratchSz,
8111
                         "%*s", indent + 8, "")) >= scratchSz)
8112
                {
8113
                    ret = WOLFSSL_FAILURE;
8114
                    break;
8115
                }
8116
                for (j = 0; j < x509->subjKeyIdSz; j++) {
8117
                    if ((valLen = XSNPRINTF(
8118
                             val, sizeof(val), "%02X%s",
8119
                             x509->subjKeyId[j],
8120
                             (j < x509->subjKeyIdSz - 1) ? ":" : "\n"))
8121
                        >= (int)sizeof(val))
8122
                    {
8123
                        ret = WOLFSSL_FAILURE;
8124
                        break;
8125
                    }
8126
                    if (scratchLen + valLen >= scratchSz) {
8127
                        if (wolfSSL_BIO_write(bio, scratch,
8128
                                              scratchLen) <= 0) {
8129
                            ret = WOLFSSL_FAILURE;
8130
                            break;
8131
                        }
8132
                        scratchLen = 0;
8133
                    }
8134
                    XMEMCPY(scratch + scratchLen, val, valLen);
8135
                    scratchLen += valLen;
8136
                }
8137
                if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
8138
                    break;
8139
                if (wolfSSL_BIO_write(bio, scratch,
8140
                                      scratchLen) <= 0) {
8141
                    ret = WOLFSSL_FAILURE;
8142
                    break;
8143
                }
8144
                break;
8145
8146
            case WC_NID_authority_key_identifier:
8147
                if (!x509->authKeyIdSet || x509->authKeyId == NULL ||
8148
                    x509->authKeyIdSz == 0) {
8149
                    ret = WOLFSSL_FAILURE;
8150
                    break;
8151
                }
8152
8153
                if ((scratchLen = XSNPRINTF(
8154
                         scratch, scratchSz, "%*s%s",
8155
                         indent + 8, "", "keyid:")) >= scratchSz)
8156
                {
8157
                    ret = WOLFSSL_FAILURE;
8158
                    break;
8159
                }
8160
                for (j = 0; j < x509->authKeyIdSz; j++) {
8161
                    if ((valLen = XSNPRINTF(
8162
                             val, sizeof(val), "%02X%s",
8163
                             x509->authKeyId[j],
8164
                             (j < x509->authKeyIdSz - 1) ? ":" : "\n\n"))
8165
                        >= (int)sizeof(val))
8166
                    {
8167
                        ret = WOLFSSL_FAILURE;
8168
                        break;
8169
                    }
8170
                    if (scratchLen >= scratchSz - valLen) {
8171
                        if (wolfSSL_BIO_write(bio, scratch,
8172
                                              scratchLen) <= 0)
8173
                        {
8174
                            ret = WOLFSSL_FAILURE;
8175
                            break;
8176
                        }
8177
                        scratchLen = 0;
8178
                    }
8179
                    if (scratchLen + valLen >= scratchSz) {
8180
                        ret = WOLFSSL_FAILURE;
8181
                        break;
8182
                    }
8183
                    XMEMCPY(scratch + scratchLen, val, valLen);
8184
                    scratchLen += valLen;
8185
                }
8186
                if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
8187
                    break;
8188
                if (wolfSSL_BIO_write(bio, scratch,
8189
                                      scratchLen) <= 0) {
8190
                    ret = WOLFSSL_FAILURE;
8191
                    break;
8192
                }
8193
                break;
8194
8195
            case WC_NID_basic_constraints:
8196
                if (!x509->basicConstSet) {
8197
                    ret = WOLFSSL_FAILURE;
8198
                    break;
8199
                }
8200
                /* Match OpenSSL output: print "CA:TRUE"/"CA:FALSE" and append
8201
                 * ", pathlen:N" only when a pathLenConstraint is present
8202
                 * (RFC 5280 4.2.1.9). An absent constraint imposes no limit
8203
                 * and must not be shown as pathlen:0. */
8204
                if (x509->basicConstPlSet) {
8205
                    scratchLen = XSNPRINTF(scratch, scratchSz,
8206
                        "%*sCA:%s, pathlen:%u\n",
8207
                        indent + 8, "", (x509->isCa) ? "TRUE" : "FALSE",
8208
                        (unsigned int)x509->pathLength);
8209
                }
8210
                else {
8211
                    scratchLen = XSNPRINTF(scratch, scratchSz,
8212
                        "%*sCA:%s\n",
8213
                        indent + 8, "", (x509->isCa) ? "TRUE" : "FALSE");
8214
                }
8215
                if (scratchLen >= scratchSz) {
8216
                    ret = WOLFSSL_FAILURE;
8217
                    break;
8218
                }
8219
                if (wolfSSL_BIO_write(bio, scratch,
8220
                                      scratchLen) <= 0) {
8221
                    ret = WOLFSSL_FAILURE;
8222
                    break;
8223
                }
8224
                break;
8225
8226
            case WC_NID_key_usage:
8227
                ret = X509PrintKeyUsage(bio, x509, indent + 8);
8228
                break;
8229
8230
            case WC_NID_ext_key_usage:
8231
                ret = X509PrintExtendedKeyUsage(bio, x509, indent + 8);
8232
                break;
8233
8234
        #ifdef WOLFSSL_DUAL_ALG_CERTS
8235
            case WC_NID_subject_alt_public_key_info:
8236
                ret = X509PrintAltPubKey(bio, x509, indent + 8);
8237
                break;
8238
8239
            case WC_NID_alt_signature_algorithm:
8240
                ret = X509PrintAltSigAlg(bio, x509, indent + 8);
8241
                break;
8242
8243
            case WC_NID_alt_signature_value:
8244
                ret = X509PrintAltSigVal(bio, x509, indent + 8);
8245
                break;
8246
        #endif
8247
8248
            default:
8249
                /* extension nid not yet supported */
8250
                if ((scratchLen = XSNPRINTF(
8251
                         scratch, MAX_WIDTH,
8252
                         "%*sNID %d print not yet supported\n",
8253
                         indent + 8, "", nid)) >= MAX_WIDTH)
8254
                {
8255
                    ret = WOLFSSL_FAILURE;
8256
                    break;
8257
                }
8258
8259
                if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
8260
                    ret = WOLFSSL_FAILURE;
8261
                    break;
8262
                }
8263
            }
8264
        }
8265
    }
8266
8267
    XFREE(buf, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
8268
8269
    return ret;
8270
}
8271
8272
/* print out the signature in human readable format for use with
8273
 * wolfSSL_X509_print()
8274
 * return WOLFSSL_SUCCESS on success
8275
 */
8276
static int X509PrintSignature_ex(WOLFSSL_BIO* bio, byte* sig,
8277
        int sigSz, int sigNid, int algOnly, int indent)
8278
{
8279
    char scratch[MAX_WIDTH];
8280
    int scratchLen;
8281
    WOLFSSL_ASN1_OBJECT* obj = NULL;
8282
    int ret = WOLFSSL_SUCCESS;
8283
    char tmp[100];
8284
    int tmpLen = 0;
8285
8286
    if (sigSz <= 0) {
8287
        return WOLFSSL_SUCCESS;
8288
    }
8289
8290
    if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*s%s", indent, "",
8291
                                "Signature Algorithm: ")) >= MAX_WIDTH) {
8292
        ret = WOLFSSL_FAILURE;
8293
    }
8294
8295
    if (ret == WOLFSSL_SUCCESS) {
8296
        if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0)
8297
            ret = WOLFSSL_FAILURE;
8298
    }
8299
8300
    if (ret == WOLFSSL_SUCCESS) {
8301
        obj = wolfSSL_OBJ_nid2obj(sigNid);
8302
        if (obj == NULL)
8303
            ret = WOLFSSL_FAILURE;
8304
    }
8305
    if (ret == WOLFSSL_SUCCESS) {
8306
        if (wolfSSL_OBJ_obj2txt(scratch, MAX_WIDTH, obj, 0)
8307
            == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
8308
        {
8309
            ret = WOLFSSL_FAILURE;
8310
        }
8311
    }
8312
8313
    if (ret == WOLFSSL_SUCCESS) {
8314
        if ((tmpLen = XSNPRINTF(tmp, sizeof(tmp),"%s\n", scratch))
8315
            >= (int)sizeof(tmp))
8316
        {
8317
            ret = WOLFSSL_FAILURE;
8318
        }
8319
    }
8320
    if (ret == WOLFSSL_SUCCESS) {
8321
        if (wolfSSL_BIO_write(bio, tmp, tmpLen) <= 0)
8322
            ret = WOLFSSL_FAILURE;
8323
    }
8324
8325
    /* Leave function if the desired content to print
8326
     * is only the signature algorithm */
8327
    if (algOnly) {
8328
        if (obj != NULL)
8329
            wolfSSL_ASN1_OBJECT_free(obj);
8330
8331
        return ret;
8332
    }
8333
8334
    if (ret == WOLFSSL_SUCCESS) {
8335
        ret = X509PrintSigHex(bio, sig, sigSz, indent + 5);
8336
    }
8337
8338
    if (obj != NULL)
8339
        wolfSSL_ASN1_OBJECT_free(obj);
8340
8341
    return ret;
8342
}
8343
8344
static int X509PrintSignature(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
8345
        int algOnly, int indent)
8346
{
8347
    int sigSz = 0;
8348
    if (wolfSSL_X509_get_signature(x509, NULL, &sigSz) <= 0) {
8349
        return WOLFSSL_FAILURE;
8350
    }
8351
8352
    if (sigSz > 0) {
8353
        unsigned char* sig;
8354
        int sigNid;
8355
8356
        sigNid = wolfSSL_X509_get_signature_nid(x509);
8357
        if (sigNid <= 0) {
8358
            return WOLFSSL_FAILURE;
8359
        }
8360
8361
        sig = (unsigned char*)XMALLOC(sigSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8362
        if (sig == NULL) {
8363
            return WOLFSSL_FAILURE;
8364
        }
8365
8366
        if (wolfSSL_X509_get_signature(x509, sig, &sigSz) <= 0) {
8367
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8368
            return WOLFSSL_FAILURE;
8369
        }
8370
8371
        if (X509PrintSignature_ex(bio, sig, sigSz, sigNid, algOnly, indent)
8372
                != WOLFSSL_SUCCESS) {
8373
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8374
            return WOLFSSL_FAILURE;
8375
        }
8376
8377
        XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8378
8379
    }
8380
8381
    return WOLFSSL_SUCCESS;
8382
}
8383
8384
8385
/* print out the public key in human readable format for use with
8386
 * wolfSSL_X509_print()
8387
 * return WOLFSSL_SUCCESS on success
8388
 */
8389
static int X509PrintPubKey(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
8390
{
8391
    char scratch[MAX_WIDTH];
8392
    const char* nameStr;
8393
    WOLFSSL_EVP_PKEY* pubKey;
8394
    int len;
8395
    int ret = WOLFSSL_SUCCESS;
8396
8397
    if (indent < 0) indent = 0;
8398
    if (indent > MAX_INDENT) indent = MAX_INDENT;
8399
8400
    if (bio == NULL || x509 == NULL)
8401
        return BAD_FUNC_ARG;
8402
8403
    len = XSNPRINTF(scratch, MAX_WIDTH, "%*sSubject Public Key Info:\n", indent,
8404
        "");
8405
    if (len < 0 || len >= MAX_WIDTH)
8406
        return WOLFSSL_FAILURE;
8407
    if (wolfSSL_BIO_write(bio, scratch, len) <= 0)
8408
        return WOLFSSL_FAILURE;
8409
8410
    /* get the alg string associated with the OID */
8411
    nameStr = wolfSSL_OBJ_nid2ln(oid2nid((word32)x509->pubKeyOID, oidKeyType));
8412
    if (nameStr == NULL)
8413
        return WOLFSSL_FAILURE;
8414
8415
    len = XSNPRINTF(scratch, MAX_WIDTH, "%*sPublic Key Algorithm: %s\n",
8416
        indent + 4, "", nameStr);
8417
    if (len < 0 || len >= MAX_WIDTH)
8418
        return WOLFSSL_FAILURE;
8419
    if (wolfSSL_BIO_write(bio, scratch, len) <= 0)
8420
        return WOLFSSL_FAILURE;
8421
8422
    pubKey = wolfSSL_X509_get_pubkey(x509);
8423
    if (pubKey == NULL)
8424
        return WOLFSSL_FAILURE;
8425
8426
    ret = wolfSSL_EVP_PKEY_print_public(bio, pubKey, indent + 8, NULL);
8427
8428
    wolfSSL_EVP_PKEY_free(pubKey);
8429
8430
    if (ret == WOLFSSL_SUCCESS)
8431
        return WOLFSSL_SUCCESS;
8432
    if (ret != WC_NO_ERR_TRACE(WOLFSSL_UNKNOWN))
8433
        return WOLFSSL_FAILURE;
8434
8435
    /* if the alg is unhandled then still try to print the rest of the cert */
8436
    len = XSNPRINTF(scratch, MAX_WIDTH, "%*sprint not supported\n", indent + 8,
8437
        "");
8438
    if (len < 0 || len >= MAX_WIDTH)
8439
        return WOLFSSL_FAILURE;
8440
    if (wolfSSL_BIO_write(bio, scratch, len) <= 0)
8441
        return WOLFSSL_FAILURE;
8442
8443
    return WOLFSSL_SUCCESS;
8444
}
8445
8446
8447
/* human readable print out of x509 name formatted for use with
8448
 * wolfSSL_X509_print()
8449
 * return WOLFSSL_SUCCESS on success
8450
 */
8451
static int X509PrintName(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name,
8452
        char* type, int indent)
8453
{
8454
    if (name != NULL) {
8455
        char scratch[MAX_WIDTH];
8456
        int scratchLen;
8457
8458
        if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH,
8459
                                     "%*s%s", indent, "", type))
8460
            >= MAX_WIDTH)
8461
        {
8462
            return WOLFSSL_FAILURE;
8463
        }
8464
        if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
8465
            return WOLFSSL_FAILURE;
8466
        }
8467
        if (wolfSSL_X509_NAME_print_ex(bio, name, 1,
8468
                WOLFSSL_ASN1_STRFLGS_ESC_CTRL) <= 0) {
8469
            return WOLFSSL_FAILURE;
8470
        }
8471
        if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) {
8472
            return WOLFSSL_FAILURE;
8473
        }
8474
    }
8475
    return WOLFSSL_SUCCESS;
8476
}
8477
8478
8479
/* human readable print out of x509 version
8480
 * return WOLFSSL_SUCCESS on success
8481
 */
8482
static int X509PrintVersion(WOLFSSL_BIO* bio, int version, int indent)
8483
{
8484
    char scratch[MAX_WIDTH];
8485
    int scratchLen;
8486
8487
    if (indent < 0) indent = 0;
8488
    if (indent > MAX_INDENT) indent = MAX_INDENT;
8489
8490
    scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*s%s", indent, "", "Version:");
8491
    if ((scratchLen < 0) || (scratchLen >= MAX_WIDTH)) {
8492
        return WOLFSSL_FAILURE;
8493
    }
8494
8495
    if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
8496
        return WOLFSSL_FAILURE;
8497
    }
8498
8499
    scratchLen = XSNPRINTF(scratch, MAX_WIDTH, " %d (0x%x)\n",
8500
                    version, (byte)version-1);
8501
    if ((scratchLen < 0) || (scratchLen >= MAX_WIDTH)) {
8502
        return WOLFSSL_FAILURE;
8503
    }
8504
8505
    if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
8506
        return WOLFSSL_FAILURE;
8507
    }
8508
    return WOLFSSL_SUCCESS;
8509
}
8510
8511
#ifdef WOLFSSL_CERT_REQ
8512
/* Print out of REQ attributes
8513
 * return WOLFSSL_SUCCESS on success
8514
 */
8515
static int X509PrintReqAttributes(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
8516
        int indent)
8517
{
8518
    WOLFSSL_X509_ATTRIBUTE* attr;
8519
    char scratch[MAX_WIDTH];
8520
    int scratchLen;
8521
    int i = 0;
8522
8523
    if (indent < 0) indent = 0;
8524
    if (indent > MAX_INDENT) indent = MAX_INDENT;
8525
8526
    if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH,
8527
                                 "%*s%s", indent, "", "Attributes: \n"))
8528
        >= MAX_WIDTH)
8529
    {
8530
        return WOLFSSL_FAILURE;
8531
    }
8532
    if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
8533
        return WOLFSSL_FAILURE;
8534
    }
8535
    do {
8536
        attr = wolfSSL_X509_REQ_get_attr(x509, i);
8537
        if (attr != NULL) {
8538
            char lName[NAME_SZ/4]; /* NAME_SZ default is 80 */
8539
            int lNameSz = NAME_SZ/4;
8540
            const byte* data;
8541
8542
            if (wolfSSL_OBJ_obj2txt(lName, lNameSz, attr->object, 0)
8543
                == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
8544
            {
8545
                return WOLFSSL_FAILURE;
8546
            }
8547
            lNameSz = (int)XSTRLEN(lName);
8548
            data = wolfSSL_ASN1_STRING_get0_data(
8549
                    attr->value->value.asn1_string);
8550
            if (data == NULL) {
8551
                WOLFSSL_MSG("No REQ attribute found when expected");
8552
                return WOLFSSL_FAILURE;
8553
            }
8554
            if (XSNPRINTF(scratch, MAX_WIDTH,
8555
                          "%*s%s%*s:", indent+4, "",
8556
                          lName, (NAME_SZ/4)-lNameSz, "")
8557
                >= MAX_WIDTH)
8558
            {
8559
                return WOLFSSL_FAILURE;
8560
            }
8561
            if ((X509PrintEscStr(bio, scratch, (const char*)data,
8562
                    wolfSSL_ASN1_STRING_length(
8563
                        attr->value->value.asn1_string)) != WOLFSSL_SUCCESS) ||
8564
                (wolfSSL_BIO_write(bio, "\n", 1) <= 0)) {
8565
                WOLFSSL_MSG("Error writing REQ attribute");
8566
                return WOLFSSL_FAILURE;
8567
            }
8568
        }
8569
        i++;
8570
    } while (attr != NULL);
8571
8572
    return WOLFSSL_SUCCESS;
8573
}
8574
8575
8576
/*
8577
 * return WOLFSSL_SUCCESS on success
8578
 */
8579
int wolfSSL_X509_REQ_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
8580
{
8581
    char subjType[] = "Subject: ";
8582
8583
    if (bio == NULL || x509 == NULL) {
8584
        return WOLFSSL_FAILURE;
8585
    }
8586
8587
    if (wolfSSL_BIO_write(bio, "Certificate Request:\n",
8588
                  (int)XSTRLEN("Certificate Request:\n")) <= 0) {
8589
            return WOLFSSL_FAILURE;
8590
    }
8591
8592
    if (wolfSSL_BIO_write(bio, "    Data:\n",
8593
                  (int)XSTRLEN("    Data:\n")) <= 0) {
8594
            return WOLFSSL_FAILURE;
8595
    }
8596
8597
    /* print version of cert.  Note that we increment by 1 because for REQs,
8598
     * the value stored in x509->version is the actual value of the field; not
8599
     * the version. */
8600
    if (X509PrintVersion(bio, (int)wolfSSL_X509_REQ_get_version(x509) + 1, 8)
8601
            != WOLFSSL_SUCCESS) {
8602
        return WOLFSSL_FAILURE;
8603
    }
8604
8605
    if (X509PrintSerial(bio, x509, 8) != WOLFSSL_SUCCESS) {
8606
        return WOLFSSL_FAILURE;
8607
    }
8608
8609
    /* print subject */
8610
    if (X509PrintName(bio, wolfSSL_X509_get_subject_name(x509), subjType, 8)
8611
            != WOLFSSL_SUCCESS) {
8612
        return WOLFSSL_FAILURE;
8613
    }
8614
8615
    /* get and print public key */
8616
    if (X509PrintPubKey(bio, x509, 8) != WOLFSSL_SUCCESS) {
8617
        return WOLFSSL_FAILURE;
8618
    }
8619
8620
    /* print out extensions */
8621
    if (X509PrintExtensions(bio, x509, 4) != WOLFSSL_SUCCESS) {
8622
        return WOLFSSL_FAILURE;
8623
    }
8624
8625
    /* print out req attributes */
8626
    if (X509PrintReqAttributes(bio, x509, 4) != WOLFSSL_SUCCESS) {
8627
        return WOLFSSL_FAILURE;
8628
    }
8629
8630
    /* print out signature */
8631
    if (X509PrintSignature(bio, x509, 0, 4) != WOLFSSL_SUCCESS) {
8632
        return WOLFSSL_FAILURE;
8633
    }
8634
8635
    /* done with print out */
8636
    if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
8637
        return WOLFSSL_FAILURE;
8638
    }
8639
8640
    return WOLFSSL_SUCCESS;
8641
}
8642
#endif /* WOLFSSL_CERT_REQ */
8643
8644
8645
/* Writes the human readable form of x509 to bio.
8646
 *
8647
 * bio  WOLFSSL_BIO to write to.
8648
 * x509 Certificate to write.
8649
 *
8650
 * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
8651
 */
8652
int wolfSSL_X509_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
8653
    unsigned long nmflags, unsigned long cflag)
8654
{
8655
    char issuType[] = "Issuer:";
8656
    char subjType[] = "Subject:";
8657
8658
    WOLFSSL_ENTER("wolfSSL_X509_print_ex");
8659
8660
    /* flags currently not supported */
8661
    (void)nmflags;
8662
    (void)cflag;
8663
8664
    if (bio == NULL || x509 == NULL) {
8665
        return WOLFSSL_FAILURE;
8666
    }
8667
8668
    if (wolfSSL_BIO_write(bio, "Certificate:\n",
8669
                  (int)XSTRLEN("Certificate:\n")) <= 0) {
8670
            return WOLFSSL_FAILURE;
8671
    }
8672
8673
    if (wolfSSL_BIO_write(bio, "    Data:\n",
8674
                  (int)XSTRLEN("    Data:\n")) <= 0) {
8675
            return WOLFSSL_FAILURE;
8676
    }
8677
8678
    /* print version of cert */
8679
    if (X509PrintVersion(bio, wolfSSL_X509_version(x509), 8)
8680
            != WOLFSSL_SUCCESS) {
8681
        return WOLFSSL_FAILURE;
8682
    }
8683
8684
    /* print serial number out */
8685
    if (X509PrintSerial(bio, x509, 8) != WOLFSSL_SUCCESS) {
8686
        return WOLFSSL_FAILURE;
8687
    }
8688
8689
    /* print out signature algo*/
8690
    if (X509PrintSignature(bio, x509, 1, 8) != WOLFSSL_SUCCESS) {
8691
        return WOLFSSL_FAILURE;
8692
    }
8693
8694
    /* print issuer */
8695
    if (X509PrintName(bio, wolfSSL_X509_get_issuer_name(x509), issuType, 8)
8696
            != WOLFSSL_SUCCESS) {
8697
        return WOLFSSL_FAILURE;
8698
    }
8699
8700
    #ifndef NO_ASN_TIME
8701
    /* print validity */
8702
    if (X509PrintValidity(bio, &x509->notBefore, &x509->notAfter, 8)
8703
        != WOLFSSL_SUCCESS) {
8704
        return WOLFSSL_FAILURE;
8705
    }
8706
    #endif /* NO_ASN_TIME */
8707
8708
    /* print subject */
8709
    if (X509PrintName(bio, wolfSSL_X509_get_subject_name(x509), subjType, 8)
8710
            != WOLFSSL_SUCCESS) {
8711
        return WOLFSSL_FAILURE;
8712
    }
8713
8714
    /* get and print public key */
8715
    if (X509PrintPubKey(bio, x509, 8) != WOLFSSL_SUCCESS) {
8716
        return WOLFSSL_FAILURE;
8717
    }
8718
8719
    /* print out extensions */
8720
    if (X509PrintExtensions(bio, x509, 8) != WOLFSSL_SUCCESS) {
8721
        return WOLFSSL_FAILURE;
8722
    }
8723
8724
    /* print out signature */
8725
    if (X509PrintSignature(bio, x509, 0, 4) != WOLFSSL_SUCCESS) {
8726
        return WOLFSSL_FAILURE;
8727
    }
8728
8729
    /* done with print out */
8730
    if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
8731
        return WOLFSSL_FAILURE;
8732
    }
8733
8734
    return WOLFSSL_SUCCESS;
8735
}
8736
int wolfSSL_X509_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
8737
{
8738
    return wolfSSL_X509_print_ex(bio, x509, 0, 0);
8739
}
8740
8741
#if defined(WOLFSSL_ACERT)
8742
/* Retrieve sig NID from an ACERT.
8743
 *
8744
 * returns  NID on success
8745
 * returns  0 on failure
8746
 */
8747
int wolfSSL_X509_ACERT_get_signature_nid(const WOLFSSL_X509_ACERT *x509)
8748
{
8749
    if (x509 == NULL) {
8750
        return 0;
8751
    }
8752
8753
    return oid2nid((word32)x509->sigOID, oidSigType);
8754
}
8755
8756
static int X509AcertPrintSignature(WOLFSSL_BIO* bio, WOLFSSL_X509_ACERT* x509,
8757
                                   int algOnly, int indent)
8758
{
8759
    int sigSz = 0;
8760
    if (wolfSSL_X509_ACERT_get_signature(x509, NULL, &sigSz) <= 0) {
8761
        return WOLFSSL_FAILURE;
8762
    }
8763
8764
    if (sigSz > 0) {
8765
        unsigned char* sig;
8766
        int sigNid;
8767
8768
        sigNid = wolfSSL_X509_ACERT_get_signature_nid(x509);
8769
        if (sigNid <= 0) {
8770
            return WOLFSSL_FAILURE;
8771
        }
8772
8773
        sig = (unsigned char*)XMALLOC(sigSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8774
        if (sig == NULL) {
8775
            return WOLFSSL_FAILURE;
8776
        }
8777
8778
        if (wolfSSL_X509_ACERT_get_signature(x509, sig, &sigSz) <= 0) {
8779
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8780
            return WOLFSSL_FAILURE;
8781
        }
8782
8783
        if (X509PrintSignature_ex(bio, sig, sigSz, sigNid, algOnly, indent)
8784
                != WOLFSSL_SUCCESS) {
8785
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8786
            return WOLFSSL_FAILURE;
8787
        }
8788
8789
        if (sig != NULL) {
8790
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8791
        }
8792
8793
    }
8794
8795
    return WOLFSSL_SUCCESS;
8796
}
8797
8798
static int X509AcertPrintSerial(WOLFSSL_BIO* bio, WOLFSSL_X509_ACERT* x509,
8799
                                int indent)
8800
{
8801
    unsigned char serial[32];
8802
    int  sz = sizeof(serial);
8803
8804
    XMEMSET(serial, 0, sz);
8805
    if (wolfSSL_X509_ACERT_get_serial_number(x509, serial, &sz)
8806
        == WOLFSSL_SUCCESS) {
8807
        X509PrintSerial_ex(bio, serial, sz, 1, indent);
8808
    }
8809
    return WOLFSSL_SUCCESS;
8810
}
8811
8812
int wolfSSL_X509_ACERT_print(WOLFSSL_BIO* bio, WOLFSSL_X509_ACERT* x509)
8813
{
8814
    const char * hdr =                "Attribute Certificate:\n";
8815
    const char * data_hdr =           "    Data:\n";
8816
    const char * holder_hdr =         "        Holder:\n";
8817
    const char * holder_issuer_hdr =  "            Issuer:";
8818
    const char * holder_name_hdr =    "            Name:";
8819
    const char * attcert_issuer_hdr = "        Issuer:";
8820
8821
    if (bio == NULL || x509 == NULL) {
8822
        return WOLFSSL_FAILURE;
8823
    }
8824
8825
    /* print acert header */
8826
    if (wolfSSL_BIO_write(bio, hdr, (int)XSTRLEN(hdr)) <= 0) {
8827
        return WOLFSSL_FAILURE;
8828
    }
8829
8830
    /* print data header */
8831
    if (wolfSSL_BIO_write(bio, data_hdr, (int)XSTRLEN(data_hdr)) <= 0) {
8832
        return WOLFSSL_FAILURE;
8833
    }
8834
8835
    /* print version of cert */
8836
    if (X509PrintVersion(bio, wolfSSL_X509_ACERT_version(x509), 8)
8837
            != WOLFSSL_SUCCESS) {
8838
        return WOLFSSL_FAILURE;
8839
    }
8840
8841
    /* print serial number out */
8842
    if (X509AcertPrintSerial(bio, x509, 8) != WOLFSSL_SUCCESS) {
8843
        return WOLFSSL_FAILURE;
8844
    }
8845
8846
    /* print holder field */
8847
    if (wolfSSL_BIO_write(bio, holder_hdr, (int)XSTRLEN(holder_hdr)) <= 0) {
8848
        return WOLFSSL_FAILURE;
8849
    }
8850
8851
    if (x509->holderEntityName != NULL) {
8852
        /* print issuer header */
8853
        if (wolfSSL_BIO_write(bio, holder_name_hdr,
8854
            (int)XSTRLEN(holder_name_hdr)) <= 0) {
8855
            return WOLFSSL_FAILURE;
8856
        }
8857
8858
        if (X509_print_name_entry(bio, x509->holderEntityName, 1)
8859
                != WOLFSSL_SUCCESS) {
8860
            return WOLFSSL_FAILURE;
8861
        }
8862
    }
8863
8864
    if (x509->holderIssuerName != NULL) {
8865
        /* print issuer header */
8866
        if (wolfSSL_BIO_write(bio, holder_issuer_hdr,
8867
            (int)XSTRLEN(holder_issuer_hdr)) <= 0) {
8868
            return WOLFSSL_FAILURE;
8869
        }
8870
8871
        if (X509_print_name_entry(bio, x509->holderIssuerName, 1)
8872
            != WOLFSSL_SUCCESS) {
8873
            return WOLFSSL_FAILURE;
8874
        }
8875
    }
8876
8877
    if (x509->holderSerialSz > 0) {
8878
        X509PrintSerial_ex(bio, x509->holderSerial, x509->holderSerialSz,
8879
                           1, 12);
8880
    }
8881
8882
    /* print issuer header */
8883
    if (wolfSSL_BIO_write(bio, attcert_issuer_hdr,
8884
        (int)XSTRLEN(attcert_issuer_hdr)) <= 0) {
8885
        return WOLFSSL_FAILURE;
8886
    }
8887
8888
    if (x509->AttCertIssuerName != NULL) {
8889
        if (X509_print_name_entry(bio, x509->AttCertIssuerName, 1)
8890
                != WOLFSSL_SUCCESS) {
8891
            return WOLFSSL_FAILURE;
8892
        }
8893
    }
8894
    else {
8895
        const char * msg = " Issuer type not supported.\n";
8896
        if (wolfSSL_BIO_write(bio, msg, (int)XSTRLEN(msg)) <= 0) {
8897
            return WOLFSSL_FAILURE;
8898
        }
8899
    }
8900
8901
    #ifndef NO_ASN_TIME
8902
    /* print validity */
8903
    if (X509PrintValidity(bio, &x509->notBefore, &x509->notAfter, 8)
8904
        != WOLFSSL_SUCCESS) {
8905
        return WOLFSSL_FAILURE;
8906
    }
8907
    #endif /* NO_ASN_TIME */
8908
8909
    /* print raw attributes */
8910
    if (x509->rawAttr && x509->rawAttrLen > 0) {
8911
        char attr_hdr[128]; /* buffer for XSNPRINTF */
8912
8913
        if (XSNPRINTF(attr_hdr, 128, "%*s%s: %d bytes\n", 8, "",
8914
                    "Attributes", x509->rawAttrLen) >= 128) {
8915
            return WOLFSSL_FAILURE;
8916
        }
8917
8918
        if (wolfSSL_BIO_write(bio, attr_hdr, (int)XSTRLEN(attr_hdr)) <= 0) {
8919
                return WOLFSSL_FAILURE;
8920
        }
8921
    }
8922
8923
    /* print out sig algo and signature */
8924
    if (X509AcertPrintSignature(bio, x509, 0, 8) != WOLFSSL_SUCCESS) {
8925
        return WOLFSSL_FAILURE;
8926
    }
8927
8928
    /* done with print out */
8929
    if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
8930
        return WOLFSSL_FAILURE;
8931
    }
8932
8933
    return WOLFSSL_SUCCESS;
8934
}
8935
#endif /* WOLFSSL_ACERT */
8936
8937
#ifndef NO_FILESYSTEM
8938
int wolfSSL_X509_print_fp(XFILE fp, WOLFSSL_X509 *x509)
8939
{
8940
    WOLFSSL_BIO* bio;
8941
    int ret;
8942
8943
    WOLFSSL_ENTER("wolfSSL_X509_print_fp");
8944
8945
    if (!fp || !x509) {
8946
        WOLFSSL_MSG("Bad parameter");
8947
        return WOLFSSL_FAILURE;
8948
    }
8949
8950
    if (!(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file()))) {
8951
        WOLFSSL_MSG("wolfSSL_BIO_new wolfSSL_BIO_s_file error");
8952
        return WOLFSSL_FAILURE;
8953
    }
8954
8955
    if (wolfSSL_BIO_set_fp(bio, fp, WOLFSSL_BIO_NOCLOSE) != WOLFSSL_SUCCESS) {
8956
        WOLFSSL_MSG("wolfSSL_BIO_set_fp error");
8957
        wolfSSL_BIO_free(bio);
8958
        return WOLFSSL_FAILURE;
8959
    }
8960
8961
    ret = wolfSSL_X509_print(bio, x509);
8962
8963
    wolfSSL_BIO_free(bio);
8964
8965
    return ret;
8966
}
8967
#endif /* NO_FILESYSTEM */
8968
8969
#endif /* XSNPRINTF */
8970
8971
int wolfSSL_X509_signature_print(WOLFSSL_BIO *bp,
8972
        const WOLFSSL_X509_ALGOR *sigalg, const WOLFSSL_ASN1_STRING *sig)
8973
{
8974
    int length = 0;
8975
    word32 idx = 0;
8976
    int i;
8977
8978
    (void)sig;
8979
8980
    WOLFSSL_ENTER("wolfSSL_X509_signature_print");
8981
8982
    if (!bp || !sigalg) {
8983
        WOLFSSL_MSG("Bad parameter");
8984
        return WOLFSSL_FAILURE;
8985
    }
8986
8987
    if ((sigalg->algorithm->obj == NULL) ||
8988
        (sigalg->algorithm->obj[idx] != ASN_OBJECT_ID)) {
8989
        WOLFSSL_MSG("Bad ASN1 Object");
8990
        return WOLFSSL_FAILURE;
8991
    }
8992
    idx++; /* skip object id */
8993
8994
    if (GetLength((const byte*)sigalg->algorithm->obj, &idx, &length,
8995
                  sigalg->algorithm->objSz) < 0 || length < 0) {
8996
        return WOLFSSL_FAILURE;
8997
    }
8998
8999
    if (wolfSSL_BIO_puts(bp, "    Raw Signature Algorithm:") <= 0) {
9000
        WOLFSSL_MSG("wolfSSL_BIO_puts error");
9001
        return WOLFSSL_FAILURE;
9002
    }
9003
9004
    for (i = 0; i < length; ++i) {
9005
        char hex_digits[4];
9006
        if (XSNPRINTF(hex_digits, sizeof(hex_digits), "%c%02X", i>0 ? ':' : ' ',
9007
                  (unsigned int)sigalg->algorithm->obj[idx+i])
9008
            >= (int)sizeof(hex_digits))
9009
        {
9010
            WOLFSSL_MSG("buffer overrun");
9011
            return WOLFSSL_FAILURE;
9012
        }
9013
        if (wolfSSL_BIO_puts(bp, hex_digits) <= 0)
9014
            return WOLFSSL_FAILURE;
9015
    }
9016
9017
    if (wolfSSL_BIO_puts(bp, "\n") <= 0)
9018
        return WOLFSSL_FAILURE;
9019
9020
    return WOLFSSL_SUCCESS;
9021
}
9022
#endif /* !NO_BIO */
9023
9024
#ifndef NO_WOLFSSL_STUB
9025
void wolfSSL_X509_get0_signature(const WOLFSSL_ASN1_BIT_STRING **psig,
9026
        const WOLFSSL_X509_ALGOR **palg, const WOLFSSL_X509 *x509)
9027
{
9028
    (void)psig;
9029
    (void)palg;
9030
    (void)x509;
9031
    WOLFSSL_STUB("wolfSSL_X509_get0_signature");
9032
}
9033
#endif
9034
9035
#endif /* OPENSSL_EXTRA */
9036
9037
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
9038
const char* wolfSSL_X509_verify_cert_error_string(long err)
9039
{
9040
    return wolfSSL_ERR_reason_error_string((unsigned long)err);
9041
}
9042
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
9043
9044
#ifdef OPENSSL_EXTRA
9045
9046
/* Add directory path that will be used for loading certs and CRLs
9047
 * which have the <hash>.rn name format.
9048
 * type may be WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
9049
 * returns WOLFSSL_SUCCESS on successful, otherwise negative or zero. */
9050
int wolfSSL_X509_LOOKUP_add_dir(WOLFSSL_X509_LOOKUP* lookup, const char* dir,
9051
                               long type)
9052
{
9053
    return wolfSSL_X509_LOOKUP_ctrl(lookup, WOLFSSL_X509_L_ADD_DIR, dir, type,
9054
                                    NULL);
9055
}
9056
9057
int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP* lookup,
9058
                                 const char* file, long type)
9059
{
9060
#if !defined(NO_FILESYSTEM) && \
9061
    (defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM))
9062
    int           ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
9063
    XFILE         fp;
9064
    long          sz;
9065
    byte*         pem = NULL;
9066
    byte*         curr = NULL;
9067
    byte*         prev = NULL;
9068
    const char* header = NULL;
9069
    const char* footer = NULL;
9070
9071
    if (type != WOLFSSL_FILETYPE_PEM)
9072
        return WS_RETURN_CODE(BAD_FUNC_ARG, (int)WOLFSSL_FAILURE);
9073
9074
    fp = XFOPEN(file, "rb");
9075
    if (fp == XBADFILE)
9076
        return WS_RETURN_CODE(BAD_FUNC_ARG, (int)WOLFSSL_FAILURE);
9077
9078
    if (XFSEEK(fp, 0, XSEEK_END) != 0) {
9079
        XFCLOSE(fp);
9080
        return WS_RETURN_CODE(WOLFSSL_BAD_FILE,WOLFSSL_FAILURE);
9081
    }
9082
    sz = XFTELL(fp);
9083
    if (XFSEEK(fp, 0, XSEEK_SET) != 0) {
9084
        XFCLOSE(fp);
9085
        return WS_RETURN_CODE(WOLFSSL_BAD_FILE,WOLFSSL_FAILURE);
9086
    }
9087
9088
    if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
9089
        WOLFSSL_MSG("X509_LOOKUP_load_file size error");
9090
        goto end;
9091
    }
9092
9093
    pem = (byte*)XMALLOC(sz, 0, DYNAMIC_TYPE_PEM);
9094
    if (pem == NULL) {
9095
        ret = MEMORY_ERROR;
9096
        goto end;
9097
    }
9098
9099
    /* Read in file which may be CRLs or certificates. */
9100
    if (XFREAD(pem, (size_t)sz, 1, fp) != 1)
9101
        goto end;
9102
9103
    prev = curr = pem;
9104
    do {
9105
        /* get PEM header and footer based on type */
9106
        if (wc_PemGetHeaderFooter(CRL_TYPE, &header, &footer) == 0 &&
9107
                XSTRNSTR((char*)curr, header, sz) != NULL) {
9108
#ifdef HAVE_CRL
9109
            WOLFSSL_CERT_MANAGER* cm = lookup->store->cm;
9110
9111
            if (cm->crl == NULL) {
9112
                if (wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECK)
9113
                    != WOLFSSL_SUCCESS) {
9114
                    WOLFSSL_MSG("Enable CRL failed");
9115
                    goto end;
9116
                }
9117
            }
9118
9119
            ret = BufferLoadCRL(cm->crl, curr, sz, WOLFSSL_FILETYPE_PEM,
9120
                NO_VERIFY);
9121
            if (ret != WOLFSSL_SUCCESS)
9122
                goto end;
9123
#endif
9124
            curr = (byte*)XSTRNSTR((char*)curr, footer, sz);
9125
        }
9126
        else if (wc_PemGetHeaderFooter(CERT_TYPE, &header, &footer) == 0 &&
9127
                XSTRNSTR((char*)curr, header, sz) != NULL) {
9128
            ret = X509StoreLoadCertBuffer(lookup->store, curr,
9129
                                        (word32)sz, WOLFSSL_FILETYPE_PEM);
9130
            if (ret != WOLFSSL_SUCCESS)
9131
                goto end;
9132
            curr = (byte*)XSTRNSTR((char*)curr, footer, sz);
9133
        }
9134
        else
9135
            goto end;
9136
9137
        if (curr == NULL)
9138
            goto end;
9139
9140
        curr++;
9141
        sz -= (long)(curr - prev);
9142
        prev = curr;
9143
    }
9144
    while (ret == WOLFSSL_SUCCESS);
9145
9146
end:
9147
    XFREE(pem, 0, DYNAMIC_TYPE_PEM);
9148
    XFCLOSE(fp);
9149
    return WS_RETURN_CODE(ret, (int)WOLFSSL_FAILURE);
9150
#else
9151
    (void)lookup;
9152
    (void)file;
9153
    (void)type;
9154
    return WS_RETURN_CODE(WOLFSSL_FAILURE,WOLFSSL_FAILURE);
9155
#endif
9156
}
9157
9158
WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_hash_dir(void)
9159
{
9160
    /* Method implementation in functions. */
9161
    static WOLFSSL_X509_LOOKUP_METHOD meth = { 1 };
9162
    return &meth;
9163
}
9164
9165
WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_file(void)
9166
{
9167
    /* Method implementation in functions. */
9168
    static WOLFSSL_X509_LOOKUP_METHOD meth = { 0 };
9169
    return &meth;
9170
}
9171
9172
/* set directory path to load certificate or CRL which have the hash.N form */
9173
/* for late use                                                             */
9174
/* @param ctx    a pointer to WOLFSSL_BY_DIR structure                      */
9175
/* @param argc   directory path                                             */
9176
/* @param argl   file type, either WOLFSSL_FILETYPE_PEM or                  */
9177
/*                                          WOLFSSL_FILETYPE_ASN1           */
9178
/* @return WOLFSSL_SUCCESS on successful, otherwise negative or zero        */
9179
/* Note: on failure, path elements parsed before the failing one have       */
9180
/*       already been added to ctx->dir_entry                               */
9181
static int x509AddCertDir(WOLFSSL_BY_DIR *ctx, const char *argc, long argl)
9182
{
9183
#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
9184
    WOLFSSL_BY_DIR_entry *entry;
9185
    size_t pathLen;
9186
    int i, num;
9187
    const char* c;
9188
    WC_DECLARE_VAR(buf, char, MAX_FILENAME_SZ, 0);
9189
9190
    WOLFSSL_ENTER("x509AddCertDir");
9191
9192
    pathLen = 0;
9193
    c = argc;
9194
    /* sanity check, zero length */
9195
    if (ctx == NULL || c == NULL || *c == '\0')
9196
        return WOLFSSL_FAILURE;
9197
9198
#ifdef WOLFSSL_SMALL_STACK
9199
    buf = (char*)XMALLOC(MAX_FILENAME_SZ, NULL, DYNAMIC_TYPE_OPENSSL);
9200
    if (buf == NULL) {
9201
        WOLFSSL_LEAVE("x509AddCertDir", MEMORY_E);
9202
        return MEMORY_E;
9203
    }
9204
#endif
9205
9206
    XMEMSET(buf, 0, MAX_FILENAME_SZ);
9207
9208
    do {
9209
        if (*c == SEPARATOR_CHAR || *c == '\0') {
9210
9211
            num = wolfSSL_sk_BY_DIR_entry_num(ctx->dir_entry);
9212
9213
            for (i=0; i<num; i++) {
9214
9215
                entry = wolfSSL_sk_BY_DIR_entry_value(ctx->dir_entry, i);
9216
9217
                if (XSTRLEN(entry->dir_name) == pathLen &&
9218
                    XSTRNCMP(entry->dir_name, buf, pathLen) == 0) {
9219
                    WOLFSSL_MSG("dir entry found");
9220
                    break;
9221
                }
9222
            }
9223
9224
            if (num == -1 || i == num) {
9225
                WOLFSSL_MSG("no entry found");
9226
9227
                if (ctx->dir_entry == NULL) {
9228
                    ctx->dir_entry = wolfSSL_sk_BY_DIR_entry_new_null();
9229
9230
                    if (ctx->dir_entry == NULL) {
9231
                        WOLFSSL_MSG("failed to allocate dir_entry");
9232
                            WC_FREE_VAR_EX(buf, 0, DYNAMIC_TYPE_OPENSSL);
9233
                        return 0;
9234
                    }
9235
                }
9236
9237
                entry = wolfSSL_BY_DIR_entry_new();
9238
                if (entry == NULL) {
9239
                    WOLFSSL_MSG("failed to allocate dir entry");
9240
                        WC_FREE_VAR_EX(buf, 0, DYNAMIC_TYPE_OPENSSL);
9241
                    return 0;
9242
                }
9243
                entry->dir_type = (int)argl;
9244
                entry->dir_name = (char*)XMALLOC(pathLen + 1/* \0 termination*/
9245
                                                , NULL, DYNAMIC_TYPE_OPENSSL);
9246
                entry->hashes = wolfSSL_sk_BY_DIR_HASH_new_null();
9247
                if (entry->dir_name == NULL || entry->hashes == NULL) {
9248
                    WOLFSSL_MSG("failed to allocate dir name");
9249
                    wolfSSL_BY_DIR_entry_free(entry);
9250
                        WC_FREE_VAR_EX(buf, 0, DYNAMIC_TYPE_OPENSSL);
9251
                    return 0;
9252
                }
9253
9254
                XMEMCPY(entry->dir_name, buf, pathLen);
9255
                entry->dir_name[pathLen] = '\0';
9256
9257
                if (wolfSSL_sk_BY_DIR_entry_push(ctx->dir_entry, entry) <= 0) {
9258
                    wolfSSL_BY_DIR_entry_free(entry);
9259
                        WC_FREE_VAR_EX(buf, 0, DYNAMIC_TYPE_OPENSSL);
9260
                    return 0;
9261
                }
9262
            }
9263
            /* skip separator */
9264
            if (*c == SEPARATOR_CHAR) c++;
9265
9266
            pathLen = 0;
9267
            XMEMSET(buf, 0, MAX_FILENAME_SZ);
9268
        }
9269
        if (pathLen >= MAX_FILENAME_SZ) {
9270
            WOLFSSL_MSG("dir name too long for internal buffer");
9271
            WC_FREE_VAR_EX(buf, 0, DYNAMIC_TYPE_OPENSSL);
9272
            return 0;
9273
        }
9274
        buf[pathLen++] = *c;
9275
9276
    } while(*c++ != '\0');
9277
9278
    WC_FREE_VAR_EX(buf, 0, DYNAMIC_TYPE_OPENSSL);
9279
9280
    return WOLFSSL_SUCCESS;
9281
#else
9282
    (void)ctx;
9283
    (void)argc;
9284
    (void)argl;
9285
    return WOLFSSL_NOT_IMPLEMENTED;
9286
#endif
9287
}
9288
9289
/* set additional data to X509_LOOKUP                                   */
9290
/* @param ctx    a pointer to X509_LOOKUP structure                     */
9291
/* @param cmd    control command :                                      */
9292
/*               X509_L_FILE_LOAD, X509_L_ADD_DIR X509_L_ADD_STORE or   */
9293
/*               X509_L_LOAD_STORE                                      */
9294
/* @param argc   arguments for the control command                      */
9295
/* @param argl   arguments for the control command                      */
9296
/* @param **ret  return value of the control command                    */
9297
/* @return WOLFSSL_SUCCESS on successful, otherwise WOLFSSL_FAILURE     */
9298
/* note: WOLFSSL_X509_L_ADD_STORE and WOLFSSL_X509_L_LOAD_STORE have not*/
9299
/*       yet implemented. It returns WOLFSSL_NOT_IMPLEMENTED            */
9300
/*       when those control commands are passed.                        */
9301
/* Note: on failure, path elements parsed before the failing one have   */
9302
/*       already been added to ctx->dir_entry                           */
9303
int wolfSSL_X509_LOOKUP_ctrl(WOLFSSL_X509_LOOKUP *ctx, int cmd,
9304
        const char *argc, long argl, char **ret)
9305
{
9306
    int lret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
9307
9308
    WOLFSSL_ENTER("wolfSSL_X509_LOOKUP_ctrl");
9309
#if !defined(NO_FILESYSTEM)
9310
    if (ctx != NULL) {
9311
        switch (cmd) {
9312
        case WOLFSSL_X509_L_FILE_LOAD:
9313
            /* expects to return a number of processed cert or crl file */
9314
            lret = wolfSSL_X509_load_cert_crl_file(ctx, argc, (int)argl) > 0 ?
9315
                            WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
9316
            break;
9317
        case WOLFSSL_X509_L_ADD_DIR:
9318
            /* store directory location to use it later */
9319
#if !defined(NO_WOLFSSL_DIR)
9320
            lret = x509AddCertDir(ctx->dirs, argc, argl);
9321
#else
9322
            (void)x509AddCertDir;
9323
            lret = WOLFSSL_NOT_IMPLEMENTED;
9324
#endif
9325
            break;
9326
        case WOLFSSL_X509_L_ADD_STORE:
9327
        case WOLFSSL_X509_L_LOAD_STORE:
9328
            return WOLFSSL_NOT_IMPLEMENTED;
9329
9330
        default:
9331
            break;
9332
        }
9333
    }
9334
    (void)ret;
9335
#else
9336
    (void)ctx;
9337
    (void)argc;
9338
    (void)argl;
9339
    (void)ret;
9340
    (void)cmd;
9341
    (void)x509AddCertDir;
9342
    lret = WOLFSSL_NOT_IMPLEMENTED;
9343
#endif
9344
    return lret;
9345
}
9346
9347
9348
#if defined(WOLFSSL_CERT_GEN)
9349
static int wolfssl_x509_make_der(WOLFSSL_X509* x509, int req,
9350
        unsigned char* der, int* derSz, int includeSig);
9351
#endif
9352
9353
#ifdef WOLFSSL_CERT_GEN
9354
#ifndef NO_BIO
9355
/* Converts the X509 to DER format and outputs it into bio.
9356
 *
9357
 * bio  is the structure to hold output DER
9358
 * x509 certificate to create DER from
9359
 * req  if set then a CSR is generated
9360
 *
9361
 * returns WOLFSSL_SUCCESS on success
9362
 */
9363
static int loadX509orX509REQFromBio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
9364
    int req)
9365
{
9366
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
9367
    /* Get large buffer to hold cert der */
9368
    int derSz = X509_BUFFER_SZ;
9369
    WC_DECLARE_VAR(der, byte, X509_BUFFER_SZ, 0);
9370
    WOLFSSL_ENTER("wolfSSL_i2d_X509_bio");
9371
9372
    if (bio == NULL || x509 == NULL) {
9373
        return WOLFSSL_FAILURE;
9374
    }
9375
9376
#ifdef WOLFSSL_SMALL_STACK
9377
    der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
9378
    if (!der) {
9379
        WOLFSSL_MSG("malloc failed");
9380
        return WOLFSSL_FAILURE;
9381
    }
9382
#endif
9383
9384
    if (wolfssl_x509_make_der(x509, req, der, &derSz, 1) != WOLFSSL_SUCCESS) {
9385
        goto cleanup;
9386
    }
9387
9388
    if (wolfSSL_BIO_write(bio, der, derSz) != derSz) {
9389
        goto cleanup;
9390
    }
9391
9392
    ret = WOLFSSL_SUCCESS;
9393
cleanup:
9394
    WC_FREE_VAR_EX(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
9395
9396
    return ret;
9397
}
9398
9399
/* Converts the X509 to DER format and outputs it into bio.
9400
 *
9401
 * bio  is the structure to hold output DER
9402
 * x509 certificate to create DER from
9403
 *
9404
 * returns WOLFSSL_SUCCESS on success
9405
 */
9406
int wolfSSL_i2d_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
9407
{
9408
    return loadX509orX509REQFromBio(bio, x509, 0);
9409
}
9410
9411
#ifdef WOLFSSL_CERT_REQ
9412
int wolfSSL_i2d_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
9413
{
9414
    return loadX509orX509REQFromBio(bio, x509, 1);
9415
}
9416
#endif /* WOLFSSL_CERT_REQ */
9417
#endif /* !NO_BIO */
9418
#endif /* WOLFSSL_CERT_GEN */
9419
9420
/* Converts an internal structure to a DER buffer
9421
 *
9422
 * x509 structure to get DER buffer from
9423
 * out  buffer to hold result. If NULL then *out is NULL then a new buffer is
9424
 *      created.
9425
 *
9426
 * returns the size of the DER result on success
9427
 */
9428
int wolfSSL_i2d_X509(WOLFSSL_X509* x509, unsigned char** out)
9429
{
9430
    const unsigned char* der;
9431
    int derSz = 0;
9432
    int advance = 1;
9433
9434
    WOLFSSL_ENTER("wolfSSL_i2d_X509");
9435
9436
    if (x509 == NULL) {
9437
        WOLFSSL_LEAVE("wolfSSL_i2d_X509", BAD_FUNC_ARG);
9438
        return BAD_FUNC_ARG;
9439
    }
9440
9441
    der = wolfSSL_X509_get_der(x509, &derSz);
9442
    if (der == NULL || derSz <= 0) {
9443
        WOLFSSL_LEAVE("wolfSSL_i2d_X509", MEMORY_E);
9444
        return MEMORY_E;
9445
    }
9446
9447
    if (out != NULL && *out == NULL) {
9448
        *out = (unsigned char*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL);
9449
        if (*out == NULL) {
9450
            WOLFSSL_LEAVE("wolfSSL_i2d_X509", MEMORY_E);
9451
            return MEMORY_E;
9452
        }
9453
        advance = 0;
9454
    }
9455
9456
    if (out != NULL) {
9457
        XMEMCPY(*out, der, derSz);
9458
        if (advance)
9459
            *out += derSz;
9460
    }
9461
9462
    WOLFSSL_LEAVE("wolfSSL_i2d_X509", derSz);
9463
    return derSz;
9464
}
9465
9466
#ifdef WOLFSSL_DUAL_ALG_CERTS
9467
/* Generate a der preTBS from a decoded cert, and write
9468
 * to buffer.
9469
 *
9470
 * @param [in]  cert  The decoded cert to parse.
9471
 * @param [out] der   The der buffer to write in.
9472
 * @param [in]  derSz The der buffer size.
9473
 *
9474
 * @return  preTBS der size on success.
9475
 * */
9476
int wc_GeneratePreTBS(DecodedCert* cert, byte *der, int derSz) {
9477
    int ret = 0;
9478
    WOLFSSL_X509 *x = NULL;
9479
    byte certIsCSR = 0;
9480
9481
    WOLFSSL_ENTER("wc_GeneratePreTBS");
9482
9483
    if ((cert == NULL) || (der == NULL) || (derSz <= 0)) {
9484
        return BAD_FUNC_ARG;
9485
    }
9486
9487
#ifdef WOLFSSL_CERT_REQ
9488
    certIsCSR = cert->isCSR;
9489
#endif
9490
9491
    x = wolfSSL_X509_new();
9492
    if (x == NULL) {
9493
        ret = MEMORY_E;
9494
    }
9495
    else {
9496
        ret = CopyDecodedToX509(x, cert);
9497
    }
9498
9499
    if (ret == 0) {
9500
        /* Remove the altsigval extension. */
9501
        XFREE(x->altSigValDer, x->heap, DYNAMIC_TYPE_X509_EXT);
9502
        x->altSigValDer = NULL;
9503
        x->altSigValLen = 0;
9504
        /* Remove sigOID so it won't be encoded. */
9505
        x->sigOID = 0;
9506
        /* We now have a PreTBS. Encode it. */
9507
        ret = wolfssl_x509_make_der(x, certIsCSR, der, &derSz, 0);
9508
        if (ret == WOLFSSL_SUCCESS) {
9509
            ret = derSz;
9510
        }
9511
    }
9512
9513
    if (x != NULL) {
9514
        wolfSSL_X509_free(x);
9515
        x = NULL;
9516
    }
9517
9518
    return ret;
9519
}
9520
#endif /* WOLFSSL_DUAL_ALG_CERTS */
9521
9522
#ifndef NO_BIO
9523
/**
9524
 * Converts the DER from bio and creates a WOLFSSL_X509 structure from it.
9525
 * @param bio  is the structure holding DER
9526
 * @param x509 certificate to create from DER. Can be NULL
9527
 * @param req  1 for a CSR and 0 for a x509 cert
9528
 * @return pointer to WOLFSSL_X509 structure on success and NULL on fail
9529
 */
9530
static WOLFSSL_X509* d2i_X509orX509REQ_bio(WOLFSSL_BIO* bio,
9531
                                            WOLFSSL_X509** x509, int req)
9532
{
9533
    WOLFSSL_X509* localX509 = NULL;
9534
    byte* mem  = NULL;
9535
    int    size;
9536
    int    derSz;
9537
    int    hdrSz = 2;
9538
    int    len = 0;
9539
    word32 idx = 1;
9540
    byte   hdr[6];
9541
9542
    WOLFSSL_ENTER("wolfSSL_d2i_X509_bio");
9543
9544
    if (bio == NULL) {
9545
        WOLFSSL_MSG("Bad Function Argument bio is NULL");
9546
        return NULL;
9547
    }
9548
9549
    size = wolfSSL_BIO_get_len(bio);
9550
    if (size <= 0) {
9551
        WOLFSSL_MSG("wolfSSL_BIO_get_len error. Possibly no pending data.");
9552
        WOLFSSL_ERROR(WOLFSSL_ASN1_R_HEADER_TOO_LONG_E);
9553
        return NULL;
9554
    }
9555
9556
    /* Consume only the first DER object. A BIO holding a chain is then
9557
     * decoded one certificate per call, as with OpenSSL. */
9558
    if (wolfSSL_BIO_read(bio, hdr, hdrSz) != hdrSz) {
9559
        WOLFSSL_MSG("wolfSSL_BIO_read error");
9560
        return NULL;
9561
    }
9562
    if (hdr[1] & ASN_LONG_LENGTH) {
9563
        int n = hdr[1] & 0x7F;
9564
        if (n < 1 || n > 4 || wolfSSL_BIO_read(bio, hdr + hdrSz, n) != n) {
9565
            WOLFSSL_MSG("Bad DER length");
9566
            return NULL;
9567
        }
9568
        hdrSz += n;
9569
    }
9570
    if (hdr[0] != (ASN_SEQUENCE | ASN_CONSTRUCTED) ||
9571
            GetLength_ex(hdr, &idx, &len, (word32)hdrSz, 0) < 0 ||
9572
            len < 0 || (int)idx + len > size) {
9573
        WOLFSSL_MSG("Bad DER header");
9574
        return NULL;
9575
    }
9576
    derSz = (int)idx + len;
9577
9578
    if (!(mem = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL))) {
9579
        WOLFSSL_MSG("malloc error");
9580
        return NULL;
9581
    }
9582
    XMEMCPY(mem, hdr, hdrSz);
9583
    if (derSz > hdrSz && wolfSSL_BIO_read(bio, mem + hdrSz, derSz - hdrSz) !=
9584
            derSz - hdrSz) {
9585
        WOLFSSL_MSG("wolfSSL_BIO_read error");
9586
        XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL);
9587
        return NULL;
9588
    }
9589
9590
    if (req) {
9591
#ifdef WOLFSSL_CERT_REQ
9592
        localX509 = wolfSSL_X509_REQ_d2i(NULL, mem, derSz);
9593
#else
9594
        WOLFSSL_MSG("CSR not compiled in");
9595
#endif
9596
    }
9597
    else {
9598
        localX509 = wolfSSL_X509_d2i_ex(NULL, mem, derSz, bio->heap);
9599
    }
9600
    if (localX509 == NULL) {
9601
        WOLFSSL_MSG("wolfSSL_X509_d2i error");
9602
        XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL);
9603
        return NULL;
9604
    }
9605
9606
    if (x509 != NULL) {
9607
        *x509 = localX509;
9608
    }
9609
9610
    XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL);
9611
    return localX509;
9612
}
9613
9614
WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509)
9615
{
9616
    return d2i_X509orX509REQ_bio(bio, x509, 0);
9617
}
9618
9619
#ifdef WOLFSSL_CERT_REQ
9620
WOLFSSL_X509* wolfSSL_d2i_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509)
9621
{
9622
    return d2i_X509orX509REQ_bio(bio, x509, 1);
9623
}
9624
#endif
9625
#endif /* !NO_BIO */
9626
9627
#endif /* OPENSSL_EXTRA */
9628
9629
#ifdef OPENSSL_EXTRA
9630
/* Use the public key to verify the signature. Note: this only verifies
9631
 * the certificate signature.
9632
 * returns WOLFSSL_SUCCESS on successful signature verification */
9633
static int verifyX509orX509REQ(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey,
9634
    int req)
9635
{
9636
    int ret;
9637
    const byte* der;
9638
    int derSz = 0;
9639
    int type;
9640
    const byte* pubKey;
9641
    int pubKeySz;
9642
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
9643
    byte edPubKey[ED25519_PUB_KEY_SIZE];
9644
    word32 edPubKeySz = (word32)sizeof(edPubKey);
9645
#endif
9646
9647
    (void)req;
9648
9649
    if (x509 == NULL || pkey == NULL) {
9650
        return WOLFSSL_FATAL_ERROR;
9651
    }
9652
9653
    der = wolfSSL_X509_get_der(x509, &derSz);
9654
    if (der == NULL) {
9655
        WOLFSSL_MSG("Error getting WOLFSSL_X509 DER");
9656
        return WOLFSSL_FATAL_ERROR;
9657
    }
9658
9659
    /* Most key types verify against the cached public-key DER. */
9660
    pubKey   = (const byte*)pkey->pkey.ptr;
9661
    pubKeySz = pkey->pkey_sz;
9662
9663
    switch (pkey->type) {
9664
        case WC_EVP_PKEY_RSA:
9665
            type = RSAk;
9666
            break;
9667
9668
        case WC_EVP_PKEY_EC:
9669
            type = ECDSAk;
9670
            break;
9671
9672
        case WC_EVP_PKEY_DSA:
9673
            type = DSAk;
9674
            break;
9675
9676
    #if defined(WOLFSSL_HAVE_MLDSA)
9677
        case WC_EVP_PKEY_DILITHIUM:
9678
            type = WOLFSSL_ATOMIC_LOAD(pkey->mldsaOID);
9679
            if (type == 0) {
9680
                WOLFSSL_MSG("ML-DSA pkey missing key OID");
9681
                return WOLFSSL_FATAL_ERROR;
9682
            }
9683
            break;
9684
    #endif
9685
    #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
9686
        case WC_EVP_PKEY_ED25519:
9687
            /* The signature check needs the raw public key; for Ed25519
9688
             * pkey->pkey.ptr holds a PKCS#8 private blob (or nothing), so
9689
             * export the public key from the ed25519_key instead. */
9690
            if (pkey->ed25519 == NULL ||
9691
                    wc_ed25519_export_public(pkey->ed25519, edPubKey,
9692
                        &edPubKeySz) != 0) {
9693
                WOLFSSL_MSG("Unable to export Ed25519 public key");
9694
                return WOLFSSL_FATAL_ERROR;
9695
            }
9696
            pubKey   = edPubKey;
9697
            pubKeySz = (int)edPubKeySz;
9698
            type     = ED25519k;
9699
            break;
9700
    #endif
9701
9702
        default:
9703
            WOLFSSL_MSG("Unknown pkey key type");
9704
            return WOLFSSL_FATAL_ERROR;
9705
    }
9706
9707
#ifdef WOLFSSL_CERT_REQ
9708
    if (req)
9709
        ret = CheckCSRSignaturePubKey(der, (word32)derSz, x509->heap,
9710
                (unsigned char*)pubKey, pubKeySz, type);
9711
    else
9712
#endif
9713
        ret = CheckCertSignaturePubKey(der, (word32)derSz, x509->heap,
9714
                (unsigned char*)pubKey, pubKeySz, type);
9715
    if (ret == 0) {
9716
        return WOLFSSL_SUCCESS;
9717
    }
9718
    return WOLFSSL_FAILURE;
9719
}
9720
9721
int wolfSSL_X509_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey)
9722
{
9723
    return verifyX509orX509REQ(x509, pkey, 0);
9724
}
9725
9726
#ifdef WOLFSSL_CERT_REQ
9727
int wolfSSL_X509_REQ_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey)
9728
{
9729
    return verifyX509orX509REQ(x509, pkey, 1);
9730
}
9731
#endif /* WOLFSSL_CERT_REQ */
9732
9733
#if !defined(NO_FILESYSTEM)
9734
static void *wolfSSL_d2i_X509_fp_ex(XFILE file, void **x509, int type)
9735
{
9736
    void *newx509 = NULL;
9737
    byte *fileBuffer = NULL;
9738
    long sz = 0;
9739
9740
    /* init variable */
9741
    if (x509)
9742
        *x509 = NULL;
9743
9744
    /* argument check */
9745
    if (file == XBADFILE) {
9746
        return NULL;
9747
    }
9748
9749
    /* determine file size */
9750
    if (XFSEEK(file, 0, XSEEK_END) != 0) {
9751
        return NULL;
9752
    }
9753
    sz = XFTELL(file);
9754
    if (XFSEEK(file, 0, XSEEK_SET) != 0) {
9755
        return NULL;
9756
    }
9757
9758
    if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
9759
        WOLFSSL_MSG("d2i_X509_fp_ex file size error");
9760
        return NULL;
9761
    }
9762
9763
    fileBuffer = (byte *)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
9764
    if (fileBuffer != NULL) {
9765
        if ((long)XFREAD(fileBuffer, 1, (size_t)sz, file) != sz) {
9766
            WOLFSSL_MSG("File read failed");
9767
            goto err_exit;
9768
        }
9769
        if (type == CERT_TYPE) {
9770
            newx509 = (void *)wolfSSL_X509_d2i(NULL, fileBuffer, (int)sz);
9771
        }
9772
    #ifdef HAVE_CRL
9773
        else if (type == CRL_TYPE) {
9774
            newx509 = (void *)wolfSSL_d2i_X509_CRL(NULL, fileBuffer, (int)sz);
9775
        }
9776
    #endif
9777
    #ifdef WOLFSSL_CERT_REQ
9778
        else if (type == CERTREQ_TYPE) {
9779
             newx509 = (void *)wolfSSL_X509_REQ_d2i(NULL, fileBuffer, (int)sz);
9780
        }
9781
    #endif
9782
    #if !defined(NO_ASN) && !defined(NO_PWDBASED) && defined(HAVE_PKCS12)
9783
        else if (type == PKCS12_TYPE) {
9784
            if ((newx509 = wc_PKCS12_new()) == NULL) {
9785
                goto err_exit;
9786
            }
9787
            if (wc_d2i_PKCS12(fileBuffer, (word32)sz,
9788
                                                     (WC_PKCS12*)newx509) < 0) {
9789
                goto err_exit;
9790
            }
9791
        }
9792
    #endif
9793
        else {
9794
            goto err_exit;
9795
        }
9796
        if (newx509 == NULL) {
9797
            WOLFSSL_MSG("X509 failed");
9798
            goto err_exit;
9799
        }
9800
    }
9801
9802
    if (x509)
9803
        *x509 = newx509;
9804
9805
    goto _exit;
9806
9807
err_exit:
9808
#if !defined(NO_ASN) && !defined(NO_PWDBASED) && defined(HAVE_PKCS12)
9809
    if ((newx509 != NULL) && (type == PKCS12_TYPE)) {
9810
        wc_PKCS12_free((WC_PKCS12*)newx509);
9811
        newx509 = NULL;
9812
    }
9813
#endif
9814
_exit:
9815
    XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
9816
9817
    return newx509;
9818
}
9819
9820
#ifdef WOLFSSL_CERT_REQ
9821
WOLFSSL_X509* wolfSSL_d2i_X509_REQ_fp(XFILE fp, WOLFSSL_X509 **req)
9822
{
9823
    return (WOLFSSL_X509 *)wolfSSL_d2i_X509_fp_ex(fp, (void **)req,
9824
                                                  CERTREQ_TYPE);
9825
}
9826
#endif /* WOLFSSL_CERT_REQ */
9827
9828
WOLFSSL_X509 *wolfSSL_d2i_X509_fp(XFILE fp, WOLFSSL_X509 **x509)
9829
{
9830
    WOLFSSL_ENTER("wolfSSL_d2i_X509_fp");
9831
    return (WOLFSSL_X509 *)wolfSSL_d2i_X509_fp_ex(fp, (void **)x509, CERT_TYPE);
9832
}
9833
9834
/* load certificate or CRL file, and add it to the STORE           */
9835
/* @param ctx    a pointer to X509_LOOKUP structure                */
9836
/* @param file   file name to load                                 */
9837
/* @param type   WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1     */
9838
/* @return a number of loading CRL or certificate, otherwise zero  */
9839
int wolfSSL_X509_load_cert_crl_file(WOLFSSL_X509_LOOKUP *ctx,
9840
    const char *file, int type)
9841
{
9842
    WOLFSSL_X509 *x509 = NULL;
9843
9844
    int cnt = 0;
9845
9846
    WOLFSSL_ENTER("wolfSSL_X509_load_cert_crl_file");
9847
9848
    /* stanity check */
9849
    if (ctx == NULL || file == NULL) {
9850
        WOLFSSL_MSG("bad arguments");
9851
        return 0;
9852
    }
9853
9854
    if (type != WOLFSSL_FILETYPE_PEM) {
9855
        x509 = wolfSSL_X509_load_certificate_file(file, type);
9856
        if (x509 != NULL) {
9857
            if (wolfSSL_X509_STORE_add_cert(ctx->store, x509)
9858
                                    == WOLFSSL_SUCCESS) {
9859
                cnt++;
9860
            }
9861
            else {
9862
                WOLFSSL_MSG("wolfSSL_X509_STORE_add_cert error");
9863
            }
9864
            wolfSSL_X509_free(x509);
9865
            x509 = NULL;
9866
        }
9867
        else {
9868
            WOLFSSL_MSG("wolfSSL_X509_load_certificate_file error");
9869
        }
9870
9871
    }
9872
    else {
9873
#if defined(OPENSSL_ALL)
9874
    #if !defined(NO_BIO)
9875
        STACK_OF(WOLFSSL_X509_INFO) *info;
9876
        WOLFSSL_X509_INFO *info_tmp;
9877
        int i;
9878
        int num = 0;
9879
        WOLFSSL_BIO *bio = wolfSSL_BIO_new_file(file, "rb");
9880
        if (!bio) {
9881
            WOLFSSL_MSG("wolfSSL_BIO_new error");
9882
            return cnt;
9883
        }
9884
9885
        info = wolfSSL_PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
9886
9887
        wolfSSL_BIO_free(bio);
9888
9889
        if (!info) {
9890
            WOLFSSL_MSG("wolfSSL_PEM_X509_INFO_read_bio error");
9891
            return cnt;
9892
        }
9893
        num = wolfSSL_sk_X509_INFO_num(info);
9894
        for (i=0; i < num; i++) {
9895
            info_tmp = wolfSSL_sk_X509_INFO_value(info, i);
9896
9897
            if (info_tmp == NULL)
9898
                continue;
9899
9900
            if (info_tmp->x509) {
9901
                if (wolfSSL_X509_STORE_add_cert(ctx->store, info_tmp->x509) ==
9902
                    WOLFSSL_SUCCESS) {
9903
                    cnt ++;
9904
                }
9905
                else {
9906
                    WOLFSSL_MSG("wolfSSL_X509_STORE_add_cert failed");
9907
                }
9908
            }
9909
#ifdef HAVE_CRL
9910
            if (info_tmp->crl) {
9911
                if (wolfSSL_X509_STORE_add_crl(ctx->store, info_tmp->crl) ==
9912
                    WOLFSSL_SUCCESS) {
9913
                    cnt ++;
9914
                }
9915
                else {
9916
                    WOLFSSL_MSG("wolfSSL_X509_STORE_add_crl failed");
9917
                }
9918
            }
9919
#endif
9920
        }
9921
        wolfSSL_sk_X509_INFO_pop_free(info, wolfSSL_X509_INFO_free);
9922
    #elif defined(HAVE_CRL)
9923
        /* Only supports one certificate or CRL in the file. */
9924
        WOLFSSL_X509_CRL* crl = NULL;
9925
        XFILE fp = XFOPEN(file, "rb");
9926
        if (fp == XBADFILE) {
9927
            WOLFSSL_MSG("XFOPEN error");
9928
            return cnt;
9929
        }
9930
9931
        x509 = wolfSSL_PEM_read_X509(fp, NULL, NULL, NULL);
9932
        if (x509 != NULL) {
9933
            if (wolfSSL_X509_STORE_add_cert(ctx->store, x509) ==
9934
                WOLFSSL_SUCCESS) {
9935
                cnt++;
9936
            }
9937
            else {
9938
                WOLFSSL_MSG("wolfSSL_X509_STORE_add_cert failed");
9939
            }
9940
        }
9941
        else {
9942
            if (XFSEEK(fp, 0, XSEEK_SET) != 0) {
9943
                WOLFSSL_MSG("XFSEEK error");
9944
                return cnt;
9945
            }
9946
            crl = wolfSSL_PEM_read_X509_CRL(fp, NULL, NULL, NULL);
9947
            if (crl != NULL) {
9948
                if (wolfSSL_X509_STORE_add_crl(ctx->store, crl) ==
9949
                    WOLFSSL_SUCCESS) {
9950
                    cnt++;
9951
                }
9952
                else {
9953
                    WOLFSSL_MSG("wolfSSL_X509_STORE_add_crl failed");
9954
                }
9955
            }
9956
            else {
9957
                WOLFSSL_MSG("Certificate and CRL not recognized");
9958
                return cnt;
9959
            }
9960
        }
9961
9962
        wolfSSL_X509_free(x509);
9963
        wolfSSL_X509_CRL_free(crl);
9964
    #endif
9965
#else
9966
    (void)cnt;
9967
#endif /* OPENSSL_ALL && !NO_BIO */
9968
    }
9969
9970
    WOLFSSL_LEAVE("wolfSSL_X509_load_ceretificate_crl_file", cnt);
9971
    return cnt;
9972
}
9973
#endif /* !NO_FILESYSTEM */
9974
9975
9976
#ifdef HAVE_CRL
9977
9978
#ifndef NO_BIO
9979
WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL_bio(WOLFSSL_BIO *bp,
9980
                                                    WOLFSSL_X509_CRL **x)
9981
{
9982
    int derSz;
9983
    byte* der = NULL;
9984
    WOLFSSL_X509_CRL* crl = NULL;
9985
9986
    if (bp == NULL)
9987
        return NULL;
9988
9989
    if ((derSz = wolfSSL_BIO_get_len(bp)) > 0) {
9990
        der = (byte*)XMALLOC(derSz, 0, DYNAMIC_TYPE_DER);
9991
        if (der != NULL) {
9992
            if (wolfSSL_BIO_read(bp, der, derSz) == derSz) {
9993
                crl = wolfSSL_d2i_X509_CRL(x, der, derSz);
9994
            }
9995
        }
9996
    }
9997
9998
    XFREE(der, 0, DYNAMIC_TYPE_DER);
9999
10000
    return crl;
10001
}
10002
#endif
10003
10004
#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
10005
WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL_fp(XFILE fp, WOLFSSL_X509_CRL **crl)
10006
{
10007
    WOLFSSL_ENTER("wolfSSL_d2i_X509_CRL_fp");
10008
    return (WOLFSSL_X509_CRL *)wolfSSL_d2i_X509_fp_ex(fp, (void **)crl,
10009
        CRL_TYPE);
10010
}
10011
10012
/* Read CRL file, and add it to store and corresponding cert manager     */
10013
/* @param ctx   a pointer of X509_LOOKUP back to the X509_STORE          */
10014
/* @param file  a file to read                                           */
10015
/* @param type  WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1            */
10016
/* @return WOLFSSL_SUCCESS(1) on successful, otherwise WOLFSSL_FAILURE(0)*/
10017
int wolfSSL_X509_load_crl_file(WOLFSSL_X509_LOOKUP *ctx,
10018
                                             const char *file, int type)
10019
{
10020
#ifndef NO_BIO
10021
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
10022
    int count = 0;
10023
    WOLFSSL_BIO *bio = NULL;
10024
    WOLFSSL_X509_CRL *crl = NULL;
10025
10026
    WOLFSSL_ENTER("wolfSSL_X509_load_crl_file");
10027
10028
    if (ctx == NULL || file == NULL)
10029
        return ret;
10030
10031
    if ((bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file())) == NULL)
10032
        return ret;
10033
10034
    if (wolfSSL_BIO_read_filename(bio, file) <= 0) {
10035
        wolfSSL_BIO_free(bio);
10036
        return ret;
10037
    }
10038
10039
    if (wolfSSL_BIO_read_filename(bio, file) <= 0) {
10040
        wolfSSL_BIO_free(bio);
10041
        return ret;
10042
    }
10043
10044
    if (type == WOLFSSL_FILETYPE_PEM) {
10045
        do {
10046
            crl = wolfSSL_PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL);
10047
            if (crl == NULL) {
10048
                if (count <= 0) {
10049
                    WOLFSSL_MSG("Load crl failed");
10050
                }
10051
                break;
10052
            }
10053
10054
            ret = wolfSSL_X509_STORE_add_crl(ctx->store, crl);
10055
            if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
10056
                WOLFSSL_MSG("Adding crl failed");
10057
                break;
10058
            }
10059
            count++;
10060
            wolfSSL_X509_CRL_free(crl);
10061
            crl = NULL;
10062
        }   while(crl == NULL);
10063
10064
        ret = count;
10065
    }
10066
    else if (type == WOLFSSL_FILETYPE_ASN1) {
10067
        crl = wolfSSL_d2i_X509_CRL_bio(bio, NULL);
10068
        if (crl == NULL) {
10069
            WOLFSSL_MSG("Load crl failed");
10070
        }
10071
        else {
10072
            ret = wolfSSL_X509_STORE_add_crl(ctx->store, crl);
10073
            if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
10074
                WOLFSSL_MSG("Adding crl failed");
10075
            }
10076
            else {
10077
                ret = 1;/* handled a file */
10078
            }
10079
        }
10080
    }
10081
    else {
10082
        WOLFSSL_MSG("Invalid file type");
10083
    }
10084
10085
    wolfSSL_X509_CRL_free(crl);
10086
    wolfSSL_BIO_free(bio);
10087
10088
    WOLFSSL_LEAVE("wolfSSL_X509_load_crl_file", ret);
10089
    return ret;
10090
#else
10091
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
10092
    int count = 0;
10093
    XFILE fp;
10094
    WOLFSSL_X509_CRL *crl = NULL;
10095
10096
    WOLFSSL_ENTER("wolfSSL_X509_load_crl_file");
10097
10098
    if (ctx == NULL || file == NULL)
10099
        return ret;
10100
10101
    if ((fp = XFOPEN(file, "rb")) == XBADFILE)
10102
        return ret;
10103
10104
    if (type == WOLFSSL_FILETYPE_PEM) {
10105
        do {
10106
            crl = wolfSSL_PEM_read_X509_CRL(fp, NULL, NULL, NULL);
10107
            if (crl == NULL) {
10108
                if (count <= 0) {
10109
                    WOLFSSL_MSG("Load crl failed");
10110
                }
10111
                break;
10112
            }
10113
10114
            ret = wolfSSL_X509_STORE_add_crl(ctx->store, crl);
10115
            if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
10116
                WOLFSSL_MSG("Adding crl failed");
10117
                break;
10118
            }
10119
            count++;
10120
            wolfSSL_X509_CRL_free(crl);
10121
            crl = NULL;
10122
        }
10123
        while(crl == NULL);
10124
10125
        ret = count;
10126
    }
10127
    else if (type == WOLFSSL_FILETYPE_ASN1) {
10128
        crl = wolfSSL_d2i_X509_CRL_fp(fp, NULL);
10129
        if (crl == NULL) {
10130
            WOLFSSL_MSG("Load crl failed");
10131
        }
10132
        else {
10133
            ret = wolfSSL_X509_STORE_add_crl(ctx->store, crl);
10134
            if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
10135
                WOLFSSL_MSG("Adding crl failed");
10136
            }
10137
            else {
10138
                ret = 1;/* handled a file */
10139
            }
10140
        }
10141
    }
10142
    else {
10143
        WOLFSSL_MSG("Invalid file type");
10144
    }
10145
10146
    wolfSSL_X509_CRL_free(crl);
10147
    XFCLOSE(fp);
10148
10149
    WOLFSSL_LEAVE("wolfSSL_X509_load_crl_file", ret);
10150
    return ret;
10151
#endif /* !NO_BIO */
10152
}
10153
#endif /* !NO_FILESYSTEM */
10154
10155
10156
/* Decode a DER encoded CRL, following the OpenSSL d2i contract.
10157
 *
10158
 * The OpenSSL form takes a pointer to the buffer pointer and advances it
10159
 * past the object that was decoded, which is how a caller walks a buffer
10160
 * holding more than one object. wolfSSL_d2i_X509_CRL() takes the buffer
10161
 * directly and cannot report what it consumed, so an OpenSSL caller
10162
 * passing &p would hand it the address of its own pointer variable.
10163
 *
10164
 * @param [in, out] crl  CRL object to return, may be NULL.
10165
 * @param [in, out] in   Pointer to the buffer pointer; advanced on success.
10166
 * @param [in]      len  Length of data in the buffer.
10167
 * @return  CRL object on success, NULL on error.
10168
 */
10169
WOLFSSL_X509_CRL* wolfSSL_d2i_X509_CRL_ex(WOLFSSL_X509_CRL** crl,
10170
        const unsigned char** in, long len)
10171
{
10172
    WOLFSSL_X509_CRL* ret;
10173
    const unsigned char* p;
10174
    long objLen = 0;
10175
    int tag = 0;
10176
    int cls = 0;
10177
10178
    WOLFSSL_ENTER("wolfSSL_d2i_X509_CRL_ex");
10179
10180
    if ((in == NULL) || (*in == NULL) || (len <= 0)) {
10181
        WOLFSSL_MSG("Bad argument value");
10182
        return NULL;
10183
    }
10184
10185
    ret = wolfSSL_d2i_X509_CRL(crl, *in, (int)len);
10186
    if (ret == NULL) {
10187
        return NULL;
10188
    }
10189
10190
    /* Advance past the object just decoded. The header parsed once already
10191
     * to get here, so a failure now leaves the caller's pointer alone
10192
     * rather than moving it somewhere unknown. */
10193
    p = *in;
10194
    if ((wolfSSL_ASN1_get_object(&p, &objLen, &tag, &cls, len) & 0x80) == 0) {
10195
        *in = p + objLen;
10196
    }
10197
10198
    return ret;
10199
}
10200
10201
WOLFSSL_X509_CRL* wolfSSL_d2i_X509_CRL(WOLFSSL_X509_CRL** crl,
10202
        const unsigned char* in, int len)
10203
{
10204
    WOLFSSL_X509_CRL *newcrl = NULL;
10205
    int ret = WOLFSSL_SUCCESS;
10206
10207
    WOLFSSL_ENTER("wolfSSL_d2i_X509_CRL");
10208
10209
    if (in == NULL) {
10210
        WOLFSSL_MSG("Bad argument value");
10211
    }
10212
    else {
10213
        newcrl =(WOLFSSL_X509_CRL*)XMALLOC(sizeof(WOLFSSL_X509_CRL), NULL,
10214
                DYNAMIC_TYPE_CRL);
10215
        if (newcrl == NULL) {
10216
            WOLFSSL_MSG("New CRL allocation failed");
10217
        }
10218
        else {
10219
            ret = InitCRL(newcrl, NULL);
10220
            if (ret < 0) {
10221
                WOLFSSL_MSG("Init tmp CRL failed");
10222
                /* A failed InitCRL() has already released whatever it took,
10223
                 * so dispose of the memory here and keep this object away
10224
                 * from the wolfSSL_X509_CRL_free() below, which would destroy
10225
                 * the lock and the condition variable a second time. */
10226
                XFREE(newcrl, NULL, DYNAMIC_TYPE_CRL);
10227
                newcrl = NULL;
10228
            }
10229
            else {
10230
                ret = BufferLoadCRL(newcrl, in, len, WOLFSSL_FILETYPE_ASN1,
10231
                    NO_VERIFY);
10232
                if (ret != WOLFSSL_SUCCESS) {
10233
                    WOLFSSL_MSG("Buffer Load CRL failed");
10234
                }
10235
                else {
10236
                    if (crl) {
10237
                        *crl = newcrl;
10238
                    }
10239
                }
10240
            }
10241
        }
10242
    }
10243
10244
    if ((ret != WOLFSSL_SUCCESS) && (newcrl != NULL)) {
10245
        wolfSSL_X509_CRL_free(newcrl);
10246
        newcrl = NULL;
10247
    }
10248
10249
    return newcrl;
10250
}
10251
10252
/* Retrieve issuer X509_NAME from CRL
10253
 * return X509_NAME*  on success
10254
 * return NULL on failure
10255
 */
10256
WOLFSSL_X509_NAME* wolfSSL_X509_CRL_get_issuer_name(const WOLFSSL_X509_CRL* crl)
10257
{
10258
    if (crl == NULL || crl->crlList == NULL)
10259
        return NULL;
10260
10261
    return crl->crlList->issuer;
10262
}
10263
10264
/* Set issuer name of CRL
10265
 * return WOLFSSL_SUCCESS on success
10266
 * return WOLFSSL_FAILURE on failure
10267
 */
10268
int wolfSSL_X509_CRL_set_issuer_name(WOLFSSL_X509_CRL* crl,
10269
                                     const WOLFSSL_X509_NAME* name)
10270
{
10271
    WOLFSSL_X509_NAME* newName;
10272
10273
    if (crl == NULL || crl->crlList == NULL || name == NULL)
10274
        return WOLFSSL_FAILURE;
10275
10276
    newName = wolfSSL_X509_NAME_dup(name);
10277
    if (newName == NULL)
10278
        return WOLFSSL_FAILURE;
10279
10280
    if (crl->crlList->issuer != NULL) {
10281
        FreeX509Name(crl->crlList->issuer);
10282
        XFREE(crl->crlList->issuer, crl->heap, DYNAMIC_TYPE_X509);
10283
    }
10284
    crl->crlList->issuer = newName;
10285
10286
    return WOLFSSL_SUCCESS;
10287
}
10288
10289
/* Retrieve version from CRL
10290
 * return version on success
10291
 * return 0 on failure
10292
 */
10293
int wolfSSL_X509_CRL_version(WOLFSSL_X509_CRL* crl)
10294
{
10295
    if (crl == NULL || crl->crlList == NULL)
10296
        return 0;
10297
10298
    return crl->crlList->version;
10299
}
10300
10301
/* Set version of CRL
10302
 * Caller passes the RFC 5280 value: 0 for v1, 1 for v2.
10303
 * Internally wolfSSL stores version + 1 (v1 = 1, v2 = 2) to match
10304
 * what ParseCRL produces, so apply the same normalization here.
10305
 * return WOLFSSL_SUCCESS on success
10306
 * return WOLFSSL_FAILURE on failure
10307
 */
10308
int wolfSSL_X509_CRL_set_version(WOLFSSL_X509_CRL* crl, long version)
10309
{
10310
    if (crl == NULL || crl->crlList == NULL)
10311
        return WOLFSSL_FAILURE;
10312
10313
    /* Only v1 (0) and v2 (1) are defined by RFC 5280. */
10314
    if (version < 0 || version > 1)
10315
        return WOLFSSL_FAILURE;
10316
10317
    /* Store as version + 1 to match internal convention. */
10318
    crl->crlList->version = (int)version + 1;
10319
    return WOLFSSL_SUCCESS;
10320
}
10321
10322
/* Retrieve sig OID from CRL
10323
 * return OID on success
10324
 * return 0 on failure
10325
 */
10326
int wolfSSL_X509_CRL_get_signature_type(WOLFSSL_X509_CRL* crl)
10327
{
10328
    if (crl == NULL || crl->crlList == NULL)
10329
        return 0;
10330
10331
    return crl->crlList->signatureOID;
10332
}
10333
10334
/* Set signature type of CRL
10335
 * return WOLFSSL_SUCCESS on success
10336
 * return WOLFSSL_FAILURE on failure
10337
 */
10338
int wolfSSL_X509_CRL_set_signature_type(WOLFSSL_X509_CRL* crl,
10339
                                        int signatureType)
10340
{
10341
    if (crl == NULL || crl->crlList == NULL)
10342
        return WOLFSSL_FAILURE;
10343
10344
    crl->crlList->signatureOID = signatureType;
10345
    return WOLFSSL_SUCCESS;
10346
}
10347
10348
/* Retrieve sig NID from CRL
10349
 * return NID on success
10350
 * return 0 on failure
10351
 */
10352
int wolfSSL_X509_CRL_get_signature_nid(const WOLFSSL_X509_CRL* crl)
10353
{
10354
    if (crl == NULL || crl->crlList == NULL)
10355
        return 0;
10356
10357
    return oid2nid(crl->crlList->signatureOID, oidSigType);
10358
}
10359
10360
/* Set signature NID of CRL
10361
 * return WOLFSSL_SUCCESS on success
10362
 * return negative value on failure
10363
 */
10364
int wolfSSL_X509_CRL_set_signature_nid(WOLFSSL_X509_CRL* crl, int nid)
10365
{
10366
    int ret = WOLFSSL_SUCCESS;
10367
    word32 oid;
10368
10369
    if (crl == NULL || crl->crlList == NULL || nid <= 0) {
10370
        ret = BAD_FUNC_ARG;
10371
    }
10372
10373
    if (ret == WOLFSSL_SUCCESS) {
10374
        oid = nid2oid(nid, oidSigType);
10375
        if (oid == (word32)-1 || oid == (word32)WOLFSSL_FATAL_ERROR) {
10376
            ret = WOLFSSL_FATAL_ERROR;
10377
        }
10378
        else {
10379
            crl->crlList->signatureOID = oid;
10380
        }
10381
    }
10382
10383
    return ret;
10384
}
10385
10386
/* Retrieve signature from CRL
10387
 * return WOLFSSL_SUCCESS on success and negative values on failure
10388
 */
10389
int wolfSSL_X509_CRL_get_signature(WOLFSSL_X509_CRL* crl,
10390
    unsigned char* buf, int* bufSz)
10391
{
10392
    WOLFSSL_ENTER("wolfSSL_X509_CRL_get_signature");
10393
10394
    if (crl == NULL || crl->crlList == NULL ||
10395
        crl->crlList->signature == NULL || bufSz == NULL)
10396
        return BAD_FUNC_ARG;
10397
10398
    if (buf != NULL) {
10399
        if (*bufSz < (int)crl->crlList->signatureSz) {
10400
            WOLFSSL_MSG("Signature buffer too small");
10401
            return BUFFER_E;
10402
        }
10403
        else {
10404
            XMEMCPY(buf, crl->crlList->signature, crl->crlList->signatureSz);
10405
        }
10406
    }
10407
    *bufSz = (int)crl->crlList->signatureSz;
10408
10409
    return WOLFSSL_SUCCESS;
10410
}
10411
10412
int wolfSSL_X509_CRL_set_signature(WOLFSSL_X509_CRL* crl,
10413
    unsigned char* buf, int bufSz)
10414
{
10415
    byte* newSig;
10416
10417
    if (crl == NULL || crl->crlList == NULL || buf == NULL || bufSz <= 0) {
10418
        return BAD_FUNC_ARG;
10419
    }
10420
10421
    /* Ensure signature buffer is allocated and large enough. */
10422
    if (crl->crlList->signature == NULL) {
10423
        crl->crlList->signature = (byte*)XMALLOC((word32)bufSz, crl->heap,
10424
                                                 DYNAMIC_TYPE_CRL_ENTRY);
10425
        if (crl->crlList->signature == NULL) {
10426
            return MEMORY_E;
10427
        }
10428
        crl->crlList->signatureSz = (word32)bufSz;
10429
    }
10430
    else if ((word32)bufSz > crl->crlList->signatureSz) {
10431
        newSig = (byte*)XMALLOC((word32)bufSz, crl->heap,
10432
                                DYNAMIC_TYPE_CRL_ENTRY);
10433
        if (newSig == NULL) {
10434
            return MEMORY_E;
10435
        }
10436
        XFREE(crl->crlList->signature, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
10437
        crl->crlList->signature = newSig;
10438
        crl->crlList->signatureSz = (word32)bufSz;
10439
    }
10440
    else {
10441
        /* Reuse existing buffer, clear contents in case new signature
10442
         * is smaller. Note that we do not shrink the buffer. */
10443
        XMEMSET(crl->crlList->signature, 0, crl->crlList->signatureSz);
10444
    }
10445
10446
    XMEMCPY(crl->crlList->signature, buf, bufSz);
10447
    crl->crlList->signatureSz = (word32)bufSz;
10448
    return WOLFSSL_SUCCESS;
10449
}
10450
10451
/* Retrieve serial number from RevokedCert
10452
 * return WOLFSSL_SUCCESS on success and negative values on failure
10453
 */
10454
int wolfSSL_X509_REVOKED_get_serial_number(RevokedCert* rev,
10455
    byte* in, int* inOutSz)
10456
{
10457
    WOLFSSL_ENTER("wolfSSL_X509_REVOKED_get_serial_number");
10458
    if (rev == NULL || inOutSz == NULL) {
10459
        return BAD_FUNC_ARG;
10460
    }
10461
10462
    if (in != NULL) {
10463
        if (*inOutSz < rev->serialSz) {
10464
            WOLFSSL_MSG("Serial buffer too small");
10465
            return BUFFER_E;
10466
        }
10467
        XMEMCPY(in, rev->serialNumber, rev->serialSz);
10468
    }
10469
    *inOutSz = rev->serialSz;
10470
10471
    return WOLFSSL_SUCCESS;
10472
}
10473
10474
const WOLFSSL_ASN1_INTEGER* wolfSSL_X509_REVOKED_get0_serial_number(const
10475
                                                      WOLFSSL_X509_REVOKED *rev)
10476
{
10477
    WOLFSSL_ENTER("wolfSSL_X509_REVOKED_get0_serial_number");
10478
10479
    if (rev != NULL) {
10480
        return rev->serialNumber;
10481
    }
10482
    else
10483
        return NULL;
10484
}
10485
10486
const WOLFSSL_ASN1_TIME* wolfSSL_X509_REVOKED_get0_revocation_date(const
10487
                                                      WOLFSSL_X509_REVOKED *rev)
10488
{
10489
    WOLFSSL_ENTER("wolfSSL_X509_REVOKED_get0_revocation_date");
10490
10491
    if (rev != NULL) {
10492
        return rev->revocationDate;
10493
    }
10494
    return NULL;
10495
}
10496
10497
10498
#ifndef NO_BIO
10499
/* print serial number out
10500
*  return WOLFSSL_SUCCESS on success
10501
*/
10502
static int X509RevokedPrintSerial(WOLFSSL_BIO* bio, RevokedCert* rev,
10503
    int indent)
10504
{
10505
    unsigned char serial[32];
10506
    int  sz = sizeof(serial);
10507
10508
    if (indent < 0) indent = 0;
10509
    if (indent > MAX_INDENT) indent = MAX_INDENT;
10510
10511
    XMEMSET(serial, 0, sz);
10512
    if (wolfSSL_X509_REVOKED_get_serial_number(rev, serial, &sz)
10513
            == WOLFSSL_SUCCESS) {
10514
        X509PrintSerial_ex(bio, serial, sz, 0, indent);
10515
    }
10516
    return WOLFSSL_SUCCESS;
10517
}
10518
10519
10520
/* print out the signature in human readable format for use with
10521
* wolfSSL_X509_CRL_print()
10522
 * return WOLFSSL_SUCCESS on success
10523
 */
10524
static int X509CRLPrintSignature(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl,
10525
        int algOnly, int indent)
10526
{
10527
    int sigSz = 0;
10528
10529
    if (wolfSSL_X509_CRL_get_signature(crl, NULL, &sigSz) <= 0) {
10530
        return WOLFSSL_FAILURE;
10531
    }
10532
10533
    if (sigSz > 0) {
10534
        unsigned char* sig;
10535
        int sigNid = wolfSSL_X509_CRL_get_signature_nid(crl);
10536
10537
        sig = (unsigned char*)XMALLOC(sigSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10538
        if (sig == NULL) {
10539
            return WOLFSSL_FAILURE;
10540
        }
10541
10542
        if (wolfSSL_X509_CRL_get_signature(crl, sig, &sigSz) <= 0) {
10543
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10544
            return WOLFSSL_FAILURE;
10545
        }
10546
10547
        if (X509PrintSignature_ex(bio, sig, sigSz, sigNid, algOnly, indent)
10548
                != WOLFSSL_SUCCESS) {
10549
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10550
            return WOLFSSL_FAILURE;
10551
        }
10552
10553
        XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10554
10555
    }
10556
10557
    return WOLFSSL_SUCCESS;
10558
}
10559
#endif /* !NO_BIO */
10560
10561
#if !defined(NO_BIO) && defined(XSNPRINTF)
10562
/* print out the extensions in human readable format for use with
10563
 * wolfSSL_X509_CRL_print()
10564
 * return WOLFSSL_SUCCESS on success
10565
 */
10566
static int X509CRLPrintExtensions(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl,
10567
        int indent)
10568
{
10569
    char tmp[MAX_WIDTH]; /* buffer for XSNPRINTF */
10570
    int  ret = 0;
10571
10572
    if (indent < 0) indent = 0;
10573
    if (indent > MAX_INDENT) indent = MAX_INDENT;
10574
10575
    if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s\n", indent, "",
10576
                "CRL extensions:") >= MAX_WIDTH) {
10577
        ret = WOLFSSL_FAILURE;
10578
    }
10579
10580
    if (ret == 0 && wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10581
        ret = WOLFSSL_FAILURE;
10582
    }
10583
10584
    if (ret == 0 && crl->crlList->crlNumberSet) {
10585
        char dec_string[49]; /* 20 octets can express numbers up to approx
10586
                                49 decimal digits */
10587
        int freeMp = 0;
10588
    #ifdef WOLFSSL_SMALL_STACK
10589
        mp_int* dec_num = (mp_int*)XMALLOC(sizeof(*dec_num), NULL,
10590
                            DYNAMIC_TYPE_BIGINT);
10591
        if (dec_num == NULL) {
10592
            ret = MEMORY_E;
10593
        }
10594
    #else
10595
        mp_int dec_num[1];
10596
    #endif
10597
10598
        if (ret == 0 && (mp_init(dec_num) != MP_OKAY)) {
10599
             ret = MP_INIT_E;
10600
        }
10601
        else if (ret == 0) {
10602
            freeMp = 1;
10603
        }
10604
10605
        if (ret == 0 && mp_read_radix(dec_num, (char *)crl->crlList->crlNumber,
10606
                    MP_RADIX_HEX) != MP_OKAY) {
10607
            ret = WOLFSSL_FAILURE;
10608
        }
10609
10610
        if (ret == 0 && mp_toradix(dec_num, dec_string, MP_RADIX_DEC)
10611
                    != MP_OKAY) {
10612
            ret = WOLFSSL_FAILURE;
10613
        }
10614
10615
        if (ret == 0 && XSNPRINTF(tmp, MAX_WIDTH, "%*s%s\n", indent + 4, "",
10616
                    "X509v3 CRL Number:") >= MAX_WIDTH) {
10617
            ret = WOLFSSL_FAILURE;
10618
        }
10619
10620
        if (ret == 0 && wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10621
            ret = WOLFSSL_FAILURE;
10622
        }
10623
10624
        if (ret == 0 && XSNPRINTF(tmp, MAX_WIDTH, "%*s%s\n", indent + 8, "",
10625
            dec_string) >= MAX_WIDTH) {
10626
            ret = WOLFSSL_FAILURE;
10627
        }
10628
10629
        if (ret == 0 && wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10630
            ret = WOLFSSL_FAILURE;
10631
        }
10632
10633
        XMEMSET(tmp, 0, sizeof(tmp));
10634
10635
        if (freeMp) {
10636
            mp_free(dec_num);
10637
        }
10638
10639
        WC_FREE_VAR_EX(dec_num, NULL, DYNAMIC_TYPE_BIGINT);
10640
    }
10641
10642
#if !defined(NO_SKID)
10643
    if (ret == 0 && crl->crlList->extAuthKeyIdSet &&
10644
            crl->crlList->extAuthKeyId[0] != 0) {
10645
        word32 i;
10646
        char val[5];
10647
        int valSz = 5;
10648
10649
        if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s", indent + 4, "",
10650
                    "X509v3 Authority Key Identifier:") >= MAX_WIDTH) {
10651
            ret = WOLFSSL_FAILURE;
10652
        }
10653
10654
        if (ret == 0) {
10655
            XSTRNCAT(tmp, "\n", MAX_WIDTH - XSTRLEN(tmp) - 1);
10656
        }
10657
10658
        if (ret == 0 && wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10659
            ret = WOLFSSL_FAILURE;
10660
        }
10661
        XMEMSET(tmp, 0, MAX_WIDTH);
10662
10663
        if (ret == 0 && XSNPRINTF(tmp, MAX_WIDTH - 1, "%*s%s",
10664
                    indent + 8, "", "keyid") >= MAX_WIDTH) {
10665
            ret = WOLFSSL_FAILURE;
10666
        }
10667
10668
10669
        for (i = 0; i < XSTRLEN((char*)crl->crlList->extAuthKeyId); i++) {
10670
            /* check if buffer is almost full */
10671
            if (ret == 0 && XSTRLEN(tmp) >= sizeof(tmp) - valSz) {
10672
                if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10673
                    ret = WOLFSSL_FAILURE;
10674
                }
10675
                tmp[0] = '\0';
10676
            }
10677
            if (ret == 0 && XSNPRINTF(val, (size_t)valSz, ":%02X",
10678
                    crl->crlList->extAuthKeyId[i]) >= valSz) {
10679
                WOLFSSL_MSG("buffer overrun");
10680
                ret = WOLFSSL_FAILURE;
10681
            }
10682
            if (ret == 0) {
10683
                XSTRNCAT(tmp, val, valSz);
10684
            }
10685
        }
10686
        if (ret == 0) {
10687
            XSTRNCAT(tmp, "\n", XSTRLEN("\n") + 1);
10688
        }
10689
        if (ret == 0 && wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10690
            ret = WOLFSSL_FAILURE;
10691
        }
10692
    }
10693
#endif
10694
10695
    if (ret == 0) {
10696
        ret = WOLFSSL_SUCCESS;
10697
    }
10698
10699
    return ret;
10700
}
10701
10702
/* iterate through a CRL's Revoked Certs and print out in human
10703
 * readable format for use with wolfSSL_X509_CRL_print()
10704
 * return WOLFSSL_SUCCESS on success
10705
 */
10706
static int X509CRLPrintRevoked(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl,
10707
        int indent)
10708
{
10709
    char tmp[MAX_WIDTH]; /* buffer for XSNPRINTF */
10710
    int i;
10711
10712
    if (crl->crlList->totalCerts > 0) {
10713
        RevokedCert* revoked = crl->crlList->certs;
10714
10715
        if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s\n", indent, "",
10716
                    "Revoked Certificates:") >= MAX_WIDTH) {
10717
            return WOLFSSL_FAILURE;
10718
        }
10719
10720
        if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10721
            return WOLFSSL_FAILURE;
10722
        }
10723
        XMEMSET(tmp, 0, MAX_WIDTH);
10724
10725
        for (i = 0; i < crl->crlList->totalCerts; i++) {
10726
            if (revoked->serialSz > 0) {
10727
                if (X509RevokedPrintSerial(bio, revoked, indent + 4)
10728
                        != WOLFSSL_SUCCESS) {
10729
                    return WOLFSSL_FAILURE;
10730
                }
10731
            }
10732
        #ifndef NO_ASN_TIME
10733
             if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s", indent + 8, "",
10734
                         "Revocation Date: ") >= MAX_WIDTH) {
10735
                return WOLFSSL_FAILURE;
10736
            }
10737
10738
            if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10739
                return WOLFSSL_FAILURE;
10740
            }
10741
10742
            if (revoked->revDate[0] != 0) {
10743
                if (GetTimeString(revoked->revDate, ASN_UTC_TIME,
10744
                    tmp, MAX_WIDTH, MAX_DATE_SIZE) != WOLFSSL_SUCCESS) {
10745
                    if (GetTimeString(revoked->revDate, ASN_GENERALIZED_TIME,
10746
                    tmp, MAX_WIDTH, MAX_DATE_SIZE) != WOLFSSL_SUCCESS) {
10747
                        WOLFSSL_MSG("Error getting revocation date");
10748
                        return WOLFSSL_FAILURE;
10749
                    }
10750
                }
10751
            }
10752
            else {
10753
                XSTRNCPY(tmp, "Not Set", MAX_WIDTH-1);
10754
            }
10755
            tmp[MAX_WIDTH - 1] = '\0'; /* make sure null terminated */
10756
            if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10757
                return WOLFSSL_FAILURE;
10758
            }
10759
10760
            if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) {
10761
                return WOLFSSL_FAILURE;
10762
            }
10763
        #endif
10764
            revoked = revoked->next;
10765
        }
10766
    }
10767
    else {
10768
        if (wolfSSL_BIO_write(bio, "No Revoked Certificates.\n",
10769
                       (int)XSTRLEN("No Revoked Certificates.\n")) <= 0) {
10770
            return WOLFSSL_FAILURE;
10771
        }
10772
    }
10773
10774
    return WOLFSSL_SUCCESS;
10775
}
10776
10777
#ifndef NO_ASN_TIME
10778
/* print out the last/next update times in human readable
10779
 * format for use with wolfSSL_X509_CRL_print()
10780
 * return WOLFSSL_SUCCESS on success
10781
 */
10782
static int X509CRLPrintDates(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl,
10783
        int indent)
10784
{
10785
    char tmp[MAX_WIDTH]; /* buffer for XSNPRINTF */
10786
10787
    if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s", indent, "",
10788
                "Last Update: ") >= MAX_WIDTH) {
10789
        return WOLFSSL_FAILURE;
10790
    }
10791
10792
    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10793
        return WOLFSSL_FAILURE;
10794
    }
10795
10796
    if (crl->crlList->lastDate[0] != 0) {
10797
        if (GetTimeString(crl->crlList->lastDate, crl->crlList->lastDateFormat,
10798
            tmp, MAX_WIDTH, MAX_DATE_SIZE) != WOLFSSL_SUCCESS) {
10799
            WOLFSSL_MSG("Error getting last update date");
10800
            return WOLFSSL_FAILURE;
10801
        }
10802
    }
10803
    else {
10804
        XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
10805
    }
10806
    tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
10807
    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10808
        return WOLFSSL_FAILURE;
10809
    }
10810
10811
    if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) {
10812
        return WOLFSSL_FAILURE;
10813
    }
10814
10815
    if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s", indent, "",
10816
                "Next Update: ") >= MAX_WIDTH) {
10817
        return WOLFSSL_FAILURE;
10818
    }
10819
10820
    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10821
        return WOLFSSL_FAILURE;
10822
    }
10823
10824
    if (crl->crlList->nextDate[0] != 0) {
10825
        if (GetTimeString(crl->crlList->nextDate, crl->crlList->nextDateFormat,
10826
            tmp, MAX_WIDTH, MAX_DATE_SIZE) != WOLFSSL_SUCCESS) {
10827
            WOLFSSL_MSG("Error getting next update date");
10828
            return WOLFSSL_FAILURE;
10829
        }
10830
    }
10831
    else {
10832
        XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
10833
    }
10834
    tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
10835
    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10836
        return WOLFSSL_FAILURE;
10837
    }
10838
10839
    if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) {
10840
        return WOLFSSL_FAILURE;
10841
    }
10842
10843
    return WOLFSSL_SUCCESS;
10844
}
10845
#endif
10846
10847
/* Writes the human readable form of x509 to bio.
10848
 *
10849
 * bio  WOLFSSL_BIO to write to.
10850
 * crl Certificate revocation list to write.
10851
 *
10852
 * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
10853
 */
10854
int wolfSSL_X509_CRL_print(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl)
10855
{
10856
    char issuType[] = "Issuer: ";
10857
10858
    if (bio == NULL || crl == NULL || crl->crlList == NULL) {
10859
        return WOLFSSL_FAILURE;
10860
    }
10861
10862
    if (wolfSSL_BIO_write(bio, "Certificate Revocation List (CRL):\n",
10863
                  (int)XSTRLEN("Certificate Revocation List (CRL):\n")) <= 0) {
10864
            return WOLFSSL_FAILURE;
10865
    }
10866
10867
    /* print version */
10868
    if (X509PrintVersion(bio, wolfSSL_X509_CRL_version(crl), 8)
10869
            != WOLFSSL_SUCCESS) {
10870
        return WOLFSSL_FAILURE;
10871
    }
10872
10873
    /* print signature algo */
10874
    if (X509CRLPrintSignature(bio, crl, 1, 8) != WOLFSSL_SUCCESS) {
10875
        return WOLFSSL_FAILURE;
10876
    }
10877
10878
    /* print issuer name */
10879
    if (X509PrintName(bio, wolfSSL_X509_CRL_get_issuer_name(crl), issuType, 8)
10880
            != WOLFSSL_SUCCESS) {
10881
        return WOLFSSL_FAILURE;
10882
    }
10883
10884
#ifndef NO_ASN_TIME
10885
    /* print last and next update times */
10886
    if (X509CRLPrintDates(bio, crl, 8) != WOLFSSL_SUCCESS) {
10887
        return WOLFSSL_FAILURE;
10888
    }
10889
#endif
10890
10891
    /* print CRL extensions */
10892
    if (X509CRLPrintExtensions(bio, crl, 8) != WOLFSSL_SUCCESS) {
10893
        return WOLFSSL_FAILURE;
10894
    }
10895
10896
    /* print CRL Revoked Certs */
10897
    if (X509CRLPrintRevoked(bio, crl, 0) != WOLFSSL_SUCCESS) {
10898
        return WOLFSSL_FAILURE;
10899
    }
10900
10901
    if (X509CRLPrintSignature(bio, crl, 0, 4) != WOLFSSL_SUCCESS) {
10902
        return WOLFSSL_FAILURE;
10903
    }
10904
10905
    if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
10906
        return WOLFSSL_FAILURE;
10907
    }
10908
10909
    return WOLFSSL_SUCCESS;
10910
}
10911
#endif /* !NO_BIO && XSNPRINTF */
10912
#endif /* HAVE_CRL */
10913
#endif /* OPENSSL_EXTRA */
10914
10915
#if defined(HAVE_CRL) && (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL))
10916
void wolfSSL_X509_CRL_free(WOLFSSL_X509_CRL *crl)
10917
{
10918
    WOLFSSL_ENTER("wolfSSL_X509_CRL_free");
10919
10920
    if (crl)
10921
        FreeCRL(crl, 1);
10922
}
10923
#endif /* HAVE_CRL && (OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL) */
10924
10925
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA)
10926
WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_lastUpdate(WOLFSSL_X509_CRL* crl)
10927
{
10928
    if ((crl != NULL) && (crl->crlList != NULL) &&
10929
        (crl->crlList->lastDateAsn1.data[0] != 0)) {
10930
        return &crl->crlList->lastDateAsn1;
10931
    }
10932
    return NULL;
10933
}
10934
10935
int wolfSSL_X509_CRL_set_lastUpdate(WOLFSSL_X509_CRL* crl,
10936
                                    const WOLFSSL_ASN1_TIME* time)
10937
{
10938
    if (crl != NULL && crl->crlList != NULL && time != NULL) {
10939
        crl->crlList->lastDateAsn1 = *time;
10940
        return WOLFSSL_SUCCESS;
10941
    }
10942
    return WOLFSSL_FAILURE;
10943
}
10944
10945
WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_nextUpdate(WOLFSSL_X509_CRL* crl)
10946
{
10947
    if ((crl != NULL) && (crl->crlList != NULL) &&
10948
        (crl->crlList->nextDateAsn1.data[0] != 0)) {
10949
        return &crl->crlList->nextDateAsn1;
10950
    }
10951
    return NULL;
10952
}
10953
10954
int wolfSSL_X509_CRL_set_nextUpdate(WOLFSSL_X509_CRL* crl,
10955
                                    const WOLFSSL_ASN1_TIME* time)
10956
{
10957
    if (crl != NULL && crl->crlList != NULL && time != NULL) {
10958
        crl->crlList->nextDateAsn1 = *time;
10959
        return WOLFSSL_SUCCESS;
10960
    }
10961
    return WOLFSSL_FAILURE;
10962
}
10963
10964
#ifndef NO_WOLFSSL_STUB
10965
int wolfSSL_X509_CRL_verify(WOLFSSL_X509_CRL* crl, WOLFSSL_EVP_PKEY* key)
10966
{
10967
    (void)crl;
10968
    (void)key;
10969
    WOLFSSL_STUB("X509_CRL_verify");
10970
    return 0;
10971
}
10972
#endif
10973
10974
/* Encode CRL to DER format in memory.
10975
 *
10976
 * If *out is NULL, allocates memory and returns it via *out.
10977
 * If *out is not NULL, writes DER data starting at *out.
10978
 *
10979
 * @param crl  CRL to encode
10980
 * @param out  Pointer to output buffer pointer
10981
 * @return     Size of DER encoding on success, WOLFSSL_FAILURE on failure
10982
 */
10983
int wolfSSL_i2d_X509_CRL(WOLFSSL_X509_CRL* crl, unsigned char** out)
10984
{
10985
    int ret;
10986
    long derSz = 0;
10987
    byte* der = NULL;
10988
    int alloced = 0;
10989
10990
    WOLFSSL_ENTER("wolfSSL_i2d_X509_CRL");
10991
10992
    if (crl == NULL) {
10993
        return BAD_FUNC_ARG;
10994
    }
10995
10996
    /* Get required size */
10997
    ret = BufferStoreCRL(crl, NULL, &derSz, WOLFSSL_FILETYPE_ASN1);
10998
    if (ret != WOLFSSL_SUCCESS || derSz <= 0) {
10999
        WOLFSSL_MSG("BufferStoreCRL failed to get size");
11000
        return WOLFSSL_FAILURE;
11001
    }
11002
11003
    if (out == NULL) {
11004
        /* Just return size */
11005
        return (int)derSz;
11006
    }
11007
11008
    if (*out == NULL) {
11009
        /* Allocate output buffer */
11010
        der = (byte*)XMALLOC((size_t)derSz, NULL, DYNAMIC_TYPE_OPENSSL);
11011
        if (der == NULL) {
11012
            WOLFSSL_MSG("Memory allocation failed");
11013
            return MEMORY_E;
11014
        }
11015
        alloced = 1;
11016
    }
11017
    else {
11018
        der = *out;
11019
    }
11020
11021
    /* Encode CRL to DER */
11022
    ret = BufferStoreCRL(crl, der, &derSz, WOLFSSL_FILETYPE_ASN1);
11023
    if (ret != WOLFSSL_SUCCESS) {
11024
        WOLFSSL_MSG("BufferStoreCRL failed to encode");
11025
        if (alloced) {
11026
            XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
11027
        }
11028
        return WOLFSSL_FAILURE;
11029
    }
11030
11031
    if (alloced) {
11032
        *out = der;
11033
    }
11034
    else {
11035
        *out += derSz;
11036
    }
11037
11038
    return (int)derSz;
11039
}
11040
11041
#ifndef NO_BIO
11042
/* Write the DER encoding of a CRL to a BIO.
11043
 *
11044
 * @param bio  BIO to write to
11045
 * @param crl  CRL to encode
11046
 * @return     WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure
11047
 */
11048
int wolfSSL_i2d_X509_CRL_bio(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl)
11049
{
11050
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
11051
    int derSz;
11052
    unsigned char* der = NULL;
11053
11054
    WOLFSSL_ENTER("wolfSSL_i2d_X509_CRL_bio");
11055
11056
    if ((bio == NULL) || (crl == NULL)) {
11057
        return WOLFSSL_FAILURE;
11058
    }
11059
11060
    derSz = wolfSSL_i2d_X509_CRL(crl, &der);
11061
    if ((derSz > 0) && (der != NULL) &&
11062
            (wolfSSL_BIO_write(bio, der, derSz) == derSz)) {
11063
        ret = WOLFSSL_SUCCESS;
11064
    }
11065
    XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
11066
11067
    return ret;
11068
}
11069
#endif /* !NO_BIO */
11070
#endif /* HAVE_CRL && OPENSSL_EXTRA */
11071
11072
#if defined(WOLFSSL_CERT_EXT) && \
11073
    (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
11074
/* Set CRL Distribution Points from pre-encoded DER.
11075
 *
11076
 * x509  - Certificate to modify
11077
 * der   - Pre-encoded CRLDistributionPoints DER
11078
 * derSz - Size of DER in bytes
11079
 *
11080
 * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
11081
 */
11082
int wolfSSL_X509_CRL_set_dist_points(WOLFSSL_X509* x509,
11083
    const unsigned char* der, int derSz)
11084
{
11085
    WOLFSSL_ENTER("wolfSSL_X509_CRL_set_dist_points");
11086
11087
    if (x509 == NULL || der == NULL || derSz <= 0) {
11088
        return WOLFSSL_FAILURE;
11089
    }
11090
11091
    if (x509->rawCRLInfo != NULL) {
11092
        XFREE(x509->rawCRLInfo, x509->heap, DYNAMIC_TYPE_X509_EXT);
11093
    }
11094
    x509->rawCRLInfo = (byte*)XMALLOC((word32)derSz, x509->heap,
11095
                                       DYNAMIC_TYPE_X509_EXT);
11096
    if (x509->rawCRLInfo == NULL) {
11097
        return WOLFSSL_FAILURE;
11098
    }
11099
11100
    XMEMCPY(x509->rawCRLInfo, der, (word32)derSz);
11101
    x509->rawCRLInfoSz = derSz;
11102
    x509->CRLdistSet = 1;
11103
11104
    return WOLFSSL_SUCCESS;
11105
}
11106
11107
/* Add CRL Distribution Point URI.
11108
 * Encodes URI into proper CRLDistributionPoints DER format.
11109
 *
11110
 * x509     - Certificate to modify
11111
 * uri      - URI string (e.g., "http://crl.example.com/ca.crl")
11112
 * critical - Whether extension is critical
11113
 *
11114
 * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
11115
 */
11116
int wolfSSL_X509_CRL_add_dist_point(WOLFSSL_X509* x509,
11117
    const char* uri, int critical)
11118
{
11119
    word32 uriLen;
11120
    byte* derBuf = NULL;
11121
    word32 derSz;
11122
    word32 idx;
11123
    word32 uriTagLen;    /* [6] tag + length + URI */
11124
    word32 genNamesLen;  /* [0] IMPLICIT GeneralNames wrapper */
11125
    word32 distPtNmLen;  /* [0] EXPLICIT distributionPoint wrapper */
11126
    word32 distPtSeqLen; /* SEQUENCE for DistributionPoint */
11127
    word32 outerSeqLen;  /* SEQUENCE for CRLDistributionPoints */
11128
    int ret = WOLFSSL_SUCCESS;
11129
11130
    WOLFSSL_ENTER("wolfSSL_X509_CRL_add_dist_point");
11131
11132
    if (x509 == NULL || uri == NULL) {
11133
        return WOLFSSL_FAILURE;
11134
    }
11135
11136
    uriLen = (word32)XSTRLEN(uri);
11137
    if (uriLen == 0) {
11138
        WOLFSSL_MSG("URI empty");
11139
        return WOLFSSL_FAILURE;
11140
    }
11141
11142
    /*
11143
     * Encode CRL Distribution Points in DER format:
11144
     * CRLDistributionPoints ::= SEQUENCE OF DistributionPoint
11145
     * DistributionPoint ::= SEQUENCE {
11146
     *     distributionPoint [0] EXPLICIT DistributionPointName OPTIONAL
11147
     * }
11148
     * DistributionPointName ::= CHOICE {
11149
     *     fullName [0] IMPLICIT GeneralNames
11150
     * }
11151
     * GeneralNames ::= SEQUENCE OF GeneralName
11152
     * GeneralName ::= [6] IMPLICIT IA5String (uniformResourceIdentifier)
11153
     */
11154
11155
    /* Calculate sizes from innermost to outermost */
11156
    /* [6] tag (1 byte) + length encoding + URI data */
11157
    uriTagLen = ASN_TAG_SZ + SetLength(uriLen, NULL) + uriLen;
11158
    /* [0] CONSTRUCTED tag (1 byte) + length encoding + uriTagLen */
11159
    genNamesLen = ASN_TAG_SZ + SetLength(uriTagLen, NULL) + uriTagLen;
11160
    /* [0] CONSTRUCTED tag (1 byte) + length encoding + genNamesLen */
11161
    distPtNmLen = ASN_TAG_SZ + SetLength(genNamesLen, NULL) + genNamesLen;
11162
    /* SEQUENCE header + distPtNmLen */
11163
    distPtSeqLen = SetSequence(distPtNmLen, NULL) + distPtNmLen;
11164
    /* Outer SEQUENCE header + distPtSeqLen */
11165
    outerSeqLen = SetSequence(distPtSeqLen, NULL) + distPtSeqLen;
11166
11167
    derSz = outerSeqLen;
11168
11169
    /* Allocate buffer for DER encoding */
11170
    derBuf = (byte*)XMALLOC(derSz, x509->heap, DYNAMIC_TYPE_X509_EXT);
11171
    if (derBuf == NULL) {
11172
        return WOLFSSL_FAILURE;
11173
    }
11174
11175
    /* Build forward using SetSequence/SetHeader/SetLength */
11176
    idx = 0;
11177
11178
    /* SEQUENCE for CRLDistributionPoints (outer) */
11179
    idx += SetSequence(distPtSeqLen, derBuf + idx);
11180
11181
    /* SEQUENCE for DistributionPoint */
11182
    idx += SetSequence(distPtNmLen, derBuf + idx);
11183
11184
    /* [0] EXPLICIT wrapper for distributionPoint */
11185
    derBuf[idx++] = (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED);
11186
    idx += SetLength(genNamesLen, derBuf + idx);
11187
11188
    /* [0] IMPLICIT wrapper for GeneralNames (constructed) */
11189
    derBuf[idx++] = (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED);
11190
    idx += SetLength(uriTagLen, derBuf + idx);
11191
11192
    /* [6] IMPLICIT IA5String tag for URI (context-specific, primitive) */
11193
    derBuf[idx++] = (ASN_CONTEXT_SPECIFIC | 6); /* [6] tag */
11194
    idx += SetLength(uriLen, derBuf + idx);
11195
11196
    /* Copy URI string */
11197
    XMEMCPY(derBuf + idx, uri, uriLen);
11198
    idx += uriLen;
11199
11200
    /* Store the encoded CRL info in x509 */
11201
    {
11202
        ret = wolfSSL_X509_CRL_set_dist_points(x509, derBuf, (int)idx);
11203
        if (ret == WOLFSSL_SUCCESS && critical) {
11204
            x509->CRLdistCrit = 1;
11205
        }
11206
    }
11207
11208
    XFREE(derBuf, x509->heap, DYNAMIC_TYPE_X509_EXT);
11209
11210
    return ret;
11211
}
11212
#endif /* WOLFSSL_CERT_EXT && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */
11213
11214
#ifdef OPENSSL_EXTRA
11215
11216
11217
WOLFSSL_X509_VERIFY_PARAM* wolfSSL_X509_VERIFY_PARAM_new(void)
11218
{
11219
    WOLFSSL_X509_VERIFY_PARAM *param = NULL;
11220
    param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC(
11221
            sizeof(WOLFSSL_X509_VERIFY_PARAM), NULL, DYNAMIC_TYPE_OPENSSL);
11222
    if (param != NULL)
11223
        XMEMSET(param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM ));
11224
11225
    return(param);
11226
}
11227
11228
11229
void wolfSSL_X509_VERIFY_PARAM_free(WOLFSSL_X509_VERIFY_PARAM *param)
11230
{
11231
    XFREE(param, NULL, DYNAMIC_TYPE_OPENSSL);
11232
}
11233
11234
11235
/* Sets flags by OR'ing with existing value. */
11236
int wolfSSL_X509_VERIFY_PARAM_set_flags(WOLFSSL_X509_VERIFY_PARAM *param,
11237
        unsigned long flags)
11238
{
11239
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
11240
11241
    if (param != NULL) {
11242
        param->flags |= flags;
11243
        ret = WOLFSSL_SUCCESS;
11244
    }
11245
11246
    return ret;
11247
}
11248
11249
11250
/* Sets the verification time and makes verification use it. */
11251
void wolfSSL_X509_VERIFY_PARAM_set_time(WOLFSSL_X509_VERIFY_PARAM *param,
11252
        time_t t)
11253
{
11254
    if (param != NULL) {
11255
        param->check_time = t;
11256
        param->flags |= WOLFSSL_USE_CHECK_TIME;
11257
    }
11258
}
11259
11260
11261
int wolfSSL_X509_VERIFY_PARAM_get_flags(WOLFSSL_X509_VERIFY_PARAM *param)
11262
{
11263
    int ret = 0;
11264
11265
    if (param != NULL) {
11266
        ret = (int)param->flags;
11267
    }
11268
11269
    return ret;
11270
}
11271
11272
11273
int wolfSSL_X509_VERIFY_PARAM_clear_flags(WOLFSSL_X509_VERIFY_PARAM *param,
11274
        unsigned long flags)
11275
{
11276
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
11277
11278
    if (param != NULL) {
11279
        param->flags &= ~flags;
11280
        ret = WOLFSSL_SUCCESS;
11281
    }
11282
11283
    return ret;
11284
}
11285
11286
/* note WOLFSSL_X509_VERIFY_PARAM does not record purpose, trust, depth, or
11287
 * auth_level.
11288
 */
11289
static const WOLFSSL_X509_VERIFY_PARAM x509_verify_param_builtins[] = {
11290
    {
11291
     "ssl_client",              /* name */
11292
     0,                         /* check_time */
11293
     0,                         /* inherit_flags */
11294
     0,                         /* flags */
11295
     "",                        /* hostname */
11296
     0,                         /* hostFlags */
11297
     ""                         /* ipasc */
11298
    },
11299
    {
11300
     "ssl_server",              /* name */
11301
     0,                         /* check_time */
11302
     0,                         /* inherit_flags */
11303
     0,                         /* flags */
11304
     "",                        /* hostname */
11305
     0,                         /* hostFlags */
11306
     ""                         /* ipasc */
11307
    }
11308
};
11309
11310
const WOLFSSL_X509_VERIFY_PARAM *wolfSSL_X509_VERIFY_PARAM_lookup(
11311
    const char *name)
11312
{
11313
    const WOLFSSL_X509_VERIFY_PARAM *param = &x509_verify_param_builtins[0],
11314
        *param_end = &x509_verify_param_builtins[
11315
                                         XELEM_CNT(x509_verify_param_builtins)];
11316
11317
    if (name == NULL) {
11318
        return NULL;
11319
    }
11320
    while (param < param_end) {
11321
        if (XSTRCMP(name, param->name) == 0)
11322
            return param;
11323
        ++param;
11324
    }
11325
    return NULL;
11326
}
11327
11328
/* inherits properties of param "to" to param "from"
11329
*
11330
* WOLFSSL_VPARAM_DEFAULT          any values in "src" is copied
11331
*                                 if "src" value is new for "to".
11332
* WOLFSSL_VPARAM_OVERWRITE        all values of "form" are copied to "to"
11333
* WOLFSSL_VPARAM_RESET_FLAGS      the flag values are copied, not Ored
11334
* WOLFSSL_VPARAM_LOCKED           don't copy any values
11335
* WOLFSSL_VPARAM_ONCE             the current inherit_flags is zerroed
11336
*/
11337
int wolfSSL_X509_VERIFY_PARAM_inherit(WOLFSSL_X509_VERIFY_PARAM *to,
11338
                                         const WOLFSSL_X509_VERIFY_PARAM *from)
11339
{
11340
    int ret = WOLFSSL_SUCCESS;
11341
    int isOverWrite = 0;
11342
    int isDefault = 0;
11343
    unsigned int flags;
11344
11345
    /* sanity check */
11346
    if (!to || !from) {
11347
        /* be compatible to openssl return value */
11348
        return WOLFSSL_SUCCESS;
11349
    }
11350
    flags = to->inherit_flags | from->inherit_flags;
11351
11352
    if (flags & WOLFSSL_VPARAM_LOCKED) {
11353
        return WOLFSSL_SUCCESS;
11354
    }
11355
11356
    if (flags & WOLFSSL_VPARAM_ONCE) {
11357
        to->inherit_flags = 0;
11358
    }
11359
11360
    isOverWrite = (flags & WOLFSSL_VPARAM_OVERWRITE);
11361
    isDefault = (flags & WOLFSSL_VPARAM_DEFAULT);
11362
11363
    /* copy check_time if check time is not set */
11364
    if ((to->flags & WOLFSSL_USE_CHECK_TIME) == 0 || isOverWrite) {
11365
           to->check_time = from->check_time;
11366
           to->flags &= ~WOLFSSL_USE_CHECK_TIME;
11367
    }
11368
    /* host name */
11369
    if (isOverWrite ||
11370
        (from->hostName[0] != 0 && (to->hostName[0] == 0 || isDefault))) {
11371
            if (!(ret = wolfSSL_X509_VERIFY_PARAM_set1_host(to, from->hostName,
11372
                (unsigned int)XSTRLEN(from->hostName))))
11373
                return ret;
11374
    }
11375
    /* host flags */
11376
    if (isOverWrite ||
11377
        (from->hostFlags != 0 && (to->hostFlags == 0 || isDefault))) {
11378
        to->hostFlags = from->hostFlags;
11379
    }
11380
    /* ip ascii */
11381
    if (isOverWrite ||
11382
        (from->ipasc[0] != 0 && (to->ipasc[0] == 0 || isDefault))) {
11383
11384
            if (!(ret = wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(to, from->ipasc)))
11385
                return ret;
11386
    }
11387
11388
    if (flags & WOLFSSL_VPARAM_RESET_FLAGS)
11389
        to->flags = 0;
11390
11391
    to->flags |= from->flags;
11392
11393
    return ret;
11394
}
11395
11396
/******************************************************************************
11397
* wolfSSL_X509_VERIFY_PARAM_set1_host - sets the DNS hostname to name
11398
* Hostname is cleared if name is NULL or empty.
11399
*
11400
* If nameSz is zero, name must be NUL-terminated.
11401
* Otherwise, nameSz specifies the input length and may include one
11402
* trailing NUL. Embedded NULs are rejected without changing the
11403
* previously configured hostname.
11404
*
11405
* RETURNS:
11406
* WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on invalid input.
11407
*
11408
*/
11409
int wolfSSL_X509_VERIFY_PARAM_set1_host(WOLFSSL_X509_VERIFY_PARAM* pParam,
11410
                                         const char* name,
11411
                                         unsigned int nameSz)
11412
{
11413
    unsigned int i;
11414
11415
    WOLFSSL_ENTER("wolfSSL_X509_VERIFY_PARAM_set1_host");
11416
11417
    if (pParam == NULL)
11418
        return WOLFSSL_FAILURE;
11419
11420
    /* If name is NULL, clear hostname. */
11421
    if (name == NULL) {
11422
        XMEMSET(pParam->hostName, 0, WOLFSSL_HOST_NAME_MAX);
11423
        return WOLFSSL_SUCCESS;
11424
    }
11425
11426
    /* If name is NULL-terminated, namelen can be set to zero. */
11427
    if (nameSz == 0) {
11428
        nameSz = (unsigned int)XSTRLEN(name);
11429
    }
11430
11431
    if (nameSz > 0 && name[nameSz - 1] == '\0')
11432
        nameSz--;
11433
11434
    /* Reject embedded NULs before changing the hostname policy. */
11435
    for (i = 0; i < nameSz; i++) {
11436
        if (name[i] == '\0') {
11437
            return WOLFSSL_FAILURE;
11438
        }
11439
    }
11440
11441
    if (nameSz > WOLFSSL_HOST_NAME_MAX-1) {
11442
        WOLFSSL_MSG("Truncating name");
11443
        nameSz = WOLFSSL_HOST_NAME_MAX-1;
11444
    }
11445
11446
    if (nameSz > 0) {
11447
        XMEMCPY(pParam->hostName, name, nameSz);
11448
        XMEMSET(pParam->hostName + nameSz, 0,
11449
                WOLFSSL_HOST_NAME_MAX - nameSz);
11450
    }
11451
11452
    pParam->hostName[nameSz] = '\0';
11453
11454
    return WOLFSSL_SUCCESS;
11455
}
11456
11457
/* Set VERIFY PARAM from "from" pointer to "to" pointer */
11458
int wolfSSL_X509_VERIFY_PARAM_set1(WOLFSSL_X509_VERIFY_PARAM *to,
11459
                                   const WOLFSSL_X509_VERIFY_PARAM *from)
11460
{
11461
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
11462
    unsigned int _inherit_flags;
11463
11464
    if (!to) {
11465
        return ret;
11466
    }
11467
    /* keeps the inherit flags for save */
11468
    _inherit_flags = to->inherit_flags;
11469
11470
    /* Ored DEFAULT inherit flag property to copy "from" contents to "to"
11471
    *  contents
11472
    */
11473
    to->inherit_flags |= WOLFSSL_VPARAM_DEFAULT;
11474
11475
    ret = wolfSSL_X509_VERIFY_PARAM_inherit(to, from);
11476
11477
    /* restore inherit flag */
11478
    to->inherit_flags = _inherit_flags;
11479
11480
    return ret;
11481
}
11482
11483
/* Set the host flag in the X509_VERIFY_PARAM structure */
11484
void wolfSSL_X509_VERIFY_PARAM_set_hostflags(WOLFSSL_X509_VERIFY_PARAM* param,
11485
                                             unsigned int flags)
11486
{
11487
    if (param != NULL) {
11488
        param->hostFlags = flags;
11489
    }
11490
}
11491
11492
/* Sets the expected IP address to ipasc.
11493
 *
11494
 * param is a pointer to the X509_VERIFY_PARAM structure
11495
 * ipasc is a NULL-terminated string with N.N.N.N for IPv4 and
11496
 *       HH:HH ... HH:HH for IPv6. There is no validation performed on the
11497
 *       parameter, and it must be an exact match with the IP in the cert.
11498
 *
11499
 * return 1 for success and 0 for failure*/
11500
int wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(WOLFSSL_X509_VERIFY_PARAM *param,
11501
        const char *ipasc)
11502
{
11503
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
11504
11505
    if (param != NULL) {
11506
        if (ipasc == NULL) {
11507
            param->ipasc[0] = '\0';
11508
        }
11509
        else {
11510
            XSTRLCPY(param->ipasc, ipasc, WOLFSSL_MAX_IPSTR);
11511
            param->ipasc[WOLFSSL_MAX_IPSTR-1] = '\0';
11512
        }
11513
        ret = WOLFSSL_SUCCESS;
11514
    }
11515
11516
    return ret;
11517
}
11518
/* Sets the expected IP address to ip(asc)
11519
 *          by re-constructing IP address in ascii
11520
 * @param  param is a pointer to the X509_VERIFY_PARAM structure
11521
 * @param  ip    in binary format of ip address
11522
 * @param  iplen size of ip, 4 for ipv4, 16 for ipv6
11523
 * @return 1 for success and 0 for failure
11524
 */
11525
int wolfSSL_X509_VERIFY_PARAM_set1_ip(WOLFSSL_X509_VERIFY_PARAM* param,
11526
    const unsigned char* ip, size_t iplen)
11527
{
11528
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
11529
#ifndef NO_FILESYSTEM
11530
    char* buf = NULL;
11531
    char* p = NULL;
11532
    word32 val = 0;
11533
    int i;
11534
    const size_t max_ipv6_len = 40;
11535
    byte write_zero = 0;
11536
#endif
11537
11538
    /* sanity check */
11539
    if (param == NULL || (iplen != 0 && iplen != 4 && iplen != 16)) {
11540
        WOLFSSL_MSG("bad function arg");
11541
        return ret;
11542
    }
11543
    if (ip == NULL && iplen != 0) {
11544
        WOLFSSL_MSG("bad function arg");
11545
        return ret;
11546
    }
11547
#ifndef NO_FILESYSTEM
11548
    if (iplen == 4) {
11549
        /* ipv4 www.xxx.yyy.zzz max 15 length + Null termination */
11550
        buf = (char*)XMALLOC(16, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11551
        if (!buf) {
11552
            WOLFSSL_MSG("failed malloc");
11553
            return ret;
11554
        }
11555
11556
        (void)XSNPRINTF(buf, 16, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
11557
        buf[15] = '\0'; /* null terminate */
11558
    }
11559
    else if (iplen == 16) {
11560
        /* ipv6 normal address scheme
11561
        *   y1:y2:y3:y4:y5:y6:y7:y8, len(yx):4, len(y1-y8):32. len(":"):7
11562
        *   Max len is 32 + 7 + 1(Termination) = 40 bytes
11563
        *
11564
        *   ipv6 dual address
11565
        *   Or y1:y2:y3:y4:y:y6:x.x.x.x yx is 4, y1-y6 is 24, ":" is 6
11566
        *   x.x.x.x is 15.
11567
        *   Max len is 24 + 6 + 15 + 1(Termination) = 46 bytes
11568
        *
11569
        *   Expect data in ip[16]
11570
        *   e.g (aaaa):(bbbb):(cccc):....(hhhh)
11571
        *   (aaaa) = (ip[0<<8)|ip[1]
11572
        *   ......
11573
        *   (hhhh) = (ip[14]<<8)|(ip[15])
11574
        *
11575
        *   e.g ::(gggg):(hhhh)
11576
        *   ip[0]-[11] = 0
11577
        *   (gggg) = (ip[12]<<8) |(ip[13])
11578
        *   (hhhh) = (ip[14]<<8) |(ip[15])
11579
        *
11580
        *   Because it is not able to know which ivp6 scheme uses from data to
11581
        *   reconstruct IP address, this function assumes
11582
        *   ivp6 normal address scheme, not dual address scheme,
11583
        *   to re-construct IP address in ascii.
11584
        */
11585
        buf = (char*)XMALLOC(max_ipv6_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11586
        if (!buf) {
11587
            WOLFSSL_MSG("failed malloc");
11588
            return ret;
11589
        }
11590
        p = buf;
11591
        for (i = 0; i < 16; i += 2) {
11592
            val = (((word32)(ip[i]<<8)) | (ip[i+1])) & 0xFFFF;
11593
            if (val == 0) {
11594
                if (!write_zero) {
11595
                    *p = ':';
11596
                }
11597
                p++;
11598
                *p = '\0';
11599
                write_zero = 1;
11600
            }
11601
            else {
11602
                if (i != 0) {
11603
                    *p++ = ':';
11604
                }
11605
                (void)XSNPRINTF(p, max_ipv6_len - (size_t)(p - buf), "%x", val);
11606
            }
11607
            /* sanity check */
11608
            if (XSTRLEN(buf) > max_ipv6_len) {
11609
                WOLFSSL_MSG("The target ip address exceeds buffer length(40)");
11610
                XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11611
                buf = NULL;
11612
                break;
11613
            }
11614
            /* move the pointer to the last */
11615
            /* XSTRLEN includes NULL because of XSPRINTF use */
11616
            p = buf + (XSTRLEN(buf));
11617
        }
11618
        /* termination */
11619
        if (i == 16 && buf) {
11620
            p--;
11621
            if ((*p) == ':') {
11622
                /* when the last character is :, the following segments are zero
11623
                 * Therefore, adding : and null termination */
11624
                p++;
11625
                *p++ = ':';
11626
                *p = '\0';
11627
            }
11628
        }
11629
    }
11630
    else {
11631
        WOLFSSL_MSG("iplen is zero, do nothing");
11632
        return WOLFSSL_SUCCESS;
11633
    }
11634
11635
    if (buf) {
11636
        /* set address to ip asc */
11637
        ret = wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(param, buf);
11638
        XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11639
    }
11640
#else
11641
    (void)param;
11642
    (void)ip;
11643
    (void)iplen;
11644
#endif
11645
11646
    return ret;
11647
}
11648
11649
#ifndef NO_WOLFSSL_STUB
11650
void wolfSSL_X509_OBJECT_free_contents(WOLFSSL_X509_OBJECT* obj)
11651
{
11652
    (void)obj;
11653
    WOLFSSL_STUB("X509_OBJECT_free_contents");
11654
}
11655
#endif
11656
11657
#ifndef NO_ASN_TIME
11658
int wolfSSL_X509_cmp_current_time(const WOLFSSL_ASN1_TIME* asnTime)
11659
{
11660
    return wolfSSL_X509_cmp_time(asnTime, NULL);
11661
}
11662
11663
/* return WOLFSSL_FATAL_ERROR if asnTime is earlier than or equal to cmpTime,
11664
 * and 1 otherwise
11665
 * return 0 on error
11666
 */
11667
int wolfSSL_X509_cmp_time(const WOLFSSL_ASN1_TIME* asnTime, time_t* cmpTime)
11668
{
11669
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
11670
    time_t tmpTime, *pTime = &tmpTime;
11671
    struct tm ts, *tmpTs, *ct;
11672
#if defined(NEED_TMP_TIME)
11673
    /* for use with gmtime_r */
11674
    struct tm tmpTimeStorage;
11675
11676
    tmpTs = &tmpTimeStorage;
11677
#else
11678
    tmpTs = NULL;
11679
#endif
11680
    (void)tmpTs;
11681
11682
    if (asnTime == NULL) {
11683
        return WOLFSSL_FAILURE;
11684
    }
11685
11686
    if (cmpTime == NULL) {
11687
        /* Use current time */
11688
        *pTime = wc_Time(0);
11689
    }
11690
    else {
11691
        pTime = cmpTime;
11692
    }
11693
11694
    if (wolfSSL_ASN1_TIME_to_tm((WOLFSSL_ASN1_TIME*)asnTime, &ts) !=
11695
                                                              WOLFSSL_SUCCESS) {
11696
        WOLFSSL_MSG("Failed to convert WOLFSSL_ASN1_TIME to struct tm.");
11697
        return WOLFSSL_FAILURE;
11698
    }
11699
11700
    /* Convert to time struct*/
11701
    ct = XGMTIME(pTime, tmpTs);
11702
11703
    if (ct == NULL)
11704
        return GETTIME_ERROR;
11705
11706
    /* DateGreaterThan returns 1 for >; 0 for <= */
11707
    ret = DateGreaterThan(&ts, ct) ? 1 : -1;
11708
11709
    return ret;
11710
}
11711
#endif /* !NO_ASN_TIME */
11712
11713
#if (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)) && \
11714
    !defined(NO_ASN_TIME) && !defined(USER_TIME) && !defined(TIME_OVERRIDES)
11715
WOLFSSL_ASN1_TIME *wolfSSL_X509_time_adj_ex(WOLFSSL_ASN1_TIME *asnTime,
11716
    int offset_day, long offset_sec, time_t *in_tm)
11717
{
11718
    /* get current time if in_tm is null */
11719
    time_t t = in_tm ? *in_tm : wc_Time(0);
11720
    return wolfSSL_ASN1_TIME_adj(asnTime, t, offset_day, offset_sec);
11721
}
11722
11723
WOLFSSL_ASN1_TIME *wolfSSL_X509_time_adj(WOLFSSL_ASN1_TIME *asnTime,
11724
    long offset_sec, time_t *in_tm)
11725
{
11726
    return wolfSSL_X509_time_adj_ex(asnTime, 0, offset_sec, in_tm);
11727
}
11728
11729
WOLFSSL_ASN1_TIME* wolfSSL_X509_gmtime_adj(WOLFSSL_ASN1_TIME *s, long adj)
11730
{
11731
    return wolfSSL_X509_time_adj(s, adj, NULL);
11732
}
11733
#endif
11734
11735
int wolfSSL_sk_X509_REVOKED_num(WOLFSSL_STACK* sk)
11736
{
11737
    WOLFSSL_ENTER("wolfSSL_sk_X509_REVOKED_num");
11738
    if (sk != NULL) {
11739
        return (int)sk->num;
11740
    }
11741
    return 0;
11742
}
11743
11744
/* Free a WOLFSSL_X509_REVOKED and all its owned memory. */
11745
void wolfSSL_X509_REVOKED_free(WOLFSSL_X509_REVOKED* rev)
11746
{
11747
    if (rev == NULL) {
11748
        return;
11749
    }
11750
11751
    wolfSSL_ASN1_INTEGER_free(rev->serialNumber);
11752
    wolfSSL_ASN1_TIME_free(rev->revocationDate);
11753
11754
    if (rev->extensions != NULL) {
11755
        wolfSSL_sk_pop_free(rev->extensions, NULL);
11756
    }
11757
    if (rev->issuer != NULL) {
11758
        wolfSSL_sk_pop_free(rev->issuer, NULL);
11759
    }
11760
11761
    XFREE(rev, NULL, DYNAMIC_TYPE_OPENSSL);
11762
}
11763
11764
#ifdef HAVE_CRL
11765
/* Build a WOLFSSL_X509_REVOKED from an internal RevokedCert.
11766
 * Caller takes ownership of the returned object. */
11767
static WOLFSSL_X509_REVOKED* RevokedCertToRevoked(RevokedCert* rc, int seq)
11768
{
11769
    WOLFSSL_X509_REVOKED* rev;
11770
    WOLFSSL_ASN1_INTEGER* serial;
11771
11772
    if (rc == NULL) {
11773
        return NULL;
11774
    }
11775
11776
    rev = (WOLFSSL_X509_REVOKED*)XMALLOC(sizeof(WOLFSSL_X509_REVOKED), NULL,
11777
                                          DYNAMIC_TYPE_OPENSSL);
11778
    if (rev == NULL) {
11779
        return NULL;
11780
    }
11781
    XMEMSET(rev, 0, sizeof(WOLFSSL_X509_REVOKED));
11782
11783
    /* Serial number */
11784
    serial = wolfSSL_ASN1_INTEGER_new();
11785
    if (serial == NULL) {
11786
        XFREE(rev, NULL, DYNAMIC_TYPE_OPENSSL);
11787
        return NULL;
11788
    }
11789
    if (rc->serialSz > 0 && rc->serialSz <= EXTERNAL_SERIAL_SIZE) {
11790
        serial->data = (unsigned char*)XMALLOC((size_t)rc->serialSz, NULL,
11791
                                               DYNAMIC_TYPE_OPENSSL);
11792
        if (serial->data == NULL) {
11793
            wolfSSL_ASN1_INTEGER_free(serial);
11794
            XFREE(rev, NULL, DYNAMIC_TYPE_OPENSSL);
11795
            return NULL;
11796
        }
11797
        XMEMCPY(serial->data, rc->serialNumber, (size_t)rc->serialSz);
11798
        serial->length = rc->serialSz;
11799
        serial->dataMax = rc->serialSz;
11800
        serial->isDynamic = 1;
11801
    }
11802
    rev->serialNumber = serial;
11803
11804
    /* Revocation date */
11805
    {
11806
        WOLFSSL_ASN1_TIME* revDate = wolfSSL_ASN1_TIME_new();
11807
        if (revDate != NULL) {
11808
            int dateLen = 0;
11809
            /* Determine date length from the format byte */
11810
            if (rc->revDateFormat == ASN_UTC_TIME ||
11811
                    rc->revDateFormat == ASN_GENERALIZED_TIME) {
11812
                /* Find actual length: dates are null-terminated strings in
11813
                 * revDate buffer up to MAX_DATE_SIZE */
11814
                while (dateLen < MAX_DATE_SIZE && rc->revDate[dateLen] != 0)
11815
                    dateLen++;
11816
            }
11817
            if (dateLen > 0 && dateLen < MAX_DATE_SIZE) {
11818
                XMEMCPY(revDate->data, rc->revDate, (size_t)dateLen);
11819
                revDate->length = dateLen;
11820
                revDate->type = rc->revDateFormat;
11821
            }
11822
        }
11823
        rev->revocationDate = revDate;
11824
    }
11825
11826
    /* Reason code */
11827
    rev->reason = rc->reasonCode;
11828
11829
    /* Sequence (load order) */
11830
    rev->sequence = seq;
11831
11832
    /* issuer: left as NULL (indirect CRL not yet supported) */
11833
    /* extensions: left as NULL for now (raw DER available in RevokedCert
11834
     * but decoded STACK_OF(X509_EXTENSION) build not yet implemented) */
11835
11836
    return rev;
11837
}
11838
#endif /* HAVE_CRL */
11839
11840
WOLFSSL_STACK* wolfSSL_X509_CRL_get_REVOKED(WOLFSSL_X509_CRL* crl)
11841
{
11842
    WOLFSSL_ENTER("wolfSSL_X509_CRL_get_REVOKED");
11843
11844
    if (crl == NULL) {
11845
        return NULL;
11846
    }
11847
11848
#if defined(OPENSSL_EXTRA) && defined(HAVE_CRL)
11849
    /* Return cached stack if already built */
11850
    if (crl->revokedStack != NULL) {
11851
        return crl->revokedStack;
11852
    }
11853
11854
    /* Build the stack from the internal RevokedCert linked list */
11855
    if (crl->crlList != NULL) {
11856
        WOLFSSL_STACK* sk;
11857
        RevokedCert* rc;
11858
        int seq = 0;
11859
11860
        sk = wolfSSL_sk_new_null();
11861
        if (sk == NULL) {
11862
            return NULL;
11863
        }
11864
        sk->type = STACK_TYPE_X509_REVOKED;
11865
11866
        for (rc = crl->crlList->certs; rc != NULL; rc = rc->next) {
11867
            WOLFSSL_X509_REVOKED* rev = RevokedCertToRevoked(rc, seq);
11868
            if (rev == NULL) {
11869
                /* Clean up on failure */
11870
                wolfSSL_sk_pop_free(sk, NULL);
11871
                return NULL;
11872
            }
11873
            /* Push to stack. wolfSSL_sk_push returns total count on success. */
11874
            if (wolfSSL_sk_push(sk, rev) <= 0) {
11875
                wolfSSL_X509_REVOKED_free(rev);
11876
                wolfSSL_sk_pop_free(sk, NULL);
11877
                return NULL;
11878
            }
11879
            seq++;
11880
        }
11881
11882
        crl->revokedStack = sk;
11883
        return sk;
11884
    }
11885
#endif /* OPENSSL_EXTRA && HAVE_CRL */
11886
11887
    return NULL;
11888
}
11889
11890
WOLFSSL_X509_REVOKED* wolfSSL_sk_X509_REVOKED_value(
11891
                                    WOLFSSL_STACK* sk, int idx)
11892
{
11893
    WOLFSSL_ENTER("wolfSSL_sk_X509_REVOKED_value");
11894
11895
    if (sk == NULL) {
11896
        return NULL;
11897
    }
11898
11899
    return (WOLFSSL_X509_REVOKED*)wolfSSL_sk_value(sk, idx);
11900
}
11901
11902
/* Extension accessors for WOLFSSL_X509_REVOKED */
11903
int wolfSSL_X509_REVOKED_get_ext_count(const WOLFSSL_X509_REVOKED* rev)
11904
{
11905
    WOLFSSL_ENTER("wolfSSL_X509_REVOKED_get_ext_count");
11906
    if (rev != NULL && rev->extensions != NULL) {
11907
        return (int)rev->extensions->num;
11908
    }
11909
    return 0;
11910
}
11911
11912
WOLFSSL_X509_EXTENSION* wolfSSL_X509_REVOKED_get_ext(
11913
                                     const WOLFSSL_X509_REVOKED* rev, int loc)
11914
{
11915
    WOLFSSL_ENTER("wolfSSL_X509_REVOKED_get_ext");
11916
    if (rev != NULL && rev->extensions != NULL) {
11917
        return (WOLFSSL_X509_EXTENSION*)wolfSSL_sk_value(rev->extensions, loc);
11918
    }
11919
    return NULL;
11920
}
11921
11922
#endif /* OPENSSL_EXTRA */
11923
11924
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
11925
11926
WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509* x509)
11927
{
11928
    WOLFSSL_ASN1_INTEGER* a;
11929
    int i = 0;
11930
11931
    WOLFSSL_ENTER("wolfSSL_X509_get_serialNumber");
11932
11933
    if (x509 == NULL) {
11934
        WOLFSSL_MSG("NULL function argument");
11935
        return NULL;
11936
    }
11937
11938
    if (x509->serialNumber != NULL)
11939
       return x509->serialNumber;
11940
11941
    if (x509->serialSz < 0) {
11942
        WOLFSSL_MSG("Invalid serial number size");
11943
        return NULL;
11944
    }
11945
11946
    a = wolfSSL_ASN1_INTEGER_new();
11947
    if (a == NULL)
11948
        return NULL;
11949
11950
    /* Make sure there is space for the data, ASN.1 type and length. */
11951
    if (x509->serialSz > (WOLFSSL_ASN1_INTEGER_MAX - 2)) {
11952
        /* dynamically create data buffer, +2 for type and length */
11953
        a->data = (unsigned char*)XMALLOC(x509->serialSz + 2, NULL,
11954
                DYNAMIC_TYPE_OPENSSL);
11955
        if (a->data == NULL) {
11956
            wolfSSL_ASN1_INTEGER_free(a);
11957
            return NULL;
11958
        }
11959
        a->dataMax   = (unsigned int)x509->serialSz + 2;
11960
        a->isDynamic = 1;
11961
    }
11962
    else {
11963
        /* Use array instead of dynamic memory */
11964
        a->data    = a->intData;
11965
        a->dataMax = WOLFSSL_ASN1_INTEGER_MAX;
11966
    }
11967
11968
    #if defined(WOLFSSL_QT) || defined(WOLFSSL_HAPROXY)
11969
        XMEMCPY(&a->data[i], x509->serial, x509->serialSz);
11970
        a->length = x509->serialSz;
11971
    #else
11972
        a->data[i++] = ASN_INTEGER;
11973
        i += SetLength(x509->serialSz, a->data + i);
11974
        XMEMCPY(&a->data[i], x509->serial, x509->serialSz);
11975
        a->length = x509->serialSz + 2;
11976
    #endif
11977
11978
    x509->serialNumber = a;
11979
11980
    return a;
11981
}
11982
11983
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
11984
11985
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
11986
11987
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
11988
    defined(WOLFSSL_APACHE_HTTPD) || defined(WOLFSSL_HAPROXY) || \
11989
    defined(WOLFSSL_WPAS)
11990
WOLFSSL_X509_ALGOR* wolfSSL_X509_ALGOR_new(void)
11991
{
11992
    WOLFSSL_X509_ALGOR* ret;
11993
    ret = (WOLFSSL_X509_ALGOR*)XMALLOC(sizeof(WOLFSSL_X509_ALGOR), NULL,
11994
                                       DYNAMIC_TYPE_OPENSSL);
11995
    if (ret) {
11996
        XMEMSET(ret, 0, sizeof(WOLFSSL_X509_ALGOR));
11997
    }
11998
    return ret;
11999
}
12000
12001
void wolfSSL_X509_ALGOR_free(WOLFSSL_X509_ALGOR *alg)
12002
{
12003
    if (alg) {
12004
        wolfSSL_ASN1_OBJECT_free(alg->algorithm);
12005
        wolfSSL_ASN1_TYPE_free(alg->parameter);
12006
        XFREE(alg, NULL, DYNAMIC_TYPE_OPENSSL);
12007
    }
12008
}
12009
12010
/* Returns X509_ALGOR struct with signature algorithm */
12011
const WOLFSSL_X509_ALGOR* wolfSSL_X509_get0_tbs_sigalg(const WOLFSSL_X509 *x509)
12012
{
12013
    WOLFSSL_ENTER("wolfSSL_X509_get0_tbs_sigalg");
12014
12015
    if (x509 == NULL) {
12016
        WOLFSSL_MSG("x509 struct NULL error");
12017
        return NULL;
12018
    }
12019
12020
    return &x509->algor;
12021
}
12022
12023
/* Sets paobj pointer to X509_ALGOR signature algorithm */
12024
void wolfSSL_X509_ALGOR_get0(const WOLFSSL_ASN1_OBJECT **paobj, int *pptype,
12025
                            const void **ppval, const WOLFSSL_X509_ALGOR *algor)
12026
{
12027
    WOLFSSL_ENTER("wolfSSL_X509_ALGOR_get0");
12028
12029
    if (!algor) {
12030
        WOLFSSL_MSG("algor object is NULL");
12031
        return;
12032
    }
12033
12034
    if (paobj)
12035
        *paobj = algor->algorithm;
12036
    if (ppval && algor->parameter)
12037
        *ppval = algor->parameter->value.ptr;
12038
    if (pptype) {
12039
        if (algor->parameter) {
12040
            *pptype = algor->parameter->type;
12041
        }
12042
        else {
12043
            /* Default to WOLFSSL_V_ASN1_OBJECT */
12044
            *pptype = WOLFSSL_V_ASN1_OBJECT;
12045
        }
12046
    }
12047
}
12048
12049
/**
12050
 * Populate algor members.
12051
 *
12052
 * @param algor The object to be set
12053
 * @param aobj The value to be set in algor->algorithm
12054
 * @param ptype The type of algor->parameter
12055
 * @param pval The value of algor->parameter
12056
 * @return WOLFSSL_SUCCESS on success
12057
 *         WOLFSSL_FAILURE on missing parameters or bad malloc
12058
 */
12059
int wolfSSL_X509_ALGOR_set0(WOLFSSL_X509_ALGOR *algor,
12060
                            WOLFSSL_ASN1_OBJECT *aobj, int ptype, void *pval)
12061
{
12062
    if (!algor) {
12063
        return WOLFSSL_FAILURE;
12064
    }
12065
12066
    if (!algor->parameter) {
12067
        algor->parameter = wolfSSL_ASN1_TYPE_new();
12068
        if (!algor->parameter) {
12069
            return WOLFSSL_FAILURE;
12070
        }
12071
    }
12072
12073
    if (aobj) {
12074
        algor->algorithm = aobj;
12075
    }
12076
    wolfSSL_ASN1_TYPE_set(algor->parameter, ptype, pval);
12077
12078
    return WOLFSSL_SUCCESS;
12079
}
12080
12081
/**
12082
 * Serialize object to DER encoding
12083
 *
12084
 * @param alg Object to serialize
12085
 * @param pp  Output
12086
 * @return Length on success
12087
 *         Negative number on failure
12088
 */
12089
int wolfSSL_i2d_X509_ALGOR(const WOLFSSL_X509_ALGOR* alg,
12090
        unsigned char** pp)
12091
{
12092
    int len;
12093
    word32 oid = 0;
12094
    word32 idx = 0;
12095
    unsigned char* buf = NULL;
12096
12097
    if (alg == NULL || alg->algorithm == 0) {
12098
        WOLFSSL_MSG("alg is NULL or algorithm not set");
12099
        return WOLFSSL_FATAL_ERROR;
12100
    }
12101
12102
    if (GetObjectId(alg->algorithm->obj, &idx, &oid,
12103
            (word32)alg->algorithm->grp, alg->algorithm->objSz) < 0) {
12104
        WOLFSSL_MSG("Issue getting OID of object");
12105
        return WOLFSSL_FATAL_ERROR;
12106
    }
12107
12108
    len = (int)SetAlgoID((int)oid, NULL, alg->algorithm->grp, 0);
12109
    if (len == 0) {
12110
        WOLFSSL_MSG("SetAlgoID error");
12111
        return WOLFSSL_FATAL_ERROR;
12112
    }
12113
12114
    if (pp != NULL) {
12115
        if (*pp != NULL)
12116
            buf = *pp;
12117
        else {
12118
            buf = (byte*)XMALLOC((size_t)len, NULL, DYNAMIC_TYPE_ASN1);
12119
            if (buf == NULL)
12120
                return WOLFSSL_FATAL_ERROR;
12121
        }
12122
12123
        len = (int)SetAlgoID((int)oid, buf, alg->algorithm->grp, 0);
12124
        if (len == 0) {
12125
            WOLFSSL_MSG("SetAlgoID error");
12126
            if (*pp == NULL)
12127
                XFREE(buf, NULL, DYNAMIC_TYPE_ASN1);
12128
            return WOLFSSL_FATAL_ERROR;
12129
        }
12130
12131
        if (*pp != NULL)
12132
            *pp += len;
12133
        else
12134
            *pp = buf;
12135
    }
12136
12137
    return len;
12138
}
12139
12140
WOLFSSL_X509_ALGOR* wolfSSL_d2i_X509_ALGOR(WOLFSSL_X509_ALGOR** out,
12141
        const byte** src, long len)
12142
{
12143
    WOLFSSL_X509_ALGOR* ret = NULL;
12144
    word32 idx = 0;
12145
    word32 oid = 0;
12146
    int grp;
12147
12148
    WOLFSSL_ENTER("wolfSSL_d2i_X509_ALGOR");
12149
12150
    if (src == NULL || *src == NULL || len <= 0)
12151
        return NULL;
12152
12153
    if (GetAlgoId(*src, &idx, &oid, oidIgnoreType, (word32)len) != 0)
12154
        return NULL;
12155
12156
    /* Try to guess the type */
12157
    for (grp = 0; grp < oidIgnoreType; grp++) {
12158
        word32 oidSz;
12159
        if (OidFromId(oid, (word32)grp, &oidSz) != NULL)
12160
            break;
12161
    }
12162
    if (grp == oidIgnoreType)
12163
        return NULL;
12164
12165
    ret = wolfSSL_X509_ALGOR_new();
12166
    if (ret == NULL)
12167
        return NULL;
12168
12169
    ret->algorithm = wolfSSL_OBJ_nid2obj(oid2nid(oid, grp));
12170
    if (ret->algorithm == NULL) {
12171
        wolfSSL_X509_ALGOR_free(ret);
12172
        return NULL;
12173
    }
12174
    *src += idx;
12175
12176
    if (out != NULL) {
12177
        if (*out != NULL)
12178
            wolfSSL_X509_ALGOR_free(*out);
12179
        *out = ret;
12180
    }
12181
12182
    return ret;
12183
}
12184
12185
/**
12186
 * Allocate a new WOLFSSL_X509_PUBKEY object.
12187
 *
12188
 * @return New zero'ed WOLFSSL_X509_PUBKEY object
12189
 */
12190
WOLFSSL_X509_PUBKEY *wolfSSL_X509_PUBKEY_new(void)
12191
{
12192
    WOLFSSL_X509_PUBKEY *ret;
12193
    ret = (WOLFSSL_X509_PUBKEY*)XMALLOC(sizeof(WOLFSSL_X509_PUBKEY), NULL,
12194
                                        DYNAMIC_TYPE_OPENSSL);
12195
    if (!ret) {
12196
        return NULL;
12197
    }
12198
    XMEMSET(ret, 0, sizeof(WOLFSSL_X509_PUBKEY));
12199
    ret->algor = wolfSSL_X509_ALGOR_new();
12200
    if (!ret->algor) {
12201
        wolfSSL_X509_PUBKEY_free(ret);
12202
        return NULL;
12203
    }
12204
    return ret;
12205
}
12206
12207
/**
12208
 * Free WOLFSSL_X509_PUBKEY and all its members.
12209
 *
12210
 * @param at Object to free
12211
 */
12212
void wolfSSL_X509_PUBKEY_free(WOLFSSL_X509_PUBKEY *x)
12213
{
12214
    if (x) {
12215
        if (x->algor) {
12216
            wolfSSL_X509_ALGOR_free(x->algor);
12217
        }
12218
        if (x->pkey) {
12219
            wolfSSL_EVP_PKEY_free(x->pkey);
12220
        }
12221
        XFREE(x, NULL, DYNAMIC_TYPE_OPENSSL);
12222
    }
12223
}
12224
12225
/* Returns X509_PUBKEY structure containing X509_ALGOR and EVP_PKEY */
12226
WOLFSSL_X509_PUBKEY* wolfSSL_X509_get_X509_PUBKEY(const WOLFSSL_X509* x509)
12227
{
12228
    WOLFSSL_ENTER("wolfSSL_X509_get_X509_PUBKEY");
12229
12230
    if (x509 == NULL) {
12231
        WOLFSSL_MSG("x509 struct NULL error");
12232
        return NULL;
12233
    }
12234
12235
    return (WOLFSSL_X509_PUBKEY*)&x509->key;
12236
}
12237
12238
/* Step over SubjectPublicKeyInfo to its subjectPublicKey BIT STRING.
12239
 *
12240
 * @param [in, out] der    On in, the SPKI. On out, the BIT STRING contents.
12241
 * @param [in, out] derSz  On in, size of the encoding. On out, size of the
12242
 *                         BIT STRING contents.
12243
 * @return  0 on success.
12244
 * @return  WOLFSSL_FATAL_ERROR when the encoding does not parse.
12245
 */
12246
static int x509_pubkey_bit_string(const unsigned char** der, int* derSz)
12247
{
12248
    word32 idx = 0;
12249
    int len = 0;
12250
12251
    if ((*der == NULL) || (*derSz <= 0)) {
12252
        return WOLFSSL_FATAL_ERROR;
12253
    }
12254
    if (GetSequence(*der, &idx, &len, (word32)*derSz) < 0) {
12255
        return WOLFSSL_FATAL_ERROR;
12256
    }
12257
    /* spki length must span the whole encoding */
12258
    if (idx + (word32)len != (word32)*derSz) {
12259
        return WOLFSSL_FATAL_ERROR;
12260
    }
12261
    /* step over AlgorithmIdentifier */
12262
    if (GetSequence(*der, &idx, &len, (word32)*derSz) < 0) {
12263
        return WOLFSSL_FATAL_ERROR;
12264
    }
12265
    idx += (word32)len;
12266
    /* subjectPublicKey is the last field */
12267
    if (CheckBitString(*der, &idx, &len, (word32)*derSz, 1, NULL) < 0) {
12268
        return WOLFSSL_FATAL_ERROR;
12269
    }
12270
    if (idx + (word32)len != (word32)*derSz) {
12271
        return WOLFSSL_FATAL_ERROR;
12272
    }
12273
12274
    *der += idx;
12275
    *derSz = len;
12276
12277
    return 0;
12278
}
12279
12280
/* Sets ppkalg pointer to X509_PUBKEY algorithm. Returns WOLFSSL_SUCCESS on
12281
    success or WOLFSSL_FAILURE on error. */
12282
int wolfSSL_X509_PUBKEY_get0_param(WOLFSSL_ASN1_OBJECT **ppkalg,
12283
     const unsigned char **pk, int *ppklen, WOLFSSL_X509_ALGOR **pa,
12284
     WOLFSSL_X509_PUBKEY *pub)
12285
{
12286
    const unsigned char* bitStr;
12287
    int bitStrSz;
12288
12289
    WOLFSSL_ENTER("wolfSSL_X509_PUBKEY_get0_param");
12290
12291
    if (!pub || !pub->pubKeyOID) {
12292
        WOLFSSL_MSG("X509_PUBKEY struct not populated");
12293
        return WOLFSSL_FAILURE;
12294
    }
12295
12296
    if (!pub->algor) {
12297
        if (!(pub->algor = wolfSSL_X509_ALGOR_new())) {
12298
            return WOLFSSL_FAILURE;
12299
        }
12300
        pub->algor->algorithm = wolfSSL_OBJ_nid2obj(pub->pubKeyOID);
12301
        if (pub->algor->algorithm == NULL) {
12302
            WOLFSSL_MSG("Failed to create object from NID");
12303
            return WOLFSSL_FAILURE;
12304
        }
12305
    }
12306
12307
    if (pa)
12308
        *pa = pub->algor;
12309
    if (ppkalg)
12310
        *ppkalg = pub->algor->algorithm;
12311
12312
    if ((pk != NULL) || (ppklen != NULL)) {
12313
        bitStr = (const unsigned char*)pub->pkey->pkey.ptr;
12314
        bitStrSz = pub->pkey->pkey_sz;
12315
12316
        /* try to parse BIT STRING from SPKI, otherwise return the
12317
         * pointer as is */
12318
        if (x509_pubkey_bit_string(&bitStr, &bitStrSz) != 0) {
12319
            WOLFSSL_MSG("No SubjectPublicKeyInfo wrapper found");
12320
        }
12321
12322
        if (pk)
12323
            *pk = bitStr;
12324
        if (ppklen)
12325
            *ppklen = bitStrSz;
12326
    }
12327
12328
    return WOLFSSL_SUCCESS;
12329
}
12330
12331
/* Returns a pointer to the pkey when passed a key */
12332
WOLFSSL_EVP_PKEY* wolfSSL_X509_PUBKEY_get(WOLFSSL_X509_PUBKEY* key)
12333
{
12334
    WOLFSSL_ENTER("wolfSSL_X509_PUBKEY_get");
12335
    if (key == NULL || key->pkey == NULL) {
12336
        WOLFSSL_LEAVE("wolfSSL_X509_PUBKEY_get", BAD_FUNC_ARG);
12337
        return NULL;
12338
    }
12339
    if (wolfSSL_EVP_PKEY_up_ref(key->pkey) != WOLFSSL_SUCCESS) {
12340
        WOLFSSL_LEAVE("wolfSSL_X509_PUBKEY_get", BAD_MUTEX_E);
12341
        return NULL;
12342
    }
12343
    WOLFSSL_LEAVE("wolfSSL_X509_PUBKEY_get", WOLFSSL_SUCCESS);
12344
    return key->pkey;
12345
}
12346
12347
int wolfSSL_X509_PUBKEY_set(WOLFSSL_X509_PUBKEY **x, WOLFSSL_EVP_PKEY *key)
12348
{
12349
    WOLFSSL_X509_PUBKEY *pk = NULL;
12350
    int ptype;
12351
    void *pval;
12352
#ifndef NO_DSA
12353
    WOLFSSL_ASN1_STRING *str;
12354
#endif
12355
#ifdef HAVE_ECC
12356
    int nid;
12357
    const WOLFSSL_EC_GROUP *group;
12358
#endif
12359
    WOLFSSL_ASN1_OBJECT *keyTypeObj;
12360
12361
    WOLFSSL_ENTER("wolfSSL_X509_PUBKEY_set");
12362
12363
    if (!x || !key) {
12364
        return WOLFSSL_FAILURE;
12365
    }
12366
12367
    if (!(pk = wolfSSL_X509_PUBKEY_new())) {
12368
        return WOLFSSL_FAILURE;
12369
    }
12370
12371
    switch (key->type) {
12372
#ifndef NO_RSA
12373
    case WC_EVP_PKEY_RSA:
12374
        pval = NULL;
12375
        ptype = WOLFSSL_V_ASN1_NULL;
12376
        pk->pubKeyOID = RSAk;
12377
        break;
12378
#endif
12379
#ifndef NO_DSA
12380
    case WC_EVP_PKEY_DSA:
12381
        if (!key->dsa->p || !key->dsa->q || !key->dsa->g)
12382
            goto error;
12383
12384
        str = wolfSSL_ASN1_STRING_new();
12385
        if (str == NULL)
12386
            goto error;
12387
12388
        str->length = wolfSSL_i2d_DSAparams(key->dsa,
12389
             (unsigned char **)&str->data);
12390
        if (str->length <= 0) {
12391
            wolfSSL_ASN1_STRING_free(str);
12392
            goto error;
12393
        }
12394
        str->isDynamic = 1;
12395
12396
        pval = str;
12397
        ptype = WOLFSSL_V_ASN1_SEQUENCE;
12398
        pk->pubKeyOID = DSAk;
12399
        break;
12400
#endif
12401
#ifdef HAVE_ECC
12402
    case WC_EVP_PKEY_EC:
12403
        group = wolfSSL_EC_KEY_get0_group(key->ecc);
12404
        if (!group)
12405
            goto error;
12406
12407
        nid = wolfSSL_EC_GROUP_get_curve_name(group);
12408
        if (nid <= 0) {
12409
            /* TODO: Add support for no nid case */
12410
            WOLFSSL_MSG("nid not found");
12411
            goto error;
12412
        }
12413
12414
        pval = wolfSSL_OBJ_nid2obj(nid);
12415
        if (!pval)
12416
            goto error;
12417
12418
        ptype = WOLFSSL_V_ASN1_OBJECT;
12419
        pk->pubKeyOID = ECDSAk;
12420
        break;
12421
#endif
12422
    default:
12423
        WOLFSSL_MSG("Unknown key type");
12424
        goto error;
12425
    }
12426
12427
    keyTypeObj = wolfSSL_OBJ_nid2obj(key->type);
12428
    if (keyTypeObj == NULL) {
12429
        if (ptype == WOLFSSL_V_ASN1_OBJECT)
12430
            wolfSSL_ASN1_OBJECT_free((WOLFSSL_ASN1_OBJECT *)pval);
12431
        else
12432
            wolfSSL_ASN1_STRING_free((WOLFSSL_ASN1_STRING *)pval);
12433
        goto error;
12434
    }
12435
    if (!wolfSSL_X509_ALGOR_set0(pk->algor, keyTypeObj, ptype, pval)) {
12436
        WOLFSSL_MSG("Failed to create algorithm object");
12437
        wolfSSL_ASN1_OBJECT_free(keyTypeObj);
12438
        if (ptype == WOLFSSL_V_ASN1_OBJECT)
12439
            wolfSSL_ASN1_OBJECT_free((WOLFSSL_ASN1_OBJECT *)pval);
12440
        else
12441
            wolfSSL_ASN1_STRING_free((WOLFSSL_ASN1_STRING *)pval);
12442
        goto error;
12443
    }
12444
12445
    if (!wolfSSL_EVP_PKEY_up_ref(key)) {
12446
        WOLFSSL_MSG("Failed to up key reference");
12447
        goto error;
12448
    }
12449
    pk->pkey = key;
12450
12451
    wolfSSL_X509_PUBKEY_free(*x);
12452
    *x = pk;
12453
    return WOLFSSL_SUCCESS;
12454
error:
12455
    if (pk) {
12456
        wolfSSL_X509_PUBKEY_free(pk);
12457
    }
12458
    return WOLFSSL_FAILURE;
12459
}
12460
12461
#endif /* OPENSSL_ALL || OPENSSL_EXTRA || WOLFSSL_APACHE_HTTPD ||
12462
        * WOLFSSL_HAPROXY || WOLFSSL_WPAS */
12463
12464
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_ASN)
12465
12466
int wolfSSL_i2d_X509_PUBKEY(WOLFSSL_X509_PUBKEY* x509_PubKey,
12467
    unsigned char** der)
12468
{
12469
    if (x509_PubKey == NULL)
12470
        return WOLFSSL_FATAL_ERROR;
12471
    return wolfSSL_i2d_PUBKEY(x509_PubKey->pkey, der);
12472
}
12473
12474
#endif /* OPENSSL_EXTRA && !NO_CERTS && !NO_ASN */
12475
12476
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
12477
12478
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
12479
WOLFSSL_BASIC_CONSTRAINTS* wolfSSL_BASIC_CONSTRAINTS_new(void)
12480
{
12481
    WOLFSSL_BASIC_CONSTRAINTS* bc;
12482
    bc = (WOLFSSL_BASIC_CONSTRAINTS*)
12483
          XMALLOC(sizeof(WOLFSSL_BASIC_CONSTRAINTS), NULL,
12484
          DYNAMIC_TYPE_X509_EXT);
12485
    if (bc == NULL) {
12486
        WOLFSSL_MSG("Failed to malloc basic constraints");
12487
        return NULL;
12488
    }
12489
    XMEMSET(bc, 0, sizeof(WOLFSSL_BASIC_CONSTRAINTS));
12490
    return bc;
12491
}
12492
12493
/* frees the wolfSSL_BASIC_CONSTRAINTS object */
12494
void wolfSSL_BASIC_CONSTRAINTS_free(WOLFSSL_BASIC_CONSTRAINTS *bc)
12495
{
12496
    WOLFSSL_ENTER("wolfSSL_BASIC_CONSTRAINTS_free");
12497
    if (bc == NULL) {
12498
        WOLFSSL_MSG("Argument is NULL");
12499
        return;
12500
    }
12501
    if (bc->pathlen) {
12502
        wolfSSL_ASN1_INTEGER_free(bc->pathlen);
12503
    }
12504
    XFREE(bc, NULL, DYNAMIC_TYPE_OPENSSL);
12505
}
12506
12507
WOLFSSL_AUTHORITY_KEYID* wolfSSL_AUTHORITY_KEYID_new(void)
12508
{
12509
    WOLFSSL_AUTHORITY_KEYID* akey = (WOLFSSL_AUTHORITY_KEYID*)XMALLOC(
12510
          sizeof(WOLFSSL_AUTHORITY_KEYID), NULL, DYNAMIC_TYPE_OPENSSL);
12511
    if (!akey) {
12512
        WOLFSSL_MSG("Issue creating WOLFSSL_AUTHORITY_KEYID struct");
12513
        return NULL;
12514
    }
12515
    XMEMSET(akey, 0, sizeof(WOLFSSL_AUTHORITY_KEYID));
12516
    return akey;
12517
}
12518
12519
/* frees the wolfSSL_AUTHORITY_KEYID object */
12520
void wolfSSL_AUTHORITY_KEYID_free(WOLFSSL_AUTHORITY_KEYID *id)
12521
{
12522
    WOLFSSL_ENTER("wolfSSL_AUTHORITY_KEYID_free");
12523
    if (id == NULL) {
12524
        WOLFSSL_MSG("Argument is NULL");
12525
        return;
12526
    }
12527
    if (id->keyid) {
12528
        wolfSSL_ASN1_STRING_free(id->keyid);
12529
    }
12530
    if (id->issuer) {
12531
        wolfSSL_ASN1_OBJECT_free(id->issuer);
12532
    }
12533
    if (id->serial) {
12534
        wolfSSL_ASN1_INTEGER_free(id->serial);
12535
    }
12536
    XFREE(id, NULL, DYNAMIC_TYPE_OPENSSL);
12537
}
12538
12539
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
12540
12541
#ifdef KEEP_PEER_CERT
12542
char*  wolfSSL_X509_get_subjectCN(WOLFSSL_X509* x509)
12543
{
12544
    if (x509 == NULL)
12545
        return NULL;
12546
12547
    return x509->subjectCN;
12548
}
12549
#endif /* KEEP_PEER_CERT */
12550
12551
#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA)
12552
/* increments ref count of WOLFSSL_X509. Return 1 on success, 0 on error */
12553
int wolfSSL_X509_up_ref(WOLFSSL_X509* x509)
12554
{
12555
    if (x509) {
12556
        int ret;
12557
        wolfSSL_RefInc(&x509->ref, &ret);
12558
        if (ret != 0) {
12559
            WOLFSSL_MSG("Failed to lock x509 mutex");
12560
            return WOLFSSL_FAILURE;
12561
        }
12562
12563
        return WOLFSSL_SUCCESS;
12564
    }
12565
12566
    return WOLFSSL_FAILURE;
12567
}
12568
#endif /* OPENSSL_EXTRA_X509_SMALL || OPENSSL_EXTRA */
12569
12570
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
12571
WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_chain_up_ref(
12572
        WOLF_STACK_OF(WOLFSSL_X509)* chain)
12573
{
12574
    /* wolfSSL_sk_dup takes care of doing a deep copy */
12575
    return wolfSSL_sk_dup(chain);
12576
}
12577
#endif
12578
12579
#if defined(OPENSSL_EXTRA)
12580
12581
WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* wolfSSL_sk_X509_OBJECT_deep_copy(
12582
    const WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk,
12583
    WOLFSSL_X509_OBJECT* (*c)(const WOLFSSL_X509_OBJECT*),
12584
    void (*f)(WOLFSSL_X509_OBJECT*))
12585
{
12586
    (void)f; /* free function */
12587
    (void)c; /* copy function */
12588
    return wolfSSL_sk_dup((WOLFSSL_STACK*)sk);
12589
}
12590
#endif
12591
12592
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
12593
    void wolfSSL_X509_NAME_free(WOLFSSL_X509_NAME *name)
12594
    {
12595
        WOLFSSL_ENTER_VERBOSE("wolfSSL_X509_NAME_free");
12596
        FreeX509Name(name);
12597
        if (name != NULL) {
12598
            XFREE(name, name->heap, DYNAMIC_TYPE_X509);
12599
        }
12600
    }
12601
12602
12603
    /* Malloc's a new WOLFSSL_X509_NAME structure
12604
     *
12605
     * returns NULL on failure, otherwise returns a new structure.
12606
     */
12607
    WOLFSSL_X509_NAME* wolfSSL_X509_NAME_new_ex(void *heap)
12608
    {
12609
        WOLFSSL_X509_NAME* name;
12610
12611
        WOLFSSL_ENTER_VERBOSE("wolfSSL_X509_NAME_new_ex");
12612
12613
        name = (WOLFSSL_X509_NAME*)XMALLOC(sizeof(WOLFSSL_X509_NAME), heap,
12614
                DYNAMIC_TYPE_X509);
12615
        if (name != NULL) {
12616
            InitX509Name(name, 1, heap);
12617
        }
12618
        return name;
12619
    }
12620
12621
    WOLFSSL_X509_NAME* wolfSSL_X509_NAME_new(void) {
12622
        return wolfSSL_X509_NAME_new_ex(NULL);
12623
    }
12624
12625
    /* Creates a duplicate of a WOLFSSL_X509_NAME structure.
12626
       Returns a new WOLFSSL_X509_NAME structure or NULL on failure */
12627
    WOLFSSL_X509_NAME* wolfSSL_X509_NAME_dup(const WOLFSSL_X509_NAME *name)
12628
    {
12629
        WOLFSSL_X509_NAME* copy = NULL;
12630
12631
        WOLFSSL_ENTER("wolfSSL_X509_NAME_dup");
12632
12633
        if (name == NULL) {
12634
            WOLFSSL_MSG("NULL parameter");
12635
            return NULL;
12636
        }
12637
12638
        if (!(copy = wolfSSL_X509_NAME_new_ex(name->heap))) {
12639
            return NULL;
12640
        }
12641
12642
        /* copy contents */
12643
        InitX509Name(copy, 1, name->heap);
12644
        if (wolfSSL_X509_NAME_copy(name, copy) != WOLFSSL_SUCCESS) {
12645
            wolfSSL_X509_NAME_free(copy);
12646
            return NULL;
12647
        }
12648
12649
        return copy;
12650
    }
12651
12652
#ifdef WOLFSSL_CERT_GEN
12653
12654
#if defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT) || \
12655
    defined(OPENSSL_EXTRA)
12656
    /* Helper function to copy cert name from a WOLFSSL_X509_NAME structure to
12657
    * a Cert structure.
12658
    *
12659
    * returns length of DER on success and a negative error value on failure
12660
    */
12661
    static int CopyX509NameToCert(WOLFSSL_X509_NAME* n, byte* out)
12662
    {
12663
        unsigned char* der = NULL;
12664
        int length = WC_NO_ERR_TRACE(BAD_FUNC_ARG), ret;
12665
        word32 idx = 0;
12666
12667
        ret = wolfSSL_i2d_X509_NAME(n, &der);
12668
        if (ret > (int)sizeof(CertName) || ret < 0) {
12669
            WOLFSSL_MSG("Name conversion error");
12670
            ret = MEMORY_E;
12671
        }
12672
12673
        if (ret > 0) {
12674
            /* strip off sequence, this gets added on certificate creation */
12675
            ret = GetSequence(der, &idx, &length, (word32)ret);
12676
        }
12677
12678
        if (ret > 0) {
12679
            XMEMCPY(out, der + idx, length);
12680
        }
12681
12682
        XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
12683
12684
        return length;
12685
    }
12686
#endif
12687
12688
#ifdef WOLFSSL_CERT_REQ
12689
    static int ReqCertFromX509(Cert* cert, WOLFSSL_X509* req)
12690
    {
12691
        int ret;
12692
12693
        if (wc_InitCert(cert) != 0)
12694
            return WOLFSSL_FAILURE;
12695
12696
12697
        ret = CopyX509NameToCert(&req->subject, cert->sbjRaw);
12698
        if (ret < 0) {
12699
            WOLFSSL_MSG("REQ subject conversion error");
12700
            ret = MEMORY_E;
12701
        }
12702
        else {
12703
            ret = WOLFSSL_SUCCESS;
12704
        }
12705
12706
        if (ret == WOLFSSL_SUCCESS) {
12707
            cert->version = req->version;
12708
            cert->isCA = req->isCa;
12709
            cert->basicConstSet = req->basicConstSet;
12710
            cert->basicConstCrit = req->basicConstCrit;
12711
            if (req->pathLengthSet) {
12712
                if (req->pathLength > WOLFSSL_MAX_PATH_LEN) {
12713
                    WOLFSSL_MSG("Basic Constraints path length too large");
12714
                    WOLFSSL_ERROR_VERBOSE(ASN_PATHLEN_SIZE_E);
12715
                    ret = WOLFSSL_FAILURE;
12716
                }
12717
                else {
12718
                    cert->pathLen = (byte)req->pathLength;
12719
                    cert->pathLenSet = req->pathLengthSet;
12720
                }
12721
            }
12722
    #ifdef WOLFSSL_CERT_EXT
12723
            if (req->subjKeyIdSz != 0) {
12724
                if (req->subjKeyIdSz > CTC_MAX_SKID_SIZE) {
12725
                    WOLFSSL_MSG("Subject Key ID too large");
12726
                    WOLFSSL_ERROR_VERBOSE(BUFFER_E);
12727
                    ret = WOLFSSL_FAILURE;
12728
                }
12729
                else if (req->subjKeyId == NULL) {
12730
                    WOLFSSL_MSG("Subject Key ID missing");
12731
                    WOLFSSL_ERROR_VERBOSE(BAD_FUNC_ARG);
12732
                    ret = WOLFSSL_FAILURE;
12733
                }
12734
                else {
12735
                    XMEMCPY(cert->skid, req->subjKeyId, req->subjKeyIdSz);
12736
                    cert->skidSz = (int)req->subjKeyIdSz;
12737
                }
12738
            }
12739
            if (req->keyUsageSet)
12740
                cert->keyUsage = req->keyUsage;
12741
12742
            cert->extKeyUsage = req->extKeyUsage;
12743
    #endif
12744
        }
12745
12746
        if (ret == WOLFSSL_SUCCESS) {
12747
        #if defined(OPENSSL_ALL)
12748
            int idx;
12749
        #endif
12750
12751
            XMEMCPY(cert->challengePw, req->challengePw, CTC_NAME_SIZE);
12752
            cert->challengePwPrintableString = req->challengePw[0] != 0;
12753
12754
        #if defined(OPENSSL_ALL)
12755
            idx = wolfSSL_X509_REQ_get_attr_by_NID(req,
12756
                    WC_NID_pkcs9_unstructuredName, -1);
12757
            if (idx != WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) {
12758
                WOLFSSL_X509_ATTRIBUTE *attr;
12759
                attr = wolfSSL_X509_REQ_get_attr(req, idx);
12760
                if (attr != NULL) {
12761
                    const unsigned char *attrData;
12762
                    int attrDataSz;
12763
12764
                    attrData = wolfSSL_ASN1_STRING_get0_data(
12765
                            attr->value->value.asn1_string);
12766
                    attrDataSz = wolfSSL_ASN1_STRING_length(
12767
                            attr->value->value.asn1_string);
12768
12769
                    /* +1 to make sure is terminated string */
12770
                    if (attrDataSz + 1 > CTC_NAME_SIZE) {
12771
                        WOLFSSL_MSG("attribute size was too large to copy");
12772
                        ret = REQ_ATTRIBUTE_E;
12773
                    }
12774
                    else {
12775
                        XMEMCPY(cert->unstructuredName, attrData, attrDataSz);
12776
                        cert->unstructuredName[attrDataSz] = '\0';
12777
                    }
12778
                }
12779
            }
12780
12781
        #ifdef WOLFSSL_CUSTOM_OID
12782
            if (ret == WOLFSSL_SUCCESS) {
12783
                if ((req->customExtCount < 0) ||
12784
                    (req->customExtCount >= NUM_CUSTOM_EXT)) {
12785
                    WOLFSSL_MSG("Bad value for customExtCount.");
12786
                    ret = WOLFSSL_FAILURE;
12787
                }
12788
12789
                if (ret == WOLFSSL_SUCCESS) {
12790
                    for (idx = 0; idx < req->customExtCount; idx++) {
12791
                        /* Note that ownership is NOT transferred.
12792
                         * req->custom_exts buffers still need to be cleaned
12793
                         * up. */
12794
                        cert->customCertExt[idx] = req->custom_exts[idx];
12795
                    }
12796
                    cert->customCertExtCount = req->customExtCount;
12797
                }
12798
            }
12799
        #endif /* WOLFSSL_CUSTOM_OID */
12800
        #endif /* OPENSSL_ALL */
12801
12802
    #ifdef WOLFSSL_ALT_NAMES
12803
            if (ret == WOLFSSL_SUCCESS) {
12804
                cert->altNamesSz = FlattenAltNames(cert->altNames,
12805
                        sizeof(cert->altNames), req->altNames);
12806
            }
12807
    #endif /* WOLFSSL_ALT_NAMES */
12808
        }
12809
12810
        return ret;
12811
    }
12812
#endif /* WOLFSSL_CERT_REQ */
12813
12814
/* converts WOLFSSL_AN1_TIME to Cert form, returns positive size on
12815
 * success */
12816
static int CertDateFromX509(byte* out, int outSz, WOLFSSL_ASN1_TIME* t)
12817
{
12818
    int sz, i;
12819
12820
    if (t->length + 1 >= outSz) {
12821
        return BUFFER_E;
12822
    }
12823
12824
    out[0] = (byte) t->type;
12825
    sz = (int)SetLength((word32)t->length, out + 1) + 1;  /* gen tag */
12826
    for (i = 0; i < t->length; i++) {
12827
        out[sz + i] = t->data[i];
12828
    }
12829
    return t->length + sz;
12830
}
12831
12832
/* convert a WOLFSSL_X509 to a Cert structure for writing out */
12833
static int CertFromX509(Cert* cert, WOLFSSL_X509* x509)
12834
{
12835
    int ret;
12836
#ifdef WOLFSSL_CERT_EXT
12837
    int i;
12838
#endif
12839
12840
    WOLFSSL_ENTER("wolfSSL_X509_to_Cert");
12841
12842
    if (x509 == NULL || cert == NULL) {
12843
        return BAD_FUNC_ARG;
12844
    }
12845
12846
    wc_InitCert(cert);
12847
12848
    cert->version = (int)wolfSSL_X509_get_version(x509);
12849
12850
    if (x509->notBefore.length > 0) {
12851
        cert->beforeDateSz = CertDateFromX509(cert->beforeDate,
12852
                    CTC_DATE_SIZE, &x509->notBefore);
12853
        if (cert->beforeDateSz <= 0) {
12854
            WOLFSSL_MSG("Error converting WOLFSSL_X509 not before date");
12855
            return WOLFSSL_FAILURE;
12856
        }
12857
    }
12858
    else {
12859
        cert->beforeDateSz = 0;
12860
    }
12861
12862
    if (x509->notAfter.length > 0) {
12863
        cert->afterDateSz = CertDateFromX509(cert->afterDate,
12864
                    CTC_DATE_SIZE, &x509->notAfter);
12865
        if (cert->afterDateSz <= 0) {
12866
            WOLFSSL_MSG("Error converting WOLFSSL_X509 not after date");
12867
            return WOLFSSL_FAILURE;
12868
        }
12869
    }
12870
    else {
12871
        cert->afterDateSz = 0;
12872
    }
12873
12874
#ifdef WOLFSSL_ALT_NAMES
12875
    cert->altNamesSz = FlattenAltNames(cert->altNames,
12876
            sizeof(cert->altNames), x509->altNames);
12877
#endif /* WOLFSSL_ALT_NAMES */
12878
12879
    cert->sigType = wolfSSL_X509_get_signature_type(x509);
12880
    cert->keyType = x509->pubKeyOID;
12881
    cert->isCA    = wolfSSL_X509_get_isCA(x509);
12882
    cert->basicConstCrit = x509->basicConstCrit;
12883
    cert->basicConstSet = x509->basicConstSet;
12884
    if (x509->pathLengthSet) {
12885
        if (x509->pathLength > WOLFSSL_MAX_PATH_LEN) {
12886
            WOLFSSL_MSG("Basic Constraints path length too large");
12887
            WOLFSSL_ERROR_VERBOSE(ASN_PATHLEN_SIZE_E);
12888
            return WOLFSSL_FAILURE;
12889
        }
12890
        cert->pathLen = (byte)x509->pathLength;
12891
        cert->pathLenSet = x509->pathLengthSet;
12892
    }
12893
12894
#ifdef WOLFSSL_CERT_EXT
12895
    if (x509->subjKeyIdSz <= CTC_MAX_SKID_SIZE) {
12896
        if (x509->subjKeyId) {
12897
            XMEMCPY(cert->skid, x509->subjKeyId, x509->subjKeyIdSz);
12898
        }
12899
        cert->skidSz = (int)x509->subjKeyIdSz;
12900
    }
12901
    else {
12902
        WOLFSSL_MSG("Subject Key ID too large");
12903
        WOLFSSL_ERROR_VERBOSE(BUFFER_E);
12904
        return WOLFSSL_FAILURE;
12905
    }
12906
12907
    #ifdef WOLFSSL_AKID_NAME
12908
    cert->rawAkid = 0;
12909
    if (x509->authKeyIdSrc) {
12910
        if (x509->authKeyIdSrcSz > sizeof(cert->akid)) {
12911
            WOLFSSL_MSG("Auth Key ID too large");
12912
            WOLFSSL_ERROR_VERBOSE(BUFFER_E);
12913
            return WOLFSSL_FAILURE;
12914
        }
12915
        XMEMCPY(cert->akid, x509->authKeyIdSrc, x509->authKeyIdSrcSz);
12916
        cert->akidSz = (int)x509->authKeyIdSrcSz;
12917
        cert->rawAkid = 1;
12918
    }
12919
    else
12920
    #endif
12921
    if (x509->authKeyId) {
12922
        if (x509->authKeyIdSz > sizeof(cert->akid)) {
12923
            WOLFSSL_MSG("Auth Key ID too large");
12924
            WOLFSSL_ERROR_VERBOSE(BUFFER_E);
12925
            return WOLFSSL_FAILURE;
12926
        }
12927
        XMEMCPY(cert->akid, x509->authKeyId, x509->authKeyIdSz);
12928
        cert->akidSz = (int)x509->authKeyIdSz;
12929
    }
12930
12931
    for (i = 0; i < x509->certPoliciesNb; i++) {
12932
        /* copy the smaller of MAX macros, by default they are currently equal*/
12933
        if ((int)CTC_MAX_CERTPOL_SZ <= (int)MAX_CERTPOL_SZ) {
12934
            XMEMCPY(cert->certPolicies[i], x509->certPolicies[i],
12935
                    CTC_MAX_CERTPOL_SZ);
12936
        }
12937
        else {
12938
            XMEMCPY(cert->certPolicies[i], x509->certPolicies[i],
12939
                    MAX_CERTPOL_SZ);
12940
        }
12941
    }
12942
    cert->certPoliciesNb = (word16)x509->certPoliciesNb;
12943
12944
    cert->keyUsage = x509->keyUsage;
12945
    cert->extKeyUsage = x509->extKeyUsage;
12946
    cert->nsCertType = x509->nsCertType;
12947
12948
    if (x509->rawCRLInfo != NULL) {
12949
        if (x509->rawCRLInfoSz > CTC_MAX_CRLINFO_SZ) {
12950
            WOLFSSL_MSG("CRL Info too large");
12951
            WOLFSSL_ERROR_VERBOSE(BUFFER_E);
12952
            return WOLFSSL_FAILURE;
12953
        }
12954
        XMEMCPY(cert->crlInfo, x509->rawCRLInfo, x509->rawCRLInfoSz);
12955
        cert->crlInfoSz = x509->rawCRLInfoSz;
12956
    }
12957
12958
#ifdef WOLFSSL_DUAL_ALG_CERTS
12959
    /* We point to instance in x509 so DON'T need to be free'd. */
12960
    cert->sapkiDer = x509->sapkiDer;
12961
    cert->sapkiLen = x509->sapkiLen;
12962
    cert->sapkiCrit = x509->sapkiCrit;
12963
    cert->altSigAlgDer = x509->altSigAlgDer;
12964
    cert->altSigAlgLen  = x509->altSigAlgLen;
12965
    cert->altSigAlgCrit = x509->altSigAlgCrit;
12966
    cert->altSigValDer = x509->altSigValDer;
12967
    cert->altSigValLen = x509->altSigValLen;
12968
    cert->altSigValCrit = x509->altSigValCrit;
12969
#endif /* WOLFSSL_DUAL_ALG_CERTS */
12970
12971
#if defined(WOLFSSL_ASN_TEMPLATE) && defined(WOLFSSL_CUSTOM_OID) && \
12972
    defined(HAVE_OID_ENCODING)
12973
12974
    if ((x509->customExtCount < 0) ||
12975
            (x509->customExtCount >= NUM_CUSTOM_EXT)) {
12976
        WOLFSSL_MSG("Bad value for customExtCount.");
12977
        return WOLFSSL_FAILURE;
12978
    }
12979
12980
    for (i = 0; i < x509->customExtCount; i++) {
12981
        if (wc_SetCustomExtension(cert, x509->custom_exts[i].crit,
12982
                x509->custom_exts[i].oid, x509->custom_exts[i].val,
12983
                x509->custom_exts[i].valSz))
12984
        {
12985
            return WOLFSSL_FAILURE;
12986
        }
12987
    }
12988
#endif /* WOLFSSL_ASN_TEMPLATE && WOLFSSL_CUSTOM_OID && HAVE_OID_ENCODING */
12989
12990
#endif /* WOLFSSL_CERT_EXT */
12991
12992
#ifdef WOLFSSL_CERT_REQ
12993
    /* copy over challenge password for REQ certs */
12994
    XMEMCPY(cert->challengePw, x509->challengePw, CTC_NAME_SIZE);
12995
#endif
12996
12997
    /* Only makes sense to do this for OPENSSL_EXTRA because without
12998
     * this define the function will error out below */
12999
    #ifdef OPENSSL_EXTRA
13000
    if (x509->serialSz == 0 && x509->serialNumber != NULL &&
13001
            /* Check if the buffer contains more than just the
13002
             * ASN tag and length */
13003
            x509->serialNumber->length > 2) {
13004
        if (wolfSSL_X509_set_serialNumber(x509, x509->serialNumber)
13005
                != WOLFSSL_SUCCESS) {
13006
            WOLFSSL_MSG("Failed to set serial number");
13007
            return WOLFSSL_FAILURE;
13008
        }
13009
    }
13010
    #endif
13011
13012
    /* set serial number */
13013
    if (x509->serialSz > 0) {
13014
    #if defined(OPENSSL_EXTRA)
13015
        byte serial[EXTERNAL_SERIAL_SIZE];
13016
        int  serialSz = EXTERNAL_SERIAL_SIZE;
13017
13018
        ret = wolfSSL_X509_get_serial_number(x509, serial, &serialSz);
13019
        if (ret != WOLFSSL_SUCCESS) {
13020
            WOLFSSL_MSG("Serial size error");
13021
            return WOLFSSL_FAILURE;
13022
        }
13023
13024
        if (serialSz > EXTERNAL_SERIAL_SIZE ||
13025
                serialSz > CTC_SERIAL_SIZE) {
13026
            WOLFSSL_MSG("Serial size too large error");
13027
            WOLFSSL_ERROR_VERBOSE(BUFFER_E);
13028
            return WOLFSSL_FAILURE;
13029
        }
13030
        XMEMCPY(cert->serial, serial, serialSz);
13031
        cert->serialSz = serialSz;
13032
    #else
13033
        WOLFSSL_MSG("Getting X509 serial number not supported");
13034
        return WOLFSSL_FAILURE;
13035
    #endif
13036
    }
13037
13038
    /* copy over Name structures */
13039
    if (x509->issuerSet)
13040
        cert->selfSigned = 0;
13041
13042
#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
13043
    ret = CopyX509NameToCert(&x509->subject, cert->sbjRaw);
13044
    if (ret < 0) {
13045
        WOLFSSL_MSG("Subject conversion error");
13046
        return MEMORY_E;
13047
    }
13048
    if (cert->selfSigned) {
13049
        XMEMCPY(cert->issRaw, cert->sbjRaw, sizeof(CertName));
13050
    }
13051
    else {
13052
        ret = CopyX509NameToCert(&x509->issuer, cert->issRaw);
13053
        if (ret < 0) {
13054
            WOLFSSL_MSG("Issuer conversion error");
13055
            return MEMORY_E;
13056
        }
13057
    }
13058
#endif
13059
13060
    cert->heap = x509->heap;
13061
13062
    (void)ret;
13063
    return WOLFSSL_SUCCESS;
13064
}
13065
13066
13067
#if defined(WOLFSSL_HAVE_MLDSA) && defined(WOLFSSL_MLDSA_PRIVATE_KEY) && \
13068
    !defined(WOLFSSL_MLDSA_NO_ASN1) && !defined(WOLFSSL_MLDSA_NO_SIGN)
13069
    /* ML-DSA X.509 signing needs private key decode and sign support; keep
13070
     * every gate that decides "can we sign with ML-DSA" identical so that
13071
     * verify-only builds reject the key type up front. */
13072
    #define WOLFSSL_MLDSA_X509_SIGN
13073
#endif
13074
13075
    /* returns the sig type to use on success i.e CTC_SHAwRSA and WOLFSSL_FALURE
13076
     * on fail case */
13077
    static int wolfSSL_sigTypeFromPKEY(WOLFSSL_EVP_MD* md,
13078
            WOLFSSL_EVP_PKEY* pkey)
13079
    {
13080
    #if defined(OPENSSL_EXTRA)
13081
        int hashType;
13082
        int sigType = WOLFSSL_FAILURE;
13083
    #endif
13084
13085
        if (pkey == NULL) {
13086
            return WOLFSSL_FAILURE;
13087
        }
13088
13089
    #if defined(HAVE_ED25519)
13090
        /* Ed25519 carries its own hash and needs no hash/PWDBASED info, so
13091
         * resolve it outside the guard below (works in --disable-pwdbased).
13092
         * OpenSSL rejects a non-NULL digest for Ed25519 -- match that rather
13093
         * than silently ignoring the caller's md. */
13094
        if (pkey->type == WC_EVP_PKEY_ED25519) {
13095
            if (md != NULL)
13096
                return WOLFSSL_FAILURE;
13097
            return CTC_ED25519;
13098
        }
13099
    #endif
13100
13101
    #if !defined(NO_PWDBASED) && defined(OPENSSL_EXTRA)
13102
    #ifdef WOLFSSL_MLDSA_X509_SIGN
13103
        if (pkey->type == WC_EVP_PKEY_DILITHIUM) {
13104
            /* ML-DSA does not use a separate hash. A NULL md matches
13105
             * OpenSSL's X509_sign(x, pkey, NULL); unlike OpenSSL, a
13106
             * non-NULL md is deliberately ignored rather than rejected to
13107
             * keep hash-passing callers working. */
13108
            if (md != NULL) {
13109
                WOLFSSL_MSG("Ignoring md for ML-DSA signing");
13110
            }
13111
            switch (WOLFSSL_ATOMIC_LOAD(pkey->mldsaOID)) {
13112
                case ML_DSA_44k:
13113
                    sigType = CTC_ML_DSA_44;
13114
                    break;
13115
                case ML_DSA_65k:
13116
                    sigType = CTC_ML_DSA_65;
13117
                    break;
13118
                case ML_DSA_87k:
13119
                    sigType = CTC_ML_DSA_87;
13120
                    break;
13121
            #ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
13122
                case DILITHIUM_LEVEL2k:
13123
                    sigType = CTC_DILITHIUM_LEVEL2;
13124
                    break;
13125
                case DILITHIUM_LEVEL3k:
13126
                    sigType = CTC_DILITHIUM_LEVEL3;
13127
                    break;
13128
                case DILITHIUM_LEVEL5k:
13129
                    sigType = CTC_DILITHIUM_LEVEL5;
13130
                    break;
13131
            #endif
13132
                default:
13133
                    return WOLFSSL_FAILURE;
13134
            }
13135
            return sigType;
13136
        }
13137
    #endif /* WOLFSSL_MLDSA_X509_SIGN */
13138
13139
        /* Every remaining key type signs a digest, and
13140
         * wolfSSL_EVP_get_hashinfo() below dereferences md without a NULL
13141
         * check of its own.  (Checked after ML-DSA, which accepts a NULL md.)
13142
         */
13143
        if (md == NULL) {
13144
            return WOLFSSL_FAILURE;
13145
        }
13146
13147
        /* Convert key type and hash algorithm to a signature algorithm */
13148
        if (wolfSSL_EVP_get_hashinfo(md, &hashType, NULL)
13149
            == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
13150
        {
13151
            return WOLFSSL_FAILURE;
13152
        }
13153
13154
        if (pkey->type == WC_EVP_PKEY_RSA) {
13155
            switch (hashType) {
13156
                case WC_HASH_TYPE_SHA:
13157
                    sigType = CTC_SHAwRSA;
13158
                    break;
13159
                case WC_HASH_TYPE_SHA224:
13160
                    sigType = CTC_SHA224wRSA;
13161
                    break;
13162
                case WC_HASH_TYPE_SHA256:
13163
                    sigType = CTC_SHA256wRSA;
13164
                    break;
13165
                case WC_HASH_TYPE_SHA384:
13166
                    sigType = CTC_SHA384wRSA;
13167
                    break;
13168
                case WC_HASH_TYPE_SHA512:
13169
                    sigType = CTC_SHA512wRSA;
13170
                    break;
13171
            #ifdef WOLFSSL_SHA3
13172
                case WC_HASH_TYPE_SHA3_224:
13173
                    sigType = CTC_SHA3_224wRSA;
13174
                    break;
13175
                case WC_HASH_TYPE_SHA3_256:
13176
                    sigType = CTC_SHA3_256wRSA;
13177
                    break;
13178
                case WC_HASH_TYPE_SHA3_384:
13179
                    sigType = CTC_SHA3_384wRSA;
13180
                    break;
13181
                case WC_HASH_TYPE_SHA3_512:
13182
                    sigType = CTC_SHA3_512wRSA;
13183
                    break;
13184
            #endif
13185
                default:
13186
                    return WOLFSSL_FAILURE;
13187
            }
13188
        }
13189
        else if (pkey->type == WC_EVP_PKEY_EC) {
13190
            switch (hashType) {
13191
                case WC_HASH_TYPE_SHA:
13192
                    sigType = CTC_SHAwECDSA;
13193
                    break;
13194
                case WC_HASH_TYPE_SHA224:
13195
                    sigType = CTC_SHA224wECDSA;
13196
                    break;
13197
                case WC_HASH_TYPE_SHA256:
13198
                    sigType = CTC_SHA256wECDSA;
13199
                    break;
13200
                case WC_HASH_TYPE_SHA384:
13201
                    sigType = CTC_SHA384wECDSA;
13202
                    break;
13203
                case WC_HASH_TYPE_SHA512:
13204
                    sigType = CTC_SHA512wECDSA;
13205
                    break;
13206
            #ifdef WOLFSSL_SHA3
13207
                case WC_HASH_TYPE_SHA3_224:
13208
                    sigType = CTC_SHA3_224wECDSA;
13209
                    break;
13210
                case WC_HASH_TYPE_SHA3_256:
13211
                    sigType = CTC_SHA3_256wECDSA;
13212
                    break;
13213
                case WC_HASH_TYPE_SHA3_384:
13214
                    sigType = CTC_SHA3_384wECDSA;
13215
                    break;
13216
                case WC_HASH_TYPE_SHA3_512:
13217
                    sigType = CTC_SHA3_512wECDSA;
13218
                    break;
13219
            #endif
13220
                default:
13221
                    return WOLFSSL_FAILURE;
13222
            }
13223
        }
13224
        else
13225
            return WOLFSSL_FAILURE;
13226
        return sigType;
13227
#else
13228
        (void)md;
13229
        (void)pkey;
13230
        WOLFSSL_MSG("Cannot get signature type without OPENSSL_EXTRA");
13231
        return WOLFSSL_FAILURE;
13232
#endif /* OPENSSL_EXTRA */
13233
    }
13234
13235
13236
    /* generates DER buffer from WOLFSSL_X509
13237
     * If req == 1 then creates a request DER buffer
13238
     *
13239
     * updates derSz with certificate body size on success
13240
     * return WOLFSSL_SUCCESS on success
13241
     */
13242
    static int wolfssl_x509_make_der(WOLFSSL_X509* x509, int req,
13243
            unsigned char* der, int* derSz, int includeSig)
13244
    {
13245
        int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
13246
        int totalLen;
13247
        Cert* cert = NULL;
13248
        void* key = NULL;
13249
        int type = -1;
13250
    #ifndef NO_RSA
13251
        RsaKey* rsa = NULL;
13252
    #endif
13253
    #ifdef HAVE_ECC
13254
        ecc_key* ecc = NULL;
13255
    #endif
13256
    #ifndef NO_DSA
13257
        DsaKey* dsa = NULL;
13258
    #endif
13259
    #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
13260
        ed25519_key* ed25519 = NULL;
13261
    #endif
13262
    #if defined(HAVE_FALCON)
13263
        falcon_key* falcon = NULL;
13264
    #endif
13265
    #if defined(WOLFSSL_HAVE_MLDSA)
13266
        wc_MlDsaKey* mldsa = NULL;
13267
    #endif
13268
    #if defined(WOLFSSL_HAVE_SLHDSA)
13269
        SlhDsaKey* slhdsa = NULL;
13270
    #endif
13271
        WC_RNG rng;
13272
        word32 idx = 0;
13273
13274
        if (x509 == NULL || der == NULL || derSz == NULL)
13275
            return BAD_FUNC_ARG;
13276
13277
    #ifndef WOLFSSL_CERT_REQ
13278
        if (req) {
13279
            WOLFSSL_MSG("WOLFSSL_CERT_REQ needed for certificate request");
13280
            return WOLFSSL_FAILURE;
13281
        }
13282
    #endif
13283
13284
        /* allocate Cert struct on heap since it is large */
13285
        cert = (Cert*)XMALLOC(sizeof(Cert), NULL, DYNAMIC_TYPE_CERT);
13286
        if (cert == NULL) {
13287
            WOLFSSL_MSG("Failed to allocate memory for Cert struct");
13288
            return WOLFSSL_FAILURE;
13289
        }
13290
        XMEMSET(cert, 0, sizeof(Cert));
13291
13292
    #ifdef WOLFSSL_CERT_REQ
13293
        if (req) {
13294
            if (ReqCertFromX509(cert, x509) != WOLFSSL_SUCCESS) {
13295
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13296
                return WOLFSSL_FAILURE;
13297
            }
13298
        }
13299
        else
13300
    #endif
13301
        {
13302
            /* Create a Cert that has the certificate fields. */
13303
            if (CertFromX509(cert, x509) != WOLFSSL_SUCCESS) {
13304
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13305
                return WOLFSSL_FAILURE;
13306
            }
13307
        }
13308
13309
        /* Create a public key object from requests public key. */
13310
    #ifndef NO_RSA
13311
        if (x509->pubKeyOID == RSAk) {
13312
13313
            rsa = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
13314
            if (rsa == NULL) {
13315
                WOLFSSL_MSG("Failed to allocate memory for RsaKey");
13316
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13317
                return WOLFSSL_FAILURE;
13318
            }
13319
13320
            type = RSA_TYPE;
13321
            ret = wc_InitRsaKey(rsa, x509->heap);
13322
            if (ret != 0) {
13323
                XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
13324
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13325
                return ret;
13326
            }
13327
            ret = wc_RsaPublicKeyDecode(x509->pubKey.buffer, &idx, rsa,
13328
                                                           x509->pubKey.length);
13329
            if (ret != 0) {
13330
                WOLFSSL_ERROR_VERBOSE(ret);
13331
                wc_FreeRsaKey(rsa);
13332
                XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
13333
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13334
                return ret;
13335
            }
13336
            key = (void*)rsa;
13337
        }
13338
    #endif
13339
    #ifdef HAVE_ECC
13340
        if (x509->pubKeyOID == ECDSAk) {
13341
13342
            ecc = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
13343
            if (ecc == NULL) {
13344
                WOLFSSL_MSG("Failed to allocate memory for ecc_key");
13345
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13346
                return WOLFSSL_FAILURE;
13347
            }
13348
13349
            type = ECC_TYPE;
13350
            ret = wc_ecc_init(ecc);
13351
            if (ret != 0) {
13352
                XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
13353
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13354
                return ret;
13355
            }
13356
            ret = wc_EccPublicKeyDecode(x509->pubKey.buffer, &idx, ecc,
13357
                                                           x509->pubKey.length);
13358
            if (ret != 0) {
13359
                WOLFSSL_ERROR_VERBOSE(ret);
13360
                wc_ecc_free(ecc);
13361
                XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
13362
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13363
                return ret;
13364
            }
13365
            key = (void*)ecc;
13366
        }
13367
    #endif
13368
    #ifndef NO_DSA
13369
        if (x509->pubKeyOID == DSAk) {
13370
13371
            dsa = (DsaKey*)XMALLOC(sizeof(DsaKey), NULL, DYNAMIC_TYPE_DSA);
13372
            if (dsa == NULL) {
13373
                WOLFSSL_MSG("Failed to allocate memory for DsaKey");
13374
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13375
                return WOLFSSL_FAILURE;
13376
            }
13377
13378
            type = DSA_TYPE;
13379
            ret = wc_InitDsaKey(dsa);
13380
            if (ret != 0) {
13381
                XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
13382
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13383
                return ret;
13384
            }
13385
            ret = wc_DsaPublicKeyDecode(x509->pubKey.buffer, &idx, dsa,
13386
                                                           x509->pubKey.length);
13387
            if (ret != 0) {
13388
                WOLFSSL_ERROR_VERBOSE(ret);
13389
                wc_FreeDsaKey(dsa);
13390
                XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
13391
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13392
                return ret;
13393
            }
13394
            key = (void*)dsa;
13395
        }
13396
    #endif
13397
    #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
13398
        if (x509->pubKeyOID == ED25519k) {
13399
            ed25519 = wolfSSL_ED25519_new(x509->heap, INVALID_DEVID);
13400
            if (ed25519 == NULL) {
13401
                WOLFSSL_MSG("Failed to allocate memory for ed25519_key");
13402
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13403
                return WOLFSSL_FAILURE;
13404
            }
13405
13406
            type = ED25519_TYPE;
13407
            /* The X.509 public key buffer holds the raw Ed25519 key. */
13408
            ret = wc_ed25519_import_public(x509->pubKey.buffer,
13409
                                           x509->pubKey.length, ed25519);
13410
            if (ret != 0) {
13411
                WOLFSSL_ERROR_VERBOSE(ret);
13412
                wolfSSL_ED25519_free(ed25519);
13413
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13414
                return ret;
13415
            }
13416
            key = (void*)ed25519;
13417
        }
13418
    #endif
13419
    #if defined(HAVE_FALCON)
13420
        if ((x509->pubKeyOID == FALCON_LEVEL1k) ||
13421
            (x509->pubKeyOID == FALCON_LEVEL5k)) {
13422
            falcon = (falcon_key*)XMALLOC(sizeof(falcon_key), NULL,
13423
                                          DYNAMIC_TYPE_FALCON);
13424
            if (falcon == NULL) {
13425
                WOLFSSL_MSG("Failed to allocate memory for falcon_key");
13426
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13427
                return WOLFSSL_FAILURE;
13428
            }
13429
13430
            ret = wc_falcon_init(falcon);
13431
            if (ret != 0) {
13432
                XFREE(falcon, NULL, DYNAMIC_TYPE_FALCON);
13433
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13434
                return ret;
13435
            }
13436
13437
            if (x509->pubKeyOID == FALCON_LEVEL1k) {
13438
                type = FALCON_LEVEL1_TYPE;
13439
                ret = wc_falcon_set_level(falcon, 1);
13440
            }
13441
            else if (x509->pubKeyOID == FALCON_LEVEL5k) {
13442
                type = FALCON_LEVEL5_TYPE;
13443
                ret = wc_falcon_set_level(falcon, 5);
13444
            }
13445
13446
            if (ret == 0) {
13447
                ret = wc_Falcon_PublicKeyDecode(x509->pubKey.buffer, &idx,
13448
                                                falcon, x509->pubKey.length);
13449
            }
13450
            if (ret != 0) {
13451
                WOLFSSL_ERROR_VERBOSE(ret);
13452
                wc_falcon_free(falcon);
13453
                XFREE(falcon, NULL, DYNAMIC_TYPE_FALCON);
13454
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13455
                return ret;
13456
            }
13457
            key = (void*)falcon;
13458
        }
13459
    #endif
13460
    #if defined(WOLFSSL_HAVE_MLDSA)
13461
        if ((x509->pubKeyOID == ML_DSA_44k) ||
13462
            (x509->pubKeyOID == ML_DSA_65k) ||
13463
            (x509->pubKeyOID == ML_DSA_87k)
13464
            #ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
13465
         || (x509->pubKeyOID == DILITHIUM_LEVEL2k)
13466
         || (x509->pubKeyOID == DILITHIUM_LEVEL3k)
13467
         || (x509->pubKeyOID == DILITHIUM_LEVEL5k)
13468
            #endif /* WOLFSSL_MLDSA_FIPS204_DRAFT */
13469
            ) {
13470
            mldsa = (wc_MlDsaKey*)XMALLOC(sizeof(wc_MlDsaKey), NULL,
13471
                                          DYNAMIC_TYPE_MLDSA);
13472
            if (mldsa == NULL) {
13473
                WOLFSSL_MSG("Failed to allocate memory for wc_MlDsaKey");
13474
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13475
                return WOLFSSL_FAILURE;
13476
            }
13477
13478
            ret = wc_MlDsaKey_Init(mldsa, NULL, INVALID_DEVID);
13479
            if (ret != 0) {
13480
                XFREE(mldsa, NULL, DYNAMIC_TYPE_MLDSA);
13481
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13482
                return ret;
13483
            }
13484
13485
            if (x509->pubKeyOID == ML_DSA_44k) {
13486
                type = ML_DSA_44_TYPE;
13487
                wc_MlDsaKey_SetParams(mldsa, WC_ML_DSA_44);
13488
            }
13489
            else if (x509->pubKeyOID == ML_DSA_65k) {
13490
                type = ML_DSA_65_TYPE;
13491
                wc_MlDsaKey_SetParams(mldsa, WC_ML_DSA_65);
13492
            }
13493
            else if (x509->pubKeyOID == ML_DSA_87k) {
13494
                type = ML_DSA_87_TYPE;
13495
                wc_MlDsaKey_SetParams(mldsa, WC_ML_DSA_87);
13496
            }
13497
            #ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
13498
            else if (x509->pubKeyOID == DILITHIUM_LEVEL2k) {
13499
                type = DILITHIUM_LEVEL2_TYPE;
13500
                wc_MlDsaKey_SetParams(mldsa, WC_ML_DSA_44_DRAFT);
13501
            }
13502
            else if (x509->pubKeyOID == DILITHIUM_LEVEL3k) {
13503
                type = DILITHIUM_LEVEL3_TYPE;
13504
                wc_MlDsaKey_SetParams(mldsa, WC_ML_DSA_65_DRAFT);
13505
            }
13506
            else if (x509->pubKeyOID == DILITHIUM_LEVEL5k) {
13507
                type = DILITHIUM_LEVEL5_TYPE;
13508
                wc_MlDsaKey_SetParams(mldsa, WC_ML_DSA_87_DRAFT);
13509
            }
13510
            #endif /* WOLFSSL_MLDSA_FIPS204_DRAFT */
13511
13512
            ret = wc_MlDsaKey_PublicKeyDecode(mldsa, x509->pubKey.buffer,
13513
                                    x509->pubKey.length, &idx);
13514
            if (ret != 0) {
13515
                WOLFSSL_ERROR_VERBOSE(ret);
13516
                wc_MlDsaKey_Free(mldsa);
13517
                XFREE(mldsa, NULL, DYNAMIC_TYPE_MLDSA);
13518
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13519
                return ret;
13520
            }
13521
            key = (void*)mldsa;
13522
        }
13523
    #endif
13524
    #if defined(WOLFSSL_HAVE_SLHDSA)
13525
        if (wc_IsSlhDsaOid(x509->pubKeyOID)) {
13526
            int paramInt = wc_SlhDsaOidToParam(x509->pubKeyOID);
13527
            int certType = wc_SlhDsaOidToCertType(x509->pubKeyOID);
13528
13529
            /* The OID is a recognised SLH-DSA OID but the parameter set
13530
             * isn't built in; surface NOT_COMPILED_IN directly so
13531
             * callers can render an accurate diagnostic. */
13532
            if (paramInt == WC_NO_ERR_TRACE(NOT_COMPILED_IN) ||
13533
                    certType == WC_NO_ERR_TRACE(NOT_COMPILED_IN)) {
13534
                WOLFSSL_MSG("SLH-DSA variant not compiled in");
13535
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13536
                return NOT_COMPILED_IN;
13537
            }
13538
            /* Defensive: wc_IsSlhDsaOid already implies both lookups
13539
             * succeed, but check explicitly so any future drift between the
13540
             * three OID helpers surfaces as a clean failure rather than
13541
             * undefined behaviour from casting -1 to enum SlhDsaParam. */
13542
            if (paramInt < 0 || certType < 0) {
13543
                WOLFSSL_MSG("SLH-DSA OID helper mismatch");
13544
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13545
                return WOLFSSL_FAILURE;
13546
            }
13547
13548
            slhdsa = (SlhDsaKey*)XMALLOC(sizeof(SlhDsaKey), NULL,
13549
                                          DYNAMIC_TYPE_SLHDSA);
13550
            if (slhdsa == NULL) {
13551
                WOLFSSL_MSG("Failed to allocate memory for SlhDsaKey");
13552
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13553
                return WOLFSSL_FAILURE;
13554
            }
13555
13556
            type = certType;
13557
13558
            ret = wc_SlhDsaKey_Init(slhdsa, (enum SlhDsaParam)paramInt, NULL,
13559
                                    INVALID_DEVID);
13560
            if (ret != 0) {
13561
                XFREE(slhdsa, NULL, DYNAMIC_TYPE_SLHDSA);
13562
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13563
                return ret;
13564
            }
13565
13566
            ret = wc_SlhDsaKey_PublicKeyDecode(x509->pubKey.buffer, &idx,
13567
                                               slhdsa, x509->pubKey.length);
13568
            if (ret != 0) {
13569
                WOLFSSL_ERROR_VERBOSE(ret);
13570
                wc_SlhDsaKey_Free(slhdsa);
13571
                XFREE(slhdsa, NULL, DYNAMIC_TYPE_SLHDSA);
13572
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13573
                return ret;
13574
            }
13575
            key = (void*)slhdsa;
13576
        }
13577
    #endif
13578
        if (key == NULL) {
13579
            WOLFSSL_MSG("No public key found for certificate");
13580
            XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13581
            return WOLFSSL_FAILURE;
13582
        }
13583
13584
        /* Make the body of the certificate request. */
13585
    #ifdef WOLFSSL_CERT_REQ
13586
        if (req) {
13587
            ret = wc_MakeCertReq_ex(cert, der, *derSz, type, key);
13588
        }
13589
        else
13590
    #endif
13591
        {
13592
            ret = wc_InitRng(&rng);
13593
            if (ret != 0) {
13594
                ret = WOLFSSL_FAILURE;
13595
                goto cleanup;
13596
            }
13597
13598
            ret = wc_MakeCert_ex(cert, der, *derSz, type, key, &rng);
13599
            wc_FreeRng(&rng);
13600
        }
13601
        if (ret <= 0) {
13602
            WOLFSSL_ERROR_VERBOSE(ret);
13603
            ret = WOLFSSL_FAILURE;
13604
            goto cleanup;
13605
        }
13606
13607
        if ((x509->serialSz == 0) &&
13608
                (cert->serialSz <= EXTERNAL_SERIAL_SIZE) &&
13609
                (cert->serialSz > 0)) {
13610
        #if defined(OPENSSL_EXTRA)
13611
            WOLFSSL_ASN1_INTEGER *i = wolfSSL_ASN1_INTEGER_new();
13612
13613
            if (i == NULL) {
13614
                WOLFSSL_MSG("wolfSSL_ASN1_INTEGER_new error");
13615
                ret = WOLFSSL_FAILURE;
13616
                goto cleanup;
13617
            }
13618
            else {
13619
                i->length = cert->serialSz + 2;
13620
                i->data[0] = ASN_INTEGER;
13621
                i->data[1] = (unsigned char)cert->serialSz;
13622
                XMEMCPY(i->data + 2, cert->serial, cert->serialSz);
13623
                if (wolfSSL_X509_set_serialNumber(x509, i) != WOLFSSL_SUCCESS) {
13624
                    WOLFSSL_MSG("Issue setting generated serial number");
13625
                    wolfSSL_ASN1_INTEGER_free(i);
13626
                    ret = WOLFSSL_FAILURE;
13627
                    goto cleanup;
13628
                }
13629
                wolfSSL_ASN1_INTEGER_free(i);
13630
            }
13631
        #else
13632
            WOLFSSL_MSG("ASN1_INTEGER API not in build");
13633
13634
            ret = WOLFSSL_FAILURE;
13635
            goto cleanup;
13636
        #endif /* OPENSSL_EXTRA */
13637
        }
13638
13639
        if (includeSig) {
13640
            if (!x509->sig.buffer) {
13641
                WOLFSSL_MSG("No signature buffer");
13642
                ret = WOLFSSL_FAILURE;
13643
                goto cleanup;
13644
            }
13645
            totalLen = AddSignature(NULL, ret, NULL, x509->sig.length,
13646
                                  x509->sigOID);
13647
            if (totalLen > *derSz) {
13648
                WOLFSSL_MSG("Output der buffer too short");
13649
                ret = WOLFSSL_FAILURE;
13650
                goto cleanup;
13651
            }
13652
            ret = AddSignature(der, ret, x509->sig.buffer,
13653
                               x509->sig.length, x509->sigOID);
13654
        }
13655
13656
        *derSz = ret;
13657
        ret = WOLFSSL_SUCCESS;
13658
cleanup:
13659
        /* Dispose of the public key object. */
13660
    #ifndef NO_RSA
13661
        if (x509->pubKeyOID == RSAk) {
13662
            wc_FreeRsaKey(rsa);
13663
            XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
13664
        }
13665
    #endif
13666
    #ifdef HAVE_ECC
13667
        if (x509->pubKeyOID == ECDSAk) {
13668
            wc_ecc_free(ecc);
13669
            XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
13670
        }
13671
    #endif
13672
    #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
13673
        if (x509->pubKeyOID == ED25519k) {
13674
            wolfSSL_ED25519_free(ed25519);
13675
        }
13676
    #endif
13677
    #ifndef NO_DSA
13678
        if (x509->pubKeyOID == DSAk) {
13679
            wc_FreeDsaKey(dsa);
13680
            XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
13681
        }
13682
    #endif
13683
    #if defined(HAVE_FALCON)
13684
        if ((x509->pubKeyOID == FALCON_LEVEL1k) ||
13685
            (x509->pubKeyOID == FALCON_LEVEL5k)) {
13686
            wc_falcon_free(falcon);
13687
            XFREE(falcon, NULL, DYNAMIC_TYPE_FALCON);
13688
        }
13689
    #endif
13690
    #if defined(WOLFSSL_HAVE_MLDSA)
13691
        if ((x509->pubKeyOID == ML_DSA_44k) ||
13692
            (x509->pubKeyOID == ML_DSA_65k) ||
13693
            (x509->pubKeyOID == ML_DSA_87k)
13694
        #ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
13695
         || (x509->pubKeyOID == DILITHIUM_LEVEL2k)
13696
         || (x509->pubKeyOID == DILITHIUM_LEVEL3k)
13697
         || (x509->pubKeyOID == DILITHIUM_LEVEL5k)
13698
        #endif
13699
        ) {
13700
            wc_MlDsaKey_Free(mldsa);
13701
            XFREE(mldsa, NULL, DYNAMIC_TYPE_MLDSA);
13702
        }
13703
    #endif
13704
    #if defined(WOLFSSL_HAVE_SLHDSA)
13705
        /* wc_IsSlhDsaOid returns 1 even for OIDs whose backend is
13706
         * NOT_COMPILED_IN; the early-return at the top of the SLH-DSA
13707
         * branch keeps slhdsa==NULL in that case. Guard the cleanup so
13708
         * future restructuring (a goto cleanup from inside the
13709
         * unbuilt-variant handler) cannot dereference a NULL key. */
13710
        if (wc_IsSlhDsaOid(x509->pubKeyOID) && slhdsa != NULL) {
13711
            wc_SlhDsaKey_Free(slhdsa);
13712
            XFREE(slhdsa, NULL, DYNAMIC_TYPE_SLHDSA);
13713
        }
13714
    #endif
13715
        XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13716
13717
        return ret;
13718
    }
13719
13720
13721
    /* signs a der buffer for the WOLFSSL_X509 structure using the PKEY and MD
13722
     * hash passed in
13723
     *
13724
     * WARNING: this free's and replaces the existing DER buffer in the
13725
     *          WOLFSSL_X509 with the newly signed buffer.
13726
     * returns size of signed buffer on success and negative values on fail
13727
     */
13728
    static int wolfSSL_X509_resign_cert(WOLFSSL_X509* x509, int req,
13729
            unsigned char* der, int derSz, int certBodySz, WOLFSSL_EVP_MD* md,
13730
            WOLFSSL_EVP_PKEY* pkey)
13731
    {
13732
        int ret;
13733
        void* key = NULL;
13734
        int type = -1;
13735
        int sigType;
13736
        WC_RNG rng;
13737
    #ifdef WOLFSSL_MLDSA_X509_SIGN
13738
        wc_MlDsaKey* mldsa = NULL;
13739
    #endif
13740
13741
        (void)req;
13742
        WOLFSSL_ENTER("wolfSSL_X509_resign_cert");
13743
13744
        sigType = wolfSSL_sigTypeFromPKEY(md, pkey);
13745
        if (sigType == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
13746
            WOLFSSL_MSG("Error getting signature type from pkey");
13747
            return WOLFSSL_FATAL_ERROR;
13748
        }
13749
13750
13751
        /* Get the private key object and type from pkey. */
13752
    #ifndef NO_RSA
13753
        if (pkey->type == WC_EVP_PKEY_RSA) {
13754
            type = RSA_TYPE;
13755
            key = pkey->rsa->internal;
13756
        }
13757
    #endif
13758
    #ifdef HAVE_ECC
13759
        if (pkey->type == WC_EVP_PKEY_EC) {
13760
            type = ECC_TYPE;
13761
            key = pkey->ecc->internal;
13762
        }
13763
    #endif
13764
    #ifdef WOLFSSL_MLDSA_X509_SIGN
13765
        if (pkey->type == WC_EVP_PKEY_DILITHIUM) {
13766
            /* Decode the ML-DSA private key held as DER in pkey.ptr. */
13767
            word32 idx = 0;
13768
            int oidSum = 0;
13769
            int decRet;
13770
13771
            mldsa = (wc_MlDsaKey*)XMALLOC(sizeof(wc_MlDsaKey), x509->heap,
13772
                    DYNAMIC_TYPE_MLDSA);
13773
            if (mldsa == NULL) {
13774
                WOLFSSL_MSG("Failed to allocate memory for wc_MlDsaKey");
13775
                return WOLFSSL_FATAL_ERROR;
13776
            }
13777
            if (wc_MlDsaKey_Init(mldsa, x509->heap, INVALID_DEVID) != 0) {
13778
                WOLFSSL_MSG("wc_MlDsaKey_Init error");
13779
                XFREE(mldsa, x509->heap, DYNAMIC_TYPE_MLDSA);
13780
                return WOLFSSL_FATAL_ERROR;
13781
            }
13782
            PRIVATE_KEY_UNLOCK();
13783
            decRet = wc_MlDsaKey_PrivateKeyDecode(mldsa,
13784
                    (const byte*)pkey->pkey.ptr, (word32)pkey->pkey_sz,
13785
                    &idx);
13786
            PRIVATE_KEY_LOCK();
13787
            /* Map the parameter set to its OID with mldsa_get_oid_sum():
13788
             * unlike wc_MlDsaKey_GetParams() it distinguishes FIPS204-draft
13789
             * levels. */
13790
            if (decRet != 0 ||
13791
                    mldsa_get_oid_sum(mldsa, &oidSum) != 0) {
13792
                WOLFSSL_MSG("Error decoding ML-DSA private key");
13793
                wc_MlDsaKey_Free(mldsa);
13794
                XFREE(mldsa, x509->heap, DYNAMIC_TYPE_MLDSA);
13795
                return WOLFSSL_FATAL_ERROR;
13796
            }
13797
            /* sigType above came from the cached pkey->mldsaOID; require
13798
             * the decoded key to agree so a stale cache cannot emit a
13799
             * certificate whose signatureAlgorithm disagrees with the
13800
             * actual signature. */
13801
            if (oidSum != WOLFSSL_ATOMIC_LOAD(pkey->mldsaOID)) {
13802
                WOLFSSL_MSG("ML-DSA key does not match cached pkey OID");
13803
                wc_MlDsaKey_Free(mldsa);
13804
                XFREE(mldsa, x509->heap, DYNAMIC_TYPE_MLDSA);
13805
                return WOLFSSL_FATAL_ERROR;
13806
            }
13807
            switch (oidSum) {
13808
                case ML_DSA_44k:
13809
                    type = ML_DSA_44_TYPE;
13810
                    break;
13811
                case ML_DSA_65k:
13812
                    type = ML_DSA_65_TYPE;
13813
                    break;
13814
                case ML_DSA_87k:
13815
                    type = ML_DSA_87_TYPE;
13816
                    break;
13817
            #ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
13818
                case DILITHIUM_LEVEL2k:
13819
                    type = DILITHIUM_LEVEL2_TYPE;
13820
                    break;
13821
                case DILITHIUM_LEVEL3k:
13822
                    type = DILITHIUM_LEVEL3_TYPE;
13823
                    break;
13824
                case DILITHIUM_LEVEL5k:
13825
                    type = DILITHIUM_LEVEL5_TYPE;
13826
                    break;
13827
            #endif
13828
                default:
13829
                    WOLFSSL_MSG("Unsupported ML-DSA parameter set");
13830
                    wc_MlDsaKey_Free(mldsa);
13831
                    XFREE(mldsa, x509->heap, DYNAMIC_TYPE_MLDSA);
13832
                    return WOLFSSL_FATAL_ERROR;
13833
            }
13834
            key = mldsa;
13835
        }
13836
    #endif /* WOLFSSL_MLDSA_X509_SIGN */
13837
    #if defined(HAVE_ED25519)
13838
        if (pkey->type == WC_EVP_PKEY_ED25519) {
13839
            /* Reject a missing key here, as the other Ed25519 entry points do,
13840
             * so a public-only or uninitialised EVP_PKEY fails clearly instead
13841
             * of reaching wc_SignCert_ex() with a NULL key and coming back as
13842
             * an algorithm-id error. */
13843
            if (pkey->ed25519 == NULL) {
13844
                WOLFSSL_MSG("No Ed25519 key in EVP_PKEY");
13845
                return WOLFSSL_FATAL_ERROR;
13846
            }
13847
            type = ED25519_TYPE;
13848
            key = pkey->ed25519;
13849
        }
13850
    #endif
13851
13852
        /* Sign the certificate (request) body. */
13853
        ret = wc_InitRng(&rng);
13854
        if (ret != 0) {
13855
        #ifdef WOLFSSL_MLDSA_X509_SIGN
13856
            if (mldsa != NULL) {
13857
                wc_MlDsaKey_Free(mldsa);
13858
                XFREE(mldsa, x509->heap, DYNAMIC_TYPE_MLDSA);
13859
            }
13860
        #endif
13861
            return ret;
13862
        }
13863
        ret = wc_SignCert_ex(certBodySz, sigType, der, (word32)derSz, type, key,
13864
            &rng);
13865
        wc_FreeRng(&rng);
13866
    #ifdef WOLFSSL_MLDSA_X509_SIGN
13867
        if (mldsa != NULL) {
13868
            wc_MlDsaKey_Free(mldsa);
13869
            XFREE(mldsa, x509->heap, DYNAMIC_TYPE_MLDSA);
13870
        }
13871
    #endif
13872
        if (ret < 0) {
13873
            WOLFSSL_LEAVE("wolfSSL_X509_resign_cert", ret);
13874
            return ret;
13875
        }
13876
        derSz = ret;
13877
13878
        /* Extract signature from buffer */
13879
        {
13880
            word32 idx = 0;
13881
            int    len = 0;
13882
13883
            /* Read top level sequence */
13884
            if (GetSequence(der, &idx, &len, (word32)derSz) < 0) {
13885
                WOLFSSL_MSG("GetSequence error");
13886
                return WOLFSSL_FATAL_ERROR;
13887
            }
13888
            /* Move idx to signature */
13889
            idx += certBodySz;
13890
            /* Read signature algo sequence */
13891
            if (GetSequence(der, &idx, &len, (word32)derSz) < 0) {
13892
                WOLFSSL_MSG("GetSequence error");
13893
                return WOLFSSL_FATAL_ERROR;
13894
            }
13895
            idx += len;
13896
            /* Read signature bit string */
13897
            if (CheckBitString(der, &idx, &len, (word32)derSz, 0, NULL) != 0) {
13898
                WOLFSSL_MSG("CheckBitString error");
13899
                return WOLFSSL_FATAL_ERROR;
13900
            }
13901
            /* Sanity check */
13902
            if (idx + len != (word32)derSz) {
13903
                WOLFSSL_MSG("unexpected asn1 structure");
13904
                return WOLFSSL_FATAL_ERROR;
13905
            }
13906
            x509->sig.length = 0;
13907
            if (x509->sig.buffer)
13908
                XFREE(x509->sig.buffer, x509->heap, DYNAMIC_TYPE_SIGNATURE);
13909
            x509->sig.buffer = (byte*)XMALLOC(len, x509->heap,
13910
                                              DYNAMIC_TYPE_SIGNATURE);
13911
            if (!x509->sig.buffer) {
13912
                WOLFSSL_MSG("malloc error");
13913
                return WOLFSSL_FATAL_ERROR;
13914
            }
13915
            XMEMCPY(x509->sig.buffer, der + idx, len);
13916
            x509->sig.length = (unsigned int)len;
13917
        }
13918
13919
        /* Put in the new certificate encoding into the x509 object. */
13920
        FreeDer(&x509->derCert);
13921
        type = CERT_TYPE;
13922
    #ifdef WOLFSSL_CERT_REQ
13923
        if (req) {
13924
            type = CERTREQ_TYPE;
13925
        }
13926
    #endif
13927
        if (AllocDer(&x509->derCert, (word32)derSz, type, NULL) != 0)
13928
            return WOLFSSL_FATAL_ERROR;
13929
        XMEMCPY(x509->derCert->buffer, der, derSz);
13930
        x509->derCert->length = (word32)derSz;
13931
13932
        return ret;
13933
    }
13934
13935
13936
#ifndef WC_MAX_X509_GEN
13937
    /* able to override max size until dynamic buffer created */
13938
    #define WC_MAX_X509_GEN 4096
13939
#endif
13940
#if defined(WOLFSSL_HAVE_MLDSA) && !defined(WC_MAX_X509_GEN_MLDSA)
13941
    /* Base size plus the largest compiled-in ML-DSA signature and its
13942
     * ASN.1 overhead; the subject key is added in x509_gen_buf_sz(). */
13943
    #define WC_MAX_X509_GEN_MLDSA \
13944
        (WC_MAX_X509_GEN + MLDSA_MAX_SIG_SIZE + MAX_ALGO_SZ + \
13945
         MAX_SEQ_SZ * 2)
13946
#endif
13947
13948
/* DER buffer size for certificate/CSR signing: chosen from the signing
13949
 * key type, plus the subject public key held in the x509 so that a
13950
 * large (e.g. ML-DSA) public key fits under a classic signing key too. */
13951
static int x509_gen_buf_sz(const WOLFSSL_X509* x509,
13952
    const WOLFSSL_EVP_PKEY* pkey)
13953
{
13954
    int sz = WC_MAX_X509_GEN;
13955
13956
#ifdef WOLFSSL_HAVE_MLDSA
13957
    if (pkey != NULL && pkey->type == WC_EVP_PKEY_DILITHIUM) {
13958
        sz = WC_MAX_X509_GEN_MLDSA;
13959
    }
13960
#else
13961
    (void)pkey;
13962
#endif
13963
    return sz + (int)x509->pubKey.length;
13964
}
13965
13966
/* returns the size of signature on success */
13967
int wolfSSL_X509_sign(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey,
13968
        const WOLFSSL_EVP_MD* md)
13969
{
13970
    int  ret;
13971
    byte *der = NULL;
13972
    int  bufSz = 0;
13973
    int  derSz = 0;
13974
    int  sigType;
13975
13976
    WOLFSSL_ENTER("wolfSSL_X509_sign");
13977
13978
    if (x509 == NULL || pkey == NULL) {
13979
        ret = WOLFSSL_FAILURE;
13980
        goto out;
13981
    }
13982
13983
    bufSz = x509_gen_buf_sz(x509, pkey);
13984
    derSz = bufSz;
13985
    der = (byte *)XMALLOC((size_t)bufSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13986
    if (der == NULL) {
13987
        ret = WOLFSSL_FAILURE;
13988
        goto out;
13989
    }
13990
13991
    /* Resolves the (pkey, md) combination - most key types require an explicit
13992
     * digest, Ed25519 requires a NULL one, ML-DSA ignores it - and only
13993
     * updates sigOID on success, so the object is unmodified on a rejected
13994
     * key/md combination. */
13995
    sigType = wolfSSL_sigTypeFromPKEY((WOLFSSL_EVP_MD*)md, pkey);
13996
    if (sigType == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
13997
        WOLFSSL_MSG("Unsupported key/md combination for signing");
13998
        ret = WOLFSSL_FAILURE;
13999
        goto out;
14000
    }
14001
    x509->sigOID = sigType;
14002
    if ((ret = wolfssl_x509_make_der(x509, 0, der, &derSz, 0)) !=
14003
            WOLFSSL_SUCCESS) {
14004
        WOLFSSL_MSG("Unable to make DER for X509");
14005
        WOLFSSL_LEAVE("wolfSSL_X509_sign", ret);
14006
        (void)ret;
14007
        ret = WOLFSSL_FAILURE;
14008
        goto out;
14009
    }
14010
14011
    ret = wolfSSL_X509_resign_cert(x509, 0, der, bufSz, derSz,
14012
            (WOLFSSL_EVP_MD*)md, pkey);
14013
    if (ret <= 0) {
14014
        WOLFSSL_LEAVE("wolfSSL_X509_sign", ret);
14015
        ret = WOLFSSL_FAILURE;
14016
        goto out;
14017
    }
14018
14019
out:
14020
    XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14021
14022
    return ret;
14023
}
14024
14025
#if defined(OPENSSL_EXTRA)
14026
int wolfSSL_X509_sign_ctx(WOLFSSL_X509 *x509, WOLFSSL_EVP_MD_CTX *ctx)
14027
{
14028
    WOLFSSL_ENTER("wolfSSL_X509_sign_ctx");
14029
14030
    if (!x509 || !ctx || !ctx->pctx || !ctx->pctx->pkey) {
14031
        WOLFSSL_MSG("Bad parameter");
14032
        return WOLFSSL_FAILURE;
14033
    }
14034
14035
    return wolfSSL_X509_sign(x509, ctx->pctx->pkey,
14036
        wolfSSL_EVP_MD_CTX_md(ctx));
14037
}
14038
#endif /* OPENSSL_EXTRA */
14039
#endif /* WOLFSSL_CERT_GEN */
14040
14041
14042
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
14043
    defined(OPENSSL_EXTRA_X509_SMALL) || defined(WOLFSSL_WPAS_SMALL)
14044
/* Converts from WC_NID_* value to wolfSSL value if needed.
14045
 *
14046
 * @param [in] nid  Numeric Id of a domain name component.
14047
 * @return  Domain name tag values - wolfSSL internal values.
14048
 * @return  -1 when nid isn't known.
14049
 */
14050
static int ConvertNIDToWolfSSL(int nid)
14051
{
14052
    switch (nid) {
14053
        case WC_NID_commonName : return ASN_COMMON_NAME;
14054
    #ifdef WOLFSSL_CERT_NAME_ALL
14055
        case WC_NID_name :       return ASN_NAME;
14056
        case WC_NID_givenName:   return ASN_GIVEN_NAME;
14057
        case WC_NID_dnQualifier :   return ASN_DNQUALIFIER;
14058
        case WC_NID_initials:   return ASN_INITIALS;
14059
    #endif /* WOLFSSL_CERT_NAME_ALL */
14060
        case WC_NID_surname :    return ASN_SUR_NAME;
14061
        case WC_NID_countryName: return ASN_COUNTRY_NAME;
14062
        case WC_NID_localityName: return ASN_LOCALITY_NAME;
14063
        case WC_NID_stateOrProvinceName: return ASN_STATE_NAME;
14064
        case WC_NID_streetAddress: return ASN_STREET_ADDR;
14065
        case WC_NID_organizationName: return ASN_ORG_NAME;
14066
        case WC_NID_organizationalUnitName: return ASN_ORGUNIT_NAME;
14067
        case WC_NID_emailAddress: return ASN_EMAIL_NAME;
14068
        case WC_NID_pkcs9_contentType: return ASN_CONTENT_TYPE;
14069
        case WC_NID_serialNumber: return ASN_SERIAL_NUMBER;
14070
        case WC_NID_userId: return ASN_USER_ID;
14071
        case WC_NID_x500UniqueIdentifier: return ASN_X500_UNIQUE_ID;
14072
        case WC_NID_businessCategory: return ASN_BUS_CAT;
14073
        case WC_NID_domainComponent: return ASN_DOMAIN_COMPONENT;
14074
        case WC_NID_postalCode: return ASN_POSTAL_CODE;
14075
        case WC_NID_rfc822Mailbox: return ASN_RFC822_MAILBOX;
14076
        case WC_NID_favouriteDrink: return ASN_FAVOURITE_DRINK;
14077
        default:
14078
            WOLFSSL_MSG("Attribute NID not found");
14079
            return WOLFSSL_FATAL_ERROR;
14080
    }
14081
}
14082
#endif /* OPENSSL_ALL || OPENSSL_EXTRA ||
14083
          OPENSSL_EXTRA_X509_SMALL || WOLFSSL_WPAS_SMALL*/
14084
14085
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
14086
    defined(OPENSSL_EXTRA_X509_SMALL)
14087
/* This is to convert the x509 name structure into canonical DER format     */
14088
/*  , which has the following rules:                                        */
14089
/*   convert to UTF8                                                        */
14090
/*   convert to lower case                                                  */
14091
/*   multi-spaces collapsed                                                 */
14092
/*   leading SEQUENCE header is skipped                                     */
14093
/* @param  name a pointer to X509_NAME that is to be converted              */
14094
/* @param  out  a pointer to converted data                                 */
14095
/* @return a number of converted bytes, otherwise <=0 error code            */
14096
int wolfSSL_i2d_X509_NAME_canon(WOLFSSL_X509_NAME* name, unsigned char** out)
14097
{
14098
    int  totalBytes = 0, i, idx;
14099
    byte *output, *local = NULL;
14100
    WC_DECLARE_VAR(names, EncodedName, MAX_NAME_ENTRIES, 0);
14101
14102
    if (name == NULL)
14103
        return BAD_FUNC_ARG;
14104
14105
    WC_ALLOC_VAR_EX(names, EncodedName, MAX_NAME_ENTRIES, NULL,
14106
        DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E);
14107
14108
    XMEMSET(names, 0, sizeof(EncodedName) * MAX_NAME_ENTRIES);
14109
14110
    for (i = 0; i < MAX_NAME_ENTRIES; i++) {
14111
        WOLFSSL_X509_NAME_ENTRY* entry;
14112
        int ret;
14113
14114
        entry = wolfSSL_X509_NAME_get_entry(name, i);
14115
        if (entry != NULL && entry->set >= 1) {
14116
            const char* nameStr;
14117
            WOLFSSL_ASN1_STRING* data;
14118
            WOLFSSL_ASN1_STRING* cano_data;
14119
14120
            cano_data = wolfSSL_ASN1_STRING_new();
14121
            if (cano_data == NULL) {
14122
                WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14123
                return MEMORY_E;
14124
            }
14125
14126
            data = wolfSSL_X509_NAME_ENTRY_get_data(entry);
14127
            if (data == NULL) {
14128
                WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14129
                wolfSSL_ASN1_STRING_free(cano_data);
14130
                WOLFSSL_MSG("Error getting entry data");
14131
                return WOLFSSL_FATAL_ERROR;
14132
            }
14133
            if (wolfSSL_ASN1_STRING_canon(cano_data, data) != WOLFSSL_SUCCESS) {
14134
                WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14135
                wolfSSL_ASN1_STRING_free(cano_data);
14136
                return WOLFSSL_FAILURE;
14137
            }
14138
            nameStr = (const char*)wolfSSL_ASN1_STRING_data(cano_data);
14139
14140
            /* allow for blank values in the name structure, eg OU= */
14141
            if (nameStr)
14142
            {
14143
                ret = wc_EncodeNameCanonical(&names[i], nameStr, CTC_UTF8,
14144
                    (byte)ConvertNIDToWolfSSL(entry->nid));
14145
                if (ret < 0) {
14146
                    WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14147
                    wolfSSL_ASN1_STRING_free(cano_data);
14148
                    WOLFSSL_MSG("EncodeName failed");
14149
                    return WOLFSSL_FATAL_ERROR;
14150
                }
14151
                totalBytes += ret;
14152
            }
14153
14154
            wolfSSL_ASN1_STRING_free(cano_data);
14155
        }
14156
    }
14157
14158
    if (out == NULL) {
14159
        /* If out is NULL, caller just wants length. */
14160
        WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14161
        return totalBytes;
14162
    }
14163
14164
    /* skip header */
14165
    /* check if using buffer passed in */
14166
    if (*out == NULL) {
14167
        *out = local = (unsigned char*)XMALLOC(totalBytes, NULL,
14168
                DYNAMIC_TYPE_OPENSSL);
14169
        if (*out == NULL) {
14170
            return MEMORY_E;
14171
        }
14172
    }
14173
    output = *out;
14174
    idx = 0;
14175
14176
    for (i = 0; i < MAX_NAME_ENTRIES; i++) {
14177
        if (names[i].used) {
14178
            XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
14179
            idx += names[i].totalLen;
14180
        }
14181
    }
14182
14183
    WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14184
14185
    /* used existing buffer passed in, so increment pointer */
14186
    if (local == NULL) {
14187
        *out += totalBytes;
14188
    }
14189
    return totalBytes;
14190
}
14191
#endif /* OPENSSL_ALL || OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
14192
14193
#ifdef WOLFSSL_CERT_GEN
14194
/* Guarded by either
14195
 * A) WOLFSSL_WPAS_SMALL is on or
14196
 * B) (OPENSSL_EXTRA or OPENSSL_EXTRA_X509_SMALL) + WOLFSSL_CERT_GEN +
14197
 *    (WOLFSSL_CERT_REQ or WOLFSSL_CERT_EXT or OPENSSL_EXTRA) has been
14198
 *    defined
14199
 */
14200
#if defined(WOLFSSL_WPAS_SMALL) || \
14201
    (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
14202
    defined(WOLFSSL_CERT_GEN) && \
14203
    (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT) || \
14204
     defined(OPENSSL_EXTRA))
14205
14206
/* Converts the x509 name structure into DER format.
14207
 *
14208
 * out  pointer to either a pre setup buffer or a pointer to null for
14209
 *      creating a dynamic buffer. In the case that a pre-existing buffer is
14210
 *      used out will be incremented the size of the DER buffer on success. If
14211
 *      out is NULL, the function returns the necessary output buffer length.
14212
 *
14213
 * returns the size of the buffer on success, or negative value with failure
14214
 */
14215
int wolfSSL_i2d_X509_NAME(WOLFSSL_X509_NAME* name, unsigned char** out)
14216
{
14217
    int  totalBytes = 0, i, idx;
14218
    byte temp[MAX_SEQ_SZ];
14219
    byte *output, *local = NULL;
14220
    WC_DECLARE_VAR(names, EncodedName, MAX_NAME_ENTRIES, 0);
14221
14222
    if (name == NULL)
14223
        return BAD_FUNC_ARG;
14224
14225
    WC_ALLOC_VAR_EX(names, EncodedName, MAX_NAME_ENTRIES, NULL,
14226
        DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E);
14227
14228
    XMEMSET(names, 0, sizeof(EncodedName) * MAX_NAME_ENTRIES);
14229
14230
    for (i = 0; i < MAX_NAME_ENTRIES; i++) {
14231
        WOLFSSL_X509_NAME_ENTRY* entry;
14232
        int ret;
14233
14234
        entry = wolfSSL_X509_NAME_get_entry(name, i);
14235
        if (entry != NULL && entry->set >= 1) {
14236
            const char* nameStr;
14237
            int type;
14238
            WOLFSSL_ASN1_STRING* data;
14239
14240
            data = wolfSSL_X509_NAME_ENTRY_get_data(entry);
14241
            if (data == NULL) {
14242
                WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14243
                WOLFSSL_MSG("Error getting entry data");
14244
                return WOLFSSL_FATAL_ERROR;
14245
            }
14246
14247
            nameStr = (const char*)wolfSSL_ASN1_STRING_data(data);
14248
            type    = wolfSSL_ASN1_STRING_type(data);
14249
14250
            switch (type) {
14251
                case WOLFSSL_MBSTRING_UTF8:
14252
                    type = CTC_UTF8;
14253
                    break;
14254
                case WOLFSSL_MBSTRING_ASC:
14255
                case WOLFSSL_V_ASN1_PRINTABLESTRING:
14256
                    type = CTC_PRINTABLE;
14257
                    break;
14258
                default:
14259
                    WOLFSSL_MSG(
14260
                        "Unknown encoding type conversion UTF8 by default");
14261
                    type = CTC_UTF8;
14262
            }
14263
            ret = wc_EncodeName(&names[i], nameStr, (char)type,
14264
                (byte)ConvertNIDToWolfSSL(entry->nid));
14265
            if (ret < 0) {
14266
                WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14267
                WOLFSSL_MSG("EncodeName failed");
14268
                return WOLFSSL_FATAL_ERROR;
14269
            }
14270
            totalBytes += ret;
14271
        }
14272
    }
14273
14274
    /* header */
14275
    idx = (int)SetSequence((word32)totalBytes, temp);
14276
    if (totalBytes + idx > ASN_NAME_MAX) {
14277
        WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14278
        WOLFSSL_MSG("Total Bytes is greater than ASN_NAME_MAX");
14279
        return BUFFER_E;
14280
    }
14281
14282
    if (out == NULL) {
14283
        /* If out is NULL, caller just wants length. */
14284
        totalBytes += idx;
14285
        WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14286
        return totalBytes;
14287
    }
14288
14289
    /* check if using buffer passed in */
14290
    if (*out == NULL) {
14291
        *out = local = (unsigned char*)XMALLOC(totalBytes + idx, name->heap,
14292
                DYNAMIC_TYPE_OPENSSL);
14293
        if (*out == NULL) {
14294
            return MEMORY_E;
14295
        }
14296
    }
14297
    output = *out;
14298
14299
    idx = (int)SetSequence((word32)totalBytes, output);
14300
    totalBytes += idx;
14301
    for (i = 0; i < MAX_NAME_ENTRIES; i++) {
14302
        if (names[i].used) {
14303
            XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
14304
            idx += names[i].totalLen;
14305
        }
14306
    }
14307
14308
    WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14309
14310
    /* used existing buffer passed in, so increment pointer */
14311
    if (local == NULL) {
14312
        *out += totalBytes;
14313
    }
14314
    return totalBytes;
14315
}
14316
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
14317
#endif /* WOLFSSL_CERT_GEN */
14318
14319
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) || \
14320
    defined (WOLFSSL_WPAS_SMALL)
14321
14322
    WOLFSSL_X509_NAME *wolfSSL_d2i_X509_NAME(WOLFSSL_X509_NAME **name,
14323
                                             unsigned char **in, long length)
14324
    {
14325
        WOLFSSL_X509_NAME* tmp = NULL;
14326
        WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
14327
14328
        WOLFSSL_ENTER("wolfSSL_d2i_X509_NAME");
14329
14330
        if (!in || !*in || length <= 0) {
14331
            WOLFSSL_MSG("Bad argument");
14332
            return NULL;
14333
        }
14334
14335
        WC_ALLOC_VAR_EX(cert, DecodedCert, 1, NULL, DYNAMIC_TYPE_DCERT,
14336
            return NULL);
14337
14338
        /* Set the X509_NAME buffer as the input data for cert.
14339
         * in is NOT a full certificate. Just the name. */
14340
        InitDecodedCert(cert, *in, (word32)length, NULL);
14341
14342
        /* Parse the X509 subject name */
14343
        if (GetName(cert, ASN_SUBJECT, (int)length) != 0) {
14344
            WOLFSSL_MSG("WOLFSSL_X509_NAME parse error");
14345
            goto cleanup;
14346
        }
14347
14348
        if (!(tmp = wolfSSL_X509_NAME_new_ex(cert->heap))) {
14349
            WOLFSSL_MSG("wolfSSL_X509_NAME_new_ex error");
14350
            goto cleanup;
14351
        }
14352
14353
        if (wolfSSL_X509_NAME_copy((WOLFSSL_X509_NAME*)cert->subjectName,
14354
                    tmp) != WOLFSSL_SUCCESS) {
14355
            wolfSSL_X509_NAME_free(tmp);
14356
            tmp = NULL;
14357
            goto cleanup;
14358
        }
14359
14360
        if (name)
14361
            *name = tmp;
14362
cleanup:
14363
        FreeDecodedCert(cert);
14364
        WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
14365
        return tmp;
14366
    }
14367
#endif /* OPENSSL_EXTRA || OPENSSL_ALL || WOLFSSL_WPAS_SMALL */
14368
14369
14370
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
14371
14372
    /* Compares the two X509 names. If the size of x is larger then y then a
14373
     * positive value is returned if x is smaller a negative value is returned.
14374
     * In the case that the sizes are equal a the value of strcmp between the
14375
     * two names is returned.
14376
     *
14377
     * x First name for comparison
14378
     * y Second name to compare with x
14379
     */
14380
    int wolfSSL_X509_NAME_cmp(const WOLFSSL_X509_NAME* x,
14381
            const WOLFSSL_X509_NAME* y)
14382
    {
14383
        const char* _x;
14384
        const char* _y;
14385
        WOLFSSL_ENTER("wolfSSL_X509_NAME_cmp");
14386
14387
        if (x == NULL || y == NULL) {
14388
            WOLFSSL_MSG("Bad argument passed in");
14389
            return -2;
14390
        }
14391
14392
        if (x == y) {
14393
            return 0; /* match */
14394
        }
14395
14396
        if (x->sz != y->sz) {
14397
            return x->sz - y->sz;
14398
        }
14399
14400
        /*
14401
         * If the name member is not set or is immediately null terminated then
14402
         * compare the staticName member
14403
         */
14404
        _x = (x->name && *x->name) ? x->name : x->staticName;
14405
        _y = (y->name && *y->name) ? y->name : y->staticName;
14406
14407
        return XSTRNCASECMP(_x, _y, x->sz); /* y sz is the same */
14408
    }
14409
14410
#ifndef NO_BIO
14411
14412
static WOLFSSL_X509 *loadX509orX509REQFromPemBio(WOLFSSL_BIO *bp,
14413
        WOLFSSL_X509 **x, wc_pem_password_cb *cb, void *u, int type)
14414
{
14415
    WOLFSSL_X509* x509 = NULL;
14416
#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
14417
    unsigned char* pem = NULL;
14418
    int pemSz;
14419
    long  i = 0, l, footerSz;
14420
    const char* footer = NULL;
14421
    int streaming = 0;  /* Flag to indicate if source is streaming (FIFO) */
14422
    const char* altFooter = NULL;
14423
    long altFooterSz = 0;
14424
14425
    WOLFSSL_ENTER("loadX509orX509REQFromPemBio");
14426
14427
    if (bp == NULL || (type != CERT_TYPE && type != CERTREQ_TYPE &&
14428
                       type != TRUSTED_CERT_TYPE)) {
14429
        WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_X509", BAD_FUNC_ARG);
14430
        return NULL;
14431
    }
14432
14433
    if ((l = wolfSSL_BIO_get_len(bp)) <= 0) {
14434
        /* No certificate size available - could be FIFO or other streaming
14435
         * source. Use MAX_X509_SIZE as initial buffer, will resize if needed. */
14436
        l = MAX_X509_SIZE;
14437
        streaming = 1;
14438
    }
14439
14440
    pemSz = (int)l;
14441
    pem   = (unsigned char*)XMALLOC(pemSz, 0, DYNAMIC_TYPE_PEM);
14442
    if (pem == NULL)
14443
        return NULL;
14444
    XMEMSET(pem, 0, pemSz);
14445
14446
    i = 0;
14447
    if (wc_PemGetHeaderFooter(type, NULL, &footer) != 0) {
14448
        XFREE(pem, 0, DYNAMIC_TYPE_PEM);
14449
        return NULL;
14450
    }
14451
    footerSz = (long)XSTRLEN(footer);
14452
14453
    /* For TRUSTED_CERT_TYPE, also prepare to check for regular CERT footer
14454
     * as the file might contain regular certificates instead of TRUSTED
14455
     * format */
14456
    if (type == TRUSTED_CERT_TYPE) {
14457
        wc_PemGetHeaderFooter(CERT_TYPE, NULL, &altFooter);
14458
        if (altFooter != NULL) {
14459
            altFooterSz = (long)XSTRLEN(altFooter);
14460
        }
14461
    }
14462
14463
    /* TODO: Inefficient
14464
     * reading in one byte at a time until see the footer
14465
     */
14466
    while ((l = wolfSSL_BIO_read(bp, (char *)&pem[i], 1)) == 1) {
14467
        int foundFooter = 0;
14468
        i++;
14469
        /* Check if buffer is full and we're reading from streaming source */
14470
        if (i >= pemSz && streaming) {
14471
            /* Double the buffer size for streaming sources */
14472
            int newSz = pemSz * 2;
14473
            unsigned char* newPem;
14474
14475
            /* Sanity check: don't grow beyond reasonable limit */
14476
            if (newSz > MAX_BIO_READ_BUFFER) {
14477
                WOLFSSL_MSG("PEM data too large for streaming source");
14478
                XFREE(pem, 0, DYNAMIC_TYPE_PEM);
14479
                return NULL;
14480
            }
14481
14482
            newPem = (unsigned char*)XREALLOC(pem, newSz, 0, DYNAMIC_TYPE_PEM);
14483
            if (newPem == NULL) {
14484
                WOLFSSL_MSG("Failed to resize PEM buffer");
14485
                XFREE(pem, 0, DYNAMIC_TYPE_PEM);
14486
                return NULL;
14487
            }
14488
14489
            pem = newPem;
14490
            pemSz = newSz;
14491
        }
14492
        else if (i >= pemSz) {
14493
            /* Buffer full for non-streaming source - this shouldn't happen */
14494
            break;
14495
        }
14496
14497
        /* Check for the expected footer OR alternate footer (for
14498
         * TRUSTED_CERT_TYPE) */
14499
        if (i > footerSz &&
14500
            XMEMCMP((char *)&pem[i-footerSz], footer, footerSz) == 0) {
14501
            foundFooter = 1;
14502
        }
14503
        else if (i > altFooterSz && altFooter != NULL &&
14504
            XMEMCMP((char *)&pem[i-altFooterSz], altFooter, altFooterSz) == 0) {
14505
            foundFooter = 1;
14506
        }
14507
14508
        if (foundFooter) {
14509
            if (i < pemSz && wolfSSL_BIO_read(bp, (char *)&pem[i], 1) == 1) {
14510
                /* attempt to read newline following footer */
14511
                i++;
14512
                if (i < pemSz && pem[i-1] == '\r') {
14513
                    /* found \r , Windows line ending is \r\n so try to read one
14514
                     * more byte for \n, ignoring return value */
14515
                    (void)wolfSSL_BIO_read(bp, (char *)&pem[i++], 1);
14516
                }
14517
            }
14518
            break;
14519
        }
14520
    }
14521
    if (l == 0 && i == 0) {
14522
        WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
14523
    }
14524
    if (i > pemSz) {
14525
        WOLFSSL_MSG("Error parsing PEM");
14526
    }
14527
    else {
14528
        pemSz = (int)i;
14529
    #ifdef WOLFSSL_CERT_REQ
14530
        if (type == CERTREQ_TYPE)
14531
            x509 = loadX509orX509REQFromBuffer(pem, pemSz, WOLFSSL_FILETYPE_PEM,
14532
                CERTREQ_TYPE, cb, u);
14533
        else
14534
    #endif
14535
        /* Use TRUSTED_CERT_TYPE if input was TRUSTED CERTIFICATE format,
14536
         * otherwise use CERT_TYPE for regular certificates */
14537
        if (type == TRUSTED_CERT_TYPE)
14538
            x509 = loadX509orX509REQFromBuffer(pem, pemSz, WOLFSSL_FILETYPE_PEM,
14539
                TRUSTED_CERT_TYPE, cb, u);
14540
        else
14541
            x509 = loadX509orX509REQFromBuffer(pem, pemSz, WOLFSSL_FILETYPE_PEM,
14542
                CERT_TYPE, cb, u);
14543
    }
14544
14545
    if (x != NULL) {
14546
        *x = x509;
14547
    }
14548
14549
    XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
14550
14551
#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
14552
    (void)bp;
14553
    (void)x;
14554
    (void)cb;
14555
    (void)u;
14556
14557
    return x509;
14558
}
14559
14560
14561
WC_MAYBE_UNUSED
14562
static unsigned char* ReadPemFromBioToBuffer(WOLFSSL_BIO *bp, int *pemSz)
14563
{
14564
    unsigned char* pem = NULL;
14565
14566
    WOLFSSL_ENTER("ReadPemFromBioToBuffer");
14567
14568
    if (bp == NULL || pemSz == NULL) {
14569
        WOLFSSL_LEAVE("ReadPemFromBioToBuffer", BAD_FUNC_ARG);
14570
        return NULL;
14571
    }
14572
14573
    if ((*pemSz = wolfSSL_BIO_get_len(bp)) <= 0) {
14574
        /* No certificate size available - could be FIFO or other streaming
14575
         * source. Use MAX_X509_SIZE as initial buffer, read in loop. */
14576
        int totalRead = 0;
14577
        int readSz;
14578
14579
        *pemSz = MAX_X509_SIZE;
14580
        pem = (unsigned char*)XMALLOC(*pemSz, 0, DYNAMIC_TYPE_PEM);
14581
        if (pem == NULL) {
14582
            return NULL;
14583
        }
14584
14585
        /* Read from streaming source until EOF or buffer full */
14586
        while ((readSz = wolfSSL_BIO_read(bp, pem + totalRead,
14587
                                          *pemSz - totalRead)) > 0) {
14588
            totalRead += readSz;
14589
14590
            /* If buffer is full, try to grow it */
14591
            if (totalRead >= *pemSz) {
14592
                int newSz = *pemSz * 2;
14593
                unsigned char* newPem;
14594
14595
                /* Sanity check */
14596
                if (newSz > MAX_BIO_READ_BUFFER) {
14597
                    WOLFSSL_MSG("PEM data too large for streaming source");
14598
                    XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
14599
                    return NULL;
14600
                }
14601
14602
                newPem = (unsigned char*)XREALLOC(pem, newSz, 0,
14603
                        DYNAMIC_TYPE_PEM);
14604
                if (newPem == NULL) {
14605
                    XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
14606
                    return NULL;
14607
                }
14608
                pem = newPem;
14609
                *pemSz = newSz;
14610
            }
14611
        }
14612
14613
        *pemSz = totalRead;
14614
        if (*pemSz <= 0) {
14615
            XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
14616
            return NULL;
14617
        }
14618
    }
14619
    else {
14620
        /* Known size - allocate and read */
14621
        pem = (unsigned char*)XMALLOC(*pemSz, 0, DYNAMIC_TYPE_PEM);
14622
        if (pem == NULL) {
14623
            return NULL;
14624
        }
14625
14626
        XMEMSET(pem, 0, *pemSz);
14627
14628
        *pemSz = wolfSSL_BIO_read(bp, pem, *pemSz);
14629
        if (*pemSz <= 0) {
14630
            XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
14631
            return NULL;
14632
        }
14633
    }
14634
14635
    WOLFSSL_LEAVE("ReadPemFromBioToBuffer", 0);
14636
    return pem;
14637
}
14638
14639
14640
14641
#if defined(WOLFSSL_ACERT)
14642
    WOLFSSL_X509_ACERT *wolfSSL_PEM_read_bio_X509_ACERT(WOLFSSL_BIO *bp,
14643
                                                        WOLFSSL_X509_ACERT **x,
14644
                                                        wc_pem_password_cb *cb,
14645
                                                        void *u)
14646
    {
14647
        WOLFSSL_X509_ACERT* x509 = NULL;
14648
#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
14649
        unsigned char * pem = NULL;
14650
        int             pemSz;
14651
14652
        WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509_ACERT");
14653
14654
        if (bp == NULL) {
14655
            return NULL;
14656
        }
14657
14658
        pem = ReadPemFromBioToBuffer(bp, &pemSz);
14659
        if (pem == NULL) {
14660
            return NULL;
14661
        }
14662
14663
        x509 = wolfSSL_X509_ACERT_load_certificate_buffer(pem, pemSz,
14664
                                                          WOLFSSL_FILETYPE_PEM);
14665
14666
        if (x != NULL) {
14667
            *x = x509;
14668
        }
14669
14670
        XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
14671
14672
#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
14673
        (void)bp;
14674
        (void)x;
14675
        (void)cb;
14676
        (void)u;
14677
14678
        return x509;
14679
14680
    }
14681
#endif /* WOLFSSL_ACERT */
14682
14683
    WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x,
14684
                                            wc_pem_password_cb *cb, void *u)
14685
    {
14686
        return loadX509orX509REQFromPemBio(bp, x, cb, u, CERT_TYPE);
14687
    }
14688
14689
    /*
14690
     * bp : bio to read X509 from
14691
     * x  : x509 to write to
14692
     * cb : password call back for reading PEM
14693
     * u  : password
14694
     * _AUX is for working with a trusted X509 certificate
14695
     */
14696
    WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_AUX(WOLFSSL_BIO *bp,
14697
                               WOLFSSL_X509 **x, wc_pem_password_cb *cb,
14698
                               void *u)
14699
    {
14700
        WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509_AUX");
14701
14702
        /* AUX info is; trusted/rejected uses, friendly name, private key id,
14703
         * and potentially a stack of "other" info. wolfSSL does not store
14704
         * friendly name or private key id yet in WOLFSSL_X509 for human
14705
         * readability and does not support extra trusted/rejected uses for
14706
         * root CA. Use TRUSTED_CERT_TYPE to properly parse TRUSTED CERTIFICATE
14707
         * format and strip auxiliary data. */
14708
        return loadX509orX509REQFromPemBio(bp, x, cb, u, TRUSTED_CERT_TYPE);
14709
    }
14710
14711
#ifdef WOLFSSL_CERT_REQ
14712
WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_REQ(WOLFSSL_BIO *bp, WOLFSSL_X509 **x,
14713
                                                wc_pem_password_cb *cb, void *u)
14714
{
14715
    return loadX509orX509REQFromPemBio(bp, x, cb, u, CERTREQ_TYPE);
14716
}
14717
14718
#ifndef NO_FILESYSTEM
14719
    WOLFSSL_X509* wolfSSL_PEM_read_X509_REQ(XFILE fp, WOLFSSL_X509** x,
14720
                                            wc_pem_password_cb* cb, void* u)
14721
    {
14722
        int err = 0;
14723
        WOLFSSL_X509* ret = NULL;
14724
        WOLFSSL_BIO* bio = NULL;
14725
14726
        WOLFSSL_ENTER("wolfSSL_PEM_read_X509_REQ");
14727
14728
        if (fp == XBADFILE) {
14729
            WOLFSSL_MSG("Invalid file.");
14730
            err = 1;
14731
        }
14732
14733
        if (err == 0) {
14734
            bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
14735
            if (bio == NULL) {
14736
                WOLFSSL_MSG("Failed to create new BIO with input file.");
14737
                err = 1;
14738
            }
14739
        }
14740
        if (err == 0 && wolfSSL_BIO_set_fp(bio, fp, WOLFSSL_BIO_CLOSE)
14741
                != WOLFSSL_SUCCESS) {
14742
            WOLFSSL_MSG("Failed to set BIO file pointer.");
14743
            err = 1;
14744
        }
14745
        if (err == 0) {
14746
            ret = wolfSSL_PEM_read_bio_X509_REQ(bio, x, cb, u);
14747
        }
14748
14749
        wolfSSL_BIO_free(bio);
14750
14751
        return ret;
14752
    }
14753
#endif /* !NO_FILESYSTEM */
14754
#endif /* WOLFSSL_CERT_REQ */
14755
14756
    WOLFSSL_X509_CRL *wolfSSL_PEM_read_bio_X509_CRL(WOLFSSL_BIO *bp,
14757
            WOLFSSL_X509_CRL **x, wc_pem_password_cb *cb, void *u)
14758
    {
14759
#if defined(WOLFSSL_PEM_TO_DER) && defined(HAVE_CRL)
14760
        WOLFSSL_X509_CRL* crl = NULL;
14761
14762
        WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509_CRL");
14763
14764
        /* OpenSSL's PEM_read_bio_X509_CRL skips intervening cert/key blocks
14765
         * and returns the next CRL in the stream (NULL only at EOF). Mirror
14766
         * that by looping over the per-block reader until we get a CRL or
14767
         * the BIO has nothing left to parse. */
14768
        for (;;) {
14769
            WOLFSSL_X509*      x509   = NULL;
14770
            WOLFSSL_X509_PKEY* x_pkey = NULL;
14771
            if (wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio(bp, cb,
14772
                        &x509, &crl, &x_pkey) != WOLFSSL_SUCCESS) {
14773
                break;
14774
            }
14775
            if (crl != NULL) {
14776
                break;
14777
            }
14778
            wolfSSL_X509_free(x509);
14779
            wolfSSL_X509_PKEY_free(x_pkey);
14780
        }
14781
14782
        if (x != NULL) {
14783
            if (*x != NULL && *x != crl) {
14784
                wolfSSL_X509_CRL_free(*x);
14785
            }
14786
            *x = crl;
14787
        }
14788
14789
        (void)u;
14790
14791
        return crl;
14792
#else
14793
        (void)bp;
14794
        (void)x;
14795
        (void)cb;
14796
        (void)u;
14797
14798
        return NULL;
14799
#endif
14800
    }
14801
14802
#endif /* !NO_BIO */
14803
14804
#if !defined(NO_FILESYSTEM)
14805
static void* wolfSSL_PEM_read_X509_ex(XFILE fp, void **x,
14806
    wc_pem_password_cb *cb, void *u, int type)
14807
{
14808
    unsigned char* pem = NULL;
14809
    int pemSz;
14810
    long i = 0, l;
14811
    void *newx509;
14812
    int derSz;
14813
    DerBuffer* der = NULL;
14814
14815
    WOLFSSL_ENTER("wolfSSL_PEM_read_X509");
14816
14817
    if (fp == XBADFILE) {
14818
        WOLFSSL_LEAVE("wolfSSL_PEM_read_X509", BAD_FUNC_ARG);
14819
        return NULL;
14820
    }
14821
    /* Read cert from file */
14822
    i = XFTELL(fp);
14823
    if (i < 0) {
14824
        WOLFSSL_LEAVE("wolfSSL_PEM_read_X509", BAD_FUNC_ARG);
14825
        return NULL;
14826
    }
14827
14828
    if (XFSEEK(fp, 0, XSEEK_END) != 0)
14829
        return NULL;
14830
    l = XFTELL(fp);
14831
    if (l < 0)
14832
        return NULL;
14833
    if (XFSEEK(fp, i, SEEK_SET) != 0)
14834
        return NULL;
14835
    pemSz = (int)(l - i);
14836
14837
    /* check calculated length */
14838
    if (pemSz > MAX_WOLFSSL_FILE_SIZE || pemSz <= 0) {
14839
        WOLFSSL_MSG("PEM_read_X509_ex file size error");
14840
        return NULL;
14841
    }
14842
14843
    /* allocate pem buffer */
14844
    pem = (unsigned char*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_PEM);
14845
    if (pem == NULL)
14846
        return NULL;
14847
14848
    if ((int)XFREAD((char *)pem, 1, (size_t)pemSz, fp) != pemSz)
14849
        goto err_exit;
14850
14851
    switch (type) {
14852
        case CERT_TYPE:
14853
            newx509 = (void *)wolfSSL_X509_load_certificate_buffer(pem,
14854
                pemSz, WOLFSSL_FILETYPE_PEM);
14855
            break;
14856
14857
    #ifdef HAVE_CRL
14858
        case CRL_TYPE:
14859
            if ((PemToDer(pem, pemSz, CRL_TYPE, &der, NULL, NULL, NULL)) < 0)
14860
                goto err_exit;
14861
            derSz = (int)der->length;
14862
            newx509 = (void*)wolfSSL_d2i_X509_CRL((WOLFSSL_X509_CRL **)x,
14863
                (const unsigned char *)der->buffer, derSz);
14864
            if (newx509 == NULL)
14865
                goto err_exit;
14866
            FreeDer(&der);
14867
            break;
14868
    #endif
14869
14870
        default:
14871
            goto err_exit;
14872
    }
14873
    if (x != NULL) {
14874
        *x = newx509;
14875
    }
14876
    XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
14877
    return newx509;
14878
14879
err_exit:
14880
    XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
14881
    if (der != NULL)
14882
        FreeDer(&der);
14883
14884
    /* unused */
14885
    (void)cb;
14886
    (void)u;
14887
    (void)derSz;
14888
14889
    return NULL;
14890
}
14891
14892
WOLFSSL_X509* wolfSSL_PEM_read_X509(XFILE fp, WOLFSSL_X509 **x,
14893
                                                wc_pem_password_cb *cb, void *u)
14894
{
14895
    return (WOLFSSL_X509* )wolfSSL_PEM_read_X509_ex(fp, (void **)x, cb, u,
14896
         CERT_TYPE);
14897
}
14898
14899
#if defined(HAVE_CRL)
14900
WOLFSSL_X509_CRL* wolfSSL_PEM_read_X509_CRL(XFILE fp,
14901
                        WOLFSSL_X509_CRL **crl, wc_pem_password_cb *cb, void *u)
14902
{
14903
    return (WOLFSSL_X509_CRL* )wolfSSL_PEM_read_X509_ex(fp, (void **)crl, cb, u,
14904
         CRL_TYPE);
14905
}
14906
14907
/* Store CRL to file in DER or PEM format.
14908
 * Returns WOLFSSL_SUCCESS on success, negative on failure.
14909
 */
14910
int wolfSSL_write_X509_CRL(WOLFSSL_X509_CRL* crl, const char* path, int type)
14911
{
14912
    int ret;
14913
    WOLFSSL_ENTER("wolfSSL_write_X509_CRL");
14914
    ret = StoreCRL(crl, path, type);
14915
    WOLFSSL_LEAVE("wolfSSL_write_X509_CRL", ret);
14916
    return ret;
14917
}
14918
#endif
14919
14920
#ifdef WOLFSSL_CERT_GEN
14921
#ifndef NO_BIO
14922
    int wolfSSL_PEM_write_X509(XFILE fp, WOLFSSL_X509* x)
14923
    {
14924
        int ret;
14925
        WOLFSSL_BIO* bio;
14926
14927
        if (x == NULL || fp == XBADFILE)
14928
            return 0;
14929
14930
        bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
14931
        if (bio == NULL)
14932
            return 0;
14933
14934
        if (wolfSSL_BIO_set_fp(bio, fp, WOLFSSL_BIO_NOCLOSE) != WOLFSSL_SUCCESS) {
14935
            wolfSSL_BIO_free(bio);
14936
            bio = NULL;
14937
        }
14938
14939
        ret = wolfSSL_PEM_write_bio_X509(bio, x);
14940
14941
        if (bio != NULL)
14942
            wolfSSL_BIO_free(bio);
14943
14944
        return ret;
14945
    }
14946
#endif /* !NO_BIO */
14947
#endif /* WOLFSSL_CERT_GEN */
14948
#endif /* !NO_FILESYSTEM */
14949
14950
#endif /* OPENSSL_EXTRA || OPENSSL_ALL */
14951
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
14952
14953
#ifndef NO_BIO
14954
    /* create and return a new WOLFSSL_X509_PKEY structure or NULL on failure */
14955
    static WOLFSSL_X509_PKEY* wolfSSL_X509_PKEY_new(void* heap)
14956
    {
14957
        WOLFSSL_X509_PKEY* ret;
14958
14959
        ret = (WOLFSSL_X509_PKEY*)XMALLOC(sizeof(WOLFSSL_X509_PKEY), heap,
14960
            DYNAMIC_TYPE_KEY);
14961
        if (ret != NULL) {
14962
            XMEMSET(ret, 0, sizeof(WOLFSSL_X509_PKEY));
14963
            ret->heap = heap;
14964
        }
14965
        return ret;
14966
    }
14967
#endif /* !NO_BIO */
14968
14969
14970
    /* free up all memory used by "xPkey" passed in */
14971
    void wolfSSL_X509_PKEY_free(WOLFSSL_X509_PKEY* xPkey)
14972
    {
14973
        if (xPkey != NULL) {
14974
            wolfSSL_EVP_PKEY_free(xPkey->dec_pkey);
14975
            XFREE(xPkey, xPkey->heap, DYNAMIC_TYPE_KEY);
14976
        }
14977
    }
14978
14979
14980
#ifndef NO_BIO
14981
14982
#define PEM_COMPARE_HEADER(start, end, header) \
14983
        ((end) - (start) == XSTR_SIZEOF(header) && XMEMCMP(start, header, \
14984
                XSTR_SIZEOF(header)) == 0)
14985
14986
    /**
14987
     * This read one structure from bio and returns the read structure
14988
     * in the appropriate output parameter (x509, crl, x_pkey). The
14989
     * output parameters must be set to NULL.
14990
     * @param bio    Input for reading structures
14991
     * @param cb     Password callback
14992
     * @param x509   Output
14993
     * @param crl    Output
14994
     * @param x_pkey Output
14995
     * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE otherwise
14996
     */
14997
    int wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio(
14998
            WOLFSSL_BIO* bio, wc_pem_password_cb* cb, WOLFSSL_X509** x509,
14999
            WOLFSSL_X509_CRL** crl, WOLFSSL_X509_PKEY** x_pkey)
15000
    {
15001
15002
#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
15003
        char* pem = NULL;
15004
        long  i = pem_struct_min_sz, l;
15005
        const char* header = NULL;
15006
        const char* headerEnd = NULL;
15007
        const char* footer = NULL;
15008
        const char* footerEnd = NULL;
15009
        long searchPos = 0;
15010
    #ifdef HAVE_CRL
15011
        DerBuffer* der = NULL;
15012
    #endif
15013
        WOLFSSL_BIO* pemBio = NULL;
15014
15015
        if (!bio || !x509 || *x509 || !crl || *crl || !x_pkey || *x_pkey) {
15016
            WOLFSSL_MSG("Bad input parameter or output parameters "
15017
                        "not set to a NULL value.");
15018
            return WOLFSSL_FAILURE;
15019
        }
15020
15021
        l = wolfSSL_BIO_get_len(bio);
15022
15023
        if (l < 0) {
15024
            WOLFSSL_ERROR(BAD_FUNC_ARG);
15025
            return WOLFSSL_FAILURE;
15026
        }
15027
15028
        if (l == 0) {
15029
            /* Streaming BIO (pipe/FIFO/socket): size unknown, use the cap. */
15030
            l = MAX_BIO_READ_BUFFER;
15031
        }
15032
        else if (l <= pem_struct_min_sz) {
15033
            /* No certificate in buffer */
15034
            WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
15035
            return WOLFSSL_FAILURE;
15036
        }
15037
15038
        pem = (char*)XMALLOC(l, 0, DYNAMIC_TYPE_PEM);
15039
        if (pem == NULL)
15040
            return WOLFSSL_FAILURE;
15041
15042
        if (wolfSSL_BIO_read(bio, &pem[0], pem_struct_min_sz) !=
15043
                pem_struct_min_sz) {
15044
            WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
15045
            goto err;
15046
        }
15047
15048
        /* Read the header and footer */
15049
        while (i < l && wolfSSL_BIO_read(bio, &pem[i], 1) == 1) {
15050
            i++;
15051
            if (!header) {
15052
                header = XSTRNSTR(pem + searchPos, "-----BEGIN ",
15053
                        (size_t)(i - searchPos));
15054
                if (header == NULL) {
15055
                    searchPos = i > (long)(XSTR_SIZEOF("-----BEGIN ") - 1)
15056
                        ? i - (XSTR_SIZEOF("-----BEGIN ") - 1) : 0;
15057
                }
15058
            }
15059
            else if (!headerEnd) {
15060
                headerEnd = XSTRNSTR(header + XSTR_SIZEOF("-----BEGIN "),
15061
                        "-----",
15062
                        i - (header + XSTR_SIZEOF("-----BEGIN ") - pem));
15063
                if (headerEnd) {
15064
                    headerEnd += XSTR_SIZEOF("-----");
15065
                    if (i >= l ||
15066
                            wolfSSL_BIO_read(bio, &pem[i], 1) != 1) {
15067
                        WOLFSSL_MSG("wolfSSL_BIO_read error");
15068
                        goto err;
15069
                    }
15070
                    i++;
15071
                    if (*headerEnd != '\n' && *headerEnd != '\r') {
15072
                        WOLFSSL_MSG("Missing newline after header");
15073
                        goto err;
15074
                    }
15075
                    searchPos = (long)(headerEnd - pem);
15076
                }
15077
            }
15078
            else if (!footer) {
15079
                footer = XSTRNSTR(pem + searchPos, "-----END ",
15080
                        (size_t)(i - searchPos));
15081
                if (footer == NULL) {
15082
                    if (i > (long)(XSTR_SIZEOF("-----END ") - 1))
15083
                        searchPos = i - (XSTR_SIZEOF("-----END ") - 1);
15084
                }
15085
            }
15086
            else if (!footerEnd) {
15087
                footerEnd = XSTRNSTR(footer + XSTR_SIZEOF("-----"),
15088
                        "-----",
15089
                        i - (footer + XSTR_SIZEOF("-----") - pem));
15090
                if (footerEnd) {
15091
                    footerEnd += XSTR_SIZEOF("-----");
15092
                    /* Now check that footer matches header */
15093
                    if ((headerEnd - (header + XSTR_SIZEOF("-----BEGIN "))) ==
15094
                        (footerEnd - (footer + XSTR_SIZEOF("-----END "))) &&
15095
                        XMEMCMP(header + XSTR_SIZEOF("-----BEGIN "),
15096
                                footer + XSTR_SIZEOF("-----END "),
15097
                        headerEnd - (header + XSTR_SIZEOF("-----BEGIN ")))
15098
                            != 0) {
15099
                        WOLFSSL_MSG("Header and footer don't match");
15100
                        goto err;
15101
                    }
15102
                    /* header and footer match */
15103
                    break;
15104
                }
15105
            }
15106
        }
15107
        if (!footerEnd) {
15108
            /* Only check footerEnd since it is set last */
15109
            WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
15110
            goto err;
15111
        }
15112
        else {
15113
            if (PEM_COMPARE_HEADER(header, headerEnd,
15114
                    "-----BEGIN CERTIFICATE-----")) {
15115
                /* We have a certificate */
15116
                WOLFSSL_MSG("Parsing x509 cert");
15117
                *x509 = wolfSSL_X509_load_certificate_buffer(
15118
                        (const unsigned char*) header,
15119
                        (int)(footerEnd - header), WOLFSSL_FILETYPE_PEM);
15120
                if (!*x509) {
15121
                    WOLFSSL_MSG("wolfSSL_X509_load_certificate_buffer error");
15122
                    goto err;
15123
                }
15124
            }
15125
    #ifdef HAVE_CRL
15126
            else if (PEM_COMPARE_HEADER(header, headerEnd,
15127
                        "-----BEGIN X509 CRL-----")) {
15128
                /* We have a crl */
15129
                WOLFSSL_MSG("Parsing crl");
15130
                if ((PemToDer((const unsigned char*) header,
15131
                        (long)(footerEnd - header), CRL_TYPE, &der, NULL, NULL,
15132
                        NULL)) < 0) {
15133
                    WOLFSSL_MSG("PemToDer error");
15134
                    goto err;
15135
                }
15136
                *crl = wolfSSL_d2i_X509_CRL(NULL, der->buffer, der->length);
15137
                if (!*crl) {
15138
                    WOLFSSL_MSG("wolfSSL_d2i_X509_CRL error");
15139
                    goto err;
15140
                }
15141
            }
15142
    #endif
15143
            else {
15144
                WOLFSSL_MSG("Parsing x509 key");
15145
15146
                if (!(*x_pkey = wolfSSL_X509_PKEY_new(NULL))) {
15147
                    WOLFSSL_MSG("wolfSSL_X509_PKEY_new error");
15148
                    goto err;
15149
                }
15150
15151
                if (!(pemBio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()))) {
15152
                    WOLFSSL_MSG("wolfSSL_BIO_new error");
15153
                    goto err;
15154
                }
15155
15156
                if (wolfSSL_BIO_write(pemBio, header,
15157
                        (int)(footerEnd - header)) != footerEnd - header) {
15158
                    WOLFSSL_MSG("wolfSSL_BIO_new error");
15159
                    goto err;
15160
                }
15161
15162
                if (wolfSSL_PEM_read_bio_PrivateKey(pemBio,
15163
                        &(*x_pkey)->dec_pkey, cb, NULL) == NULL) {
15164
                    WOLFSSL_MSG("wolfSSL_PEM_read_bio_PrivateKey error");
15165
                    goto err;
15166
                }
15167
15168
                wolfSSL_BIO_free(pemBio);
15169
            }
15170
        }
15171
15172
        XFREE(pem, 0, DYNAMIC_TYPE_PEM);
15173
    #ifdef HAVE_CRL
15174
        if (der)
15175
            FreeDer(&der);
15176
    #endif
15177
        return WOLFSSL_SUCCESS;
15178
err:
15179
        XFREE(pem, 0, DYNAMIC_TYPE_PEM);
15180
    #ifdef HAVE_CRL
15181
        if (der)
15182
            FreeDer(&der);
15183
    #endif
15184
        if (*x_pkey) {
15185
            wolfSSL_X509_PKEY_free(*x_pkey);
15186
            *x_pkey = NULL;
15187
        }
15188
        if (pemBio)
15189
            wolfSSL_BIO_free(pemBio);
15190
        return WOLFSSL_FAILURE;
15191
#else /* ! (WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM) */
15192
        return WOLFSSL_FAILURE;
15193
#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
15194
    }
15195
15196
#endif /* OPENSSL_EXTRA || OPENSSL_ALL */
15197
#ifdef OPENSSL_ALL
15198
15199
#ifndef NO_FILESYSTEM
15200
    WOLF_STACK_OF(WOLFSSL_X509_INFO)* wolfSSL_PEM_X509_INFO_read(
15201
            XFILE fp, WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
15202
            pem_password_cb* cb, void* u)
15203
    {
15204
        WOLFSSL_BIO* fileBio = wolfSSL_BIO_new_fp(fp, WOLFSSL_BIO_NOCLOSE);
15205
        WOLF_STACK_OF(WOLFSSL_X509_INFO)* ret = NULL;
15206
15207
        WOLFSSL_ENTER("wolfSSL_PEM_X509_INFO_read");
15208
        if (fileBio != NULL) {
15209
            ret = wolfSSL_PEM_X509_INFO_read_bio(fileBio, sk, cb, u);
15210
            wolfSSL_BIO_free(fileBio);
15211
        }
15212
        return ret;
15213
    }
15214
#endif /* !NO_FILESYSTEM */
15215
15216
    /*
15217
     * bio WOLFSSL_BIO to read certificates from
15218
     * sk  possible stack to push more X509_INFO structs to. Can be NULL
15219
     * cb  callback password for encrypted PEM certificates
15220
     * u   user input such as password
15221
     *
15222
     * returns stack on success and NULL or default stack passed in on fail
15223
     */
15224
    WOLF_STACK_OF(WOLFSSL_X509_INFO)* wolfSSL_PEM_X509_INFO_read_bio(
15225
        WOLFSSL_BIO* bio, WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
15226
        wc_pem_password_cb* cb, void* u)
15227
    {
15228
        WOLF_STACK_OF(WOLFSSL_X509_INFO)* localSk = NULL;
15229
        int ret = WOLFSSL_SUCCESS;
15230
        WOLFSSL_X509_INFO* current = NULL;
15231
        WOLFSSL_X509*      x509 = NULL;
15232
        WOLFSSL_X509_CRL*  crl  = NULL;
15233
        WOLFSSL_X509_PKEY* x_pkey = NULL;
15234
15235
        (void)u;
15236
15237
        WOLFSSL_ENTER("wolfSSL_PEM_X509_INFO_read_bio");
15238
15239
        /* attempt to use passed in stack or create a new one */
15240
        if (sk != NULL) {
15241
            localSk = sk;
15242
        }
15243
        else {
15244
            localSk = wolfSSL_sk_X509_INFO_new_null();
15245
        }
15246
        if (localSk == NULL) {
15247
            WOLFSSL_LEAVE("wolfSSL_PEM_X509_INFO_read_bio",
15248
                    MEMORY_E);
15249
            return NULL;
15250
        }
15251
15252
        /* parse through BIO and push new info's found onto stack */
15253
        while (1) {
15254
            x509 = NULL;
15255
            crl  = NULL;
15256
            x_pkey = NULL;
15257
15258
            if (wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio(bio, cb,
15259
                    &x509, &crl, &x_pkey) == WOLFSSL_SUCCESS) {
15260
                if (current == NULL ||
15261
                        (x509 && current->x509) ||
15262
                        (crl && current->crl) ||
15263
                        (x_pkey && current->x_pkey)) {
15264
                    /* Need to create new current since existing one already
15265
                     * has the member filled or this is the first successful
15266
                     * read. */
15267
                    current = wolfSSL_X509_INFO_new();
15268
                    if (current == NULL) {
15269
                        ret = MEMORY_E;
15270
                        break;
15271
                    }
15272
                    if (wolfSSL_sk_X509_INFO_push(localSk, current) <= 0) {
15273
                        wolfSSL_X509_INFO_free(current);
15274
                        current = NULL;
15275
                        ret = WOLFSSL_FAILURE;
15276
                        break;
15277
                    }
15278
                }
15279
15280
                if (x509) {
15281
                    current->x509 = x509;
15282
                }
15283
                else if (crl) {
15284
                    current->crl = crl;
15285
                }
15286
                else if (x_pkey) {
15287
                    current->x_pkey = x_pkey;
15288
                }
15289
                else {
15290
                    WOLFSSL_MSG("No output parameters set");
15291
                    ret = WOLFSSL_FAILURE;
15292
                    break;
15293
                }
15294
            }
15295
            else {
15296
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
15297
                unsigned long err;
15298
                CLEAR_ASN_NO_PEM_HEADER_ERROR(err);
15299
                if (ERR_GET_LIB(err) != ERR_LIB_PEM ||
15300
                    ERR_GET_REASON(err) != PEM_R_NO_START_LINE) {
15301
                    ret = WOLFSSL_FAILURE;
15302
                }
15303
#else
15304
                if (wolfSSL_sk_X509_INFO_num(localSk) > 0) {
15305
                    WOLFSSL_MSG("At least one X509_INFO object on stack."
15306
                                "Assuming error means EOF or no more PEM"
15307
                                "headers found.");
15308
                }
15309
                else {
15310
                    ret = WOLFSSL_FAILURE;
15311
                }
15312
#endif
15313
                break;
15314
            }
15315
        }
15316
        if (ret != WOLFSSL_SUCCESS ||
15317
                wolfSSL_sk_X509_INFO_num(localSk) == 0) {
15318
            /* current should always be pushed onto the localsk stack at this
15319
             * point. The only case when it isn't is when
15320
             * wolfSSL_sk_X509_INFO_push fails but in that case the current
15321
             * free is handled inside the loop. */
15322
            if (localSk != sk) {
15323
                wolfSSL_sk_pop_free(localSk, NULL);
15324
            }
15325
            wolfSSL_X509_free(x509);
15326
#ifdef HAVE_CRL
15327
            wolfSSL_X509_CRL_free(crl);
15328
#endif
15329
            wolfSSL_X509_PKEY_free(x_pkey);
15330
            localSk = NULL;
15331
        }
15332
        WOLFSSL_LEAVE("wolfSSL_PEM_X509_INFO_read_bio", ret);
15333
        return localSk;
15334
    }
15335
#endif /* !NO_BIO */
15336
#endif /* OPENSSL_EXTRA || OPENSSL_ALL */
15337
15338
    void wolfSSL_X509_NAME_ENTRY_free(WOLFSSL_X509_NAME_ENTRY* ne)
15339
    {
15340
        WOLFSSL_ENTER_VERBOSE("wolfSSL_X509_NAME_ENTRY_free");
15341
        if (ne != NULL) {
15342
            wolfSSL_ASN1_OBJECT_free(ne->object);
15343
            if (ne->value != NULL) {
15344
                wolfSSL_ASN1_STRING_free(ne->value);
15345
            }
15346
            XFREE(ne, NULL, DYNAMIC_TYPE_NAME_ENTRY);
15347
        }
15348
    }
15349
15350
15351
    WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_new(void)
15352
    {
15353
        WOLFSSL_X509_NAME_ENTRY* ne;
15354
15355
        ne = (WOLFSSL_X509_NAME_ENTRY*)XMALLOC(sizeof(WOLFSSL_X509_NAME_ENTRY),
15356
                NULL, DYNAMIC_TYPE_NAME_ENTRY);
15357
        if (ne != NULL) {
15358
            XMEMSET(ne, 0, sizeof(WOLFSSL_X509_NAME_ENTRY));
15359
        }
15360
15361
        return ne;
15362
    }
15363
15364
15365
    static void wolfssl_x509_name_entry_set(WOLFSSL_X509_NAME_ENTRY* ne,
15366
        int nid, int type, const unsigned char *data, int dataSz)
15367
    {
15368
        ne->nid = nid;
15369
        /* Reuse the object if already available. */
15370
        ne->object = wolfSSL_OBJ_nid2obj_ex(nid, ne->object);
15371
        if (ne->value == NULL) {
15372
            ne->value = wolfSSL_ASN1_STRING_type_new(type);
15373
        }
15374
        if (ne->value != NULL) {
15375
            if (wolfSSL_ASN1_STRING_set(ne->value, (const void*)data,
15376
                                            dataSz) == WOLFSSL_SUCCESS) {
15377
                ne->set = 1;
15378
            }
15379
            else {
15380
                /* Free the ASN1_STRING if it is not set. */
15381
                wolfSSL_ASN1_STRING_free(ne->value);
15382
                ne->value = NULL;
15383
            }
15384
        }
15385
    }
15386
15387
    /* Create a new WOLFSSL_X509_NAME_ENTRY structure based on the text passed
15388
     * in. Returns NULL on failure */
15389
    WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_create_by_txt(
15390
            WOLFSSL_X509_NAME_ENTRY **neIn, const char *txt, int type,
15391
            const unsigned char *data, int dataSz)
15392
    {
15393
        int nid = -1;
15394
        WOLFSSL_X509_NAME_ENTRY* ne = NULL;
15395
15396
        WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_create_by_txt");
15397
15398
        if (txt == NULL) {
15399
            return NULL;
15400
        }
15401
15402
        if (neIn != NULL) {
15403
            ne = *neIn;
15404
        }
15405
15406
        nid = wolfSSL_OBJ_txt2nid(txt);
15407
        if (nid == WC_NID_undef) {
15408
            WOLFSSL_MSG("Unable to find text");
15409
            ne = NULL;
15410
        }
15411
        else {
15412
            if (ne == NULL) {
15413
                ne = wolfSSL_X509_NAME_ENTRY_new();
15414
                if (ne == NULL) {
15415
                    return NULL;
15416
                }
15417
            }
15418
15419
            wolfssl_x509_name_entry_set(ne, nid, type, data, dataSz);
15420
        }
15421
15422
        return ne;
15423
    }
15424
15425
15426
    /* Creates a new entry given the NID, type, and data
15427
     * "dataSz" is number of bytes in data, if set to -1 then XSTRLEN is used
15428
     * "out" can be used to store the new entry data in an existing structure
15429
     *       if NULL then a new WOLFSSL_X509_NAME_ENTRY structure is created
15430
     * returns a pointer to WOLFSSL_X509_NAME_ENTRY on success and NULL on fail
15431
     */
15432
    WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_create_by_NID(
15433
            WOLFSSL_X509_NAME_ENTRY** out, int nid, int type,
15434
            const unsigned char* data, int dataSz)
15435
    {
15436
        WOLFSSL_X509_NAME_ENTRY* ne;
15437
15438
        WOLFSSL_ENTER_VERBOSE("wolfSSL_X509_NAME_ENTRY_create_by_NID");
15439
15440
        if (!data) {
15441
            WOLFSSL_MSG("Bad parameter");
15442
            return NULL;
15443
        }
15444
15445
        if (out == NULL || *out == NULL) {
15446
            ne = wolfSSL_X509_NAME_ENTRY_new();
15447
            if (ne == NULL) {
15448
                return NULL;
15449
            }
15450
            if (out != NULL) {
15451
                *out = ne;
15452
            }
15453
        }
15454
        else {
15455
            ne = *out;
15456
        }
15457
15458
        wolfssl_x509_name_entry_set(ne, nid, type, data, dataSz);
15459
15460
        return ne;
15461
    }
15462
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
15463
15464
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
15465
    defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
15466
    defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
15467
    defined(HAVE_POCO_LIB) || defined(WOLFSSL_HAPROXY)
15468
WOLFSSL_ASN1_OBJECT* wolfSSL_X509_NAME_ENTRY_get_object(
15469
    WOLFSSL_X509_NAME_ENTRY *ne)
15470
{
15471
    WOLFSSL_ASN1_OBJECT* object = NULL;
15472
15473
    WOLFSSL_ENTER_VERBOSE("wolfSSL_X509_NAME_ENTRY_get_object");
15474
15475
    if (ne != NULL) {
15476
        /* Create object from nid - reuse existing object if possible. */
15477
        object = wolfSSL_OBJ_nid2obj_ex(ne->nid, ne->object);
15478
        if (object != NULL) {
15479
            /* Set the object when no error. */
15480
            ne->object = object;
15481
        }
15482
    }
15483
15484
    return object;
15485
}
15486
#endif /* OPENSSL_ALL || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE ||
15487
        * HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_POCO_LIB || WOLFSSL_HAPROXY */
15488
15489
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
15490
    /* add all entry of type "nid" to the buffer "fullName" and advance "idx"
15491
     * since number of entries is small, a brute force search is used here
15492
     * returns the number of entries added
15493
     */
15494
    static int AddAllEntry(WOLFSSL_X509_NAME* name, char* fullName,
15495
            int fullNameSz, int* idx)
15496
    {
15497
        int i;
15498
        int ret = 0;
15499
15500
        for (i = 0; i < MAX_NAME_ENTRIES; i++) {
15501
            if (name->entry[i].set) {
15502
                WOLFSSL_X509_NAME_ENTRY* e;
15503
                WOLFSSL_ASN1_OBJECT* obj;
15504
15505
                int sz;
15506
                unsigned char* data;
15507
15508
                e = &name->entry[i];
15509
                obj = wolfSSL_X509_NAME_ENTRY_get_object(e);
15510
                if (obj == NULL) {
15511
                    return BAD_FUNC_ARG;
15512
                }
15513
15514
                XMEMCPY(fullName + *idx, "/", 1); *idx = *idx + 1;
15515
                sz = (int)XSTRLEN(obj->sName);
15516
                XMEMCPY(fullName + *idx, obj->sName, sz);
15517
                *idx += sz;
15518
                XMEMCPY(fullName + *idx, "=", 1); *idx = *idx + 1;
15519
15520
                data = wolfSSL_ASN1_STRING_data(e->value);
15521
                if (data != NULL) {
15522
                    sz = (int)XSTRLEN((const char*)data);
15523
                    XMEMCPY(fullName + *idx, data, sz);
15524
                    *idx += sz;
15525
                }
15526
15527
                ret++;
15528
            }
15529
        }
15530
        (void)fullNameSz;
15531
        return ret;
15532
    }
15533
15534
15535
    /* Converts a list of entries in WOLFSSL_X509_NAME struct into a string
15536
     * returns 0 on success */
15537
    static int RebuildFullName(WOLFSSL_X509_NAME* name)
15538
    {
15539
        int totalLen = 0, i, idx, entryCount = 0;
15540
15541
        if (name == NULL)
15542
            return BAD_FUNC_ARG;
15543
15544
        for (i = 0; i < MAX_NAME_ENTRIES; i++) {
15545
            if (name->entry[i].set) {
15546
                WOLFSSL_X509_NAME_ENTRY* e;
15547
                WOLFSSL_ASN1_OBJECT* obj;
15548
15549
                e = &name->entry[i];
15550
                obj = wolfSSL_X509_NAME_ENTRY_get_object(e);
15551
                if (obj == NULL)
15552
                    return BAD_FUNC_ARG;
15553
15554
                totalLen += (int)XSTRLEN(obj->sName) + 2;/*+2 for '/' and '=' */
15555
                totalLen += wolfSSL_ASN1_STRING_length(e->value);
15556
            }
15557
        }
15558
15559
        if (name->dynamicName) {
15560
            XFREE(name->name, name->heap, DYNAMIC_TYPE_X509);
15561
            name->name = name->staticName;
15562
            name->dynamicName = 0;
15563
        }
15564
15565
        if (totalLen >= ASN_NAME_MAX) {
15566
            name->name = (char*)XMALLOC(totalLen + 1, name->heap,
15567
                    DYNAMIC_TYPE_X509);
15568
            if (name->name == NULL)
15569
                return MEMORY_E;
15570
            name->dynamicName = 1;
15571
        }
15572
15573
        idx = 0;
15574
        entryCount = AddAllEntry(name, name->name, totalLen, &idx);
15575
        if (entryCount < 0)
15576
            return entryCount;
15577
15578
        name->name[idx] = '\0';
15579
        name->sz = idx + 1; /* size includes null terminator */
15580
        name->entrySz = entryCount;
15581
15582
        return 0;
15583
    }
15584
15585
    /* Copies entry into name. With it being copied freeing entry becomes the
15586
     * callers responsibility.
15587
     * returns 1 for success and 0 for error */
15588
    int wolfSSL_X509_NAME_add_entry(WOLFSSL_X509_NAME* name,
15589
            WOLFSSL_X509_NAME_ENTRY* entry, int idx, int set)
15590
    {
15591
        WOLFSSL_X509_NAME_ENTRY* current = NULL;
15592
        int ret, i;
15593
15594
        WOLFSSL_ENTER_VERBOSE("wolfSSL_X509_NAME_add_entry");
15595
15596
        if (name == NULL || entry == NULL || entry->value == NULL) {
15597
            WOLFSSL_MSG("NULL argument passed in");
15598
            return WOLFSSL_FAILURE;
15599
        }
15600
15601
        if (idx >= 0) {
15602
            /* place in specific index */
15603
15604
            if (idx >= MAX_NAME_ENTRIES) {
15605
                WOLFSSL_MSG("Error index to insert entry is larger than array");
15606
                return WOLFSSL_FAILURE;
15607
            }
15608
            i = idx;
15609
        }
15610
        else {
15611
            /* iterate through and find first open spot */
15612
            for (i = 0; i < MAX_NAME_ENTRIES; i++) {
15613
                if (name->entry[i].set == 0) { /* not set so overwritten */
15614
                    WOLFSSL_MSG_VERBOSE("Found place for name entry");
15615
                    break;
15616
                }
15617
            }
15618
15619
            if (i == MAX_NAME_ENTRIES) {
15620
                WOLFSSL_MSG("No spot found for name entry");
15621
                return WOLFSSL_FAILURE;
15622
            }
15623
        }
15624
15625
        current = &name->entry[i];
15626
        if (current->set == 0)
15627
            name->entrySz++;
15628
15629
        if (wolfSSL_X509_NAME_ENTRY_create_by_NID(&current,
15630
                            entry->nid,
15631
                            wolfSSL_ASN1_STRING_type(entry->value),
15632
                            wolfSSL_ASN1_STRING_data(entry->value),
15633
                            wolfSSL_ASN1_STRING_length(entry->value)) != NULL)
15634
        {
15635
            ret = WOLFSSL_SUCCESS;
15636
        #ifdef OPENSSL_ALL
15637
            if (name->entries == NULL) {
15638
                name->entries = wolfSSL_sk_X509_NAME_new(NULL);
15639
            }
15640
            if (wolfSSL_sk_X509_NAME_ENTRY_push(name->entries, current) <= 0) {
15641
                ret = WOLFSSL_FAILURE;
15642
            }
15643
        #endif
15644
        }
15645
        else {
15646
            ret = WOLFSSL_FAILURE;
15647
        }
15648
15649
        if (ret != WOLFSSL_SUCCESS) {
15650
            WOLFSSL_MSG("Error adding the name entry");
15651
            if (current->set == 0)
15652
                name->entrySz--;
15653
            return WOLFSSL_FAILURE;
15654
        }
15655
15656
#ifdef WOLFSSL_PYTHON
15657
        /* Set name index for OpenSSL stack index position and so Python can
15658
         * generate tuples/sets from the list. */
15659
        for (i = 0; i < MAX_NAME_ENTRIES; i++) {
15660
            if (name->entry[i].set != 0)
15661
                name->entry[i].set = i + 1;
15662
        }
15663
#endif
15664
15665
        if (RebuildFullName(name) != 0)
15666
            return WOLFSSL_FAILURE;
15667
15668
        (void)set;
15669
        return WOLFSSL_SUCCESS;
15670
    }
15671
15672
    int wolfSSL_X509_NAME_add_entry_by_txt(WOLFSSL_X509_NAME *name,
15673
                                           const char *field, int type,
15674
                                           const unsigned char *bytes, int len,
15675
                                           int loc, int set)
15676
    {
15677
        int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
15678
        int nid;
15679
        WOLFSSL_X509_NAME_ENTRY* entry;
15680
15681
        (void)type;
15682
        WOLFSSL_ENTER("wolfSSL_X509_NAME_add_entry_by_txt");
15683
15684
        if (name == NULL || field == NULL)
15685
            return WOLFSSL_FAILURE;
15686
15687
        if ((nid = wolfSSL_OBJ_txt2nid(field)) == WC_NID_undef) {
15688
            WOLFSSL_MSG("Unable convert text to NID");
15689
            return WOLFSSL_FAILURE;
15690
        }
15691
15692
        entry = wolfSSL_X509_NAME_ENTRY_create_by_NID(NULL,
15693
                  nid, type, (unsigned char*)bytes, len);
15694
        if (entry == NULL)
15695
            return WOLFSSL_FAILURE;
15696
15697
        ret = wolfSSL_X509_NAME_add_entry(name, entry, loc, set);
15698
        wolfSSL_X509_NAME_ENTRY_free(entry);
15699
15700
        return ret;
15701
    }
15702
15703
    int wolfSSL_X509_NAME_add_entry_by_NID(WOLFSSL_X509_NAME *name, int nid,
15704
                                           int type, const unsigned char *bytes,
15705
                                           int len, int loc, int set)
15706
    {
15707
        int ret;
15708
        WOLFSSL_X509_NAME_ENTRY* entry;
15709
        WOLFSSL_ENTER_VERBOSE("wolfSSL_X509_NAME_add_entry_by_NID");
15710
        entry = wolfSSL_X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes,
15711
                len);
15712
        if (entry == NULL)
15713
            return WOLFSSL_FAILURE;
15714
        ret = wolfSSL_X509_NAME_add_entry(name, entry, loc, set);
15715
        wolfSSL_X509_NAME_ENTRY_free(entry);
15716
        return ret;
15717
    }
15718
15719
    WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_delete_entry(
15720
            WOLFSSL_X509_NAME *name, int loc)
15721
    {
15722
        WOLFSSL_X509_NAME_ENTRY* ret;
15723
        WOLFSSL_ENTER("wolfSSL_X509_NAME_delete_entry");
15724
15725
        if (!name) {
15726
            WOLFSSL_MSG("Bad parameter");
15727
            return NULL;
15728
        }
15729
15730
        ret = wolfSSL_X509_NAME_get_entry(name, loc);
15731
        if (!ret) {
15732
            WOLFSSL_MSG("loc entry not found");
15733
            return NULL;
15734
        }
15735
        name->entry[loc].set = 0;
15736
#ifdef WOLFSSL_PYTHON
15737
        {
15738
            int i;
15739
            /* Set name index for OpenSSL stack index position and so Python can
15740
            * generate tuples/sets from the list. */
15741
            for (i = 0; i < MAX_NAME_ENTRIES; i++) {
15742
                if (name->entry[i].set != 0)
15743
                    name->entry[i].set = i + 1;
15744
            }
15745
        }
15746
#endif
15747
        return ret;
15748
    }
15749
15750
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
15751
15752
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN)
15753
    int wolfSSL_X509_NAME_get_index_by_OBJ(WOLFSSL_X509_NAME *name,
15754
                                           const WOLFSSL_ASN1_OBJECT *obj,
15755
                                           int idx) {
15756
        if (!name || idx >= MAX_NAME_ENTRIES ||
15757
                !obj || !obj->obj) {
15758
            return WOLFSSL_FATAL_ERROR;
15759
        }
15760
15761
        if (idx < 0) {
15762
            idx = -1;
15763
        }
15764
15765
        for (idx++; idx < MAX_NAME_ENTRIES; idx++) {
15766
            /* Find index of desired name */
15767
            if (name->entry[idx].set) {
15768
                if (XSTRLEN(obj->sName) ==
15769
                        XSTRLEN(name->entry[idx].object->sName) &&
15770
                    XSTRNCMP((const char*) obj->sName,
15771
                        name->entry[idx].object->sName, obj->objSz - 1) == 0) {
15772
                    return idx;
15773
                }
15774
            }
15775
        }
15776
        return WOLFSSL_FATAL_ERROR;
15777
    }
15778
#endif
15779
15780
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
15781
    defined(OPENSSL_EXTRA_X509_SMALL)
15782
15783
#ifdef OPENSSL_EXTRA
15784
    int wolfSSL_X509_NAME_ENTRY_set(const WOLFSSL_X509_NAME_ENTRY *ne)
15785
    {
15786
        if (ne != NULL) {
15787
            return ne->set;
15788
        }
15789
        return 0;
15790
    }
15791
#endif
15792
15793
15794
    /* returns a pointer to the internal entry at location 'loc' on success,
15795
     * a null pointer is returned in fail cases */
15796
    WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_get_entry(
15797
                                        const WOLFSSL_X509_NAME *name, int loc)
15798
    {
15799
        WOLFSSL_ENTER_VERBOSE("wolfSSL_X509_NAME_get_entry");
15800
15801
        if (name == NULL) {
15802
            return NULL;
15803
        }
15804
15805
        if (loc < 0 || loc >= MAX_NAME_ENTRIES) {
15806
            WOLFSSL_MSG("Bad argument");
15807
            return NULL;
15808
        }
15809
15810
        if (name->entry[loc].set) {
15811
            return (WOLFSSL_X509_NAME_ENTRY*)&name->entry[loc];
15812
        }
15813
        else {
15814
            return NULL;
15815
        }
15816
    }
15817
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
15818
15819
#ifdef OPENSSL_EXTRA
15820
15821
int wolfSSL_X509_check_private_key(WOLFSSL_X509 *x509, WOLFSSL_EVP_PKEY *key)
15822
{
15823
    WOLFSSL_ENTER("wolfSSL_X509_check_private_key");
15824
15825
    if (!x509 || !key) {
15826
        WOLFSSL_MSG("Bad parameter");
15827
        return WOLFSSL_FAILURE;
15828
    }
15829
15830
#ifndef NO_CHECK_PRIVATE_KEY
15831
    return wc_CheckPrivateKey((byte*)key->pkey.ptr, key->pkey_sz,
15832
            x509->pubKey.buffer, x509->pubKey.length,
15833
            (enum Key_Sum)x509->pubKeyOID, key->heap) == 1 ?
15834
                    WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
15835
#else
15836
    /* not compiled in */
15837
    return WOLFSSL_SUCCESS;
15838
#endif
15839
}
15840
15841
#endif /* OPENSSL_EXTRA */
15842
15843
#if defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL) \
15844
    || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA)
15845
#ifndef NO_BIO
15846
15847
#ifdef WOLFSSL_CERT_GEN
15848
15849
#ifdef WOLFSSL_CERT_REQ
15850
/* writes the x509 from x to the WOLFSSL_BIO bp
15851
 *
15852
 * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on fail
15853
 */
15854
int wolfSSL_PEM_write_bio_X509_REQ(WOLFSSL_BIO *bp, WOLFSSL_X509 *x)
15855
{
15856
    byte* pem;
15857
    int   pemSz = 0;
15858
    const unsigned char* der;
15859
    int derSz;
15860
    int ret;
15861
15862
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509_REQ");
15863
15864
    if (x == NULL || bp == NULL) {
15865
        return WOLFSSL_FAILURE;
15866
    }
15867
15868
    der = wolfSSL_X509_get_der(x, &derSz);
15869
    if (der == NULL) {
15870
        return WOLFSSL_FAILURE;
15871
    }
15872
15873
    /* get PEM size */
15874
    pemSz = wc_DerToPemEx(der, (word32)derSz, NULL, 0, NULL, CERTREQ_TYPE);
15875
    if (pemSz < 0) {
15876
        return WOLFSSL_FAILURE;
15877
    }
15878
15879
    /* create PEM buffer and convert from DER */
15880
    pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15881
    if (pem == NULL) {
15882
        return WOLFSSL_FAILURE;
15883
    }
15884
    if (wc_DerToPemEx(der, (word32)derSz, pem, pemSz, NULL, CERTREQ_TYPE) < 0) {
15885
        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15886
        return WOLFSSL_FAILURE;
15887
    }
15888
15889
    /* write the PEM to BIO */
15890
    ret = wolfSSL_BIO_write(bp, pem, pemSz);
15891
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15892
15893
    if (ret <= 0) return WOLFSSL_FAILURE;
15894
    return WOLFSSL_SUCCESS;
15895
}
15896
#endif /* WOLFSSL_CERT_REQ */
15897
15898
15899
/* writes the x509 from x to the WOLFSSL_BIO bp
15900
 *
15901
 * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on fail
15902
 */
15903
int wolfSSL_PEM_write_bio_X509_AUX(WOLFSSL_BIO *bp, WOLFSSL_X509 *x)
15904
{
15905
    byte* pem;
15906
    int   pemSz = 0;
15907
    const unsigned char* der;
15908
    int derSz;
15909
    int ret;
15910
15911
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509_AUX");
15912
15913
    if (bp == NULL || x == NULL) {
15914
        WOLFSSL_MSG("NULL argument passed in");
15915
        return WOLFSSL_FAILURE;
15916
    }
15917
15918
    der = wolfSSL_X509_get_der(x, &derSz);
15919
    if (der == NULL) {
15920
        return WOLFSSL_FAILURE;
15921
    }
15922
15923
    /* get PEM size */
15924
    pemSz = wc_DerToPemEx(der, (word32)derSz, NULL, 0, NULL, CERT_TYPE);
15925
    if (pemSz < 0) {
15926
        return WOLFSSL_FAILURE;
15927
    }
15928
15929
    /* create PEM buffer and convert from DER */
15930
    pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15931
    if (pem == NULL) {
15932
        return WOLFSSL_FAILURE;
15933
    }
15934
    if (wc_DerToPemEx(der, (word32)derSz, pem, pemSz, NULL, CERT_TYPE) < 0) {
15935
        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15936
        return WOLFSSL_FAILURE;
15937
    }
15938
15939
    /* write the PEM to BIO */
15940
    ret = wolfSSL_BIO_write(bp, pem, pemSz);
15941
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15942
15943
    if (ret <= 0) return WOLFSSL_FAILURE;
15944
    return WOLFSSL_SUCCESS;
15945
}
15946
15947
int wolfSSL_PEM_write_bio_X509(WOLFSSL_BIO *bio, WOLFSSL_X509 *cert)
15948
{
15949
    byte* pem = NULL;
15950
    int   pemSz = 0;
15951
    /* Get large buffer to hold cert der */
15952
    const byte* der = NULL;
15953
    int derSz = X509_BUFFER_SZ;
15954
    int ret;
15955
15956
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509");
15957
15958
    if (bio == NULL || cert == NULL) {
15959
        WOLFSSL_MSG("NULL argument passed in");
15960
        return WOLFSSL_FAILURE;
15961
    }
15962
15963
    /* Do not call wolfssl_x509_make_der() here. If we did, then need to re-sign
15964
     * because we don't know the original order of the extensions and so we must
15965
     * assume our extensions are in a different order, thus need to re-sign. */
15966
    der = wolfSSL_X509_get_der(cert, &derSz);
15967
    if (der == NULL) {
15968
        goto error;
15969
    }
15970
15971
    /* get PEM size */
15972
    pemSz = wc_DerToPemEx(der, (word32)derSz, NULL, 0, NULL, CERT_TYPE);
15973
    if (pemSz < 0) {
15974
        goto error;
15975
    }
15976
15977
    /* create PEM buffer and convert from DER */
15978
    pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15979
    if (pem == NULL) {
15980
        goto error;
15981
    }
15982
    if (wc_DerToPemEx(der, (word32)derSz, pem, pemSz, NULL, CERT_TYPE) < 0) {
15983
        goto error;
15984
    }
15985
15986
    /* write the PEM to BIO */
15987
    ret = wolfSSL_BIO_write(bio, pem, pemSz);
15988
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15989
15990
    if (ret <= 0) return WOLFSSL_FAILURE;
15991
    return WOLFSSL_SUCCESS;
15992
15993
error:
15994
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15995
    return WOLFSSL_FAILURE;
15996
}
15997
#endif /* WOLFSSL_CERT_GEN */
15998
15999
#endif /* !NO_BIO */
16000
#endif /* HAVE_LIGHTY || HAVE_STUNNEL || WOLFSSL_MYSQL_COMPATIBLE */
16001
16002
#if defined(OPENSSL_EXTRA) || defined(HAVE_STUNNEL) || \
16003
        defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY) || \
16004
        defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_OPENSSH) || \
16005
        defined(HAVE_SBLIM_SFCB)
16006
16007
WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_sk_X509_NAME_new(
16008
        WOLF_SK_COMPARE_CB(WOLFSSL_X509_NAME, cb))
16009
{
16010
    WOLFSSL_STACK* sk;
16011
    (void)cb;
16012
16013
    WOLFSSL_ENTER_VERBOSE("wolfSSL_sk_X509_NAME_new");
16014
16015
    sk = wolfSSL_sk_new_node(NULL);
16016
    if (sk != NULL) {
16017
        sk->type = STACK_TYPE_X509_NAME;
16018
    }
16019
16020
    return sk;
16021
}
16022
16023
int wolfSSL_sk_X509_NAME_num(const WOLF_STACK_OF(WOLFSSL_X509_NAME) *sk)
16024
{
16025
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_num");
16026
16027
    if (sk == NULL)
16028
        return BAD_FUNC_ARG;
16029
16030
    return (int)sk->num;
16031
}
16032
16033
/* Getter function for WOLFSSL_X509_NAME pointer
16034
 *
16035
 * sk is the stack to retrieve pointer from
16036
 * i  is the index value in stack
16037
 *
16038
 * returns a pointer to a WOLFSSL_X509_NAME structure on success and NULL on
16039
 *         fail
16040
 */
16041
WOLFSSL_X509_NAME* wolfSSL_sk_X509_NAME_value(
16042
    const WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, int i)
16043
{
16044
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_value");
16045
    return (WOLFSSL_X509_NAME*)wolfSSL_sk_value(sk, i);
16046
}
16047
16048
WOLFSSL_X509_NAME* wolfSSL_sk_X509_NAME_pop(
16049
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk)
16050
{
16051
    return (WOLFSSL_X509_NAME*)wolfSSL_sk_pop(sk);
16052
}
16053
16054
void wolfSSL_sk_X509_NAME_pop_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk,
16055
    void (*f) (WOLFSSL_X509_NAME*))
16056
{
16057
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_pop_free");
16058
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
16059
}
16060
16061
/* Free only the sk structure, NOT X509_NAME members */
16062
void wolfSSL_sk_X509_NAME_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk)
16063
{
16064
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_free");
16065
    wolfSSL_sk_free(sk);
16066
}
16067
16068
int wolfSSL_sk_X509_NAME_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk,
16069
    WOLFSSL_X509_NAME* name)
16070
{
16071
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_push");
16072
16073
    return wolfSSL_sk_push(sk, name);
16074
}
16075
16076
/* return index of found, or negative to indicate not found */
16077
int wolfSSL_sk_X509_NAME_find(const WOLF_STACK_OF(WOLFSSL_X509_NAME) *sk,
16078
    WOLFSSL_X509_NAME *name)
16079
{
16080
    int i;
16081
16082
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_find");
16083
16084
    if (sk == NULL)
16085
        return BAD_FUNC_ARG;
16086
16087
    for (i = 0; sk; i++, sk = sk->next) {
16088
        if (wolfSSL_X509_NAME_cmp(sk->data.name, name) == 0) {
16089
            return i;
16090
        }
16091
    }
16092
    return WOLFSSL_FATAL_ERROR;
16093
}
16094
16095
/* Name Entry */
16096
WOLF_STACK_OF(WOLFSSL_X509_NAME_ENTRY)* wolfSSL_sk_X509_NAME_ENTRY_new(
16097
    WOLF_SK_COMPARE_CB(WOLFSSL_X509_NAME_ENTRY, cb))
16098
{
16099
    WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL);
16100
    if (sk != NULL) {
16101
        sk->type = STACK_TYPE_X509_NAME_ENTRY;
16102
        (void)cb;
16103
    }
16104
    return sk;
16105
}
16106
16107
int wolfSSL_sk_X509_NAME_ENTRY_push(WOLF_STACK_OF(WOLFSSL_X509_NAME_ENTRY)* sk,
16108
    WOLFSSL_X509_NAME_ENTRY* name_entry)
16109
{
16110
    return wolfSSL_sk_push(sk, name_entry);
16111
}
16112
16113
WOLFSSL_X509_NAME_ENTRY* wolfSSL_sk_X509_NAME_ENTRY_value(
16114
    const WOLF_STACK_OF(WOLFSSL_X509_NAME_ENTRY)* sk, int i)
16115
{
16116
    return (WOLFSSL_X509_NAME_ENTRY*)wolfSSL_sk_value(sk, i);
16117
}
16118
16119
int wolfSSL_sk_X509_NAME_ENTRY_num(
16120
    const WOLF_STACK_OF(WOLFSSL_X509_NAME_ENTRY)* sk)
16121
{
16122
    if (sk == NULL)
16123
        return BAD_FUNC_ARG;
16124
    return (int)sk->num;
16125
}
16126
16127
void wolfSSL_sk_X509_NAME_ENTRY_free(WOLF_STACK_OF(WOLFSSL_X509_NAME_ENTRY)* sk)
16128
{
16129
    wolfSSL_sk_free(sk);
16130
}
16131
16132
#endif /* OPENSSL_EXTRA || HAVE_STUNNEL || WOLFSSL_NGINX ||
16133
            HAVE_LIGHTY || WOLFSSL_HAPROXY ||
16134
            WOLFSSL_OPENSSH || HAVE_SBLIM_SFCB */
16135
16136
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
16137
    (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
16138
    defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
16139
    defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB))
16140
16141
#if defined(OPENSSL_ALL)
16142
WOLFSSL_X509_INFO* wolfSSL_X509_INFO_new(void)
16143
{
16144
    WOLFSSL_X509_INFO* info;
16145
    info = (WOLFSSL_X509_INFO*)XMALLOC(sizeof(WOLFSSL_X509_INFO), NULL,
16146
        DYNAMIC_TYPE_X509);
16147
    if (info) {
16148
        XMEMSET(info, 0, sizeof(*info));
16149
    }
16150
    return info;
16151
}
16152
16153
void wolfSSL_X509_INFO_free(WOLFSSL_X509_INFO* info)
16154
{
16155
    if (info == NULL)
16156
        return;
16157
16158
    if (info->x509) {
16159
        wolfSSL_X509_free(info->x509);
16160
        info->x509 = NULL;
16161
    }
16162
#ifdef HAVE_CRL
16163
    if (info->crl) {
16164
        wolfSSL_X509_CRL_free(info->crl);
16165
        info->crl = NULL;
16166
    }
16167
#endif
16168
    wolfSSL_X509_PKEY_free(info->x_pkey);
16169
    info->x_pkey = NULL;
16170
16171
    XFREE(info, NULL, DYNAMIC_TYPE_X509);
16172
}
16173
#endif
16174
16175
WOLFSSL_STACK* wolfSSL_sk_X509_INFO_new_null(void)
16176
{
16177
    WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL);
16178
    if (sk) {
16179
        sk->type = STACK_TYPE_X509_INFO;
16180
    }
16181
    return sk;
16182
}
16183
16184
int wolfSSL_sk_X509_INFO_num(const WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk)
16185
{
16186
    WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_num");
16187
16188
    return wolfSSL_sk_num(sk);
16189
}
16190
16191
WOLFSSL_X509_INFO* wolfSSL_sk_X509_INFO_value(
16192
        const WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk, int i)
16193
{
16194
    WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_value");
16195
16196
    return (WOLFSSL_X509_INFO *)wolfSSL_sk_value(sk, i);
16197
}
16198
16199
WOLFSSL_X509_INFO* wolfSSL_sk_X509_INFO_pop(
16200
        WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk)
16201
{
16202
    return (WOLFSSL_X509_INFO*)wolfSSL_sk_pop(sk);
16203
}
16204
16205
#if defined(OPENSSL_ALL)
16206
void wolfSSL_sk_X509_INFO_pop_free(WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
16207
    void (*f) (WOLFSSL_X509_INFO*))
16208
{
16209
    WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_pop_free");
16210
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
16211
}
16212
16213
void wolfSSL_sk_X509_INFO_free(WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk)
16214
{
16215
    WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_free");
16216
    wolfSSL_sk_free(sk);
16217
}
16218
16219
/* Adds the WOLFSSL_X509_INFO to the stack "sk". "sk" takes control of "in" and
16220
 * tries to free it when the stack is free'd.
16221
 *
16222
 * return number of elements on success 0 on fail
16223
 */
16224
int wolfSSL_sk_X509_INFO_push(WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
16225
                                                      WOLFSSL_X509_INFO* in)
16226
{
16227
    return wolfSSL_sk_push(sk, in);
16228
}
16229
16230
/* Creates a duplicate of WOLF_STACK_OF(WOLFSSL_X509_NAME).
16231
 * Returns a new WOLF_STACK_OF(WOLFSSL_X509_NAME) or NULL on failure */
16232
WOLF_STACK_OF(WOLFSSL_X509_NAME) *wolfSSL_dup_CA_list(
16233
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk)
16234
{
16235
    int i;
16236
    const int num = wolfSSL_sk_X509_NAME_num(sk);
16237
    WOLF_STACK_OF(WOLFSSL_X509_NAME) *copy;
16238
    WOLFSSL_X509_NAME *name;
16239
16240
    WOLFSSL_ENTER("wolfSSL_dup_CA_list");
16241
16242
    copy = wolfSSL_sk_X509_NAME_new(NULL);
16243
    if (copy == NULL) {
16244
        WOLFSSL_MSG("Memory error");
16245
        return NULL;
16246
    }
16247
16248
    for (i = 0; i < num; i++) {
16249
        name = wolfSSL_X509_NAME_dup(wolfSSL_sk_X509_NAME_value(sk, i));
16250
        if (name == NULL || wolfSSL_sk_X509_NAME_push(copy, name) <= 0) {
16251
            WOLFSSL_MSG("Memory error");
16252
            wolfSSL_sk_X509_NAME_pop_free(copy, wolfSSL_X509_NAME_free);
16253
            wolfSSL_X509_NAME_free(name);
16254
            return NULL;
16255
        }
16256
    }
16257
16258
    return copy;
16259
}
16260
16261
void* wolfSSL_sk_X509_OBJECT_value(WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk,
16262
    int i)
16263
{
16264
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_value");
16265
    for (; sk != NULL && i > 0; i--)
16266
        sk = sk->next;
16267
16268
    if (i != 0 || sk == NULL)
16269
        return NULL;
16270
    return sk->data.x509_obj;
16271
}
16272
16273
int wolfSSL_sk_X509_OBJECT_num(const WOLF_STACK_OF(WOLFSSL_X509_OBJECT) *s)
16274
{
16275
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_num");
16276
    if (s) {
16277
        return (int)s->num;
16278
    }
16279
    else {
16280
        return 0;
16281
    }
16282
}
16283
16284
int wolfSSL_sk_X509_NAME_set_cmp_func(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk,
16285
    WOLF_SK_COMPARE_CB(WOLFSSL_X509_NAME, cb))
16286
{
16287
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_set_cmp_func");
16288
16289
    if (sk == NULL)
16290
        return BAD_FUNC_ARG;
16291
16292
    WOLFSSL_MSG("Stack comparison not used in wolfSSL");
16293
    (void)cb;
16294
    return 0;
16295
}
16296
#endif /* OPENSSL_ALL */
16297
16298
#ifndef NO_BIO
16299
16300
/* Helper function for X509_NAME_print_ex. Sets *buf to string for domain
16301
   name attribute based on NID. Returns size of buf */
16302
static int get_dn_attr_by_nid(int n, const char** buf)
16303
{
16304
    int len = 0;
16305
    const char *str;
16306
16307
    switch(n)
16308
    {
16309
        case WC_NID_commonName :
16310
            str = "CN";
16311
            len = 2;
16312
            break;
16313
        case WC_NID_countryName:
16314
            str = "C";
16315
            len = 1;
16316
            break;
16317
        case WC_NID_localityName:
16318
            str = "L";
16319
            len = 1;
16320
            break;
16321
        case WC_NID_stateOrProvinceName:
16322
            str = "ST";
16323
            len = 2;
16324
            break;
16325
        case WC_NID_streetAddress:
16326
            str = "street";
16327
            len = 6;
16328
            break;
16329
        case WC_NID_organizationName:
16330
            str = "O";
16331
            len = 1;
16332
            break;
16333
        case WC_NID_organizationalUnitName:
16334
            str = "OU";
16335
            len = 2;
16336
            break;
16337
        case WC_NID_postalCode:
16338
            str = "postalCode";
16339
            len = 10;
16340
            break;
16341
        case WC_NID_emailAddress:
16342
            str = "emailAddress";
16343
            len = 12;
16344
            break;
16345
        case WC_NID_surname:
16346
            str = "SN";
16347
            len = 2;
16348
            break;
16349
        case WC_NID_givenName:
16350
            str = "GN";
16351
            len = 2;
16352
            break;
16353
        case WC_NID_dnQualifier:
16354
            str = "dnQualifier";
16355
            len = 11;
16356
            break;
16357
        case WC_NID_name:
16358
            str = "name";
16359
            len = 4;
16360
            break;
16361
        case WC_NID_initials:
16362
            str = "initials";
16363
            len = 8;
16364
            break;
16365
        case WC_NID_domainComponent:
16366
            str = "DC";
16367
            len = 2;
16368
            break;
16369
        case WC_NID_pkcs9_contentType:
16370
            str = "contentType";
16371
            len = 11;
16372
            break;
16373
        case WC_NID_userId:
16374
            str = "UID";
16375
            len = 3;
16376
            break;
16377
        case WC_NID_x500UniqueIdentifier:
16378
            str = "x500UniqueIdentifier";
16379
            len = 20;
16380
            break;
16381
        case WC_NID_serialNumber:
16382
            str = "serialNumber";
16383
            len = 12;
16384
            break;
16385
        case WC_NID_title:
16386
            str = "title";
16387
            len = 5;
16388
            break;
16389
        case WC_NID_rfc822Mailbox:
16390
            str = "mail";
16391
            len = 4;
16392
            break;
16393
        default:
16394
            WOLFSSL_MSG("Attribute type not found");
16395
            str = NULL;
16396
16397
    }
16398
    if (buf != NULL)
16399
        *buf = str;
16400
    return len;
16401
}
16402
16403
/* Escape a name entry value. Mirrors OpenSSL's do_esc_char() for single
16404
 * byte characters. Only ASN1_STRFLGS_ESC_2253, ASN1_STRFLGS_ESC_CTRL and
16405
 * ASN1_STRFLGS_ESC_MSB are implemented. ASN1_STRFLGS_ESC_QUOTE does not
16406
 * quote but, as in OpenSSL, still causes the backslash to be escaped.
16407
 *
16408
 * in    - value to escape, may contain NUL bytes
16409
 * inSz  - length of in
16410
 * flags - ASN1_STRFLGS_* flags
16411
 * out   - buffer for escaped value, NULL to only get the length
16412
 *
16413
 * Returns number of bytes written, or needed when out is NULL.
16414
 */
16415
static int wolfssl_x509_name_esc_value(const char* in, int inSz,
16416
                                       unsigned long flags, char* out)
16417
{
16418
    static const char hexDigit[] = "0123456789ABCDEF";
16419
    const unsigned long escFlags = WOLFSSL_ASN1_STRFLGS_ESC_2253 |
16420
        WOLFSSL_ASN1_STRFLGS_ESC_CTRL | WOLFSSL_ASN1_STRFLGS_ESC_MSB |
16421
        WOLFSSL_ASN1_STRFLGS_ESC_QUOTE;
16422
    int i;
16423
    int outIdx = 0;
16424
16425
    for (i = 0; i < inSz; i++) {
16426
        unsigned char c = (unsigned char)in[i];
16427
        int hex = 0;
16428
        int bs = 0;
16429
16430
        if (c >= 0x80) {
16431
            hex = (flags & WOLFSSL_ASN1_STRFLGS_ESC_MSB) != 0;
16432
        }
16433
        else if ((flags & WOLFSSL_ASN1_STRFLGS_ESC_2253) &&
16434
                 (c == ',' || c == '+' || c == '"' || c == '\\' ||
16435
                  c == '<' || c == '>' || c == ';' ||
16436
                  (i == 0 && (c == ' ' || c == '#')) ||
16437
                  (i == inSz - 1 && c == ' '))) {
16438
            bs = 1;
16439
        }
16440
        else if ((flags & WOLFSSL_ASN1_STRFLGS_ESC_CTRL) &&
16441
                 (c < 0x20 || c == 0x7F)) {
16442
            hex = 1;
16443
        }
16444
        else if (c == '\\' && (flags & escFlags)) {
16445
            /* Any escaping means the escape character itself is escaped. */
16446
            bs = 1;
16447
        }
16448
16449
        if (hex) {
16450
            if (out != NULL) {
16451
                out[outIdx]     = '\\';
16452
                out[outIdx + 1] = hexDigit[c >> 4];
16453
                out[outIdx + 2] = hexDigit[c & 0x0F];
16454
            }
16455
            outIdx += 3;
16456
        }
16457
        else {
16458
            if (bs) {
16459
                if (out != NULL)
16460
                    out[outIdx] = '\\';
16461
                outIdx++;
16462
            }
16463
            if (out != NULL)
16464
                out[outIdx] = (char)c;
16465
            outIdx++;
16466
        }
16467
    }
16468
16469
    return outIdx;
16470
}
16471
16472
/*
16473
 * Print human readable version of X509_NAME to provided BIO.
16474
 *
16475
 * bio    - output BIO to place name string. Does not include null terminator.
16476
 * name   - input name to convert to string
16477
 * indent - number of indent spaces to prepend to name string, and to every
16478
 *          line with XN_FLAG_SEP_MULTILINE
16479
 * flags  - flags to control function behavior, as in OpenSSL:
16480
 *              XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_CPLUS_SPC,
16481
 *              XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MULTILINE - entry
16482
 *                                      separator, ", " when none is set
16483
 *              XN_FLAG_FN_SN, XN_FLAG_FN_LN, XN_FLAG_FN_NONE - attribute
16484
 *                                      name style, XN_FLAG_FN_OID prints
16485
 *                                      short names
16486
 *              XN_FLAG_FN_ALIGN      - pad the attribute name
16487
 *              XN_FLAG_DN_REV        - print name reversed
16488
 *              XN_FLAG_SPC_EQ        - spaces before and after '='
16489
 *              ASN1_STRFLGS_ESC_2253 - backslash escape the RFC 2253
16490
 *                                      special characters in values
16491
 *              ASN1_STRFLGS_ESC_CTRL - escape control characters as \XX
16492
 *              ASN1_STRFLGS_ESC_MSB  - escape bytes above 0x7F as \XX
16493
 *          Multi-valued RDNs are flattened: their attributes are separated
16494
 *          like RDNs.
16495
 *
16496
 * Returns WOLFSSL_SUCCESS (1) on success, WOLFSSL_FAILURE (0) on failure.
16497
 */
16498
int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name,
16499
                int indent, unsigned long flags)
16500
{
16501
    int i, count = 0;
16502
    int eqSz = 1;
16503
    const char* eqStr = "=";
16504
    int sepSz = 2;
16505
    const char* sep = ", ";
16506
    int lineIndent = 0;
16507
    int fnOpt;
16508
    int fnWidth = 0;
16509
    WOLFSSL_X509_NAME_ENTRY* ne;
16510
    WOLFSSL_ASN1_STRING* str;
16511
16512
    WOLFSSL_ENTER("wolfSSL_X509_NAME_print_ex");
16513
16514
    if ((name == NULL) || (bio == NULL))
16515
        return WOLFSSL_FAILURE;
16516
16517
    if (indent < 0)
16518
        indent = 0;
16519
16520
    switch (flags & WOLFSSL_XN_FLAG_SEP_MASK) {
16521
        case WOLFSSL_XN_FLAG_SEP_COMMA_PLUS:
16522
            sep = ",";
16523
            sepSz = 1;
16524
            break;
16525
        case WOLFSSL_XN_FLAG_SEP_SPLUS_SPC:
16526
            sep = "; ";
16527
            sepSz = 2;
16528
            break;
16529
        case WOLFSSL_XN_FLAG_SEP_MULTILINE:
16530
            sep = "\n";
16531
            sepSz = 1;
16532
            lineIndent = indent;
16533
            break;
16534
        default:
16535
            /* XN_FLAG_SEP_CPLUS_SPC or no separator flag */
16536
            break;
16537
    }
16538
16539
    if (flags & WOLFSSL_XN_FLAG_SPC_EQ) {
16540
        eqStr = " = ";
16541
        eqSz = 3;
16542
    }
16543
16544
    fnOpt = (int)(flags & WOLFSSL_XN_FLAG_FN_MASK);
16545
    if (flags & WOLFSSL_XN_FLAG_FN_ALIGN) {
16546
        if (fnOpt == WOLFSSL_XN_FLAG_FN_SN)
16547
            fnWidth = 10;
16548
        else if (fnOpt == WOLFSSL_XN_FLAG_FN_LN)
16549
            fnWidth = 25;
16550
    }
16551
16552
    for (i = 0; i < indent; i++) {
16553
        if (wolfSSL_BIO_write(bio, " ", 1) != 1)
16554
            return WOLFSSL_FAILURE;
16555
    }
16556
16557
    count = wolfSSL_X509_NAME_entry_count(name);
16558
16559
    for (i = 0; i < count; i++) {
16560
        const char* attr = NULL;
16561
        int attrSz = 0;
16562
        int padSz = 0;
16563
        int valSz;
16564
        int tmpSz;
16565
        int idx;
16566
        int j;
16567
        char* tmp;
16568
16569
        if (flags & WOLFSSL_XN_FLAG_DN_REV) {
16570
            ne = wolfSSL_X509_NAME_get_entry(name, count - i - 1);
16571
        }
16572
        else {
16573
            ne = wolfSSL_X509_NAME_get_entry(name, i);
16574
        }
16575
        if (ne == NULL)
16576
            return WOLFSSL_FAILURE;
16577
16578
        str = wolfSSL_X509_NAME_ENTRY_get_data(ne);
16579
        if (str == NULL)
16580
            return WOLFSSL_FAILURE;
16581
16582
        if (fnOpt == WOLFSSL_XN_FLAG_FN_NONE) {
16583
            /* no attribute name */
16584
        }
16585
#ifdef OPENSSL_EXTRA
16586
        else if (fnOpt == WOLFSSL_XN_FLAG_FN_LN) {
16587
            attr = wolfSSL_OBJ_nid2ln(ne->nid);
16588
            if (attr == NULL)
16589
                return WOLFSSL_FAILURE;
16590
            attrSz = (int)XSTRLEN(attr);
16591
        }
16592
#endif
16593
        else {
16594
            /* attrSz is without null terminator */
16595
            attrSz = get_dn_attr_by_nid(ne->nid, &attr);
16596
            if (attrSz == 0 || attr == NULL)
16597
                return WOLFSSL_FAILURE;
16598
        }
16599
        if (attrSz < fnWidth)
16600
            padSz = fnWidth - attrSz;
16601
16602
        /* escaping can triple the value length */
16603
        if (str->length < 0 || str->length > INT_MAX / 4)
16604
            return WOLFSSL_FAILURE;
16605
16606
        valSz = wolfssl_x509_name_esc_value(str->data, str->length, flags,
16607
                                            NULL);
16608
16609
        /* attribute, padding, '=', value and separator, +1 for empty */
16610
        tmpSz = attrSz + padSz + eqSz + valSz + sepSz + 1;
16611
        tmp = (char*)XMALLOC((size_t)tmpSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16612
        if (tmp == NULL)
16613
            return WOLFSSL_FAILURE;
16614
16615
        idx = 0;
16616
        if (fnOpt != WOLFSSL_XN_FLAG_FN_NONE) {
16617
            XMEMCPY(tmp, attr, (size_t)attrSz);
16618
            idx = attrSz;
16619
            XMEMSET(tmp + idx, ' ', (size_t)padSz);
16620
            idx += padSz;
16621
            XMEMCPY(tmp + idx, eqStr, (size_t)eqSz);
16622
            idx += eqSz;
16623
        }
16624
        (void)wolfssl_x509_name_esc_value(str->data, str->length, flags,
16625
                                          tmp + idx);
16626
        idx += valSz;
16627
        if (i < count - 1) {
16628
            XMEMCPY(tmp + idx, sep, (size_t)sepSz);
16629
            idx += sepSz;
16630
        }
16631
16632
        if (wolfSSL_BIO_write(bio, tmp, idx) != idx) {
16633
            XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16634
            return WOLFSSL_FAILURE;
16635
        }
16636
16637
        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16638
16639
        if (i < count - 1) {
16640
            for (j = 0; j < lineIndent; j++) {
16641
                if (wolfSSL_BIO_write(bio, " ", 1) != 1)
16642
                    return WOLFSSL_FAILURE;
16643
            }
16644
        }
16645
    }
16646
16647
    return WOLFSSL_SUCCESS;
16648
}
16649
16650
#ifndef NO_FILESYSTEM
16651
int wolfSSL_X509_NAME_print_ex_fp(XFILE file, WOLFSSL_X509_NAME* name,
16652
        int indent, unsigned long flags)
16653
{
16654
    WOLFSSL_BIO* bio;
16655
    int ret;
16656
16657
    WOLFSSL_ENTER("wolfSSL_X509_NAME_print_ex_fp");
16658
16659
    if (!(bio = wolfSSL_BIO_new_fp(file, WOLFSSL_BIO_NOCLOSE))) {
16660
        WOLFSSL_MSG("wolfSSL_BIO_new_fp error");
16661
        return WOLFSSL_FAILURE;
16662
    }
16663
16664
    ret = wolfSSL_X509_NAME_print_ex(bio, name, indent, flags);
16665
16666
    wolfSSL_BIO_free(bio);
16667
16668
    return ret;
16669
}
16670
#endif /* NO_FILESYSTEM */
16671
#endif /* !NO_BIO */
16672
16673
#ifndef NO_WOLFSSL_STUB
16674
WOLFSSL_ASN1_BIT_STRING* wolfSSL_X509_get0_pubkey_bitstr(const WOLFSSL_X509* x)
16675
{
16676
    (void)x;
16677
    WOLFSSL_ENTER("wolfSSL_X509_get0_pubkey_bitstr");
16678
    WOLFSSL_STUB("X509_get0_pubkey_bitstr");
16679
16680
    return NULL;
16681
}
16682
#endif
16683
16684
#ifdef OPENSSL_ALL
16685
WOLFSSL_X509_LOOKUP_TYPE wolfSSL_X509_OBJECT_get_type(
16686
        const WOLFSSL_X509_OBJECT* obj)
16687
{
16688
    if (obj == NULL)
16689
        return WOLFSSL_X509_LU_NONE;
16690
    return obj->type;
16691
}
16692
16693
WOLFSSL_X509_OBJECT* wolfSSL_X509_OBJECT_new(void)
16694
{
16695
    WOLFSSL_X509_OBJECT* ret = (WOLFSSL_X509_OBJECT*)
16696
            XMALLOC(sizeof(WOLFSSL_X509_OBJECT), NULL, DYNAMIC_TYPE_OPENSSL);
16697
    if (ret != NULL)
16698
        XMEMSET(ret, 0, sizeof(WOLFSSL_X509_OBJECT));
16699
    return ret;
16700
}
16701
16702
void wolfSSL_X509_OBJECT_free(WOLFSSL_X509_OBJECT *obj)
16703
{
16704
    WOLFSSL_ENTER("wolfSSL_X509_OBJECT_free");
16705
    if (obj != NULL) {
16706
        if (obj->type == WOLFSSL_X509_LU_X509) {
16707
            wolfSSL_X509_free(obj->data.x509);
16708
        }
16709
    #ifdef HAVE_CRL
16710
        else if (obj->type == WOLFSSL_X509_LU_CRL) {
16711
            wolfSSL_X509_CRL_free(obj->data.crl);
16712
        }
16713
    #endif
16714
        else {
16715
            /* We don't free as this will point to
16716
             * store->cm->crl which we don't own */
16717
            WOLFSSL_MSG("Not free'ing CRL in WOLFSSL_X509_OBJECT");
16718
        }
16719
        XFREE(obj, NULL, DYNAMIC_TYPE_OPENSSL);
16720
    }
16721
}
16722
16723
WOLFSSL_X509_OBJECT *wolfSSL_X509_OBJECT_retrieve_by_subject(
16724
        WOLF_STACK_OF(WOLFSSL_X509_OBJECT) *sk,
16725
        WOLFSSL_X509_LOOKUP_TYPE type,
16726
        WOLFSSL_X509_NAME *name)
16727
{
16728
    int i;
16729
16730
    WOLFSSL_ENTER("wolfSSL_X509_OBJECT_retrieve_by_subject");
16731
16732
    if (sk == NULL || name == NULL)
16733
        return NULL;
16734
16735
    for (i = 0; i < wolfSSL_sk_X509_OBJECT_num(sk); i++) {
16736
        WOLFSSL_X509_OBJECT* obj = (WOLFSSL_X509_OBJECT *)
16737
            wolfSSL_sk_X509_OBJECT_value(sk, i);
16738
        if (obj != NULL && obj->type == type &&
16739
            wolfSSL_X509_NAME_cmp(
16740
                wolfSSL_X509_get_subject_name(obj->data.x509), name) == 0)
16741
            return obj;
16742
    }
16743
    return NULL;
16744
}
16745
#endif /* OPENSSL_ALL */
16746
16747
#ifndef NO_WOLFSSL_STUB
16748
WOLFSSL_X509_OBJECT* wolfSSL_sk_X509_OBJECT_delete(
16749
    WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk, int i)
16750
{
16751
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_delete");
16752
    WOLFSSL_STUB("wolfSSL_sk_X509_OBJECT_delete");
16753
    (void)sk;
16754
    (void)i;
16755
    return NULL;
16756
}
16757
#endif
16758
16759
WOLFSSL_X509 *wolfSSL_X509_OBJECT_get0_X509(const WOLFSSL_X509_OBJECT *obj)
16760
{
16761
    if (obj != NULL && obj->type == WOLFSSL_X509_LU_X509)
16762
        return obj->data.x509;
16763
    return NULL;
16764
}
16765
16766
WOLFSSL_X509_CRL *wolfSSL_X509_OBJECT_get0_X509_CRL(WOLFSSL_X509_OBJECT *obj)
16767
{
16768
    if (obj != NULL && obj->type == WOLFSSL_X509_LU_CRL)
16769
        return obj->data.crl;
16770
    return NULL;
16771
}
16772
16773
#endif /* OPENSSL_ALL || (OPENSSL_EXTRA && (HAVE_STUNNEL || WOLFSSL_NGINX ||
16774
        * HAVE_LIGHTY || WOLFSSL_HAPROXY || WOLFSSL_OPENSSH ||
16775
        * HAVE_SBLIM_SFCB)) */
16776
16777
16778
#if defined(OPENSSL_EXTRA)
16779
16780
int wolfSSL_sk_X509_num(const WOLF_STACK_OF(WOLFSSL_X509) *s)
16781
{
16782
    WOLFSSL_ENTER("wolfSSL_sk_X509_num");
16783
16784
    if (s == NULL)
16785
        return WOLFSSL_FATAL_ERROR;
16786
    return (int)s->num;
16787
}
16788
16789
#endif /* OPENSSL_EXTRA */
16790
16791
#ifdef HAVE_EX_DATA_CRYPTO
16792
int wolfSSL_X509_get_ex_new_index(int idx, void *arg,
16793
                                  WOLFSSL_CRYPTO_EX_new* new_func,
16794
                                  WOLFSSL_CRYPTO_EX_dup* dup_func,
16795
                                  WOLFSSL_CRYPTO_EX_free* free_func)
16796
{
16797
    WOLFSSL_ENTER("wolfSSL_X509_get_ex_new_index");
16798
16799
    return wolfssl_local_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_X509, idx, arg,
16800
                                    new_func, dup_func, free_func);
16801
}
16802
#endif
16803
16804
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
16805
void *wolfSSL_X509_get_ex_data(WOLFSSL_X509 *x509, int idx)
16806
{
16807
    WOLFSSL_ENTER("wolfSSL_X509_get_ex_data");
16808
#ifdef HAVE_EX_DATA
16809
    if (x509 != NULL) {
16810
        return wolfSSL_CRYPTO_get_ex_data(&x509->ex_data, idx);
16811
    }
16812
#else
16813
    (void)x509;
16814
    (void)idx;
16815
#endif
16816
    return NULL;
16817
}
16818
16819
int wolfSSL_X509_set_ex_data(WOLFSSL_X509 *x509, int idx, void *data)
16820
{
16821
    WOLFSSL_ENTER("wolfSSL_X509_set_ex_data");
16822
#ifdef HAVE_EX_DATA
16823
    if (x509 != NULL) {
16824
        return wolfSSL_CRYPTO_set_ex_data(&x509->ex_data, idx, data);
16825
    }
16826
#else
16827
    (void)x509;
16828
    (void)idx;
16829
    (void)data;
16830
#endif
16831
    return WOLFSSL_FAILURE;
16832
}
16833
16834
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
16835
int wolfSSL_X509_set_ex_data_with_cleanup(
16836
    WOLFSSL_X509 *x509,
16837
    int idx,
16838
    void *data,
16839
    wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
16840
{
16841
    WOLFSSL_ENTER("wolfSSL_X509_set_ex_data_with_cleanup");
16842
    if (x509 != NULL)
16843
    {
16844
        return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&x509->ex_data, idx,
16845
                                                       data, cleanup_routine);
16846
    }
16847
    return WOLFSSL_FAILURE;
16848
}
16849
#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
16850
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
16851
16852
16853
#ifndef NO_ASN
16854
int wolfSSL_X509_check_host(WOLFSSL_X509 *x, const char *chk, size_t chklen,
16855
                    unsigned int flags, char **peername)
16856
0
{
16857
0
    int         ret;
16858
0
    size_t      i;
16859
0
    WC_DECLARE_VAR(dCert, DecodedCert, 1, 0);
16860
16861
0
    WOLFSSL_ENTER("wolfSSL_X509_check_host");
16862
16863
    /* flags and peername not needed for Nginx. */
16864
0
    (void)peername;
16865
16866
0
    if ((x == NULL) || (chk == NULL)) {
16867
0
        WOLFSSL_MSG("Invalid parameter");
16868
0
        return WOLFSSL_FAILURE;
16869
0
    }
16870
16871
0
    if (flags & WOLFSSL_NO_WILDCARDS) {
16872
0
        WOLFSSL_MSG("X509_CHECK_FLAG_NO_WILDCARDS not yet implemented");
16873
0
        return WOLFSSL_FAILURE;
16874
0
    }
16875
0
    if (flags & WOLFSSL_NO_PARTIAL_WILDCARDS) {
16876
0
        WOLFSSL_MSG("X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS not yet implemented");
16877
0
        return WOLFSSL_FAILURE;
16878
0
    }
16879
0
    if (flags & WOLFSSL_MULTI_LABEL_WILDCARDS) {
16880
0
        WOLFSSL_MSG("X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS not yet implemented");
16881
0
        return WOLFSSL_FAILURE;
16882
0
    }
16883
16884
#ifdef WOLFSSL_SMALL_STACK
16885
    dCert = (DecodedCert *)XMALLOC(sizeof(*dCert), x->heap,
16886
                                   DYNAMIC_TYPE_DCERT);
16887
    if (dCert == NULL) {
16888
        WOLFSSL_MSG("\tout of memory");
16889
        return WOLFSSL_FATAL_ERROR;
16890
    }
16891
#endif
16892
16893
0
    InitDecodedCert(dCert, x->derCert->buffer, x->derCert->length, NULL);
16894
0
    ret = ParseCertRelative(dCert, CERT_TYPE, 0, NULL, NULL);
16895
0
    if (ret != 0) {
16896
0
        goto out;
16897
0
    }
16898
16899
    /* Replicate openssl behavior for checklen */
16900
0
    if (chklen == 0) {
16901
0
        chklen = (size_t)(XSTRLEN(chk));
16902
0
    }
16903
0
    else {
16904
0
        for (i = 0; i < (chklen > 1 ? chklen - 1 : chklen); i++) {
16905
0
            if (chk[i] == '\0') {
16906
0
                ret = WOLFSSL_FATAL_ERROR;
16907
0
                goto out;
16908
0
            }
16909
0
        }
16910
0
    }
16911
0
    if (chklen > 1 && (chk[chklen - 1] == '\0')) {
16912
0
        chklen--;
16913
0
    }
16914
16915
#ifdef WOLFSSL_IP_ALT_NAME
16916
    ret = CheckIPAddr(dCert, (char *)chk, chklen);
16917
    if (ret == 0) {
16918
        goto out;
16919
    }
16920
#endif /* WOLFSSL_IP_ALT_NAME */
16921
16922
0
    ret = CheckHostName(dCert, (char *)chk, chklen, flags, 0);
16923
16924
0
out:
16925
16926
0
    FreeDecodedCert(dCert);
16927
0
    WC_FREE_VAR_EX(dCert, x->heap, DYNAMIC_TYPE_DCERT);
16928
16929
0
    if (ret != 0)
16930
0
        return WOLFSSL_FAILURE;
16931
0
    return WOLFSSL_SUCCESS;
16932
0
}
16933
16934
16935
int wolfSSL_X509_check_ip_asc(WOLFSSL_X509 *x, const char *ipasc,
16936
        unsigned int flags)
16937
0
{
16938
0
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
16939
0
    WC_DECLARE_VAR(dCert, DecodedCert, 1, 0);
16940
16941
0
    WOLFSSL_ENTER("wolfSSL_X509_check_ip_asc");
16942
16943
    /* flags not yet implemented */
16944
0
    (void)flags;
16945
16946
0
    if ((x == NULL) || (x->derCert == NULL) || (ipasc == NULL)) {
16947
0
        WOLFSSL_MSG("Invalid parameter");
16948
0
    }
16949
0
    else {
16950
0
        ret = WOLFSSL_SUCCESS;
16951
0
    }
16952
16953
#ifdef WOLFSSL_SMALL_STACK
16954
    if (ret == WOLFSSL_SUCCESS) {
16955
        dCert = (DecodedCert *)XMALLOC(sizeof(*dCert), x->heap,
16956
                                       DYNAMIC_TYPE_DCERT);
16957
        if (dCert == NULL) {
16958
            WOLFSSL_MSG("\tout of memory");
16959
            ret = WOLFSSL_FAILURE;
16960
        }
16961
    }
16962
#endif
16963
16964
0
    if (ret == WOLFSSL_SUCCESS) {
16965
0
        InitDecodedCert(dCert, x->derCert->buffer, x->derCert->length, NULL);
16966
0
        ret = ParseCertRelative(dCert, CERT_TYPE, 0, NULL, NULL);
16967
0
        if (ret != 0) {
16968
0
            ret = WOLFSSL_FAILURE;
16969
0
        }
16970
0
        else {
16971
0
            ret = CheckIPAddr(dCert, ipasc, (size_t)XSTRLEN(ipasc));
16972
0
            if (ret != 0) {
16973
0
                ret = WOLFSSL_FAILURE;
16974
0
            }
16975
0
            else {
16976
0
                ret = WOLFSSL_SUCCESS;
16977
0
            }
16978
0
        }
16979
0
        FreeDecodedCert(dCert);
16980
0
    }
16981
16982
#ifdef WOLFSSL_SMALL_STACK
16983
    if (x != NULL) {
16984
        XFREE(dCert, x->heap, DYNAMIC_TYPE_DCERT);
16985
    }
16986
#endif
16987
16988
0
    return ret;
16989
0
}
16990
#endif
16991
16992
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN)
16993
int wolfSSL_X509_check_email(WOLFSSL_X509 *x, const char *chk, size_t chkLen,
16994
                             unsigned int flags)
16995
{
16996
    WOLFSSL_X509_NAME *subjName;
16997
    int emailLen;
16998
    char *emailBuf;
16999
17000
    (void)flags;
17001
17002
    WOLFSSL_ENTER("wolfSSL_X509_check_email");
17003
17004
    if ((x == NULL) || (chk == NULL)) {
17005
        WOLFSSL_MSG("Invalid parameter");
17006
        return WOLFSSL_FAILURE;
17007
    }
17008
17009
    subjName = wolfSSL_X509_get_subject_name(x);
17010
    if (subjName == NULL)
17011
        return WOLFSSL_FAILURE;
17012
17013
    /* Call with NULL buffer to get required length. */
17014
    emailLen = wolfSSL_X509_NAME_get_text_by_NID(subjName, WC_NID_emailAddress,
17015
                                                 NULL, 0);
17016
    if (emailLen < 0)
17017
        return WOLFSSL_FAILURE;
17018
17019
    ++emailLen; /* Add 1 for the NUL. */
17020
17021
    emailBuf = (char*)XMALLOC(emailLen, x->heap, DYNAMIC_TYPE_OPENSSL);
17022
    if (emailBuf == NULL)
17023
        return WOLFSSL_FAILURE;
17024
17025
    emailLen = wolfSSL_X509_NAME_get_text_by_NID(subjName, WC_NID_emailAddress,
17026
                                                 emailBuf, emailLen);
17027
    if (emailLen < 0) {
17028
        XFREE(emailBuf, x->heap, DYNAMIC_TYPE_OPENSSL);
17029
        return WOLFSSL_FAILURE;
17030
    }
17031
17032
    if (chkLen == 0)
17033
        chkLen = XSTRLEN(chk);
17034
17035
    if (chkLen != (size_t)emailLen
17036
     || XSTRNCMP(chk, emailBuf, chkLen)) {
17037
        XFREE(emailBuf, x->heap, DYNAMIC_TYPE_OPENSSL);
17038
        return WOLFSSL_FAILURE;
17039
    }
17040
17041
    XFREE(emailBuf, x->heap, DYNAMIC_TYPE_OPENSSL);
17042
    return WOLFSSL_SUCCESS;
17043
}
17044
#endif /* OPENSSL_EXTRA && WOLFSSL_CERT_GEN */
17045
17046
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \
17047
    || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY)
17048
17049
int wolfSSL_X509_NAME_digest(const WOLFSSL_X509_NAME *name,
17050
        const WOLFSSL_EVP_MD *type, unsigned char *md, unsigned int *len)
17051
{
17052
    WOLFSSL_ENTER("wolfSSL_X509_NAME_digest");
17053
17054
    if (name == NULL || type == NULL)
17055
        return WOLFSSL_FAILURE;
17056
17057
/* wolfSSL_EVP_Digest() is only compiled with these defines. */
17058
#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL)
17059
    return wolfSSL_EVP_Digest((unsigned char*)name->name,
17060
                              name->sz, md, len, type, NULL);
17061
#else
17062
    (void)md;
17063
    (void)len;
17064
    return NOT_COMPILED_IN;
17065
#endif
17066
}
17067
17068
#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY ||
17069
    OPENSSL_EXTRA || HAVE_LIGHTY */
17070
17071
#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
17072
    defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
17073
17074
void wolfSSL_X509_email_free(WOLF_STACK_OF(WOLFSSL_STRING) *sk)
17075
{
17076
    wolfSSL_sk_pop_free(sk, NULL);
17077
}
17078
17079
static int x509_aia_append_string(WOLFSSL_STACK* list, const byte* uri,
17080
        word32 uriSz)
17081
{
17082
    WOLFSSL_STRING url = (WOLFSSL_STRING)XMALLOC(uriSz + 1, NULL,
17083
            DYNAMIC_TYPE_OPENSSL);
17084
    if (url == NULL)
17085
        return -1;
17086
    XMEMCPY(url, uri, uriSz);
17087
    url[uriSz] = '\0';
17088
17089
    if (wolfSSL_sk_push(list, url) <= 0) {
17090
        XFREE(url, NULL, DYNAMIC_TYPE_OPENSSL);
17091
        return -1;
17092
    }
17093
17094
    return 0;
17095
}
17096
17097
static WOLFSSL_STACK* x509_get1_aia_by_method(WOLFSSL_X509* x, word32 method,
17098
    const byte* fallback, int fallbackSz)
17099
{
17100
    WOLFSSL_STACK* ret = NULL;
17101
    int i;
17102
17103
    if (x == NULL)
17104
        return NULL;
17105
17106
    ret = wolfSSL_sk_WOLFSSL_STRING_new();
17107
    if (ret == NULL)
17108
        return NULL;
17109
17110
    /* Build from multi-entry list when available; otherwise fall back to the
17111
     * legacy single-entry fields to preserve previous behavior. */
17112
    if (x->authInfoListSz > 0) {
17113
        for (i = 0; i < x->authInfoListSz; i++) {
17114
            if (x->authInfoList[i].method != method ||
17115
                    x->authInfoList[i].uri == NULL ||
17116
                    x->authInfoList[i].uriSz == 0) {
17117
                continue;
17118
            }
17119
17120
            if (x509_aia_append_string(ret, x->authInfoList[i].uri,
17121
                    x->authInfoList[i].uriSz) != 0) {
17122
                wolfSSL_X509_email_free(ret);
17123
                return NULL;
17124
            }
17125
        }
17126
    }
17127
    /* Only use fallback when nothing was found in the list */
17128
    if (wolfSSL_sk_num(ret) == 0 && fallback != NULL && fallbackSz > 0) {
17129
        if (x509_aia_append_string(ret, fallback, (word32)fallbackSz) != 0) {
17130
            wolfSSL_X509_email_free(ret);
17131
            return NULL;
17132
        }
17133
    }
17134
17135
    /* Return NULL when empty */
17136
    if (wolfSSL_sk_num(ret) == 0) {
17137
        wolfSSL_X509_email_free(ret);
17138
        ret = NULL;
17139
    }
17140
17141
    return ret;
17142
}
17143
17144
WOLF_STACK_OF(WOLFSSL_STRING) *wolfSSL_X509_get1_ocsp(WOLFSSL_X509 *x)
17145
{
17146
    if (x == NULL)
17147
        return NULL;
17148
    return x509_get1_aia_by_method(x, AIA_OCSP_OID, x->authInfo, x->authInfoSz);
17149
}
17150
17151
int wolfSSL_X509_get_aia_overflow(WOLFSSL_X509 *x)
17152
{
17153
    int overflow = 0;
17154
17155
    WOLFSSL_ENTER("wolfSSL_X509_get_aia_overflow");
17156
17157
    if (x != NULL) {
17158
        overflow = x->authInfoListOverflow;
17159
    }
17160
17161
    WOLFSSL_LEAVE("wolfSSL_X509_get_aia_overflow", overflow);
17162
17163
    return overflow;
17164
}
17165
17166
#ifdef WOLFSSL_ASN_CA_ISSUER
17167
WOLF_STACK_OF(WOLFSSL_STRING) *wolfSSL_X509_get1_ca_issuers(WOLFSSL_X509 *x)
17168
{
17169
    if (x == NULL)
17170
        return NULL;
17171
    return x509_get1_aia_by_method(x, AIA_CA_ISSUER_OID, x->authInfoCaIssuer,
17172
            x->authInfoCaIssuerSz);
17173
}
17174
#endif /* WOLFSSL_ASN_CA_ISSUER */
17175
17176
int wolfSSL_X509_check_issued(WOLFSSL_X509 *issuer, WOLFSSL_X509 *subject)
17177
{
17178
    WOLFSSL_X509_NAME *issuerName = wolfSSL_X509_get_issuer_name(subject);
17179
    WOLFSSL_X509_NAME *subjectName = wolfSSL_X509_get_subject_name(issuer);
17180
17181
    if (issuerName == NULL || subjectName == NULL)
17182
        return WOLFSSL_X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
17183
17184
    /* Literal matching of encoded names and key ids. */
17185
    if (issuerName->sz != subjectName->sz ||
17186
           XMEMCMP(issuerName->name, subjectName->name, subjectName->sz) != 0) {
17187
        return WOLFSSL_X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
17188
    }
17189
17190
    if (subject->authKeyId != NULL && issuer->subjKeyId != NULL) {
17191
        if (subject->authKeyIdSz != issuer->subjKeyIdSz ||
17192
                XMEMCMP(subject->authKeyId, issuer->subjKeyId,
17193
                        issuer->subjKeyIdSz) != 0) {
17194
            return WOLFSSL_X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
17195
        }
17196
    }
17197
17198
    return WOLFSSL_X509_V_OK;
17199
}
17200
17201
#endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */
17202
17203
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
17204
    defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
17205
WOLFSSL_X509* wolfSSL_X509_dup(WOLFSSL_X509 *x)
17206
{
17207
    WOLFSSL_ENTER("wolfSSL_X509_dup");
17208
17209
    if (x == NULL) {
17210
        WOLFSSL_MSG("Error: NULL input");
17211
        return NULL;
17212
    }
17213
17214
    if (x->derCert == NULL) {
17215
        WOLFSSL_MSG("Error: NULL derCert parameter");
17216
        return NULL;
17217
    }
17218
17219
    return wolfSSL_X509_d2i_ex(NULL, x->derCert->buffer, x->derCert->length,
17220
        x->heap);
17221
}
17222
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || KEEP_PEER_CERT || \
17223
          SESSION_CERTS */
17224
17225
#if defined(OPENSSL_EXTRA)
17226
int wolfSSL_X509_check_ca(WOLFSSL_X509 *x509)
17227
{
17228
    WOLFSSL_ENTER("wolfSSL_X509_check_ca");
17229
17230
    if (x509 == NULL)
17231
        return WOLFSSL_FAILURE;
17232
    if (x509->isCa)
17233
        return 1;
17234
    if (x509->extKeyUsageCrit)
17235
        return 4;
17236
17237
    return 0;
17238
}
17239
#endif /* OPENSSL_EXTRA */
17240
17241
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
17242
long wolfSSL_X509_get_version(const WOLFSSL_X509 *x509)
17243
{
17244
    int version = 0;
17245
17246
    WOLFSSL_ENTER("wolfSSL_X509_get_version");
17247
17248
    if (x509 == NULL) {
17249
        WOLFSSL_MSG("invalid parameter");
17250
        return 0L;
17251
    }
17252
    version = x509->version;
17253
    if (version != 0)
17254
        return (long)version - 1L;
17255
17256
    return 0L;
17257
}
17258
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
17259
17260
#if defined(OPENSSL_EXTRA)
17261
int wolfSSL_X509_get_signature_nid(const WOLFSSL_X509 *x)
17262
{
17263
    if (x == NULL)
17264
        return 0;
17265
17266
    return oid2nid((word32)x->sigOID, oidSigType);
17267
}
17268
#endif  /* OPENSSL_EXTRA */
17269
17270
#if defined(OPENSSL_EXTRA)
17271
WOLFSSL_STACK* wolfSSL_sk_X509_new(WOLF_SK_COMPARE_CB(WOLFSSL_X509, cb))
17272
{
17273
    (void)cb;
17274
    return wolfSSL_sk_X509_new_null();
17275
}
17276
17277
WOLFSSL_STACK* wolfSSL_sk_X509_new_null(void)
17278
{
17279
    WOLFSSL_STACK* s = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
17280
            DYNAMIC_TYPE_OPENSSL);
17281
    if (s != NULL) {
17282
        XMEMSET(s, 0, sizeof(*s));
17283
        s->type = STACK_TYPE_X509;
17284
    }
17285
17286
    return s;
17287
}
17288
#endif  /* OPENSSL_EXTRA */
17289
17290
#ifdef OPENSSL_ALL
17291
17292
WOLFSSL_STACK* wolfSSL_sk_X509_OBJECT_new(void)
17293
{
17294
    WOLFSSL_STACK* s = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
17295
            DYNAMIC_TYPE_OPENSSL);
17296
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_new");
17297
    if (s != NULL) {
17298
        XMEMSET(s, 0, sizeof(*s));
17299
        s->type = STACK_TYPE_X509_OBJ;
17300
    }
17301
    return s;
17302
}
17303
17304
void wolfSSL_sk_X509_OBJECT_free(WOLFSSL_STACK* s)
17305
{
17306
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_free");
17307
    wolfSSL_sk_free(s);
17308
}
17309
17310
void wolfSSL_sk_X509_OBJECT_pop_free(WOLFSSL_STACK* s,
17311
        void (*f) (WOLFSSL_X509_OBJECT*))
17312
{
17313
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_pop_free");
17314
    wolfSSL_sk_pop_free(s, (wolfSSL_sk_freefunc)f);
17315
}
17316
17317
int wolfSSL_sk_X509_OBJECT_push(WOLFSSL_STACK* sk, WOLFSSL_X509_OBJECT* obj)
17318
{
17319
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_push");
17320
17321
    if (sk == NULL || obj == NULL) {
17322
        return WOLFSSL_FAILURE;
17323
    }
17324
17325
    return wolfSSL_sk_push(sk, obj);
17326
}
17327
17328
#endif /* OPENSSL_ALL */
17329
17330
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
17331
/* unlike wolfSSL_X509_NAME_dup this does not malloc a duplicate, only deep
17332
 * copy. "to" is expected to be a fresh blank name, if not pointers could be
17333
 * lost */
17334
int wolfSSL_X509_NAME_copy(const WOLFSSL_X509_NAME* from, WOLFSSL_X509_NAME* to)
17335
{
17336
    int i;
17337
17338
    WOLFSSL_ENTER("wolfSSL_X509_NAME_copy");
17339
17340
    if (from == NULL || to == NULL) {
17341
        WOLFSSL_MSG("NULL parameter");
17342
        return BAD_FUNC_ARG;
17343
    }
17344
17345
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY)
17346
    if (from->rawLen > 0) {
17347
        if (from->rawLen > ASN_NAME_MAX) {
17348
            WOLFSSL_MSG("Bad raw size");
17349
            return BAD_FUNC_ARG;
17350
        }
17351
        XMEMCPY(to->raw, from->raw, from->rawLen);
17352
        to->rawLen = from->rawLen;
17353
    }
17354
#endif
17355
17356
    if (from->dynamicName) {
17357
        to->name = (char*)XMALLOC(from->sz, to->heap, DYNAMIC_TYPE_SUBJECT_CN);
17358
        if (to->name == NULL)
17359
            return WOLFSSL_FAILURE;
17360
        to->dynamicName = 1;
17361
    }
17362
    XMEMCPY(to->name, from->name, from->sz);
17363
    to->sz = from->sz;
17364
17365
    for (i = 0; i < MAX_NAME_ENTRIES; i++) {
17366
        WOLFSSL_X509_NAME_ENTRY* ne = wolfSSL_X509_NAME_get_entry(from, i);
17367
        if (ne != NULL) {
17368
            if (wolfSSL_X509_NAME_add_entry(to, ne, i, 1) != WOLFSSL_SUCCESS) {
17369
                return WOLFSSL_FAILURE;
17370
            }
17371
        }
17372
    }
17373
    to->entrySz = from->entrySz;
17374
    return WOLFSSL_SUCCESS;
17375
}
17376
17377
17378
/* copies over information from "name" to the "cert" subject name
17379
 * returns WOLFSSL_SUCCESS on success */
17380
int wolfSSL_X509_set_subject_name(WOLFSSL_X509 *cert, WOLFSSL_X509_NAME *name)
17381
{
17382
    WOLFSSL_ENTER("wolfSSL_X509_set_subject_name");
17383
    if (cert == NULL || name == NULL)
17384
        return WOLFSSL_FAILURE;
17385
17386
    FreeX509Name(&cert->subject);
17387
    InitX509Name(&cert->subject, 0, cert->heap);
17388
17389
    if (wolfSSL_X509_NAME_copy(name, &cert->subject) != WOLFSSL_SUCCESS) {
17390
        FreeX509Name(&cert->subject);
17391
        return WOLFSSL_FAILURE;
17392
    }
17393
17394
    cert->subject.x509 = cert;
17395
    return WOLFSSL_SUCCESS;
17396
}
17397
17398
17399
/* copies over information from "name" to the "cert" issuer name
17400
 * returns WOLFSSL_SUCCESS on success */
17401
int wolfSSL_X509_set_issuer_name(WOLFSSL_X509 *cert, WOLFSSL_X509_NAME *name)
17402
{
17403
    WOLFSSL_ENTER("wolfSSL_X509_set_issuer_name");
17404
    if (cert == NULL || name == NULL)
17405
        return WOLFSSL_FAILURE;
17406
17407
    FreeX509Name(&cert->issuer);
17408
    InitX509Name(&cert->issuer, 0, cert->heap);
17409
17410
    if (wolfSSL_X509_NAME_copy(name, &cert->issuer) != WOLFSSL_SUCCESS) {
17411
        FreeX509Name(&cert->issuer);
17412
        return WOLFSSL_FAILURE;
17413
    }
17414
17415
    cert->issuer.x509 = cert;
17416
    cert->issuerSet = 1;
17417
17418
    return WOLFSSL_SUCCESS;
17419
}
17420
17421
17422
int wolfSSL_X509_set_notAfter(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME* t)
17423
{
17424
    if (x509 == NULL || t == NULL) {
17425
        return WOLFSSL_FAILURE;
17426
    }
17427
17428
    if (t->length < 0 || t->length > CTC_DATE_SIZE - 2) {
17429
        return WOLFSSL_FAILURE;
17430
    }
17431
17432
    x509->notAfter.type = t->type;
17433
    x509->notAfter.length = t->length;
17434
17435
    XMEMCPY(x509->notAfter.data, t->data, CTC_DATE_SIZE);
17436
17437
    return WOLFSSL_SUCCESS;
17438
}
17439
17440
int wolfSSL_X509_set_notBefore(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME* t)
17441
{
17442
    if (x509 == NULL || t == NULL) {
17443
        return WOLFSSL_FAILURE;
17444
    }
17445
17446
    if (t->length < 0 || t->length > CTC_DATE_SIZE - 2) {
17447
        return WOLFSSL_FAILURE;
17448
    }
17449
17450
    x509->notBefore.type = t->type;
17451
    x509->notBefore.length = t->length;
17452
17453
    XMEMCPY(x509->notBefore.data, t->data, CTC_DATE_SIZE);
17454
17455
    return WOLFSSL_SUCCESS;
17456
}
17457
17458
int wolfSSL_X509_set1_notAfter(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME *t)
17459
{
17460
    return wolfSSL_X509_set_notAfter(x509, t);
17461
}
17462
17463
int wolfSSL_X509_set1_notBefore(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME *t)
17464
{
17465
    return wolfSSL_X509_set_notBefore(x509, t);
17466
}
17467
17468
int wolfSSL_X509_set_serialNumber(WOLFSSL_X509* x509, WOLFSSL_ASN1_INTEGER* s)
17469
{
17470
    WOLFSSL_ENTER("wolfSSL_X509_set_serialNumber");
17471
    if (x509 == NULL || s == NULL || s->data == NULL ||
17472
            s->length >= EXTERNAL_SERIAL_SIZE)
17473
        return WOLFSSL_FAILURE;
17474
17475
    /* WOLFSSL_ASN1_INTEGER has type | size | data
17476
     * Sanity check that the data is actually in ASN format */
17477
    if (s->length < 3 || s->data[0] != ASN_INTEGER ||
17478
            s->data[1] != s->length - 2) {
17479
        return WOLFSSL_FAILURE;
17480
    }
17481
    XMEMCPY(x509->serial, s->data + 2, s->length - 2);
17482
    x509->serialSz = s->length - 2;
17483
    x509->serial[x509->serialSz] = 0;
17484
17485
    return WOLFSSL_SUCCESS;
17486
}
17487
17488
int wolfSSL_X509_set_pubkey(WOLFSSL_X509 *cert, WOLFSSL_EVP_PKEY *pkey)
17489
{
17490
    byte* p = NULL;
17491
    int derSz = 0;
17492
    WOLFSSL_ENTER("wolfSSL_X509_set_pubkey");
17493
17494
    if (cert == NULL || pkey == NULL)
17495
        return WOLFSSL_FAILURE;
17496
17497
    /* Regenerate since pkey->pkey.ptr may contain private key */
17498
    switch (pkey->type) {
17499
#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(NO_RSA)
17500
    case WC_EVP_PKEY_RSA:
17501
        {
17502
            RsaKey* rsa;
17503
17504
            if (pkey->rsa == NULL || pkey->rsa->internal == NULL)
17505
                return WOLFSSL_FAILURE;
17506
17507
            rsa = (RsaKey*)pkey->rsa->internal;
17508
            derSz = wc_RsaPublicKeyDerSize(rsa, 1);
17509
            if (derSz <= 0)
17510
                return WOLFSSL_FAILURE;
17511
17512
            p = (byte*)XMALLOC(derSz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
17513
            if (p == NULL)
17514
                return WOLFSSL_FAILURE;
17515
17516
            if ((derSz = wc_RsaKeyToPublicDer(rsa, p, (word32)derSz)) <= 0) {
17517
                XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
17518
                return WOLFSSL_FAILURE;
17519
            }
17520
            cert->pubKeyOID = RSAk;
17521
        }
17522
        break;
17523
#endif /* (WOLFSSL_KEY_GEN || OPENSSL_EXTRA) && !NO_RSA */
17524
#if !defined(HAVE_SELFTEST) && (defined(WOLFSSL_KEY_GEN) || \
17525
        defined(WOLFSSL_CERT_GEN)) && !defined(NO_DSA)
17526
    case WC_EVP_PKEY_DSA:
17527
        {
17528
            DsaKey* dsa;
17529
17530
            if (pkey->dsa == NULL || pkey->dsa->internal == NULL)
17531
                return WOLFSSL_FAILURE;
17532
17533
            dsa = (DsaKey*)pkey->dsa->internal;
17534
            /* size of pub, priv, p, q, g + ASN.1 additional information */
17535
            derSz = 5 * mp_unsigned_bin_size(&dsa->g) + MAX_ALGO_SZ;
17536
            p = (byte*)XMALLOC(derSz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
17537
            if (p == NULL)
17538
                return WOLFSSL_FAILURE;
17539
17540
            if ((derSz = wc_DsaKeyToPublicDer(dsa, p, (word32)derSz)) <= 0) {
17541
                XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
17542
                return WOLFSSL_FAILURE;
17543
            }
17544
            cert->pubKeyOID = DSAk;
17545
        }
17546
        break;
17547
#endif /* !HAVE_SELFTEST && (WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN) && !NO_DSA */
17548
#ifdef HAVE_ECC
17549
    case WC_EVP_PKEY_EC:
17550
        {
17551
            ecc_key* ecc;
17552
17553
            if (pkey->ecc == NULL || pkey->ecc->internal == NULL)
17554
                return WOLFSSL_FAILURE;
17555
17556
            ecc = (ecc_key*)pkey->ecc->internal;
17557
            derSz = wc_EccPublicKeyDerSize(ecc, 1);
17558
            if (derSz <= 0)
17559
                return WOLFSSL_FAILURE;
17560
17561
            p = (byte*)XMALLOC(derSz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
17562
            if (p == NULL)
17563
                return WOLFSSL_FAILURE;
17564
17565
            if ((derSz = wc_EccPublicKeyToDer(ecc, p, (word32)derSz, 1)) <= 0) {
17566
                XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
17567
                return WOLFSSL_FAILURE;
17568
            }
17569
            cert->pubKeyOID = ECDSAk;
17570
        }
17571
        break;
17572
#endif
17573
#if defined(WOLFSSL_HAVE_MLDSA) && defined(WOLFSSL_MLDSA_PUBLIC_KEY) && \
17574
    !defined(WOLFSSL_MLDSA_NO_ASN1) && defined(WC_ENABLE_ASYM_KEY_EXPORT)
17575
    case WC_EVP_PKEY_DILITHIUM:
17576
        {
17577
            /* Decode key DER (private or public) and export public part. */
17578
            wc_MlDsaKey* mldsa;
17579
            word32 idx = 0;
17580
            word32 rawLen = 0;
17581
            int oidSum = 0;
17582
            int decodeOk = 0;
17583
17584
            mldsa = (wc_MlDsaKey*)XMALLOC(sizeof(wc_MlDsaKey), cert->heap,
17585
                    DYNAMIC_TYPE_MLDSA);
17586
            if (mldsa == NULL) {
17587
                WOLFSSL_MSG("Failed to allocate memory for wc_MlDsaKey");
17588
                return WOLFSSL_FAILURE;
17589
            }
17590
            if (wc_MlDsaKey_Init(mldsa, cert->heap, INVALID_DEVID) != 0) {
17591
                WOLFSSL_MSG("wc_MlDsaKey_Init error");
17592
                XFREE(mldsa, cert->heap, DYNAMIC_TYPE_MLDSA);
17593
                return WOLFSSL_FAILURE;
17594
            }
17595
        #ifdef WOLFSSL_MLDSA_PRIVATE_KEY
17596
            PRIVATE_KEY_UNLOCK();
17597
            if (wc_MlDsaKey_PrivateKeyDecode(mldsa,
17598
                    (const byte*)pkey->pkey.ptr, (word32)pkey->pkey_sz,
17599
                    &idx) == 0) {
17600
                decodeOk = 1;
17601
            }
17602
            PRIVATE_KEY_LOCK();
17603
        #endif
17604
            if (!decodeOk) {
17605
            #ifdef WOLFSSL_MLDSA_PRIVATE_KEY
17606
                /* A failed PrivateKeyDecode may leave the level pinned;
17607
                 * reset the key so PublicKeyDecode auto-detects it from
17608
                 * the SPKI OID. */
17609
                wc_MlDsaKey_Free(mldsa);
17610
                if (wc_MlDsaKey_Init(mldsa, cert->heap, INVALID_DEVID) != 0) {
17611
                    WOLFSSL_MSG("wc_MlDsaKey_Init error");
17612
                    XFREE(mldsa, cert->heap, DYNAMIC_TYPE_MLDSA);
17613
                    return WOLFSSL_FAILURE;
17614
                }
17615
            #endif
17616
                idx = 0;
17617
                if (wc_MlDsaKey_PublicKeyDecode(mldsa,
17618
                        (const byte*)pkey->pkey.ptr, (word32)pkey->pkey_sz,
17619
                        &idx) != 0) {
17620
                    WOLFSSL_MSG("Error decoding ML-DSA public key");
17621
                    wc_MlDsaKey_Free(mldsa);
17622
                    XFREE(mldsa, cert->heap, DYNAMIC_TYPE_MLDSA);
17623
                    return WOLFSSL_FAILURE;
17624
                }
17625
            }
17626
            /* Map the parameter set to its OID with mldsa_get_oid_sum():
17627
             * unlike wc_MlDsaKey_GetParams() it distinguishes FIPS204-draft
17628
             * levels, keeping pubKeyOID consistent with the exported key. */
17629
            if (mldsa_get_oid_sum(mldsa, &oidSum) != 0) {
17630
                WOLFSSL_MSG("Error getting ML-DSA OID");
17631
                wc_MlDsaKey_Free(mldsa);
17632
                XFREE(mldsa, cert->heap, DYNAMIC_TYPE_MLDSA);
17633
                return WOLFSSL_FAILURE;
17634
            }
17635
17636
            /* Store the RAW public key */
17637
            if (wc_MlDsaKey_GetPubLen(mldsa, &derSz) != 0) {
17638
                WOLFSSL_MSG("Error getting ML-DSA public key length");
17639
                wc_MlDsaKey_Free(mldsa);
17640
                XFREE(mldsa, cert->heap, DYNAMIC_TYPE_MLDSA);
17641
                return WOLFSSL_FAILURE;
17642
            }
17643
            p = (byte*)XMALLOC(derSz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
17644
            if (p == NULL) {
17645
                WOLFSSL_MSG("malloc error");
17646
                wc_MlDsaKey_Free(mldsa);
17647
                XFREE(mldsa, cert->heap, DYNAMIC_TYPE_MLDSA);
17648
                return WOLFSSL_FAILURE;
17649
            }
17650
            rawLen = (word32)derSz;
17651
            if (wc_MlDsaKey_ExportPubRaw(mldsa, p, &rawLen) != 0) {
17652
                WOLFSSL_MSG("Error exporting ML-DSA public key");
17653
                wc_MlDsaKey_Free(mldsa);
17654
                XFREE(mldsa, cert->heap, DYNAMIC_TYPE_MLDSA);
17655
                XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
17656
                return WOLFSSL_FAILURE;
17657
            }
17658
            wc_MlDsaKey_Free(mldsa);
17659
            XFREE(mldsa, cert->heap, DYNAMIC_TYPE_MLDSA);
17660
            derSz = (int)rawLen;
17661
            cert->pubKeyOID = oidSum;
17662
        }
17663
        break;
17664
#endif /* WOLFSSL_HAVE_MLDSA && WOLFSSL_MLDSA_PUBLIC_KEY &&
17665
        * !WOLFSSL_MLDSA_NO_ASN1 && WC_ENABLE_ASYM_KEY_EXPORT */
17666
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
17667
    case WC_EVP_PKEY_ED25519:
17668
        {
17669
            word32 rawLen = ED25519_PUB_KEY_SIZE;
17670
17671
            if (pkey->ed25519 == NULL)
17672
                return WOLFSSL_FAILURE;
17673
17674
            /* Store the RAW public key: wolfSSL keeps an X.509 Ed25519
17675
             * public key as the bare key bytes (see StoreKey /
17676
             * CopyDecodedToX509), not a SubjectPublicKeyInfo. */
17677
            p = (byte*)XMALLOC(rawLen, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
17678
            if (p == NULL)
17679
                return WOLFSSL_FAILURE;
17680
17681
            if (wc_ed25519_export_public(pkey->ed25519, p, &rawLen) != 0) {
17682
                XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
17683
                return WOLFSSL_FAILURE;
17684
            }
17685
            derSz = (int)rawLen;
17686
            cert->pubKeyOID = ED25519k;
17687
        }
17688
        break;
17689
#endif
17690
    default:
17691
        return WOLFSSL_FAILURE;
17692
    }
17693
    XFREE(cert->pubKey.buffer, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
17694
    cert->pubKey.buffer = p;
17695
    cert->pubKey.length = (unsigned int)derSz;
17696
17697
    return WOLFSSL_SUCCESS;
17698
}
17699
17700
int wolfSSL_X509_set_version(WOLFSSL_X509* x509, long v)
17701
{
17702
    WOLFSSL_ENTER("wolfSSL_X509_set_version");
17703
    if ((x509 == NULL) || (v < 0) || (v >= INT_MAX)) {
17704
        return WOLFSSL_FAILURE;
17705
    }
17706
    x509->version = (int) v + 1;
17707
17708
    return WOLFSSL_SUCCESS;
17709
}
17710
17711
#ifdef WOLFSSL_CERT_EXT
17712
/* Set Subject Key Identifier from raw bytes.
17713
 *
17714
 * x509  - Certificate to modify
17715
 * skid  - Raw SKID bytes
17716
 * skidSz - Size of SKID in bytes
17717
 *
17718
 * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
17719
 */
17720
int wolfSSL_X509_set_subject_key_id(WOLFSSL_X509* x509,
17721
    const unsigned char* skid, int skidSz)
17722
{
17723
    WOLFSSL_ENTER("wolfSSL_X509_set_subject_key_id");
17724
17725
    if (x509 == NULL || skid == NULL || skidSz <= 0) {
17726
        return WOLFSSL_FAILURE;
17727
    }
17728
17729
    /* Allocate/reallocate memory for subjKeyId */
17730
    if (x509->subjKeyId == NULL || (int)x509->subjKeyIdSz < skidSz) {
17731
        if (x509->subjKeyId != NULL) {
17732
            XFREE(x509->subjKeyId, x509->heap, DYNAMIC_TYPE_X509_EXT);
17733
        }
17734
        x509->subjKeyId = (byte*)XMALLOC((word32)skidSz, x509->heap,
17735
                                          DYNAMIC_TYPE_X509_EXT);
17736
        if (x509->subjKeyId == NULL) {
17737
            return WOLFSSL_FAILURE;
17738
        }
17739
    }
17740
17741
    XMEMCPY(x509->subjKeyId, skid, (word32)skidSz);
17742
    x509->subjKeyIdSz = (word32)skidSz;
17743
    x509->subjKeyIdSet = 1;
17744
17745
    return WOLFSSL_SUCCESS;
17746
}
17747
17748
#ifndef NO_SHA
17749
/* Set Subject Key Identifier by computing SHA-1 hash of the public key.
17750
 *
17751
 * x509 - Certificate to modify (must have public key set)
17752
 *
17753
 * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
17754
 */
17755
int wolfSSL_X509_set_subject_key_id_ex(WOLFSSL_X509* x509)
17756
{
17757
    byte hash[WC_SHA_DIGEST_SIZE];
17758
    int ret;
17759
17760
    WOLFSSL_ENTER("wolfSSL_X509_set_subject_key_id_ex");
17761
17762
    if (x509 == NULL) {
17763
        return WOLFSSL_FAILURE;
17764
    }
17765
17766
    /* Check if public key has been set */
17767
    if (x509->pubKey.buffer == NULL || x509->pubKey.length == 0) {
17768
        WOLFSSL_MSG("Public key not set");
17769
        return WOLFSSL_FAILURE;
17770
    }
17771
17772
    /* Compute SHA-1 hash of the public key */
17773
    ret = wc_ShaHash(x509->pubKey.buffer, x509->pubKey.length, hash);
17774
    if (ret != 0) {
17775
        WOLFSSL_MSG("wc_ShaHash failed");
17776
        return WOLFSSL_FAILURE;
17777
    }
17778
17779
    return wolfSSL_X509_set_subject_key_id(x509, hash, WC_SHA_DIGEST_SIZE);
17780
}
17781
#endif /* !NO_SHA */
17782
17783
/* Set Authority Key Identifier from raw bytes.
17784
 * The bytes passed in are the keyIdentifier OCTET STRING contents only,
17785
 * they must not be a pre-encoded AuthorityKeyIdentifier SEQUENCE.
17786
 * The cert encoder wraps them in SEQUENCE { [0] keyIdentifier } at sign time.
17787
 *
17788
 * x509   - Certificate to modify
17789
 * akid   - Raw AKID bytes
17790
 * akidSz - Size of AKID in bytes
17791
 *
17792
 * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
17793
 */
17794
int wolfSSL_X509_set_authority_key_id(WOLFSSL_X509* x509,
17795
    const unsigned char* akid, int akidSz)
17796
{
17797
    byte* newAkid = NULL;
17798
17799
    WOLFSSL_ENTER("wolfSSL_X509_set_authority_key_id");
17800
17801
    if (x509 == NULL || akid == NULL || akidSz <= 0) {
17802
        return WOLFSSL_FAILURE;
17803
    }
17804
17805
    /* Allocate new buffer up front so failure leaves prior state intact */
17806
    newAkid = (byte*)XMALLOC((word32)akidSz, x509->heap, DYNAMIC_TYPE_X509_EXT);
17807
    if (newAkid == NULL) {
17808
        return WOLFSSL_FAILURE;
17809
    }
17810
    XMEMCPY(newAkid, akid, (word32)akidSz);
17811
17812
    /* Free any prior storage. authKeyIdSrc may be populated from a prior
17813
     * parse cert operation. authKeyId aliases inside that buffer, so
17814
     * authKeyIdSrc must be freed first to avoid a dangling authKeyId. */
17815
    if (x509->authKeyIdSrc != NULL) {
17816
        XFREE(x509->authKeyIdSrc, x509->heap, DYNAMIC_TYPE_X509_EXT);
17817
        x509->authKeyIdSrc = NULL;
17818
        x509->authKeyIdSrcSz = 0;
17819
    }
17820
    else if (x509->authKeyId != NULL) {
17821
        XFREE(x509->authKeyId, x509->heap, DYNAMIC_TYPE_X509_EXT);
17822
    }
17823
17824
    /* Store newAkid as authKeyId only, do not populate authKeyIdSrc.
17825
     * When authKeyIdSrc is non-NULL, the encoder writes those bytes without
17826
     * SEQUENCE/[0] wrapper. authKeyIdSrc must be NULL here so encoder does
17827
     * wrap them. */
17828
    x509->authKeyId = newAkid;
17829
    x509->authKeyIdSz = (word32)akidSz;
17830
    x509->authKeyIdSet = 1;
17831
17832
    return WOLFSSL_SUCCESS;
17833
}
17834
17835
#ifndef NO_SHA
17836
/* Set Authority Key Identifier from issuer certificate.
17837
 * Extracts SKID from issuer (or computes from issuer's public key).
17838
 *
17839
 * x509   - Certificate to modify
17840
 * issuer - Issuer certificate
17841
 *
17842
 * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
17843
 */
17844
int wolfSSL_X509_set_authority_key_id_ex(WOLFSSL_X509* x509,
17845
    WOLFSSL_X509* issuer)
17846
{
17847
    byte hash[WC_SHA_DIGEST_SIZE];
17848
    int ret;
17849
17850
    WOLFSSL_ENTER("wolfSSL_X509_set_authority_key_id_ex");
17851
17852
    if (x509 == NULL || issuer == NULL) {
17853
        return WOLFSSL_FAILURE;
17854
    }
17855
17856
    /* First try to use issuer's SKID if it's set */
17857
    if (issuer->subjKeyIdSet && issuer->subjKeyId != NULL &&
17858
        issuer->subjKeyIdSz > 0) {
17859
        return wolfSSL_X509_set_authority_key_id(x509, issuer->subjKeyId,
17860
                                                  (int)issuer->subjKeyIdSz);
17861
    }
17862
17863
    /* Otherwise compute from issuer's public key */
17864
    if (issuer->pubKey.buffer == NULL || issuer->pubKey.length == 0) {
17865
        WOLFSSL_MSG("Issuer public key not available");
17866
        return WOLFSSL_FAILURE;
17867
    }
17868
17869
    ret = wc_ShaHash(issuer->pubKey.buffer, issuer->pubKey.length, hash);
17870
    if (ret != 0) {
17871
        WOLFSSL_MSG("wc_ShaHash failed");
17872
        return WOLFSSL_FAILURE;
17873
    }
17874
17875
    return wolfSSL_X509_set_authority_key_id(x509, hash, WC_SHA_DIGEST_SIZE);
17876
}
17877
#endif /* !NO_SHA */
17878
#endif /* WOLFSSL_CERT_EXT */
17879
17880
#ifndef IGNORE_NETSCAPE_CERT_TYPE
17881
/* Set Netscape Certificate Type extension.
17882
 *
17883
 * x509       - Certificate to modify
17884
 * nsCertType - Bitwise OR of NS_SSL_CLIENT, NS_SSL_SERVER, etc.
17885
 *
17886
 * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
17887
 */
17888
int wolfSSL_X509_set_ns_cert_type(WOLFSSL_X509* x509, int nsCertType)
17889
{
17890
    WOLFSSL_ENTER("wolfSSL_X509_set_ns_cert_type");
17891
17892
    if (x509 == NULL) {
17893
        return WOLFSSL_FAILURE;
17894
    }
17895
17896
    x509->nsCertType = (byte)nsCertType;
17897
17898
    return WOLFSSL_SUCCESS;
17899
}
17900
#endif /* !IGNORE_NETSCAPE_CERT_TYPE */
17901
17902
#endif /* (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) && WOLFSSL_CERT_GEN */
17903
17904
#if (defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)) &&           \
17905
    defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ)
17906
17907
void wolfSSL_X509V3_set_ctx(WOLFSSL_X509V3_CTX* ctx, WOLFSSL_X509* issuer,
17908
        WOLFSSL_X509* subject, WOLFSSL_X509* req, WOLFSSL_X509_CRL* crl,
17909
        int flag)
17910
{
17911
    int ret = WOLFSSL_SUCCESS;
17912
    WOLFSSL_ENTER("wolfSSL_X509V3_set_ctx");
17913
    if (!ctx) {
17914
        ret = WOLFSSL_FAILURE;
17915
        WOLFSSL_MSG("wolfSSL_X509V3_set_ctx() called with null ctx.");
17916
    }
17917
17918
    if (ret == WOLFSSL_SUCCESS && (ctx->x509 != NULL)) {
17919
        ret = WOLFSSL_FAILURE;
17920
        WOLFSSL_MSG("wolfSSL_X509V3_set_ctx() called "
17921
                    "with ctx->x509 already allocated.");
17922
    }
17923
17924
    if (ret == WOLFSSL_SUCCESS) {
17925
        ctx->x509 = wolfSSL_X509_new_ex(
17926
            (issuer && issuer->heap) ? issuer->heap :
17927
            (subject && subject->heap) ? subject->heap :
17928
            (req && req->heap) ? req->heap :
17929
            NULL);
17930
        if (!ctx->x509) {
17931
            ret = WOLFSSL_FAILURE;
17932
            WOLFSSL_MSG("wolfSSL_X509_new_ex() failed "
17933
                        "in wolfSSL_X509V3_set_ctx().");
17934
        }
17935
    }
17936
17937
    /* Set parameters in ctx as long as ret == WOLFSSL_SUCCESS */
17938
    if (ret == WOLFSSL_SUCCESS && issuer)
17939
        ret = wolfSSL_X509_set_issuer_name(ctx->x509, &issuer->issuer);
17940
17941
    if (ret == WOLFSSL_SUCCESS && subject)
17942
        ret = wolfSSL_X509_set_subject_name(ctx->x509, &subject->subject);
17943
17944
    if (ret == WOLFSSL_SUCCESS && req) {
17945
        WOLFSSL_MSG("req not implemented.");
17946
    }
17947
17948
    if (ret == WOLFSSL_SUCCESS && crl) {
17949
        WOLFSSL_MSG("crl not implemented.");
17950
    }
17951
17952
    if (ret == WOLFSSL_SUCCESS && flag) {
17953
        WOLFSSL_MSG("flag not implemented.");
17954
    }
17955
17956
    if (ret != WOLFSSL_SUCCESS) {
17957
        WOLFSSL_MSG("Error setting WOLFSSL_X509V3_CTX parameters.");
17958
    }
17959
}
17960
17961
#ifndef NO_BIO
17962
int wolfSSL_i2d_X509_REQ(WOLFSSL_X509* req, unsigned char** out)
17963
{
17964
    int derSz = 0;
17965
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
17966
    WOLFSSL_BIO* bio = NULL;
17967
    WOLFSSL_ENTER("wolfSSL_i2d_X509_REQ");
17968
17969
    if (req == NULL || out == NULL) {
17970
        return BAD_FUNC_ARG;
17971
    }
17972
17973
    if (!(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()))) {
17974
        return WOLFSSL_FAILURE;
17975
    }
17976
17977
    if (wolfSSL_i2d_X509_REQ_bio(bio, req) != WOLFSSL_SUCCESS) {
17978
        WOLFSSL_MSG("wolfSSL_i2d_X509_REQ_bio error");
17979
        goto cleanup;
17980
    }
17981
17982
    derSz = wolfSSL_BIO_get_len(bio);
17983
17984
    if (*out == NULL) {
17985
        *out = (unsigned char*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL);
17986
        if (!*out) {
17987
            WOLFSSL_MSG("malloc error");
17988
            ret = MEMORY_E;
17989
            goto cleanup;
17990
        }
17991
    }
17992
17993
    if (wolfSSL_BIO_read(bio, *out, derSz) != derSz) {
17994
        WOLFSSL_MSG("wolfSSL_BIO_read error");
17995
        goto cleanup;
17996
    }
17997
17998
    ret = derSz;
17999
cleanup:
18000
    wolfSSL_BIO_free(bio);
18001
18002
    return ret;
18003
}
18004
#endif /* !NO_BIO */
18005
18006
WOLFSSL_X509* wolfSSL_X509_REQ_new(void)
18007
{
18008
    return wolfSSL_X509_new();
18009
}
18010
18011
void wolfSSL_X509_REQ_free(WOLFSSL_X509* req)
18012
{
18013
    wolfSSL_X509_free(req);
18014
}
18015
18016
int wolfSSL_X509_REQ_set_version(WOLFSSL_X509 *x, long version)
18017
{
18018
    WOLFSSL_ENTER("wolfSSL_X509_REQ_set_version");
18019
    if ((x == NULL) || (version < 0) || (version >= INT_MAX)) {
18020
        return WOLFSSL_FAILURE;
18021
    }
18022
    x->version = (int)version;
18023
    return WOLFSSL_SUCCESS;
18024
}
18025
18026
long wolfSSL_X509_REQ_get_version(const WOLFSSL_X509 *req)
18027
{
18028
    WOLFSSL_ENTER("wolfSSL_X509_REQ_get_version");
18029
    if (req == NULL) {
18030
        return 0; /* invalid arg */
18031
    }
18032
    return (long)req->version;
18033
}
18034
18035
int wolfSSL_X509_REQ_sign(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey,
18036
                          const WOLFSSL_EVP_MD *md)
18037
{
18038
    int ret;
18039
    byte* der = NULL;
18040
    int bufSz;
18041
    int derSz;
18042
    int sigType;
18043
18044
    if (req == NULL || pkey == NULL) {
18045
        WOLFSSL_LEAVE("wolfSSL_X509_REQ_sign", BAD_FUNC_ARG);
18046
        return WOLFSSL_FAILURE;
18047
    }
18048
18049
    bufSz = x509_gen_buf_sz(req, pkey);
18050
    derSz = bufSz;
18051
    der = (byte*)XMALLOC((size_t)bufSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18052
    if (der == NULL) {
18053
        return WOLFSSL_FAILURE;
18054
    }
18055
18056
    /* Create a Cert that has the certificate request fields.  The (pkey, md)
18057
     * combination is resolved by wolfSSL_sigTypeFromPKEY() - Ed25519 CSRs sign
18058
     * with a NULL digest, ML-DSA ignores the digest, every other key type
18059
     * requires one - and sigOID is only updated on success, so the object is
18060
     * unmodified on a rejected key/md combination. */
18061
    sigType = wolfSSL_sigTypeFromPKEY((WOLFSSL_EVP_MD*)md, pkey);
18062
    if (sigType == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
18063
        WOLFSSL_MSG("Unsupported key/md combination for signing");
18064
        XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18065
        return WOLFSSL_FAILURE;
18066
    }
18067
    req->sigOID = sigType;
18068
    ret = wolfssl_x509_make_der(req, 1, der, &derSz, 0);
18069
    if (ret != WOLFSSL_SUCCESS) {
18070
        XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18071
        WOLFSSL_MSG("Unable to make DER for X509");
18072
        WOLFSSL_LEAVE("wolfSSL_X509_REQ_sign", ret);
18073
        return WOLFSSL_FAILURE;
18074
    }
18075
18076
    if (wolfSSL_X509_resign_cert(req, 1, der, bufSz, derSz,
18077
            (WOLFSSL_EVP_MD*)md, pkey) <= 0) {
18078
        XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18079
        return WOLFSSL_FAILURE;
18080
    }
18081
    XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18082
    return WOLFSSL_SUCCESS;
18083
}
18084
18085
int wolfSSL_X509_REQ_sign_ctx(WOLFSSL_X509 *req,
18086
                              WOLFSSL_EVP_MD_CTX* md_ctx)
18087
{
18088
    if (md_ctx && md_ctx->pctx)
18089
        return wolfSSL_X509_REQ_sign(req, md_ctx->pctx->pkey,
18090
                wolfSSL_EVP_MD_CTX_md(md_ctx));
18091
    else
18092
        return WOLFSSL_FAILURE;
18093
}
18094
18095
static int regenX509REQDerBuffer(WOLFSSL_X509* x509)
18096
{
18097
    int derSz = X509_BUFFER_SZ;
18098
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
18099
#ifndef WOLFSSL_SMALL_STACK
18100
    byte der[X509_BUFFER_SZ];
18101
#else
18102
    byte* der;
18103
18104
    der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18105
    if (!der) {
18106
        WOLFSSL_MSG("malloc failed");
18107
        return WOLFSSL_FAILURE;
18108
    }
18109
#endif
18110
18111
    if (wolfssl_x509_make_der(x509, 1, der, &derSz, 0) == WOLFSSL_SUCCESS) {
18112
        FreeDer(&x509->derCert);
18113
        if (AllocDer(&x509->derCert, (word32)derSz, CERT_TYPE,
18114
                                                             x509->heap) == 0) {
18115
            XMEMCPY(x509->derCert->buffer, der, derSz);
18116
            ret = WOLFSSL_SUCCESS;
18117
        }
18118
        else {
18119
            WOLFSSL_MSG("Failed to allocate DER buffer for X509");
18120
        }
18121
    }
18122
    else {
18123
        WOLFSSL_MSG("Unable to make DER for X509 REQ");
18124
    }
18125
    WC_FREE_VAR_EX(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18126
    return ret;
18127
}
18128
18129
int wolfSSL_X509_REQ_add_extensions(WOLFSSL_X509* req,
18130
        WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* ext_sk)
18131
{
18132
    WOLFSSL_X509_EXTENSION* ext = NULL;
18133
18134
    if (!req || !ext_sk) {
18135
        WOLFSSL_MSG("Bad parameter");
18136
        return WOLFSSL_FAILURE;
18137
    }
18138
18139
    /* It is not an error if the stack is empty. */
18140
    ext = ext_sk->data.ext;
18141
    if (ext == NULL) {
18142
        return WOLFSSL_SUCCESS;
18143
    }
18144
18145
    while (ext_sk) {
18146
        ext = ext_sk->data.ext;
18147
18148
        if (wolfSSL_X509_add_ext(req, ext, -1) != WOLFSSL_SUCCESS) {
18149
            WOLFSSL_MSG("wolfSSL_X509_add_ext error");
18150
            return WOLFSSL_FAILURE;
18151
        }
18152
18153
        ext_sk = ext_sk->next;
18154
    }
18155
18156
    return regenX509REQDerBuffer(req);
18157
}
18158
18159
int wolfSSL_X509_REQ_add1_attr_by_txt(WOLFSSL_X509 *req,
18160
                              const char *attrname, int type,
18161
                              const unsigned char *bytes, int len)
18162
{
18163
    WOLFSSL_ENTER("wolfSSL_X509_REQ_add1_attr_by_txt");
18164
18165
#ifdef HAVE_LIBEST
18166
    if (!req || !attrname || !bytes || type != MBSTRING_ASC) {
18167
        WOLFSSL_MSG("Bad parameter");
18168
        return WOLFSSL_FAILURE;
18169
    }
18170
18171
    if (len < 0) {
18172
        len = (int)XSTRLEN((char*)bytes);
18173
    }
18174
18175
    /* For now just pretend that we support this for libest testing */
18176
    if (len == XSTR_SIZEOF("1.3.6.1.1.1.1.22") &&
18177
            XMEMCMP("1.3.6.1.1.1.1.22", bytes, len) == 0) {
18178
        /* MAC Address */
18179
    }
18180
    else if (len == XSTR_SIZEOF("1.2.840.10045.2.1") &&
18181
            XMEMCMP("1.2.840.10045.2.1", bytes, len) == 0) {
18182
        /* ecPublicKey */
18183
    }
18184
    else if (len == XSTR_SIZEOF("1.2.840.10045.4.3.3") &&
18185
            XMEMCMP("1.2.840.10045.4.3.3", bytes, len) == 0) {
18186
        /* ecdsa-with-SHA384 */
18187
    }
18188
    else {
18189
        return WOLFSSL_FAILURE;
18190
    }
18191
18192
    /* return error if not built for libest */
18193
    return WOLFSSL_SUCCESS;
18194
#else
18195
    (void)req;
18196
    (void)attrname;
18197
    (void)type;
18198
    (void)bytes;
18199
    (void)len;
18200
    return WOLFSSL_FAILURE;
18201
#endif
18202
}
18203
18204
18205
static int wolfSSL_X509_ATTRIBUTE_set(WOLFSSL_X509_ATTRIBUTE* attr,
18206
        const char* data, int dataSz, int type, int nid)
18207
{
18208
    if (attr) {
18209
        attr->value->value.asn1_string = wolfSSL_ASN1_STRING_new();
18210
        if (wolfSSL_ASN1_STRING_set(attr->value->value.asn1_string,
18211
                data, dataSz) != WOLFSSL_SUCCESS) {
18212
            wolfSSL_ASN1_STRING_free(attr->value->value.asn1_string);
18213
            WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
18214
            return WOLFSSL_FAILURE;
18215
        }
18216
        attr->value->type = type;
18217
        attr->object->nid = nid;
18218
    }
18219
    else {
18220
        WOLFSSL_MSG("wolfSSL_X509_ATTRIBUTE_new error");
18221
        return WOLFSSL_FAILURE;
18222
    }
18223
18224
    return WOLFSSL_SUCCESS;
18225
}
18226
18227
18228
int wolfSSL_X509_REQ_add1_attr_by_NID(WOLFSSL_X509 *req,
18229
                                      int nid, int type,
18230
                                      const unsigned char *bytes,
18231
                                      int len)
18232
{
18233
    int ret;
18234
    WOLFSSL_X509_ATTRIBUTE* attr;
18235
18236
    WOLFSSL_ENTER("wolfSSL_X509_REQ_add1_attr_by_NID");
18237
18238
    if (!req || !bytes || type != WOLFSSL_MBSTRING_ASC) {
18239
        WOLFSSL_MSG("Bad parameter");
18240
        return WOLFSSL_FAILURE;
18241
    }
18242
18243
    switch (nid) {
18244
    case WC_NID_pkcs9_challengePassword:
18245
        if (len < 0)
18246
            len = (int)XSTRLEN((char*)bytes);
18247
        if (len < CTC_NAME_SIZE) {
18248
            XMEMCPY(req->challengePw, bytes, len);
18249
            req->challengePw[len] = '\0';
18250
        }
18251
        else {
18252
            WOLFSSL_MSG("Challenge password too long");
18253
            WOLFSSL_ERROR_VERBOSE(BUFFER_E);
18254
            return WOLFSSL_FAILURE;
18255
        }
18256
        break;
18257
    case WC_NID_serialNumber:
18258
        if (len < 0)
18259
            len = (int)XSTRLEN((char*)bytes);
18260
        if (len + 1 > EXTERNAL_SERIAL_SIZE) {
18261
            WOLFSSL_MSG("SerialNumber too long");
18262
            WOLFSSL_ERROR_VERBOSE(BUFFER_E);
18263
            return WOLFSSL_FAILURE;
18264
        }
18265
        XMEMCPY(req->serial, bytes, len);
18266
        req->serialSz = len;
18267
        break;
18268
18269
    case WC_NID_pkcs9_unstructuredName:
18270
    case WC_NID_pkcs9_contentType:
18271
    case WC_NID_surname:
18272
    case WC_NID_initials:
18273
    case WC_NID_givenName:
18274
    case WC_NID_dnQualifier:
18275
        break;
18276
18277
    default:
18278
        WOLFSSL_MSG("Unsupported attribute");
18279
        return WOLFSSL_FAILURE;
18280
    }
18281
18282
    attr = wolfSSL_X509_ATTRIBUTE_new();
18283
    ret = wolfSSL_X509_ATTRIBUTE_set(attr, (const char*)bytes, len,
18284
            WOLFSSL_V_ASN1_PRINTABLESTRING, nid);
18285
    if (ret != WOLFSSL_SUCCESS) {
18286
        wolfSSL_X509_ATTRIBUTE_free(attr);
18287
    }
18288
    else {
18289
        if (req->reqAttributes == NULL) {
18290
            req->reqAttributes = wolfSSL_sk_new_node(req->heap);
18291
            if (req->reqAttributes != NULL) {
18292
                req->reqAttributes->type = STACK_TYPE_X509_REQ_ATTR;
18293
            }
18294
        }
18295
        if ((req->reqAttributes != NULL) &&
18296
                (req->reqAttributes->type == STACK_TYPE_X509_REQ_ATTR)) {
18297
            /* Using wolfSSL_sk_insert to maintain backwards compatibility with
18298
             * earlier versions of _push API that pushed items to the start of
18299
             * the list instead of the end. */
18300
            ret = wolfSSL_sk_insert(req->reqAttributes, attr, 0) > 0
18301
                    ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
18302
        }
18303
        else {
18304
            ret = WOLFSSL_FAILURE;
18305
        }
18306
        if (ret != WOLFSSL_SUCCESS)
18307
            wolfSSL_X509_ATTRIBUTE_free(attr);
18308
    }
18309
18310
    return ret;
18311
}
18312
18313
WOLFSSL_X509 *wolfSSL_X509_to_X509_REQ(WOLFSSL_X509 *x,
18314
        WOLFSSL_EVP_PKEY *pkey, const WOLFSSL_EVP_MD *md)
18315
{
18316
    WOLFSSL_ENTER("wolfSSL_X509_to_X509_REQ");
18317
    (void)pkey;
18318
    (void)md;
18319
    return wolfSSL_X509_dup(x);
18320
}
18321
18322
int wolfSSL_X509_REQ_set_subject_name(WOLFSSL_X509 *req,
18323
                                      WOLFSSL_X509_NAME *name)
18324
{
18325
    return wolfSSL_X509_set_subject_name(req, name);
18326
}
18327
18328
int wolfSSL_X509_REQ_set_pubkey(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey)
18329
{
18330
    return wolfSSL_X509_set_pubkey(req, pkey);
18331
}
18332
#endif /* OPENSSL_ALL && WOLFSSL_CERT_GEN && WOLFSSL_CERT_REQ */
18333
18334
#if (defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)) && \
18335
    (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_REQ))
18336
18337
WOLFSSL_ASN1_TYPE *wolfSSL_X509_ATTRIBUTE_get0_type(
18338
        WOLFSSL_X509_ATTRIBUTE *attr, int idx)
18339
{
18340
    WOLFSSL_ENTER("wolfSSL_X509_ATTRIBUTE_get0_type");
18341
18342
    if (!attr || idx != 0) {
18343
        WOLFSSL_MSG("Bad parameter");
18344
        return NULL;
18345
    }
18346
18347
    return attr->value;
18348
}
18349
18350
18351
/**
18352
 * @param req X509_REQ containing attribute
18353
 * @return the number of attributes
18354
 */
18355
int wolfSSL_X509_REQ_get_attr_count(const WOLFSSL_X509 *req)
18356
{
18357
    if (req == NULL || req->reqAttributes == NULL)
18358
        return 0;
18359
18360
    return wolfSSL_sk_num(req->reqAttributes);
18361
}
18362
18363
18364
/**
18365
 * @param req X509_REQ containing attribute
18366
 * @param loc NID of the attribute to return
18367
 */
18368
WOLFSSL_X509_ATTRIBUTE *wolfSSL_X509_REQ_get_attr(
18369
        const WOLFSSL_X509 *req, int loc)
18370
{
18371
    WOLFSSL_ENTER("wolfSSL_X509_REQ_get_attr");
18372
18373
    if (!req || req->reqAttributes == NULL) {
18374
        WOLFSSL_MSG("Bad parameter");
18375
        return NULL;
18376
    }
18377
18378
    return (WOLFSSL_X509_ATTRIBUTE*)wolfSSL_sk_value(req->reqAttributes, loc);
18379
}
18380
18381
/* Return NID as the attr index */
18382
int wolfSSL_X509_REQ_get_attr_by_NID(const WOLFSSL_X509 *req,
18383
        int nid, int lastpos)
18384
{
18385
    int idx;
18386
18387
    WOLFSSL_ENTER("wolfSSL_X509_REQ_get_attr_by_NID");
18388
18389
    if (!req) {
18390
        WOLFSSL_MSG("Bad parameter");
18391
        return WOLFSSL_FATAL_ERROR;
18392
    }
18393
18394
    /* search through stack for first matching nid */
18395
    for (idx = lastpos + 1; idx < wolfSSL_sk_num(req->reqAttributes); idx++) {
18396
        WOLFSSL_X509_ATTRIBUTE* attr =
18397
             (WOLFSSL_X509_ATTRIBUTE*)wolfSSL_sk_value(req->reqAttributes, idx);
18398
        if (attr != NULL && attr->object != NULL && attr->object->nid == nid)
18399
            return idx;
18400
    }
18401
18402
    return WOLFSSL_FATAL_ERROR;
18403
}
18404
18405
WOLFSSL_X509_ATTRIBUTE* wolfSSL_X509_ATTRIBUTE_new(void)
18406
{
18407
    WOLFSSL_X509_ATTRIBUTE* ret;
18408
    WOLFSSL_ENTER("wolfSSL_X509_ATTRIBUTE_new");
18409
    ret = (WOLFSSL_X509_ATTRIBUTE*)XMALLOC(sizeof(WOLFSSL_X509_ATTRIBUTE),
18410
            NULL, DYNAMIC_TYPE_OPENSSL);
18411
    if (!ret) {
18412
        WOLFSSL_MSG("malloc error");
18413
        return NULL;
18414
    }
18415
    XMEMSET(ret, 0, sizeof(WOLFSSL_X509_ATTRIBUTE));
18416
    ret->object = wolfSSL_ASN1_OBJECT_new();
18417
    ret->value = wolfSSL_ASN1_TYPE_new();
18418
    /* Don't allocate ret->set since WOLFSSL_ASN1_TYPE
18419
     * is not supported as a stack type */
18420
    if (!ret->object || !ret->value) {
18421
        WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new or wolfSSL_ASN1_TYPE_new error");
18422
        wolfSSL_X509_ATTRIBUTE_free(ret);
18423
        return NULL;
18424
    }
18425
    return ret;
18426
}
18427
18428
void wolfSSL_X509_ATTRIBUTE_free(WOLFSSL_X509_ATTRIBUTE* attr)
18429
{
18430
    WOLFSSL_ENTER("wolfSSL_X509_ATTRIBUTE_free");
18431
    if (attr) {
18432
        if (attr->object) {
18433
            wolfSSL_ASN1_OBJECT_free(attr->object);
18434
        }
18435
        if (attr->value) {
18436
            wolfSSL_ASN1_TYPE_free(attr->value);
18437
        }
18438
        if (attr->set) {
18439
            wolfSSL_sk_pop_free(attr->set, NULL);
18440
        }
18441
        XFREE(attr, NULL, DYNAMIC_TYPE_OPENSSL);
18442
    }
18443
}
18444
#endif /* (OPENSSL_ALL || OPENSSL_EXTRA) &&
18445
          (WOLFSSL_CERT_GEN || WOLFSSL_CERT_REQ) */
18446
18447
#if defined(WOLFSSL_ACERT) && \
18448
   (defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA))
18449
18450
/* Allocate and return a new WOLFSSL_X509_ACERT struct pointer.
18451
 *
18452
 * @param [in]      heap        heap hint
18453
 *
18454
 * @return  pointer  on success
18455
 * @return  NULL     on error
18456
 * */
18457
WOLFSSL_X509_ACERT * wolfSSL_X509_ACERT_new_ex(void* heap)
18458
{
18459
    WOLFSSL_X509_ACERT * x509 = NULL;
18460
18461
    WOLFSSL_ENTER("wolfSSL_X509_ACERT_new");
18462
18463
    x509 = (WOLFSSL_X509_ACERT*) XMALLOC(sizeof(WOLFSSL_X509_ACERT), heap,
18464
                                         DYNAMIC_TYPE_X509_ACERT);
18465
18466
    if (x509 != NULL) {
18467
        wolfSSL_X509_ACERT_init(x509, 1, heap);
18468
    }
18469
18470
    return x509;
18471
}
18472
18473
WOLFSSL_X509_ACERT * wolfSSL_X509_ACERT_new(void)
18474
{
18475
    return wolfSSL_X509_ACERT_new_ex(NULL);
18476
}
18477
18478
/* Initialize a WOLFSSL_X509_ACERT struct.
18479
 *
18480
 * If dynamic == 1, then the x509 pointer will be freed
18481
 * in wolfSSL_X509_ACERT_free.
18482
 *
18483
 * @param [in]      x509        x509 acert pointer
18484
 * @param [in]      dynamic     dynamic mem flag
18485
 * @param [in]      heap        heap hint
18486
 *
18487
 * @return  void
18488
 * */
18489
void wolfSSL_X509_ACERT_init(WOLFSSL_X509_ACERT * x509, int dynamic, void* heap)
18490
{
18491
    WOLFSSL_ENTER("wolfSSL_X509_ACERT_init");
18492
18493
    if (x509 == NULL) {
18494
        WOLFSSL_MSG("error: InitX509Acert: null parameter");
18495
        return;
18496
    }
18497
18498
    XMEMSET(x509, 0, sizeof(*x509));
18499
18500
    x509->heap = heap;
18501
    x509->dynamic = dynamic;
18502
}
18503
18504
/* Free a WOLFSSL_X509_ACERT struct and its sub-fields.
18505
 *
18506
 * If this ACERT was initialized with dynamic == 1, then
18507
 * the x509 pointer itself will be freed as well.
18508
 *
18509
 * @param [in]      x509        x509 acert pointer
18510
 *
18511
 * @return  void
18512
 * */
18513
void wolfSSL_X509_ACERT_free(WOLFSSL_X509_ACERT * x509)
18514
{
18515
    int    dynamic = 0;
18516
    void * heap = NULL;
18517
18518
    WOLFSSL_ENTER("wolfSSL_X509_ACERT_free");
18519
18520
    if (x509 == NULL) {
18521
        WOLFSSL_MSG("error: wolfSSL_X509_ACERT_free: null parameter");
18522
        return;
18523
    }
18524
18525
    dynamic = x509->dynamic;
18526
    heap = x509->heap;
18527
18528
    /* Free holder and att cert issuer structures. */
18529
    if (x509->holderIssuerName) {
18530
        FreeAltNames(x509->holderIssuerName, heap);
18531
        x509->holderIssuerName = NULL;
18532
    }
18533
18534
    if (x509->holderEntityName) {
18535
        FreeAltNames(x509->holderEntityName, heap);
18536
        x509->holderEntityName = NULL;
18537
    }
18538
18539
    if (x509->AttCertIssuerName) {
18540
        FreeAltNames(x509->AttCertIssuerName, heap);
18541
        x509->AttCertIssuerName = NULL;
18542
    }
18543
18544
    if (x509->rawAttr != NULL) {
18545
        XFREE(x509->rawAttr, heap, DYNAMIC_TYPE_X509_EXT);
18546
        x509->rawAttr = NULL;
18547
        x509->rawAttrLen = 0;
18548
    }
18549
18550
    /* Free derCert source and signature buffer. */
18551
    FreeDer(&x509->derCert);
18552
18553
    if (x509->sig.buffer != NULL) {
18554
        XFREE(x509->sig.buffer, heap, DYNAMIC_TYPE_SIGNATURE);
18555
        x509->sig.buffer = NULL;
18556
    }
18557
18558
    /* Finally memset and free x509 acert structure. */
18559
    XMEMSET(x509, 0, sizeof(*x509));
18560
18561
    if (dynamic == 1) {
18562
        XFREE(x509, heap, DYNAMIC_TYPE_X509_ACERT);
18563
    }
18564
18565
    return;
18566
}
18567
18568
#if defined(OPENSSL_EXTRA)
18569
long wolfSSL_X509_ACERT_get_version(const WOLFSSL_X509_ACERT* x509)
18570
{
18571
    int version = 0;
18572
18573
    if (x509 == NULL) {
18574
        return 0L;
18575
    }
18576
18577
    version = x509->version;
18578
18579
    return version != 0 ? (long)version - 1L : 0L;
18580
}
18581
#endif /* OPENSSL_EXTRA */
18582
18583
int wolfSSL_X509_ACERT_version(WOLFSSL_X509_ACERT* x509)
18584
{
18585
    if (x509 == NULL) {
18586
        return 0;
18587
    }
18588
18589
    return x509->version;
18590
}
18591
18592
/* Retrieve the serial number from an ACERT.
18593
 *
18594
 * @param [in]       x509    the x509 attribute certificate
18595
 * @param [in, out]  buf     the serial number buffer pointer
18596
 * @param [in, out]  bufSz   the serial number buffer size pointer
18597
 *
18598
 * buf may be null, but bufSz is required. On success, sets
18599
 * bufSz pointer to signature length, and copies signature
18600
 * to buf if provided.
18601
 *
18602
 * Returns  WWOLFSSL_FATAL_ERROR if bufSz is null or too small.
18603
 * Returns  WOLFSSL_SUCCESS on success.
18604
 */
18605
int wolfSSL_X509_ACERT_get_serial_number(WOLFSSL_X509_ACERT* x509,
18606
                                         byte* buf, int* bufSz)
18607
{
18608
    WOLFSSL_ENTER("wolfSSL_X509_ACERT_get_serial_number");
18609
18610
    if (x509 == NULL || bufSz == NULL) {
18611
        WOLFSSL_MSG("error: null argument passed in");
18612
        return BAD_FUNC_ARG;
18613
    }
18614
18615
    if (buf != NULL) {
18616
        if (*bufSz < x509->serialSz) {
18617
            WOLFSSL_MSG("error: serial buffer too small");
18618
            return BUFFER_E;
18619
        }
18620
18621
        XMEMCPY(buf, x509->serial, x509->serialSz);
18622
    }
18623
18624
    *bufSz = x509->serialSz;
18625
18626
    return WOLFSSL_SUCCESS;
18627
}
18628
18629
/* Sets buf pointer and len to raw Attribute buffer and buffer len
18630
 * in X509 struct.
18631
 *
18632
 * Returns WOLFSSL_SUCCESS on success.
18633
 * Returns BAD_FUNC_ARG if input pointers are null.
18634
 * */
18635
int wolfSSL_X509_ACERT_get_attr_buf(const WOLFSSL_X509_ACERT* x509,
18636
                                                const byte ** rawAttr,
18637
                                                word32 * rawAttrLen)
18638
{
18639
    if (x509 == NULL || rawAttr == NULL || rawAttrLen == NULL) {
18640
        return BAD_FUNC_ARG;
18641
    }
18642
18643
    *rawAttr = x509->rawAttr;
18644
    *rawAttrLen = x509->rawAttrLen;
18645
18646
    return WOLFSSL_SUCCESS;
18647
}
18648
18649
#ifndef NO_WOLFSSL_STUB
18650
int wolfSSL_X509_ACERT_sign(WOLFSSL_X509_ACERT * x509,
18651
                                        WOLFSSL_EVP_PKEY * pkey,
18652
                                        const WOLFSSL_EVP_MD * md)
18653
{
18654
    WOLFSSL_STUB("X509_ACERT_sign");
18655
    (void) x509;
18656
    (void) pkey;
18657
    (void) md;
18658
    return WOLFSSL_NOT_IMPLEMENTED;
18659
}
18660
#endif /* NO_WOLFSSL_STUB */
18661
18662
/* Helper function for ACERT_verify.
18663
 *
18664
 * @param [in]       x509    the x509 attribute certificate
18665
 * @param [in, out]  outSz   the x509 der length
18666
 *
18667
 * @return  der buffer on success
18668
 * @return  NULL on error
18669
 * */
18670
static const byte* acert_get_der(WOLFSSL_X509_ACERT * x509, int* outSz)
18671
{
18672
    if (x509 == NULL || x509->derCert == NULL || outSz == NULL) {
18673
        return NULL;
18674
    }
18675
18676
    *outSz = (int)x509->derCert->length;
18677
    return x509->derCert->buffer;
18678
}
18679
18680
/* Given an X509_ACERT and EVP_PKEY, verify the acert's signature.
18681
 *
18682
 * @param [in]    x509    the x509 attribute certificate
18683
 * @param [in]    pkey    the evp_pkey
18684
 *
18685
 * @return  WOLFSSL_SUCCESS on verify success
18686
 * @return  < 0 on error
18687
 * */
18688
int wolfSSL_X509_ACERT_verify(WOLFSSL_X509_ACERT* x509, WOLFSSL_EVP_PKEY* pkey)
18689
{
18690
    int          ret = 0;
18691
    const byte * der = NULL;
18692
    int          derSz = 0;
18693
    int          pkey_type;
18694
18695
    if (x509 == NULL || pkey == NULL) {
18696
        WOLFSSL_MSG("error: wolfSSL_X509_ACERT_verify: bad arg");
18697
        return WOLFSSL_FATAL_ERROR;
18698
    }
18699
18700
    WOLFSSL_ENTER("wolfSSL_X509_ACERT_verify");
18701
18702
    der = acert_get_der(x509, &derSz);
18703
18704
    if (der == NULL || derSz <= 0) {
18705
        WOLFSSL_MSG("error: wolfSSL_X509_ACERT_verify: get der failed");
18706
        return WOLFSSL_FATAL_ERROR;
18707
    }
18708
18709
    switch (pkey->type) {
18710
    case WC_EVP_PKEY_RSA:
18711
        pkey_type = RSAk;
18712
        break;
18713
18714
    case WC_EVP_PKEY_EC:
18715
        pkey_type = ECDSAk;
18716
        break;
18717
18718
    case WC_EVP_PKEY_DSA:
18719
        pkey_type = DSAk;
18720
        break;
18721
18722
    default:
18723
        WOLFSSL_MSG("error: wolfSSL_X509_ACERT_verify: unknown pkey type");
18724
        return WOLFSSL_FATAL_ERROR;
18725
    }
18726
18727
18728
    ret = VerifyX509Acert(der, (word32)derSz,
18729
                          (const byte *)pkey->pkey.ptr, pkey->pkey_sz,
18730
                          pkey_type, x509->heap);
18731
18732
    return ret == 0 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
18733
}
18734
18735
/* Loads an x509 attribute certificate from buffer, and returns
18736
 * pointer to new WOLFSSL_X509_ACERT struct on success.
18737
 *
18738
 * @param [in]  buf    The acert buffer to load.
18739
 * @param [in]  sz     The size of the buffer.
18740
 * @param [in]  format The format of the buffer data.
18741
 * @param [in]  heap   Dynamic memory allocation hint.
18742
 *
18743
 * @return  pointer to WOLFSSL_X509_ACERT on success.
18744
 * @return  NULL on error.
18745
 * */
18746
WOLFSSL_X509_ACERT * wolfSSL_X509_ACERT_load_certificate_buffer_ex(
18747
    const unsigned char* buf, int sz, int format, void * heap)
18748
{
18749
    int                  ret = 0;
18750
    WOLFSSL_X509_ACERT * x509 = NULL;
18751
    DerBuffer *          der = NULL;
18752
    WC_DECLARE_VAR(acert, DecodedAcert, 1, 0);
18753
18754
    WOLFSSL_ENTER("wolfSSL_X509_ACERT_load_certificate_buffer");
18755
18756
    if (format == WOLFSSL_FILETYPE_PEM) {
18757
    #ifdef WOLFSSL_PEM_TO_DER
18758
        ret = PemToDer(buf, sz, ACERT_TYPE, &der, heap, NULL, NULL);
18759
18760
        if (ret != 0 || der == NULL || der->buffer == NULL) {
18761
            WOLFSSL_ERROR(ret);
18762
18763
            if (der != NULL) {
18764
                FreeDer(&der);
18765
            }
18766
18767
            return NULL;
18768
        }
18769
    #else
18770
        WOLFSSL_ERROR(NOT_COMPILED_IN);
18771
        return NULL;
18772
    #endif
18773
    }
18774
    else {
18775
        ret = AllocDer(&der, (word32)sz, ACERT_TYPE, heap);
18776
18777
        if (ret != 0 || der == NULL || der->buffer == NULL) {
18778
            WOLFSSL_ERROR(ret);
18779
            return NULL;
18780
        }
18781
18782
        XMEMCPY(der->buffer, buf, sz);
18783
    }
18784
18785
    #ifdef WOLFSSL_SMALL_STACK
18786
    acert = (DecodedAcert*)XMALLOC(sizeof(DecodedAcert), heap,
18787
                                   DYNAMIC_TYPE_DCERT);
18788
    if (acert == NULL) {
18789
        WOLFSSL_ERROR(MEMORY_ERROR);
18790
        FreeDer(&der);
18791
        return NULL;
18792
    }
18793
    #endif
18794
18795
    InitDecodedAcert(acert, der->buffer, der->length, heap);
18796
18797
    ret = ParseX509Acert(acert, VERIFY_SKIP_DATE);
18798
18799
    if (ret == 0) {
18800
        x509 = wolfSSL_X509_ACERT_new_ex(heap);
18801
18802
        if (x509 != NULL) {
18803
            ret = CopyDecodedAcertToX509(x509, acert);
18804
18805
            if (ret != 0) {
18806
                wolfSSL_X509_ACERT_free(x509);
18807
                x509 = NULL;
18808
            }
18809
        }
18810
        else {
18811
            ret = MEMORY_ERROR;
18812
        }
18813
    }
18814
18815
    FreeDecodedAcert(acert);
18816
18817
    WC_FREE_VAR_EX(acert, heap, DYNAMIC_TYPE_DCERT);
18818
18819
    FreeDer(&der);
18820
18821
    if (ret != 0) {
18822
        WOLFSSL_ERROR(ret);
18823
    }
18824
18825
    return x509;
18826
}
18827
18828
WOLFSSL_X509_ACERT * wolfSSL_X509_ACERT_load_certificate_buffer(
18829
    const unsigned char* buf, int sz, int format)
18830
{
18831
    return wolfSSL_X509_ACERT_load_certificate_buffer_ex(buf, sz, format, NULL);
18832
}
18833
18834
/* Retrieve the signature from an ACERT.
18835
 *
18836
 * @param [in]       x509    the x509 attribute certificate
18837
 * @param [in, out]  buf     the signature buffer pointer
18838
 * @param [in, out]  bufSz   the signature buffer size pointer
18839
 *
18840
 * buf may be null, but bufSz is required. On success, sets
18841
 * bufSz pointer to signature length, and copies signature
18842
 * to buf if provided.
18843
 *
18844
 * Returns  WWOLFSSL_FATAL_ERROR if bufSz is null or too small.
18845
 * Returns  WOLFSSL_SUCCESS on success.
18846
 */
18847
int wolfSSL_X509_ACERT_get_signature(WOLFSSL_X509_ACERT* x509,
18848
                                     unsigned char* buf, int* bufSz)
18849
{
18850
    WOLFSSL_ENTER("wolfSSL_X509_ACERT_get_signature");
18851
18852
    if (x509 == NULL || bufSz == NULL) {
18853
        return WOLFSSL_FATAL_ERROR;
18854
    }
18855
18856
    /* If buf array is provided, it must be long enough. */
18857
    if (buf != NULL && *bufSz < (int)x509->sig.length) {
18858
        return WOLFSSL_FATAL_ERROR;
18859
    }
18860
18861
    if (buf != NULL) {
18862
        /* Copy in buffer if provided. */
18863
        XMEMCPY(buf, x509->sig.buffer, x509->sig.length);
18864
    }
18865
18866
    *bufSz = (int)x509->sig.length;
18867
18868
    return WOLFSSL_SUCCESS;
18869
}
18870
#endif /* WOLFSSL_ACERT && (OPENSSL_EXTRA_X509_SMALL || OPENSSL_EXTRA) */
18871
18872
#endif /* !NO_CERTS */
18873
18874
#endif /* !WOLFCRYPT_ONLY */
18875
18876
#endif /* WOLFSSL_X509_INCLUDED */