Coverage Report

Created: 2026-11-12 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-normal-math/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
        if (obj == NULL) {
1523
            XFREE(der, x509->heap, DYNAMIC_TYPE_X509_EXT);
1524
            return WOLFSSL_FAILURE;
1525
        }
1526
        XMEMCPY(der + idx, obj->obj, obj->objSz);
1527
        idx += obj->objSz;
1528
    }
1529
1530
    XFREE(x509->extKeyUsageSrc, x509->heap, DYNAMIC_TYPE_X509_EXT);
1531
    x509->extKeyUsageSrc   = der;
1532
    x509->extKeyUsageSz    = derSz;
1533
    x509->extKeyUsageCount = (word32)num;
1534
    x509->extKeyUsage      = usage;
1535
    x509->extKeyUsageCrit  = (byte)ext->crit;
1536
1537
    return WOLFSSL_SUCCESS;
1538
}
1539
1540
int wolfSSL_X509_add_ext(WOLFSSL_X509 *x509, WOLFSSL_X509_EXTENSION *ext,
1541
    int loc)
1542
{
1543
    int nid;
1544
1545
    WOLFSSL_ENTER("wolfSSL_X509_add_ext");
1546
1547
    if (!x509 || !ext || loc >= 0) {
1548
        WOLFSSL_MSG("Bad parameter");
1549
        return WOLFSSL_FAILURE;
1550
    }
1551
    nid = (ext->obj != NULL) ? ext->obj->type : ext->value.nid;
1552
1553
    switch (nid) {
1554
    case WC_NID_authority_key_identifier:
1555
        if (x509->authKeyIdSrc != NULL) {
1556
            /* If authKeyId points into authKeyIdSrc then free it and
1557
             * revert to old functionality */
1558
            XFREE(x509->authKeyIdSrc, x509->heap, DYNAMIC_TYPE_X509_EXT);
1559
            x509->authKeyIdSrc = NULL;
1560
            x509->authKeyId = NULL;
1561
        }
1562
        if (asn1_string_copy_to_buffer(&ext->value, &x509->authKeyId,
1563
                &x509->authKeyIdSz, x509->heap) != WOLFSSL_SUCCESS) {
1564
            WOLFSSL_MSG("asn1_string_copy_to_buffer error");
1565
            return WOLFSSL_FAILURE;
1566
        }
1567
        x509->authKeyIdCrit = (byte)ext->crit;
1568
        break;
1569
    case WC_NID_subject_key_identifier:
1570
        if (asn1_string_copy_to_buffer(&ext->value, &x509->subjKeyId,
1571
                &x509->subjKeyIdSz, x509->heap) != WOLFSSL_SUCCESS) {
1572
            WOLFSSL_MSG("asn1_string_copy_to_buffer error");
1573
            return WOLFSSL_FAILURE;
1574
        }
1575
        x509->subjKeyIdCrit = (byte)ext->crit;
1576
        break;
1577
    case WC_NID_subject_alt_name:
1578
        if (wolfssl_x509_add_subj_alt_name_ext(x509, ext) != WOLFSSL_SUCCESS) {
1579
            return WOLFSSL_FAILURE;
1580
        }
1581
        break;
1582
    case WC_NID_key_usage:
1583
        if (ext && ext->value.data) {
1584
            if (ext->value.length == sizeof(word16)) {
1585
                /* if ext->value is already word16, set directly */
1586
                word16 ku;
1587
                XMEMCPY(&ku, ext->value.data, sizeof(word16));
1588
                x509->keyUsage = ku;
1589
#ifdef BIG_ENDIAN_ORDER
1590
                x509->keyUsage = rotlFixed16(x509->keyUsage, 8U);
1591
#endif
1592
                x509->keyUsageCrit = (byte)ext->crit;
1593
                x509->keyUsageSet = 1;
1594
            }
1595
            else if (ext->value.length > 0) {
1596
                /* ext->value is comma-delimited string, convert to word16 */
1597
                if (ParseKeyUsageStr(ext->value.data, &x509->keyUsage,
1598
                                     x509->heap) != 0) {
1599
                    return WOLFSSL_FAILURE;
1600
                }
1601
                x509->keyUsageCrit = (byte)ext->crit;
1602
                x509->keyUsageSet = 1;
1603
            }
1604
            else {
1605
                return WOLFSSL_FAILURE;
1606
            }
1607
        }
1608
        break;
1609
    case WC_NID_ext_key_usage:
1610
        if (ext && ext->value.data) {
1611
            if (ext->value.length == sizeof(byte)) {
1612
                /* if ext->value is already 1 byte, set directly */
1613
                x509->extKeyUsage = *(byte*)ext->value.data;
1614
                x509->extKeyUsageCrit = (byte)ext->crit;
1615
            }
1616
            else if (ext->value.length > 0) {
1617
                /* ext->value is comma-delimited string, convert to word16 */
1618
                if (ParseExtKeyUsageStr(ext->value.data, &x509->extKeyUsage,
1619
                                        x509->heap) != 0) {
1620
                    return WOLFSSL_FAILURE;
1621
                }
1622
                x509->extKeyUsageCrit = (byte)ext->crit;
1623
            }
1624
            else {
1625
                return WOLFSSL_FAILURE;
1626
            }
1627
        }
1628
        else if (ext && ext->ext_sk != NULL) {
1629
            if (wolfssl_x509_add_ext_key_usage_sk(x509, ext) !=
1630
                    WOLFSSL_SUCCESS) {
1631
                return WOLFSSL_FAILURE;
1632
            }
1633
        }
1634
        /* No data and no object stack: nothing to set, treat as no-op like the
1635
         * WC_NID_key_usage case above. */
1636
        break;
1637
    case WC_NID_basic_constraints:
1638
        if (ext->obj) {
1639
            x509->isCa = (byte)ext->obj->ca;
1640
            x509->basicConstCrit = (byte)ext->crit;
1641
            if (ext->obj->pathlen) {
1642
                x509->pathLength = (word32)ext->obj->pathlen->length;
1643
                x509->basicConstPlSet = 1;
1644
                x509->pathLengthSet = 1;
1645
            }
1646
            x509->basicConstSet = 1;
1647
        }
1648
        break;
1649
    default:
1650
#ifdef WOLFSSL_CUSTOM_OID
1651
        if (wolfssl_x509_add_custom_ext(x509, ext) != WOLFSSL_SUCCESS) {
1652
            return WOLFSSL_FAILURE;
1653
        }
1654
        break;
1655
#else
1656
        WOLFSSL_MSG("Unsupported extension to add");
1657
        return WOLFSSL_FAILURE;
1658
#endif /* WOLFSSL_CUSTOM_OID */
1659
    } /* switch (nid) */
1660
1661
    return WOLFSSL_SUCCESS;
1662
}
1663
1664
/* Returns pointer to ASN1_STRING in X509_EXTENSION object */
1665
static WOLFSSL_ASN1_STRING* wolfSSL_X509_EXTENSION_get_data_internal(
1666
    WOLFSSL_X509_EXTENSION* ext)
1667
{
1668
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_get_data_internal");
1669
    if (ext == NULL)
1670
        return NULL;
1671
1672
    return &ext->value;
1673
}
1674
1675
1676
#ifndef NO_BIO
1677
1678
#ifndef MAX_INDENT
1679
    #define MAX_INDENT 40
1680
#endif
1681
1682
1683
/* Return 0 on success and 1 on failure. Copies ext data to bio, using indent
1684
 *  to pad the output. flag is ignored. */
1685
int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, WOLFSSL_X509_EXTENSION *ext,
1686
        unsigned long flag, int indent)
1687
{
1688
    WOLFSSL_ASN1_OBJECT* obj;
1689
    WOLFSSL_ASN1_STRING* str;
1690
    int nid;
1691
    int rc = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
1692
    char tmp[CTC_NAME_SIZE*2 + 1];
1693
    const int tmpSz = sizeof(tmp);
1694
    int tmpLen = 0;
1695
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_print");
1696
1697
    if (indent < 0) indent = 0;
1698
    if (indent > MAX_INDENT) indent = MAX_INDENT;
1699
1700
    if ((out == NULL) || (ext == NULL)) {
1701
        WOLFSSL_MSG("NULL parameter error");
1702
        return rc;
1703
    }
1704
1705
    obj = wolfSSL_X509_EXTENSION_get_object(ext);
1706
    if (obj == NULL) {
1707
        WOLFSSL_MSG("Error getting ASN1_OBJECT from X509_EXTENSION");
1708
        return rc;
1709
    }
1710
1711
    str = wolfSSL_X509_EXTENSION_get_data_internal(ext);
1712
    if (str == NULL) {
1713
        WOLFSSL_MSG("Error getting ASN1_STRING from X509_EXTENSION");
1714
        return rc;
1715
    }
1716
1717
    /* Print extension based on the type */
1718
    nid = wolfSSL_OBJ_obj2nid(obj);
1719
    switch (nid) {
1720
        case BASIC_CA_OID:
1721
        {
1722
            char isCa[] = "TRUE";
1723
            char notCa[] = "FALSE";
1724
            if ((tmpLen = XSNPRINTF(tmp, tmpSz, "%*sCA:%s", indent, "",
1725
                                     obj->ca ? isCa : notCa))
1726
                >= tmpSz)
1727
                return rc;
1728
            break;
1729
        }
1730
        case ALT_NAMES_OID:
1731
        {
1732
            WOLFSSL_STACK* sk;
1733
            char* val;
1734
            int valLen;
1735
            int len;
1736
1737
            sk = ext->ext_sk;
1738
            while (sk != NULL) {
1739
                if (sk->type == STACK_TYPE_GEN_NAME && sk->data.gn) {
1740
                    /* str is GENERAL_NAME for subject alternative name ext */
1741
                    str = sk->data.gn->d.ia5;
1742
                    len = str->length + 2; /* + 2 for NULL char and "," */
1743
                    if (len > tmpSz) {
1744
                        WOLFSSL_MSG("len greater than buffer size");
1745
                        return rc;
1746
                    }
1747
1748
                    val = (char*)XMALLOC(len + indent, NULL,
1749
                                                       DYNAMIC_TYPE_TMP_BUFFER);
1750
                    if (val == NULL) {
1751
                        WOLFSSL_MSG("Memory error");
1752
                        return rc;
1753
                    }
1754
                    valLen = XSNPRINTF(val, (size_t)len + indent,
1755
                            "%*s%.*s", indent, "", str->length, str->data);
1756
                    if ((valLen < 0) || (valLen >= len + indent)
1757
                            || ((tmpLen + valLen) >= tmpSz)) {
1758
                        XFREE(val, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1759
                        return rc;
1760
                    }
1761
                    XMEMCPY(tmp + tmpLen, val, valLen);
1762
                    tmpLen += valLen;
1763
                    XFREE(val, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1764
                }
1765
                sk = sk->next;
1766
            }
1767
            break;
1768
        }
1769
        case AUTH_KEY_OID:
1770
        case SUBJ_KEY_OID:
1771
        {
1772
            char* asn1str;
1773
            asn1str = wolfSSL_i2s_ASN1_STRING(NULL, str);
1774
            if (asn1str == NULL) {
1775
                WOLFSSL_MSG("wolfSSL_i2s_ASN1_STRING returned NULL");
1776
                return rc;
1777
            }
1778
            tmpLen = XSNPRINTF(tmp, tmpSz, "%*s%.*s", indent, "",
1779
                    tmpSz - 1 - indent, asn1str);
1780
            XFREE(asn1str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1781
            if (tmpLen >= tmpSz)
1782
                tmpLen = tmpSz - 1;
1783
            break;
1784
        }
1785
        case AUTH_INFO_OID:
1786
        case CERT_POLICY_OID:
1787
        case CRL_DIST_OID:
1788
        case KEY_USAGE_OID:
1789
            WOLFSSL_MSG("X509V3_EXT_print not yet implemented for ext type");
1790
            break;
1791
1792
        default:
1793
            if ((tmpLen = XSNPRINTF(
1794
                     tmp, tmpSz, "%*s%s", indent, "", str->strData))
1795
                >= tmpSz)
1796
                return rc;
1797
    }
1798
1799
    if (wolfSSL_BIO_write(out, tmp, tmpLen) == tmpLen) {
1800
        rc = WOLFSSL_SUCCESS;
1801
    }
1802
    (void) flag;
1803
1804
    return rc;
1805
}
1806
#endif /* !NO_BIO */
1807
1808
#ifndef NO_WOLFSSL_STUB
1809
int wolfSSL_X509V3_EXT_add_nconf(WOLFSSL_CONF *conf, WOLFSSL_X509V3_CTX *ctx,
1810
        const char *section, WOLFSSL_X509 *cert)
1811
{
1812
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_add_nconf");
1813
    WOLFSSL_STUB("wolfSSL_X509V3_EXT_add_nconf");
1814
    (void)conf;
1815
    (void)ctx;
1816
    (void)section;
1817
    (void)cert;
1818
    return WOLFSSL_SUCCESS;
1819
}
1820
#endif
1821
1822
/* Find extension by NID in a stack of extensions.
1823
 *
1824
 * @param sk Stack of extensions
1825
 * @param nid ID to search for
1826
 * @param lastpos Start search from this position (not inclusive, -1 means start from beginning)
1827
 * @return Index of matching extension or -1 on error/not found
1828
 */
1829
int wolfSSL_X509v3_get_ext_by_NID(const WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk,
1830
                                 int nid, int lastpos)
1831
{
1832
    int i;
1833
    WOLFSSL_ENTER("wolfSSL_X509v3_get_ext_by_NID");
1834
1835
    if (sk == NULL) {
1836
        WOLFSSL_MSG("Stack pointer is NULL");
1837
        return WOLFSSL_FATAL_ERROR;
1838
    }
1839
1840
    if (lastpos < -1 || lastpos >= wolfSSL_sk_num(sk)) {
1841
        WOLFSSL_MSG("Invalid position argument");
1842
        return WOLFSSL_FATAL_ERROR;
1843
    }
1844
1845
    for (i = lastpos + 1; i < wolfSSL_sk_num(sk); i++) {
1846
        WOLFSSL_X509_EXTENSION* ext = wolfSSL_sk_X509_EXTENSION_value(sk, i);
1847
        if (ext && ext->obj) {
1848
            if (wolfSSL_OBJ_obj2nid(ext->obj) == nid)
1849
                return i;
1850
        }
1851
    }
1852
1853
    /* Not found */
1854
    return -1;
1855
}
1856
1857
/* Get extension from a stack of extensions by location.
1858
 *
1859
 * @param sk Stack of extensions
1860
 * @param loc Index of extension to retrieve
1861
 * @return Pointer to extension or NULL on error
1862
 */
1863
WOLFSSL_X509_EXTENSION* wolfSSL_X509v3_get_ext(
1864
    const WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk, int loc)
1865
{
1866
    WOLFSSL_ENTER("wolfSSL_X509v3_get_ext");
1867
1868
    if (sk == NULL) {
1869
        WOLFSSL_MSG("Stack pointer is NULL");
1870
        return NULL;
1871
    }
1872
1873
    if (loc < 0 || loc >= wolfSSL_sk_num(sk)) {
1874
        WOLFSSL_MSG("Invalid location argument");
1875
        return NULL;
1876
    }
1877
1878
    return wolfSSL_sk_X509_EXTENSION_value(sk, loc);
1879
}
1880
1881
/* Returns crit flag in X509_EXTENSION object */
1882
int wolfSSL_X509_EXTENSION_get_critical(const WOLFSSL_X509_EXTENSION* ex)
1883
{
1884
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_get_critical");
1885
    if (ex == NULL)
1886
        return BAD_FUNC_ARG;
1887
    return ex->crit;
1888
}
1889
1890
/* Sets if the extension is critical
1891
 * returns WOLFSSL_SUCCESS on success
1892
 */
1893
int wolfSSL_X509_EXTENSION_set_critical(WOLFSSL_X509_EXTENSION* ex, int crit)
1894
{
1895
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_set_critical");
1896
    if (ex == NULL)
1897
        return WOLFSSL_FAILURE;
1898
    ex->crit = crit;
1899
    return WOLFSSL_SUCCESS;
1900
}
1901
1902
/* Creates v3_ext_method for a given X509v3 extension
1903
 *
1904
 * ex   : The X509_EXTENSION used to create v3_ext_method. If the extension is
1905
 * not NULL, get the NID of the extension object and populate the
1906
 * extension type-specific X509V3_EXT_* function(s) in v3_ext_method.
1907
 *
1908
 * Returns NULL on error or pointer to the v3_ext_method populated with
1909
 * extension type-specific X509V3_EXT_* function(s).
1910
 *
1911
 * NOTE: WC_NID_subject_key_identifier is currently the only extension
1912
 * implementing the X509V3_EXT_* functions, as it is the only type called
1913
 * directly by QT. The other extension types return a pointer to a
1914
 * v3_ext_method struct that contains only the NID.
1915
 */
1916
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
1917
const WOLFSSL_v3_ext_method* wolfSSL_X509V3_EXT_get(WOLFSSL_X509_EXTENSION* ex)
1918
#else
1919
WOLFSSL_v3_ext_method* wolfSSL_X509V3_EXT_get(WOLFSSL_X509_EXTENSION* ex)
1920
#endif
1921
{
1922
    int nid;
1923
    WOLFSSL_v3_ext_method method;
1924
1925
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_get");
1926
    if ((ex == NULL) || (ex->obj == NULL)) {
1927
        WOLFSSL_MSG("Passed an invalid X509_EXTENSION*");
1928
        return NULL;
1929
    }
1930
    /* Initialize method to 0 */
1931
    XMEMSET(&method, 0, sizeof(struct WOLFSSL_v3_ext_method));
1932
1933
    nid = ex->obj->nid;
1934
    if (nid <= 0) {
1935
        WOLFSSL_MSG("Failed to get nid from passed extension object");
1936
        return NULL;
1937
    }
1938
    switch (nid) {
1939
        case WC_NID_basic_constraints:
1940
            break;
1941
        case WC_NID_subject_key_identifier:
1942
            method.i2s = (WOLFSSL_X509V3_EXT_I2S)wolfSSL_i2s_ASN1_STRING;
1943
            break;
1944
        case WC_NID_subject_alt_name:
1945
            WOLFSSL_MSG("i2v function not yet implemented for Subject "
1946
                        "Alternative Name");
1947
            break;
1948
        case WC_NID_key_usage:
1949
            WOLFSSL_MSG("i2v function not yet implemented for Key Usage");
1950
            break;
1951
        case WC_NID_authority_key_identifier:
1952
            WOLFSSL_MSG("i2v function not yet implemented for Auth Key Id");
1953
            break;
1954
        case WC_NID_info_access:
1955
            WOLFSSL_MSG("i2v function not yet implemented for Info Access");
1956
            break;
1957
        case WC_NID_ext_key_usage:
1958
            WOLFSSL_MSG("i2v function not yet implemented for Ext Key Usage");
1959
            break;
1960
        case WC_NID_certificate_policies:
1961
            WOLFSSL_MSG("r2i function not yet implemented for Cert Policies");
1962
            break;
1963
        case WC_NID_crl_distribution_points:
1964
            WOLFSSL_MSG("r2i function not yet implemented for CRL Dist Points");
1965
            break;
1966
        default:
1967
            /* If extension type is unknown, return NULL -- QT makes call to
1968
                X509_EXTENSION_get_data() if there is no v3_ext_method */
1969
            WOLFSSL_MSG("X509V3_EXT_get(): Unknown extension type found");
1970
            return NULL;
1971
    }
1972
1973
    method.ext_nid = nid;
1974
    ex->ext_method = method;
1975
1976
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
1977
    return (const WOLFSSL_v3_ext_method*)&ex->ext_method;
1978
#else
1979
    return (WOLFSSL_v3_ext_method*)&ex->ext_method;
1980
#endif
1981
}
1982
1983
/* Create an Authority Info Access (AIA) from the contents of the extension.
1984
 *
1985
 * AIA is a stack of Access Descriptions.
1986
 *
1987
 * RFC 5280: 4.2.2.1
1988
 *
1989
 * @param [in] ext  X509v3 extension.
1990
 * @return  Stack of Access Descriptions as an AIA on success.
1991
 * @return  NULL on error.
1992
 */
1993
static WOLFSSL_AUTHORITY_INFO_ACCESS* wolfssl_x509v3_ext_aia_d2i(
1994
    WOLFSSL_X509_EXTENSION* ext)
1995
{
1996
    int err = 0;
1997
    int ret;
1998
    WOLFSSL_AUTHORITY_INFO_ACCESS* aia = NULL;
1999
    WOLFSSL_STACK* sk;
2000
    WOLFSSL_ACCESS_DESCRIPTION* ad = NULL;
2001
2002
    /* Get the type specific data of this extension. */
2003
    sk = ext->ext_sk;
2004
    if (sk == NULL) {
2005
        WOLFSSL_MSG("ACCESS_DESCRIPTION stack NULL");
2006
        err = 1;
2007
    }
2008
2009
    if (!err) {
2010
        /* AUTHORITY_INFO_ACCESS is a stack of ACCESS_DESCRIPTION entries. */
2011
        aia = wolfSSL_sk_new_null();
2012
        if (aia == NULL) {
2013
            WOLFSSL_MSG("Failed to malloc AUTHORITY_INFO_ACCESS");
2014
            err = 1;
2015
        }
2016
    }
2017
    if (!err) {
2018
        /* AIA is a stack of Access Descriptions. */
2019
        aia->type = STACK_TYPE_ACCESS_DESCRIPTION;
2020
    }
2021
2022
    while ((!err) && (sk != NULL)) {
2023
        WOLFSSL_ASN1_OBJECT* aiaEntry;
2024
2025
        /* Looking for objects in extension's data. */
2026
        if (sk->type != STACK_TYPE_OBJ) {
2027
            sk = sk->next;
2028
            continue;
2029
        }
2030
2031
        /* Get ASN.1 Object from the stack entry's data. */
2032
        aiaEntry = sk->data.obj;
2033
2034
        /* ACCESS_DESCRIPTION has two members: method and location.
2035
         *  method: ASN1_OBJECT as either AIA_OCSP_OID or AIA_CA_ISSUER_OID
2036
         *  location: GENERAL_NAME structure containing the URI.
2037
         */
2038
2039
        /* Allocate a new Access Description. */
2040
        ad = (WOLFSSL_ACCESS_DESCRIPTION*)XMALLOC(
2041
            sizeof(WOLFSSL_ACCESS_DESCRIPTION), NULL, DYNAMIC_TYPE_X509_EXT);
2042
        if (ad == NULL) {
2043
            WOLFSSL_MSG("Failed to malloc ACCESS_DESCRIPTION");
2044
            err = 1;
2045
            break;
2046
        }
2047
        XMEMSET(ad, 0, sizeof(WOLFSSL_ACCESS_DESCRIPTION));
2048
2049
        /* Create new ASN1_OBJECT from NID. */
2050
        ad->method = wolfSSL_OBJ_nid2obj(aiaEntry->nid);
2051
        if (ad->method == NULL) {
2052
            WOLFSSL_MSG("OBJ_nid2obj() failed");
2053
            err = 1;
2054
            break;
2055
        }
2056
2057
        /* Allocate memory for GENERAL NAME. */
2058
        ad->location = wolfSSL_GENERAL_NAME_new();
2059
        if (ad->location == NULL) {
2060
            WOLFSSL_MSG("Failed to malloc GENERAL_NAME");
2061
            err = 1;
2062
            break;
2063
        }
2064
2065
        /* Set the type of general name to URI (only type supported). */
2066
        ret = wolfSSL_GENERAL_NAME_set_type(ad->location, WOLFSSL_GEN_URI);
2067
        if (ret != WOLFSSL_SUCCESS) {
2068
            err = 1;
2069
            break;
2070
        }
2071
2072
        /* Set the URI into GENERAL_NAME. */
2073
        ret = wolfSSL_ASN1_STRING_set(ad->location->d.uniformResourceIdentifier,
2074
            aiaEntry->obj, aiaEntry->objSz);
2075
        if (ret != WOLFSSL_SUCCESS) {
2076
            WOLFSSL_MSG("ASN1_STRING_set() failed");
2077
            err = 1;
2078
            break;
2079
        }
2080
        /* Push onto AUTHORITY_INFO_ACCESS stack. */
2081
        ret = wolfSSL_sk_ACCESS_DESCRIPTION_push(aia, ad) > 0
2082
                ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
2083
        if (ret != WOLFSSL_SUCCESS) {
2084
            WOLFSSL_MSG("Error pushing ASN1 AD onto stack");
2085
            err = 1;
2086
            break;
2087
        }
2088
        /* Set to NULL so that it doesn't get freed now it is in AIA stack. */
2089
        ad = NULL;
2090
2091
        sk = sk->next;
2092
    }
2093
2094
    if (err) {
2095
        /* Dispose of Access Description if not put in stack. */
2096
        if (ad != NULL) {
2097
            wolfSSL_ASN1_OBJECT_free(ad->method);
2098
            wolfSSL_GENERAL_NAME_free(ad->location);
2099
            XFREE(ad, NULL, DYNAMIC_TYPE_X509_EXT);
2100
        }
2101
        /* Dispose of incomplete Access Description stack. */
2102
        wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(aia, NULL);
2103
        aia = NULL;
2104
    }
2105
    return aia;
2106
}
2107
2108
/* Parses and returns an x509v3 extension internal structure.
2109
 *
2110
 * ext   : The X509_EXTENSION for parsing internal structure. If extension is
2111
 * not NULL, get the NID of the extension object and create a new
2112
 * extension-specific internal structure based on the extension type.
2113
 *
2114
 * Returns NULL on error or if NID is not found, otherwise returns a pointer to
2115
 * the extension type-specific X509_EXTENSION internal structure.
2116
 * Return is expected to be free'd by caller.
2117
 */
2118
void* wolfSSL_X509V3_EXT_d2i(WOLFSSL_X509_EXTENSION* ext)
2119
{
2120
    const WOLFSSL_v3_ext_method* method;
2121
    int ret;
2122
    WOLFSSL_ASN1_OBJECT* object;
2123
    WOLFSSL_BASIC_CONSTRAINTS* bc;
2124
    WOLFSSL_AUTHORITY_KEYID* akey;
2125
    WOLFSSL_ASN1_STRING* asn1String = NULL, *newString = NULL;
2126
    WOLFSSL_STACK* sk;
2127
    void *data = NULL;
2128
    WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
2129
2130
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_d2i");
2131
2132
    if (ext == NULL) {
2133
        WOLFSSL_MSG("Bad function Argument");
2134
        return NULL;
2135
    }
2136
2137
    object = wolfSSL_X509_EXTENSION_get_object(ext);
2138
    if (object == NULL) {
2139
        WOLFSSL_MSG("X509_EXTENSION_get_object failed");
2140
        return NULL;
2141
    }
2142
    /* extract extension info */
2143
    method = wolfSSL_X509V3_EXT_get(ext);
2144
    if (method == NULL) {
2145
        WOLFSSL_MSG("wolfSSL_X509V3_EXT_get error");
2146
        return NULL;
2147
    }
2148
2149
#ifdef WOLFSSL_SMALL_STACK
2150
    cert = (DecodedCert *)XMALLOC(sizeof(*cert), NULL,
2151
            DYNAMIC_TYPE_X509_EXT);
2152
    if (cert == NULL) {
2153
        WOLFSSL_MSG("\tout of memory");
2154
        return NULL;
2155
    }
2156
#endif
2157
2158
    InitDecodedCert(cert, NULL, 0, NULL);
2159
2160
    if ((object->type != WC_NID_basic_constraints) &&
2161
        (object->type != WC_NID_subject_alt_name) &&
2162
        (object->type != WC_NID_info_access)) {
2163
2164
        asn1String = wolfSSL_X509_EXTENSION_get_data_internal(ext);
2165
        if (asn1String == NULL) {
2166
            WOLFSSL_MSG("X509_EXTENSION_get_data() failed");
2167
            goto out;
2168
        }
2169
2170
        ret = DecodeExtensionType((const byte*)asn1String->data,
2171
                asn1String->length, object->type, (byte)ext->crit, cert, NULL);
2172
        if (ret != 0) {
2173
            WOLFSSL_MSG("DecodeExtensionType() failed");
2174
            goto out;
2175
        }
2176
    }
2177
2178
    /* Return pointer to proper internal structure based on NID */
2179
    switch (object->type) {
2180
        /* basicConstraints */
2181
        case WC_NID_basic_constraints:
2182
            WOLFSSL_MSG("basicConstraints");
2183
            /* Allocate new BASIC_CONSTRAINTS structure */
2184
            bc = wolfSSL_BASIC_CONSTRAINTS_new();
2185
            if (bc == NULL) {
2186
                WOLFSSL_MSG("Failed to malloc basic constraints");
2187
                break;
2188
            }
2189
            /* Copy pathlen and CA into BASIC_CONSTRAINTS from object */
2190
            bc->ca = object->ca;
2191
            /* RFC 5280 4.2.1.9:
2192
             *   "A pathLenConstraint of zero indicates that no non-self-issued
2193
             *    intermediate CA certificates may follow in a valid
2194
             *    certification path."
2195
             * Check for length of 0 or greater.
2196
             */
2197
            if ((object->pathlen != NULL) && (object->pathlen->length >= 0)) {
2198
                bc->pathlen = wolfSSL_ASN1_INTEGER_dup(object->pathlen);
2199
                if (bc->pathlen == NULL) {
2200
                    WOLFSSL_MSG("Failed to duplicate ASN1_INTEGER");
2201
                    wolfSSL_BASIC_CONSTRAINTS_free(bc);
2202
                    break;
2203
                }
2204
            }
2205
            else
2206
                bc->pathlen = NULL;
2207
2208
            data = bc;
2209
            break;
2210
2211
        /* subjectKeyIdentifier */
2212
        case WC_NID_subject_key_identifier:
2213
        {
2214
            WOLFSSL_MSG("subjectKeyIdentifier");
2215
2216
            newString = wolfSSL_ASN1_STRING_new();
2217
            if (newString == NULL) {
2218
                WOLFSSL_MSG("Failed to malloc ASN1_STRING");
2219
                break;
2220
            }
2221
            ret = wolfSSL_ASN1_STRING_set(newString, cert->extSubjKeyId,
2222
                                          cert->extSubjKeyIdSz);
2223
            if (ret != WOLFSSL_SUCCESS) {
2224
                WOLFSSL_MSG("ASN1_STRING_set() failed");
2225
                wolfSSL_ASN1_STRING_free(newString);
2226
                break;
2227
            };
2228
2229
            newString->type = asn1String->type;
2230
            data = newString;
2231
            break;
2232
        }
2233
2234
        /* authorityKeyIdentifier */
2235
        case WC_NID_authority_key_identifier:
2236
        {
2237
            WOLFSSL_MSG("AuthorityKeyIdentifier");
2238
2239
            akey = (WOLFSSL_AUTHORITY_KEYID*)
2240
                    XMALLOC(sizeof(WOLFSSL_AUTHORITY_KEYID), NULL,
2241
                    DYNAMIC_TYPE_X509_EXT);
2242
            if (akey == NULL) {
2243
                WOLFSSL_MSG("Failed to malloc authority key id");
2244
                break;
2245
            }
2246
2247
            XMEMSET(akey, 0, sizeof(WOLFSSL_AUTHORITY_KEYID));
2248
2249
            akey->keyid = wolfSSL_ASN1_STRING_new();
2250
            if (akey->keyid == NULL) {
2251
                WOLFSSL_MSG("ASN1_STRING_new() failed");
2252
                wolfSSL_AUTHORITY_KEYID_free(akey);
2253
                break;
2254
            }
2255
2256
            ret = wolfSSL_ASN1_STRING_set(akey->keyid, cert->extAuthKeyId,
2257
                                          cert->extAuthKeyIdSz);
2258
            if (ret != WOLFSSL_SUCCESS) {
2259
                WOLFSSL_MSG("ASN1_STRING_set() failed");
2260
                wolfSSL_AUTHORITY_KEYID_free(akey);
2261
                break;
2262
            };
2263
            akey->keyid->type   = asn1String->type;
2264
2265
            /* For now, set issuer and serial to NULL. This may need to be
2266
                updated for future use */
2267
            akey->issuer = NULL;
2268
            akey->serial = NULL;
2269
2270
            data = akey;
2271
            break;
2272
        }
2273
2274
        /* keyUsage */
2275
        case WC_NID_key_usage:
2276
        {
2277
            WOLFSSL_MSG("keyUsage");
2278
2279
            /* This may need to be updated for future use. The i2v method for
2280
                keyUsage is not currently set. For now, return the ASN1_STRING
2281
                representation of KeyUsage bit string */
2282
            newString = wolfSSL_ASN1_STRING_new();
2283
            if (newString == NULL) {
2284
                WOLFSSL_MSG("Failed to malloc ASN1_STRING");
2285
                break;
2286
            }
2287
            ret = wolfSSL_ASN1_STRING_set(newString, (byte*)&cert->extKeyUsage,
2288
                                                                sizeof(word16));
2289
            if (ret != WOLFSSL_SUCCESS) {
2290
                WOLFSSL_MSG("ASN1_STRING_set() failed");
2291
                wolfSSL_ASN1_STRING_free(newString);
2292
                break;
2293
            };
2294
            newString->type = asn1String->type;
2295
            data = newString;
2296
            break;
2297
        }
2298
2299
        /* extKeyUsage */
2300
        case WC_NID_ext_key_usage:
2301
            WOLFSSL_MSG("extKeyUsage not supported yet");
2302
            break;
2303
2304
        /* certificatePolicies */
2305
        case WC_NID_certificate_policies:
2306
            WOLFSSL_MSG("certificatePolicies not supported yet");
2307
            break;
2308
2309
        /* cRLDistributionPoints */
2310
        case WC_NID_crl_distribution_points:
2311
            WOLFSSL_MSG("cRLDistributionPoints not supported yet");
2312
            break;
2313
2314
        case WC_NID_subject_alt_name:
2315
            if (ext->ext_sk == NULL) {
2316
                WOLFSSL_MSG("Subject alt name stack NULL");
2317
                break;
2318
            }
2319
            sk = wolfSSL_sk_dup(ext->ext_sk);
2320
            if (sk == NULL) {
2321
                WOLFSSL_MSG("Failed to duplicate subject alt names stack.");
2322
                break;
2323
            }
2324
            data = sk;
2325
            break;
2326
2327
        /* authorityInfoAccess */
2328
        case WC_NID_info_access:
2329
            WOLFSSL_MSG("AuthorityInfoAccess");
2330
            data = wolfssl_x509v3_ext_aia_d2i(ext);
2331
            break;
2332
2333
        default:
2334
            WOLFSSL_MSG("Extension NID not in table, returning NULL");
2335
            break;
2336
    }
2337
2338
out:
2339
2340
    FreeDecodedCert(cert);
2341
    WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_X509_EXT);
2342
2343
    return data;
2344
}
2345
2346
/* Looks for the extension matching the passed in nid
2347
 *
2348
 * x509 : certificate to get parse through for extension.
2349
 * nid : Extension OID to be found.
2350
 * lastPos : Start search from extension after lastPos.
2351
 *           Set to -1 to search from index 0.
2352
 * return >= 0 If successful the extension index is returned.
2353
 * return WOLFSSL_FATAL_ERROR If extension is not found or error is encountered.
2354
 */
2355
int wolfSSL_X509_get_ext_by_NID(const WOLFSSL_X509* x509, int nid, int lastPos)
2356
{
2357
    int extCount = 0, length = 0, outSz = 0, sz = 0, ret = 0;
2358
    int isSet = 0, found = 0, loc;
2359
    const byte* rawCert;
2360
    const byte* input;
2361
    word32 oid, idx = 0, tmpIdx = 0, foundNID;
2362
    WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
2363
2364
    WOLFSSL_ENTER("wolfSSL_X509_get_ext_by_NID");
2365
2366
    if (x509 == NULL) {
2367
        WOLFSSL_MSG("\tNot passed a certificate");
2368
        return WOLFSSL_FATAL_ERROR;
2369
    }
2370
2371
    if (lastPos < -1 || (lastPos > (wolfSSL_X509_get_ext_count(x509) - 1))) {
2372
        WOLFSSL_MSG("\tBad location argument");
2373
        return WOLFSSL_FATAL_ERROR;
2374
    }
2375
2376
    loc = lastPos + 1;
2377
2378
    rawCert = wolfSSL_X509_get_der((WOLFSSL_X509*)x509, &outSz);
2379
    if (rawCert == NULL) {
2380
        WOLFSSL_MSG("\tX509_get_der() failed");
2381
        return WOLFSSL_FATAL_ERROR;
2382
    }
2383
2384
#ifdef WOLFSSL_SMALL_STACK
2385
    cert = (DecodedCert *)XMALLOC(sizeof(*cert), x509->heap,
2386
                                  DYNAMIC_TYPE_DCERT);
2387
    if (cert == NULL) {
2388
        WOLFSSL_MSG("\tout of memory");
2389
        return WOLFSSL_FATAL_ERROR;
2390
    }
2391
#endif
2392
2393
    InitDecodedCert( cert, rawCert, (word32)outSz, 0);
2394
2395
    if (ParseCert(cert,
2396
#ifdef WOLFSSL_CERT_REQ
2397
            x509->isCSR ? CERTREQ_TYPE :
2398
#endif
2399
            CA_TYPE,
2400
            NO_VERIFY, NULL) < 0) {
2401
        WOLFSSL_MSG("\tCertificate parsing failed");
2402
        goto out;
2403
    }
2404
2405
    input = cert->extensions;
2406
    sz = cert->extensionsSz;
2407
2408
    if (input == NULL || sz == 0) {
2409
        WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
2410
        goto out;
2411
    }
2412
2413
#ifdef WOLFSSL_CERT_REQ
2414
    if (!x509->isCSR)
2415
#endif
2416
    {
2417
        if (input[idx++] != ASN_EXTENSIONS) {
2418
            WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
2419
            goto out;
2420
        }
2421
2422
        if (GetLength(input, &idx, &length, (word32)sz) < 0) {
2423
            WOLFSSL_MSG("\tfail: invalid length");
2424
            goto out;
2425
        }
2426
    }
2427
2428
    if (GetSequence(input, &idx, &length, (word32)sz) < 0) {
2429
        WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
2430
        goto out;
2431
    }
2432
2433
    while (idx < (word32)sz) {
2434
        oid = 0;
2435
2436
        if (GetSequence(input, &idx, &length, (word32)sz) < 0) {
2437
            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
2438
            goto out;
2439
        }
2440
2441
        tmpIdx = idx;
2442
        ret = GetObjectId(input, &idx, &oid, oidCertExtType, (word32)sz);
2443
        if (ret < 0) {
2444
            WOLFSSL_MSG("\tfail: OBJECT ID");
2445
            goto out;
2446
        }
2447
        idx = tmpIdx;
2448
        foundNID = (word32)oid2nid(oid, oidCertExtType);
2449
2450
        if (extCount >= loc) {
2451
            /* extCount >= loc. Now check if extension has been set */
2452
            isSet = wolfSSL_X509_ext_isSet_by_NID((WOLFSSL_X509*)x509,
2453
                (int)foundNID);
2454
            if (isSet && ((word32)nid == foundNID)) {
2455
                found = 1;
2456
                break;
2457
            }
2458
        }
2459
2460
        idx += length;
2461
        extCount++;
2462
    } /* while(idx < sz) */
2463
2464
out:
2465
2466
    FreeDecodedCert(cert);
2467
    WC_FREE_VAR_EX(cert, x509->heap, DYNAMIC_TYPE_DCERT);
2468
2469
    return found ? extCount : WOLFSSL_FATAL_ERROR;
2470
}
2471
2472
#endif /* OPENSSL_ALL || OPENSSL_EXTRA */
2473
2474
#if defined(OPENSSL_EXTRA) && !defined(IGNORE_NAME_CONSTRAINTS)
2475
/*
2476
 * Convert a Base_entry linked list to a STACK of GENERAL_SUBTREE.
2477
 *
2478
 * Base_entry stores name constraint data from DecodedCert. This function
2479
 * converts it to GENERAL_SUBTREE format.
2480
 *
2481
 * Supported types: ASN_DNS_TYPE, ASN_RFC822_TYPE, ASN_DIR_TYPE, ASN_IP_TYPE,
2482
 *                  ASN_URI_TYPE
2483
 *
2484
 * Returns 0 on success, negative on error.
2485
 */
2486
static int ConvertBaseEntryToSubtreeStack(Base_entry* list, WOLFSSL_STACK* sk,
2487
                                          void* heap)
2488
{
2489
    Base_entry* entry = list;
2490
    WOLFSSL_GENERAL_SUBTREE* subtree = NULL;
2491
    WOLFSSL_GENERAL_NAME* gn = NULL;
2492
    (void)heap;
2493
2494
    while (entry != NULL) {
2495
2496
        if (entry->type != ASN_DNS_TYPE && entry->type != ASN_RFC822_TYPE &&
2497
            entry->type != ASN_DIR_TYPE && entry->type != ASN_IP_TYPE &&
2498
            entry->type != ASN_URI_TYPE) {
2499
            entry = entry->next;
2500
            continue;
2501
        }
2502
2503
        /* Allocate subtree and general name */
2504
        subtree = (WOLFSSL_GENERAL_SUBTREE*)XMALLOC(
2505
            sizeof(WOLFSSL_GENERAL_SUBTREE), heap, DYNAMIC_TYPE_OPENSSL);
2506
        if (subtree == NULL) {
2507
            WOLFSSL_MSG("Failed to allocate GENERAL_SUBTREE");
2508
            return MEMORY_E;
2509
        }
2510
        XMEMSET(subtree, 0, sizeof(WOLFSSL_GENERAL_SUBTREE));
2511
2512
        gn = wolfSSL_GENERAL_NAME_new();
2513
        if (gn == NULL) {
2514
            WOLFSSL_MSG("Failed to allocate GENERAL_NAME");
2515
            XFREE(subtree, heap, DYNAMIC_TYPE_OPENSSL);
2516
            return MEMORY_E;
2517
        }
2518
2519
        /* Free default ia5 string allocated by GENERAL_NAME_new */
2520
        wolfSSL_ASN1_STRING_free(gn->d.ia5);
2521
        gn->d.ia5 = NULL;
2522
2523
        switch (entry->type) {
2524
            case ASN_DNS_TYPE:
2525
            case ASN_RFC822_TYPE:
2526
            case ASN_URI_TYPE:
2527
            {
2528
                if (entry->type == ASN_DNS_TYPE) {
2529
                    gn->type = WOLFSSL_GEN_DNS;
2530
                }
2531
                else if (entry->type == ASN_RFC822_TYPE) {
2532
                    gn->type = WOLFSSL_GEN_EMAIL;
2533
                }
2534
                else {
2535
                    gn->type = WOLFSSL_GEN_URI;
2536
                }
2537
                gn->d.ia5 = wolfSSL_ASN1_STRING_new();
2538
                if (gn->d.ia5 == NULL) {
2539
                    WOLFSSL_MSG("Failed to allocate ASN1_STRING");
2540
                    wolfSSL_GENERAL_NAME_free(gn);
2541
                    XFREE(subtree, heap, DYNAMIC_TYPE_OPENSSL);
2542
                    return MEMORY_E;
2543
                }
2544
                if (wolfSSL_ASN1_STRING_set(gn->d.ia5, entry->name,
2545
                        entry->nameSz) != WOLFSSL_SUCCESS) {
2546
                    WOLFSSL_MSG("Failed to set ASN1_STRING");
2547
                    wolfSSL_GENERAL_NAME_free(gn);
2548
                    XFREE(subtree, heap, DYNAMIC_TYPE_OPENSSL);
2549
                    return MEMORY_E;
2550
                }
2551
                gn->d.ia5->type = WOLFSSL_V_ASN1_IA5STRING;
2552
                break;
2553
            }
2554
2555
            case ASN_DIR_TYPE:
2556
            {
2557
                byte* seqBuf = NULL;
2558
                unsigned char* p = NULL;
2559
                int seqLen = 0;
2560
2561
                /* Wrap in SEQUENCE and parse as X509_NAME */
2562
                gn->type = WOLFSSL_GEN_DIRNAME;
2563
                seqBuf = (byte*)XMALLOC((word32)entry->nameSz + MAX_SEQ_SZ,
2564
                                        heap, DYNAMIC_TYPE_TMP_BUFFER);
2565
                if (seqBuf == NULL) {
2566
                    WOLFSSL_MSG("Failed to allocate sequence buffer");
2567
                    wolfSSL_GENERAL_NAME_free(gn);
2568
                    XFREE(subtree, heap, DYNAMIC_TYPE_OPENSSL);
2569
                    return MEMORY_E;
2570
                }
2571
2572
                seqLen = SetSequence(entry->nameSz, seqBuf);
2573
                XMEMCPY(seqBuf + seqLen, entry->name, entry->nameSz);
2574
2575
                p = seqBuf;
2576
                gn->d.directoryName = wolfSSL_d2i_X509_NAME(NULL, &p,
2577
                    (long)entry->nameSz + seqLen);
2578
                XFREE(seqBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
2579
2580
                if (gn->d.directoryName == NULL) {
2581
                    WOLFSSL_MSG("Failed to parse directoryName");
2582
                    wolfSSL_GENERAL_NAME_free(gn);
2583
                    XFREE(subtree, heap, DYNAMIC_TYPE_OPENSSL);
2584
                    return ASN_PARSE_E;
2585
                }
2586
                break;
2587
            }
2588
2589
            case ASN_IP_TYPE:
2590
            {
2591
                /* For IP address, store raw bytes as OCTET_STRING. */
2592
                gn->type = WOLFSSL_GEN_IPADD;
2593
                gn->d.iPAddress = wolfSSL_ASN1_STRING_new();
2594
                if (gn->d.iPAddress == NULL) {
2595
                    WOLFSSL_MSG("Failed to allocate ASN1_STRING for IP");
2596
                    wolfSSL_GENERAL_NAME_free(gn);
2597
                    XFREE(subtree, heap, DYNAMIC_TYPE_OPENSSL);
2598
                    return MEMORY_E;
2599
                }
2600
                if (wolfSSL_ASN1_STRING_set(gn->d.iPAddress, entry->name,
2601
                        entry->nameSz) != WOLFSSL_SUCCESS) {
2602
                    WOLFSSL_MSG("Failed to set IP ASN1_STRING");
2603
                    wolfSSL_GENERAL_NAME_free(gn);
2604
                    XFREE(subtree, heap, DYNAMIC_TYPE_OPENSSL);
2605
                    return MEMORY_E;
2606
                }
2607
                gn->d.iPAddress->type = WOLFSSL_V_ASN1_OCTET_STRING;
2608
                break;
2609
            }
2610
        }
2611
2612
        subtree->base = gn;
2613
2614
        if (wolfSSL_sk_push(sk, subtree) <= 0) {
2615
            WOLFSSL_MSG("Failed to push subtree onto stack");
2616
            wolfSSL_GENERAL_NAME_free(gn);
2617
            XFREE(subtree, heap, DYNAMIC_TYPE_OPENSSL);
2618
            return MEMORY_E;
2619
        }
2620
        entry = entry->next;
2621
    }
2622
2623
    return 0;
2624
}
2625
#endif /* OPENSSL_EXTRA && !IGNORE_NAME_CONSTRAINTS */
2626
2627
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
2628
/* Looks for the extension matching the passed in nid
2629
 *
2630
 * c   : if not null then is set to status value -2 if multiple occurrences
2631
 *       of the extension are found, -1 if not found, 0 if found and not
2632
 *       critical, and 1 if found and critical.
2633
 * nid : Extension OID to be found.
2634
 * idx : if NULL return first extension found match, otherwise start search at
2635
 *       idx location and set idx to the location of extension returned.
2636
 * returns NULL or a pointer to an WOLFSSL_ASN1_BIT_STRING (for KEY_USAGE_OID)
2637
 * or WOLFSSL_STACK (for other)
2638
 * holding extension structure
2639
 *
2640
 * NOTE code for decoding extensions is in asn.c DecodeCertExtensions --
2641
 * use already decoded extension in this function to avoid decoding twice.
2642
 * Currently we do not make use of idx since getting pre decoded extensions.
2643
 */
2644
void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c,
2645
    int* idx)
2646
{
2647
    void* ret = NULL;
2648
    WOLFSSL_STACK* sk = NULL;
2649
    WOLFSSL_ASN1_OBJECT* obj = NULL;
2650
    WOLFSSL_GENERAL_NAME* gn = NULL;
2651
#ifdef OPENSSL_EXTRA
2652
    WOLFSSL_DIST_POINT* dp = NULL;
2653
#endif
2654
    WOLFSSL_BASIC_CONSTRAINTS* bc = NULL;
2655
2656
    WOLFSSL_ENTER("wolfSSL_X509_get_ext_d2i");
2657
2658
    if (x509 == NULL) {
2659
        return NULL;
2660
    }
2661
2662
    if (c != NULL) {
2663
        *c = -1; /* default to not found */
2664
    }
2665
2666
    switch (nid) {
2667
        case BASIC_CA_OID:
2668
            if (x509->basicConstSet) {
2669
                bc = wolfSSL_BASIC_CONSTRAINTS_new();
2670
                if (!bc) {
2671
                    WOLFSSL_MSG("wolfSSL_BASIC_CONSTRAINTS_new error");
2672
                    return NULL;
2673
                }
2674
2675
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) || \
2676
        defined(WOLFSSL_APACHE_HTTPD)
2677
                bc->ca = x509->isCa;
2678
#endif
2679
                /* RFC 5280 4.2.1.9: only populate pathLen when the
2680
                 * pathLenConstraint field was present. When absent, no limit
2681
                 * is imposed and pathlen must remain NULL so it is
2682
                 * distinguishable from a pathLenConstraint of 0. */
2683
                if (x509->basicConstPlSet) {
2684
                    WOLFSSL_ASN1_INTEGER* a = wolfSSL_ASN1_INTEGER_new();
2685
                    if (a == NULL) {
2686
                        WOLFSSL_MSG("wolfSSL_ASN1_INTEGER_new error");
2687
                        wolfSSL_BASIC_CONSTRAINTS_free(bc);
2688
                        return NULL;
2689
                    }
2690
                    a->length = (int)x509->pathLength;
2691
                    bc->pathlen = a;
2692
                }
2693
2694
                if (c != NULL) {
2695
                    *c = x509->basicConstCrit;
2696
                }
2697
            }
2698
            else {
2699
                WOLFSSL_MSG("No Basic Constraint set");
2700
            }
2701
            return bc;
2702
2703
        case ALT_NAMES_OID:
2704
        {
2705
            DNS_entry* dns = NULL;
2706
2707
            if (x509->subjAltNameSet && x509->altNames != NULL) {
2708
                /* Malloc GENERAL_NAME stack */
2709
                sk = wolfSSL_sk_new_null();
2710
                if (sk == NULL)
2711
                    return NULL;
2712
                sk->type = STACK_TYPE_GEN_NAME;
2713
2714
                /* alt names are DNS_entry structs */
2715
                if (c != NULL) {
2716
                    if (x509->altNames->next != NULL) {
2717
                        *c = -2; /* more then one found */
2718
                    }
2719
                    else {
2720
                        *c = x509->subjAltNameCrit;
2721
                    }
2722
                }
2723
2724
                dns = x509->altNames;
2725
                /* Currently only support GEN_DNS type */
2726
                while (dns != NULL) {
2727
                    gn = wolfSSL_GENERAL_NAME_new();
2728
                    if (gn == NULL) {
2729
                        WOLFSSL_MSG("Error creating GENERAL_NAME");
2730
                        goto err;
2731
                    }
2732
2733
                    switch (dns->type) {
2734
                        case ASN_DIR_TYPE:
2735
                            gn->type = dns->type;
2736
                            {
2737
                                int localIdx = 0;
2738
                                unsigned char* n = (unsigned char*)XMALLOC(
2739
                                        dns->len + MAX_SEQ_SZ, x509->heap,
2740
                                        DYNAMIC_TYPE_TMP_BUFFER);
2741
                                if (n == NULL) {
2742
                                    goto err;
2743
                                }
2744
2745
                                localIdx += SetSequence(dns->len, n);
2746
                                XMEMCPY(n + localIdx, dns->name, dns->len);
2747
                                gn->d.dirn =  wolfSSL_d2i_X509_NAME(NULL, &n,
2748
                                        dns->len + localIdx);
2749
                                XFREE(n, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
2750
                                if (gn->d.dirn == NULL) {
2751
                                    WOLFSSL_MSG("Convert altDirName to X509 "
2752
                                            "NAME failed");
2753
                                    goto err;
2754
                                }
2755
                            }
2756
                            break;
2757
2758
                        case ASN_OTHER_TYPE:
2759
                            /* gn->type set internally */
2760
                            if (!wolfssl_dns_entry_othername_to_gn(dns, gn)) {
2761
                                goto err;
2762
                            }
2763
                            break;
2764
2765
                        case ASN_IP_TYPE:
2766
                            gn->type = dns->type;
2767
                            if (wolfSSL_ASN1_STRING_set(gn->d.iPAddress,
2768
                                    dns->name, dns->len) != WOLFSSL_SUCCESS) {
2769
                                WOLFSSL_MSG("ASN1_STRING_set failed");
2770
                                goto err;
2771
                            }
2772
                            gn->d.iPAddress->type = WOLFSSL_V_ASN1_OCTET_STRING;
2773
                            break;
2774
2775
                        case ASN_RID_TYPE:
2776
                            /* Always handle registeredID: the union
2777
                             * member d.registeredID is populated from
2778
                             * raw OID body bytes. WOLFSSL_RID_ALT_NAME
2779
                             * only gates the human-readable ridString,
2780
                             * which this path does not need. */
2781
                            gn->type = dns->type;
2782
                            /* Free ia5 before using union for registeredID */
2783
                            wolfSSL_ASN1_STRING_free(gn->d.ia5);
2784
                            gn->d.ia5 = NULL;
2785
2786
                            gn->d.registeredID = wolfSSL_ASN1_OBJECT_new();
2787
                            if (gn->d.registeredID == NULL) {
2788
                                goto err;
2789
                            }
2790
                            {
2791
                                /* Store DER-encoded OID (tag+length+content) */
2792
                                word32 derSz = 1 + SetLength(dns->len, NULL)
2793
                                               + dns->len;
2794
                                byte* der = (byte*)XMALLOC(derSz,
2795
                                    gn->d.registeredID->heap,
2796
                                    DYNAMIC_TYPE_ASN1);
2797
                                if (der == NULL) {
2798
                                    goto err;
2799
                                }
2800
                                {
2801
                                    word32 derIdx = 0;
2802
                                    der[derIdx++] = ASN_OBJECT_ID;
2803
                                    derIdx += SetLength(dns->len, der + derIdx);
2804
                                    XMEMCPY(der + derIdx, dns->name, dns->len);
2805
                                }
2806
                                gn->d.registeredID->obj = der;
2807
                                gn->d.registeredID->objSz = derSz;
2808
                            }
2809
                            gn->d.registeredID->dynamic |=
2810
                                WOLFSSL_ASN1_DYNAMIC_DATA;
2811
                            gn->d.registeredID->grp = oidCertExtType;
2812
                            break;
2813
2814
                        default:
2815
                            gn->type = dns->type;
2816
                            if (wolfSSL_ASN1_STRING_set(gn->d.dNSName,
2817
                                    dns->name, dns->len) != WOLFSSL_SUCCESS) {
2818
                                WOLFSSL_MSG("ASN1_STRING_set failed");
2819
                                goto err;
2820
                            }
2821
                            gn->d.dNSName->type = WOLFSSL_V_ASN1_IA5STRING;
2822
                    }
2823
2824
                    dns = dns->next;
2825
                    /* Using wolfSSL_sk_insert to maintain backwards
2826
                     * compatibility with earlier versions of _push API that
2827
                     * pushed items to the start of the list instead of the
2828
                     * end. */
2829
                    if (wolfSSL_sk_insert(sk, gn, 0) <= 0) {
2830
                        WOLFSSL_MSG("Error pushing ASN1 object onto stack");
2831
                        goto err;
2832
                    }
2833
                    /* null so that it doesn't get pushed again after switch */
2834
                    gn = NULL;
2835
                }
2836
            }
2837
            else {
2838
                WOLFSSL_MSG("No Alt Names set");
2839
            }
2840
2841
            break;
2842
        }
2843
2844
        case CRL_DIST_OID:
2845
    #if defined(OPENSSL_EXTRA)
2846
            if (x509->CRLdistSet && x509->CRLInfo != NULL) {
2847
                if (c != NULL) {
2848
                    *c = x509->CRLdistCrit;
2849
                }
2850
2851
                sk = wolfSSL_sk_new_null();
2852
                if (sk == NULL) {
2853
                    return NULL;
2854
                }
2855
                sk->type = STACK_TYPE_DIST_POINT;
2856
2857
                gn = wolfSSL_GENERAL_NAME_new();
2858
                if (gn == NULL) {
2859
                    WOLFSSL_MSG("Error creating GENERAL_NAME");
2860
                    goto err;
2861
                }
2862
2863
                if (wolfSSL_GENERAL_NAME_set_type(gn, WOLFSSL_GEN_URI) !=
2864
                        WOLFSSL_SUCCESS) {
2865
                    WOLFSSL_MSG("Error setting GENERAL_NAME type");
2866
                    goto err;
2867
                }
2868
2869
                if (wolfSSL_ASN1_STRING_set(gn->d.uniformResourceIdentifier,
2870
                        x509->CRLInfo, x509->CRLInfoSz) != WOLFSSL_SUCCESS) {
2871
                    WOLFSSL_MSG("ASN1_STRING_set failed");
2872
                    goto err;
2873
                }
2874
2875
                /* wolfSSL only decodes one dist point */
2876
                dp = wolfSSL_DIST_POINT_new();
2877
                if (dp == NULL) {
2878
                    WOLFSSL_MSG("Error creating DIST_POINT");
2879
                    goto err;
2880
                }
2881
2882
                /* push GENERAL_NAME onto fullname stack */
2883
                if (wolfSSL_sk_GENERAL_NAME_push(dp->distpoint->name.fullname,
2884
                                                 gn) <= 0) {
2885
                    WOLFSSL_MSG("wolfSSL_sk_GENERAL_NAME_push error");
2886
                    goto err;
2887
                }
2888
                /* gn now owned by stack. */
2889
                gn = NULL;
2890
2891
                /* push DIST_POINT onto stack */
2892
                if (wolfSSL_sk_DIST_POINT_push(sk, dp) <= 0) {
2893
                    WOLFSSL_MSG("Error pushing DIST_POINT onto stack");
2894
                    goto err;
2895
                }
2896
                /* dp now owned by stack. */
2897
                dp = NULL;
2898
2899
            }
2900
            else {
2901
                WOLFSSL_MSG("No CRL dist set");
2902
            }
2903
    #endif /* OPENSSL_EXTRA */
2904
            break;
2905
2906
        case AUTH_INFO_OID:
2907
            if (x509->authInfoSet && x509->authInfo != NULL) {
2908
                if (c != NULL) {
2909
                    *c = x509->authInfoCrit;
2910
                }
2911
                obj = wolfSSL_ASN1_OBJECT_new();
2912
                if (obj == NULL) {
2913
                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
2914
                    return NULL;
2915
                }
2916
                obj->type  = AUTH_INFO_OID;
2917
                obj->grp   = oidCertExtType;
2918
                obj->obj   = x509->authInfo;
2919
                obj->objSz = (unsigned int)x509->authInfoSz;
2920
            }
2921
            else {
2922
                WOLFSSL_MSG("No Auth Info set");
2923
            }
2924
            break;
2925
2926
        case AUTH_KEY_OID:
2927
            if (x509->authKeyIdSet) {
2928
                WOLFSSL_AUTHORITY_KEYID* akey = wolfSSL_AUTHORITY_KEYID_new();
2929
                if (!akey) {
2930
                    WOLFSSL_MSG(
2931
                        "Issue creating WOLFSSL_AUTHORITY_KEYID struct");
2932
                    return NULL;
2933
                }
2934
2935
                if (c != NULL) {
2936
                    *c = x509->authKeyIdCrit;
2937
                }
2938
                obj = wolfSSL_ASN1_OBJECT_new();
2939
                if (obj == NULL) {
2940
                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
2941
                    wolfSSL_AUTHORITY_KEYID_free(akey);
2942
                    return NULL;
2943
                }
2944
                obj->type  = AUTH_KEY_OID;
2945
                obj->grp   = oidCertExtType;
2946
                obj->obj   = x509->authKeyId;
2947
                obj->objSz = x509->authKeyIdSz;
2948
                akey->issuer = obj;
2949
                return akey;
2950
            }
2951
            else {
2952
                WOLFSSL_MSG("No Auth Key set");
2953
            }
2954
            break;
2955
2956
        case SUBJ_KEY_OID:
2957
            if (x509->subjKeyIdSet) {
2958
                if (c != NULL) {
2959
                    *c = x509->subjKeyIdCrit;
2960
                }
2961
                obj = wolfSSL_ASN1_OBJECT_new();
2962
                if (obj == NULL) {
2963
                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
2964
                    return NULL;
2965
                }
2966
                obj->type  = SUBJ_KEY_OID;
2967
                obj->grp   = oidCertExtType;
2968
                obj->obj   = x509->subjKeyId;
2969
                obj->objSz = x509->subjKeyIdSz;
2970
            }
2971
            else {
2972
                WOLFSSL_MSG("No Subject Key set");
2973
            }
2974
            break;
2975
2976
        case CERT_POLICY_OID:
2977
        {
2978
        #ifdef WOLFSSL_CERT_EXT
2979
            int i;
2980
2981
            if (x509->certPoliciesNb > 0) {
2982
                if (c != NULL) {
2983
                    if (x509->certPoliciesNb > 1) {
2984
                        *c = -2;
2985
                    }
2986
                    else {
2987
                        *c = 0;
2988
                    }
2989
                }
2990
2991
                sk = wolfSSL_sk_new_asn1_obj();
2992
                if (sk == NULL) {
2993
                    return NULL;
2994
                }
2995
2996
                for (i = 0; i < x509->certPoliciesNb - 1; i++) {
2997
                    obj = wolfSSL_ASN1_OBJECT_new();
2998
                    if (obj == NULL) {
2999
                        WOLFSSL_MSG(
3000
                            "Issue creating WOLFSSL_ASN1_OBJECT struct");
3001
                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
3002
                        return NULL;
3003
                    }
3004
                    obj->type  = CERT_POLICY_OID;
3005
                    obj->grp   = oidCertExtType;
3006
                    obj->obj   = (byte*)(x509->certPolicies[i]);
3007
                    obj->objSz = MAX_CERTPOL_SZ;
3008
                    if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) <= 0) {
3009
                        WOLFSSL_MSG("Error pushing ASN1 object onto stack");
3010
                        wolfSSL_ASN1_OBJECT_free(obj);
3011
                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
3012
                        sk = NULL;
3013
                    }
3014
                }
3015
3016
                obj = wolfSSL_ASN1_OBJECT_new();
3017
                if (obj == NULL) {
3018
                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
3019
                    wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
3020
                    return NULL;
3021
                }
3022
                obj->type  = CERT_POLICY_OID;
3023
                obj->grp   = oidCertExtType;
3024
                obj->obj   = (byte*)(x509->certPolicies[i]);
3025
                obj->objSz = MAX_CERTPOL_SZ;
3026
3027
                if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) <= 0) {
3028
                    WOLFSSL_MSG("Error pushing ASN1 object onto stack");
3029
                    wolfSSL_ASN1_OBJECT_free(obj);
3030
                    wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
3031
                    sk = NULL;
3032
                }
3033
3034
                obj = NULL;
3035
            }
3036
            else {
3037
                WOLFSSL_MSG("No Cert Policy set");
3038
            }
3039
        #endif /* WOLFSSL_CERT_EXT */
3040
        #ifdef WOLFSSL_SEP
3041
            if (x509->certPolicySet) {
3042
                if (c != NULL) {
3043
                    *c = x509->certPolicyCrit;
3044
                }
3045
                obj = wolfSSL_ASN1_OBJECT_new();
3046
                if (obj == NULL) {
3047
                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
3048
                    return NULL;
3049
                }
3050
                obj->type  = CERT_POLICY_OID;
3051
                obj->grp   = oidCertExtType;
3052
            }
3053
            else {
3054
                WOLFSSL_MSG("No Cert Policy set");
3055
            }
3056
        #endif
3057
            break;
3058
        }
3059
        case KEY_USAGE_OID:
3060
        {
3061
            WOLFSSL_ASN1_STRING* asn1str = NULL;
3062
            if (x509->keyUsageSet) {
3063
                if (c != NULL) {
3064
                    *c = x509->keyUsageCrit;
3065
                }
3066
3067
                asn1str = wolfSSL_ASN1_STRING_new();
3068
                if (asn1str == NULL) {
3069
                    WOLFSSL_MSG("Failed to malloc ASN1_STRING");
3070
                    return NULL;
3071
                }
3072
3073
                if (wolfSSL_ASN1_STRING_set(asn1str, &x509->keyUsage,
3074
                        sizeof(word16)) != WOLFSSL_SUCCESS) {
3075
                    WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
3076
                    wolfSSL_ASN1_STRING_free(asn1str);
3077
                    return NULL;
3078
                }
3079
3080
                asn1str->type = KEY_USAGE_OID;
3081
            }
3082
            else {
3083
                WOLFSSL_MSG("No Key Usage set");
3084
            }
3085
            /* don't add stack of and return bit string directly */
3086
            return asn1str;
3087
        }
3088
        case INHIBIT_ANY_OID:
3089
            WOLFSSL_MSG("INHIBIT ANY extension not supported");
3090
            break;
3091
3092
        case EXT_KEY_USAGE_OID:
3093
            if (x509->extKeyUsageSrc != NULL) {
3094
                const byte* ekuSrc = x509->extKeyUsageSrc;
3095
                word32 i;
3096
3097
                sk = wolfSSL_sk_new_asn1_obj();
3098
                if (sk == NULL) {
3099
                    WOLFSSL_MSG("Issue creating stack");
3100
                    return NULL;
3101
                }
3102
3103
                for (i = 0; i < x509->extKeyUsageCount; i++) {
3104
                    long ekuSrcLen = (long)(x509->extKeyUsageSz -
3105
                            (word32)(ekuSrc - x509->extKeyUsageSrc));
3106
                    WOLFSSL_ASN1_OBJECT* ekuObj = wolfSSL_d2i_ASN1_OBJECT(NULL,
3107
                            &ekuSrc, ekuSrcLen);
3108
                    if (ekuObj == NULL) {
3109
                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
3110
                        WOLFSSL_MSG("d2i obj error");
3111
                        return NULL;
3112
                    }
3113
                    ekuObj->type  = EXT_KEY_USAGE_OID;
3114
                    ekuObj->grp   = oidCertExtType;
3115
                    /* Push to end to maintain order */
3116
                    if (wolfSSL_sk_insert(sk, ekuObj, -1) <= 0) {
3117
                        wolfSSL_ASN1_OBJECT_free(ekuObj);
3118
                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
3119
                        WOLFSSL_MSG("d2i obj error");
3120
                        return NULL;
3121
                    }
3122
                }
3123
3124
                if ((word32)(ekuSrc - x509->extKeyUsageSrc)
3125
                        != x509->extKeyUsageSz ||
3126
                        i != x509->extKeyUsageCount) {
3127
                    wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
3128
                    WOLFSSL_MSG("incorrect eku count or buffer not exhausted");
3129
                    return NULL;
3130
                }
3131
3132
                if (c != NULL) {
3133
                    if (x509->extKeyUsageCount > 1) {
3134
                        *c = -2;
3135
                    }
3136
                    else {
3137
                        *c = x509->extKeyUsageCrit;
3138
                    }
3139
                }
3140
            }
3141
            else {
3142
                WOLFSSL_MSG("No Extended Key Usage set");
3143
            }
3144
            break;
3145
3146
    #if defined(OPENSSL_EXTRA) && !defined(IGNORE_NAME_CONSTRAINTS)
3147
        case NAME_CONS_OID:
3148
        {
3149
            WOLFSSL_NAME_CONSTRAINTS* nc = NULL;
3150
3151
            /* Check if name constraints exist in stored X509 */
3152
            if (x509->permittedNames == NULL && x509->excludedNames == NULL) {
3153
                WOLFSSL_MSG("No Name Constraints set");
3154
                break;
3155
            }
3156
3157
            if (c != NULL) {
3158
                *c = x509->nameConstraintCrit;
3159
            }
3160
3161
            nc = (WOLFSSL_NAME_CONSTRAINTS*)XMALLOC(
3162
                sizeof(WOLFSSL_NAME_CONSTRAINTS), x509->heap,
3163
                DYNAMIC_TYPE_OPENSSL);
3164
            if (nc == NULL) {
3165
                WOLFSSL_MSG("Failed to allocate NAME_CONSTRAINTS");
3166
                break;
3167
            }
3168
            XMEMSET(nc, 0, sizeof(WOLFSSL_NAME_CONSTRAINTS));
3169
3170
            /* Convert permitted names */
3171
            if (x509->permittedNames != NULL) {
3172
                nc->permittedSubtrees = wolfSSL_sk_new_null();
3173
                if (nc->permittedSubtrees == NULL) {
3174
                    WOLFSSL_MSG("Failed to allocate permitted stack");
3175
                    wolfSSL_NAME_CONSTRAINTS_free(nc);
3176
                    break;
3177
                }
3178
                nc->permittedSubtrees->type = STACK_TYPE_GENERAL_SUBTREE;
3179
3180
                if (ConvertBaseEntryToSubtreeStack(x509->permittedNames,
3181
                        nc->permittedSubtrees, x509->heap) != 0) {
3182
                    WOLFSSL_MSG("Failed to convert permitted names");
3183
                    wolfSSL_NAME_CONSTRAINTS_free(nc);
3184
                    break;
3185
                }
3186
            }
3187
3188
            /* Convert excluded names */
3189
            if (x509->excludedNames != NULL) {
3190
                nc->excludedSubtrees = wolfSSL_sk_new_null();
3191
                if (nc->excludedSubtrees == NULL) {
3192
                    WOLFSSL_MSG("Failed to allocate excluded stack");
3193
                    wolfSSL_NAME_CONSTRAINTS_free(nc);
3194
                    break;
3195
                }
3196
                nc->excludedSubtrees->type = STACK_TYPE_GENERAL_SUBTREE;
3197
3198
                if (ConvertBaseEntryToSubtreeStack(x509->excludedNames,
3199
                        nc->excludedSubtrees, x509->heap) != 0) {
3200
                    WOLFSSL_MSG("Failed to convert excluded names");
3201
                    wolfSSL_NAME_CONSTRAINTS_free(nc);
3202
                    break;
3203
                }
3204
            }
3205
3206
            return nc;
3207
        }
3208
    #endif /* OPENSSL_EXTRA && !IGNORE_NAME_CONSTRAINTS */
3209
3210
        case PRIV_KEY_USAGE_PERIOD_OID:
3211
            WOLFSSL_MSG("Private Key Usage Period extension not supported");
3212
            break;
3213
3214
        case SUBJ_INFO_ACC_OID:
3215
            WOLFSSL_MSG("Subject Info Access extension not supported");
3216
            break;
3217
3218
        case POLICY_MAP_OID:
3219
            WOLFSSL_MSG("Policy Map extension not supported");
3220
            break;
3221
3222
        case POLICY_CONST_OID:
3223
            WOLFSSL_MSG("Policy Constraint extension not supported");
3224
            break;
3225
3226
        case ISSUE_ALT_NAMES_OID:
3227
            WOLFSSL_MSG("Issue Alt Names extension not supported");
3228
            break;
3229
3230
        case TLS_FEATURE_OID:
3231
            WOLFSSL_MSG("TLS Feature extension not supported");
3232
            break;
3233
3234
        default:
3235
            WOLFSSL_MSG("Unsupported/Unknown extension OID");
3236
    }
3237
3238
    /* make sure stack of is allocated */
3239
    if ((obj || gn) && sk == NULL) {
3240
        sk = wolfSSL_sk_new_asn1_obj();
3241
        if (sk == NULL) {
3242
            goto err;
3243
        }
3244
    }
3245
    if (obj) {
3246
        if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) <= 0) {
3247
            WOLFSSL_MSG("Error pushing ASN1_OBJECT object onto "
3248
                        "stack.");
3249
            goto err;
3250
        }
3251
    }
3252
3253
    ret = sk;
3254
3255
    (void)idx;
3256
3257
    return ret;
3258
3259
err:
3260
    if (obj) {
3261
        wolfSSL_ASN1_OBJECT_free(obj);
3262
    }
3263
    if (gn) {
3264
        wolfSSL_GENERAL_NAME_free(gn);
3265
    }
3266
    #ifdef OPENSSL_EXTRA
3267
    if (dp) {
3268
        wolfSSL_DIST_POINT_free(dp);
3269
    }
3270
    #endif
3271
    if (sk) {
3272
        wolfSSL_sk_pop_free(sk, NULL);
3273
    }
3274
    return NULL;
3275
}
3276
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
3277
3278
#ifdef OPENSSL_EXTRA
3279
int wolfSSL_X509_add_altname_ex(WOLFSSL_X509* x509, const char* name,
3280
        word32 nameSz, int type)
3281
{
3282
    DNS_entry* newAltName = NULL;
3283
3284
    if (x509 == NULL)
3285
        return WOLFSSL_FAILURE;
3286
3287
    if ((name == NULL) || (nameSz == 0))
3288
        return WOLFSSL_SUCCESS;
3289
3290
    /* AltNameNewEx() takes a signed length. */
3291
    if (nameSz > (word32)INT_MAX)
3292
        return WOLFSSL_FAILURE;
3293
3294
    /* One block, so nothing to unwind on failure. */
3295
    newAltName = AltNameNewEx(name, (int)nameSz, x509->heap);
3296
    if (newAltName == NULL)
3297
        return WOLFSSL_FAILURE;
3298
3299
    newAltName->next = x509->altNames;
3300
    newAltName->type = type;
3301
    x509->altNames = newAltName;
3302
3303
    return WOLFSSL_SUCCESS;
3304
}
3305
3306
int wolfSSL_X509_add_altname(WOLFSSL_X509* x509, const char* name, int type)
3307
{
3308
    word32 nameSz;
3309
3310
    if (name == NULL)
3311
        return WOLFSSL_SUCCESS;
3312
3313
    nameSz = (word32)XSTRLEN(name);
3314
    if (nameSz == 0)
3315
        return WOLFSSL_SUCCESS;
3316
3317
    if (type == ASN_IP_TYPE) {
3318
#ifdef WOLFSSL_IP_ALT_NAME
3319
        byte ip4[4];
3320
        byte ip6[16];
3321
        int ptonRet;
3322
3323
        /* Check if this is an ip4 address */
3324
    #ifdef FREESCALE_MQX
3325
        ptonRet = XINET_PTON(WOLFSSL_IP4, name, ip4, sizeof(ip4));
3326
        if (ptonRet == RTCS_OK) {
3327
    #else
3328
        ptonRet = XINET_PTON(WOLFSSL_IP4, name, ip4);
3329
        if (ptonRet == 1) {
3330
    #endif
3331
            return wolfSSL_X509_add_altname_ex(x509, (const char*)ip4, 4,
3332
                type);
3333
        }
3334
3335
        /* Check for ip6 */
3336
    #ifdef FREESCALE_MQX
3337
        ptonRet = XINET_PTON(WOLFSSL_IP6, name, ip6, sizeof(ip6));
3338
        if (ptonRet == RTCS_OK) {
3339
    #else
3340
        ptonRet = XINET_PTON(WOLFSSL_IP6, name, ip6);
3341
        if (ptonRet == 1) {
3342
    #endif
3343
            return wolfSSL_X509_add_altname_ex(x509, (const char*)ip6, 16,
3344
                type);
3345
        }
3346
3347
        WOLFSSL_MSG("IP address parse failed");
3348
        return WOLFSSL_FAILURE;
3349
#else
3350
        WOLFSSL_MSG("WOLFSSL_IP_ALT_NAME not enabled");
3351
        return WOLFSSL_FAILURE;
3352
#endif
3353
    }
3354
3355
    return wolfSSL_X509_add_altname_ex(x509, name, nameSz, type);
3356
}
3357
3358
#ifndef NO_WOLFSSL_STUB
3359
WOLFSSL_X509_EXTENSION *wolfSSL_X509_delete_ext(WOLFSSL_X509 *x509, int loc)
3360
{
3361
    WOLFSSL_STUB("wolfSSL_X509_delete_ext");
3362
    (void)x509;
3363
    (void)loc;
3364
    return NULL;
3365
}
3366
3367
/* currently LHASH is not implemented (and not needed for Apache port) */
3368
WOLFSSL_X509_EXTENSION* wolfSSL_X509V3_EXT_conf_nid(
3369
        WOLF_LHASH_OF(CONF_VALUE)* conf, WOLFSSL_X509V3_CTX* ctx, int nid,
3370
        char* value)
3371
{
3372
    WOLFSSL_STUB("wolfSSL_X509V3_EXT_conf_nid");
3373
3374
    if (conf != NULL) {
3375
        WOLFSSL_MSG("Handling LHASH not implemented yet");
3376
        return NULL;
3377
    }
3378
3379
    (void)conf;
3380
    (void)ctx;
3381
    (void)nid;
3382
    (void)value;
3383
    return NULL;
3384
}
3385
3386
void wolfSSL_X509V3_set_ctx_nodb(WOLFSSL_X509V3_CTX* ctx)
3387
{
3388
    WOLFSSL_STUB("wolfSSL_X509V3_set_ctx_nodb");
3389
    (void)ctx;
3390
}
3391
#endif /* !NO_WOLFSSL_STUB */
3392
3393
#ifdef OPENSSL_EXTRA
3394
static WOLFSSL_X509_EXTENSION* createExtFromStr(int nid, const char *value)
3395
{
3396
    WOLFSSL_X509_EXTENSION* ext;
3397
3398
    ext = wolfSSL_X509_EXTENSION_new();
3399
    if (ext == NULL) {
3400
        WOLFSSL_MSG("memory error");
3401
        return NULL;
3402
    }
3403
    ext->value.nid = nid;
3404
3405
    switch (nid) {
3406
        case WC_NID_subject_key_identifier:
3407
        case WC_NID_authority_key_identifier:
3408
            if (wolfSSL_ASN1_STRING_set(&ext->value, value, -1)
3409
                    != WOLFSSL_SUCCESS) {
3410
                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
3411
                goto err_cleanup;
3412
            }
3413
            ext->value.type = CTC_UTF8;
3414
            break;
3415
        case WC_NID_subject_alt_name:
3416
        {
3417
            WOLFSSL_GENERAL_NAMES* gns;
3418
            WOLFSSL_GENERAL_NAME* gn;
3419
3420
            if (wolfSSL_ASN1_STRING_set(&ext->value, value, -1)
3421
                    != WOLFSSL_SUCCESS) {
3422
                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
3423
                goto err_cleanup;
3424
            }
3425
            ext->value.type = ASN_DNS_TYPE;
3426
3427
            /* add stack of general names */
3428
            gns = wolfSSL_sk_new_null();
3429
            if (gns == NULL) {
3430
                WOLFSSL_MSG("wolfSSL_sk_new_null error");
3431
                goto err_cleanup;
3432
            }
3433
            ext->ext_sk = gns; /* wolfSSL_X509_EXTENSION_free will handle
3434
                                * free'ing gns */
3435
            gns->type = STACK_TYPE_GEN_NAME;
3436
            gn = wolfSSL_GENERAL_NAME_new();
3437
            if (gn == NULL) {
3438
                WOLFSSL_MSG("wolfSSL_GENERAL_NAME_new error");
3439
                goto err_cleanup;
3440
            }
3441
            if (wolfSSL_sk_GENERAL_NAME_push(gns, gn) <= 0) {
3442
                WOLFSSL_MSG("wolfSSL_sk_GENERAL_NAME_push error");
3443
                wolfSSL_GENERAL_NAME_free(gn);
3444
                goto err_cleanup;
3445
            }
3446
            if (wolfSSL_ASN1_STRING_set(gn->d.ia5, value, -1)
3447
                    != WOLFSSL_SUCCESS) {
3448
                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set failed");
3449
                goto err_cleanup;
3450
            }
3451
            gn->type = ASN_DNS_TYPE;
3452
            break;
3453
        }
3454
        case WC_NID_key_usage:
3455
            if (wolfSSL_ASN1_STRING_set(&ext->value, value, -1)
3456
                    != WOLFSSL_SUCCESS) {
3457
                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
3458
                goto err_cleanup;
3459
            }
3460
            ext->value.type = KEY_USAGE_OID;
3461
            break;
3462
        case WC_NID_ext_key_usage:
3463
            if (wolfSSL_ASN1_STRING_set(&ext->value, value, -1)
3464
                    != WOLFSSL_SUCCESS) {
3465
                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
3466
                goto err_cleanup;
3467
            }
3468
            ext->value.type = EXT_KEY_USAGE_OID;
3469
            break;
3470
        default:
3471
            WOLFSSL_MSG("invalid or unsupported NID");
3472
            goto err_cleanup;
3473
    }
3474
    return ext;
3475
err_cleanup:
3476
    wolfSSL_X509_EXTENSION_free(ext);
3477
    return NULL;
3478
}
3479
3480
/**
3481
 * Create a WOLFSSL_X509_EXTENSION from the input arguments.
3482
 * @param conf  Not used
3483
 * @param ctx   Not used
3484
 * @param nid   Interprets the value parameter as the x509 extension that
3485
 *              corresponds to this NID.
3486
 * @param value A NULL terminated string that is taken as the value of the
3487
 *              newly created extension object.
3488
 * @return WOLFSSL_X509_EXTENSION* on success or NULL on failure.
3489
 */
3490
WOLFSSL_X509_EXTENSION* wolfSSL_X509V3_EXT_nconf_nid(WOLFSSL_CONF* conf,
3491
        WOLFSSL_X509V3_CTX *ctx, int nid, const char *value)
3492
{
3493
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_nconf_nid");
3494
3495
    if (value == NULL) {
3496
        WOLFSSL_MSG("value NULL parameter");
3497
        return NULL;
3498
    }
3499
3500
    if (conf != NULL || ctx != NULL) {
3501
        WOLFSSL_MSG("wolfSSL_X509V3_EXT_nconf_nid does not handle either "
3502
                    "conf or ctx parameters");
3503
    }
3504
3505
    return createExtFromStr(nid, value);
3506
}
3507
3508
/**
3509
 * Create a WOLFSSL_X509_EXTENSION from the input arguments.
3510
 * @param conf  Not used
3511
 * @param ctx   Not used
3512
 * @param sName The textual representation of the NID that the value parameter
3513
 *              should be interpreted as.
3514
 * @param value A NULL terminated string that is taken as the value of the
3515
 *              newly created extension object.
3516
 * @return WOLFSSL_X509_EXTENSION* on success or NULL on failure.
3517
 */
3518
WOLFSSL_X509_EXTENSION* wolfSSL_X509V3_EXT_nconf(WOLFSSL_CONF *conf,
3519
        WOLFSSL_X509V3_CTX *ctx, const char *sName, const char *value)
3520
{
3521
    const WOLFSSL_ObjectInfo* info = wolfssl_object_info;
3522
    size_t i;
3523
3524
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_nconf");
3525
3526
    if (value == NULL || sName == NULL) {
3527
        WOLFSSL_MSG("NULL parameter");
3528
        return NULL;
3529
    }
3530
3531
    if (conf != NULL || ctx != NULL) {
3532
        WOLFSSL_MSG("wolfSSL_X509V3_EXT_nconf does not handle either "
3533
                    "conf or ctx parameters");
3534
    }
3535
3536
    for (i = 0; i < wolfssl_object_info_sz; i++, info++) {
3537
        if (XSTRCMP(info->sName, sName) == 0)
3538
            return createExtFromStr(info->nid, value);
3539
    }
3540
3541
    WOLFSSL_MSG("value didn't match any known NID");
3542
    return NULL;
3543
}
3544
3545
static void wolfSSL_X509V3_EXT_METHOD_populate(WOLFSSL_v3_ext_method *method,
3546
                                               int nid)
3547
{
3548
    if (!method)
3549
        return;
3550
3551
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_METHOD_populate");
3552
    switch (nid) {
3553
    case WC_NID_subject_key_identifier:
3554
        method->i2s = (WOLFSSL_X509V3_EXT_I2S)wolfSSL_i2s_ASN1_STRING;
3555
        FALL_THROUGH;
3556
    case WC_NID_authority_key_identifier:
3557
    case WC_NID_key_usage:
3558
    case WC_NID_certificate_policies:
3559
    case WC_NID_policy_mappings:
3560
    case WC_NID_subject_alt_name:
3561
    case WC_NID_issuer_alt_name:
3562
    case WC_NID_basic_constraints:
3563
    case WC_NID_name_constraints:
3564
    case WC_NID_policy_constraints:
3565
    case WC_NID_ext_key_usage:
3566
    case WC_NID_crl_distribution_points:
3567
    case WC_NID_inhibit_any_policy:
3568
    case WC_NID_info_access:
3569
        WOLFSSL_MSG("Nothing to populate for current NID");
3570
        break;
3571
    default:
3572
        WOLFSSL_MSG("Unknown or unsupported NID");
3573
        break;
3574
    }
3575
3576
    return;
3577
}
3578
3579
/**
3580
 * @param nid One of the WC_NID_* constants defined in asn.h
3581
 * @param crit
3582
 * @param data This data is copied to the returned extension.
3583
 * @return
3584
 */
3585
WOLFSSL_X509_EXTENSION *wolfSSL_X509V3_EXT_i2d(int nid, int crit,
3586
                                               void *data)
3587
{
3588
    WOLFSSL_X509_EXTENSION *ext = NULL;
3589
    WOLFSSL_ASN1_STRING* asn1str = NULL;
3590
3591
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_i2d");
3592
3593
    if (!data) {
3594
        return NULL;
3595
    }
3596
3597
    if (!(ext = wolfSSL_X509_EXTENSION_new())) {
3598
        return NULL;
3599
    }
3600
3601
    wolfSSL_X509V3_EXT_METHOD_populate(&ext->ext_method, nid);
3602
3603
    switch (nid) {
3604
    case WC_NID_subject_key_identifier:
3605
        /* WOLFSSL_ASN1_STRING */
3606
    case WC_NID_key_usage:
3607
        /* WOLFSSL_ASN1_STRING */
3608
    {
3609
        asn1str = (WOLFSSL_ASN1_STRING*)data;
3610
        ext->value = *asn1str;
3611
        if (asn1str->isDynamic) {
3612
            ext->value.data = (char*)XMALLOC(asn1str->length, NULL,
3613
                                             DYNAMIC_TYPE_OPENSSL);
3614
            if (!ext->value.data) {
3615
                WOLFSSL_MSG("malloc failed");
3616
                /* Zero so that no existing memory is freed */
3617
                XMEMSET(&ext->value, 0, sizeof(WOLFSSL_ASN1_STRING));
3618
                goto err_cleanup;
3619
            }
3620
            XMEMCPY(ext->value.data, asn1str->data, asn1str->length);
3621
        }
3622
        else {
3623
            ext->value.data = ext->value.strData;
3624
        }
3625
3626
        if (!(ext->obj = wolfSSL_OBJ_nid2obj(nid))) {
3627
            WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new failed");
3628
            goto err_cleanup;
3629
        }
3630
3631
        break;
3632
    }
3633
    case WC_NID_subject_alt_name:
3634
        /* typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES */
3635
    case WC_NID_issuer_alt_name:
3636
        /* typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES */
3637
    case WC_NID_ext_key_usage:
3638
        /* typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE */
3639
    case WC_NID_info_access:
3640
        /* typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS */
3641
    {
3642
        WOLFSSL_STACK* sk = (WOLFSSL_STACK*)data;
3643
3644
        if (ext->ext_sk) {
3645
            wolfSSL_sk_pop_free(ext->ext_sk, NULL);
3646
        }
3647
3648
        if (!(ext->ext_sk = wolfSSL_sk_dup(sk))) {
3649
            WOLFSSL_MSG("wolfSSL_sk_dup failed");
3650
            goto err_cleanup;
3651
        }
3652
3653
        if (!(ext->obj = wolfSSL_OBJ_nid2obj(nid))) {
3654
            WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new failed");
3655
            goto err_cleanup;
3656
        }
3657
3658
        break;
3659
    }
3660
    case WC_NID_basic_constraints:
3661
    {
3662
        /* WOLFSSL_BASIC_CONSTRAINTS */
3663
        WOLFSSL_BASIC_CONSTRAINTS* bc = (WOLFSSL_BASIC_CONSTRAINTS*)data;
3664
3665
        /* Build from the NID like the other cases: a bare ASN1_OBJECT has
3666
         * type 0, which wolfSSL_X509_add_ext() rejects. */
3667
        if (!(ext->obj = wolfSSL_OBJ_nid2obj(nid))) {
3668
            WOLFSSL_MSG("wolfSSL_OBJ_nid2obj failed");
3669
            goto err_cleanup;
3670
        }
3671
3672
        ext->obj->ca = bc->ca;
3673
        if (bc->pathlen) {
3674
            ext->obj->pathlen = wolfSSL_ASN1_INTEGER_dup(bc->pathlen);
3675
            if (!ext->obj->pathlen) {
3676
                WOLFSSL_MSG("wolfSSL_ASN1_INTEGER_dup failed");
3677
                goto err_cleanup;
3678
            }
3679
        }
3680
        break;
3681
    }
3682
    case WC_NID_authority_key_identifier:
3683
    {
3684
        /* AUTHORITY_KEYID */
3685
        WOLFSSL_AUTHORITY_KEYID* akey = (WOLFSSL_AUTHORITY_KEYID*)data;
3686
3687
        if (akey->keyid) {
3688
            if (wolfSSL_ASN1_STRING_set(&ext->value, akey->keyid->data,
3689
                                    akey->keyid->length) != WOLFSSL_SUCCESS) {
3690
                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set failed");
3691
                goto err_cleanup;
3692
            }
3693
            ext->value.type = akey->keyid->type;
3694
3695
            if (!(ext->obj = wolfSSL_OBJ_nid2obj(nid))) {
3696
                WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new failed");
3697
                goto err_cleanup;
3698
            }
3699
3700
        }
3701
        else if (akey->issuer) {
3702
            ext->obj = wolfSSL_ASN1_OBJECT_dup(akey->issuer);
3703
            if (!ext->obj) {
3704
                WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_dup failed");
3705
                goto err_cleanup;
3706
            }
3707
        }
3708
        else {
3709
            WOLFSSL_MSG("WC_NID_authority_key_identifier empty data");
3710
            goto err_cleanup;
3711
        }
3712
        break;
3713
    }
3714
    case WC_NID_inhibit_any_policy:
3715
        /* ASN1_INTEGER */
3716
    case WC_NID_certificate_policies:
3717
        /* STACK_OF(POLICYINFO) */
3718
    case WC_NID_policy_mappings:
3719
        /* STACK_OF(POLICY_MAPPING) */
3720
    case WC_NID_name_constraints:
3721
        /* NAME_CONSTRAINTS */
3722
    case WC_NID_policy_constraints:
3723
        /* POLICY_CONSTRAINTS */
3724
    case WC_NID_crl_distribution_points:
3725
        /* typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS */
3726
    default:
3727
        WOLFSSL_MSG("Unknown or unsupported NID");
3728
        break;
3729
    }
3730
3731
    ext->crit = crit;
3732
3733
    return ext;
3734
err_cleanup:
3735
    if (ext) {
3736
        wolfSSL_X509_EXTENSION_free(ext);
3737
    }
3738
    return NULL;
3739
}
3740
3741
/* Report whether an extension of type @nid is present in the in-memory @x509,
3742
 * based on wolfSSL's typed extension storage. Only the NIDs that
3743
 * wolfSSL_X509_add_ext() can consume have such storage.
3744
 *
3745
 * @return 1 when present, 0 when absent and -1 when @nid has no typed storage
3746
 * and presence therefore cannot be determined. */
3747
static int wolfssl_x509_ext_is_set(const WOLFSSL_X509 *x509, int nid)
3748
{
3749
    switch (nid) {
3750
    case WC_NID_subject_alt_name:
3751
        return (x509->subjAltNameSet != 0) || (x509->altNames != NULL);
3752
    case WC_NID_key_usage:
3753
        return x509->keyUsageSet != 0;
3754
    case WC_NID_ext_key_usage:
3755
        return (x509->extKeyUsage != 0) || (x509->extKeyUsageSrc != NULL);
3756
    case WC_NID_basic_constraints:
3757
        return x509->basicConstSet != 0;
3758
    case WC_NID_subject_key_identifier:
3759
        return (x509->subjKeyId != NULL) || (x509->subjKeyIdSet != 0);
3760
    case WC_NID_authority_key_identifier:
3761
        return (x509->authKeyId != NULL) || (x509->authKeyIdSet != 0);
3762
    default:
3763
        return -1;
3764
    }
3765
}
3766
3767
/* Remove the extension of type @nid from the in-memory @x509 by clearing the
3768
 * matching typed storage (mirrors the frees in FreeX509()). Every field the
3769
 * accessors for @nid look at has to be cleared, including the cached and
3770
 * "is set" flags, or the removed extension stays observable.
3771
 *
3772
 * The encoded certificate (x509->derCert) is not re-generated, so APIs that
3773
 * decode the DER again - wolfSSL_X509_get_ext_count(),
3774
 * wolfSSL_X509_get_ext_by_NID() - keep reporting the original extensions.
3775
 * That limitation is shared with wolfSSL_X509_add_ext().
3776
 *
3777
 * Returns WOLFSSL_SUCCESS if @nid is a supported, removable extension,
3778
 * otherwise WOLFSSL_FAILURE. */
3779
static int wolfssl_x509_remove_ext(WOLFSSL_X509 *x509, int nid)
3780
{
3781
    switch (nid) {
3782
    case WC_NID_subject_alt_name:
3783
        if (x509->altNames != NULL) {
3784
            FreeAltNames(x509->altNames, x509->heap);
3785
            x509->altNames = NULL;
3786
        }
3787
        /* Retrieval hint indexes into the list just freed. */
3788
        x509->altNamesNext = NULL;
3789
    #ifdef OPENSSL_ALL
3790
        XFREE(x509->subjAltNameSrc, x509->heap, DYNAMIC_TYPE_X509_EXT);
3791
        x509->subjAltNameSrc = NULL;
3792
        x509->subjAltNameSz = 0;
3793
    #endif
3794
        x509->subjAltNameSet = 0;
3795
        x509->subjAltNameCrit = 0;
3796
        break;
3797
    case WC_NID_key_usage:
3798
        x509->keyUsage = 0;
3799
        x509->keyUsageCrit = 0;
3800
        x509->keyUsageSet = 0;
3801
        break;
3802
    case WC_NID_ext_key_usage:
3803
        XFREE(x509->extKeyUsageSrc, x509->heap, DYNAMIC_TYPE_X509_EXT);
3804
        x509->extKeyUsageSrc = NULL;
3805
        x509->extKeyUsageSz = 0;
3806
        x509->extKeyUsageCount = 0;
3807
        x509->extKeyUsage = 0;
3808
        x509->extKeyUsageCrit = 0;
3809
        break;
3810
    case WC_NID_basic_constraints:
3811
        x509->isCa = 0;
3812
        x509->pathLength = 0;
3813
        x509->basicConstCrit = 0;
3814
        x509->basicConstSet = 0;
3815
        x509->basicConstPlSet = 0;
3816
        x509->pathLengthSet = 0;
3817
        break;
3818
    case WC_NID_subject_key_identifier:
3819
        XFREE(x509->subjKeyId, x509->heap, DYNAMIC_TYPE_X509_EXT);
3820
        x509->subjKeyId = NULL;
3821
        x509->subjKeyIdSz = 0;
3822
        /* Cached ASN1_STRING handed out by get0_subject_key_id(). */
3823
        wolfSSL_ASN1_STRING_free(x509->subjKeyIdStr);
3824
        x509->subjKeyIdStr = NULL;
3825
        x509->subjKeyIdSet = 0;
3826
        x509->subjKeyIdCrit = 0;
3827
        break;
3828
    case WC_NID_authority_key_identifier:
3829
        /* authKeyId may point into authKeyIdSrc; free the source first. */
3830
        if (x509->authKeyIdSrc != NULL) {
3831
            XFREE(x509->authKeyIdSrc, x509->heap, DYNAMIC_TYPE_X509_EXT);
3832
            x509->authKeyIdSrc = NULL;
3833
        }
3834
        else {
3835
            XFREE(x509->authKeyId, x509->heap, DYNAMIC_TYPE_X509_EXT);
3836
        }
3837
        x509->authKeyId = NULL;
3838
        x509->authKeyIdSz = 0;
3839
        x509->authKeyIdSrcSz = 0;
3840
        x509->authKeyIdSet = 0;
3841
        x509->authKeyIdCrit = 0;
3842
        break;
3843
    default:
3844
        WOLFSSL_MSG("Extension NID not supported for removal");
3845
        return WOLFSSL_FAILURE;
3846
    }
3847
    return WOLFSSL_SUCCESS;
3848
}
3849
3850
/**
3851
 * Encode @value as an extension of type @nid and add it to @x, honoring the
3852
 * OpenSSL X509V3_ADD_* operation selected by the low nibble of @flags:
3853
 *   X509V3_ADD_DEFAULT          - add, fail if already present
3854
 *   X509V3_ADD_APPEND           - add without checking for an existing one
3855
 *   X509V3_ADD_REPLACE          - replace any existing, else add
3856
 *   X509V3_ADD_REPLACE_EXISTING - replace, fail if not already present
3857
 *   X509V3_ADD_KEEP_EXISTING    - keep existing (no-op if present), else add
3858
 *   X509V3_ADD_DELETE           - delete existing, fail if not present
3859
 * X509V3_ADD_SILENT is accepted but inert: this function reports nothing that
3860
 * could be suppressed, and the flag never changes the result.
3861
 *
3862
 * Presence can only be determined for the extensions wolfSSL_X509_add_ext()
3863
 * stores in typed fields. For any other NID every operation except
3864
 * X509V3_ADD_APPEND - the one defined as not checking - fails.
3865
 *
3866
 * @return WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE otherwise.
3867
 */
3868
int wolfSSL_X509_add1_ext_i2d(WOLFSSL_X509 *x, int nid, void *value,
3869
                              int crit, unsigned long flags)
3870
{
3871
    WOLFSSL_X509_EXTENSION *ext = NULL;
3872
    int ret;
3873
    unsigned long op;
3874
    int exists;
3875
3876
    WOLFSSL_ENTER("wolfSSL_X509_add1_ext_i2d");
3877
3878
    if (x == NULL) {
3879
        WOLFSSL_MSG("Bad parameter");
3880
        return WOLFSSL_FAILURE;
3881
    }
3882
3883
    op = flags & WOLFSSL_X509V3_ADD_OP_MASK;
3884
    exists = wolfssl_x509_ext_is_set(x, nid);
3885
    if (exists < 0) {
3886
        if (op != WOLFSSL_X509V3_ADD_APPEND) {
3887
            WOLFSSL_MSG("Extension presence not tracked for this NID");
3888
            return WOLFSSL_FAILURE;
3889
        }
3890
        exists = 0;
3891
    }
3892
3893
    switch (op) {
3894
    case WOLFSSL_X509V3_ADD_DELETE:
3895
        if (!exists) {
3896
            WOLFSSL_MSG("No extension to delete (X509V3_ADD_DELETE)");
3897
            return WOLFSSL_FAILURE;
3898
        }
3899
        return wolfssl_x509_remove_ext(x, nid);
3900
    case WOLFSSL_X509V3_ADD_DEFAULT:
3901
        if (exists) {
3902
            WOLFSSL_MSG("Extension already present (X509V3_ADD_DEFAULT)");
3903
            return WOLFSSL_FAILURE;
3904
        }
3905
        break;
3906
    case WOLFSSL_X509V3_ADD_APPEND:
3907
    case WOLFSSL_X509V3_ADD_REPLACE:
3908
        break;
3909
    case WOLFSSL_X509V3_ADD_REPLACE_EXISTING:
3910
        if (!exists) {
3911
            WOLFSSL_MSG("No extension to replace "
3912
                        "(X509V3_ADD_REPLACE_EXISTING)");
3913
            return WOLFSSL_FAILURE;
3914
        }
3915
        break;
3916
    case WOLFSSL_X509V3_ADD_KEEP_EXISTING:
3917
        if (exists) {
3918
            /* Keep the existing extension; nothing to add. */
3919
            return WOLFSSL_SUCCESS;
3920
        }
3921
        break;
3922
    default:
3923
        WOLFSSL_MSG("Unsupported X509V3_ADD_* operation");
3924
        return WOLFSSL_FAILURE;
3925
    }
3926
3927
    if (value == NULL) {
3928
        WOLFSSL_MSG("Bad parameter");
3929
        return WOLFSSL_FAILURE;
3930
    }
3931
3932
    /* Encode the new extension before dropping the old one so that a failure
3933
     * leaves the certificate untouched. */
3934
    ext = wolfSSL_X509V3_EXT_i2d(nid, crit, value);
3935
    if (ext == NULL) {
3936
        return WOLFSSL_FAILURE;
3937
    }
3938
3939
    /* wolfSSL_X509_add_ext() dispatches on the encoded object, which for an
3940
     * authorityKeyIdentifier built from an issuer name is caller supplied.
3941
     * Refuse here rather than remove one extension and write another. */
3942
    if (((ext->obj != NULL) ? ext->obj->type : ext->value.nid) != nid) {
3943
        WOLFSSL_MSG("Encoded extension is not the requested NID");
3944
        wolfSSL_X509_EXTENSION_free(ext);
3945
        return WOLFSSL_FAILURE;
3946
    }
3947
3948
    /* wolfSSL_X509V3_EXT_i2d() copies an extKeyUsage stack without looking
3949
     * inside it, so encoding is not the check that matters here. Reject a bad
3950
     * stack before the existing extension is dropped for it. */
3951
    if ((nid == WC_NID_ext_key_usage) && (ext->value.data == NULL) &&
3952
            (ext->ext_sk != NULL)) {
3953
        word32 ekuSz = 0;
3954
        byte ekuUsage = 0;
3955
3956
        if (wolfssl_x509_eku_sk_check(ext->ext_sk, &ekuSz, &ekuUsage) !=
3957
                WOLFSSL_SUCCESS) {
3958
            wolfSSL_X509_EXTENSION_free(ext);
3959
            return WOLFSSL_FAILURE;
3960
        }
3961
    }
3962
3963
    if (exists && ((op == WOLFSSL_X509V3_ADD_REPLACE) ||
3964
                   (op == WOLFSSL_X509V3_ADD_REPLACE_EXISTING))) {
3965
        if (wolfssl_x509_remove_ext(x, nid) != WOLFSSL_SUCCESS) {
3966
            wolfSSL_X509_EXTENSION_free(ext);
3967
            return WOLFSSL_FAILURE;
3968
        }
3969
    }
3970
3971
    ret = wolfSSL_X509_add_ext(x, ext, -1);
3972
    wolfSSL_X509_EXTENSION_free(ext);
3973
3974
    return ret;
3975
}
3976
3977
/* Returns pointer to ASN1_OBJECT from an X509_EXTENSION object */
3978
WOLFSSL_ASN1_OBJECT* wolfSSL_X509_EXTENSION_get_object(
3979
    WOLFSSL_X509_EXTENSION* ext)
3980
{
3981
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_get_object");
3982
    if (ext == NULL)
3983
        return NULL;
3984
    return ext->obj;
3985
}
3986
3987
3988
/**
3989
 * duplicates the 'obj' input and sets it into the 'ext' structure
3990
 * returns WOLFSSL_SUCCESS on success
3991
 */
3992
int wolfSSL_X509_EXTENSION_set_object(WOLFSSL_X509_EXTENSION* ext,
3993
        const WOLFSSL_ASN1_OBJECT* obj)
3994
{
3995
    WOLFSSL_ASN1_OBJECT *current;
3996
3997
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_set_object");
3998
    if (ext == NULL)
3999
        return WOLFSSL_FAILURE;
4000
4001
    current = wolfSSL_X509_EXTENSION_get_object(ext);
4002
    if (current != NULL) {
4003
        wolfSSL_ASN1_OBJECT_free(current);
4004
    }
4005
    ext->obj = wolfSSL_ASN1_OBJECT_dup((WOLFSSL_ASN1_OBJECT*)obj);
4006
    return WOLFSSL_SUCCESS;
4007
}
4008
#endif /* OPENSSL_ALL */
4009
4010
#ifdef WOLFSSL_OLD_EXTDATA_FMT
4011
/*
4012
 * Replace the current string in 'asn1str', which is the full X.509
4013
 * extension octet string with some data specific for the extension
4014
 * type. The extension is the one given in 'oid'.
4015
 * Return 0 in case of success, or a negative error code.
4016
 */
4017
static int wolfSSL_ASN1_STRING_into_old_ext_fmt(WOLFSSL_ASN1_STRING *asn1str,
4018
                                                word32 oid)
4019
{
4020
    switch (oid)
4021
    {
4022
        case AUTH_INFO_OID:
4023
            wolfSSL_ASN1_STRING_clear(asn1str);
4024
            asn1str->data = NULL;
4025
            asn1str->length = 0;
4026
            return 0;
4027
4028
        case AUTH_KEY_OID:
4029
        {
4030
            int ret = 0;
4031
            const byte *extAuthKeyId = NULL;
4032
            word32 extAuthKeyIdSz = 0;
4033
            char *data = NULL;
4034
4035
            ret = DecodeAuthKeyId((const byte *)asn1str->data, asn1str->length,
4036
                    &extAuthKeyId, &extAuthKeyIdSz, NULL, NULL, NULL, NULL);
4037
4038
            if (ret != 0)
4039
                return ret;
4040
4041
            data = (char*)XMALLOC((size_t)(extAuthKeyIdSz), NULL,
4042
                                  DYNAMIC_TYPE_OPENSSL);
4043
            if (data == NULL)
4044
                return MEMORY_ERROR;
4045
4046
            XMEMCPY(data, extAuthKeyId, (size_t)extAuthKeyIdSz);
4047
            wolfSSL_ASN1_STRING_set(asn1str, data, extAuthKeyIdSz);
4048
            XFREE(data, NULL, DYNAMIC_TYPE_OPENSSL);
4049
            return 0;
4050
        }
4051
4052
        case SUBJ_KEY_OID:
4053
        {
4054
            int ret = 0;
4055
            const byte *extSubjKeyId = NULL;
4056
            word32 extSubjKeyIdSz = 0;
4057
            char *data = NULL;
4058
4059
            ret = DecodeSubjKeyId((const byte *)asn1str->data, asn1str->length,
4060
                    &extSubjKeyId, &extSubjKeyIdSz);
4061
            if (ret != 0)
4062
                return ret;
4063
4064
            data = (char*)XMALLOC((size_t)(extSubjKeyIdSz), NULL,
4065
                                  DYNAMIC_TYPE_OPENSSL);
4066
            if (data == NULL)
4067
                return MEMORY_ERROR;
4068
4069
            XMEMCPY(data, extSubjKeyId, (size_t)extSubjKeyIdSz);
4070
            wolfSSL_ASN1_STRING_set(asn1str, data, extSubjKeyIdSz);
4071
            XFREE(data, NULL, DYNAMIC_TYPE_OPENSSL);
4072
            return 0;
4073
        }
4074
4075
        case CERT_POLICY_OID:
4076
            wolfSSL_ASN1_STRING_clear(asn1str);
4077
            asn1str->data = NULL;
4078
            asn1str->length = 0;
4079
            return 0;
4080
4081
        case KEY_USAGE_OID:
4082
        {
4083
            int ret = 0;
4084
            word16 extKeyUsage = 0;
4085
4086
            ret = DecodeKeyUsage((const byte *)asn1str->data, asn1str->length,
4087
                    &extKeyUsage);
4088
            if (ret != 0)
4089
                return ret;
4090
4091
            wolfSSL_ASN1_STRING_set(asn1str, (byte*)&extKeyUsage,
4092
                                    sizeof(extKeyUsage));
4093
            return 0;
4094
        }
4095
4096
        case EXT_KEY_USAGE_OID:
4097
        {
4098
            int ret = 0;
4099
            const byte *extExtKeyUsageSrc = NULL;
4100
            word32 extExtKeyUsageSz = 0;
4101
            word32 extExtKeyUsageCount = 0;
4102
            byte extExtKeyUsage = 0;
4103
            byte extExtKeyUsageSsh = 0;
4104
            char *data = NULL;
4105
4106
            ret = DecodeExtKeyUsage((const byte*)asn1str->data, asn1str->length,
4107
                    &extExtKeyUsageSrc, &extExtKeyUsageSz, &extExtKeyUsageCount,
4108
                    &extExtKeyUsage, &extExtKeyUsageSsh, NULL);
4109
            if (ret != 0)
4110
                return ret;
4111
4112
            data = (char*)XMALLOC((size_t)(extExtKeyUsageSz), NULL,
4113
                                  DYNAMIC_TYPE_OPENSSL);
4114
            if (data == NULL)
4115
                return MEMORY_ERROR;
4116
4117
            XMEMCPY(data, extExtKeyUsageSrc, (size_t)extExtKeyUsageSz);
4118
            wolfSSL_ASN1_STRING_set(asn1str, data, extExtKeyUsageSz);
4119
            XFREE(data, NULL, DYNAMIC_TYPE_OPENSSL);
4120
            return 0;
4121
        }
4122
4123
        case CRL_DIST_OID:
4124
            wolfSSL_ASN1_STRING_clear(asn1str);
4125
            asn1str->data = NULL;
4126
            asn1str->length = 0;
4127
            return 0;
4128
4129
        default:
4130
            /* Do nothing, it is already set */
4131
            return 0;
4132
    }
4133
}
4134
#endif /* WOLFSSL_OLD_EXTDATA_FMT */
4135
4136
/* Returns pointer to ASN1_STRING in X509_EXTENSION object */
4137
WOLFSSL_ASN1_STRING* wolfSSL_X509_EXTENSION_get_data(
4138
    WOLFSSL_X509_EXTENSION* ext)
4139
{
4140
    WOLFSSL_ASN1_STRING *ret;
4141
4142
    ret =  wolfSSL_X509_EXTENSION_get_data_internal(ext);
4143
4144
#ifdef WOLFSSL_OLD_EXTDATA_FMT
4145
    if (ret)
4146
    {
4147
        int error;
4148
        error = wolfSSL_ASN1_STRING_into_old_ext_fmt (ret, ext->obj->type);
4149
        if (error != 0)
4150
        {
4151
            WOLFSSL_MSG("Error calling wolfSSL_ASN1_STRING_into_old_ext_fmt");
4152
            return NULL;
4153
        }
4154
    }
4155
#endif
4156
4157
    return ret;
4158
}
4159
4160
4161
/**
4162
 * Creates a duplicate of input 'data' and sets it into 'ext' structure
4163
 * returns WOLFSSL_SUCCESS on success
4164
 */
4165
int wolfSSL_X509_EXTENSION_set_data(WOLFSSL_X509_EXTENSION* ext,
4166
        WOLFSSL_ASN1_STRING* data)
4167
{
4168
    if (ext == NULL || data == NULL)
4169
        return WOLFSSL_FAILURE;
4170
4171
    /* wolfSSL_ASN1_STRING_copy() defers to wolfSSL_ASN1_STRING_set(), which
4172
     * owns the free of any existing dynamic buffer and only releases it once
4173
     * the new contents have been copied.  Freeing it here as well would leave
4174
     * ext->value.data dangling for that copy, so leave the buffer alone; the
4175
     * self-aliased case (data == &ext->value) keeps working too. */
4176
    return wolfSSL_ASN1_STRING_copy(&ext->value, data);
4177
}
4178
4179
int wolfSSL_X509_digest(const WOLFSSL_X509* x509, const WOLFSSL_EVP_MD* digest,
4180
        unsigned char* buf, unsigned int* len)
4181
{
4182
    int ret;
4183
4184
    WOLFSSL_ENTER("wolfSSL_X509_digest");
4185
4186
    if (x509 == NULL || digest == NULL) {
4187
        WOLFSSL_MSG("Null argument found");
4188
        return WOLFSSL_FAILURE;
4189
    }
4190
4191
    if (x509->derCert == NULL) {
4192
        WOLFSSL_MSG("No DER certificate stored in X509");
4193
        return WOLFSSL_FAILURE;
4194
    }
4195
4196
    ret = wolfSSL_EVP_Digest(x509->derCert->buffer, x509->derCert->length, buf,
4197
                              len, digest, NULL);
4198
    WOLFSSL_LEAVE("wolfSSL_X509_digest", ret);
4199
    return ret;
4200
}
4201
4202
int wolfSSL_X509_pubkey_digest(const WOLFSSL_X509 *x509,
4203
        const WOLFSSL_EVP_MD *digest, unsigned char* buf, unsigned int* len)
4204
{
4205
    int ret;
4206
4207
    WOLFSSL_ENTER("wolfSSL_X509_pubkey_digest");
4208
4209
    if (x509 == NULL || digest == NULL) {
4210
        WOLFSSL_MSG("Null argument found");
4211
        return WOLFSSL_FAILURE;
4212
    }
4213
4214
    if (x509->pubKey.buffer == NULL || x509->pubKey.length == 0) {
4215
        WOLFSSL_MSG("No DER public key stored in X509");
4216
        return WOLFSSL_FAILURE;
4217
    }
4218
4219
    ret = wolfSSL_EVP_Digest(x509->pubKey.buffer, x509->pubKey.length, buf,
4220
                              len, digest, NULL);
4221
    WOLFSSL_LEAVE("wolfSSL_X509_pubkey_digest", ret);
4222
    return ret;
4223
}
4224
4225
#endif /* OPENSSL_EXTRA */
4226
4227
#ifdef OPENSSL_EXTRA
4228
4229
    #ifndef NO_WOLFSSL_STUB
4230
    const char* wolfSSL_X509_get_default_cert_file_env(void)
4231
    {
4232
        WOLFSSL_STUB("X509_get_default_cert_file_env");
4233
        return "";
4234
    }
4235
4236
    const char* wolfSSL_X509_get_default_cert_file(void)
4237
    {
4238
        WOLFSSL_STUB("X509_get_default_cert_file");
4239
        return "";
4240
    }
4241
4242
    const char* wolfSSL_X509_get_default_cert_dir_env(void)
4243
    {
4244
        WOLFSSL_STUB("X509_get_default_cert_dir_env");
4245
        return "";
4246
    }
4247
4248
    const char* wolfSSL_X509_get_default_cert_dir(void)
4249
    {
4250
        WOLFSSL_STUB("X509_get_default_cert_dir");
4251
        return "";
4252
    }
4253
    #endif
4254
4255
#endif /* OPENSSL_EXTRA */
4256
4257
#if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS) || \
4258
    defined(KEEP_OUR_CERT) || \
4259
    defined(OPENSSL_EXTRA)  || defined(OPENSSL_EXTRA_X509_SMALL)
4260
4261
/* user externally called free X509, if dynamic go ahead with free, otherwise
4262
 * don't */
4263
static void ExternalFreeX509(WOLFSSL_X509* x509)
4264
{
4265
#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA)
4266
    int doFree = 0;
4267
#endif
4268
4269
    WOLFSSL_ENTER("ExternalFreeX509");
4270
    if (x509) {
4271
        if (x509->dynamicMemory) {
4272
        #if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA)
4273
            int ret;
4274
            wolfSSL_RefDec(&x509->ref, &doFree, &ret);
4275
            if (ret != 0) {
4276
                WOLFSSL_MSG("Couldn't lock x509 mutex");
4277
            }
4278
            if (doFree)
4279
        #endif /* OPENSSL_EXTRA_X509_SMALL || OPENSSL_EXTRA */
4280
            {
4281
            #ifdef HAVE_EX_DATA_CLEANUP_HOOKS
4282
                /* Only with the last reference, as other holders may still
4283
                 * use the ex_data. */
4284
                wolfSSL_CRYPTO_cleanup_ex_data(&x509->ex_data);
4285
            #endif
4286
                FreeX509(x509);
4287
                XFREE(x509, x509->heap, DYNAMIC_TYPE_X509);
4288
            }
4289
        }
4290
        else {
4291
            WOLFSSL_MSG("free called on non dynamic object, not freeing");
4292
        }
4293
    }
4294
}
4295
4296
/* Frees an external WOLFSSL_X509 structure */
4297
WOLFSSL_ABI
4298
void wolfSSL_X509_free(WOLFSSL_X509* x509)
4299
{
4300
    WOLFSSL_ENTER("wolfSSL_X509_free");
4301
    ExternalFreeX509(x509);
4302
}
4303
#endif
4304
4305
#if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS) || \
4306
    defined(OPENSSL_EXTRA)  || defined(OPENSSL_EXTRA_X509_SMALL)
4307
4308
/* copy name into in buffer, at most sz bytes, if buffer is null will
4309
   malloc buffer, call responsible for freeing                     */
4310
WOLFSSL_ABI
4311
char* wolfSSL_X509_NAME_oneline(WOLFSSL_X509_NAME* name, char* in, int sz)
4312
{
4313
    int copySz;
4314
4315
    WOLFSSL_ENTER("wolfSSL_X509_NAME_oneline");
4316
4317
    if (name == NULL) {
4318
        WOLFSSL_MSG("WOLFSSL_X509_NAME pointer was NULL");
4319
        return NULL;
4320
    }
4321
4322
    if (name->sz == 0)
4323
        return in;
4324
4325
    if (!in) {
4326
    #ifdef WOLFSSL_STATIC_MEMORY
4327
        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
4328
        return NULL;
4329
    #else
4330
        in = (char*)XMALLOC(name->sz, NULL, DYNAMIC_TYPE_OPENSSL);
4331
        if (!in)
4332
            return in;
4333
        copySz = name->sz;
4334
    #endif
4335
    }
4336
    else {
4337
        copySz = (int)min((word32)sz, (word32)name->sz);
4338
        if (copySz <= 0)
4339
            return in;
4340
    }
4341
4342
    XMEMCPY(in, name->name, copySz - 1);
4343
    in[copySz - 1] = 0;
4344
4345
    return in;
4346
}
4347
4348
#ifdef OPENSSL_EXTRA
4349
/* Given an X509_NAME, convert it to canonical form and then hash
4350
 * with the provided hash type. Returns the first 4 bytes of the hash
4351
 * as unsigned long on success, and 0 otherwise. */
4352
static unsigned long X509NameHash(WOLFSSL_X509_NAME* name,
4353
    enum wc_HashType hashType)
4354
{
4355
    unsigned long  hash = 0;
4356
    unsigned char* canonName = NULL;
4357
    byte           digest[WC_MAX_DIGEST_SIZE];
4358
    int            size = 0;
4359
    int            rc;
4360
4361
    WOLFSSL_ENTER("X509NameHash");
4362
4363
    if (name == NULL) {
4364
        WOLFSSL_ERROR_MSG("WOLFSSL_X509_NAME pointer was NULL");
4365
        return 0;
4366
    }
4367
4368
    if (name->sz == 0) {
4369
        WOLFSSL_ERROR_MSG("Nothing to hash in WOLFSSL_X509_NAME");
4370
        return 0;
4371
    }
4372
4373
    size = wolfSSL_i2d_X509_NAME_canon(name, &canonName);
4374
4375
    if (size <= 0 || canonName == NULL) {
4376
        WOLFSSL_ERROR_MSG("wolfSSL_i2d_X509_NAME_canon error");
4377
        return 0;
4378
    }
4379
4380
    rc = wc_Hash(hashType, (const byte*)canonName, (word32)size, digest,
4381
        sizeof(digest));
4382
4383
    if (rc == 0) {
4384
        hash = (((unsigned long)digest[3] << 24) |
4385
                ((unsigned long)digest[2] << 16) |
4386
                ((unsigned long)digest[1] <<  8) |
4387
                ((unsigned long)digest[0]));
4388
    }
4389
    else if (rc == WC_NO_ERR_TRACE(HASH_TYPE_E)) {
4390
        WOLFSSL_ERROR_MSG("Hash function not compiled in");
4391
    }
4392
    else {
4393
        WOLFSSL_ERROR_MSG("Error hashing name");
4394
    }
4395
4396
    XFREE(canonName, NULL, DYNAMIC_TYPE_OPENSSL);
4397
    return hash;
4398
}
4399
4400
unsigned long wolfSSL_X509_NAME_hash(WOLFSSL_X509_NAME* name)
4401
{
4402
    return X509NameHash(name, WC_HASH_TYPE_SHA);
4403
}
4404
4405
/******************************************************************************
4406
* wolfSSL_X509_subject_name_hash
4407
* wolfSSL_X509_issuer_name_hash
4408
* Compute the hash digest of the subject / issuer name.
4409
* These functions prefer SHA-1 (if available) for compatibility. Otherwise
4410
* they use SHA-256.
4411
*
4412
* RETURNS:
4413
* The first 4 bytes of SHA-1 (or SHA-256) hash in little endian order as
4414
* unsigned long.
4415
* Otherwise, returns zero.
4416
*
4417
* Note:
4418
* Returns the same hash value as OpenSSL's X509_X_name_hash() API
4419
* if SHA-1 support is compiled in. SHA-256 will be used if SHA-1 is
4420
* not available.
4421
*/
4422
unsigned long wolfSSL_X509_subject_name_hash(const WOLFSSL_X509* x509)
4423
{
4424
    if (x509 == NULL) {
4425
        WOLFSSL_ERROR_MSG("WOLFSSL_X509 pointer was NULL");
4426
        return 0;
4427
    }
4428
4429
    #ifndef NO_SHA
4430
    return X509NameHash((WOLFSSL_X509_NAME*) &x509->subject, WC_HASH_TYPE_SHA);
4431
    #elif !defined(NO_SHA256)
4432
    return X509NameHash((WOLFSSL_X509_NAME*) &x509->subject,
4433
                        WC_HASH_TYPE_SHA256);
4434
    #else
4435
    WOLFSSL_ERROR_MSG("Hash function not compiled in");
4436
    return 0;
4437
    #endif
4438
}
4439
4440
unsigned long wolfSSL_X509_issuer_name_hash(const WOLFSSL_X509* x509)
4441
{
4442
    if (x509 == NULL) {
4443
        WOLFSSL_ERROR_MSG("WOLFSSL_X509 pointer was NULL");
4444
        return 0;
4445
    }
4446
4447
    #ifndef NO_SHA
4448
    return X509NameHash((WOLFSSL_X509_NAME*) &x509->issuer, WC_HASH_TYPE_SHA);
4449
    #elif !defined(NO_SHA256)
4450
    return X509NameHash((WOLFSSL_X509_NAME*) &x509->issuer,
4451
                        WC_HASH_TYPE_SHA256);
4452
    #else
4453
    WOLFSSL_ERROR_MSG("Hash function not compiled in");
4454
    return 0;
4455
    #endif
4456
}
4457
#endif /* OPENSSL_EXTRA */
4458
4459
#if defined(OPENSSL_EXTRA) && defined(XSNPRINTF)
4460
/* Copies X509 subject name into a buffer, with comma-separated name entries
4461
 *   (matching OpenSSL v1.0.0 format)
4462
 * Example Output for Issuer:
4463
 *
4464
 * C=US, ST=Montana, L=Bozeman, O=Sawtooth, OU=Consulting,
4465
 *  CN=www.wolfssl.com, emailAddress=facts@wolfssl.com
4466
 */
4467
char* wolfSSL_X509_get_name_oneline(WOLFSSL_X509_NAME* name, char* in, int sz)
4468
{
4469
    int count, i;
4470
    int totalLen = 0;
4471
    char tmpBuf[256];
4472
    WOLFSSL_ENTER("wolfSSL_X509_get_name_oneline");
4473
4474
    if (name == NULL) {
4475
        WOLFSSL_MSG("wolfSSL_X509_get_name_oneline failed");
4476
        return NULL;
4477
    }
4478
    #ifdef WOLFSSL_STATIC_MEMORY
4479
    if (!in) {
4480
        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
4481
        return NULL;
4482
    }
4483
    #endif
4484
4485
    /* Loop through X509 name entries and copy new format to buffer */
4486
    count = wolfSSL_X509_NAME_entry_count(name);
4487
    for (i = 0; i < count; i++) {
4488
        WOLFSSL_X509_NAME_ENTRY* entry;
4489
        int nameSz;
4490
        int strSz;
4491
        int strLen;
4492
        char *str;
4493
        const int tmpBufSz = sizeof(tmpBuf);
4494
        char buf[80];
4495
        const char* sn;
4496
4497
        /* Get name entry and size */
4498
        entry = wolfSSL_X509_NAME_get_entry(name, i);
4499
        if (entry == NULL) {
4500
            WOLFSSL_MSG("wolfSSL_X509_NAME_get_entry failed");
4501
            return NULL;
4502
        }
4503
        nameSz = wolfSSL_X509_NAME_get_text_by_NID(name, entry->nid, buf,
4504
                                                                   sizeof(buf));
4505
        if (nameSz < 0) {
4506
            WOLFSSL_MSG("wolfSSL_X509_NAME_get_text_by_NID failed");
4507
            return NULL;
4508
        }
4509
4510
        /* Get short name */
4511
        sn = wolfSSL_OBJ_nid2sn(entry->nid);
4512
        if (sn == NULL) {
4513
            WOLFSSL_MSG("OBJ_nid2sn failed");
4514
            return NULL;
4515
        }
4516
4517
        /* Copy sn and name text to buffer
4518
         * Add extra strSz for '=', ',', ' ' and '\0' characters in XSNPRINTF.
4519
         */
4520
        if (i != count - 1) {
4521
            strSz = (int)XSTRLEN(sn) + nameSz + 4;
4522
            str = (char*)XMALLOC(strSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4523
            if (str == NULL) {
4524
                WOLFSSL_MSG("Memory error");
4525
                return NULL;
4526
            }
4527
            strLen = XSNPRINTF(str, (size_t)strSz, "%s=%s, ", sn, buf);
4528
            if ((strLen  < 0) || (strLen  >= strSz)) {
4529
                WOLFSSL_MSG("buffer overrun");
4530
                XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4531
                return NULL;
4532
            }
4533
        }
4534
        else {
4535
            /* Copy last name entry
4536
            * Add extra strSz for '=' and '\0' characters in XSNPRINTF.
4537
            */
4538
            strSz = (int)XSTRLEN(sn) + nameSz + 2;
4539
            str = (char*)XMALLOC(strSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4540
            if (str == NULL) {
4541
                WOLFSSL_MSG("Memory error");
4542
                return NULL;
4543
            }
4544
            strLen = XSNPRINTF(str, (size_t)strSz, "%s=%s", sn, buf);
4545
            if ((strLen  < 0) || (strLen  >= strSz)) {
4546
                WOLFSSL_MSG("buffer overrun");
4547
                XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4548
                return NULL;
4549
            }
4550
        }
4551
        /* Copy string to tmpBuf */
4552
        if (totalLen + strLen > tmpBufSz) {
4553
            WOLFSSL_MSG("buffer overrun");
4554
            XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4555
            return NULL;
4556
        }
4557
        XMEMCPY(tmpBuf + totalLen, str, strLen);
4558
        totalLen += strLen;
4559
        XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4560
    }
4561
4562
    /* Allocate space based on total string size if no buffer was provided */
4563
    if (!in) {
4564
        in = (char*)XMALLOC(totalLen+1, NULL, DYNAMIC_TYPE_OPENSSL);
4565
        if (in == NULL) {
4566
            WOLFSSL_MSG("Memory error");
4567
            return in;
4568
        }
4569
    }
4570
    else {
4571
        if (totalLen + 1 > sz) {
4572
            WOLFSSL_MSG("buffer overrun");
4573
            return NULL;
4574
        }
4575
    }
4576
4577
    XMEMCPY(in, tmpBuf, totalLen); /* cppcheck-suppress uninitvar */
4578
    in[totalLen] = '\0';
4579
4580
    return in;
4581
}
4582
#endif
4583
4584
4585
static WOLFSSL_X509* d2i_X509orX509REQ(WOLFSSL_X509** x509,
4586
        const byte* in, int len, int req, byte allowTrailing, void* heap);
4587
4588
/* Wraps wolfSSL_X509_d2i
4589
 *
4590
 * returns a WOLFSSL_X509 structure pointer on success and NULL on fail
4591
 */
4592
WOLFSSL_X509* wolfSSL_d2i_X509(WOLFSSL_X509** x509, const unsigned char** in,
4593
        int len)
4594
{
4595
    WOLFSSL_X509* newX509 = NULL;
4596
    WOLFSSL_ENTER("wolfSSL_d2i_X509");
4597
4598
    if (in == NULL) {
4599
        WOLFSSL_MSG("NULL input for wolfSSL_d2i_X509");
4600
        return NULL;
4601
    }
4602
4603
    /* len only bounds the input; *in is advanced past this certificate. */
4604
    newX509 = d2i_X509orX509REQ(x509, *in, len, 0, 1, NULL);
4605
    if (newX509 != NULL) {
4606
        *in += newX509->derCert->length;
4607
    }
4608
    return newX509;
4609
}
4610
4611
static WOLFSSL_X509* d2i_X509orX509REQ(WOLFSSL_X509** x509,
4612
        const byte* in, int len, int req, byte allowTrailing, void* heap)
4613
{
4614
    WOLFSSL_X509 *newX509 = NULL;
4615
    int type = req ? CERTREQ_TYPE : CERT_TYPE;
4616
4617
    WOLFSSL_ENTER("wolfSSL_X509_d2i");
4618
4619
    if (in != NULL && len > 0
4620
    #ifndef WOLFSSL_CERT_REQ
4621
            && req == 0
4622
    #else
4623
            && (req == 0 || req == 1)
4624
    #endif
4625
            ) {
4626
        WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
4627
4628
        WC_ALLOC_VAR_EX(cert, DecodedCert, 1, NULL, DYNAMIC_TYPE_DCERT,
4629
            return NULL);
4630
4631
        InitDecodedCert(cert, (byte*)in, (word32)len, heap);
4632
    #ifdef WOLFSSL_CERT_REQ
4633
        cert->isCSR = (byte)req;
4634
    #endif
4635
        cert->allowTrailing = allowTrailing;
4636
    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
4637
        /* CopyDecodedToX509() adds the name entries to the X509 directly. */
4638
        cert->noX509Name = 1;
4639
    #endif
4640
        if (ParseCertRelative(cert, type, 0, NULL, NULL) == 0) {
4641
            newX509 = wolfSSL_X509_new_ex(heap);
4642
            if (newX509 != NULL) {
4643
                if (CopyDecodedToX509(newX509, cert) != 0) {
4644
                    wolfSSL_X509_free(newX509);
4645
                    newX509 = NULL;
4646
                }
4647
            }
4648
        }
4649
        FreeDecodedCert(cert);
4650
        WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
4651
    }
4652
4653
    if (x509 != NULL)
4654
        *x509 = newX509;
4655
4656
    return newX509;
4657
}
4658
4659
int wolfSSL_X509_get_isCA(WOLFSSL_X509* x509)
4660
{
4661
    int isCA = 0;
4662
4663
    WOLFSSL_ENTER("wolfSSL_X509_get_isCA");
4664
4665
    if (x509 != NULL)
4666
        isCA = x509->isCa;
4667
4668
    WOLFSSL_LEAVE("wolfSSL_X509_get_isCA", isCA);
4669
4670
    return isCA;
4671
}
4672
4673
WOLFSSL_X509* wolfSSL_X509_d2i_ex(WOLFSSL_X509** x509, const byte* in, int len,
4674
    void* heap)
4675
{
4676
    return d2i_X509orX509REQ(x509, in, len, 0, 0, heap);
4677
}
4678
4679
WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len)
4680
{
4681
    return wolfSSL_X509_d2i_ex(x509, in, len, NULL);
4682
}
4683
4684
#ifdef WOLFSSL_CERT_REQ
4685
WOLFSSL_X509* wolfSSL_X509_REQ_d2i(WOLFSSL_X509** x509,
4686
        const unsigned char* in, int len)
4687
{
4688
    return d2i_X509orX509REQ(x509, in, len, 1, 0, NULL);
4689
}
4690
4691
WOLFSSL_X509* wolfSSL_d2i_X509_REQ_INFO(WOLFSSL_X509** req,
4692
        const unsigned char** in, int len)
4693
{
4694
    WOLFSSL_X509* ret = NULL;
4695
    WOLFSSL_ENTER("wolfSSL_d2i_X509_REQ_INFO");
4696
4697
    if (in == NULL) {
4698
        WOLFSSL_MSG("NULL input for wolfSSL_d2i_X509");
4699
        return NULL;
4700
    }
4701
4702
    ret = wolfSSL_X509_REQ_d2i(req, *in, len);
4703
    if (ret != NULL) {
4704
        *in += ret->derCert->length;
4705
    }
4706
    return ret;
4707
}
4708
#endif
4709
4710
#endif /* KEEP_PEER_CERT || SESSION_CERTS || OPENSSL_EXTRA ||
4711
          OPENSSL_EXTRA_X509_SMALL */
4712
4713
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
4714
/* returns the number of entries in the WOLFSSL_X509_NAME */
4715
int wolfSSL_X509_NAME_entry_count(const WOLFSSL_X509_NAME* name)
4716
{
4717
    int count = 0;
4718
4719
    WOLFSSL_ENTER("wolfSSL_X509_NAME_entry_count");
4720
4721
    if (name != NULL)
4722
        count = name->entrySz;
4723
4724
    WOLFSSL_LEAVE("wolfSSL_X509_NAME_entry_count", count);
4725
    return count;
4726
}
4727
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
4728
4729
#if defined(OPENSSL_EXTRA) || \
4730
    defined(KEEP_OUR_CERT) || defined(KEEP_PEER_CERT)
4731
4732
/* return the next, if any, altname from the peer cert */
4733
WOLFSSL_ABI
4734
char* wolfSSL_X509_get_next_altname(WOLFSSL_X509* cert)
4735
{
4736
    char* ret = NULL;
4737
    WOLFSSL_ENTER("wolfSSL_X509_get_next_altname");
4738
4739
    /* don't have any to work with */
4740
    if (cert == NULL || cert->altNames == NULL)
4741
        return NULL;
4742
4743
    /* already went through them */
4744
    if (cert->altNamesNext == NULL) {
4745
#ifdef WOLFSSL_MULTICIRCULATE_ALTNAMELIST
4746
        /* Reset altNames List to head
4747
         * so that caller can circulate the list again
4748
         */
4749
        cert->altNamesNext = cert->altNames;
4750
#endif
4751
        return NULL;
4752
    }
4753
4754
    /* In default builds iPAddress entries hold raw 4/16 octet payloads
4755
     * and registeredID entries hold raw OID body bytes (no human-readable
4756
     * ipString/ridString), so returning them as a C string would truncate
4757
     * at any embedded NUL byte. Such entries are still parsed into
4758
     * altNames for name-constraint enforcement; skip them here so
4759
     * string-iteration callers see the same set of entries as before.
4760
     *
4761
     * With WOLFSSL_MULTICIRCULATE_ALTNAMELIST, a list consisting only of
4762
     * skipped entries collapses to "no entries" on the first pass and
4763
     * resets to head on the next call; the cycle shape matches the
4764
     * pre-fix behavior where such entries were never parsed. */
4765
#if !defined(WOLFSSL_IP_ALT_NAME) || !defined(WOLFSSL_RID_ALT_NAME)
4766
    while (cert->altNamesNext != NULL) {
4767
        int skip = 0;
4768
#ifndef WOLFSSL_IP_ALT_NAME
4769
        if (cert->altNamesNext->type == ASN_IP_TYPE)
4770
            skip = 1;
4771
#endif
4772
#ifndef WOLFSSL_RID_ALT_NAME
4773
        if (cert->altNamesNext->type == ASN_RID_TYPE)
4774
            skip = 1;
4775
#endif
4776
        if (!skip)
4777
            break;
4778
        cert->altNamesNext = cert->altNamesNext->next;
4779
    }
4780
    if (cert->altNamesNext == NULL)
4781
        return NULL;
4782
#endif /* !WOLFSSL_IP_ALT_NAME || !WOLFSSL_RID_ALT_NAME */
4783
4784
    /* unsafe cast required for ABI compatibility. */
4785
    ret = (char *)(wc_ptr_t)cert->altNamesNext->name;
4786
#ifdef WOLFSSL_IP_ALT_NAME
4787
    /* return the IP address as a string */
4788
    if (cert->altNamesNext->type == ASN_IP_TYPE) {
4789
        ret = cert->altNamesNext->ipString;
4790
    }
4791
#endif
4792
#ifdef WOLFSSL_RID_ALT_NAME
4793
    /* return the registeredID as a string */
4794
    if (cert->altNamesNext->type == ASN_RID_TYPE) {
4795
        ret = cert->altNamesNext->ridString;
4796
    }
4797
#endif
4798
    cert->altNamesNext = cert->altNamesNext->next;
4799
4800
    return ret;
4801
}
4802
4803
int wolfSSL_X509_get_signature(WOLFSSL_X509* x509,
4804
                                                unsigned char* buf, int* bufSz)
4805
{
4806
    WOLFSSL_ENTER("wolfSSL_X509_get_signature");
4807
    if (x509 == NULL || bufSz == NULL || (*bufSz < (int)x509->sig.length &&
4808
                buf != NULL))
4809
        return WOLFSSL_FATAL_ERROR;
4810
4811
    if (buf != NULL)
4812
        XMEMCPY(buf, x509->sig.buffer, x509->sig.length);
4813
    *bufSz = (int)x509->sig.length;
4814
4815
    return WOLFSSL_SUCCESS;
4816
}
4817
4818
4819
/* Getter function that copies over the DER public key buffer to "buf" and
4820
    * sets the size in bufSz. If "buf" is NULL then just bufSz is set to needed
4821
    * buffer size. "bufSz" passed in should initially be set by the user to be
4822
    * the size of "buf". This gets checked to make sure the buffer is large
4823
    * enough to hold the public key.
4824
    *
4825
    * Note: this is the X.509 form of key with "header" info.
4826
    * return WOLFSSL_SUCCESS on success
4827
    */
4828
int wolfSSL_X509_get_pubkey_buffer(WOLFSSL_X509* x509,
4829
                                            unsigned char* buf, int* bufSz)
4830
{
4831
    WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
4832
    const byte*  der;
4833
    int length = 0;
4834
    int    ret = 0, derSz = 0;
4835
    int badDate = 0;
4836
    const byte* pubKeyX509 = NULL;
4837
    int   pubKeyX509Sz = 0;
4838
4839
    WOLFSSL_ENTER("wolfSSL_X509_get_pubkey_buffer");
4840
    if (x509 == NULL || bufSz == NULL) {
4841
        WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", BAD_FUNC_ARG);
4842
        return WOLFSSL_FATAL_ERROR;
4843
    }
4844
4845
4846
#ifdef WOLFSSL_SMALL_STACK
4847
    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert),
4848
                                    x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
4849
    if (cert == NULL) {
4850
        WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", MEMORY_E);
4851
        return WOLFSSL_FATAL_ERROR;
4852
    }
4853
#endif
4854
4855
    der = wolfSSL_X509_get_der(x509, &derSz);
4856
    if (der != NULL) {
4857
        InitDecodedCert(cert, der, (word32)derSz, NULL);
4858
        ret = wc_GetPubX509(cert, 0, &badDate);
4859
        if (ret >= 0) {
4860
            word32 idx = cert->srcIdx;
4861
            pubKeyX509 = cert->source + cert->srcIdx;
4862
            ret = GetSequence(cert->source, &cert->srcIdx, &length,
4863
                    cert->maxIdx);
4864
            pubKeyX509Sz = length + (cert->srcIdx - idx);
4865
        }
4866
        FreeDecodedCert(cert);
4867
    }
4868
    WC_FREE_VAR_EX(cert, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
4869
4870
    if (ret < 0) {
4871
        WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", ret);
4872
        return WOLFSSL_FATAL_ERROR;
4873
    }
4874
4875
    if (buf != NULL && pubKeyX509 != NULL) {
4876
        if (pubKeyX509Sz > *bufSz) {
4877
            WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", BUFFER_E);
4878
            return WOLFSSL_FATAL_ERROR;
4879
        }
4880
        XMEMCPY(buf, pubKeyX509, pubKeyX509Sz);
4881
    }
4882
    *bufSz = pubKeyX509Sz;
4883
4884
    return WOLFSSL_SUCCESS;
4885
}
4886
4887
4888
/* Getter function for the public key OID value
4889
    * return public key OID stored in WOLFSSL_X509 structure */
4890
int wolfSSL_X509_get_pubkey_type(WOLFSSL_X509* x509)
4891
{
4892
    if (x509 == NULL)
4893
        return WOLFSSL_FAILURE;
4894
    return x509->pubKeyOID;
4895
}
4896
4897
#endif /* OPENSSL_EXTRA || KEEP_OUR_CERT || KEEP_PEER_CERT || SESSION_CERTS */
4898
4899
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
4900
    defined(KEEP_OUR_CERT) || defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
4901
4902
/* write X509 serial number in unsigned binary to buffer
4903
    buffer needs to be at least EXTERNAL_SERIAL_SIZE (32) for all cases
4904
    return WOLFSSL_SUCCESS on success */
4905
int wolfSSL_X509_get_serial_number(WOLFSSL_X509* x509,
4906
                                    byte* in, int* inOutSz)
4907
{
4908
    WOLFSSL_ENTER("wolfSSL_X509_get_serial_number");
4909
    if (x509 == NULL || inOutSz == NULL) {
4910
        WOLFSSL_MSG("Null argument passed in");
4911
        return BAD_FUNC_ARG;
4912
    }
4913
4914
    if (in != NULL) {
4915
        if (*inOutSz < x509->serialSz) {
4916
            WOLFSSL_MSG("Serial buffer too small");
4917
            return BUFFER_E;
4918
        }
4919
        XMEMCPY(in, x509->serial, x509->serialSz);
4920
    }
4921
    *inOutSz = x509->serialSz;
4922
4923
    return WOLFSSL_SUCCESS;
4924
}
4925
4926
/* not an openssl compatibility function - getting for derCert */
4927
const byte* wolfSSL_X509_get_der(WOLFSSL_X509* x509, int* outSz)
4928
{
4929
    WOLFSSL_ENTER("wolfSSL_X509_get_der");
4930
4931
    if (x509 == NULL || x509->derCert == NULL || outSz == NULL)
4932
        return NULL;
4933
4934
    if (x509->derCert->length > (word32)INT_MAX) {
4935
        return NULL;
4936
    }
4937
4938
    *outSz = (int)x509->derCert->length;
4939
    return x509->derCert->buffer;
4940
}
4941
4942
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || KEEP_OUR_CERT ||
4943
        * KEEP_PEER_CERT || SESSION_CERTS */
4944
4945
#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) || \
4946
    defined(OPENSSL_ALL) || defined(KEEP_OUR_CERT) || \
4947
    defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
4948
4949
/* used by JSSE (not a standard compatibility function) */
4950
WOLFSSL_ABI
4951
const byte* wolfSSL_X509_notBefore(WOLFSSL_X509* x509)
4952
{
4953
    WOLFSSL_ENTER("wolfSSL_X509_notBefore");
4954
4955
    if (x509 == NULL) {
4956
        return NULL;
4957
    }
4958
4959
    if (x509->notBefore.length < 0 ||
4960
            x509->notBefore.length > (int)sizeof(x509->notBeforeData) - 2) {
4961
        return NULL;
4962
    }
4963
4964
    XMEMSET(x509->notBeforeData, 0, sizeof(x509->notBeforeData));
4965
    x509->notBeforeData[0] = (byte)x509->notBefore.type;
4966
    x509->notBeforeData[1] = (byte)x509->notBefore.length;
4967
    XMEMCPY(&x509->notBeforeData[2], x509->notBefore.data,
4968
        x509->notBefore.length);
4969
4970
    return x509->notBeforeData;
4971
}
4972
4973
/* used by JSSE (not a standard compatibility function) */
4974
WOLFSSL_ABI
4975
const byte* wolfSSL_X509_notAfter(WOLFSSL_X509* x509)
4976
{
4977
    WOLFSSL_ENTER("wolfSSL_X509_notAfter");
4978
4979
    if (x509 == NULL) {
4980
        return NULL;
4981
    }
4982
4983
    if (x509->notAfter.length < 0 ||
4984
            x509->notAfter.length > (int)sizeof(x509->notAfterData) - 2) {
4985
        return NULL;
4986
    }
4987
4988
    XMEMSET(x509->notAfterData, 0, sizeof(x509->notAfterData));
4989
    x509->notAfterData[0] = (byte)x509->notAfter.type;
4990
    x509->notAfterData[1] = (byte)x509->notAfter.length;
4991
    XMEMCPY(&x509->notAfterData[2], x509->notAfter.data, x509->notAfter.length);
4992
4993
    return x509->notAfterData;
4994
}
4995
4996
int wolfSSL_X509_version(WOLFSSL_X509* x509)
4997
{
4998
    WOLFSSL_ENTER("wolfSSL_X509_version");
4999
5000
    if (x509 == NULL)
5001
        return 0;
5002
5003
    return x509->version;
5004
}
5005
#endif
5006
5007
#ifdef OPENSSL_EXTRA
5008
5009
/* get the buffer to be signed (tbs) from the WOLFSSL_X509 certificate
5010
    *
5011
    * outSz : gets set to the size of the buffer
5012
    * returns a pointer to the internal buffer at the location of TBS on
5013
    *         on success and NULL on failure.
5014
    */
5015
const unsigned char* wolfSSL_X509_get_tbs(WOLFSSL_X509* x509, int* outSz)
5016
{
5017
    int sz = 0, len;
5018
    unsigned int idx = 0, tmpIdx;
5019
    const unsigned char* der = NULL;
5020
    const unsigned char* tbs = NULL;
5021
5022
    if (x509 == NULL || outSz == NULL) {
5023
        return NULL;
5024
    }
5025
5026
    der = wolfSSL_X509_get_der(x509, &sz);
5027
    if (der == NULL) {
5028
        return NULL;
5029
    }
5030
5031
    if (GetSequence(der, &idx, &len, (word32)sz) < 0) {
5032
        return NULL;
5033
    }
5034
    tbs = der + idx;
5035
    tmpIdx = idx;
5036
    if (GetSequence(der, &idx, &len, (word32)sz) < 0) {
5037
        return NULL;
5038
    }
5039
    *outSz = len + (idx - tmpIdx);
5040
    return tbs;
5041
}
5042
5043
#ifdef WOLFSSL_SEP
5044
5045
/* copy oid into in buffer, at most *inOutSz bytes, if buffer is null will
5046
   malloc buffer, call responsible for freeing. Actual size returned in
5047
   *inOutSz. Requires inOutSz be non-null */
5048
byte* wolfSSL_X509_get_device_type(WOLFSSL_X509* x509, byte* in, int *inOutSz)
5049
{
5050
    int copySz;
5051
5052
    WOLFSSL_ENTER("wolfSSL_X509_get_dev_type");
5053
    if (x509 == NULL) return NULL;
5054
    if (inOutSz == NULL) return NULL;
5055
    if (!x509->deviceTypeSz) return in;
5056
5057
    copySz = min(*inOutSz, x509->deviceTypeSz);
5058
5059
    if (!in) {
5060
    #ifdef WOLFSSL_STATIC_MEMORY
5061
        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
5062
        return NULL;
5063
    #else
5064
        in = (byte*)XMALLOC(x509->deviceTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
5065
        if (!in) return in;
5066
        copySz = x509->deviceTypeSz;
5067
    #endif
5068
    }
5069
5070
    XMEMCPY(in, x509->deviceType, copySz);
5071
    *inOutSz = copySz;
5072
5073
    return in;
5074
}
5075
5076
5077
byte* wolfSSL_X509_get_hw_type(WOLFSSL_X509* x509, byte* in, int* inOutSz)
5078
{
5079
    int copySz;
5080
5081
    WOLFSSL_ENTER("wolfSSL_X509_get_hw_type");
5082
    if (x509 == NULL) return NULL;
5083
    if (inOutSz == NULL) return NULL;
5084
    if (!x509->hwTypeSz) return in;
5085
5086
    copySz = min(*inOutSz, x509->hwTypeSz);
5087
5088
    if (!in) {
5089
    #ifdef WOLFSSL_STATIC_MEMORY
5090
        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
5091
        return NULL;
5092
    #else
5093
        in = (byte*)XMALLOC(x509->hwTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
5094
        if (!in) return in;
5095
        copySz = x509->hwTypeSz;
5096
    #endif
5097
    }
5098
5099
    XMEMCPY(in, x509->hwType, copySz);
5100
    *inOutSz = copySz;
5101
5102
    return in;
5103
}
5104
5105
5106
byte* wolfSSL_X509_get_hw_serial_number(WOLFSSL_X509* x509,byte* in,
5107
                                        int* inOutSz)
5108
{
5109
    int copySz;
5110
5111
    WOLFSSL_ENTER("wolfSSL_X509_get_hw_serial_number");
5112
    if (x509 == NULL) return NULL;
5113
    if (inOutSz == NULL) return NULL;
5114
    if (!x509->hwTypeSz) return in;
5115
5116
    copySz = min(*inOutSz, x509->hwSerialNumSz);
5117
5118
    if (!in) {
5119
    #ifdef WOLFSSL_STATIC_MEMORY
5120
        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
5121
        return NULL;
5122
    #else
5123
        in = (byte*)XMALLOC(x509->hwSerialNumSz, 0, DYNAMIC_TYPE_OPENSSL);
5124
        if (!in) return in;
5125
        copySz = x509->hwSerialNumSz;
5126
    #endif
5127
    }
5128
5129
    XMEMCPY(in, x509->hwSerialNum, copySz);
5130
    *inOutSz = copySz;
5131
5132
    return in;
5133
}
5134
5135
#endif /* WOLFSSL_SEP */
5136
#endif /* OPENSSL_EXTRA */
5137
5138
/* require OPENSSL_EXTRA since wolfSSL_X509_free is wrapped by OPENSSL_EXTRA */
5139
#if defined(OPENSSL_EXTRA)
5140
5141
WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notBefore(const WOLFSSL_X509* x509)
5142
{
5143
    WOLFSSL_ENTER("wolfSSL_X509_get_notBefore");
5144
5145
    if (x509 == NULL)
5146
        return NULL;
5147
5148
    return (WOLFSSL_ASN1_TIME*)&x509->notBefore;
5149
}
5150
5151
5152
WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notAfter(const WOLFSSL_X509* x509)
5153
{
5154
    WOLFSSL_ENTER("wolfSSL_X509_get_notAfter");
5155
5156
    if (x509 == NULL)
5157
        return NULL;
5158
5159
    return (WOLFSSL_ASN1_TIME*)&x509->notAfter;
5160
}
5161
5162
5163
/* return number of elements on success 0 on fail */
5164
int wolfSSL_sk_X509_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk,
5165
    WOLFSSL_X509* x509)
5166
{
5167
    WOLFSSL_ENTER("wolfSSL_sk_X509_push");
5168
5169
    if (sk == NULL || x509 == NULL) {
5170
        return WOLFSSL_FAILURE;
5171
    }
5172
5173
    return wolfSSL_sk_push(sk, x509);
5174
}
5175
5176
5177
/* Return and remove the last x509 pushed on stack */
5178
WOLFSSL_X509* wolfSSL_sk_X509_pop(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk)
5179
{
5180
    return (WOLFSSL_X509*)wolfSSL_sk_pop(sk);
5181
}
5182
5183
/* Getter function for WOLFSSL_X509 pointer
5184
 *
5185
 * sk is the stack to retrieve pointer from
5186
 * i  is the index value in stack
5187
 *
5188
 * returns a pointer to a WOLFSSL_X509 structure on success and NULL on
5189
 *         fail
5190
 */
5191
WOLFSSL_X509* wolfSSL_sk_X509_value(WOLF_STACK_OF(WOLFSSL_X509)* sk, int i)
5192
{
5193
    WOLFSSL_ENTER("wolfSSL_sk_X509_value");
5194
5195
    for (; sk != NULL && i > 0; i--)
5196
        sk = sk->next;
5197
5198
    if (i != 0 || sk == NULL)
5199
        return NULL;
5200
    return sk->data.x509;
5201
}
5202
5203
5204
/* Return and remove the first x509 pushed on stack */
5205
WOLFSSL_X509* wolfSSL_sk_X509_shift(WOLF_STACK_OF(WOLFSSL_X509)* sk)
5206
{
5207
    return (WOLFSSL_X509*)wolfSSL_sk_pop_node(sk, 0);
5208
}
5209
5210
#endif /* OPENSSL_EXTRA */
5211
5212
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
5213
/* Free's all nodes in X509 stack. This is different then wolfSSL_sk_X509_free
5214
 * in that it free's the underlying objects pushed to the stack.
5215
 *
5216
 * sk  stack to free nodes in
5217
 * f   X509 free function
5218
 */
5219
void wolfSSL_sk_X509_pop_free(WOLF_STACK_OF(WOLFSSL_X509)* sk,
5220
    void (*f) (WOLFSSL_X509*))
5221
{
5222
    WOLFSSL_ENTER("wolfSSL_sk_X509_pop_free");
5223
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
5224
}
5225
5226
5227
/* free just the stack structure */
5228
void wolfSSL_sk_X509_free(WOLF_STACK_OF(WOLFSSL_X509)* sk)
5229
{
5230
    wolfSSL_sk_free(sk);
5231
}
5232
5233
#ifdef HAVE_CRL
5234
WOLFSSL_STACK* wolfSSL_sk_X509_CRL_new(void)
5235
{
5236
    WOLFSSL_STACK* s = wolfSSL_sk_new_node(NULL);
5237
    if (s != NULL)
5238
        s->type = STACK_TYPE_X509_CRL;
5239
    return s;
5240
}
5241
5242
WOLFSSL_STACK* wolfSSL_sk_X509_CRL_new_null(void)
5243
{
5244
    WOLFSSL_STACK* s = wolfSSL_sk_new_null();
5245
    if (s != NULL)
5246
        s->type = STACK_TYPE_X509_CRL;
5247
    return s;
5248
}
5249
5250
void wolfSSL_sk_X509_CRL_pop_free(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk,
5251
    void (*f) (WOLFSSL_X509_CRL*))
5252
{
5253
    WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_pop_free");
5254
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
5255
}
5256
5257
void wolfSSL_sk_X509_CRL_free(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk)
5258
{
5259
    wolfSSL_sk_X509_CRL_pop_free(sk, NULL);
5260
}
5261
5262
/* return number of elements on success 0 on fail */
5263
int wolfSSL_sk_X509_CRL_push(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk,
5264
    WOLFSSL_X509_CRL* crl)
5265
{
5266
    WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_push");
5267
5268
    if (sk == NULL || crl == NULL) {
5269
        return WOLFSSL_FAILURE;
5270
    }
5271
5272
    return wolfSSL_sk_push(sk, crl);
5273
}
5274
5275
WOLFSSL_X509_CRL* wolfSSL_sk_X509_CRL_value(WOLF_STACK_OF(WOLFSSL_X509)* sk,
5276
                                            int i)
5277
{
5278
    WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_value");
5279
    if (sk)
5280
        return (WOLFSSL_X509_CRL*)wolfSSL_sk_value(sk, i);
5281
    return NULL;
5282
}
5283
5284
int wolfSSL_sk_X509_CRL_num(WOLF_STACK_OF(WOLFSSL_X509)* sk)
5285
{
5286
    WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_num");
5287
    if (sk)
5288
        return wolfSSL_sk_num(sk);
5289
    return 0;
5290
}
5291
#endif /* HAVE_CRL */
5292
5293
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
5294
5295
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_QT)
5296
/* return number of elements on success 0 on fail */
5297
int wolfSSL_sk_ACCESS_DESCRIPTION_push(WOLF_STACK_OF(ACCESS_DESCRIPTION)* sk,
5298
                                              WOLFSSL_ACCESS_DESCRIPTION* a)
5299
{
5300
    WOLFSSL_ENTER("wolfSSL_sk_ACCESS_DESCRIPTION_push");
5301
5302
    return wolfSSL_sk_push(sk, a);
5303
}
5304
5305
/* Frees all nodes in ACCESS_DESCRIPTION stack
5306
*
5307
* sk stack of nodes to free
5308
* f  free function to use
5309
*/
5310
void wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(WOLFSSL_STACK* sk,
5311
    void (*f) (WOLFSSL_ACCESS_DESCRIPTION*))
5312
{
5313
   WOLFSSL_ENTER("wolfSSL_sk_ACCESS_DESCRIPTION_pop_free");
5314
   wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
5315
}
5316
5317
void wolfSSL_sk_ACCESS_DESCRIPTION_free(WOLFSSL_STACK* sk)
5318
{
5319
    wolfSSL_sk_free(sk);
5320
}
5321
5322
5323
/* AUTHORITY_INFO_ACCESS object is a stack of ACCESS_DESCRIPTION objects,
5324
 * to free the stack the WOLFSSL_ACCESS_DESCRIPTION stack free function is
5325
 * used */
5326
void wolfSSL_AUTHORITY_INFO_ACCESS_free(
5327
        WOLF_STACK_OF(WOLFSSL_ACCESS_DESCRIPTION)* sk)
5328
{
5329
    WOLFSSL_ENTER("wolfSSL_AUTHORITY_INFO_ACCESS_free");
5330
    wolfSSL_sk_ACCESS_DESCRIPTION_free(sk);
5331
}
5332
5333
void wolfSSL_AUTHORITY_INFO_ACCESS_pop_free(
5334
        WOLF_STACK_OF(WOLFSSL_ACCESS_DESCRIPTION)* sk,
5335
        void (*f) (WOLFSSL_ACCESS_DESCRIPTION*))
5336
{
5337
    WOLFSSL_ENTER("wolfSSL_AUTHORITY_INFO_ACCESS_free");
5338
    wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(sk, f);
5339
}
5340
5341
5342
void wolfSSL_ACCESS_DESCRIPTION_free(WOLFSSL_ACCESS_DESCRIPTION* a)
5343
{
5344
    WOLFSSL_ENTER("wolfSSL_ACCESS_DESCRIPTION_free");
5345
    if (a == NULL)
5346
        return;
5347
5348
    if (a->method)
5349
        wolfSSL_ASN1_OBJECT_free(a->method);
5350
    if (a->location)
5351
        wolfSSL_GENERAL_NAME_free(a->location);
5352
    XFREE(a, NULL, DYNAMIC_TYPE_X509_EXT);
5353
5354
    /* a = NULL, don't try to a or double free it */
5355
}
5356
#endif /* OPENSSL_EXTRA || WOLFSSL_QT */
5357
5358
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
5359
5360
/* Creates and returns new GENERAL_NAME structure */
5361
WOLFSSL_GENERAL_NAME* wolfSSL_GENERAL_NAME_new(void)
5362
{
5363
    WOLFSSL_GENERAL_NAME* gn;
5364
    WOLFSSL_ENTER("GENERAL_NAME_new");
5365
5366
    gn = (WOLFSSL_GENERAL_NAME*)XMALLOC(sizeof(WOLFSSL_GENERAL_NAME), NULL,
5367
                                                             DYNAMIC_TYPE_ASN1);
5368
    if (gn == NULL) {
5369
        return NULL;
5370
    }
5371
    XMEMSET(gn, 0, sizeof(WOLFSSL_GENERAL_NAME));
5372
5373
    gn->d.ia5 = wolfSSL_ASN1_STRING_new();
5374
    if (gn->d.ia5 == NULL) {
5375
        WOLFSSL_MSG("Issue creating ASN1_STRING struct");
5376
        wolfSSL_GENERAL_NAME_free(gn);
5377
        return NULL;
5378
    }
5379
    gn->type = WOLFSSL_GEN_IA5;
5380
    return gn;
5381
}
5382
5383
WOLFSSL_GENERAL_NAME* wolfSSL_GENERAL_NAME_dup(WOLFSSL_GENERAL_NAME* gn)
5384
{
5385
    WOLFSSL_GENERAL_NAME* dupl = NULL;
5386
5387
    WOLFSSL_ENTER("wolfSSL_GENERAL_NAME_dup");
5388
5389
    if (!gn) {
5390
        WOLFSSL_MSG("Bad parameter");
5391
        return NULL;
5392
    }
5393
5394
    if (!(dupl = wolfSSL_GENERAL_NAME_new())) {
5395
        WOLFSSL_MSG("wolfSSL_GENERAL_NAME_new error");
5396
        return NULL;
5397
    }
5398
5399
    wolfSSL_ASN1_STRING_free(dupl->d.ia5);
5400
    dupl->d.ia5 = NULL;
5401
    switch (gn->type) {
5402
    /* WOLFSSL_ASN1_STRING types */
5403
    case WOLFSSL_GEN_DNS:
5404
        if (!(dupl->d.dNSName = wolfSSL_ASN1_STRING_dup(gn->d.dNSName))) {
5405
            WOLFSSL_MSG("wolfSSL_ASN1_STRING_dup error");
5406
            goto error;
5407
        }
5408
        break;
5409
    case WOLFSSL_GEN_IPADD:
5410
        if (!(dupl->d.iPAddress = wolfSSL_ASN1_STRING_dup(gn->d.iPAddress))) {
5411
            WOLFSSL_MSG("wolfSSL_ASN1_STRING_dup error");
5412
            goto error;
5413
        }
5414
        break;
5415
    case WOLFSSL_GEN_EMAIL:
5416
        if (!(dupl->d.rfc822Name = wolfSSL_ASN1_STRING_dup(gn->d.rfc822Name))) {
5417
            WOLFSSL_MSG("wolfSSL_ASN1_STRING_dup error");
5418
            goto error;
5419
        }
5420
        break;
5421
    case WOLFSSL_GEN_URI:
5422
        if (!(dupl->d.uniformResourceIdentifier =
5423
                wolfSSL_ASN1_STRING_dup(gn->d.uniformResourceIdentifier))) {
5424
            WOLFSSL_MSG("wolfSSL_ASN1_STRING_dup error");
5425
            goto error;
5426
        }
5427
        break;
5428
    case WOLFSSL_GEN_OTHERNAME:
5429
        if (gn->d.otherName->value->type != WOLFSSL_V_ASN1_UTF8STRING) {
5430
            WOLFSSL_MSG("Unsupported othername value type");
5431
            goto error;
5432
        }
5433
        dupl->d.otherName = (WOLFSSL_ASN1_OTHERNAME*)XMALLOC(
5434
            sizeof(WOLFSSL_ASN1_OTHERNAME), NULL, DYNAMIC_TYPE_ASN1);
5435
        if (dupl->d.otherName == NULL) {
5436
            WOLFSSL_MSG("XMALLOC error");
5437
            goto error;
5438
        }
5439
        dupl->d.otherName->type_id = wolfSSL_ASN1_OBJECT_dup(
5440
            gn->d.otherName->type_id);
5441
        dupl->d.otherName->value = (WOLFSSL_ASN1_TYPE*)XMALLOC(
5442
            sizeof(WOLFSSL_ASN1_TYPE), NULL, DYNAMIC_TYPE_ASN1);
5443
        if (dupl->d.otherName->value != NULL) {
5444
            dupl->d.otherName->value->type = gn->d.otherName->value->type;
5445
            dupl->d.otherName->value->value.utf8string =
5446
                wolfSSL_ASN1_STRING_dup(
5447
                                      gn->d.otherName->value->value.utf8string);
5448
        }
5449
        if ((dupl->d.otherName->type_id == NULL) ||
5450
            (dupl->d.otherName->value == NULL) ||
5451
            (dupl->d.otherName->value->value.utf8string == NULL)) {
5452
            wolfSSL_ASN1_OBJECT_free(dupl->d.otherName->type_id);
5453
            wolfSSL_ASN1_TYPE_free(dupl->d.otherName->value);
5454
            XFREE(dupl->d.otherName, NULL, DYNAMIC_TYPE_ASN1);
5455
            dupl->d.otherName = NULL;
5456
            WOLFSSL_MSG("error duping othername");
5457
            goto error;
5458
        }
5459
        break;
5460
    case WOLFSSL_GEN_X400:
5461
    case WOLFSSL_GEN_DIRNAME:
5462
    case WOLFSSL_GEN_EDIPARTY:
5463
    case WOLFSSL_GEN_RID:
5464
    default:
5465
        WOLFSSL_MSG("Unrecognized or unsupported GENERAL_NAME type");
5466
        goto error;
5467
    }
5468
    dupl->type = gn->type;
5469
5470
    return dupl;
5471
error:
5472
    wolfSSL_GENERAL_NAME_free(dupl);
5473
    return NULL;
5474
}
5475
5476
/* Set an Othername in a general name.
5477
 *
5478
 * @param [out] gen     Pointer to the GENERAL_NAME where the othername is set.
5479
 * @param [in]  oid     Object ID (ie UPN).
5480
 * @param [in]  name    The actual name.
5481
 * @return  WOLFSSL_FAILURE on invalid parameter or memory error,
5482
 *          WOLFSSL_SUCCESS otherwise.
5483
 */
5484
int wolfSSL_GENERAL_NAME_set0_othername(WOLFSSL_GENERAL_NAME* gen,
5485
                                        WOLFSSL_ASN1_OBJECT* oid,
5486
                                        WOLFSSL_ASN1_TYPE* value)
5487
{
5488
    WOLFSSL_ASN1_OBJECT *x = NULL;
5489
5490
    if ((gen == NULL) || (oid == NULL) || (value == NULL)) {
5491
        return WOLFSSL_FAILURE;
5492
    }
5493
5494
    x = wolfSSL_ASN1_OBJECT_dup(oid);
5495
    if (x == NULL) {
5496
        WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_dup() failed");
5497
        return WOLFSSL_FAILURE;
5498
    }
5499
5500
    if (wolfSSL_GENERAL_NAME_set_type(gen, WOLFSSL_GEN_OTHERNAME)
5501
            != WOLFSSL_SUCCESS) {
5502
        wolfSSL_ASN1_OBJECT_free(x);
5503
        return WOLFSSL_FAILURE;
5504
    }
5505
5506
    gen->d.otherName->type_id = x;
5507
    gen->d.otherName->value = value;
5508
    return WOLFSSL_SUCCESS;
5509
}
5510
5511
/* return number of elements on success 0 on fail */
5512
int wolfSSL_sk_GENERAL_NAME_push(WOLFSSL_GENERAL_NAMES* sk,
5513
                                 WOLFSSL_GENERAL_NAME* gn)
5514
{
5515
    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_push");
5516
5517
    return wolfSSL_sk_push(sk, gn);
5518
}
5519
5520
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
5521
5522
#ifdef OPENSSL_EXTRA
5523
5524
/* Returns the general name at index i from the stack
5525
 *
5526
 * sk  stack to get general name from
5527
 * idx index to get
5528
 *
5529
 * return a pointer to the internal node of the stack
5530
 */
5531
WOLFSSL_GENERAL_NAME* wolfSSL_sk_GENERAL_NAME_value(WOLFSSL_STACK* sk, int idx)
5532
{
5533
    return (WOLFSSL_GENERAL_NAME*)wolfSSL_sk_value(sk, idx);
5534
}
5535
5536
/* Gets the number of nodes in the stack
5537
 *
5538
 * sk  stack to get the number of nodes from
5539
 *
5540
 * returns the number of nodes, -1 if no nodes
5541
 */
5542
int wolfSSL_sk_GENERAL_NAME_num(WOLFSSL_STACK* sk)
5543
{
5544
    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_num");
5545
5546
    return wolfSSL_sk_num(sk);
5547
}
5548
5549
/* Allocates an empty GENERAL NAME stack */
5550
WOLFSSL_STACK* wolfSSL_sk_GENERAL_NAME_new(void *cmpFunc) {
5551
    WOLFSSL_STACK* sk = NULL;
5552
    (void)cmpFunc;
5553
    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_new");
5554
5555
    sk = wolfSSL_sk_new_null();
5556
    if (sk != NULL) {
5557
        sk->type = STACK_TYPE_GEN_NAME;
5558
    }
5559
5560
    return sk;
5561
}
5562
#endif /* OPENSSL_EXTRA */
5563
5564
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
5565
5566
/* Frees all nodes in a GENERAL NAME stack
5567
 *
5568
 * sk stack of nodes to free
5569
 * f  free function to use, not called with wolfSSL
5570
 */
5571
void wolfSSL_sk_GENERAL_NAME_pop_free(WOLFSSL_STACK* sk,
5572
        void (*f) (WOLFSSL_GENERAL_NAME*))
5573
{
5574
    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_pop_free");
5575
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
5576
}
5577
5578
void wolfSSL_sk_GENERAL_NAME_free(WOLFSSL_STACK* sk)
5579
{
5580
    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_free");
5581
    wolfSSL_sk_X509_pop_free(sk, NULL);
5582
}
5583
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
5584
5585
#ifdef OPENSSL_EXTRA
5586
static void wolfSSL_DIST_POINT_NAME_free(WOLFSSL_DIST_POINT_NAME* dpn)
5587
{
5588
    if (dpn != NULL) {
5589
        if (dpn->name.fullname != NULL) {
5590
            wolfSSL_sk_X509_pop_free(dpn->name.fullname, NULL);
5591
        }
5592
        XFREE(dpn, NULL, DYNAMIC_TYPE_OPENSSL);
5593
    }
5594
}
5595
5596
5597
/* returns new pointer on success and NULL on fail */
5598
static WOLFSSL_DIST_POINT_NAME* wolfSSL_DIST_POINT_NAME_new(void)
5599
{
5600
    WOLFSSL_DIST_POINT_NAME* dpn = NULL;
5601
    WOLFSSL_GENERAL_NAMES* gns = NULL;
5602
5603
    dpn = (WOLFSSL_DIST_POINT_NAME*)XMALLOC(sizeof(WOLFSSL_DIST_POINT_NAME),
5604
                                            NULL, DYNAMIC_TYPE_OPENSSL);
5605
    if (dpn == NULL) {
5606
        return NULL;
5607
    }
5608
    XMEMSET(dpn, 0, sizeof(WOLFSSL_DIST_POINT_NAME));
5609
5610
    gns = wolfSSL_sk_new_null();
5611
    if (gns == NULL) {
5612
        WOLFSSL_MSG("wolfSSL_sk_new_null error");
5613
        XFREE(dpn, NULL, DYNAMIC_TYPE_OPENSSL);
5614
        return NULL;
5615
    }
5616
    gns->type = STACK_TYPE_GEN_NAME;
5617
5618
    /* DIST_POINT_NAME type may be 0 or 1, indicating whether fullname or
5619
     * relativename is used. See: RFC 5280 section 4.2.1.13 */
5620
    dpn->name.fullname = gns;
5621
    dpn->type = 0;
5622
5623
    return dpn;
5624
}
5625
5626
5627
/* Creates and returns new DIST_POINT structure */
5628
WOLFSSL_DIST_POINT* wolfSSL_DIST_POINT_new(void)
5629
{
5630
    WOLFSSL_DIST_POINT* dp = NULL;
5631
    WOLFSSL_DIST_POINT_NAME* dpn = NULL;
5632
5633
    WOLFSSL_ENTER("wolfSSL_DIST_POINT_new");
5634
5635
    dp = (WOLFSSL_DIST_POINT*)XMALLOC(sizeof(WOLFSSL_DIST_POINT), NULL,
5636
                                      DYNAMIC_TYPE_OPENSSL);
5637
    if (dp == NULL) {
5638
        return NULL;
5639
    }
5640
    XMEMSET(dp, 0, sizeof(WOLFSSL_DIST_POINT));
5641
5642
    dpn = wolfSSL_DIST_POINT_NAME_new();
5643
    if (dpn == NULL) {
5644
        XFREE(dp, NULL, DYNAMIC_TYPE_OPENSSL);
5645
        return NULL;
5646
    }
5647
    dp->distpoint = dpn;
5648
5649
    return dp;
5650
}
5651
5652
5653
/* Frees DIST_POINT objects.
5654
*/
5655
void wolfSSL_DIST_POINT_free(WOLFSSL_DIST_POINT* dp)
5656
{
5657
    WOLFSSL_ENTER("wolfSSL_DIST_POINT_free");
5658
    if (dp != NULL) {
5659
        wolfSSL_DIST_POINT_NAME_free(dp->distpoint);
5660
        XFREE(dp, NULL, DYNAMIC_TYPE_OPENSSL);
5661
    }
5662
}
5663
5664
void wolfSSL_DIST_POINTS_free(WOLFSSL_DIST_POINTS *dps)
5665
{
5666
    WOLFSSL_ENTER("wolfSSL_DIST_POINTS_free");
5667
5668
    if (dps == NULL) {
5669
        return;
5670
    }
5671
5672
    wolfSSL_sk_free(dps);
5673
}
5674
5675
/* return number of elements on success 0 on fail */
5676
int wolfSSL_sk_DIST_POINT_push(WOLFSSL_DIST_POINTS* sk, WOLFSSL_DIST_POINT* dp)
5677
{
5678
    WOLFSSL_ENTER("wolfSSL_sk_DIST_POINT_push");
5679
5680
    if (sk == NULL || dp == NULL) {
5681
        return WOLFSSL_FAILURE;
5682
    }
5683
5684
    return wolfSSL_sk_push(sk, dp);
5685
}
5686
5687
/* Returns the CRL dist point at index i from the stack
5688
 *
5689
 * sk  stack to get general name from
5690
 * idx index to get
5691
 *
5692
 * return a pointer to the internal node of the stack
5693
 */
5694
WOLFSSL_DIST_POINT* wolfSSL_sk_DIST_POINT_value(WOLFSSL_STACK* sk, int idx)
5695
{
5696
    if (sk == NULL) {
5697
        return NULL;
5698
    }
5699
5700
    return (WOLFSSL_DIST_POINT*)wolfSSL_sk_value(sk, idx);
5701
}
5702
5703
/* Gets the number of nodes in the stack
5704
 *
5705
 * sk  stack to get the number of nodes from
5706
 *
5707
 * returns the number of nodes, -1 if no nodes
5708
 */
5709
int wolfSSL_sk_DIST_POINT_num(WOLFSSL_STACK* sk)
5710
{
5711
    WOLFSSL_ENTER("wolfSSL_sk_DIST_POINT_num");
5712
5713
    if (sk == NULL) {
5714
        return WOLFSSL_FATAL_ERROR;
5715
    }
5716
5717
    return wolfSSL_sk_num(sk);
5718
}
5719
5720
/* Frees all nodes in a DIST_POINT stack
5721
 *
5722
 * sk stack of nodes to free
5723
 * f  free function to use
5724
 */
5725
void wolfSSL_sk_DIST_POINT_pop_free(WOLFSSL_STACK* sk,
5726
        void (*f) (WOLFSSL_DIST_POINT*))
5727
{
5728
    WOLFSSL_ENTER("wolfSSL_sk_DIST_POINT_pop_free");
5729
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
5730
}
5731
5732
void wolfSSL_sk_DIST_POINT_free(WOLFSSL_STACK* sk)
5733
{
5734
    WOLFSSL_ENTER("wolfSSL_sk_DIST_POINT_free");
5735
    wolfSSL_sk_free(sk);
5736
}
5737
5738
/* returns the number of nodes in stack on success and WOLFSSL_FATAL_ERROR
5739
 * on fail */
5740
int wolfSSL_sk_ACCESS_DESCRIPTION_num(WOLFSSL_STACK* sk)
5741
{
5742
    if (sk == NULL) {
5743
        return WOLFSSL_FATAL_ERROR;
5744
    }
5745
5746
    return (int)sk->num;
5747
}
5748
5749
/* returns NULL on fail and pointer to internal data on success */
5750
WOLFSSL_ACCESS_DESCRIPTION* wolfSSL_sk_ACCESS_DESCRIPTION_value(
5751
        WOLFSSL_STACK* sk, int idx)
5752
{
5753
    WOLFSSL_STACK* ret;
5754
5755
    if (sk == NULL) {
5756
        return NULL;
5757
    }
5758
5759
    ret = wolfSSL_sk_get_node(sk, idx);
5760
    if (ret != NULL) {
5761
        return ret->data.access;
5762
    }
5763
    return NULL;
5764
}
5765
#endif /* OPENSSL_EXTRA */
5766
5767
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
5768
/* free's the internal type for the general name */
5769
static void wolfSSL_GENERAL_NAME_type_free(WOLFSSL_GENERAL_NAME* name)
5770
{
5771
    if (name != NULL) {
5772
        switch (name->type) {
5773
        case WOLFSSL_GEN_IA5:
5774
            wolfSSL_ASN1_STRING_free(name->d.ia5);
5775
            name->d.ia5 = NULL;
5776
            break;
5777
        case WOLFSSL_GEN_EMAIL:
5778
            wolfSSL_ASN1_STRING_free(name->d.rfc822Name);
5779
            name->d.rfc822Name = NULL;
5780
            break;
5781
        case WOLFSSL_GEN_DNS:
5782
            wolfSSL_ASN1_STRING_free(name->d.dNSName);
5783
            name->d.dNSName = NULL;
5784
            break;
5785
        case WOLFSSL_GEN_DIRNAME:
5786
            wolfSSL_X509_NAME_free(name->d.dirn);
5787
            name->d.dirn = NULL;
5788
            break;
5789
        case WOLFSSL_GEN_URI:
5790
            wolfSSL_ASN1_STRING_free(name->d.uniformResourceIdentifier);
5791
            name->d.uniformResourceIdentifier = NULL;
5792
            break;
5793
        case WOLFSSL_GEN_IPADD:
5794
            wolfSSL_ASN1_STRING_free(name->d.iPAddress);
5795
            name->d.iPAddress = NULL;
5796
            break;
5797
        case WOLFSSL_GEN_RID:
5798
            wolfSSL_ASN1_OBJECT_free(name->d.registeredID);
5799
            name->d.registeredID = NULL;
5800
            break;
5801
        case WOLFSSL_GEN_OTHERNAME:
5802
            if (name->d.otherName != NULL) {
5803
                wolfSSL_ASN1_OBJECT_free(name->d.otherName->type_id);
5804
                wolfSSL_ASN1_TYPE_free(name->d.otherName->value);
5805
                XFREE(name->d.otherName, NULL, DYNAMIC_TYPE_ASN1);
5806
                name->d.otherName = NULL;
5807
            }
5808
            break;
5809
        case WOLFSSL_GEN_X400:
5810
            /* Unsupported: fall through */
5811
        case WOLFSSL_GEN_EDIPARTY:
5812
            /* Unsupported: fall through */
5813
        default:
5814
            WOLFSSL_MSG("wolfSSL_GENERAL_NAME_type_free: possible leak");
5815
            break;
5816
        }
5817
    }
5818
}
5819
5820
/* sets the general name type and free's the existing one
5821
 * can fail with a memory error if malloc fails or bad arg error
5822
 * otherwise return WOLFSSL_SUCCESS */
5823
int wolfSSL_GENERAL_NAME_set_type(WOLFSSL_GENERAL_NAME* name, int typ)
5824
{
5825
    int ret = WOLFSSL_SUCCESS;
5826
5827
    if (name != NULL) {
5828
        wolfSSL_GENERAL_NAME_type_free(name);
5829
        name->type = typ;
5830
5831
        switch (typ) {
5832
            case WOLFSSL_GEN_URI:
5833
                name->d.uniformResourceIdentifier = wolfSSL_ASN1_STRING_new();
5834
                if (name->d.uniformResourceIdentifier == NULL)
5835
                    ret = MEMORY_E;
5836
                break;
5837
            case WOLFSSL_GEN_OTHERNAME:
5838
                name->d.otherName = (WOLFSSL_ASN1_OTHERNAME*)XMALLOC(
5839
                    sizeof(WOLFSSL_ASN1_OTHERNAME), NULL, DYNAMIC_TYPE_ASN1);
5840
                if (name->d.otherName == NULL) {
5841
                    ret = MEMORY_E;
5842
                }
5843
                else {
5844
                    XMEMSET(name->d.otherName, 0, sizeof(WOLFSSL_ASN1_OTHERNAME));
5845
                }
5846
                break;
5847
            default:
5848
                name->type = WOLFSSL_GEN_IA5;
5849
                name->d.ia5 = wolfSSL_ASN1_STRING_new();
5850
                if (name->d.ia5 == NULL)
5851
                    ret = MEMORY_E;
5852
        }
5853
    }
5854
    else {
5855
        ret = BAD_FUNC_ARG;
5856
    }
5857
5858
    return ret;
5859
}
5860
5861
/* Set the value in a general name. This is a compat layer API.
5862
 *
5863
 * @param [out] a       Pointer to the GENERAL_NAME where the othername is set.
5864
 * @param [in]  type    The type of this general name.
5865
 * @param [in]  value   The ASN.1 string that is the value.
5866
 * @return none
5867
 * @note the set0 indicates we take ownership so the user does NOT free value.
5868
 */
5869
void wolfSSL_GENERAL_NAME_set0_value(WOLFSSL_GENERAL_NAME *a, int type,
5870
                                     void *value)
5871
{
5872
    WOLFSSL_ASN1_STRING *val = (WOLFSSL_ASN1_STRING *)value;
5873
    if (a == NULL) {
5874
        WOLFSSL_MSG("a is NULL");
5875
        return;
5876
    }
5877
5878
    if (val == NULL) {
5879
        WOLFSSL_MSG("value is NULL");
5880
        return;
5881
    }
5882
5883
    if (type != WOLFSSL_GEN_DNS) {
5884
        WOLFSSL_MSG("Only WOLFSSL_GEN_DNS is supported");
5885
        return;
5886
    }
5887
5888
    wolfSSL_GENERAL_NAME_type_free(a);
5889
    a->type = type;
5890
    /* Only when WOLFSSL_GEN_DNS. */
5891
    a->d.dNSName = val;
5892
}
5893
5894
/* Frees GENERAL_NAME objects.
5895
*/
5896
void wolfSSL_GENERAL_NAME_free(WOLFSSL_GENERAL_NAME* name)
5897
{
5898
    WOLFSSL_ENTER("wolfSSL_GENERAL_NAME_Free");
5899
    if (name != NULL) {
5900
        wolfSSL_GENERAL_NAME_type_free(name);
5901
        XFREE(name, NULL, DYNAMIC_TYPE_OPENSSL);
5902
    }
5903
}
5904
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL*/
5905
5906
#ifdef OPENSSL_EXTRA
5907
void wolfSSL_GENERAL_NAMES_free(WOLFSSL_GENERAL_NAMES *gens)
5908
{
5909
    WOLFSSL_ENTER("wolfSSL_GENERAL_NAMES_free");
5910
5911
    if (gens == NULL) {
5912
        return;
5913
    }
5914
5915
    wolfSSL_sk_GENERAL_NAME_free(gens);
5916
}
5917
5918
void wolfSSL_EXTENDED_KEY_USAGE_free(WOLFSSL_STACK * sk)
5919
{
5920
    WOLFSSL_ENTER("wolfSSL_EXTENDED_KEY_USAGE_free");
5921
5922
    if (sk == NULL) {
5923
        return;
5924
    }
5925
5926
    wolfSSL_sk_X509_pop_free(sk, NULL);
5927
}
5928
5929
#if !defined(IGNORE_NAME_CONSTRAINTS)
5930
/*
5931
 * Allocate and initialize an empty GENERAL_SUBTREE structure.
5932
 * Returns NULL on allocation failure.
5933
 */
5934
WOLFSSL_GENERAL_SUBTREE* wolfSSL_GENERAL_SUBTREE_new(void)
5935
{
5936
    WOLFSSL_GENERAL_SUBTREE* subtree;
5937
5938
    WOLFSSL_ENTER("wolfSSL_GENERAL_SUBTREE_new");
5939
5940
    subtree = (WOLFSSL_GENERAL_SUBTREE*)XMALLOC(sizeof(WOLFSSL_GENERAL_SUBTREE),
5941
                                                NULL, DYNAMIC_TYPE_OPENSSL);
5942
    if (subtree == NULL) {
5943
        WOLFSSL_MSG("Failed to allocate GENERAL_SUBTREE");
5944
        return NULL;
5945
    }
5946
    XMEMSET(subtree, 0, sizeof(WOLFSSL_GENERAL_SUBTREE));
5947
    return subtree;
5948
}
5949
5950
/*
5951
 * Create an empty NAME_CONSTRAINTS structure.
5952
 * Returns NULL on allocation failure.
5953
 */
5954
WOLFSSL_NAME_CONSTRAINTS* wolfSSL_NAME_CONSTRAINTS_new(void)
5955
{
5956
    WOLFSSL_NAME_CONSTRAINTS* nc;
5957
5958
    WOLFSSL_ENTER("wolfSSL_NAME_CONSTRAINTS_new");
5959
5960
    nc = (WOLFSSL_NAME_CONSTRAINTS*)XMALLOC(sizeof(WOLFSSL_NAME_CONSTRAINTS),
5961
                                            NULL, DYNAMIC_TYPE_OPENSSL);
5962
    if (nc == NULL) {
5963
        WOLFSSL_MSG("Failed to allocate NAME_CONSTRAINTS");
5964
        return NULL;
5965
    }
5966
    XMEMSET(nc, 0, sizeof(WOLFSSL_NAME_CONSTRAINTS));
5967
    return nc;
5968
}
5969
5970
/* Free a GENERAL_SUBTREE and its contents. */
5971
void wolfSSL_GENERAL_SUBTREE_free(WOLFSSL_GENERAL_SUBTREE* subtree)
5972
{
5973
    if (subtree == NULL) {
5974
        return;
5975
    }
5976
    wolfSSL_GENERAL_NAME_free(subtree->base);
5977
    XFREE(subtree, NULL, DYNAMIC_TYPE_OPENSSL);
5978
}
5979
5980
/* Free a NAME_CONSTRAINTS structure and all its contents. */
5981
void wolfSSL_NAME_CONSTRAINTS_free(WOLFSSL_NAME_CONSTRAINTS* nc)
5982
{
5983
    WOLFSSL_ENTER("wolfSSL_NAME_CONSTRAINTS_free");
5984
5985
    if (nc == NULL) {
5986
        return;
5987
    }
5988
5989
    if (nc->permittedSubtrees != NULL) {
5990
        wolfSSL_sk_pop_free(nc->permittedSubtrees,
5991
            (wolfSSL_sk_freefunc)wolfSSL_GENERAL_SUBTREE_free);
5992
    }
5993
5994
    if (nc->excludedSubtrees != NULL) {
5995
        wolfSSL_sk_pop_free(nc->excludedSubtrees,
5996
            (wolfSSL_sk_freefunc)wolfSSL_GENERAL_SUBTREE_free);
5997
    }
5998
5999
    XFREE(nc, NULL, DYNAMIC_TYPE_OPENSSL);
6000
}
6001
6002
/* Get number of items in GENERAL_SUBTREE stack. */
6003
int wolfSSL_sk_GENERAL_SUBTREE_num(const WOLFSSL_STACK* sk)
6004
{
6005
    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_SUBTREE_num");
6006
6007
    return wolfSSL_sk_num(sk);
6008
}
6009
6010
/* Get GENERAL_SUBTREE at index from stack. */
6011
WOLFSSL_GENERAL_SUBTREE* wolfSSL_sk_GENERAL_SUBTREE_value(
6012
    const WOLFSSL_STACK* sk, int idx)
6013
{
6014
    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_SUBTREE_value");
6015
6016
    return (WOLFSSL_GENERAL_SUBTREE*)wolfSSL_sk_value(sk, idx);
6017
}
6018
6019
/* Check IP address string matches constraint.
6020
 *
6021
 * name: IP address string (ex "192.168.1.50")
6022
 * nameSz: length of name string
6023
 * gn: GENERAL_NAME containing IP constraint (IP + mask bytes)
6024
 *
6025
 * Return 1 on match, otherwise 0
6026
 */
6027
static int MatchIpName(const char* name, int nameSz, WOLFSSL_GENERAL_NAME* gn)
6028
{
6029
    int ipLen = 0;
6030
    int constraintLen;
6031
    char ipStr[WOLFSSL_MAX_IPSTR];
6032
    unsigned char ipBytes[16]; /* Max 16 bytes for IPv6 */
6033
    const unsigned char* constraintData;
6034
6035
    if (name == NULL || nameSz <= 0 || gn == NULL || gn->d.iPAddress == NULL) {
6036
        return 0;
6037
    }
6038
6039
    constraintData = wolfSSL_ASN1_STRING_get0_data(gn->d.iPAddress);
6040
    constraintLen = wolfSSL_ASN1_STRING_length(gn->d.iPAddress);
6041
    if (constraintData == NULL || constraintLen <= 0) {
6042
        return 0;
6043
    }
6044
6045
    /* Null-terminate IP string */
6046
    if (nameSz >= (int)sizeof(ipStr)) {
6047
        return 0;
6048
    }
6049
    XMEMCPY(ipStr, name, nameSz);
6050
    ipStr[nameSz] = '\0';
6051
6052
    /* IPv4 constraint 8 bytes (IP + mask),
6053
     * IPv6 constraint 32 bytes (IP + mask) */
6054
    if (constraintLen == 8) {
6055
    #ifdef FREESCALE_MQX
6056
        if (XINET_PTON(WOLFSSL_IP4, ipStr, ipBytes, sizeof(ipBytes)) == RTCS_OK) {
6057
    #else
6058
        if (XINET_PTON(WOLFSSL_IP4, ipStr, ipBytes) == 1) {
6059
    #endif
6060
            ipLen = 4;
6061
        }
6062
    }
6063
    else if (constraintLen == 32) {
6064
    #ifdef FREESCALE_MQX
6065
        if (XINET_PTON(WOLFSSL_IP6, ipStr, ipBytes, sizeof(ipBytes)) == RTCS_OK) {
6066
    #else
6067
        if (XINET_PTON(WOLFSSL_IP6, ipStr, ipBytes) == 1) {
6068
    #endif
6069
            ipLen = 16;
6070
        }
6071
    }
6072
6073
    if (ipLen == 0) {
6074
        return 0;
6075
    }
6076
6077
    return wolfssl_local_MatchIpSubnet(ipBytes, ipLen,
6078
        constraintData, constraintLen);
6079
}
6080
6081
/* Helper to check if name string matches a single GENERAL_NAME constraint.
6082
 * permitted selects subtree semantics for wildcard DNS names: containment
6083
 * for permitted subtrees, intersection for excluded subtrees.
6084
 * Returns 1 if matches, 0 if not. */
6085
static int MatchNameConstraint(int type, const char* name, int nameSz,
6086
    WOLFSSL_GENERAL_NAME* gn, int permitted)
6087
{
6088
    const char* baseStr;
6089
    int baseLen;
6090
6091
    if (gn == NULL || gn->type != type) {
6092
        return 0;
6093
    }
6094
6095
    switch (type) {
6096
        case WOLFSSL_GEN_IPADD:
6097
            return MatchIpName(name, nameSz, gn);
6098
6099
        case WOLFSSL_GEN_DNS:
6100
        case WOLFSSL_GEN_EMAIL:
6101
        case WOLFSSL_GEN_URI:
6102
            if (gn->d.ia5 == NULL) {
6103
                return 0;
6104
            }
6105
            baseStr = (const char*)wolfSSL_ASN1_STRING_get0_data(gn->d.ia5);
6106
            baseLen = wolfSSL_ASN1_STRING_length(gn->d.ia5);
6107
            if (baseStr == NULL || baseLen <= 0) {
6108
                return 0;
6109
            }
6110
6111
            if (type == WOLFSSL_GEN_EMAIL) {
6112
                return wolfssl_local_MatchBaseName(ASN_RFC822_TYPE, name,
6113
                    nameSz, baseStr, baseLen);
6114
            }
6115
            else if (type == WOLFSSL_GEN_URI) {
6116
                return wolfssl_local_MatchUriNameConstraint(name, nameSz,
6117
                    baseStr, baseLen);
6118
            }
6119
            else {
6120
                /* WOLFSSL_GEN_DNS uses DNS-style matching */
6121
                return wolfssl_local_MatchDnsNameConstraint(name, nameSz,
6122
                    baseStr, baseLen, permitted);
6123
            }
6124
6125
        default:
6126
            /* Unsupported type */
6127
            return 0;
6128
    }
6129
}
6130
6131
static int NameConstraintsHasType(const WOLFSSL_STACK* sk, int type)
6132
{
6133
    int i;
6134
    int num;
6135
6136
    if (sk == NULL) {
6137
        return 0;
6138
    }
6139
6140
    num = wolfSSL_sk_GENERAL_SUBTREE_num(sk);
6141
    for (i = 0; i < num; i++) {
6142
        WOLFSSL_GENERAL_SUBTREE* subtree;
6143
6144
        subtree = wolfSSL_sk_GENERAL_SUBTREE_value(sk, i);
6145
        if (subtree != NULL && subtree->base != NULL &&
6146
                subtree->base->type == type) {
6147
            return 1;
6148
        }
6149
    }
6150
6151
    return 0;
6152
}
6153
6154
/*
6155
 * Check if a name string satisfies given name constraints.
6156
 *
6157
 * nc: NAME_CONSTRAINTS struct containing permitted/excluded subtrees
6158
 * type: GeneralName type (WOLFSSL_GEN_DNS, WOLFSSL_GEN_EMAIL, etc.)
6159
 * name: The name string to check
6160
 * nameSz: Length of name string
6161
 *
6162
 * Returns 1 if name satisfies constraints (permitted and not excluded),
6163
 * otherwise 0 if name does not satisfy constraints or on error
6164
 *
6165
 * A name satisfies constraints if permitted subtrees exist for the type,
6166
 * name matches at least one, and name does not match any excluded subtree.
6167
 */
6168
int wolfSSL_NAME_CONSTRAINTS_check_name(WOLFSSL_NAME_CONSTRAINTS* nc,
6169
    int type, const char* name, int nameSz)
6170
{
6171
    int i, num;
6172
    int hasPermittedType = 0;
6173
    int matchedPermitted = 0;
6174
    WOLFSSL_GENERAL_SUBTREE* subtree;
6175
    WOLFSSL_GENERAL_NAME* gn;
6176
6177
    WOLFSSL_ENTER("wolfSSL_NAME_CONSTRAINTS_check_name");
6178
6179
    if (nc == NULL || name == NULL || nameSz <= 0) {
6180
        WOLFSSL_MSG("Bad argument to NAME_CONSTRAINTS_check_name");
6181
        return 0;
6182
    }
6183
6184
    if (type == WOLFSSL_GEN_URI &&
6185
            (NameConstraintsHasType(nc->permittedSubtrees, type) ||
6186
             NameConstraintsHasType(nc->excludedSubtrees, type)) &&
6187
            !wolfssl_local_UriNameHasDnsHost(name, nameSz)) {
6188
        WOLFSSL_MSG("URI name constraint applied to URI without DNS host");
6189
        return 0;
6190
    }
6191
6192
    /* Check permitted subtrees */
6193
    if (nc->permittedSubtrees != NULL) {
6194
        num = wolfSSL_sk_GENERAL_SUBTREE_num(nc->permittedSubtrees);
6195
        for (i = 0; i < num; i++) {
6196
            subtree = wolfSSL_sk_GENERAL_SUBTREE_value(
6197
                nc->permittedSubtrees, i);
6198
            if (subtree == NULL || subtree->base == NULL) {
6199
                continue;
6200
            }
6201
6202
            gn = subtree->base;
6203
            if (gn->type != type) {
6204
                continue;
6205
            }
6206
            hasPermittedType = 1;
6207
6208
            if (MatchNameConstraint(type, name, nameSz, gn, 1)) {
6209
                matchedPermitted = 1;
6210
                break;
6211
            }
6212
        }
6213
    }
6214
6215
    /* If permitted constraints exist for this type but none matched, fail */
6216
    if (hasPermittedType && !matchedPermitted) {
6217
        WOLFSSL_MSG("Name not in permitted subtrees");
6218
        return 0;
6219
    }
6220
6221
    /* Check excluded subtrees */
6222
    if (nc->excludedSubtrees != NULL) {
6223
        num = wolfSSL_sk_GENERAL_SUBTREE_num(nc->excludedSubtrees);
6224
        for (i = 0; i < num; i++) {
6225
            subtree = wolfSSL_sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i);
6226
            if (subtree == NULL || subtree->base == NULL) {
6227
                continue;
6228
            }
6229
6230
            gn = subtree->base;
6231
            if (gn->type != type) {
6232
                continue;
6233
            }
6234
6235
            if (MatchNameConstraint(type, name, nameSz, gn, 0)) {
6236
                WOLFSSL_MSG("Name in excluded subtrees");
6237
                return 0;
6238
            }
6239
        }
6240
    }
6241
6242
    return 1;
6243
}
6244
#endif /* !IGNORE_NAME_CONSTRAINTS */
6245
6246
#ifndef NO_BIO
6247
static int wolfssl_x509_name_esc_value(const char* in, int inSz,
6248
                                       unsigned long flags, char* out);
6249
6250
/* Write pfx then val to bio with control characters escaped.
6251
 *
6252
 * Returns WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure.
6253
 */
6254
static int X509PrintEscStr(WOLFSSL_BIO* bio, const char* pfx,
6255
                           const char* val, int valSz)
6256
{
6257
    char buf[96];
6258
    int  ret = WOLFSSL_SUCCESS;
6259
    int  pfxSz = (int)XSTRLEN(pfx);
6260
    int  inSz = 0;
6261
    int  escSz;
6262
    int  i;
6263
6264
    if ((pfxSz > 0) && (wolfSSL_BIO_write(bio, pfx, pfxSz) != pfxSz)) {
6265
        ret = WOLFSSL_FAILURE;
6266
    }
6267
    /* ESC_CTRL ignores position and at most triples a byte, so chunk it. */
6268
    for (i = 0; (ret == WOLFSSL_SUCCESS) && (i < valSz); i += inSz) {
6269
        inSz = valSz - i;
6270
        if (inSz > (int)sizeof(buf) / 3) {
6271
            inSz = (int)sizeof(buf) / 3;
6272
        }
6273
        escSz = wolfssl_x509_name_esc_value(val + i, inSz,
6274
                    WOLFSSL_ASN1_STRFLGS_ESC_CTRL, buf);
6275
        if (wolfSSL_BIO_write(bio, buf, escSz) != escSz) {
6276
            ret = WOLFSSL_FAILURE;
6277
        }
6278
    }
6279
6280
    return ret;
6281
}
6282
#endif /* !NO_BIO */
6283
6284
#if defined(OPENSSL_ALL) && !defined(NO_BIO)
6285
/* Outputs name string of the given WOLFSSL_GENERAL_NAME_OBJECT to WOLFSSL_BIO.
6286
 * Can handle following GENERAL_NAME_OBJECT types:
6287
 *  - GEN_OTHERNAME #
6288
 *  - GEN_EMAIL
6289
 *  - GEN_DNS
6290
 *  - GEN_X400  #
6291
 *  - GEN_DIRNAME
6292
 *  - GEN_EDIPARTY #
6293
 *  - GEN_URI
6294
 *  - GEN_RID
6295
 * The each name string to be output has "typename:namestring" format.
6296
 * For instance, email name string will be output as "email:facts@wolfssl.com".
6297
 * However,some types above marked with "#" will be output with
6298
 * "typename:<unsupported>".
6299
 *
6300
 * Parameters:
6301
 *  - out: WOLFSSL_BIO object which is the output destination
6302
 *  - gen: WOLFSSL_GENERAL_NAME object to be output its name
6303
 *
6304
 * Returns WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure.
6305
 */
6306
int wolfSSL_GENERAL_NAME_print(WOLFSSL_BIO* out, WOLFSSL_GENERAL_NAME* gen)
6307
{
6308
    int ret, i;
6309
    unsigned int wd;
6310
    unsigned char* p;
6311
    (void)wd;
6312
    (void)p;
6313
    (void)i;
6314
    WOLFSSL_ENTER("wolfSSL_GENERAL_NAME_print");
6315
6316
    if (out == NULL || gen == NULL)
6317
        return WOLFSSL_FAILURE;
6318
6319
    ret = WOLFSSL_FAILURE;
6320
    switch (gen->type)
6321
    {
6322
    case GEN_OTHERNAME:
6323
        ret = wolfSSL_BIO_printf(out, "othername:<unsupported>");
6324
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
6325
        break;
6326
6327
    case GEN_EMAIL:
6328
        if (gen->d.rfc822Name != NULL) {
6329
            ret = X509PrintEscStr(out, "email:", gen->d.rfc822Name->data,
6330
                                  gen->d.rfc822Name->length);
6331
        }
6332
        break;
6333
6334
    case GEN_DNS:
6335
        if (gen->d.dNSName != NULL) {
6336
            ret = X509PrintEscStr(out, "DNS:", gen->d.dNSName->data,
6337
                                  gen->d.dNSName->length);
6338
        }
6339
        break;
6340
6341
    case GEN_X400:
6342
        ret = wolfSSL_BIO_printf(out, "X400Name:<unsupported>");
6343
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
6344
        break;
6345
6346
    case GEN_DIRNAME:
6347
        ret = wolfSSL_BIO_printf(out, "DirName:");
6348
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
6349
        if (ret == WOLFSSL_SUCCESS) {
6350
            ret = wolfSSL_X509_NAME_print_ex(out, gen->d.directoryName, 0,
6351
                                                         XN_FLAG_ONELINE);
6352
        }
6353
        break;
6354
6355
    case GEN_EDIPARTY:
6356
        ret = wolfSSL_BIO_printf(out, "EdiPartyName:<unsupported>");
6357
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
6358
        break;
6359
6360
    case GEN_URI:
6361
        if (gen->d.uniformResourceIdentifier != NULL) {
6362
            ret = X509PrintEscStr(out, "URI:",
6363
                                  gen->d.uniformResourceIdentifier->data,
6364
                                  gen->d.uniformResourceIdentifier->length);
6365
        }
6366
        break;
6367
6368
    case GEN_IPADD:
6369
        ret = wolfSSL_BIO_printf(out, "IP Address");
6370
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
6371
        if (ret == WOLFSSL_SUCCESS) {
6372
6373
            if (!gen->d.iPAddress->length) {
6374
                ret = WOLFSSL_FAILURE;
6375
                break;
6376
            }
6377
            p = (unsigned char*)gen->d.iPAddress->strData;
6378
6379
            if (gen->d.iPAddress->length == 4) {
6380
                ret = wolfSSL_BIO_printf(out, ":%d.%d.%d.%d",
6381
                                  p[0],p[1],p[2],p[3]);
6382
            }
6383
            else if (gen->d.iPAddress->length == 16) {
6384
6385
                for (i = 0; i < 16 && ret == WOLFSSL_SUCCESS;) {
6386
                    wd = p[i] << 8 | p[i+1];
6387
6388
                    i += 2;
6389
                    ret = wolfSSL_BIO_printf(out, ":%X", wd);
6390
                    ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
6391
                }
6392
            }
6393
            else {
6394
                ret = wolfSSL_BIO_printf(out, "<unsupported>");
6395
            }
6396
            ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
6397
        }
6398
        break;
6399
6400
    case GEN_RID:
6401
        ret = wolfSSL_BIO_printf(out, "Registered ID:");
6402
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
6403
        if (ret == WOLFSSL_SUCCESS) {
6404
            ret = wolfSSL_i2a_ASN1_OBJECT(out, gen->d.registeredID);
6405
        }
6406
        break;
6407
6408
    default:
6409
        /* unsupported type */
6410
        break;
6411
    }
6412
6413
    if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
6414
        return WOLFSSL_FAILURE;
6415
    else
6416
        return WOLFSSL_SUCCESS;
6417
}
6418
#endif /* OPENSSL_ALL */
6419
6420
WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* wolfSSL_sk_X509_EXTENSION_new_null(void)
6421
{
6422
    WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL);
6423
    if (sk) {
6424
        sk->type = STACK_TYPE_X509_EXT;
6425
    }
6426
6427
    return (WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)*)sk;;
6428
}
6429
6430
/* returns the number of nodes on the stack */
6431
int wolfSSL_sk_X509_EXTENSION_num(WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk)
6432
{
6433
    if (sk != NULL) {
6434
        return (int)sk->num;
6435
    }
6436
    return WOLFSSL_FATAL_ERROR;
6437
}
6438
6439
6440
/* returns null on failure and pointer to internal value on success */
6441
WOLFSSL_X509_EXTENSION* wolfSSL_sk_X509_EXTENSION_value(
6442
        const WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk, int idx)
6443
{
6444
    return (WOLFSSL_X509_EXTENSION*)wolfSSL_sk_value(sk, idx);
6445
}
6446
6447
/* frees all of the nodes and the values in stack */
6448
void wolfSSL_sk_X509_EXTENSION_pop_free(
6449
        WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk,
6450
        void (*f) (WOLFSSL_X509_EXTENSION*))
6451
{
6452
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
6453
}
6454
6455
void wolfSSL_sk_X509_EXTENSION_free(WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk)
6456
{
6457
    wolfSSL_sk_pop_free(sk, NULL);
6458
}
6459
6460
#endif /* OPENSSL_EXTRA */
6461
6462
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && \
6463
    !defined(NO_STDIO_FILESYSTEM)
6464
6465
WOLFSSL_X509* wolfSSL_X509_d2i_fp(WOLFSSL_X509** x509, XFILE file)
6466
{
6467
    WOLFSSL_X509* newX509 = NULL;
6468
6469
    WOLFSSL_ENTER("wolfSSL_X509_d2i_fp");
6470
6471
    if (file != XBADFILE) {
6472
        byte* fileBuffer = NULL;
6473
        long sz = 0;
6474
6475
        if (XFSEEK(file, 0, XSEEK_END) != 0)
6476
            return NULL;
6477
        sz = XFTELL(file);
6478
        if (XFSEEK(file, 0, XSEEK_SET) != 0)
6479
            return NULL;
6480
6481
        if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
6482
            WOLFSSL_MSG("X509_d2i file size error");
6483
            return NULL;
6484
        }
6485
6486
        fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
6487
        if (fileBuffer != NULL) {
6488
            int ret = (int)XFREAD(fileBuffer, 1, (size_t)sz, file);
6489
            if (ret == sz) {
6490
                newX509 = wolfSSL_X509_d2i(NULL, fileBuffer, (int)sz);
6491
            }
6492
            XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
6493
        }
6494
    }
6495
6496
    if (x509 != NULL)
6497
        *x509 = newX509;
6498
6499
    return newX509;
6500
}
6501
6502
#endif /* OPENSSL_EXTRA && !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM */
6503
6504
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
6505
    defined(WOLFSSL_WPAS_SMALL) || defined(KEEP_PEER_CERT) || \
6506
    defined(SESSION_CERTS)
6507
6508
#ifndef NO_FILESYSTEM
6509
WOLFSSL_ABI
6510
WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format)
6511
{
6512
#ifdef WOLFSSL_SMALL_STACK
6513
    byte  staticBuffer[1]; /* force heap usage */
6514
#else
6515
    byte  staticBuffer[FILE_BUFFER_SIZE];
6516
#endif
6517
    byte* fileBuffer = staticBuffer;
6518
    int   dynamic = 0;
6519
    int   ret;
6520
    long  sz = 0;
6521
    XFILE file;
6522
6523
    WOLFSSL_X509* x509 = NULL;
6524
6525
    /* Check the inputs */
6526
    if ((fname == NULL) ||
6527
        (format != WOLFSSL_FILETYPE_ASN1 && format != WOLFSSL_FILETYPE_PEM))
6528
        return NULL;
6529
6530
    file = XFOPEN(fname, "rb");
6531
    if (file == XBADFILE)
6532
        return NULL;
6533
6534
    if (XFSEEK(file, 0, XSEEK_END) != 0) {
6535
        XFCLOSE(file);
6536
        return NULL;
6537
    }
6538
    sz = XFTELL(file);
6539
    if (XFSEEK(file, 0, XSEEK_SET) != 0) {
6540
        XFCLOSE(file);
6541
        return NULL;
6542
    }
6543
6544
    if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
6545
        WOLFSSL_MSG("X509_load_certificate_file size error");
6546
        XFCLOSE(file);
6547
        return NULL;
6548
    }
6549
6550
    if (sz > (long)sizeof(staticBuffer)) {
6551
        fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
6552
        if (fileBuffer == NULL) {
6553
            XFCLOSE(file);
6554
            return NULL;
6555
        }
6556
        dynamic = 1;
6557
    }
6558
6559
    ret = (int)XFREAD(fileBuffer, 1, (size_t)sz, file);
6560
    if (ret != sz) {
6561
        XFCLOSE(file);
6562
        if (dynamic)
6563
            XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
6564
        return NULL;
6565
    }
6566
6567
    XFCLOSE(file);
6568
6569
    x509 = wolfSSL_X509_load_certificate_buffer(fileBuffer, (int)sz, format);
6570
6571
    if (dynamic)
6572
        XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
6573
6574
    return x509;
6575
}
6576
#endif /* !NO_FILESYSTEM */
6577
6578
static WOLFSSL_X509* loadX509orX509REQFromBuffer(
6579
    const unsigned char* buf, int sz, int format, int type,
6580
    wc_pem_password_cb *cb, void *u)
6581
{
6582
6583
    int ret = 0;
6584
    WOLFSSL_X509* x509 = NULL;
6585
    DerBuffer* der = NULL;
6586
6587
    WOLFSSL_ENTER("wolfSSL_X509_load_certificate_ex");
6588
6589
    if (format == WOLFSSL_FILETYPE_PEM) {
6590
        EncryptedInfo info;
6591
        XMEMSET(&info, 0, sizeof(EncryptedInfo));
6592
    #ifdef WOLFSSL_ENCRYPTED_KEYS
6593
        info.passwd_cb       = cb;
6594
        info.passwd_userdata = u;
6595
    #endif
6596
6597
    #ifdef WOLFSSL_PEM_TO_DER
6598
        ret = PemToDer(buf, sz, type, &der, NULL, &info, NULL);
6599
        if (ret != 0) {
6600
            FreeDer(&der);
6601
        }
6602
    #else
6603
        ret = NOT_COMPILED_IN;
6604
    #endif
6605
    }
6606
    else {
6607
        ret = AllocDer(&der, (word32)sz, type, NULL);
6608
        if (ret == 0) {
6609
            XMEMCPY(der->buffer, buf, sz);
6610
        }
6611
    }
6612
6613
    /* At this point we want `der` to have the certificate in DER format */
6614
    /* ready to be decoded. */
6615
    if (der != NULL && der->buffer != NULL) {
6616
        WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
6617
6618
        WC_ALLOC_VAR_EX(cert, DecodedCert, 1, NULL, DYNAMIC_TYPE_DCERT,
6619
            ret=MEMORY_ERROR);
6620
        if (WC_VAR_OK(cert))
6621
        {
6622
            InitDecodedCert(cert, der->buffer, der->length, NULL);
6623
        #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
6624
            /* CopyDecodedToX509() adds the name entries to the X509
6625
             * directly. */
6626
            cert->noX509Name = 1;
6627
        #endif
6628
            /* For TRUSTED_CERT_TYPE the DER buffer holds the certificate
6629
             * followed by auxiliary trust info. ParseCertRelative() recognizes
6630
             * the type: it parses only the certificate, permits the trailing
6631
             * aux data, and treats it as CERT_TYPE for verification.
6632
             * CopyDecodedToX509() bounds the stored DER to the certificate. */
6633
            ret = ParseCertRelative(cert, type, 0, NULL, NULL);
6634
            if (ret == 0) {
6635
                x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
6636
                                                             DYNAMIC_TYPE_X509);
6637
                if (x509 != NULL) {
6638
                    InitX509(x509, 1, NULL);
6639
                    ret = CopyDecodedToX509(x509, cert);
6640
                    if (ret != 0) {
6641
                        wolfSSL_X509_free(x509);
6642
                        x509 = NULL;
6643
                    }
6644
                }
6645
                else {
6646
                    ret = MEMORY_ERROR;
6647
                }
6648
            }
6649
6650
            FreeDecodedCert(cert);
6651
            WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
6652
        }
6653
6654
        FreeDer(&der);
6655
    }
6656
6657
    if (ret != 0) {
6658
        WOLFSSL_ERROR(ret);
6659
    }
6660
6661
    /* unused parameter when built without WOLFSSL_ENCRYPTED_KEYS */
6662
    (void)cb;
6663
    (void)u;
6664
    return x509;
6665
}
6666
6667
WOLFSSL_X509* wolfSSL_X509_load_certificate_buffer(
6668
    const unsigned char* buf, int sz, int format)
6669
{
6670
    return loadX509orX509REQFromBuffer(buf, sz,
6671
            format, CERT_TYPE, NULL, NULL);
6672
}
6673
6674
#ifdef WOLFSSL_CERT_REQ
6675
WOLFSSL_X509* wolfSSL_X509_REQ_load_certificate_buffer(
6676
    const unsigned char* buf, int sz, int format)
6677
{
6678
    return loadX509orX509REQFromBuffer(buf, sz,
6679
            format, CERTREQ_TYPE, NULL, NULL);
6680
}
6681
#endif
6682
6683
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || KEEP_PEER_CERT || \
6684
          SESSION_CERTS */
6685
6686
#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(KEEP_PEER_CERT) || \
6687
    defined(SESSION_CERTS)
6688
/* Smaller subset of X509 compatibility functions. Avoid increasing the size of
6689
 * this subset and its memory usage */
6690
6691
/* returns a pointer to a new WOLFSSL_X509 structure on success and NULL on
6692
 * fail
6693
 */
6694
WOLFSSL_X509* wolfSSL_X509_new_ex(void* heap)
6695
{
6696
    WOLFSSL_X509* x509;
6697
6698
    x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), heap,
6699
            DYNAMIC_TYPE_X509);
6700
    if (x509 != NULL) {
6701
        InitX509(x509, 1, heap);
6702
    }
6703
6704
    return x509;
6705
}
6706
6707
WOLFSSL_X509* wolfSSL_X509_new(void)
6708
{
6709
    return wolfSSL_X509_new_ex(NULL);
6710
}
6711
6712
WOLFSSL_ABI
6713
WOLFSSL_X509_NAME* wolfSSL_X509_get_subject_name(WOLFSSL_X509* cert)
6714
{
6715
    WOLFSSL_ENTER("wolfSSL_X509_get_subject_name");
6716
    if (cert)
6717
        return &cert->subject;
6718
    return NULL;
6719
}
6720
6721
WOLFSSL_ABI
6722
WOLFSSL_X509_NAME* wolfSSL_X509_get_issuer_name(WOLFSSL_X509* cert)
6723
{
6724
    WOLFSSL_ENTER("wolfSSL_X509_get_issuer_name");
6725
    if (cert)
6726
        return &cert->issuer;
6727
    return NULL;
6728
}
6729
6730
6731
int wolfSSL_X509_get_signature_type(WOLFSSL_X509* x509)
6732
{
6733
    int type = 0;
6734
6735
    WOLFSSL_ENTER("wolfSSL_X509_get_signature_type");
6736
6737
    if (x509 != NULL)
6738
        type = x509->sigOID;
6739
6740
    return type;
6741
}
6742
6743
#if defined(OPENSSL_EXTRA_X509_SMALL)
6744
6745
int wolfSSL_X509_NAME_get_sz(WOLFSSL_X509_NAME* name)
6746
{
6747
    WOLFSSL_ENTER("wolfSSL_X509_NAME_get_sz");
6748
    if (!name)
6749
        return WOLFSSL_FATAL_ERROR;
6750
    return name->sz;
6751
}
6752
6753
/* Searches for the first ENTRY of type NID
6754
 * idx is the location to start searching from, the value at when the entry was
6755
 *     found is stored into idx
6756
 * returns a pointer to the entry on success and null on fail */
6757
static const WOLFSSL_X509_NAME_ENTRY* GetEntryByNID(
6758
        const WOLFSSL_X509_NAME* name, int nid, int* idx)
6759
{
6760
    int i;
6761
    const WOLFSSL_X509_NAME_ENTRY* ret = NULL;
6762
6763
    for (i = *idx; i < MAX_NAME_ENTRIES; i++) {
6764
        if (name->entry[i].nid == nid) {
6765
            ret = &name->entry[i];
6766
            *idx = i;
6767
            break;
6768
        }
6769
    }
6770
    return ret;
6771
}
6772
6773
6774
/* Used to get a string from the WOLFSSL_X509_NAME structure that
6775
 * corresponds with the NID value passed in. This finds the first entry with
6776
 * matching NID value, if searching for the case where there is multiple
6777
 * entries with the same NID value than other functions should be used
6778
 * (i.e. wolfSSL_X509_NAME_get_index_by_NID, wolfSSL_X509_NAME_get_entry)
6779
 *
6780
 * name structure to get string from
6781
 * nid  NID value to search for
6782
 * buf  [out] buffer to hold results. If NULL then the buffer size minus the
6783
 *      null char is returned.
6784
 * len  size of "buf" passed in
6785
 *
6786
 * returns the length of string found, not including the NULL terminator.
6787
 *         It's possible the function could return a negative value in the
6788
 *         case that len is less than or equal to 0. A negative value is
6789
 *         considered an error case.
6790
 */
6791
int wolfSSL_X509_NAME_get_text_by_NID(const WOLFSSL_X509_NAME* name,
6792
                                      int nid, char* buf, int len)
6793
{
6794
    const WOLFSSL_X509_NAME_ENTRY* e;
6795
    const unsigned char *text = NULL;
6796
    int textSz = 0;
6797
    int idx    = 0;
6798
6799
    WOLFSSL_ENTER("wolfSSL_X509_NAME_get_text_by_NID");
6800
6801
    if (name == NULL) {
6802
        WOLFSSL_MSG("NULL argument passed in");
6803
        return WOLFSSL_FATAL_ERROR;
6804
    }
6805
6806
    e = GetEntryByNID(name, nid, &idx);
6807
    if (e == NULL) {
6808
        WOLFSSL_MSG("Entry type not found");
6809
        return WOLFSSL_FATAL_ERROR;
6810
    }
6811
    text   = wolfSSL_ASN1_STRING_get0_data(e->value);
6812
    textSz = wolfSSL_ASN1_STRING_length(e->value);
6813
6814
    if (text == NULL) {
6815
        WOLFSSL_MSG("Unable to get entry text");
6816
        return WOLFSSL_FATAL_ERROR;
6817
    }
6818
6819
    /* if buf is NULL return size of buffer needed (minus null char) */
6820
    if (buf == NULL) {
6821
        WOLFSSL_MSG("Buffer is NULL, returning buffer size only");
6822
        return textSz;
6823
    }
6824
    if (len <= 0) {
6825
        return 0;
6826
    }
6827
6828
    /* + 1 to account for null char */
6829
    textSz = (int)min((word32)textSz + 1, (word32)len);
6830
    if (textSz > 0) {
6831
        XMEMCPY(buf, text, textSz - 1);
6832
        buf[textSz - 1] = '\0';
6833
    }
6834
6835
    WOLFSSL_LEAVE("wolfSSL_X509_NAME_get_text_by_NID", textSz);
6836
    return (textSz - 1); /* do not include null character in size */
6837
}
6838
6839
/* Decodes the public key of x509 into a new WOLFSSL_EVP_PKEY.
6840
 *
6841
 * returns a pointer to the created WOLFSSL_EVP_PKEY on success and NULL on fail
6842
 */
6843
static WOLFSSL_EVP_PKEY* X509DecodePubKey(WOLFSSL_X509* x509)
6844
{
6845
    WOLFSSL_EVP_PKEY* key = NULL;
6846
    int ret = 0;
6847
6848
    (void)ret;
6849
6850
    if (x509 != NULL && x509->pubKey.buffer != NULL &&
6851
            x509->pubKey.length > 0) {
6852
        key = wolfSSL_EVP_PKEY_new_ex(x509->heap);
6853
        if (key != NULL) {
6854
            if (x509->pubKeyOID == RSAk) {
6855
                key->type = WC_EVP_PKEY_RSA;
6856
            }
6857
            else if (x509->pubKeyOID == DSAk) {
6858
                key->type = WC_EVP_PKEY_DSA;
6859
            }
6860
        #ifdef WOLFSSL_HAVE_MLDSA
6861
            else if (x509->pubKeyOID == ML_DSA_44k ||
6862
                     x509->pubKeyOID == ML_DSA_65k ||
6863
                     x509->pubKeyOID == ML_DSA_87k
6864
        #ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
6865
                     || x509->pubKeyOID == DILITHIUM_LEVEL2k ||
6866
                     x509->pubKeyOID == DILITHIUM_LEVEL3k ||
6867
                     x509->pubKeyOID == DILITHIUM_LEVEL5k
6868
        #endif
6869
                     ) {
6870
                key->type = WC_EVP_PKEY_DILITHIUM;
6871
                WOLFSSL_ATOMIC_STORE(key->mldsaOID, x509->pubKeyOID);
6872
            }
6873
        #endif
6874
        #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
6875
            else if (x509->pubKeyOID == ED25519k) {
6876
                key->type = WC_EVP_PKEY_ED25519;
6877
            }
6878
        #endif
6879
        #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) && \
6880
            (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL))
6881
            else if (x509->pubKeyOID == ED448k) {
6882
                key->type = WC_EVP_PKEY_ED448;
6883
            }
6884
        #endif
6885
        #ifdef OPENSSL_EXTRA
6886
            else if (x509->pubKeyOID != ECDSAk && x509->pubKeyOID != SM2k) {
6887
                /* Other key types are decoded from the encoded key. */
6888
                const unsigned char* der = x509->pubKey.buffer;
6889
6890
                wolfSSL_EVP_PKEY_free(key);
6891
                return wolfSSL_d2i_PUBKEY(NULL, &der,
6892
                    (long)x509->pubKey.length);
6893
            }
6894
        #endif
6895
            else {
6896
                key->type = WC_EVP_PKEY_EC;
6897
            }
6898
            key->save_type = 0;
6899
            key->pkey.ptr = (char*)XMALLOC(
6900
                        x509->pubKey.length, x509->heap,
6901
                                                       DYNAMIC_TYPE_PUBLIC_KEY);
6902
            if (key->pkey.ptr == NULL) {
6903
                wolfSSL_EVP_PKEY_free(key);
6904
                return NULL;
6905
            }
6906
            XMEMCPY(key->pkey.ptr, x509->pubKey.buffer, x509->pubKey.length);
6907
            key->pkey_sz = (int)x509->pubKey.length;
6908
6909
            #ifdef HAVE_ECC
6910
                key->pkey_curve = (int)x509->pkCurveOID;
6911
            #endif /* HAVE_ECC */
6912
6913
            /* decode RSA key */
6914
            #ifndef NO_RSA
6915
            if (key->type == WC_EVP_PKEY_RSA) {
6916
                key->ownRsa = 1;
6917
                key->rsa = wolfSSL_RSA_new();
6918
                if (key->rsa == NULL) {
6919
                    wolfSSL_EVP_PKEY_free(key);
6920
                    return NULL;
6921
                }
6922
6923
                if (wolfSSL_RSA_LoadDer_ex(key->rsa,
6924
                            (const unsigned char*)key->pkey.ptr, key->pkey_sz,
6925
                            WOLFSSL_RSA_LOAD_PUBLIC) != WOLFSSL_SUCCESS) {
6926
                    wolfSSL_EVP_PKEY_free(key);
6927
                    return NULL;
6928
                }
6929
            }
6930
            #endif /* NO_RSA */
6931
6932
            /* decode ECC key */
6933
            #if defined(HAVE_ECC) && defined(OPENSSL_EXTRA)
6934
            if (key->type == WC_EVP_PKEY_EC) {
6935
                word32 idx = 0;
6936
6937
                key->ownEcc = 1;
6938
                key->ecc = wolfSSL_EC_KEY_new();
6939
                if (key->ecc == NULL || key->ecc->internal == NULL) {
6940
                    wolfSSL_EVP_PKEY_free(key);
6941
                    return NULL;
6942
                }
6943
6944
                /* not using wolfSSL_EC_KEY_LoadDer because public key in x509
6945
                 * is in the format of x963 (no sequence at start of buffer) */
6946
                ret = wc_EccPublicKeyDecode((const unsigned char*)key->pkey.ptr,
6947
                                            &idx, (ecc_key*)key->ecc->internal,
6948
                                            key->pkey_sz);
6949
                if (ret < 0) {
6950
                    WOLFSSL_ERROR_VERBOSE(ret);
6951
                    WOLFSSL_MSG("wc_EccPublicKeyDecode failed");
6952
                    wolfSSL_EVP_PKEY_free(key);
6953
                    return NULL;
6954
                }
6955
6956
                if (SetECKeyExternal(key->ecc) != WOLFSSL_SUCCESS) {
6957
                    WOLFSSL_MSG("SetECKeyExternal failed");
6958
                    wolfSSL_EVP_PKEY_free(key);
6959
                    return NULL;
6960
                }
6961
6962
                key->ecc->inSet = 1;
6963
            }
6964
            #endif /* HAVE_ECC && OPENSSL_EXTRA */
6965
6966
            #ifndef NO_DSA
6967
            if (key->type == WC_EVP_PKEY_DSA) {
6968
                key->ownDsa = 1;
6969
                key->dsa = wolfSSL_DSA_new();
6970
                if (key->dsa == NULL) {
6971
                    wolfSSL_EVP_PKEY_free(key);
6972
                    return NULL;
6973
                }
6974
6975
                if (wolfSSL_DSA_LoadDer_ex(key->dsa,
6976
                            (const unsigned char*)key->pkey.ptr, key->pkey_sz, \
6977
                            WOLFSSL_DSA_LOAD_PUBLIC) != WOLFSSL_SUCCESS) {
6978
                    wolfSSL_DSA_free(key->dsa);
6979
                    key->dsa = NULL;
6980
                    wolfSSL_EVP_PKEY_free(key);
6981
                    return NULL;
6982
                }
6983
            }
6984
            #endif /* NO_DSA */
6985
6986
            /* decode Ed25519 key */
6987
            #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
6988
            if (key->type == WC_EVP_PKEY_ED25519) {
6989
                key->ed25519 = wolfSSL_ED25519_new(x509->heap, INVALID_DEVID);
6990
                if (key->ed25519 == NULL) {
6991
                    wolfSSL_EVP_PKEY_free(key);
6992
                    return NULL;
6993
                }
6994
                key->ownEd25519 = 1;
6995
6996
                /* The X.509 public key buffer holds the raw Ed25519 key
6997
                 * (CopyDecodedToX509 / StoreKey store the BIT STRING
6998
                 * contents), so import it directly. */
6999
                if (wc_ed25519_import_public(
7000
                            (const unsigned char*)key->pkey.ptr,
7001
                            (word32)key->pkey_sz, key->ed25519) != 0) {
7002
                    WOLFSSL_MSG("wc_ed25519_import_public failed");
7003
                    wolfSSL_EVP_PKEY_free(key);
7004
                    return NULL;
7005
                }
7006
            }
7007
            #endif /* HAVE_ED25519 */
7008
7009
            /* decode Ed448 key */
7010
            #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) && \
7011
                (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL))
7012
            if (key->type == WC_EVP_PKEY_ED448) {
7013
                key->ed448 = wolfSSL_ED448_new(x509->heap, INVALID_DEVID);
7014
                if (key->ed448 == NULL) {
7015
                    wolfSSL_EVP_PKEY_free(key);
7016
                    return NULL;
7017
                }
7018
                key->ownEd448 = 1;
7019
7020
                /* The X.509 public key buffer holds the raw Ed448 key. */
7021
                if (wc_ed448_import_public(
7022
                            (const unsigned char*)key->pkey.ptr,
7023
                            (word32)key->pkey_sz, key->ed448) != 0) {
7024
                    WOLFSSL_MSG("wc_ed448_import_public failed");
7025
                    wolfSSL_EVP_PKEY_free(key);
7026
                    return NULL;
7027
                }
7028
            }
7029
            #endif /* HAVE_ED448 */
7030
7031
            /* re-encode ML-DSA key */
7032
            #if defined(WOLFSSL_HAVE_MLDSA) && \
7033
                defined(WOLFSSL_MLDSA_PUBLIC_KEY) && \
7034
                !defined(WOLFSSL_MLDSA_NO_ASN1) && \
7035
                defined(WC_ENABLE_ASYM_KEY_EXPORT) && \
7036
                (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL))
7037
            if (key->type == WC_EVP_PKEY_DILITHIUM) {
7038
                byte* spki = NULL;
7039
                word32 spkiSz = 0;
7040
7041
                /* The buffer holds the raw key. Encode to SPKI so the i2d
7042
                 * functions work fine */
7043
                if (wolfssl_i_mldsa_raw_pub_to_der((const byte*)key->pkey.ptr,
7044
                        (word32)key->pkey_sz, x509->pubKeyOID, &spki, &spkiSz,
7045
                        x509->heap) != 0) {
7046
                    WOLFSSL_MSG("wolfssl_i_mldsa_raw_pub_to_der failed");
7047
                    wolfSSL_EVP_PKEY_free(key);
7048
                    return NULL;
7049
                }
7050
                XFREE(key->pkey.ptr, x509->heap, DYNAMIC_TYPE_PUBLIC_KEY);
7051
                key->pkey.ptr = (char*)spki;
7052
                key->pkey_sz = (int)spkiSz;
7053
            }
7054
            #endif /* WOLFSSL_HAVE_MLDSA */
7055
        }
7056
    }
7057
    return key;
7058
}
7059
7060
#ifndef SINGLE_THREADED
7061
/* Reads a pointer that another thread may store with
7062
 * wolfSSL_Atomic_Ptr_CompareExchange(). */
7063
static void* X509CacheLoad(void* volatile* ptr)
7064
{
7065
#if defined(__GNUC__) && defined(__ATOMIC_SEQ_CST)
7066
    return __atomic_load_n(ptr, __ATOMIC_ACQUIRE);
7067
#else
7068
    void* current = NULL;
7069
7070
    /* Only replaces NULL with NULL, so nothing is changed. */
7071
    (void)wolfSSL_Atomic_Ptr_CompareExchange(ptr, &current, NULL);
7072
    return current;
7073
#endif
7074
}
7075
#define X509_CACHE_LOAD(ptr)    X509CacheLoad((void* volatile*)&(ptr))
7076
#else
7077
#define X509_CACHE_LOAD(ptr)    (ptr)
7078
#endif
7079
7080
/* Returns the public key cached in x509, decoding it on first use.
7081
 * The key is owned by x509 and freed with it. */
7082
static WOLFSSL_EVP_PKEY* X509CachedPubKey(WOLFSSL_X509* x509)
7083
{
7084
    WOLFSSL_EVP_PKEY* key;
7085
7086
    if (x509 == NULL)
7087
        return NULL;
7088
    key = (WOLFSSL_EVP_PKEY*)X509_CACHE_LOAD(x509->key.pkey);
7089
    if (key == NULL) {
7090
        key = X509DecodePubKey(x509);
7091
        if (key != NULL) {
7092
        #ifndef SINGLE_THREADED
7093
            void* current = NULL;
7094
7095
            /* Threads may decode the key of a shared X509 at the same time.
7096
             * Only the first key is cached, so a key handed out is never
7097
             * replaced. */
7098
            if (!wolfSSL_Atomic_Ptr_CompareExchange(
7099
                    (void* volatile*)&x509->key.pkey, &current, key)) {
7100
                wolfSSL_EVP_PKEY_free(key);
7101
                key = (WOLFSSL_EVP_PKEY*)current;
7102
            }
7103
        #else
7104
            x509->key.pkey = key;
7105
        #endif
7106
        }
7107
    }
7108
    return key;
7109
}
7110
7111
/* Returns the public key of x509 with a new reference.
7112
 *
7113
 * returns a pointer to the WOLFSSL_EVP_PKEY on success and NULL on fail.
7114
 * The caller frees it with wolfSSL_EVP_PKEY_free().
7115
 */
7116
WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
7117
{
7118
    WOLFSSL_EVP_PKEY* key;
7119
7120
    WOLFSSL_ENTER("wolfSSL_X509_get_pubkey");
7121
    key = X509CachedPubKey(x509);
7122
    if (key != NULL) {
7123
        int ret;
7124
        wolfSSL_RefInc(&key->ref, &ret);
7125
        if (ret != 0) {
7126
            WOLFSSL_MSG("Failed to lock pkey mutex");
7127
            key = NULL;
7128
        }
7129
    }
7130
    return key;
7131
}
7132
7133
/* Returns the public key of x509 without a new reference.
7134
 *
7135
 * returns a pointer to the WOLFSSL_EVP_PKEY on success and NULL on fail.
7136
 * The key must not be freed. It is valid until x509 is freed or its public
7137
 * key is changed.
7138
 */
7139
WOLFSSL_EVP_PKEY* wolfSSL_X509_get0_pubkey(const WOLFSSL_X509* x509)
7140
{
7141
    WOLFSSL_ENTER("wolfSSL_X509_get0_pubkey");
7142
    /* Only the lazily decoded key cache is written. */
7143
    return X509CachedPubKey((WOLFSSL_X509*)x509);
7144
}
7145
#endif /* OPENSSL_EXTRA_X509_SMALL */
7146
7147
/* End of smaller subset of X509 compatibility functions. Avoid increasing the
7148
 * size of this subset and its memory usage */
7149
#endif /* OPENSSL_EXTRA_X509_SMALL || KEEP_PEER_CERT || SESSION_CERTS */
7150
7151
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
7152
/*
7153
 * Converts a and b to DER and then does an XMEMCMP to check if they match.
7154
 * Returns 0 when certificates match and WOLFSSL_FATAL_ERROR when they don't.
7155
 */
7156
int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b)
7157
{
7158
        const byte* derA;
7159
        const byte* derB;
7160
        int outSzA = 0;
7161
        int outSzB = 0;
7162
7163
        if (a == NULL || b == NULL) {
7164
            return BAD_FUNC_ARG;
7165
        }
7166
7167
        derA = wolfSSL_X509_get_der((WOLFSSL_X509*)a, &outSzA);
7168
        if (derA == NULL) {
7169
            WOLFSSL_MSG("wolfSSL_X509_get_der - certificate A has failed");
7170
            return WOLFSSL_FATAL_ERROR;
7171
        }
7172
        derB = wolfSSL_X509_get_der((WOLFSSL_X509*)b, &outSzB);
7173
        if (derB == NULL) {
7174
            WOLFSSL_MSG("wolfSSL_X509_get_der - certificate B has failed");
7175
            return WOLFSSL_FATAL_ERROR;
7176
        }
7177
7178
        if (outSzA != outSzB || XMEMCMP(derA, derB, outSzA) != 0) {
7179
            WOLFSSL_LEAVE("wolfSSL_X509_cmp", WOLFSSL_FATAL_ERROR);
7180
            return WOLFSSL_FATAL_ERROR;
7181
        }
7182
7183
        WOLFSSL_LEAVE("wolfSSL_X509_cmp", 0);
7184
7185
        return 0;
7186
    }
7187
#endif /* OPENSSL_ALL */
7188
7189
#if defined(OPENSSL_EXTRA)
7190
    int wolfSSL_X509_ext_isSet_by_NID(WOLFSSL_X509* x509, int nid)
7191
    {
7192
        int isSet = 0;
7193
7194
        WOLFSSL_ENTER("wolfSSL_X509_ext_isSet_by_NID");
7195
7196
        if (x509 != NULL) {
7197
            switch (nid) {
7198
                case WC_NID_basic_constraints:
7199
                    isSet = x509->basicConstSet; break;
7200
                case WC_NID_subject_alt_name:
7201
                    isSet = x509->subjAltNameSet; break;
7202
                case WC_NID_authority_key_identifier:
7203
                    isSet = x509->authKeyIdSet; break;
7204
                case WC_NID_subject_key_identifier:
7205
                    isSet = x509->subjKeyIdSet; break;
7206
                case WC_NID_key_usage:
7207
                    isSet = x509->keyUsageSet; break;
7208
                case WC_NID_crl_distribution_points:
7209
                    isSet = x509->CRLdistSet; break;
7210
                case WC_NID_ext_key_usage:
7211
                    isSet = ((x509->extKeyUsageSrc) ? 1 : 0); break;
7212
                case WC_NID_info_access:
7213
                    isSet = x509->authInfoSet; break;
7214
            #if defined(WOLFSSL_SEP) || defined(WOLFSSL_QT)
7215
                case WC_NID_certificate_policies:
7216
                    isSet = x509->certPolicySet; break;
7217
            #endif /* WOLFSSL_SEP || WOLFSSL_QT */
7218
                default:
7219
                    WOLFSSL_MSG("NID not in table");
7220
            }
7221
        }
7222
7223
        WOLFSSL_LEAVE("wolfSSL_X509_ext_isSet_by_NID", isSet);
7224
7225
        return isSet;
7226
    }
7227
7228
7229
    int wolfSSL_X509_ext_get_critical_by_NID(WOLFSSL_X509* x509, int nid)
7230
    {
7231
        int crit = 0;
7232
7233
        WOLFSSL_ENTER("wolfSSL_X509_ext_get_critical_by_NID");
7234
7235
        if (x509 != NULL) {
7236
            switch (nid) {
7237
                case WC_NID_basic_constraints:
7238
                    crit = x509->basicConstCrit; break;
7239
                case WC_NID_subject_alt_name:
7240
                    crit = x509->subjAltNameCrit; break;
7241
                case WC_NID_authority_key_identifier:
7242
                    crit = x509->authKeyIdCrit; break;
7243
                case WC_NID_subject_key_identifier:
7244
                    crit = x509->subjKeyIdCrit; break;
7245
                case WC_NID_key_usage:
7246
                    crit = x509->keyUsageCrit; break;
7247
                case WC_NID_crl_distribution_points:
7248
                    crit= x509->CRLdistCrit; break;
7249
                case WC_NID_ext_key_usage:
7250
                    crit= x509->extKeyUsageCrit; break;
7251
            #ifdef WOLFSSL_SEP
7252
                case WC_NID_certificate_policies:
7253
                    crit = x509->certPolicyCrit; break;
7254
            #endif /* WOLFSSL_SEP */
7255
            }
7256
        }
7257
7258
        WOLFSSL_LEAVE("wolfSSL_X509_ext_get_critical_by_NID", crit);
7259
7260
        return crit;
7261
    }
7262
7263
7264
    int wolfSSL_X509_get_isSet_pathLength(WOLFSSL_X509* x509)
7265
    {
7266
        int isSet = 0;
7267
7268
        WOLFSSL_ENTER("wolfSSL_X509_get_isSet_pathLength");
7269
7270
        if (x509 != NULL)
7271
            isSet = x509->basicConstPlSet;
7272
7273
        WOLFSSL_LEAVE("wolfSSL_X509_get_isSet_pathLength", isSet);
7274
7275
        return isSet;
7276
    }
7277
7278
7279
    word32 wolfSSL_X509_get_pathLength(WOLFSSL_X509* x509)
7280
    {
7281
        word32 pathLength = 0;
7282
7283
        WOLFSSL_ENTER("wolfSSL_X509_get_pathLength");
7284
7285
        if (x509 != NULL)
7286
            pathLength = x509->pathLength;
7287
7288
        WOLFSSL_LEAVE("wolfSSL_X509_get_pathLength", pathLength);
7289
7290
        return pathLength;
7291
    }
7292
7293
7294
    unsigned int wolfSSL_X509_get_keyUsage(WOLFSSL_X509* x509)
7295
    {
7296
        word16 usage = 0;
7297
7298
        WOLFSSL_ENTER("wolfSSL_X509_get_keyUsage");
7299
7300
        if (x509 != NULL)
7301
            usage = x509->keyUsage;
7302
7303
        WOLFSSL_LEAVE("wolfSSL_X509_get_keyUsage", usage);
7304
7305
        return usage;
7306
    }
7307
7308
7309
    byte* wolfSSL_X509_get_authorityKeyID(WOLFSSL_X509* x509,
7310
                                          byte* dst, int* dstLen)
7311
    {
7312
        byte *id = NULL;
7313
        int copySz = 0;
7314
7315
        WOLFSSL_ENTER("wolfSSL_X509_get_authorityKeyID");
7316
7317
        if (x509 != NULL) {
7318
            if (x509->authKeyIdSet) {
7319
                copySz = (int)min(dstLen != NULL ? (word32)*dstLen : 0,
7320
                                  x509->authKeyIdSz);
7321
                id = x509->authKeyId;
7322
            }
7323
7324
            if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
7325
                XMEMCPY(dst, id, copySz);
7326
                id = dst;
7327
                *dstLen = copySz;
7328
            }
7329
        }
7330
7331
        WOLFSSL_LEAVE("wolfSSL_X509_get_authorityKeyID", copySz);
7332
7333
        return id;
7334
    }
7335
7336
    byte* wolfSSL_X509_get_subjectKeyID(WOLFSSL_X509* x509,
7337
                                        byte* dst, int* dstLen)
7338
    {
7339
        byte *id = NULL;
7340
        int copySz = 0;
7341
7342
        WOLFSSL_ENTER("wolfSSL_X509_get_subjectKeyID");
7343
7344
        if (x509 != NULL) {
7345
            if (x509->subjKeyIdSet) {
7346
                copySz = (int)min(dstLen != NULL ? (word32) *dstLen : 0,
7347
                                  x509->subjKeyIdSz);
7348
                id = x509->subjKeyId;
7349
            }
7350
7351
            if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
7352
                XMEMCPY(dst, id, copySz);
7353
                id = dst;
7354
                *dstLen = copySz;
7355
            }
7356
        }
7357
7358
        WOLFSSL_LEAVE("wolfSSL_X509_get_subjectKeyID", copySz);
7359
7360
        return id;
7361
    }
7362
7363
    const WOLFSSL_ASN1_STRING *wolfSSL_X509_get0_subject_key_id(
7364
            WOLFSSL_X509 *x509)
7365
    {
7366
        WOLFSSL_ASN1_STRING* ret = NULL;
7367
7368
        WOLFSSL_ENTER("wolfSSL_X509_get0_subject_key_id");
7369
7370
        if (x509 != NULL && x509->subjKeyIdSet) {
7371
            if (x509->subjKeyIdStr == NULL) {
7372
                x509->subjKeyIdStr = wolfSSL_ASN1_STRING_new();
7373
                if (x509->subjKeyIdStr != NULL) {
7374
                    if (wolfSSL_ASN1_STRING_set(x509->subjKeyIdStr,
7375
                            x509->subjKeyId, x509->subjKeyIdSz) == 1) {
7376
                    }
7377
                    else {
7378
                        wolfSSL_ASN1_STRING_free(x509->subjKeyIdStr);
7379
                        x509->subjKeyIdStr = NULL;
7380
                    }
7381
                }
7382
            }
7383
            ret = x509->subjKeyIdStr;
7384
        }
7385
7386
        WOLFSSL_LEAVE("wolfSSL_X509_get0_subject_key_id", ret != NULL);
7387
7388
        return ret;
7389
    }
7390
#endif /* OPENSSL_EXTRA */
7391
7392
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
7393
    defined(OPENSSL_EXTRA_X509_SMALL)
7394
7395
    /* Looks up the index of the first entry encountered with matching NID
7396
     * The search starts from index 'pos'
7397
     * returns a negative value on failure and positive index value on success*/
7398
    int wolfSSL_X509_NAME_get_index_by_NID(const WOLFSSL_X509_NAME* name,
7399
                                          int nid, int pos)
7400
    {
7401
        int value = nid, i;
7402
7403
        WOLFSSL_ENTER("wolfSSL_X509_NAME_get_index_by_NID");
7404
7405
        if (name == NULL) {
7406
            return BAD_FUNC_ARG;
7407
        }
7408
7409
        i = pos + 1; /* start search after index passed in */
7410
        if (i < 0) {
7411
            i = 0;
7412
        }
7413
7414
        for (;i < name->entrySz && i < MAX_NAME_ENTRIES; i++) {
7415
            if (name->entry[i].nid == value) {
7416
                return i;
7417
            }
7418
        }
7419
        return WOLFSSL_FATAL_ERROR;
7420
    }
7421
7422
7423
    WOLFSSL_ASN1_STRING*  wolfSSL_X509_NAME_ENTRY_get_data(
7424
                                              const WOLFSSL_X509_NAME_ENTRY* in)
7425
    {
7426
        WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_get_data");
7427
        if (in == NULL)
7428
            return NULL;
7429
7430
        return in->value;
7431
    }
7432
7433
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
7434
7435
#ifdef OPENSSL_EXTRA
7436
#ifndef NO_BIO
7437
7438
#ifndef MAX_WIDTH
7439
    #define MAX_WIDTH 80
7440
#endif
7441
7442
#define ACERT_NUM_DIR_TAGS 4
7443
7444
/* Convenience struct and function for printing the Holder sub fields
7445
 * of an X509 Attribute struct. */
7446
struct acert_dir_print_t {
7447
    const char * pfx;
7448
    const byte   tag[3];
7449
};
7450
7451
static struct acert_dir_print_t acert_dir_print[ACERT_NUM_DIR_TAGS] =
7452
{
7453
    { "C=", {0x55, 0x04, ASN_COUNTRY_NAME} },
7454
    { "O=", {0x55, 0x04, ASN_ORG_NAME} },
7455
    { "OU=", {0x55, 0x04, ASN_ORGUNIT_NAME} },
7456
    { "CN=", {0x55, 0x04, ASN_COMMON_NAME} },
7457
};
7458
7459
/* Print an entry of ASN_DIR_TYPE to bio.
7460
 *
7461
 * Returns WOLFSSL_SUCCESS on success.
7462
 * Returns WOLFSSL_FAILURE on failure.
7463
 * */
7464
static int X509PrintDirType(WOLFSSL_BIO* bio, const DNS_entry * entry)
7465
{
7466
    word32       k = 0;
7467
    word32       i = 0;
7468
    const char * src = entry->name;
7469
    word32       src_len = 0;
7470
    int          fld_len = 0;
7471
    int          ret = WOLFSSL_SUCCESS;
7472
    int          match_found = 0;
7473
7474
    /* The entry holds raw DER which may contain zero bytes, and under
7475
     * WC_ASN_NO_HEAP it is not NUL terminated, so use the stored length. */
7476
    if (entry->len > 0) {
7477
        src_len = (word32)entry->len;
7478
    }
7479
7480
    /* loop over printable DIR tags. */
7481
    for (k = 0; (ret == WOLFSSL_SUCCESS) && (k < ACERT_NUM_DIR_TAGS); ++k) {
7482
        const char * pfx = acert_dir_print[k].pfx;
7483
        const byte * tag = acert_dir_print[k].tag;
7484
        byte         asn_tag;
7485
7486
        /* Walk through entry looking for matches. A match needs three bytes
7487
         * of name OID plus a tag and a length, so the last offset worth
7488
         * testing is the one with exactly five bytes left. Written as an
7489
         * addition so a short entry simply skips the loop rather than
7490
         * underflowing the bound. */
7491
        for (i = 0; i + 5 <= src_len; ++i) {
7492
            if (XMEMCMP(tag, &src[i], 3) == 0) {
7493
                i += 3;
7494
7495
                /* Get the ASN Tag. */
7496
                if (GetASNTag((const byte *)src, &i, &asn_tag, src_len) < 0) {
7497
                    WOLFSSL_MSG("error: GetASNTag failed");
7498
                    break;
7499
                }
7500
7501
                /* Check it is printable. */
7502
                if ((asn_tag != ASN_PRINTABLE_STRING) &&
7503
                    (asn_tag != ASN_IA5_STRING) &&
7504
                    (asn_tag != ASN_UTF8STRING)) {
7505
                    /* Don't know what this is but we can't print it. */
7506
                    WOLFSSL_MSG("error: asn tag not printable string");
7507
                    break;
7508
                }
7509
7510
                /* Now get the length of the printable string. */
7511
                if (GetLength((const byte *)src, &i, &fld_len, src_len) < 0) {
7512
                    break;
7513
                }
7514
7515
                if (match_found && (wolfSSL_BIO_puts(bio, ", ") <= 0)) {
7516
                    ret = WOLFSSL_FAILURE;
7517
                }
7518
                if (ret == WOLFSSL_SUCCESS) {
7519
                    ret = X509PrintEscStr(bio, pfx, &src[i], fld_len);
7520
                }
7521
                if (ret != WOLFSSL_SUCCESS) {
7522
                    break;
7523
                }
7524
                i += fld_len;
7525
7526
                match_found = 1;
7527
            }
7528
        }
7529
    }
7530
7531
    if ((ret == WOLFSSL_SUCCESS) && !match_found) {
7532
        /* Nothing in the encoding was printable. Emit a placeholder, as the
7533
         * other unsupported entry types do, rather than failing the print of
7534
         * the whole certificate. */
7535
        if (wolfSSL_BIO_puts(bio, "DirName:<unprintable>") <= 0) {
7536
            ret = WOLFSSL_FAILURE;
7537
        }
7538
    }
7539
7540
    return ret;
7541
}
7542
static int X509_print_name_entry(WOLFSSL_BIO* bio,
7543
                                 const DNS_entry* entry, int indent)
7544
{
7545
    int  ret = WOLFSSL_SUCCESS;
7546
    int  nameCount = 0;
7547
    char scratch[MAX_WIDTH];
7548
    int  len;
7549
7550
    if (bio == NULL || entry == NULL) {
7551
        return WOLFSSL_FAILURE;
7552
    }
7553
7554
    len = XSNPRINTF(scratch, MAX_WIDTH, "%*s", indent, "");
7555
    if (len >= MAX_WIDTH) {
7556
        return WOLFSSL_FAILURE;
7557
    }
7558
7559
    if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) {
7560
        return WOLFSSL_FAILURE;
7561
    }
7562
7563
    while (entry != NULL) {
7564
        ++nameCount;
7565
        if (nameCount > 1) {
7566
            if (wolfSSL_BIO_write(bio, ", ", 2) <= 0) {
7567
                ret = WOLFSSL_FAILURE;
7568
                break;
7569
            }
7570
        }
7571
7572
        /* Escaped values go straight to bio, the rest through scratch. */
7573
        len = 0;
7574
        if (entry->type == ASN_DNS_TYPE) {
7575
            ret = X509PrintEscStr(bio, "DNS:", entry->name, entry->len);
7576
        }
7577
    #if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
7578
        else if (entry->type == ASN_IP_TYPE) {
7579
            len = XSNPRINTF(scratch, MAX_WIDTH, "IP Address:%s",
7580
                    entry->ipString);
7581
        }
7582
    #else
7583
        else if (entry->type == ASN_IP_TYPE) {
7584
            /* iPAddress entries are now always parsed into altNames so
7585
             * name constraints can be enforced. Without the
7586
             * human-readable ipString field, emit a fixed label so this
7587
             * print path does not fail. */
7588
            len = XSNPRINTF(scratch, MAX_WIDTH, "IP Address:<unavailable>");
7589
        }
7590
    #endif /* OPENSSL_ALL || WOLFSSL_IP_ALT_NAME */
7591
        else if (entry->type == ASN_RFC822_TYPE) {
7592
            ret = X509PrintEscStr(bio, "email:", entry->name, entry->len);
7593
        }
7594
        else if (entry->type == ASN_DIR_TYPE) {
7595
            ret = X509PrintDirType(bio, entry);
7596
        }
7597
        else if (entry->type == ASN_URI_TYPE) {
7598
            ret = X509PrintEscStr(bio, "URI:", entry->name, entry->len);
7599
        }
7600
    #ifdef WOLFSSL_RID_ALT_NAME
7601
        else if (entry->type == ASN_RID_TYPE) {
7602
            len = XSNPRINTF(scratch, MAX_WIDTH, "Registered ID:%s",
7603
                entry->ridString);
7604
        }
7605
    #else
7606
        else if (entry->type == ASN_RID_TYPE) {
7607
            /* registeredID entries are now always parsed into altNames
7608
             * so name constraints can be enforced. Without the
7609
             * human-readable ridString field, emit a fixed label so
7610
             * this print path does not fail. */
7611
            len = XSNPRINTF(scratch, MAX_WIDTH, "Registered ID:<unavailable>");
7612
        }
7613
    #endif /* WOLFSSL_RID_ALT_NAME */
7614
        else if (entry->type == ASN_OTHER_TYPE) {
7615
            len = XSNPRINTF(scratch, MAX_WIDTH,
7616
                "othername <unsupported>");
7617
        }
7618
        else {
7619
            WOLFSSL_MSG("Bad alt name type.");
7620
            ret = WOLFSSL_FAILURE;
7621
            break;
7622
        }
7623
        if ((ret != WOLFSSL_SUCCESS) || (len < 0) || (len >= MAX_WIDTH)) {
7624
            ret = WOLFSSL_FAILURE;
7625
            break;
7626
        }
7627
        if ((len > 0) && (wolfSSL_BIO_write(bio, scratch, len) <= 0)) {
7628
            ret = WOLFSSL_FAILURE;
7629
            break;
7630
        }
7631
7632
        entry = entry->next;
7633
    }
7634
7635
    if (ret == WOLFSSL_SUCCESS && wolfSSL_BIO_write(bio, "\n", 1) <= 0) {
7636
        ret = WOLFSSL_FAILURE;
7637
    }
7638
7639
    return ret;
7640
}
7641
7642
#ifdef XSNPRINTF
7643
static int X509PrintKeyUsage(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
7644
{
7645
    int ret = WOLFSSL_SUCCESS;
7646
    const int usages[] = {
7647
        KEYUSE_DIGITAL_SIG,
7648
        KEYUSE_CONTENT_COMMIT,
7649
        KEYUSE_KEY_ENCIPHER,
7650
        KEYUSE_DATA_ENCIPHER,
7651
        KEYUSE_KEY_AGREE,
7652
        KEYUSE_KEY_CERT_SIGN,
7653
        KEYUSE_CRL_SIGN,
7654
        KEYUSE_ENCIPHER_ONLY,
7655
        KEYUSE_DECIPHER_ONLY
7656
    };
7657
    const char* usageStrs[] = {
7658
        "Digital Signature",
7659
        "Non Repudiation",
7660
        "Key Encipherment",
7661
        "Data Encipherment",
7662
        "Key Agreement",
7663
        "Certificate Sign",
7664
        "CRL Sign",
7665
        "Encipher Only",
7666
        "Decipher Only"
7667
    };
7668
7669
    if (indent < 0) indent = 0;
7670
    if (indent > MAX_INDENT) indent = MAX_INDENT;
7671
7672
    if (bio == NULL || x509 == NULL) {
7673
        ret = WOLFSSL_FAILURE;
7674
    }
7675
7676
    if (ret == WOLFSSL_SUCCESS && x509->keyUsageSet && x509->keyUsage != 0) {
7677
        char scratch[MAX_WIDTH];
7678
        int len;
7679
        word32 i = 0;
7680
        int usageCount = 0;
7681
7682
        len = XSNPRINTF(scratch, MAX_WIDTH, "%*s", indent, "");
7683
        if (len >= MAX_WIDTH)
7684
            ret = WOLFSSL_FAILURE;
7685
        if (ret == WOLFSSL_SUCCESS) {
7686
            if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) {
7687
                ret = WOLFSSL_FAILURE;
7688
            }
7689
        }
7690
        for (; ret == WOLFSSL_SUCCESS && i < sizeof(usages) / sizeof(usages[i]);
7691
             i++) {
7692
            if (x509->keyUsage & usages[i]) {
7693
                ++usageCount;
7694
                if (usageCount > 1 && wolfSSL_BIO_write(bio, ", ", 2) <= 0) {
7695
                    ret = WOLFSSL_FAILURE;
7696
                    break;
7697
                }
7698
                if (wolfSSL_BIO_write(bio, usageStrs[i],
7699
                                      (int)XSTRLEN(usageStrs[i])) <= 0) {
7700
                    ret = WOLFSSL_FAILURE;
7701
                    break;
7702
                }
7703
            }
7704
        }
7705
        if (ret == WOLFSSL_SUCCESS && wolfSSL_BIO_write(bio, "\n", 1) <= 0) {
7706
            ret = WOLFSSL_FAILURE;
7707
        }
7708
    }
7709
7710
    return ret;
7711
}
7712
7713
static int X509PrintExtendedKeyUsage(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
7714
        int indent)
7715
{
7716
    int ret = WOLFSSL_SUCCESS;
7717
    const int usages[] = {
7718
        EXTKEYUSE_OCSP_SIGN,
7719
        EXTKEYUSE_TIMESTAMP,
7720
        EXTKEYUSE_EMAILPROT,
7721
        EXTKEYUSE_CODESIGN,
7722
        EXTKEYUSE_CLIENT_AUTH,
7723
        EXTKEYUSE_SERVER_AUTH,
7724
        EXTKEYUSE_ANY
7725
    };
7726
    const char* usageStrs[] = {
7727
        "OCSP Signing",
7728
        "Time Stamping",
7729
        "E-mail Protection",
7730
        "Code Signing",
7731
        "TLS Web Client Authentication",
7732
        "TLS Web Server Authentication",
7733
        "Any Extended Key Usage"
7734
    };
7735
7736
    if (bio == NULL || x509 == NULL) {
7737
        ret = WOLFSSL_FAILURE;
7738
    }
7739
7740
    if (ret == WOLFSSL_SUCCESS && x509->extKeyUsageCount > 0
7741
            && x509->extKeyUsage != 0) {
7742
        char scratch[MAX_WIDTH];
7743
        int len;
7744
        word32 i = 0;
7745
        int usageCount = 0;
7746
7747
        len = XSNPRINTF(scratch, MAX_WIDTH, "%*s", indent, "");
7748
        if (len >= MAX_WIDTH)
7749
            ret = WOLFSSL_FAILURE;
7750
        if (ret == WOLFSSL_SUCCESS) {
7751
            if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) {
7752
                ret = WOLFSSL_FAILURE;
7753
            }
7754
        }
7755
        for (; ret == WOLFSSL_SUCCESS && i < sizeof(usages) / sizeof(usages[i]);
7756
             i++) {
7757
            if (x509->extKeyUsage & usages[i]) {
7758
                ++usageCount;
7759
                if (usageCount > 1 && wolfSSL_BIO_write(bio, ", ", 2) <= 0) {
7760
                    ret = WOLFSSL_FAILURE;
7761
                    break;
7762
                }
7763
                if (wolfSSL_BIO_write(bio, usageStrs[i],
7764
                                      (int)XSTRLEN(usageStrs[i])) <= 0) {
7765
                    ret = WOLFSSL_FAILURE;
7766
                    break;
7767
                }
7768
            }
7769
        }
7770
        if (ret == WOLFSSL_SUCCESS && wolfSSL_BIO_write(bio, "\n", 1) <= 0) {
7771
            ret = WOLFSSL_FAILURE;
7772
        }
7773
    }
7774
7775
    return ret;
7776
}
7777
7778
7779
/* print serial number out
7780
 * return WOLFSSL_SUCCESS on success
7781
 */
7782
static int X509PrintSerial_ex(WOLFSSL_BIO* bio, byte* serial, int sz,
7783
        int delimiter, int indent)
7784
{
7785
    char scratch[MAX_WIDTH];
7786
    const int scratchSz = sizeof(scratch);
7787
    int scratchLen;
7788
7789
    if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*sSerial Number:",
7790
                                 indent, "")) >= MAX_WIDTH) {
7791
        WOLFSSL_MSG("buffer overrun");
7792
        return WOLFSSL_FAILURE;
7793
    }
7794
    if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
7795
        return WOLFSSL_FAILURE;
7796
    }
7797
7798
    if (sz > (int)sizeof(byte)) {
7799
        int i;
7800
7801
        /* serial is larger than int size so print off hex values */
7802
        if ((scratchLen = XSNPRINTF(
7803
                 scratch, MAX_WIDTH, "\n%*s", indent + 4, ""))
7804
                >= MAX_WIDTH) {
7805
            WOLFSSL_MSG("buffer overrun");
7806
            return WOLFSSL_FAILURE;
7807
        }
7808
        for (i = 0; i < sz; i++) {
7809
            char val[4];
7810
            int valLen;
7811
7812
            if ((valLen = XSNPRINTF(
7813
                     val, sizeof(val),
7814
                     "%02x%s", serial[i], (i < sz - 1) ?
7815
                     (delimiter ? ":" : "") : "\n"))
7816
                >= (int)sizeof(val)) {
7817
                WOLFSSL_MSG("buffer overrun");
7818
                return WOLFSSL_FAILURE;
7819
            }
7820
            if (scratchLen + valLen >= scratchSz) {
7821
                if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
7822
                    return WOLFSSL_FAILURE;
7823
                }
7824
                scratchLen = 0;
7825
            }
7826
            XMEMCPY(scratch + scratchLen, val, (size_t)valLen);
7827
            scratchLen += valLen;
7828
        }
7829
        if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
7830
            return WOLFSSL_FAILURE;
7831
        }
7832
    }
7833
7834
    /* if serial can fit into byte then print on the same line */
7835
    else  {
7836
        if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, " %d (0x%x)\n",
7837
                (char)serial[0], serial[0])) >= MAX_WIDTH) {
7838
            WOLFSSL_MSG("buffer overrun");
7839
            return WOLFSSL_FAILURE;
7840
        }
7841
        if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
7842
            return WOLFSSL_FAILURE;
7843
        }
7844
    }
7845
    return WOLFSSL_SUCCESS;
7846
}
7847
7848
static int X509PrintSerial(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
7849
{
7850
    unsigned char serial[32];
7851
    int  sz = sizeof(serial);
7852
7853
    if (indent < 0) indent = 0;
7854
    if (indent > MAX_INDENT) indent = MAX_INDENT;
7855
7856
    XMEMSET(serial, 0, sz);
7857
    if (wolfSSL_X509_get_serial_number(x509, serial, &sz) == WOLFSSL_SUCCESS) {
7858
        X509PrintSerial_ex(bio, serial, sz, 1, indent);
7859
    }
7860
    return WOLFSSL_SUCCESS;
7861
}
7862
7863
#ifndef NO_ASN_TIME
7864
static int X509PrintValidity(WOLFSSL_BIO* bio, WOLFSSL_ASN1_TIME * notBefore,
7865
                             WOLFSSL_ASN1_TIME * notAfter, int indent)
7866
{
7867
    char tmp[80];
7868
    (void) indent;
7869
7870
    if (wolfSSL_BIO_write(bio, "        Validity\n",
7871
                  (int)XSTRLEN("        Validity\n")) <= 0) {
7872
        return WOLFSSL_FAILURE;
7873
    }
7874
7875
    if (wolfSSL_BIO_write(bio, "            Not Before: ",
7876
                  (int)XSTRLEN("            Not Before: ")) <= 0) {
7877
        return WOLFSSL_FAILURE;
7878
    }
7879
    if (notBefore->length > 0) {
7880
        if (GetTimeString(notBefore->data, ASN_UTC_TIME,
7881
            tmp, sizeof(tmp), notBefore->length) != WOLFSSL_SUCCESS) {
7882
            if (GetTimeString(notBefore->data, ASN_GENERALIZED_TIME,
7883
            tmp, sizeof(tmp), notBefore->length) != WOLFSSL_SUCCESS) {
7884
                WOLFSSL_MSG("Error getting not before date");
7885
                return WOLFSSL_FAILURE;
7886
            }
7887
        }
7888
    }
7889
    else {
7890
        XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
7891
    }
7892
    tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
7893
    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
7894
        return WOLFSSL_FAILURE;
7895
    }
7896
7897
    if (wolfSSL_BIO_write(bio, "\n            Not After : ",
7898
                  (int)XSTRLEN("\n            Not After : ")) <= 0) {
7899
        return WOLFSSL_FAILURE;
7900
    }
7901
    if (notAfter->length > 0) {
7902
        if (GetTimeString(notAfter->data, ASN_UTC_TIME,
7903
            tmp, sizeof(tmp), notAfter->length) != WOLFSSL_SUCCESS) {
7904
            if (GetTimeString(notAfter->data, ASN_GENERALIZED_TIME,
7905
                tmp, sizeof(tmp), notAfter->length) != WOLFSSL_SUCCESS) {
7906
                WOLFSSL_MSG("Error getting not after date");
7907
                return WOLFSSL_FAILURE;
7908
            }
7909
        }
7910
    }
7911
    else {
7912
        XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
7913
    }
7914
    tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
7915
    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
7916
        return WOLFSSL_FAILURE;
7917
    }
7918
7919
    if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
7920
        return WOLFSSL_FAILURE;
7921
    }
7922
7923
    return WOLFSSL_SUCCESS;
7924
}
7925
#endif /* ifndef NO_ASN_TIME */
7926
7927
static int X509PrintSubjAltName(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
7928
                                int indent)
7929
{
7930
    if (!x509 || !x509->altNames || !x509->subjAltNameSet)
7931
        return WOLFSSL_FAILURE;
7932
    return X509_print_name_entry(bio, x509->altNames, indent);
7933
}
7934
7935
/* print out the signature value in human readable format for use with
7936
 * X509PrintSignature_ex() and X509PrintAltSigVal()
7937
 *
7938
 * return WOLFSSL_SUCCESS on success
7939
 */
7940
static int X509PrintSigHex(WOLFSSL_BIO* bio, byte* sig, int sigSz,
7941
        int indent)
7942
{
7943
    int i;
7944
    int tmpLen = 0;
7945
    char tmp[100];
7946
7947
    if ((tmpLen = XSNPRINTF(tmp, sizeof(tmp), "%*s", indent, ""))
7948
            >= (int)sizeof(tmp) || tmpLen < 0) {
7949
        return WOLFSSL_FAILURE;
7950
    }
7951
7952
    for (i = 0; i < sigSz; i++) {
7953
        char val[6];
7954
        int valLen;
7955
7956
        if (i == 0) {
7957
            if ((valLen = XSNPRINTF(val, sizeof(val), "%02x", sig[i]))
7958
                    >= (int)sizeof(val)) {
7959
                return WOLFSSL_FAILURE;
7960
            }
7961
        }
7962
        else if (((i % 18) == 0)) {
7963
            if (wolfSSL_BIO_write(bio, tmp, tmpLen)
7964
                    <= 0) {
7965
                return WOLFSSL_FAILURE;
7966
            }
7967
            if ((tmpLen = XSNPRINTF(tmp, sizeof(tmp), ":\n%*s",
7968
                    indent, "")) >= (int)sizeof(tmp)) {
7969
                return WOLFSSL_FAILURE;
7970
            }
7971
            if ((valLen = XSNPRINTF(val, sizeof(val), "%02x", sig[i]))
7972
                    >= (int)sizeof(val)) {
7973
                return WOLFSSL_FAILURE;
7974
            }
7975
        }
7976
        else {
7977
            if ((valLen = XSNPRINTF(val, sizeof(val), ":%02x", sig[i]))
7978
                    >= (int)sizeof(val)) {
7979
                return WOLFSSL_FAILURE;
7980
            }
7981
        }
7982
        if ((tmpLen < 0) || (valLen < 0) ||
7983
                (valLen >= ((int)sizeof(tmp) - tmpLen - 1))) {
7984
            return WOLFSSL_FAILURE;
7985
        }
7986
        XMEMCPY(tmp + tmpLen, val, valLen);
7987
        tmpLen += valLen;
7988
        tmp[tmpLen] = 0;
7989
    }
7990
7991
    /* print out remaining sig values */
7992
    if (tmpLen > 0 && wolfSSL_BIO_write(bio, tmp, tmpLen) <= 0) {
7993
        return WOLFSSL_FAILURE;
7994
    }
7995
7996
    return WOLFSSL_SUCCESS;
7997
}
7998
7999
#ifdef WOLFSSL_DUAL_ALG_CERTS
8000
/* print the OID of an unsupported algorithm
8001
 * return WOLFSSL_SUCCESS on success
8002
 */
8003
static int X509PrintAlgOid(WOLFSSL_BIO* bio, const byte* algId, int algIdSz,
8004
        int indent)
8005
{
8006
    char scratch[MAX_WIDTH];
8007
    word32 idx = 0;
8008
    int len;
8009
    int oidSz;
8010
    byte tag;
8011
8012
    /* AlgorithmIdentifier ::= SEQUENCE { algorithm OBJECT IDENTIFIER, ... } */
8013
    if (GetSequence(algId, &idx, &oidSz, (word32)algIdSz) < 0) {
8014
        return WOLFSSL_FAILURE;
8015
    }
8016
    if ((GetASNTag(algId, &idx, &tag, (word32)algIdSz) != 0) ||
8017
            (tag != ASN_OBJECT_ID)) {
8018
        return WOLFSSL_FAILURE;
8019
    }
8020
    if (GetLength(algId, &idx, &oidSz, (word32)algIdSz) < 0) {
8021
        return WOLFSSL_FAILURE;
8022
    }
8023
8024
    /* indent buffer so the OID can be decoded into scratch */
8025
    len = XSNPRINTF(scratch, MAX_WIDTH, "%*s", indent, "");
8026
    if (len < 0 || len >= MAX_WIDTH) {
8027
        return WOLFSSL_FAILURE;
8028
    }
8029
8030
    oidSz = DecodePolicyOID(scratch + len, (word32)(MAX_WIDTH - len),
8031
        algId + idx, (word32)oidSz);
8032
    if (oidSz <= 0) {
8033
        return WOLFSSL_FAILURE;
8034
    }
8035
    len += oidSz;
8036
8037
    if (len + 1 >= MAX_WIDTH) {
8038
        return WOLFSSL_FAILURE;
8039
    }
8040
    scratch[len++] = '\n';
8041
8042
    if (wolfSSL_BIO_write(bio, scratch, len) <= 0) {
8043
        return WOLFSSL_FAILURE;
8044
    }
8045
8046
    return WOLFSSL_SUCCESS;
8047
}
8048
8049
/* print out the alternative public key in human readable format for use with
8050
 * wolfSSL_X509_print()
8051
 * return WOLFSSL_SUCCESS on success
8052
 */
8053
static int X509PrintAltPubKey(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
8054
{
8055
    const unsigned char* der;
8056
    WOLFSSL_EVP_PKEY* pubKey;
8057
    char scratch[MAX_WIDTH];
8058
    int len;
8059
    int ret;
8060
8061
    if (x509->sapkiDer == NULL || x509->sapkiLen <= 0) {
8062
        return WOLFSSL_FAILURE;
8063
    }
8064
8065
    /* convert der to pkey for printing */
8066
    der = (const unsigned char*)x509->sapkiDer;
8067
    pubKey = wolfSSL_d2i_PUBKEY(NULL, &der, x509->sapkiLen);
8068
    if (pubKey != NULL) {
8069
        ret = wolfSSL_EVP_PKEY_print_public(bio, pubKey, indent, NULL);
8070
8071
        wolfSSL_EVP_PKEY_free(pubKey);
8072
8073
        if (ret == WOLFSSL_SUCCESS) {
8074
            return WOLFSSL_SUCCESS;
8075
        }
8076
        if (ret != WC_NO_ERR_TRACE(WOLFSSL_UNKNOWN)) {
8077
            return WOLFSSL_FAILURE;
8078
        }
8079
    }
8080
8081
    /* if the alg is unhandled then still try to print the rest of the cert */
8082
    len = XSNPRINTF(scratch, MAX_WIDTH, "%*sprint not supported\n", indent, "");
8083
    if (len < 0 || len >= MAX_WIDTH) {
8084
        return WOLFSSL_FAILURE;
8085
    }
8086
    if (wolfSSL_BIO_write(bio, scratch, len) <= 0) {
8087
        return WOLFSSL_FAILURE;
8088
    }
8089
8090
    return WOLFSSL_SUCCESS;
8091
}
8092
8093
/* print out the alternative signature algorithm in human readable format for
8094
 * use with wolfSSL_X509_print()
8095
 * return WOLFSSL_SUCCESS on success
8096
 */
8097
static int X509PrintAltSigAlg(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
8098
{
8099
    char scratch[MAX_WIDTH];
8100
    const char* nameStr;
8101
    word32 idx = 0;
8102
    word32 oid = 0;
8103
    int len;
8104
    int ret;
8105
8106
    if (x509->altSigAlgDer == NULL || x509->altSigAlgLen <= 0) {
8107
        return WOLFSSL_FAILURE;
8108
    }
8109
8110
    /* have an AlgorithmIdentifier, so look up the algo name */
8111
    ret = GetAlgoId(x509->altSigAlgDer, &idx, &oid, oidSigType,
8112
            (word32)x509->altSigAlgLen);
8113
    if (ret == WC_NO_ERR_TRACE(ASN_UNKNOWN_OID_E)) {
8114
        /* encoding is well formed, so print the OID */
8115
        return X509PrintAlgOid(bio, x509->altSigAlgDer, x509->altSigAlgLen,
8116
            indent);
8117
    }
8118
    if (ret < 0) {
8119
        return WOLFSSL_FAILURE;
8120
    }
8121
8122
    nameStr = wolfSSL_OBJ_nid2ln(oid2nid(oid, oidSigType));
8123
    if (nameStr == NULL) {
8124
        /* no name, so print the OID instead */
8125
        return X509PrintAlgOid(bio, x509->altSigAlgDer, x509->altSigAlgLen,
8126
            indent);
8127
    }
8128
8129
    len = XSNPRINTF(scratch, MAX_WIDTH, "%*s%s\n", indent, "", nameStr);
8130
    if (len < 0 || len >= MAX_WIDTH) {
8131
        return WOLFSSL_FAILURE;
8132
    }
8133
    if (wolfSSL_BIO_write(bio, scratch, len) <= 0) {
8134
        return WOLFSSL_FAILURE;
8135
    }
8136
8137
    return WOLFSSL_SUCCESS;
8138
}
8139
8140
/* print out the alternative signature value in human readable format for use
8141
 * with wolfSSL_X509_print()
8142
 * return WOLFSSL_SUCCESS on success
8143
 */
8144
static int X509PrintAltSigVal(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
8145
{
8146
    if (x509->altSigValDer == NULL || x509->altSigValLen <= 0) {
8147
        return WOLFSSL_FAILURE;
8148
    }
8149
8150
    /* DecodeAltSigVal() already stepped over the BIT STRING header */
8151
    if (X509PrintSigHex(bio, x509->altSigValDer, x509->altSigValLen, indent)
8152
            != WOLFSSL_SUCCESS) {
8153
        return WOLFSSL_FAILURE;
8154
    }
8155
8156
    /* X509PrintSigHex omits the trailing newline */
8157
    if (wolfSSL_BIO_write(bio, "\n", 1) <= 0) {
8158
        return WOLFSSL_FAILURE;
8159
    }
8160
8161
    return WOLFSSL_SUCCESS;
8162
}
8163
#endif /* WOLFSSL_DUAL_ALG_CERTS */
8164
8165
/* iterate through certificate extensions printing them out in human readable
8166
 * form
8167
 * return WOLFSSL_SUCCESS on success
8168
 */
8169
static int X509PrintExtensions(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
8170
{
8171
    int  ret = WOLFSSL_SUCCESS;
8172
    char scratch[MAX_WIDTH];
8173
    const int scratchSz = sizeof(scratch);
8174
    int scratchLen;
8175
    int  count, i;
8176
    char* buf = NULL;
8177
8178
    if (indent < 0) indent = 0;
8179
    if (indent > MAX_INDENT) indent = MAX_INDENT;
8180
8181
    count = wolfSSL_X509_get_ext_count(x509);
8182
    if (count <= 0)
8183
        return WOLFSSL_SUCCESS;
8184
8185
#ifdef WOLFSSL_CERT_REQ
8186
    if (x509->isCSR) {
8187
        if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*s%s\n", indent, "",
8188
                      "Requested extensions:")) >= MAX_WIDTH) {
8189
            return WOLFSSL_FAILURE;
8190
        }
8191
    }
8192
    else
8193
#endif
8194
    {
8195
        if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*s%s\n", indent, "",
8196
                                     "X509v3 extensions:")) >= MAX_WIDTH) {
8197
            return WOLFSSL_FAILURE;
8198
        }
8199
    }
8200
    if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
8201
        return WOLFSSL_FAILURE;
8202
    }
8203
8204
    buf = (char*)XMALLOC(MAX_WIDTH, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
8205
    if (buf == NULL) {
8206
        return WOLFSSL_FAILURE;
8207
    }
8208
8209
    for (i = 0; (i < count) && (ret != WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); i++) {
8210
        WOLFSSL_X509_EXTENSION* ext;
8211
8212
        ext = wolfSSL_X509_get_ext(x509, i);
8213
        if (ext != NULL) {
8214
            WOLFSSL_ASN1_OBJECT* obj;
8215
            int nid;
8216
            char val[6];
8217
            int valLen;
8218
            word32 j;
8219
8220
            obj = wolfSSL_X509_EXTENSION_get_object(ext);
8221
            if (obj == NULL) {
8222
                ret = WOLFSSL_FAILURE;
8223
                break;
8224
            }
8225
            if (wolfSSL_OBJ_obj2txt(buf, MAX_WIDTH, obj, 0)
8226
                == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
8227
            {
8228
                ret = WOLFSSL_FAILURE;
8229
                break;
8230
            }
8231
            if ((scratchLen = XSNPRINTF(
8232
                     scratch, MAX_WIDTH, "%*s", indent + 4, "")) >= MAX_WIDTH)
8233
            {
8234
                ret = WOLFSSL_FAILURE;
8235
                break;
8236
            }
8237
            if ((wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) ||
8238
                (wolfSSL_BIO_write(bio, buf, (int)XSTRLEN(buf)) <= 0)) {
8239
                ret = WOLFSSL_FAILURE;
8240
                break;
8241
            }
8242
            if ((scratchLen = XSNPRINTF(
8243
                     scratch, MAX_WIDTH, "%s\n",
8244
                     (wolfSSL_X509_EXTENSION_get_critical(ext)
8245
                      ? ": critical"
8246
                      : ": ")))
8247
                >= MAX_WIDTH)
8248
            {
8249
                ret = WOLFSSL_FAILURE;
8250
                break;
8251
            }
8252
8253
            if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
8254
                ret = WOLFSSL_FAILURE;
8255
                break;
8256
            }
8257
            nid = wolfSSL_OBJ_obj2nid(obj);
8258
            switch (nid) {
8259
            case WC_NID_subject_alt_name:
8260
                ret = X509PrintSubjAltName(bio, x509, indent + 8);
8261
                break;
8262
8263
            case WC_NID_subject_key_identifier:
8264
                if (!x509->subjKeyIdSet || x509->subjKeyId == NULL ||
8265
                    x509->subjKeyIdSz == 0)
8266
                {
8267
                    ret = WOLFSSL_FAILURE;
8268
                    break;
8269
                }
8270
8271
                if ((scratchLen = XSNPRINTF(
8272
                         scratch, scratchSz,
8273
                         "%*s", indent + 8, "")) >= scratchSz)
8274
                {
8275
                    ret = WOLFSSL_FAILURE;
8276
                    break;
8277
                }
8278
                for (j = 0; j < x509->subjKeyIdSz; j++) {
8279
                    if ((valLen = XSNPRINTF(
8280
                             val, sizeof(val), "%02X%s",
8281
                             x509->subjKeyId[j],
8282
                             (j < x509->subjKeyIdSz - 1) ? ":" : "\n"))
8283
                        >= (int)sizeof(val))
8284
                    {
8285
                        ret = WOLFSSL_FAILURE;
8286
                        break;
8287
                    }
8288
                    if (scratchLen + valLen >= scratchSz) {
8289
                        if (wolfSSL_BIO_write(bio, scratch,
8290
                                              scratchLen) <= 0) {
8291
                            ret = WOLFSSL_FAILURE;
8292
                            break;
8293
                        }
8294
                        scratchLen = 0;
8295
                    }
8296
                    XMEMCPY(scratch + scratchLen, val, valLen);
8297
                    scratchLen += valLen;
8298
                }
8299
                if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
8300
                    break;
8301
                if (wolfSSL_BIO_write(bio, scratch,
8302
                                      scratchLen) <= 0) {
8303
                    ret = WOLFSSL_FAILURE;
8304
                    break;
8305
                }
8306
                break;
8307
8308
            case WC_NID_authority_key_identifier:
8309
                if (!x509->authKeyIdSet || x509->authKeyId == NULL ||
8310
                    x509->authKeyIdSz == 0) {
8311
                    ret = WOLFSSL_FAILURE;
8312
                    break;
8313
                }
8314
8315
                if ((scratchLen = XSNPRINTF(
8316
                         scratch, scratchSz, "%*s%s",
8317
                         indent + 8, "", "keyid:")) >= scratchSz)
8318
                {
8319
                    ret = WOLFSSL_FAILURE;
8320
                    break;
8321
                }
8322
                for (j = 0; j < x509->authKeyIdSz; j++) {
8323
                    if ((valLen = XSNPRINTF(
8324
                             val, sizeof(val), "%02X%s",
8325
                             x509->authKeyId[j],
8326
                             (j < x509->authKeyIdSz - 1) ? ":" : "\n\n"))
8327
                        >= (int)sizeof(val))
8328
                    {
8329
                        ret = WOLFSSL_FAILURE;
8330
                        break;
8331
                    }
8332
                    if (scratchLen >= scratchSz - valLen) {
8333
                        if (wolfSSL_BIO_write(bio, scratch,
8334
                                              scratchLen) <= 0)
8335
                        {
8336
                            ret = WOLFSSL_FAILURE;
8337
                            break;
8338
                        }
8339
                        scratchLen = 0;
8340
                    }
8341
                    if (scratchLen + valLen >= scratchSz) {
8342
                        ret = WOLFSSL_FAILURE;
8343
                        break;
8344
                    }
8345
                    XMEMCPY(scratch + scratchLen, val, valLen);
8346
                    scratchLen += valLen;
8347
                }
8348
                if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
8349
                    break;
8350
                if (wolfSSL_BIO_write(bio, scratch,
8351
                                      scratchLen) <= 0) {
8352
                    ret = WOLFSSL_FAILURE;
8353
                    break;
8354
                }
8355
                break;
8356
8357
            case WC_NID_basic_constraints:
8358
                if (!x509->basicConstSet) {
8359
                    ret = WOLFSSL_FAILURE;
8360
                    break;
8361
                }
8362
                /* Match OpenSSL output: print "CA:TRUE"/"CA:FALSE" and append
8363
                 * ", pathlen:N" only when a pathLenConstraint is present
8364
                 * (RFC 5280 4.2.1.9). An absent constraint imposes no limit
8365
                 * and must not be shown as pathlen:0. */
8366
                if (x509->basicConstPlSet) {
8367
                    scratchLen = XSNPRINTF(scratch, scratchSz,
8368
                        "%*sCA:%s, pathlen:%u\n",
8369
                        indent + 8, "", (x509->isCa) ? "TRUE" : "FALSE",
8370
                        (unsigned int)x509->pathLength);
8371
                }
8372
                else {
8373
                    scratchLen = XSNPRINTF(scratch, scratchSz,
8374
                        "%*sCA:%s\n",
8375
                        indent + 8, "", (x509->isCa) ? "TRUE" : "FALSE");
8376
                }
8377
                if (scratchLen >= scratchSz) {
8378
                    ret = WOLFSSL_FAILURE;
8379
                    break;
8380
                }
8381
                if (wolfSSL_BIO_write(bio, scratch,
8382
                                      scratchLen) <= 0) {
8383
                    ret = WOLFSSL_FAILURE;
8384
                    break;
8385
                }
8386
                break;
8387
8388
            case WC_NID_key_usage:
8389
                ret = X509PrintKeyUsage(bio, x509, indent + 8);
8390
                break;
8391
8392
            case WC_NID_ext_key_usage:
8393
                ret = X509PrintExtendedKeyUsage(bio, x509, indent + 8);
8394
                break;
8395
8396
        #ifdef WOLFSSL_DUAL_ALG_CERTS
8397
            case WC_NID_subject_alt_public_key_info:
8398
                ret = X509PrintAltPubKey(bio, x509, indent + 8);
8399
                break;
8400
8401
            case WC_NID_alt_signature_algorithm:
8402
                ret = X509PrintAltSigAlg(bio, x509, indent + 8);
8403
                break;
8404
8405
            case WC_NID_alt_signature_value:
8406
                ret = X509PrintAltSigVal(bio, x509, indent + 8);
8407
                break;
8408
        #endif
8409
8410
            default:
8411
                /* extension nid not yet supported */
8412
                if ((scratchLen = XSNPRINTF(
8413
                         scratch, MAX_WIDTH,
8414
                         "%*sNID %d print not yet supported\n",
8415
                         indent + 8, "", nid)) >= MAX_WIDTH)
8416
                {
8417
                    ret = WOLFSSL_FAILURE;
8418
                    break;
8419
                }
8420
8421
                if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
8422
                    ret = WOLFSSL_FAILURE;
8423
                    break;
8424
                }
8425
            }
8426
        }
8427
    }
8428
8429
    XFREE(buf, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
8430
8431
    return ret;
8432
}
8433
8434
/* print out the signature in human readable format for use with
8435
 * wolfSSL_X509_print()
8436
 * return WOLFSSL_SUCCESS on success
8437
 */
8438
static int X509PrintSignature_ex(WOLFSSL_BIO* bio, byte* sig,
8439
        int sigSz, int sigNid, int algOnly, int indent)
8440
{
8441
    char scratch[MAX_WIDTH];
8442
    int scratchLen;
8443
    WOLFSSL_ASN1_OBJECT* obj = NULL;
8444
    int ret = WOLFSSL_SUCCESS;
8445
    char tmp[100];
8446
    int tmpLen = 0;
8447
8448
    if (sigSz <= 0) {
8449
        return WOLFSSL_SUCCESS;
8450
    }
8451
8452
    if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*s%s", indent, "",
8453
                                "Signature Algorithm: ")) >= MAX_WIDTH) {
8454
        ret = WOLFSSL_FAILURE;
8455
    }
8456
8457
    if (ret == WOLFSSL_SUCCESS) {
8458
        if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0)
8459
            ret = WOLFSSL_FAILURE;
8460
    }
8461
8462
    if (ret == WOLFSSL_SUCCESS) {
8463
        obj = wolfSSL_OBJ_nid2obj(sigNid);
8464
        if (obj == NULL)
8465
            ret = WOLFSSL_FAILURE;
8466
    }
8467
    if (ret == WOLFSSL_SUCCESS) {
8468
        if (wolfSSL_OBJ_obj2txt(scratch, MAX_WIDTH, obj, 0)
8469
            == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
8470
        {
8471
            ret = WOLFSSL_FAILURE;
8472
        }
8473
    }
8474
8475
    if (ret == WOLFSSL_SUCCESS) {
8476
        if ((tmpLen = XSNPRINTF(tmp, sizeof(tmp),"%s\n", scratch))
8477
            >= (int)sizeof(tmp))
8478
        {
8479
            ret = WOLFSSL_FAILURE;
8480
        }
8481
    }
8482
    if (ret == WOLFSSL_SUCCESS) {
8483
        if (wolfSSL_BIO_write(bio, tmp, tmpLen) <= 0)
8484
            ret = WOLFSSL_FAILURE;
8485
    }
8486
8487
    /* Leave function if the desired content to print
8488
     * is only the signature algorithm */
8489
    if (algOnly) {
8490
        if (obj != NULL)
8491
            wolfSSL_ASN1_OBJECT_free(obj);
8492
8493
        return ret;
8494
    }
8495
8496
    if (ret == WOLFSSL_SUCCESS) {
8497
        ret = X509PrintSigHex(bio, sig, sigSz, indent + 5);
8498
    }
8499
8500
    if (obj != NULL)
8501
        wolfSSL_ASN1_OBJECT_free(obj);
8502
8503
    return ret;
8504
}
8505
8506
static int X509PrintSignature(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
8507
        int algOnly, int indent)
8508
{
8509
    int sigSz = 0;
8510
    if (wolfSSL_X509_get_signature(x509, NULL, &sigSz) <= 0) {
8511
        return WOLFSSL_FAILURE;
8512
    }
8513
8514
    if (sigSz > 0) {
8515
        unsigned char* sig;
8516
        int sigNid;
8517
8518
        sigNid = wolfSSL_X509_get_signature_nid(x509);
8519
        if (sigNid <= 0) {
8520
            return WOLFSSL_FAILURE;
8521
        }
8522
8523
        sig = (unsigned char*)XMALLOC(sigSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8524
        if (sig == NULL) {
8525
            return WOLFSSL_FAILURE;
8526
        }
8527
8528
        if (wolfSSL_X509_get_signature(x509, sig, &sigSz) <= 0) {
8529
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8530
            return WOLFSSL_FAILURE;
8531
        }
8532
8533
        if (X509PrintSignature_ex(bio, sig, sigSz, sigNid, algOnly, indent)
8534
                != WOLFSSL_SUCCESS) {
8535
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8536
            return WOLFSSL_FAILURE;
8537
        }
8538
8539
        XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8540
8541
    }
8542
8543
    return WOLFSSL_SUCCESS;
8544
}
8545
8546
8547
/* print out the public key in human readable format for use with
8548
 * wolfSSL_X509_print()
8549
 * return WOLFSSL_SUCCESS on success
8550
 */
8551
static int X509PrintPubKey(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
8552
{
8553
    char scratch[MAX_WIDTH];
8554
    const char* nameStr;
8555
    WOLFSSL_EVP_PKEY* pubKey;
8556
    int len;
8557
    int ret = WOLFSSL_SUCCESS;
8558
8559
    if (indent < 0) indent = 0;
8560
    if (indent > MAX_INDENT) indent = MAX_INDENT;
8561
8562
    if (bio == NULL || x509 == NULL)
8563
        return BAD_FUNC_ARG;
8564
8565
    len = XSNPRINTF(scratch, MAX_WIDTH, "%*sSubject Public Key Info:\n", indent,
8566
        "");
8567
    if (len < 0 || len >= MAX_WIDTH)
8568
        return WOLFSSL_FAILURE;
8569
    if (wolfSSL_BIO_write(bio, scratch, len) <= 0)
8570
        return WOLFSSL_FAILURE;
8571
8572
    /* get the alg string associated with the OID */
8573
    nameStr = wolfSSL_OBJ_nid2ln(oid2nid((word32)x509->pubKeyOID, oidKeyType));
8574
    if (nameStr == NULL)
8575
        return WOLFSSL_FAILURE;
8576
8577
    len = XSNPRINTF(scratch, MAX_WIDTH, "%*sPublic Key Algorithm: %s\n",
8578
        indent + 4, "", nameStr);
8579
    if (len < 0 || len >= MAX_WIDTH)
8580
        return WOLFSSL_FAILURE;
8581
    if (wolfSSL_BIO_write(bio, scratch, len) <= 0)
8582
        return WOLFSSL_FAILURE;
8583
8584
    pubKey = wolfSSL_X509_get_pubkey(x509);
8585
    if (pubKey == NULL)
8586
        return WOLFSSL_FAILURE;
8587
8588
    ret = wolfSSL_EVP_PKEY_print_public(bio, pubKey, indent + 8, NULL);
8589
8590
    wolfSSL_EVP_PKEY_free(pubKey);
8591
8592
    if (ret == WOLFSSL_SUCCESS)
8593
        return WOLFSSL_SUCCESS;
8594
    if (ret != WC_NO_ERR_TRACE(WOLFSSL_UNKNOWN))
8595
        return WOLFSSL_FAILURE;
8596
8597
    /* if the alg is unhandled then still try to print the rest of the cert */
8598
    len = XSNPRINTF(scratch, MAX_WIDTH, "%*sprint not supported\n", indent + 8,
8599
        "");
8600
    if (len < 0 || len >= MAX_WIDTH)
8601
        return WOLFSSL_FAILURE;
8602
    if (wolfSSL_BIO_write(bio, scratch, len) <= 0)
8603
        return WOLFSSL_FAILURE;
8604
8605
    return WOLFSSL_SUCCESS;
8606
}
8607
8608
8609
/* human readable print out of x509 name formatted for use with
8610
 * wolfSSL_X509_print()
8611
 * return WOLFSSL_SUCCESS on success
8612
 */
8613
static int X509PrintName(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name,
8614
        char* type, int indent)
8615
{
8616
    if (name != NULL) {
8617
        char scratch[MAX_WIDTH];
8618
        int scratchLen;
8619
8620
        if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH,
8621
                                     "%*s%s", indent, "", type))
8622
            >= MAX_WIDTH)
8623
        {
8624
            return WOLFSSL_FAILURE;
8625
        }
8626
        if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
8627
            return WOLFSSL_FAILURE;
8628
        }
8629
        if (wolfSSL_X509_NAME_print_ex(bio, name, 1,
8630
                WOLFSSL_ASN1_STRFLGS_ESC_CTRL) <= 0) {
8631
            return WOLFSSL_FAILURE;
8632
        }
8633
        if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) {
8634
            return WOLFSSL_FAILURE;
8635
        }
8636
    }
8637
    return WOLFSSL_SUCCESS;
8638
}
8639
8640
8641
/* human readable print out of x509 version
8642
 * return WOLFSSL_SUCCESS on success
8643
 */
8644
static int X509PrintVersion(WOLFSSL_BIO* bio, int version, int indent)
8645
{
8646
    char scratch[MAX_WIDTH];
8647
    int scratchLen;
8648
8649
    if (indent < 0) indent = 0;
8650
    if (indent > MAX_INDENT) indent = MAX_INDENT;
8651
8652
    scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*s%s", indent, "", "Version:");
8653
    if ((scratchLen < 0) || (scratchLen >= MAX_WIDTH)) {
8654
        return WOLFSSL_FAILURE;
8655
    }
8656
8657
    if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
8658
        return WOLFSSL_FAILURE;
8659
    }
8660
8661
    scratchLen = XSNPRINTF(scratch, MAX_WIDTH, " %d (0x%x)\n",
8662
                    version, (byte)version-1);
8663
    if ((scratchLen < 0) || (scratchLen >= MAX_WIDTH)) {
8664
        return WOLFSSL_FAILURE;
8665
    }
8666
8667
    if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
8668
        return WOLFSSL_FAILURE;
8669
    }
8670
    return WOLFSSL_SUCCESS;
8671
}
8672
8673
#ifdef WOLFSSL_CERT_REQ
8674
/* Print out of REQ attributes
8675
 * return WOLFSSL_SUCCESS on success
8676
 */
8677
static int X509PrintReqAttributes(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
8678
        int indent)
8679
{
8680
    WOLFSSL_X509_ATTRIBUTE* attr;
8681
    char scratch[MAX_WIDTH];
8682
    int scratchLen;
8683
    int i = 0;
8684
8685
    if (indent < 0) indent = 0;
8686
    if (indent > MAX_INDENT) indent = MAX_INDENT;
8687
8688
    if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH,
8689
                                 "%*s%s", indent, "", "Attributes: \n"))
8690
        >= MAX_WIDTH)
8691
    {
8692
        return WOLFSSL_FAILURE;
8693
    }
8694
    if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
8695
        return WOLFSSL_FAILURE;
8696
    }
8697
    do {
8698
        attr = wolfSSL_X509_REQ_get_attr(x509, i);
8699
        if (attr != NULL) {
8700
            char lName[NAME_SZ/4]; /* NAME_SZ default is 80 */
8701
            int lNameSz = NAME_SZ/4;
8702
            const byte* data;
8703
8704
            if (wolfSSL_OBJ_obj2txt(lName, lNameSz, attr->object, 0)
8705
                == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
8706
            {
8707
                return WOLFSSL_FAILURE;
8708
            }
8709
            lNameSz = (int)XSTRLEN(lName);
8710
            data = wolfSSL_ASN1_STRING_get0_data(
8711
                    attr->value->value.asn1_string);
8712
            if (data == NULL) {
8713
                WOLFSSL_MSG("No REQ attribute found when expected");
8714
                return WOLFSSL_FAILURE;
8715
            }
8716
            if (XSNPRINTF(scratch, MAX_WIDTH,
8717
                          "%*s%s%*s:", indent+4, "",
8718
                          lName, (NAME_SZ/4)-lNameSz, "")
8719
                >= MAX_WIDTH)
8720
            {
8721
                return WOLFSSL_FAILURE;
8722
            }
8723
            if ((X509PrintEscStr(bio, scratch, (const char*)data,
8724
                    wolfSSL_ASN1_STRING_length(
8725
                        attr->value->value.asn1_string)) != WOLFSSL_SUCCESS) ||
8726
                (wolfSSL_BIO_write(bio, "\n", 1) <= 0)) {
8727
                WOLFSSL_MSG("Error writing REQ attribute");
8728
                return WOLFSSL_FAILURE;
8729
            }
8730
        }
8731
        i++;
8732
    } while (attr != NULL);
8733
8734
    return WOLFSSL_SUCCESS;
8735
}
8736
8737
8738
/*
8739
 * return WOLFSSL_SUCCESS on success
8740
 */
8741
int wolfSSL_X509_REQ_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
8742
{
8743
    char subjType[] = "Subject: ";
8744
8745
    if (bio == NULL || x509 == NULL) {
8746
        return WOLFSSL_FAILURE;
8747
    }
8748
8749
    if (wolfSSL_BIO_write(bio, "Certificate Request:\n",
8750
                  (int)XSTRLEN("Certificate Request:\n")) <= 0) {
8751
            return WOLFSSL_FAILURE;
8752
    }
8753
8754
    if (wolfSSL_BIO_write(bio, "    Data:\n",
8755
                  (int)XSTRLEN("    Data:\n")) <= 0) {
8756
            return WOLFSSL_FAILURE;
8757
    }
8758
8759
    /* print version of cert.  Note that we increment by 1 because for REQs,
8760
     * the value stored in x509->version is the actual value of the field; not
8761
     * the version. */
8762
    if (X509PrintVersion(bio, (int)wolfSSL_X509_REQ_get_version(x509) + 1, 8)
8763
            != WOLFSSL_SUCCESS) {
8764
        return WOLFSSL_FAILURE;
8765
    }
8766
8767
    if (X509PrintSerial(bio, x509, 8) != WOLFSSL_SUCCESS) {
8768
        return WOLFSSL_FAILURE;
8769
    }
8770
8771
    /* print subject */
8772
    if (X509PrintName(bio, wolfSSL_X509_get_subject_name(x509), subjType, 8)
8773
            != WOLFSSL_SUCCESS) {
8774
        return WOLFSSL_FAILURE;
8775
    }
8776
8777
    /* get and print public key */
8778
    if (X509PrintPubKey(bio, x509, 8) != WOLFSSL_SUCCESS) {
8779
        return WOLFSSL_FAILURE;
8780
    }
8781
8782
    /* print out extensions */
8783
    if (X509PrintExtensions(bio, x509, 4) != WOLFSSL_SUCCESS) {
8784
        return WOLFSSL_FAILURE;
8785
    }
8786
8787
    /* print out req attributes */
8788
    if (X509PrintReqAttributes(bio, x509, 4) != WOLFSSL_SUCCESS) {
8789
        return WOLFSSL_FAILURE;
8790
    }
8791
8792
    /* print out signature */
8793
    if (X509PrintSignature(bio, x509, 0, 4) != WOLFSSL_SUCCESS) {
8794
        return WOLFSSL_FAILURE;
8795
    }
8796
8797
    /* done with print out */
8798
    if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
8799
        return WOLFSSL_FAILURE;
8800
    }
8801
8802
    return WOLFSSL_SUCCESS;
8803
}
8804
#endif /* WOLFSSL_CERT_REQ */
8805
8806
8807
/* Writes the human readable form of x509 to bio.
8808
 *
8809
 * bio  WOLFSSL_BIO to write to.
8810
 * x509 Certificate to write.
8811
 *
8812
 * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
8813
 */
8814
int wolfSSL_X509_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
8815
    unsigned long nmflags, unsigned long cflag)
8816
{
8817
    char issuType[] = "Issuer:";
8818
    char subjType[] = "Subject:";
8819
8820
    WOLFSSL_ENTER("wolfSSL_X509_print_ex");
8821
8822
    /* flags currently not supported */
8823
    (void)nmflags;
8824
    (void)cflag;
8825
8826
    if (bio == NULL || x509 == NULL) {
8827
        return WOLFSSL_FAILURE;
8828
    }
8829
8830
    if (wolfSSL_BIO_write(bio, "Certificate:\n",
8831
                  (int)XSTRLEN("Certificate:\n")) <= 0) {
8832
            return WOLFSSL_FAILURE;
8833
    }
8834
8835
    if (wolfSSL_BIO_write(bio, "    Data:\n",
8836
                  (int)XSTRLEN("    Data:\n")) <= 0) {
8837
            return WOLFSSL_FAILURE;
8838
    }
8839
8840
    /* print version of cert */
8841
    if (X509PrintVersion(bio, wolfSSL_X509_version(x509), 8)
8842
            != WOLFSSL_SUCCESS) {
8843
        return WOLFSSL_FAILURE;
8844
    }
8845
8846
    /* print serial number out */
8847
    if (X509PrintSerial(bio, x509, 8) != WOLFSSL_SUCCESS) {
8848
        return WOLFSSL_FAILURE;
8849
    }
8850
8851
    /* print out signature algo*/
8852
    if (X509PrintSignature(bio, x509, 1, 8) != WOLFSSL_SUCCESS) {
8853
        return WOLFSSL_FAILURE;
8854
    }
8855
8856
    /* print issuer */
8857
    if (X509PrintName(bio, wolfSSL_X509_get_issuer_name(x509), issuType, 8)
8858
            != WOLFSSL_SUCCESS) {
8859
        return WOLFSSL_FAILURE;
8860
    }
8861
8862
    #ifndef NO_ASN_TIME
8863
    /* print validity */
8864
    if (X509PrintValidity(bio, &x509->notBefore, &x509->notAfter, 8)
8865
        != WOLFSSL_SUCCESS) {
8866
        return WOLFSSL_FAILURE;
8867
    }
8868
    #endif /* NO_ASN_TIME */
8869
8870
    /* print subject */
8871
    if (X509PrintName(bio, wolfSSL_X509_get_subject_name(x509), subjType, 8)
8872
            != WOLFSSL_SUCCESS) {
8873
        return WOLFSSL_FAILURE;
8874
    }
8875
8876
    /* get and print public key */
8877
    if (X509PrintPubKey(bio, x509, 8) != WOLFSSL_SUCCESS) {
8878
        return WOLFSSL_FAILURE;
8879
    }
8880
8881
    /* print out extensions */
8882
    if (X509PrintExtensions(bio, x509, 8) != WOLFSSL_SUCCESS) {
8883
        return WOLFSSL_FAILURE;
8884
    }
8885
8886
    /* print out signature */
8887
    if (X509PrintSignature(bio, x509, 0, 4) != WOLFSSL_SUCCESS) {
8888
        return WOLFSSL_FAILURE;
8889
    }
8890
8891
    /* done with print out */
8892
    if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
8893
        return WOLFSSL_FAILURE;
8894
    }
8895
8896
    return WOLFSSL_SUCCESS;
8897
}
8898
int wolfSSL_X509_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
8899
{
8900
    return wolfSSL_X509_print_ex(bio, x509, 0, 0);
8901
}
8902
8903
#if defined(WOLFSSL_ACERT)
8904
/* Retrieve sig NID from an ACERT.
8905
 *
8906
 * returns  NID on success
8907
 * returns  0 on failure
8908
 */
8909
int wolfSSL_X509_ACERT_get_signature_nid(const WOLFSSL_X509_ACERT *x509)
8910
{
8911
    if (x509 == NULL) {
8912
        return 0;
8913
    }
8914
8915
    return oid2nid((word32)x509->sigOID, oidSigType);
8916
}
8917
8918
static int X509AcertPrintSignature(WOLFSSL_BIO* bio, WOLFSSL_X509_ACERT* x509,
8919
                                   int algOnly, int indent)
8920
{
8921
    int sigSz = 0;
8922
    if (wolfSSL_X509_ACERT_get_signature(x509, NULL, &sigSz) <= 0) {
8923
        return WOLFSSL_FAILURE;
8924
    }
8925
8926
    if (sigSz > 0) {
8927
        unsigned char* sig;
8928
        int sigNid;
8929
8930
        sigNid = wolfSSL_X509_ACERT_get_signature_nid(x509);
8931
        if (sigNid <= 0) {
8932
            return WOLFSSL_FAILURE;
8933
        }
8934
8935
        sig = (unsigned char*)XMALLOC(sigSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8936
        if (sig == NULL) {
8937
            return WOLFSSL_FAILURE;
8938
        }
8939
8940
        if (wolfSSL_X509_ACERT_get_signature(x509, sig, &sigSz) <= 0) {
8941
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8942
            return WOLFSSL_FAILURE;
8943
        }
8944
8945
        if (X509PrintSignature_ex(bio, sig, sigSz, sigNid, algOnly, indent)
8946
                != WOLFSSL_SUCCESS) {
8947
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8948
            return WOLFSSL_FAILURE;
8949
        }
8950
8951
        if (sig != NULL) {
8952
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8953
        }
8954
8955
    }
8956
8957
    return WOLFSSL_SUCCESS;
8958
}
8959
8960
static int X509AcertPrintSerial(WOLFSSL_BIO* bio, WOLFSSL_X509_ACERT* x509,
8961
                                int indent)
8962
{
8963
    unsigned char serial[32];
8964
    int  sz = sizeof(serial);
8965
8966
    XMEMSET(serial, 0, sz);
8967
    if (wolfSSL_X509_ACERT_get_serial_number(x509, serial, &sz)
8968
        == WOLFSSL_SUCCESS) {
8969
        X509PrintSerial_ex(bio, serial, sz, 1, indent);
8970
    }
8971
    return WOLFSSL_SUCCESS;
8972
}
8973
8974
int wolfSSL_X509_ACERT_print(WOLFSSL_BIO* bio, WOLFSSL_X509_ACERT* x509)
8975
{
8976
    const char * hdr =                "Attribute Certificate:\n";
8977
    const char * data_hdr =           "    Data:\n";
8978
    const char * holder_hdr =         "        Holder:\n";
8979
    const char * holder_issuer_hdr =  "            Issuer:";
8980
    const char * holder_name_hdr =    "            Name:";
8981
    const char * attcert_issuer_hdr = "        Issuer:";
8982
8983
    if (bio == NULL || x509 == NULL) {
8984
        return WOLFSSL_FAILURE;
8985
    }
8986
8987
    /* print acert header */
8988
    if (wolfSSL_BIO_write(bio, hdr, (int)XSTRLEN(hdr)) <= 0) {
8989
        return WOLFSSL_FAILURE;
8990
    }
8991
8992
    /* print data header */
8993
    if (wolfSSL_BIO_write(bio, data_hdr, (int)XSTRLEN(data_hdr)) <= 0) {
8994
        return WOLFSSL_FAILURE;
8995
    }
8996
8997
    /* print version of cert */
8998
    if (X509PrintVersion(bio, wolfSSL_X509_ACERT_version(x509), 8)
8999
            != WOLFSSL_SUCCESS) {
9000
        return WOLFSSL_FAILURE;
9001
    }
9002
9003
    /* print serial number out */
9004
    if (X509AcertPrintSerial(bio, x509, 8) != WOLFSSL_SUCCESS) {
9005
        return WOLFSSL_FAILURE;
9006
    }
9007
9008
    /* print holder field */
9009
    if (wolfSSL_BIO_write(bio, holder_hdr, (int)XSTRLEN(holder_hdr)) <= 0) {
9010
        return WOLFSSL_FAILURE;
9011
    }
9012
9013
    if (x509->holderEntityName != NULL) {
9014
        /* print issuer header */
9015
        if (wolfSSL_BIO_write(bio, holder_name_hdr,
9016
            (int)XSTRLEN(holder_name_hdr)) <= 0) {
9017
            return WOLFSSL_FAILURE;
9018
        }
9019
9020
        if (X509_print_name_entry(bio, x509->holderEntityName, 1)
9021
                != WOLFSSL_SUCCESS) {
9022
            return WOLFSSL_FAILURE;
9023
        }
9024
    }
9025
9026
    if (x509->holderIssuerName != NULL) {
9027
        /* print issuer header */
9028
        if (wolfSSL_BIO_write(bio, holder_issuer_hdr,
9029
            (int)XSTRLEN(holder_issuer_hdr)) <= 0) {
9030
            return WOLFSSL_FAILURE;
9031
        }
9032
9033
        if (X509_print_name_entry(bio, x509->holderIssuerName, 1)
9034
            != WOLFSSL_SUCCESS) {
9035
            return WOLFSSL_FAILURE;
9036
        }
9037
    }
9038
9039
    if (x509->holderSerialSz > 0) {
9040
        X509PrintSerial_ex(bio, x509->holderSerial, x509->holderSerialSz,
9041
                           1, 12);
9042
    }
9043
9044
    /* print issuer header */
9045
    if (wolfSSL_BIO_write(bio, attcert_issuer_hdr,
9046
        (int)XSTRLEN(attcert_issuer_hdr)) <= 0) {
9047
        return WOLFSSL_FAILURE;
9048
    }
9049
9050
    if (x509->AttCertIssuerName != NULL) {
9051
        if (X509_print_name_entry(bio, x509->AttCertIssuerName, 1)
9052
                != WOLFSSL_SUCCESS) {
9053
            return WOLFSSL_FAILURE;
9054
        }
9055
    }
9056
    else {
9057
        const char * msg = " Issuer type not supported.\n";
9058
        if (wolfSSL_BIO_write(bio, msg, (int)XSTRLEN(msg)) <= 0) {
9059
            return WOLFSSL_FAILURE;
9060
        }
9061
    }
9062
9063
    #ifndef NO_ASN_TIME
9064
    /* print validity */
9065
    if (X509PrintValidity(bio, &x509->notBefore, &x509->notAfter, 8)
9066
        != WOLFSSL_SUCCESS) {
9067
        return WOLFSSL_FAILURE;
9068
    }
9069
    #endif /* NO_ASN_TIME */
9070
9071
    /* print raw attributes */
9072
    if (x509->rawAttr && x509->rawAttrLen > 0) {
9073
        char attr_hdr[128]; /* buffer for XSNPRINTF */
9074
9075
        if (XSNPRINTF(attr_hdr, 128, "%*s%s: %d bytes\n", 8, "",
9076
                    "Attributes", x509->rawAttrLen) >= 128) {
9077
            return WOLFSSL_FAILURE;
9078
        }
9079
9080
        if (wolfSSL_BIO_write(bio, attr_hdr, (int)XSTRLEN(attr_hdr)) <= 0) {
9081
                return WOLFSSL_FAILURE;
9082
        }
9083
    }
9084
9085
    /* print out sig algo and signature */
9086
    if (X509AcertPrintSignature(bio, x509, 0, 8) != WOLFSSL_SUCCESS) {
9087
        return WOLFSSL_FAILURE;
9088
    }
9089
9090
    /* done with print out */
9091
    if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
9092
        return WOLFSSL_FAILURE;
9093
    }
9094
9095
    return WOLFSSL_SUCCESS;
9096
}
9097
#endif /* WOLFSSL_ACERT */
9098
9099
#ifndef NO_FILESYSTEM
9100
int wolfSSL_X509_print_fp(XFILE fp, WOLFSSL_X509 *x509)
9101
{
9102
    WOLFSSL_BIO* bio;
9103
    int ret;
9104
9105
    WOLFSSL_ENTER("wolfSSL_X509_print_fp");
9106
9107
    if (!fp || !x509) {
9108
        WOLFSSL_MSG("Bad parameter");
9109
        return WOLFSSL_FAILURE;
9110
    }
9111
9112
    if (!(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file()))) {
9113
        WOLFSSL_MSG("wolfSSL_BIO_new wolfSSL_BIO_s_file error");
9114
        return WOLFSSL_FAILURE;
9115
    }
9116
9117
    if (wolfSSL_BIO_set_fp(bio, fp, WOLFSSL_BIO_NOCLOSE) != WOLFSSL_SUCCESS) {
9118
        WOLFSSL_MSG("wolfSSL_BIO_set_fp error");
9119
        wolfSSL_BIO_free(bio);
9120
        return WOLFSSL_FAILURE;
9121
    }
9122
9123
    ret = wolfSSL_X509_print(bio, x509);
9124
9125
    wolfSSL_BIO_free(bio);
9126
9127
    return ret;
9128
}
9129
#endif /* NO_FILESYSTEM */
9130
9131
#endif /* XSNPRINTF */
9132
9133
int wolfSSL_X509_signature_print(WOLFSSL_BIO *bp,
9134
        const WOLFSSL_X509_ALGOR *sigalg, const WOLFSSL_ASN1_STRING *sig)
9135
{
9136
    int length = 0;
9137
    word32 idx = 0;
9138
    int i;
9139
9140
    (void)sig;
9141
9142
    WOLFSSL_ENTER("wolfSSL_X509_signature_print");
9143
9144
    if (!bp || !sigalg) {
9145
        WOLFSSL_MSG("Bad parameter");
9146
        return WOLFSSL_FAILURE;
9147
    }
9148
9149
    if ((sigalg->algorithm->obj == NULL) ||
9150
        (sigalg->algorithm->obj[idx] != ASN_OBJECT_ID)) {
9151
        WOLFSSL_MSG("Bad ASN1 Object");
9152
        return WOLFSSL_FAILURE;
9153
    }
9154
    idx++; /* skip object id */
9155
9156
    if (GetLength((const byte*)sigalg->algorithm->obj, &idx, &length,
9157
                  sigalg->algorithm->objSz) < 0 || length < 0) {
9158
        return WOLFSSL_FAILURE;
9159
    }
9160
9161
    if (wolfSSL_BIO_puts(bp, "    Raw Signature Algorithm:") <= 0) {
9162
        WOLFSSL_MSG("wolfSSL_BIO_puts error");
9163
        return WOLFSSL_FAILURE;
9164
    }
9165
9166
    for (i = 0; i < length; ++i) {
9167
        char hex_digits[4];
9168
        if (XSNPRINTF(hex_digits, sizeof(hex_digits), "%c%02X", i>0 ? ':' : ' ',
9169
                  (unsigned int)sigalg->algorithm->obj[idx+i])
9170
            >= (int)sizeof(hex_digits))
9171
        {
9172
            WOLFSSL_MSG("buffer overrun");
9173
            return WOLFSSL_FAILURE;
9174
        }
9175
        if (wolfSSL_BIO_puts(bp, hex_digits) <= 0)
9176
            return WOLFSSL_FAILURE;
9177
    }
9178
9179
    if (wolfSSL_BIO_puts(bp, "\n") <= 0)
9180
        return WOLFSSL_FAILURE;
9181
9182
    return WOLFSSL_SUCCESS;
9183
}
9184
#endif /* !NO_BIO */
9185
9186
#ifndef NO_WOLFSSL_STUB
9187
void wolfSSL_X509_get0_signature(const WOLFSSL_ASN1_BIT_STRING **psig,
9188
        const WOLFSSL_X509_ALGOR **palg, const WOLFSSL_X509 *x509)
9189
{
9190
    (void)psig;
9191
    (void)palg;
9192
    (void)x509;
9193
    WOLFSSL_STUB("wolfSSL_X509_get0_signature");
9194
}
9195
#endif
9196
9197
#endif /* OPENSSL_EXTRA */
9198
9199
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
9200
const char* wolfSSL_X509_verify_cert_error_string(long err)
9201
{
9202
    return wolfSSL_ERR_reason_error_string((unsigned long)err);
9203
}
9204
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
9205
9206
#ifdef OPENSSL_EXTRA
9207
9208
/* Add directory path that will be used for loading certs and CRLs
9209
 * which have the <hash>.rn name format.
9210
 * type may be WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
9211
 * returns WOLFSSL_SUCCESS on successful, otherwise negative or zero. */
9212
int wolfSSL_X509_LOOKUP_add_dir(WOLFSSL_X509_LOOKUP* lookup, const char* dir,
9213
                               long type)
9214
{
9215
    return wolfSSL_X509_LOOKUP_ctrl(lookup, WOLFSSL_X509_L_ADD_DIR, dir, type,
9216
                                    NULL);
9217
}
9218
9219
int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP* lookup,
9220
                                 const char* file, long type)
9221
{
9222
#if !defined(NO_FILESYSTEM) && \
9223
    (defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM))
9224
    int           ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
9225
    XFILE         fp;
9226
    long          sz;
9227
    byte*         pem = NULL;
9228
    byte*         curr = NULL;
9229
    byte*         prev = NULL;
9230
    const char* header = NULL;
9231
    const char* footer = NULL;
9232
9233
    if (type != WOLFSSL_FILETYPE_PEM)
9234
        return WS_RETURN_CODE(BAD_FUNC_ARG, (int)WOLFSSL_FAILURE);
9235
9236
    fp = XFOPEN(file, "rb");
9237
    if (fp == XBADFILE)
9238
        return WS_RETURN_CODE(BAD_FUNC_ARG, (int)WOLFSSL_FAILURE);
9239
9240
    if (XFSEEK(fp, 0, XSEEK_END) != 0) {
9241
        XFCLOSE(fp);
9242
        return WS_RETURN_CODE(WOLFSSL_BAD_FILE,WOLFSSL_FAILURE);
9243
    }
9244
    sz = XFTELL(fp);
9245
    if (XFSEEK(fp, 0, XSEEK_SET) != 0) {
9246
        XFCLOSE(fp);
9247
        return WS_RETURN_CODE(WOLFSSL_BAD_FILE,WOLFSSL_FAILURE);
9248
    }
9249
9250
    if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
9251
        WOLFSSL_MSG("X509_LOOKUP_load_file size error");
9252
        goto end;
9253
    }
9254
9255
    pem = (byte*)XMALLOC(sz, 0, DYNAMIC_TYPE_PEM);
9256
    if (pem == NULL) {
9257
        ret = MEMORY_ERROR;
9258
        goto end;
9259
    }
9260
9261
    /* Read in file which may be CRLs or certificates. */
9262
    if (XFREAD(pem, (size_t)sz, 1, fp) != 1)
9263
        goto end;
9264
9265
    prev = curr = pem;
9266
    do {
9267
        /* get PEM header and footer based on type */
9268
        if (wc_PemGetHeaderFooter(CRL_TYPE, &header, &footer) == 0 &&
9269
                XSTRNSTR((char*)curr, header, sz) != NULL) {
9270
#ifdef HAVE_CRL
9271
            WOLFSSL_CERT_MANAGER* cm = lookup->store->cm;
9272
9273
            if (cm->crl == NULL) {
9274
                if (wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECK)
9275
                    != WOLFSSL_SUCCESS) {
9276
                    WOLFSSL_MSG("Enable CRL failed");
9277
                    goto end;
9278
                }
9279
            }
9280
9281
            ret = BufferLoadCRL(cm->crl, curr, sz, WOLFSSL_FILETYPE_PEM,
9282
                NO_VERIFY);
9283
            if (ret != WOLFSSL_SUCCESS)
9284
                goto end;
9285
#endif
9286
            curr = (byte*)XSTRNSTR((char*)curr, footer, sz);
9287
        }
9288
        else if (wc_PemGetHeaderFooter(CERT_TYPE, &header, &footer) == 0 &&
9289
                XSTRNSTR((char*)curr, header, sz) != NULL) {
9290
            ret = X509StoreLoadCertBuffer(lookup->store, curr,
9291
                                        (word32)sz, WOLFSSL_FILETYPE_PEM);
9292
            if (ret != WOLFSSL_SUCCESS)
9293
                goto end;
9294
            curr = (byte*)XSTRNSTR((char*)curr, footer, sz);
9295
        }
9296
        else
9297
            goto end;
9298
9299
        if (curr == NULL)
9300
            goto end;
9301
9302
        curr++;
9303
        sz -= (long)(curr - prev);
9304
        prev = curr;
9305
    }
9306
    while (ret == WOLFSSL_SUCCESS);
9307
9308
end:
9309
    XFREE(pem, 0, DYNAMIC_TYPE_PEM);
9310
    XFCLOSE(fp);
9311
    return WS_RETURN_CODE(ret, (int)WOLFSSL_FAILURE);
9312
#else
9313
    (void)lookup;
9314
    (void)file;
9315
    (void)type;
9316
    return WS_RETURN_CODE(WOLFSSL_FAILURE,WOLFSSL_FAILURE);
9317
#endif
9318
}
9319
9320
WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_hash_dir(void)
9321
{
9322
    /* Method implementation in functions. */
9323
    static WOLFSSL_X509_LOOKUP_METHOD meth = { 1 };
9324
    return &meth;
9325
}
9326
9327
WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_file(void)
9328
{
9329
    /* Method implementation in functions. */
9330
    static WOLFSSL_X509_LOOKUP_METHOD meth = { 0 };
9331
    return &meth;
9332
}
9333
9334
/* set directory path to load certificate or CRL which have the hash.N form */
9335
/* for late use                                                             */
9336
/* @param ctx    a pointer to WOLFSSL_BY_DIR structure                      */
9337
/* @param argc   directory path                                             */
9338
/* @param argl   file type, either WOLFSSL_FILETYPE_PEM or                  */
9339
/*                                          WOLFSSL_FILETYPE_ASN1           */
9340
/* @return WOLFSSL_SUCCESS on successful, otherwise negative or zero        */
9341
/* Note: on failure, path elements parsed before the failing one have       */
9342
/*       already been added to ctx->dir_entry                               */
9343
static int x509AddCertDir(WOLFSSL_BY_DIR *ctx, const char *argc, long argl)
9344
{
9345
#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
9346
    WOLFSSL_BY_DIR_entry *entry;
9347
    size_t pathLen;
9348
    int i, num;
9349
    const char* c;
9350
    WC_DECLARE_VAR(buf, char, MAX_FILENAME_SZ, 0);
9351
9352
    WOLFSSL_ENTER("x509AddCertDir");
9353
9354
    pathLen = 0;
9355
    c = argc;
9356
    /* sanity check, zero length */
9357
    if (ctx == NULL || c == NULL || *c == '\0')
9358
        return WOLFSSL_FAILURE;
9359
9360
#ifdef WOLFSSL_SMALL_STACK
9361
    buf = (char*)XMALLOC(MAX_FILENAME_SZ, NULL, DYNAMIC_TYPE_OPENSSL);
9362
    if (buf == NULL) {
9363
        WOLFSSL_LEAVE("x509AddCertDir", MEMORY_E);
9364
        return MEMORY_E;
9365
    }
9366
#endif
9367
9368
    XMEMSET(buf, 0, MAX_FILENAME_SZ);
9369
9370
    do {
9371
        if (*c == SEPARATOR_CHAR || *c == '\0') {
9372
9373
            num = wolfSSL_sk_BY_DIR_entry_num(ctx->dir_entry);
9374
9375
            for (i=0; i<num; i++) {
9376
9377
                entry = wolfSSL_sk_BY_DIR_entry_value(ctx->dir_entry, i);
9378
9379
                if (XSTRLEN(entry->dir_name) == pathLen &&
9380
                    XSTRNCMP(entry->dir_name, buf, pathLen) == 0) {
9381
                    WOLFSSL_MSG("dir entry found");
9382
                    break;
9383
                }
9384
            }
9385
9386
            if (num == -1 || i == num) {
9387
                WOLFSSL_MSG("no entry found");
9388
9389
                if (ctx->dir_entry == NULL) {
9390
                    ctx->dir_entry = wolfSSL_sk_BY_DIR_entry_new_null();
9391
9392
                    if (ctx->dir_entry == NULL) {
9393
                        WOLFSSL_MSG("failed to allocate dir_entry");
9394
                            WC_FREE_VAR_EX(buf, 0, DYNAMIC_TYPE_OPENSSL);
9395
                        return 0;
9396
                    }
9397
                }
9398
9399
                entry = wolfSSL_BY_DIR_entry_new();
9400
                if (entry == NULL) {
9401
                    WOLFSSL_MSG("failed to allocate dir entry");
9402
                        WC_FREE_VAR_EX(buf, 0, DYNAMIC_TYPE_OPENSSL);
9403
                    return 0;
9404
                }
9405
                entry->dir_type = (int)argl;
9406
                entry->dir_name = (char*)XMALLOC(pathLen + 1/* \0 termination*/
9407
                                                , NULL, DYNAMIC_TYPE_OPENSSL);
9408
                entry->hashes = wolfSSL_sk_BY_DIR_HASH_new_null();
9409
                if (entry->dir_name == NULL || entry->hashes == NULL) {
9410
                    WOLFSSL_MSG("failed to allocate dir name");
9411
                    wolfSSL_BY_DIR_entry_free(entry);
9412
                        WC_FREE_VAR_EX(buf, 0, DYNAMIC_TYPE_OPENSSL);
9413
                    return 0;
9414
                }
9415
9416
                XMEMCPY(entry->dir_name, buf, pathLen);
9417
                entry->dir_name[pathLen] = '\0';
9418
9419
                if (wolfSSL_sk_BY_DIR_entry_push(ctx->dir_entry, entry) <= 0) {
9420
                    wolfSSL_BY_DIR_entry_free(entry);
9421
                        WC_FREE_VAR_EX(buf, 0, DYNAMIC_TYPE_OPENSSL);
9422
                    return 0;
9423
                }
9424
            }
9425
            /* skip separator */
9426
            if (*c == SEPARATOR_CHAR) c++;
9427
9428
            pathLen = 0;
9429
            XMEMSET(buf, 0, MAX_FILENAME_SZ);
9430
        }
9431
        if (pathLen >= MAX_FILENAME_SZ) {
9432
            WOLFSSL_MSG("dir name too long for internal buffer");
9433
            WC_FREE_VAR_EX(buf, 0, DYNAMIC_TYPE_OPENSSL);
9434
            return 0;
9435
        }
9436
        buf[pathLen++] = *c;
9437
9438
    } while(*c++ != '\0');
9439
9440
    WC_FREE_VAR_EX(buf, 0, DYNAMIC_TYPE_OPENSSL);
9441
9442
    return WOLFSSL_SUCCESS;
9443
#else
9444
    (void)ctx;
9445
    (void)argc;
9446
    (void)argl;
9447
    return WOLFSSL_NOT_IMPLEMENTED;
9448
#endif
9449
}
9450
9451
/* set additional data to X509_LOOKUP                                   */
9452
/* @param ctx    a pointer to X509_LOOKUP structure                     */
9453
/* @param cmd    control command :                                      */
9454
/*               X509_L_FILE_LOAD, X509_L_ADD_DIR X509_L_ADD_STORE or   */
9455
/*               X509_L_LOAD_STORE                                      */
9456
/* @param argc   arguments for the control command                      */
9457
/* @param argl   arguments for the control command                      */
9458
/* @param **ret  return value of the control command                    */
9459
/* @return WOLFSSL_SUCCESS on successful, otherwise WOLFSSL_FAILURE     */
9460
/* note: WOLFSSL_X509_L_ADD_STORE and WOLFSSL_X509_L_LOAD_STORE have not*/
9461
/*       yet implemented. It returns WOLFSSL_NOT_IMPLEMENTED            */
9462
/*       when those control commands are passed.                        */
9463
/* Note: on failure, path elements parsed before the failing one have   */
9464
/*       already been added to ctx->dir_entry                           */
9465
int wolfSSL_X509_LOOKUP_ctrl(WOLFSSL_X509_LOOKUP *ctx, int cmd,
9466
        const char *argc, long argl, char **ret)
9467
{
9468
    int lret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
9469
9470
    WOLFSSL_ENTER("wolfSSL_X509_LOOKUP_ctrl");
9471
#if !defined(NO_FILESYSTEM)
9472
    if (ctx != NULL) {
9473
        switch (cmd) {
9474
        case WOLFSSL_X509_L_FILE_LOAD:
9475
            /* expects to return a number of processed cert or crl file */
9476
            lret = wolfSSL_X509_load_cert_crl_file(ctx, argc, (int)argl) > 0 ?
9477
                            WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
9478
            break;
9479
        case WOLFSSL_X509_L_ADD_DIR:
9480
            /* store directory location to use it later */
9481
#if !defined(NO_WOLFSSL_DIR)
9482
            lret = x509AddCertDir(ctx->dirs, argc, argl);
9483
#else
9484
            (void)x509AddCertDir;
9485
            lret = WOLFSSL_NOT_IMPLEMENTED;
9486
#endif
9487
            break;
9488
        case WOLFSSL_X509_L_ADD_STORE:
9489
        case WOLFSSL_X509_L_LOAD_STORE:
9490
            return WOLFSSL_NOT_IMPLEMENTED;
9491
9492
        default:
9493
            break;
9494
        }
9495
    }
9496
    (void)ret;
9497
#else
9498
    (void)ctx;
9499
    (void)argc;
9500
    (void)argl;
9501
    (void)ret;
9502
    (void)cmd;
9503
    (void)x509AddCertDir;
9504
    lret = WOLFSSL_NOT_IMPLEMENTED;
9505
#endif
9506
    return lret;
9507
}
9508
9509
9510
#if defined(WOLFSSL_CERT_GEN)
9511
static int wolfssl_x509_make_der(WOLFSSL_X509* x509, int req,
9512
        unsigned char* der, int* derSz, int includeSig);
9513
#endif
9514
9515
#ifdef WOLFSSL_CERT_GEN
9516
#ifndef NO_BIO
9517
/* Converts the X509 to DER format and outputs it into bio.
9518
 *
9519
 * bio  is the structure to hold output DER
9520
 * x509 certificate to create DER from
9521
 * req  if set then a CSR is generated
9522
 *
9523
 * returns WOLFSSL_SUCCESS on success
9524
 */
9525
static int loadX509orX509REQFromBio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
9526
    int req)
9527
{
9528
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
9529
    /* Get large buffer to hold cert der */
9530
    int derSz = X509_BUFFER_SZ;
9531
    WC_DECLARE_VAR(der, byte, X509_BUFFER_SZ, 0);
9532
    WOLFSSL_ENTER("wolfSSL_i2d_X509_bio");
9533
9534
    if (bio == NULL || x509 == NULL) {
9535
        return WOLFSSL_FAILURE;
9536
    }
9537
9538
#ifdef WOLFSSL_SMALL_STACK
9539
    der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
9540
    if (!der) {
9541
        WOLFSSL_MSG("malloc failed");
9542
        return WOLFSSL_FAILURE;
9543
    }
9544
#endif
9545
9546
    if (wolfssl_x509_make_der(x509, req, der, &derSz, 1) != WOLFSSL_SUCCESS) {
9547
        goto cleanup;
9548
    }
9549
9550
    if (wolfSSL_BIO_write(bio, der, derSz) != derSz) {
9551
        goto cleanup;
9552
    }
9553
9554
    ret = WOLFSSL_SUCCESS;
9555
cleanup:
9556
    WC_FREE_VAR_EX(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
9557
9558
    return ret;
9559
}
9560
9561
/* Converts the X509 to DER format and outputs it into bio.
9562
 *
9563
 * bio  is the structure to hold output DER
9564
 * x509 certificate to create DER from
9565
 *
9566
 * returns WOLFSSL_SUCCESS on success
9567
 */
9568
int wolfSSL_i2d_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
9569
{
9570
    return loadX509orX509REQFromBio(bio, x509, 0);
9571
}
9572
9573
#ifdef WOLFSSL_CERT_REQ
9574
int wolfSSL_i2d_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
9575
{
9576
    return loadX509orX509REQFromBio(bio, x509, 1);
9577
}
9578
#endif /* WOLFSSL_CERT_REQ */
9579
#endif /* !NO_BIO */
9580
#endif /* WOLFSSL_CERT_GEN */
9581
9582
/* Converts an internal structure to a DER buffer
9583
 *
9584
 * x509 structure to get DER buffer from
9585
 * out  buffer to hold result. If NULL then *out is NULL then a new buffer is
9586
 *      created.
9587
 *
9588
 * returns the size of the DER result on success
9589
 */
9590
int wolfSSL_i2d_X509(WOLFSSL_X509* x509, unsigned char** out)
9591
{
9592
    const unsigned char* der;
9593
    int derSz = 0;
9594
    int advance = 1;
9595
9596
    WOLFSSL_ENTER("wolfSSL_i2d_X509");
9597
9598
    if (x509 == NULL) {
9599
        WOLFSSL_LEAVE("wolfSSL_i2d_X509", BAD_FUNC_ARG);
9600
        return BAD_FUNC_ARG;
9601
    }
9602
9603
    der = wolfSSL_X509_get_der(x509, &derSz);
9604
    if (der == NULL || derSz <= 0) {
9605
        WOLFSSL_LEAVE("wolfSSL_i2d_X509", MEMORY_E);
9606
        return MEMORY_E;
9607
    }
9608
9609
    if (out != NULL && *out == NULL) {
9610
        *out = (unsigned char*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL);
9611
        if (*out == NULL) {
9612
            WOLFSSL_LEAVE("wolfSSL_i2d_X509", MEMORY_E);
9613
            return MEMORY_E;
9614
        }
9615
        advance = 0;
9616
    }
9617
9618
    if (out != NULL) {
9619
        XMEMCPY(*out, der, derSz);
9620
        if (advance)
9621
            *out += derSz;
9622
    }
9623
9624
    WOLFSSL_LEAVE("wolfSSL_i2d_X509", derSz);
9625
    return derSz;
9626
}
9627
9628
#ifdef WOLFSSL_DUAL_ALG_CERTS
9629
/* Generate a der preTBS from a decoded cert, and write
9630
 * to buffer.
9631
 *
9632
 * @param [in]  cert  The decoded cert to parse.
9633
 * @param [out] der   The der buffer to write in.
9634
 * @param [in]  derSz The der buffer size.
9635
 *
9636
 * @return  preTBS der size on success.
9637
 * */
9638
int wc_GeneratePreTBS(DecodedCert* cert, byte *der, int derSz) {
9639
    int ret = 0;
9640
    WOLFSSL_X509 *x = NULL;
9641
    byte certIsCSR = 0;
9642
9643
    WOLFSSL_ENTER("wc_GeneratePreTBS");
9644
9645
    if ((cert == NULL) || (der == NULL) || (derSz <= 0)) {
9646
        return BAD_FUNC_ARG;
9647
    }
9648
9649
#ifdef WOLFSSL_CERT_REQ
9650
    certIsCSR = cert->isCSR;
9651
#endif
9652
9653
    x = wolfSSL_X509_new();
9654
    if (x == NULL) {
9655
        ret = MEMORY_E;
9656
    }
9657
    else {
9658
        ret = CopyDecodedToX509(x, cert);
9659
    }
9660
9661
    if (ret == 0) {
9662
        /* Remove the altsigval extension. */
9663
        XFREE(x->altSigValDer, x->heap, DYNAMIC_TYPE_X509_EXT);
9664
        x->altSigValDer = NULL;
9665
        x->altSigValLen = 0;
9666
        /* Remove sigOID so it won't be encoded. */
9667
        x->sigOID = 0;
9668
        /* We now have a PreTBS. Encode it. */
9669
        ret = wolfssl_x509_make_der(x, certIsCSR, der, &derSz, 0);
9670
        if (ret == WOLFSSL_SUCCESS) {
9671
            ret = derSz;
9672
        }
9673
    }
9674
9675
    if (x != NULL) {
9676
        wolfSSL_X509_free(x);
9677
        x = NULL;
9678
    }
9679
9680
    return ret;
9681
}
9682
#endif /* WOLFSSL_DUAL_ALG_CERTS */
9683
9684
#ifndef NO_BIO
9685
/**
9686
 * Converts the DER from bio and creates a WOLFSSL_X509 structure from it.
9687
 * @param bio  is the structure holding DER
9688
 * @param x509 certificate to create from DER. Can be NULL
9689
 * @param req  1 for a CSR and 0 for a x509 cert
9690
 * @return pointer to WOLFSSL_X509 structure on success and NULL on fail
9691
 */
9692
static WOLFSSL_X509* d2i_X509orX509REQ_bio(WOLFSSL_BIO* bio,
9693
                                            WOLFSSL_X509** x509, int req)
9694
{
9695
    WOLFSSL_X509* localX509 = NULL;
9696
    byte* mem  = NULL;
9697
    int    size;
9698
    int    derSz;
9699
    int    hdrSz = 2;
9700
    int    len = 0;
9701
    word32 idx = 1;
9702
    byte   hdr[6];
9703
9704
    WOLFSSL_ENTER("wolfSSL_d2i_X509_bio");
9705
9706
    if (bio == NULL) {
9707
        WOLFSSL_MSG("Bad Function Argument bio is NULL");
9708
        return NULL;
9709
    }
9710
9711
    size = wolfSSL_BIO_get_len(bio);
9712
    if (size <= 0) {
9713
        WOLFSSL_MSG("wolfSSL_BIO_get_len error. Possibly no pending data.");
9714
        WOLFSSL_ERROR(WOLFSSL_ASN1_R_HEADER_TOO_LONG_E);
9715
        return NULL;
9716
    }
9717
9718
    /* Consume only the first DER object. A BIO holding a chain is then
9719
     * decoded one certificate per call, as with OpenSSL. */
9720
    if (wolfSSL_BIO_read(bio, hdr, hdrSz) != hdrSz) {
9721
        WOLFSSL_MSG("wolfSSL_BIO_read error");
9722
        return NULL;
9723
    }
9724
    if (hdr[1] & ASN_LONG_LENGTH) {
9725
        int n = hdr[1] & 0x7F;
9726
        if (n < 1 || n > 4 || wolfSSL_BIO_read(bio, hdr + hdrSz, n) != n) {
9727
            WOLFSSL_MSG("Bad DER length");
9728
            return NULL;
9729
        }
9730
        hdrSz += n;
9731
    }
9732
    if (hdr[0] != (ASN_SEQUENCE | ASN_CONSTRUCTED) ||
9733
            GetLength_ex(hdr, &idx, &len, (word32)hdrSz, 0) < 0 ||
9734
            len < 0 || (int)idx + len > size) {
9735
        WOLFSSL_MSG("Bad DER header");
9736
        return NULL;
9737
    }
9738
    derSz = (int)idx + len;
9739
9740
    if (!(mem = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL))) {
9741
        WOLFSSL_MSG("malloc error");
9742
        return NULL;
9743
    }
9744
    XMEMCPY(mem, hdr, hdrSz);
9745
    if (derSz > hdrSz && wolfSSL_BIO_read(bio, mem + hdrSz, derSz - hdrSz) !=
9746
            derSz - hdrSz) {
9747
        WOLFSSL_MSG("wolfSSL_BIO_read error");
9748
        XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL);
9749
        return NULL;
9750
    }
9751
9752
    if (req) {
9753
#ifdef WOLFSSL_CERT_REQ
9754
        localX509 = wolfSSL_X509_REQ_d2i(NULL, mem, derSz);
9755
#else
9756
        WOLFSSL_MSG("CSR not compiled in");
9757
#endif
9758
    }
9759
    else {
9760
        localX509 = wolfSSL_X509_d2i_ex(NULL, mem, derSz, bio->heap);
9761
    }
9762
    if (localX509 == NULL) {
9763
        WOLFSSL_MSG("wolfSSL_X509_d2i error");
9764
        XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL);
9765
        return NULL;
9766
    }
9767
9768
    if (x509 != NULL) {
9769
        *x509 = localX509;
9770
    }
9771
9772
    XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL);
9773
    return localX509;
9774
}
9775
9776
WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509)
9777
{
9778
    return d2i_X509orX509REQ_bio(bio, x509, 0);
9779
}
9780
9781
#ifdef WOLFSSL_CERT_REQ
9782
WOLFSSL_X509* wolfSSL_d2i_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509)
9783
{
9784
    return d2i_X509orX509REQ_bio(bio, x509, 1);
9785
}
9786
#endif
9787
#endif /* !NO_BIO */
9788
9789
#endif /* OPENSSL_EXTRA */
9790
9791
#ifdef OPENSSL_EXTRA
9792
/* Use the public key to verify the signature. Note: this only verifies
9793
 * the certificate signature.
9794
 * returns WOLFSSL_SUCCESS on successful signature verification */
9795
static int verifyX509orX509REQ(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey,
9796
    int req)
9797
{
9798
    int ret;
9799
    const byte* der;
9800
    int derSz = 0;
9801
    int type;
9802
    const byte* pubKey;
9803
    int pubKeySz;
9804
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
9805
    byte edPubKey[ED25519_PUB_KEY_SIZE];
9806
    word32 edPubKeySz = (word32)sizeof(edPubKey);
9807
#endif
9808
9809
    (void)req;
9810
9811
    if (x509 == NULL || pkey == NULL) {
9812
        return WOLFSSL_FATAL_ERROR;
9813
    }
9814
9815
    der = wolfSSL_X509_get_der(x509, &derSz);
9816
    if (der == NULL) {
9817
        WOLFSSL_MSG("Error getting WOLFSSL_X509 DER");
9818
        return WOLFSSL_FATAL_ERROR;
9819
    }
9820
9821
    /* Most key types verify against the cached public-key DER. */
9822
    pubKey   = (const byte*)pkey->pkey.ptr;
9823
    pubKeySz = pkey->pkey_sz;
9824
9825
    switch (pkey->type) {
9826
        case WC_EVP_PKEY_RSA:
9827
            type = RSAk;
9828
            break;
9829
9830
        case WC_EVP_PKEY_EC:
9831
            type = ECDSAk;
9832
            break;
9833
9834
        case WC_EVP_PKEY_DSA:
9835
            type = DSAk;
9836
            break;
9837
9838
    #if defined(WOLFSSL_HAVE_MLDSA)
9839
        case WC_EVP_PKEY_DILITHIUM:
9840
            type = WOLFSSL_ATOMIC_LOAD(pkey->mldsaOID);
9841
            if (type == 0) {
9842
                WOLFSSL_MSG("ML-DSA pkey missing key OID");
9843
                return WOLFSSL_FATAL_ERROR;
9844
            }
9845
            break;
9846
    #endif
9847
    #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
9848
        case WC_EVP_PKEY_ED25519:
9849
            /* The signature check needs the raw public key; for Ed25519
9850
             * pkey->pkey.ptr holds a PKCS#8 private blob (or nothing), so
9851
             * export the public key from the ed25519_key instead. */
9852
            if (pkey->ed25519 == NULL ||
9853
                    wc_ed25519_export_public(pkey->ed25519, edPubKey,
9854
                        &edPubKeySz) != 0) {
9855
                WOLFSSL_MSG("Unable to export Ed25519 public key");
9856
                return WOLFSSL_FATAL_ERROR;
9857
            }
9858
            pubKey   = edPubKey;
9859
            pubKeySz = (int)edPubKeySz;
9860
            type     = ED25519k;
9861
            break;
9862
    #endif
9863
9864
        default:
9865
            WOLFSSL_MSG("Unknown pkey key type");
9866
            return WOLFSSL_FATAL_ERROR;
9867
    }
9868
9869
#ifdef WOLFSSL_CERT_REQ
9870
    if (req)
9871
        ret = CheckCSRSignaturePubKey(der, (word32)derSz, x509->heap,
9872
                (unsigned char*)pubKey, pubKeySz, type);
9873
    else
9874
#endif
9875
        ret = CheckCertSignaturePubKey(der, (word32)derSz, x509->heap,
9876
                (unsigned char*)pubKey, pubKeySz, type);
9877
    if (ret == 0) {
9878
        return WOLFSSL_SUCCESS;
9879
    }
9880
    return WOLFSSL_FAILURE;
9881
}
9882
9883
int wolfSSL_X509_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey)
9884
{
9885
    return verifyX509orX509REQ(x509, pkey, 0);
9886
}
9887
9888
#ifdef WOLFSSL_CERT_REQ
9889
int wolfSSL_X509_REQ_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey)
9890
{
9891
    return verifyX509orX509REQ(x509, pkey, 1);
9892
}
9893
#endif /* WOLFSSL_CERT_REQ */
9894
9895
#if !defined(NO_FILESYSTEM)
9896
static void *wolfSSL_d2i_X509_fp_ex(XFILE file, void **x509, int type)
9897
{
9898
    void *newx509 = NULL;
9899
    byte *fileBuffer = NULL;
9900
    long sz = 0;
9901
9902
    /* init variable */
9903
    if (x509)
9904
        *x509 = NULL;
9905
9906
    /* argument check */
9907
    if (file == XBADFILE) {
9908
        return NULL;
9909
    }
9910
9911
    /* determine file size */
9912
    if (XFSEEK(file, 0, XSEEK_END) != 0) {
9913
        return NULL;
9914
    }
9915
    sz = XFTELL(file);
9916
    if (XFSEEK(file, 0, XSEEK_SET) != 0) {
9917
        return NULL;
9918
    }
9919
9920
    if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
9921
        WOLFSSL_MSG("d2i_X509_fp_ex file size error");
9922
        return NULL;
9923
    }
9924
9925
    fileBuffer = (byte *)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
9926
    if (fileBuffer != NULL) {
9927
        if ((long)XFREAD(fileBuffer, 1, (size_t)sz, file) != sz) {
9928
            WOLFSSL_MSG("File read failed");
9929
            goto err_exit;
9930
        }
9931
        if (type == CERT_TYPE) {
9932
            newx509 = (void *)wolfSSL_X509_d2i(NULL, fileBuffer, (int)sz);
9933
        }
9934
    #ifdef HAVE_CRL
9935
        else if (type == CRL_TYPE) {
9936
            newx509 = (void *)wolfSSL_d2i_X509_CRL(NULL, fileBuffer, (int)sz);
9937
        }
9938
    #endif
9939
    #ifdef WOLFSSL_CERT_REQ
9940
        else if (type == CERTREQ_TYPE) {
9941
             newx509 = (void *)wolfSSL_X509_REQ_d2i(NULL, fileBuffer, (int)sz);
9942
        }
9943
    #endif
9944
    #if !defined(NO_ASN) && !defined(NO_PWDBASED) && defined(HAVE_PKCS12)
9945
        else if (type == PKCS12_TYPE) {
9946
            if ((newx509 = wc_PKCS12_new()) == NULL) {
9947
                goto err_exit;
9948
            }
9949
            if (wc_d2i_PKCS12(fileBuffer, (word32)sz,
9950
                                                     (WC_PKCS12*)newx509) < 0) {
9951
                goto err_exit;
9952
            }
9953
        }
9954
    #endif
9955
        else {
9956
            goto err_exit;
9957
        }
9958
        if (newx509 == NULL) {
9959
            WOLFSSL_MSG("X509 failed");
9960
            goto err_exit;
9961
        }
9962
    }
9963
9964
    if (x509)
9965
        *x509 = newx509;
9966
9967
    goto _exit;
9968
9969
err_exit:
9970
#if !defined(NO_ASN) && !defined(NO_PWDBASED) && defined(HAVE_PKCS12)
9971
    if ((newx509 != NULL) && (type == PKCS12_TYPE)) {
9972
        wc_PKCS12_free((WC_PKCS12*)newx509);
9973
        newx509 = NULL;
9974
    }
9975
#endif
9976
_exit:
9977
    XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
9978
9979
    return newx509;
9980
}
9981
9982
#ifdef WOLFSSL_CERT_REQ
9983
WOLFSSL_X509* wolfSSL_d2i_X509_REQ_fp(XFILE fp, WOLFSSL_X509 **req)
9984
{
9985
    return (WOLFSSL_X509 *)wolfSSL_d2i_X509_fp_ex(fp, (void **)req,
9986
                                                  CERTREQ_TYPE);
9987
}
9988
#endif /* WOLFSSL_CERT_REQ */
9989
9990
WOLFSSL_X509 *wolfSSL_d2i_X509_fp(XFILE fp, WOLFSSL_X509 **x509)
9991
{
9992
    WOLFSSL_ENTER("wolfSSL_d2i_X509_fp");
9993
    return (WOLFSSL_X509 *)wolfSSL_d2i_X509_fp_ex(fp, (void **)x509, CERT_TYPE);
9994
}
9995
9996
/* load certificate or CRL file, and add it to the STORE           */
9997
/* @param ctx    a pointer to X509_LOOKUP structure                */
9998
/* @param file   file name to load                                 */
9999
/* @param type   WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1     */
10000
/* @return a number of loading CRL or certificate, otherwise zero  */
10001
int wolfSSL_X509_load_cert_crl_file(WOLFSSL_X509_LOOKUP *ctx,
10002
    const char *file, int type)
10003
{
10004
    WOLFSSL_X509 *x509 = NULL;
10005
10006
    int cnt = 0;
10007
10008
    WOLFSSL_ENTER("wolfSSL_X509_load_cert_crl_file");
10009
10010
    /* stanity check */
10011
    if (ctx == NULL || file == NULL) {
10012
        WOLFSSL_MSG("bad arguments");
10013
        return 0;
10014
    }
10015
10016
    if (type != WOLFSSL_FILETYPE_PEM) {
10017
        x509 = wolfSSL_X509_load_certificate_file(file, type);
10018
        if (x509 != NULL) {
10019
            if (wolfSSL_X509_STORE_add_cert(ctx->store, x509)
10020
                                    == WOLFSSL_SUCCESS) {
10021
                cnt++;
10022
            }
10023
            else {
10024
                WOLFSSL_MSG("wolfSSL_X509_STORE_add_cert error");
10025
            }
10026
            wolfSSL_X509_free(x509);
10027
            x509 = NULL;
10028
        }
10029
        else {
10030
            WOLFSSL_MSG("wolfSSL_X509_load_certificate_file error");
10031
        }
10032
10033
    }
10034
    else {
10035
#if defined(OPENSSL_ALL)
10036
    #if !defined(NO_BIO)
10037
        STACK_OF(WOLFSSL_X509_INFO) *info;
10038
        WOLFSSL_X509_INFO *info_tmp;
10039
        int i;
10040
        int num = 0;
10041
        WOLFSSL_BIO *bio = wolfSSL_BIO_new_file(file, "rb");
10042
        if (!bio) {
10043
            WOLFSSL_MSG("wolfSSL_BIO_new error");
10044
            return cnt;
10045
        }
10046
10047
        info = wolfSSL_PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
10048
10049
        wolfSSL_BIO_free(bio);
10050
10051
        if (!info) {
10052
            WOLFSSL_MSG("wolfSSL_PEM_X509_INFO_read_bio error");
10053
            return cnt;
10054
        }
10055
        num = wolfSSL_sk_X509_INFO_num(info);
10056
        for (i=0; i < num; i++) {
10057
            info_tmp = wolfSSL_sk_X509_INFO_value(info, i);
10058
10059
            if (info_tmp == NULL)
10060
                continue;
10061
10062
            if (info_tmp->x509) {
10063
                if (wolfSSL_X509_STORE_add_cert(ctx->store, info_tmp->x509) ==
10064
                    WOLFSSL_SUCCESS) {
10065
                    cnt ++;
10066
                }
10067
                else {
10068
                    WOLFSSL_MSG("wolfSSL_X509_STORE_add_cert failed");
10069
                }
10070
            }
10071
#ifdef HAVE_CRL
10072
            if (info_tmp->crl) {
10073
                if (wolfSSL_X509_STORE_add_crl(ctx->store, info_tmp->crl) ==
10074
                    WOLFSSL_SUCCESS) {
10075
                    cnt ++;
10076
                }
10077
                else {
10078
                    WOLFSSL_MSG("wolfSSL_X509_STORE_add_crl failed");
10079
                }
10080
            }
10081
#endif
10082
        }
10083
        wolfSSL_sk_X509_INFO_pop_free(info, wolfSSL_X509_INFO_free);
10084
    #elif defined(HAVE_CRL)
10085
        /* Only supports one certificate or CRL in the file. */
10086
        WOLFSSL_X509_CRL* crl = NULL;
10087
        XFILE fp = XFOPEN(file, "rb");
10088
        if (fp == XBADFILE) {
10089
            WOLFSSL_MSG("XFOPEN error");
10090
            return cnt;
10091
        }
10092
10093
        x509 = wolfSSL_PEM_read_X509(fp, NULL, NULL, NULL);
10094
        if (x509 != NULL) {
10095
            if (wolfSSL_X509_STORE_add_cert(ctx->store, x509) ==
10096
                WOLFSSL_SUCCESS) {
10097
                cnt++;
10098
            }
10099
            else {
10100
                WOLFSSL_MSG("wolfSSL_X509_STORE_add_cert failed");
10101
            }
10102
        }
10103
        else {
10104
            if (XFSEEK(fp, 0, XSEEK_SET) != 0) {
10105
                WOLFSSL_MSG("XFSEEK error");
10106
                return cnt;
10107
            }
10108
            crl = wolfSSL_PEM_read_X509_CRL(fp, NULL, NULL, NULL);
10109
            if (crl != NULL) {
10110
                if (wolfSSL_X509_STORE_add_crl(ctx->store, crl) ==
10111
                    WOLFSSL_SUCCESS) {
10112
                    cnt++;
10113
                }
10114
                else {
10115
                    WOLFSSL_MSG("wolfSSL_X509_STORE_add_crl failed");
10116
                }
10117
            }
10118
            else {
10119
                WOLFSSL_MSG("Certificate and CRL not recognized");
10120
                return cnt;
10121
            }
10122
        }
10123
10124
        wolfSSL_X509_free(x509);
10125
        wolfSSL_X509_CRL_free(crl);
10126
    #endif
10127
#else
10128
    (void)cnt;
10129
#endif /* OPENSSL_ALL && !NO_BIO */
10130
    }
10131
10132
    WOLFSSL_LEAVE("wolfSSL_X509_load_ceretificate_crl_file", cnt);
10133
    return cnt;
10134
}
10135
#endif /* !NO_FILESYSTEM */
10136
10137
10138
#ifdef HAVE_CRL
10139
10140
#ifndef NO_BIO
10141
WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL_bio(WOLFSSL_BIO *bp,
10142
                                                    WOLFSSL_X509_CRL **x)
10143
{
10144
    int derSz;
10145
    byte* der = NULL;
10146
    WOLFSSL_X509_CRL* crl = NULL;
10147
10148
    if (bp == NULL)
10149
        return NULL;
10150
10151
    if ((derSz = wolfSSL_BIO_get_len(bp)) > 0) {
10152
        der = (byte*)XMALLOC(derSz, 0, DYNAMIC_TYPE_DER);
10153
        if (der != NULL) {
10154
            if (wolfSSL_BIO_read(bp, der, derSz) == derSz) {
10155
                crl = wolfSSL_d2i_X509_CRL(x, der, derSz);
10156
            }
10157
        }
10158
    }
10159
10160
    XFREE(der, 0, DYNAMIC_TYPE_DER);
10161
10162
    return crl;
10163
}
10164
#endif
10165
10166
#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
10167
WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL_fp(XFILE fp, WOLFSSL_X509_CRL **crl)
10168
{
10169
    WOLFSSL_ENTER("wolfSSL_d2i_X509_CRL_fp");
10170
    return (WOLFSSL_X509_CRL *)wolfSSL_d2i_X509_fp_ex(fp, (void **)crl,
10171
        CRL_TYPE);
10172
}
10173
10174
/* Read CRL file, and add it to store and corresponding cert manager     */
10175
/* @param ctx   a pointer of X509_LOOKUP back to the X509_STORE          */
10176
/* @param file  a file to read                                           */
10177
/* @param type  WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1            */
10178
/* @return WOLFSSL_SUCCESS(1) on successful, otherwise WOLFSSL_FAILURE(0)*/
10179
int wolfSSL_X509_load_crl_file(WOLFSSL_X509_LOOKUP *ctx,
10180
                                             const char *file, int type)
10181
{
10182
#ifndef NO_BIO
10183
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
10184
    int count = 0;
10185
    WOLFSSL_BIO *bio = NULL;
10186
    WOLFSSL_X509_CRL *crl = NULL;
10187
10188
    WOLFSSL_ENTER("wolfSSL_X509_load_crl_file");
10189
10190
    if (ctx == NULL || file == NULL)
10191
        return ret;
10192
10193
    if ((bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file())) == NULL)
10194
        return ret;
10195
10196
    if (wolfSSL_BIO_read_filename(bio, file) <= 0) {
10197
        wolfSSL_BIO_free(bio);
10198
        return ret;
10199
    }
10200
10201
    if (wolfSSL_BIO_read_filename(bio, file) <= 0) {
10202
        wolfSSL_BIO_free(bio);
10203
        return ret;
10204
    }
10205
10206
    if (type == WOLFSSL_FILETYPE_PEM) {
10207
        do {
10208
            crl = wolfSSL_PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL);
10209
            if (crl == NULL) {
10210
                if (count <= 0) {
10211
                    WOLFSSL_MSG("Load crl failed");
10212
                }
10213
                break;
10214
            }
10215
10216
            ret = wolfSSL_X509_STORE_add_crl(ctx->store, crl);
10217
            if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
10218
                WOLFSSL_MSG("Adding crl failed");
10219
                break;
10220
            }
10221
            count++;
10222
            wolfSSL_X509_CRL_free(crl);
10223
            crl = NULL;
10224
        }   while(crl == NULL);
10225
10226
        ret = count;
10227
    }
10228
    else if (type == WOLFSSL_FILETYPE_ASN1) {
10229
        crl = wolfSSL_d2i_X509_CRL_bio(bio, NULL);
10230
        if (crl == NULL) {
10231
            WOLFSSL_MSG("Load crl failed");
10232
        }
10233
        else {
10234
            ret = wolfSSL_X509_STORE_add_crl(ctx->store, crl);
10235
            if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
10236
                WOLFSSL_MSG("Adding crl failed");
10237
            }
10238
            else {
10239
                ret = 1;/* handled a file */
10240
            }
10241
        }
10242
    }
10243
    else {
10244
        WOLFSSL_MSG("Invalid file type");
10245
    }
10246
10247
    wolfSSL_X509_CRL_free(crl);
10248
    wolfSSL_BIO_free(bio);
10249
10250
    WOLFSSL_LEAVE("wolfSSL_X509_load_crl_file", ret);
10251
    return ret;
10252
#else
10253
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
10254
    int count = 0;
10255
    XFILE fp;
10256
    WOLFSSL_X509_CRL *crl = NULL;
10257
10258
    WOLFSSL_ENTER("wolfSSL_X509_load_crl_file");
10259
10260
    if (ctx == NULL || file == NULL)
10261
        return ret;
10262
10263
    if ((fp = XFOPEN(file, "rb")) == XBADFILE)
10264
        return ret;
10265
10266
    if (type == WOLFSSL_FILETYPE_PEM) {
10267
        do {
10268
            crl = wolfSSL_PEM_read_X509_CRL(fp, NULL, NULL, NULL);
10269
            if (crl == NULL) {
10270
                if (count <= 0) {
10271
                    WOLFSSL_MSG("Load crl failed");
10272
                }
10273
                break;
10274
            }
10275
10276
            ret = wolfSSL_X509_STORE_add_crl(ctx->store, crl);
10277
            if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
10278
                WOLFSSL_MSG("Adding crl failed");
10279
                break;
10280
            }
10281
            count++;
10282
            wolfSSL_X509_CRL_free(crl);
10283
            crl = NULL;
10284
        }
10285
        while(crl == NULL);
10286
10287
        ret = count;
10288
    }
10289
    else if (type == WOLFSSL_FILETYPE_ASN1) {
10290
        crl = wolfSSL_d2i_X509_CRL_fp(fp, NULL);
10291
        if (crl == NULL) {
10292
            WOLFSSL_MSG("Load crl failed");
10293
        }
10294
        else {
10295
            ret = wolfSSL_X509_STORE_add_crl(ctx->store, crl);
10296
            if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
10297
                WOLFSSL_MSG("Adding crl failed");
10298
            }
10299
            else {
10300
                ret = 1;/* handled a file */
10301
            }
10302
        }
10303
    }
10304
    else {
10305
        WOLFSSL_MSG("Invalid file type");
10306
    }
10307
10308
    wolfSSL_X509_CRL_free(crl);
10309
    XFCLOSE(fp);
10310
10311
    WOLFSSL_LEAVE("wolfSSL_X509_load_crl_file", ret);
10312
    return ret;
10313
#endif /* !NO_BIO */
10314
}
10315
#endif /* !NO_FILESYSTEM */
10316
10317
10318
/* Decode a DER encoded CRL, following the OpenSSL d2i contract.
10319
 *
10320
 * The OpenSSL form takes a pointer to the buffer pointer and advances it
10321
 * past the object that was decoded, which is how a caller walks a buffer
10322
 * holding more than one object. wolfSSL_d2i_X509_CRL() takes the buffer
10323
 * directly and cannot report what it consumed, so an OpenSSL caller
10324
 * passing &p would hand it the address of its own pointer variable.
10325
 *
10326
 * @param [in, out] crl  CRL object to return, may be NULL.
10327
 * @param [in, out] in   Pointer to the buffer pointer; advanced on success.
10328
 * @param [in]      len  Length of data in the buffer.
10329
 * @return  CRL object on success, NULL on error.
10330
 */
10331
WOLFSSL_X509_CRL* wolfSSL_d2i_X509_CRL_ex(WOLFSSL_X509_CRL** crl,
10332
        const unsigned char** in, long len)
10333
{
10334
    WOLFSSL_X509_CRL* ret;
10335
    const unsigned char* p;
10336
    long objLen = 0;
10337
    int tag = 0;
10338
    int cls = 0;
10339
10340
    WOLFSSL_ENTER("wolfSSL_d2i_X509_CRL_ex");
10341
10342
    if ((in == NULL) || (*in == NULL) || (len <= 0)) {
10343
        WOLFSSL_MSG("Bad argument value");
10344
        return NULL;
10345
    }
10346
10347
    ret = wolfSSL_d2i_X509_CRL(crl, *in, (int)len);
10348
    if (ret == NULL) {
10349
        return NULL;
10350
    }
10351
10352
    /* Advance past the object just decoded. The header parsed once already
10353
     * to get here, so a failure now leaves the caller's pointer alone
10354
     * rather than moving it somewhere unknown. */
10355
    p = *in;
10356
    if ((wolfSSL_ASN1_get_object(&p, &objLen, &tag, &cls, len) & 0x80) == 0) {
10357
        *in = p + objLen;
10358
    }
10359
10360
    return ret;
10361
}
10362
10363
WOLFSSL_X509_CRL* wolfSSL_d2i_X509_CRL(WOLFSSL_X509_CRL** crl,
10364
        const unsigned char* in, int len)
10365
{
10366
    WOLFSSL_X509_CRL *newcrl = NULL;
10367
    int ret = WOLFSSL_SUCCESS;
10368
10369
    WOLFSSL_ENTER("wolfSSL_d2i_X509_CRL");
10370
10371
    if (in == NULL) {
10372
        WOLFSSL_MSG("Bad argument value");
10373
    }
10374
    else {
10375
        newcrl =(WOLFSSL_X509_CRL*)XMALLOC(sizeof(WOLFSSL_X509_CRL), NULL,
10376
                DYNAMIC_TYPE_CRL);
10377
        if (newcrl == NULL) {
10378
            WOLFSSL_MSG("New CRL allocation failed");
10379
        }
10380
        else {
10381
            ret = InitCRL(newcrl, NULL);
10382
            if (ret < 0) {
10383
                WOLFSSL_MSG("Init tmp CRL failed");
10384
                /* A failed InitCRL() has already released whatever it took,
10385
                 * so dispose of the memory here and keep this object away
10386
                 * from the wolfSSL_X509_CRL_free() below, which would destroy
10387
                 * the lock and the condition variable a second time. */
10388
                XFREE(newcrl, NULL, DYNAMIC_TYPE_CRL);
10389
                newcrl = NULL;
10390
            }
10391
            else {
10392
                ret = BufferLoadCRL(newcrl, in, len, WOLFSSL_FILETYPE_ASN1,
10393
                    NO_VERIFY);
10394
                if (ret != WOLFSSL_SUCCESS) {
10395
                    WOLFSSL_MSG("Buffer Load CRL failed");
10396
                }
10397
                else {
10398
                    if (crl) {
10399
                        *crl = newcrl;
10400
                    }
10401
                }
10402
            }
10403
        }
10404
    }
10405
10406
    if ((ret != WOLFSSL_SUCCESS) && (newcrl != NULL)) {
10407
        wolfSSL_X509_CRL_free(newcrl);
10408
        newcrl = NULL;
10409
    }
10410
10411
    return newcrl;
10412
}
10413
10414
/* Retrieve issuer X509_NAME from CRL
10415
 * return X509_NAME*  on success
10416
 * return NULL on failure
10417
 */
10418
WOLFSSL_X509_NAME* wolfSSL_X509_CRL_get_issuer_name(const WOLFSSL_X509_CRL* crl)
10419
{
10420
    if (crl == NULL || crl->crlList == NULL)
10421
        return NULL;
10422
10423
    return crl->crlList->issuer;
10424
}
10425
10426
/* Set issuer name of CRL
10427
 * return WOLFSSL_SUCCESS on success
10428
 * return WOLFSSL_FAILURE on failure
10429
 */
10430
int wolfSSL_X509_CRL_set_issuer_name(WOLFSSL_X509_CRL* crl,
10431
                                     const WOLFSSL_X509_NAME* name)
10432
{
10433
    WOLFSSL_X509_NAME* newName;
10434
10435
    if (crl == NULL || crl->crlList == NULL || name == NULL)
10436
        return WOLFSSL_FAILURE;
10437
10438
    newName = wolfSSL_X509_NAME_dup(name);
10439
    if (newName == NULL)
10440
        return WOLFSSL_FAILURE;
10441
10442
    if (crl->crlList->issuer != NULL) {
10443
        FreeX509Name(crl->crlList->issuer);
10444
        XFREE(crl->crlList->issuer, crl->heap, DYNAMIC_TYPE_X509);
10445
    }
10446
    crl->crlList->issuer = newName;
10447
10448
    return WOLFSSL_SUCCESS;
10449
}
10450
10451
/* Retrieve version from CRL
10452
 * return version on success
10453
 * return 0 on failure
10454
 */
10455
int wolfSSL_X509_CRL_version(WOLFSSL_X509_CRL* crl)
10456
{
10457
    if (crl == NULL || crl->crlList == NULL)
10458
        return 0;
10459
10460
    return crl->crlList->version;
10461
}
10462
10463
/* Set version of CRL
10464
 * Caller passes the RFC 5280 value: 0 for v1, 1 for v2.
10465
 * Internally wolfSSL stores version + 1 (v1 = 1, v2 = 2) to match
10466
 * what ParseCRL produces, so apply the same normalization here.
10467
 * return WOLFSSL_SUCCESS on success
10468
 * return WOLFSSL_FAILURE on failure
10469
 */
10470
int wolfSSL_X509_CRL_set_version(WOLFSSL_X509_CRL* crl, long version)
10471
{
10472
    if (crl == NULL || crl->crlList == NULL)
10473
        return WOLFSSL_FAILURE;
10474
10475
    /* Only v1 (0) and v2 (1) are defined by RFC 5280. */
10476
    if (version < 0 || version > 1)
10477
        return WOLFSSL_FAILURE;
10478
10479
    /* Store as version + 1 to match internal convention. */
10480
    crl->crlList->version = (int)version + 1;
10481
    return WOLFSSL_SUCCESS;
10482
}
10483
10484
/* Retrieve sig OID from CRL
10485
 * return OID on success
10486
 * return 0 on failure
10487
 */
10488
int wolfSSL_X509_CRL_get_signature_type(WOLFSSL_X509_CRL* crl)
10489
{
10490
    if (crl == NULL || crl->crlList == NULL)
10491
        return 0;
10492
10493
    return crl->crlList->signatureOID;
10494
}
10495
10496
/* Set signature type of CRL
10497
 * return WOLFSSL_SUCCESS on success
10498
 * return WOLFSSL_FAILURE on failure
10499
 */
10500
int wolfSSL_X509_CRL_set_signature_type(WOLFSSL_X509_CRL* crl,
10501
                                        int signatureType)
10502
{
10503
    if (crl == NULL || crl->crlList == NULL)
10504
        return WOLFSSL_FAILURE;
10505
10506
    crl->crlList->signatureOID = signatureType;
10507
    return WOLFSSL_SUCCESS;
10508
}
10509
10510
/* Retrieve sig NID from CRL
10511
 * return NID on success
10512
 * return 0 on failure
10513
 */
10514
int wolfSSL_X509_CRL_get_signature_nid(const WOLFSSL_X509_CRL* crl)
10515
{
10516
    if (crl == NULL || crl->crlList == NULL)
10517
        return 0;
10518
10519
    return oid2nid(crl->crlList->signatureOID, oidSigType);
10520
}
10521
10522
/* Set signature NID of CRL
10523
 * return WOLFSSL_SUCCESS on success
10524
 * return negative value on failure
10525
 */
10526
int wolfSSL_X509_CRL_set_signature_nid(WOLFSSL_X509_CRL* crl, int nid)
10527
{
10528
    int ret = WOLFSSL_SUCCESS;
10529
    word32 oid;
10530
10531
    if (crl == NULL || crl->crlList == NULL || nid <= 0) {
10532
        ret = BAD_FUNC_ARG;
10533
    }
10534
10535
    if (ret == WOLFSSL_SUCCESS) {
10536
        oid = nid2oid(nid, oidSigType);
10537
        if (oid == (word32)-1 || oid == (word32)WOLFSSL_FATAL_ERROR) {
10538
            ret = WOLFSSL_FATAL_ERROR;
10539
        }
10540
        else {
10541
            crl->crlList->signatureOID = oid;
10542
        }
10543
    }
10544
10545
    return ret;
10546
}
10547
10548
/* Retrieve signature from CRL
10549
 * return WOLFSSL_SUCCESS on success and negative values on failure
10550
 */
10551
int wolfSSL_X509_CRL_get_signature(WOLFSSL_X509_CRL* crl,
10552
    unsigned char* buf, int* bufSz)
10553
{
10554
    WOLFSSL_ENTER("wolfSSL_X509_CRL_get_signature");
10555
10556
    if (crl == NULL || crl->crlList == NULL ||
10557
        crl->crlList->signature == NULL || bufSz == NULL)
10558
        return BAD_FUNC_ARG;
10559
10560
    if (buf != NULL) {
10561
        if (*bufSz < (int)crl->crlList->signatureSz) {
10562
            WOLFSSL_MSG("Signature buffer too small");
10563
            return BUFFER_E;
10564
        }
10565
        else {
10566
            XMEMCPY(buf, crl->crlList->signature, crl->crlList->signatureSz);
10567
        }
10568
    }
10569
    *bufSz = (int)crl->crlList->signatureSz;
10570
10571
    return WOLFSSL_SUCCESS;
10572
}
10573
10574
int wolfSSL_X509_CRL_set_signature(WOLFSSL_X509_CRL* crl,
10575
    unsigned char* buf, int bufSz)
10576
{
10577
    byte* newSig;
10578
10579
    if (crl == NULL || crl->crlList == NULL || buf == NULL || bufSz <= 0) {
10580
        return BAD_FUNC_ARG;
10581
    }
10582
10583
    /* Ensure signature buffer is allocated and large enough. */
10584
    if (crl->crlList->signature == NULL) {
10585
        crl->crlList->signature = (byte*)XMALLOC((word32)bufSz, crl->heap,
10586
                                                 DYNAMIC_TYPE_CRL_ENTRY);
10587
        if (crl->crlList->signature == NULL) {
10588
            return MEMORY_E;
10589
        }
10590
        crl->crlList->signatureSz = (word32)bufSz;
10591
    }
10592
    else if ((word32)bufSz > crl->crlList->signatureSz) {
10593
        newSig = (byte*)XMALLOC((word32)bufSz, crl->heap,
10594
                                DYNAMIC_TYPE_CRL_ENTRY);
10595
        if (newSig == NULL) {
10596
            return MEMORY_E;
10597
        }
10598
        XFREE(crl->crlList->signature, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
10599
        crl->crlList->signature = newSig;
10600
        crl->crlList->signatureSz = (word32)bufSz;
10601
    }
10602
    else {
10603
        /* Reuse existing buffer, clear contents in case new signature
10604
         * is smaller. Note that we do not shrink the buffer. */
10605
        XMEMSET(crl->crlList->signature, 0, crl->crlList->signatureSz);
10606
    }
10607
10608
    XMEMCPY(crl->crlList->signature, buf, bufSz);
10609
    crl->crlList->signatureSz = (word32)bufSz;
10610
    return WOLFSSL_SUCCESS;
10611
}
10612
10613
/* Retrieve serial number from RevokedCert
10614
 * return WOLFSSL_SUCCESS on success and negative values on failure
10615
 */
10616
int wolfSSL_X509_REVOKED_get_serial_number(RevokedCert* rev,
10617
    byte* in, int* inOutSz)
10618
{
10619
    WOLFSSL_ENTER("wolfSSL_X509_REVOKED_get_serial_number");
10620
    if (rev == NULL || inOutSz == NULL) {
10621
        return BAD_FUNC_ARG;
10622
    }
10623
10624
    if (in != NULL) {
10625
        if (*inOutSz < rev->serialSz) {
10626
            WOLFSSL_MSG("Serial buffer too small");
10627
            return BUFFER_E;
10628
        }
10629
        XMEMCPY(in, rev->serialNumber, rev->serialSz);
10630
    }
10631
    *inOutSz = rev->serialSz;
10632
10633
    return WOLFSSL_SUCCESS;
10634
}
10635
10636
const WOLFSSL_ASN1_INTEGER* wolfSSL_X509_REVOKED_get0_serial_number(const
10637
                                                      WOLFSSL_X509_REVOKED *rev)
10638
{
10639
    WOLFSSL_ENTER("wolfSSL_X509_REVOKED_get0_serial_number");
10640
10641
    if (rev != NULL) {
10642
        return rev->serialNumber;
10643
    }
10644
    else
10645
        return NULL;
10646
}
10647
10648
const WOLFSSL_ASN1_TIME* wolfSSL_X509_REVOKED_get0_revocation_date(const
10649
                                                      WOLFSSL_X509_REVOKED *rev)
10650
{
10651
    WOLFSSL_ENTER("wolfSSL_X509_REVOKED_get0_revocation_date");
10652
10653
    if (rev != NULL) {
10654
        return rev->revocationDate;
10655
    }
10656
    return NULL;
10657
}
10658
10659
10660
#ifndef NO_BIO
10661
/* print serial number out
10662
*  return WOLFSSL_SUCCESS on success
10663
*/
10664
static int X509RevokedPrintSerial(WOLFSSL_BIO* bio, RevokedCert* rev,
10665
    int indent)
10666
{
10667
    unsigned char serial[32];
10668
    int  sz = sizeof(serial);
10669
10670
    if (indent < 0) indent = 0;
10671
    if (indent > MAX_INDENT) indent = MAX_INDENT;
10672
10673
    XMEMSET(serial, 0, sz);
10674
    if (wolfSSL_X509_REVOKED_get_serial_number(rev, serial, &sz)
10675
            == WOLFSSL_SUCCESS) {
10676
        X509PrintSerial_ex(bio, serial, sz, 0, indent);
10677
    }
10678
    return WOLFSSL_SUCCESS;
10679
}
10680
10681
10682
/* print out the signature in human readable format for use with
10683
* wolfSSL_X509_CRL_print()
10684
 * return WOLFSSL_SUCCESS on success
10685
 */
10686
static int X509CRLPrintSignature(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl,
10687
        int algOnly, int indent)
10688
{
10689
    int sigSz = 0;
10690
10691
    if (wolfSSL_X509_CRL_get_signature(crl, NULL, &sigSz) <= 0) {
10692
        return WOLFSSL_FAILURE;
10693
    }
10694
10695
    if (sigSz > 0) {
10696
        unsigned char* sig;
10697
        int sigNid = wolfSSL_X509_CRL_get_signature_nid(crl);
10698
10699
        sig = (unsigned char*)XMALLOC(sigSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10700
        if (sig == NULL) {
10701
            return WOLFSSL_FAILURE;
10702
        }
10703
10704
        if (wolfSSL_X509_CRL_get_signature(crl, sig, &sigSz) <= 0) {
10705
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10706
            return WOLFSSL_FAILURE;
10707
        }
10708
10709
        if (X509PrintSignature_ex(bio, sig, sigSz, sigNid, algOnly, indent)
10710
                != WOLFSSL_SUCCESS) {
10711
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10712
            return WOLFSSL_FAILURE;
10713
        }
10714
10715
        XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10716
10717
    }
10718
10719
    return WOLFSSL_SUCCESS;
10720
}
10721
#endif /* !NO_BIO */
10722
10723
#if !defined(NO_BIO) && defined(XSNPRINTF)
10724
/* print out the extensions in human readable format for use with
10725
 * wolfSSL_X509_CRL_print()
10726
 * return WOLFSSL_SUCCESS on success
10727
 */
10728
static int X509CRLPrintExtensions(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl,
10729
        int indent)
10730
{
10731
    char tmp[MAX_WIDTH]; /* buffer for XSNPRINTF */
10732
    int  ret = 0;
10733
10734
    if (indent < 0) indent = 0;
10735
    if (indent > MAX_INDENT) indent = MAX_INDENT;
10736
10737
    if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s\n", indent, "",
10738
                "CRL extensions:") >= MAX_WIDTH) {
10739
        ret = WOLFSSL_FAILURE;
10740
    }
10741
10742
    if (ret == 0 && wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10743
        ret = WOLFSSL_FAILURE;
10744
    }
10745
10746
    if (ret == 0 && crl->crlList->crlNumberSet) {
10747
        /* Each octet needs at most 3 decimal digits, plus the NUL. */
10748
        char dec_string[CRL_MAX_NUM_SZ * 3 + 1];
10749
        int freeMp = 0;
10750
    #ifdef WOLFSSL_SMALL_STACK
10751
        mp_int* dec_num = (mp_int*)XMALLOC(sizeof(*dec_num), NULL,
10752
                            DYNAMIC_TYPE_BIGINT);
10753
        if (dec_num == NULL) {
10754
            ret = MEMORY_E;
10755
        }
10756
    #else
10757
        mp_int dec_num[1];
10758
    #endif
10759
10760
        if (ret == 0 && (mp_init(dec_num) != MP_OKAY)) {
10761
             ret = MP_INIT_E;
10762
        }
10763
        else if (ret == 0) {
10764
            freeMp = 1;
10765
        }
10766
10767
        if (ret == 0 && mp_read_radix(dec_num, (char *)crl->crlList->crlNumber,
10768
                    MP_RADIX_HEX) != MP_OKAY) {
10769
            ret = WOLFSSL_FAILURE;
10770
        }
10771
10772
        if (ret == 0 && mp_toradix(dec_num, dec_string, MP_RADIX_DEC)
10773
                    != MP_OKAY) {
10774
            ret = WOLFSSL_FAILURE;
10775
        }
10776
10777
        if (ret == 0 && XSNPRINTF(tmp, MAX_WIDTH, "%*s%s\n", indent + 4, "",
10778
                    "X509v3 CRL Number:") >= MAX_WIDTH) {
10779
            ret = WOLFSSL_FAILURE;
10780
        }
10781
10782
        if (ret == 0 && wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10783
            ret = WOLFSSL_FAILURE;
10784
        }
10785
10786
        if (ret == 0 && XSNPRINTF(tmp, MAX_WIDTH, "%*s", indent + 8, "")
10787
                >= MAX_WIDTH) {
10788
            ret = WOLFSSL_FAILURE;
10789
        }
10790
10791
        if (ret == 0 &&
10792
                ((wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) ||
10793
                 (wolfSSL_BIO_write(bio, dec_string,
10794
                     (int)XSTRLEN(dec_string)) <= 0) ||
10795
                 (wolfSSL_BIO_write(bio, "\n", 1) <= 0))) {
10796
            ret = WOLFSSL_FAILURE;
10797
        }
10798
10799
        XMEMSET(tmp, 0, sizeof(tmp));
10800
10801
        if (freeMp) {
10802
            mp_free(dec_num);
10803
        }
10804
10805
        WC_FREE_VAR_EX(dec_num, NULL, DYNAMIC_TYPE_BIGINT);
10806
    }
10807
10808
#if !defined(NO_SKID)
10809
    if (ret == 0 && crl->crlList->extAuthKeyIdSet &&
10810
            crl->crlList->extAuthKeyId[0] != 0) {
10811
        word32 i;
10812
        char val[5];
10813
        int valSz = 5;
10814
10815
        if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s", indent + 4, "",
10816
                    "X509v3 Authority Key Identifier:") >= MAX_WIDTH) {
10817
            ret = WOLFSSL_FAILURE;
10818
        }
10819
10820
        if (ret == 0) {
10821
            XSTRNCAT(tmp, "\n", MAX_WIDTH - XSTRLEN(tmp) - 1);
10822
        }
10823
10824
        if (ret == 0 && wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10825
            ret = WOLFSSL_FAILURE;
10826
        }
10827
        XMEMSET(tmp, 0, MAX_WIDTH);
10828
10829
        if (ret == 0 && XSNPRINTF(tmp, MAX_WIDTH - 1, "%*s%s",
10830
                    indent + 8, "", "keyid") >= MAX_WIDTH) {
10831
            ret = WOLFSSL_FAILURE;
10832
        }
10833
10834
10835
        for (i = 0; i < XSTRLEN((char*)crl->crlList->extAuthKeyId); i++) {
10836
            /* check if buffer is almost full */
10837
            if (ret == 0 && XSTRLEN(tmp) >= sizeof(tmp) - valSz) {
10838
                if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10839
                    ret = WOLFSSL_FAILURE;
10840
                }
10841
                tmp[0] = '\0';
10842
            }
10843
            if (ret == 0 && XSNPRINTF(val, (size_t)valSz, ":%02X",
10844
                    crl->crlList->extAuthKeyId[i]) >= valSz) {
10845
                WOLFSSL_MSG("buffer overrun");
10846
                ret = WOLFSSL_FAILURE;
10847
            }
10848
            if (ret == 0) {
10849
                XSTRNCAT(tmp, val, valSz);
10850
            }
10851
        }
10852
        if (ret == 0) {
10853
            XSTRNCAT(tmp, "\n", XSTRLEN("\n") + 1);
10854
        }
10855
        if (ret == 0 && wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10856
            ret = WOLFSSL_FAILURE;
10857
        }
10858
    }
10859
#endif
10860
10861
    if (ret == 0) {
10862
        ret = WOLFSSL_SUCCESS;
10863
    }
10864
10865
    return ret;
10866
}
10867
10868
/* iterate through a CRL's Revoked Certs and print out in human
10869
 * readable format for use with wolfSSL_X509_CRL_print()
10870
 * return WOLFSSL_SUCCESS on success
10871
 */
10872
static int X509CRLPrintRevoked(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl,
10873
        int indent)
10874
{
10875
    char tmp[MAX_WIDTH]; /* buffer for XSNPRINTF */
10876
    int i;
10877
10878
    if (crl->crlList->totalCerts > 0) {
10879
        RevokedCert* revoked = crl->crlList->certs;
10880
10881
        if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s\n", indent, "",
10882
                    "Revoked Certificates:") >= MAX_WIDTH) {
10883
            return WOLFSSL_FAILURE;
10884
        }
10885
10886
        if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10887
            return WOLFSSL_FAILURE;
10888
        }
10889
        XMEMSET(tmp, 0, MAX_WIDTH);
10890
10891
        for (i = 0; i < crl->crlList->totalCerts; i++) {
10892
            if (revoked->serialSz > 0) {
10893
                if (X509RevokedPrintSerial(bio, revoked, indent + 4)
10894
                        != WOLFSSL_SUCCESS) {
10895
                    return WOLFSSL_FAILURE;
10896
                }
10897
            }
10898
        #ifndef NO_ASN_TIME
10899
             if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s", indent + 8, "",
10900
                         "Revocation Date: ") >= MAX_WIDTH) {
10901
                return WOLFSSL_FAILURE;
10902
            }
10903
10904
            if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10905
                return WOLFSSL_FAILURE;
10906
            }
10907
10908
            if (revoked->revDate[0] != 0) {
10909
                if (GetTimeString(revoked->revDate, ASN_UTC_TIME,
10910
                    tmp, MAX_WIDTH, MAX_DATE_SIZE) != WOLFSSL_SUCCESS) {
10911
                    if (GetTimeString(revoked->revDate, ASN_GENERALIZED_TIME,
10912
                    tmp, MAX_WIDTH, MAX_DATE_SIZE) != WOLFSSL_SUCCESS) {
10913
                        WOLFSSL_MSG("Error getting revocation date");
10914
                        return WOLFSSL_FAILURE;
10915
                    }
10916
                }
10917
            }
10918
            else {
10919
                XSTRNCPY(tmp, "Not Set", MAX_WIDTH-1);
10920
            }
10921
            tmp[MAX_WIDTH - 1] = '\0'; /* make sure null terminated */
10922
            if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10923
                return WOLFSSL_FAILURE;
10924
            }
10925
10926
            if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) {
10927
                return WOLFSSL_FAILURE;
10928
            }
10929
        #endif
10930
            revoked = revoked->next;
10931
        }
10932
    }
10933
    else {
10934
        if (wolfSSL_BIO_write(bio, "No Revoked Certificates.\n",
10935
                       (int)XSTRLEN("No Revoked Certificates.\n")) <= 0) {
10936
            return WOLFSSL_FAILURE;
10937
        }
10938
    }
10939
10940
    return WOLFSSL_SUCCESS;
10941
}
10942
10943
#ifndef NO_ASN_TIME
10944
/* print out the last/next update times in human readable
10945
 * format for use with wolfSSL_X509_CRL_print()
10946
 * return WOLFSSL_SUCCESS on success
10947
 */
10948
static int X509CRLPrintDates(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl,
10949
        int indent)
10950
{
10951
    char tmp[MAX_WIDTH]; /* buffer for XSNPRINTF */
10952
10953
    if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s", indent, "",
10954
                "Last Update: ") >= MAX_WIDTH) {
10955
        return WOLFSSL_FAILURE;
10956
    }
10957
10958
    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10959
        return WOLFSSL_FAILURE;
10960
    }
10961
10962
    if (crl->crlList->lastDate[0] != 0) {
10963
        if (GetTimeString(crl->crlList->lastDate, crl->crlList->lastDateFormat,
10964
            tmp, MAX_WIDTH, MAX_DATE_SIZE) != WOLFSSL_SUCCESS) {
10965
            WOLFSSL_MSG("Error getting last update date");
10966
            return WOLFSSL_FAILURE;
10967
        }
10968
    }
10969
    else {
10970
        XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
10971
    }
10972
    tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
10973
    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10974
        return WOLFSSL_FAILURE;
10975
    }
10976
10977
    if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) {
10978
        return WOLFSSL_FAILURE;
10979
    }
10980
10981
    if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s", indent, "",
10982
                "Next Update: ") >= MAX_WIDTH) {
10983
        return WOLFSSL_FAILURE;
10984
    }
10985
10986
    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
10987
        return WOLFSSL_FAILURE;
10988
    }
10989
10990
    if (crl->crlList->nextDate[0] != 0) {
10991
        if (GetTimeString(crl->crlList->nextDate, crl->crlList->nextDateFormat,
10992
            tmp, MAX_WIDTH, MAX_DATE_SIZE) != WOLFSSL_SUCCESS) {
10993
            WOLFSSL_MSG("Error getting next update date");
10994
            return WOLFSSL_FAILURE;
10995
        }
10996
    }
10997
    else {
10998
        XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
10999
    }
11000
    tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
11001
    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
11002
        return WOLFSSL_FAILURE;
11003
    }
11004
11005
    if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) {
11006
        return WOLFSSL_FAILURE;
11007
    }
11008
11009
    return WOLFSSL_SUCCESS;
11010
}
11011
#endif
11012
11013
/* Writes the human readable form of x509 to bio.
11014
 *
11015
 * bio  WOLFSSL_BIO to write to.
11016
 * crl Certificate revocation list to write.
11017
 *
11018
 * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
11019
 */
11020
int wolfSSL_X509_CRL_print(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl)
11021
{
11022
    char issuType[] = "Issuer: ";
11023
11024
    if (bio == NULL || crl == NULL || crl->crlList == NULL) {
11025
        return WOLFSSL_FAILURE;
11026
    }
11027
11028
    if (wolfSSL_BIO_write(bio, "Certificate Revocation List (CRL):\n",
11029
                  (int)XSTRLEN("Certificate Revocation List (CRL):\n")) <= 0) {
11030
            return WOLFSSL_FAILURE;
11031
    }
11032
11033
    /* print version */
11034
    if (X509PrintVersion(bio, wolfSSL_X509_CRL_version(crl), 8)
11035
            != WOLFSSL_SUCCESS) {
11036
        return WOLFSSL_FAILURE;
11037
    }
11038
11039
    /* print signature algo */
11040
    if (X509CRLPrintSignature(bio, crl, 1, 8) != WOLFSSL_SUCCESS) {
11041
        return WOLFSSL_FAILURE;
11042
    }
11043
11044
    /* print issuer name */
11045
    if (X509PrintName(bio, wolfSSL_X509_CRL_get_issuer_name(crl), issuType, 8)
11046
            != WOLFSSL_SUCCESS) {
11047
        return WOLFSSL_FAILURE;
11048
    }
11049
11050
#ifndef NO_ASN_TIME
11051
    /* print last and next update times */
11052
    if (X509CRLPrintDates(bio, crl, 8) != WOLFSSL_SUCCESS) {
11053
        return WOLFSSL_FAILURE;
11054
    }
11055
#endif
11056
11057
    /* print CRL extensions */
11058
    if (X509CRLPrintExtensions(bio, crl, 8) != WOLFSSL_SUCCESS) {
11059
        return WOLFSSL_FAILURE;
11060
    }
11061
11062
    /* print CRL Revoked Certs */
11063
    if (X509CRLPrintRevoked(bio, crl, 0) != WOLFSSL_SUCCESS) {
11064
        return WOLFSSL_FAILURE;
11065
    }
11066
11067
    if (X509CRLPrintSignature(bio, crl, 0, 4) != WOLFSSL_SUCCESS) {
11068
        return WOLFSSL_FAILURE;
11069
    }
11070
11071
    if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
11072
        return WOLFSSL_FAILURE;
11073
    }
11074
11075
    return WOLFSSL_SUCCESS;
11076
}
11077
#endif /* !NO_BIO && XSNPRINTF */
11078
#endif /* HAVE_CRL */
11079
#endif /* OPENSSL_EXTRA */
11080
11081
#if defined(HAVE_CRL) && (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL))
11082
void wolfSSL_X509_CRL_free(WOLFSSL_X509_CRL *crl)
11083
{
11084
    WOLFSSL_ENTER("wolfSSL_X509_CRL_free");
11085
11086
    if (crl)
11087
        FreeCRL(crl, 1);
11088
}
11089
#endif /* HAVE_CRL && (OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL) */
11090
11091
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA)
11092
WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_lastUpdate(WOLFSSL_X509_CRL* crl)
11093
{
11094
    if ((crl != NULL) && (crl->crlList != NULL) &&
11095
        (crl->crlList->lastDateAsn1.data[0] != 0)) {
11096
        return &crl->crlList->lastDateAsn1;
11097
    }
11098
    return NULL;
11099
}
11100
11101
int wolfSSL_X509_CRL_set_lastUpdate(WOLFSSL_X509_CRL* crl,
11102
                                    const WOLFSSL_ASN1_TIME* time)
11103
{
11104
    if (crl != NULL && crl->crlList != NULL && time != NULL) {
11105
        crl->crlList->lastDateAsn1 = *time;
11106
        return WOLFSSL_SUCCESS;
11107
    }
11108
    return WOLFSSL_FAILURE;
11109
}
11110
11111
WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_nextUpdate(WOLFSSL_X509_CRL* crl)
11112
{
11113
    if ((crl != NULL) && (crl->crlList != NULL) &&
11114
        (crl->crlList->nextDateAsn1.data[0] != 0)) {
11115
        return &crl->crlList->nextDateAsn1;
11116
    }
11117
    return NULL;
11118
}
11119
11120
int wolfSSL_X509_CRL_set_nextUpdate(WOLFSSL_X509_CRL* crl,
11121
                                    const WOLFSSL_ASN1_TIME* time)
11122
{
11123
    if (crl != NULL && crl->crlList != NULL && time != NULL) {
11124
        crl->crlList->nextDateAsn1 = *time;
11125
        return WOLFSSL_SUCCESS;
11126
    }
11127
    return WOLFSSL_FAILURE;
11128
}
11129
11130
#ifndef NO_WOLFSSL_STUB
11131
int wolfSSL_X509_CRL_verify(WOLFSSL_X509_CRL* crl, WOLFSSL_EVP_PKEY* key)
11132
{
11133
    (void)crl;
11134
    (void)key;
11135
    WOLFSSL_STUB("X509_CRL_verify");
11136
    return 0;
11137
}
11138
#endif
11139
11140
/* Encode CRL to DER format in memory.
11141
 *
11142
 * If *out is NULL, allocates memory and returns it via *out.
11143
 * If *out is not NULL, writes DER data starting at *out.
11144
 *
11145
 * @param crl  CRL to encode
11146
 * @param out  Pointer to output buffer pointer
11147
 * @return     Size of DER encoding on success, WOLFSSL_FAILURE on failure
11148
 */
11149
int wolfSSL_i2d_X509_CRL(WOLFSSL_X509_CRL* crl, unsigned char** out)
11150
{
11151
    int ret;
11152
    long derSz = 0;
11153
    byte* der = NULL;
11154
    int alloced = 0;
11155
11156
    WOLFSSL_ENTER("wolfSSL_i2d_X509_CRL");
11157
11158
    if (crl == NULL) {
11159
        return BAD_FUNC_ARG;
11160
    }
11161
11162
    /* Get required size */
11163
    ret = BufferStoreCRL(crl, NULL, &derSz, WOLFSSL_FILETYPE_ASN1);
11164
    if (ret != WOLFSSL_SUCCESS || derSz <= 0) {
11165
        WOLFSSL_MSG("BufferStoreCRL failed to get size");
11166
        return WOLFSSL_FAILURE;
11167
    }
11168
11169
    if (out == NULL) {
11170
        /* Just return size */
11171
        return (int)derSz;
11172
    }
11173
11174
    if (*out == NULL) {
11175
        /* Allocate output buffer */
11176
        der = (byte*)XMALLOC((size_t)derSz, NULL, DYNAMIC_TYPE_OPENSSL);
11177
        if (der == NULL) {
11178
            WOLFSSL_MSG("Memory allocation failed");
11179
            return MEMORY_E;
11180
        }
11181
        alloced = 1;
11182
    }
11183
    else {
11184
        der = *out;
11185
    }
11186
11187
    /* Encode CRL to DER */
11188
    ret = BufferStoreCRL(crl, der, &derSz, WOLFSSL_FILETYPE_ASN1);
11189
    if (ret != WOLFSSL_SUCCESS) {
11190
        WOLFSSL_MSG("BufferStoreCRL failed to encode");
11191
        if (alloced) {
11192
            XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
11193
        }
11194
        return WOLFSSL_FAILURE;
11195
    }
11196
11197
    if (alloced) {
11198
        *out = der;
11199
    }
11200
    else {
11201
        *out += derSz;
11202
    }
11203
11204
    return (int)derSz;
11205
}
11206
11207
#ifndef NO_BIO
11208
/* Write the DER encoding of a CRL to a BIO.
11209
 *
11210
 * @param bio  BIO to write to
11211
 * @param crl  CRL to encode
11212
 * @return     WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure
11213
 */
11214
int wolfSSL_i2d_X509_CRL_bio(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl)
11215
{
11216
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
11217
    int derSz;
11218
    unsigned char* der = NULL;
11219
11220
    WOLFSSL_ENTER("wolfSSL_i2d_X509_CRL_bio");
11221
11222
    if ((bio == NULL) || (crl == NULL)) {
11223
        return WOLFSSL_FAILURE;
11224
    }
11225
11226
    derSz = wolfSSL_i2d_X509_CRL(crl, &der);
11227
    if ((derSz > 0) && (der != NULL) &&
11228
            (wolfSSL_BIO_write(bio, der, derSz) == derSz)) {
11229
        ret = WOLFSSL_SUCCESS;
11230
    }
11231
    XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
11232
11233
    return ret;
11234
}
11235
#endif /* !NO_BIO */
11236
#endif /* HAVE_CRL && OPENSSL_EXTRA */
11237
11238
#if defined(WOLFSSL_CERT_EXT) && \
11239
    (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
11240
/* Set CRL Distribution Points from pre-encoded DER.
11241
 *
11242
 * x509  - Certificate to modify
11243
 * der   - Pre-encoded CRLDistributionPoints DER
11244
 * derSz - Size of DER in bytes
11245
 *
11246
 * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
11247
 */
11248
int wolfSSL_X509_CRL_set_dist_points(WOLFSSL_X509* x509,
11249
    const unsigned char* der, int derSz)
11250
{
11251
    WOLFSSL_ENTER("wolfSSL_X509_CRL_set_dist_points");
11252
11253
    if (x509 == NULL || der == NULL || derSz <= 0) {
11254
        return WOLFSSL_FAILURE;
11255
    }
11256
11257
    if (x509->rawCRLInfo != NULL) {
11258
        XFREE(x509->rawCRLInfo, x509->heap, DYNAMIC_TYPE_X509_EXT);
11259
    }
11260
    x509->rawCRLInfo = (byte*)XMALLOC((word32)derSz, x509->heap,
11261
                                       DYNAMIC_TYPE_X509_EXT);
11262
    if (x509->rawCRLInfo == NULL) {
11263
        return WOLFSSL_FAILURE;
11264
    }
11265
11266
    XMEMCPY(x509->rawCRLInfo, der, (word32)derSz);
11267
    x509->rawCRLInfoSz = derSz;
11268
    x509->CRLdistSet = 1;
11269
11270
    return WOLFSSL_SUCCESS;
11271
}
11272
11273
/* Add CRL Distribution Point URI.
11274
 * Encodes URI into proper CRLDistributionPoints DER format.
11275
 *
11276
 * x509     - Certificate to modify
11277
 * uri      - URI string (e.g., "http://crl.example.com/ca.crl")
11278
 * critical - Whether extension is critical
11279
 *
11280
 * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
11281
 */
11282
int wolfSSL_X509_CRL_add_dist_point(WOLFSSL_X509* x509,
11283
    const char* uri, int critical)
11284
{
11285
    word32 uriLen;
11286
    byte* derBuf = NULL;
11287
    word32 derSz;
11288
    word32 idx;
11289
    word32 uriTagLen;    /* [6] tag + length + URI */
11290
    word32 genNamesLen;  /* [0] IMPLICIT GeneralNames wrapper */
11291
    word32 distPtNmLen;  /* [0] EXPLICIT distributionPoint wrapper */
11292
    word32 distPtSeqLen; /* SEQUENCE for DistributionPoint */
11293
    word32 outerSeqLen;  /* SEQUENCE for CRLDistributionPoints */
11294
    int ret = WOLFSSL_SUCCESS;
11295
11296
    WOLFSSL_ENTER("wolfSSL_X509_CRL_add_dist_point");
11297
11298
    if (x509 == NULL || uri == NULL) {
11299
        return WOLFSSL_FAILURE;
11300
    }
11301
11302
    uriLen = (word32)XSTRLEN(uri);
11303
    if (uriLen == 0) {
11304
        WOLFSSL_MSG("URI empty");
11305
        return WOLFSSL_FAILURE;
11306
    }
11307
11308
    /*
11309
     * Encode CRL Distribution Points in DER format:
11310
     * CRLDistributionPoints ::= SEQUENCE OF DistributionPoint
11311
     * DistributionPoint ::= SEQUENCE {
11312
     *     distributionPoint [0] EXPLICIT DistributionPointName OPTIONAL
11313
     * }
11314
     * DistributionPointName ::= CHOICE {
11315
     *     fullName [0] IMPLICIT GeneralNames
11316
     * }
11317
     * GeneralNames ::= SEQUENCE OF GeneralName
11318
     * GeneralName ::= [6] IMPLICIT IA5String (uniformResourceIdentifier)
11319
     */
11320
11321
    /* Calculate sizes from innermost to outermost */
11322
    /* [6] tag (1 byte) + length encoding + URI data */
11323
    uriTagLen = ASN_TAG_SZ + SetLength(uriLen, NULL) + uriLen;
11324
    /* [0] CONSTRUCTED tag (1 byte) + length encoding + uriTagLen */
11325
    genNamesLen = ASN_TAG_SZ + SetLength(uriTagLen, NULL) + uriTagLen;
11326
    /* [0] CONSTRUCTED tag (1 byte) + length encoding + genNamesLen */
11327
    distPtNmLen = ASN_TAG_SZ + SetLength(genNamesLen, NULL) + genNamesLen;
11328
    /* SEQUENCE header + distPtNmLen */
11329
    distPtSeqLen = SetSequence(distPtNmLen, NULL) + distPtNmLen;
11330
    /* Outer SEQUENCE header + distPtSeqLen */
11331
    outerSeqLen = SetSequence(distPtSeqLen, NULL) + distPtSeqLen;
11332
11333
    derSz = outerSeqLen;
11334
11335
    /* Allocate buffer for DER encoding */
11336
    derBuf = (byte*)XMALLOC(derSz, x509->heap, DYNAMIC_TYPE_X509_EXT);
11337
    if (derBuf == NULL) {
11338
        return WOLFSSL_FAILURE;
11339
    }
11340
11341
    /* Build forward using SetSequence/SetHeader/SetLength */
11342
    idx = 0;
11343
11344
    /* SEQUENCE for CRLDistributionPoints (outer) */
11345
    idx += SetSequence(distPtSeqLen, derBuf + idx);
11346
11347
    /* SEQUENCE for DistributionPoint */
11348
    idx += SetSequence(distPtNmLen, derBuf + idx);
11349
11350
    /* [0] EXPLICIT wrapper for distributionPoint */
11351
    derBuf[idx++] = (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED);
11352
    idx += SetLength(genNamesLen, derBuf + idx);
11353
11354
    /* [0] IMPLICIT wrapper for GeneralNames (constructed) */
11355
    derBuf[idx++] = (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED);
11356
    idx += SetLength(uriTagLen, derBuf + idx);
11357
11358
    /* [6] IMPLICIT IA5String tag for URI (context-specific, primitive) */
11359
    derBuf[idx++] = (ASN_CONTEXT_SPECIFIC | 6); /* [6] tag */
11360
    idx += SetLength(uriLen, derBuf + idx);
11361
11362
    /* Copy URI string */
11363
    XMEMCPY(derBuf + idx, uri, uriLen);
11364
    idx += uriLen;
11365
11366
    /* Store the encoded CRL info in x509 */
11367
    {
11368
        ret = wolfSSL_X509_CRL_set_dist_points(x509, derBuf, (int)idx);
11369
        if (ret == WOLFSSL_SUCCESS && critical) {
11370
            x509->CRLdistCrit = 1;
11371
        }
11372
    }
11373
11374
    XFREE(derBuf, x509->heap, DYNAMIC_TYPE_X509_EXT);
11375
11376
    return ret;
11377
}
11378
#endif /* WOLFSSL_CERT_EXT && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */
11379
11380
#ifdef OPENSSL_EXTRA
11381
11382
11383
WOLFSSL_X509_VERIFY_PARAM* wolfSSL_X509_VERIFY_PARAM_new(void)
11384
{
11385
    WOLFSSL_X509_VERIFY_PARAM *param = NULL;
11386
    param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC(
11387
            sizeof(WOLFSSL_X509_VERIFY_PARAM), NULL, DYNAMIC_TYPE_OPENSSL);
11388
    if (param != NULL)
11389
        XMEMSET(param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM ));
11390
11391
    return(param);
11392
}
11393
11394
11395
void wolfSSL_X509_VERIFY_PARAM_free(WOLFSSL_X509_VERIFY_PARAM *param)
11396
{
11397
    XFREE(param, NULL, DYNAMIC_TYPE_OPENSSL);
11398
}
11399
11400
11401
/* Sets flags by OR'ing with existing value. */
11402
int wolfSSL_X509_VERIFY_PARAM_set_flags(WOLFSSL_X509_VERIFY_PARAM *param,
11403
        unsigned long flags)
11404
{
11405
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
11406
11407
    if (param != NULL) {
11408
        param->flags |= flags;
11409
        ret = WOLFSSL_SUCCESS;
11410
    }
11411
11412
    return ret;
11413
}
11414
11415
11416
/* Sets the verification time and makes verification use it. */
11417
void wolfSSL_X509_VERIFY_PARAM_set_time(WOLFSSL_X509_VERIFY_PARAM *param,
11418
        time_t t)
11419
{
11420
    if (param != NULL) {
11421
        param->check_time = t;
11422
        param->flags |= WOLFSSL_USE_CHECK_TIME;
11423
    }
11424
}
11425
11426
11427
int wolfSSL_X509_VERIFY_PARAM_get_flags(WOLFSSL_X509_VERIFY_PARAM *param)
11428
{
11429
    int ret = 0;
11430
11431
    if (param != NULL) {
11432
        ret = (int)param->flags;
11433
    }
11434
11435
    return ret;
11436
}
11437
11438
11439
int wolfSSL_X509_VERIFY_PARAM_clear_flags(WOLFSSL_X509_VERIFY_PARAM *param,
11440
        unsigned long flags)
11441
{
11442
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
11443
11444
    if (param != NULL) {
11445
        param->flags &= ~flags;
11446
        ret = WOLFSSL_SUCCESS;
11447
    }
11448
11449
    return ret;
11450
}
11451
11452
/* note WOLFSSL_X509_VERIFY_PARAM does not record purpose, trust, depth, or
11453
 * auth_level.
11454
 */
11455
static const WOLFSSL_X509_VERIFY_PARAM x509_verify_param_builtins[] = {
11456
    {
11457
     "ssl_client",              /* name */
11458
     0,                         /* check_time */
11459
     0,                         /* inherit_flags */
11460
     0,                         /* flags */
11461
     "",                        /* hostname */
11462
     0,                         /* hostFlags */
11463
     ""                         /* ipasc */
11464
    },
11465
    {
11466
     "ssl_server",              /* name */
11467
     0,                         /* check_time */
11468
     0,                         /* inherit_flags */
11469
     0,                         /* flags */
11470
     "",                        /* hostname */
11471
     0,                         /* hostFlags */
11472
     ""                         /* ipasc */
11473
    }
11474
};
11475
11476
const WOLFSSL_X509_VERIFY_PARAM *wolfSSL_X509_VERIFY_PARAM_lookup(
11477
    const char *name)
11478
{
11479
    const WOLFSSL_X509_VERIFY_PARAM *param = &x509_verify_param_builtins[0],
11480
        *param_end = &x509_verify_param_builtins[
11481
                                         XELEM_CNT(x509_verify_param_builtins)];
11482
11483
    if (name == NULL) {
11484
        return NULL;
11485
    }
11486
    while (param < param_end) {
11487
        if (XSTRCMP(name, param->name) == 0)
11488
            return param;
11489
        ++param;
11490
    }
11491
    return NULL;
11492
}
11493
11494
/* inherits properties of param "to" to param "from"
11495
*
11496
* WOLFSSL_VPARAM_DEFAULT          any values in "src" is copied
11497
*                                 if "src" value is new for "to".
11498
* WOLFSSL_VPARAM_OVERWRITE        all values of "form" are copied to "to"
11499
* WOLFSSL_VPARAM_RESET_FLAGS      the flag values are copied, not Ored
11500
* WOLFSSL_VPARAM_LOCKED           don't copy any values
11501
* WOLFSSL_VPARAM_ONCE             the current inherit_flags is zerroed
11502
*/
11503
int wolfSSL_X509_VERIFY_PARAM_inherit(WOLFSSL_X509_VERIFY_PARAM *to,
11504
                                         const WOLFSSL_X509_VERIFY_PARAM *from)
11505
{
11506
    int ret = WOLFSSL_SUCCESS;
11507
    int isOverWrite = 0;
11508
    int isDefault = 0;
11509
    unsigned int flags;
11510
11511
    /* sanity check */
11512
    if (!to || !from) {
11513
        /* be compatible to openssl return value */
11514
        return WOLFSSL_SUCCESS;
11515
    }
11516
    flags = to->inherit_flags | from->inherit_flags;
11517
11518
    if (flags & WOLFSSL_VPARAM_LOCKED) {
11519
        return WOLFSSL_SUCCESS;
11520
    }
11521
11522
    if (flags & WOLFSSL_VPARAM_ONCE) {
11523
        to->inherit_flags = 0;
11524
    }
11525
11526
    isOverWrite = (flags & WOLFSSL_VPARAM_OVERWRITE);
11527
    isDefault = (flags & WOLFSSL_VPARAM_DEFAULT);
11528
11529
    /* copy check_time if check time is not set */
11530
    if ((to->flags & WOLFSSL_USE_CHECK_TIME) == 0 || isOverWrite) {
11531
           to->check_time = from->check_time;
11532
           to->flags &= ~WOLFSSL_USE_CHECK_TIME;
11533
    }
11534
    /* host name */
11535
    if (isOverWrite ||
11536
        (from->hostName[0] != 0 && (to->hostName[0] == 0 || isDefault))) {
11537
            if (!(ret = wolfSSL_X509_VERIFY_PARAM_set1_host(to, from->hostName,
11538
                (unsigned int)XSTRLEN(from->hostName))))
11539
                return ret;
11540
    }
11541
    /* host flags */
11542
    if (isOverWrite ||
11543
        (from->hostFlags != 0 && (to->hostFlags == 0 || isDefault))) {
11544
        to->hostFlags = from->hostFlags;
11545
    }
11546
    /* ip ascii */
11547
    if (isOverWrite ||
11548
        (from->ipasc[0] != 0 && (to->ipasc[0] == 0 || isDefault))) {
11549
11550
            if (!(ret = wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(to, from->ipasc)))
11551
                return ret;
11552
    }
11553
11554
    if (flags & WOLFSSL_VPARAM_RESET_FLAGS)
11555
        to->flags = 0;
11556
11557
    to->flags |= from->flags;
11558
11559
    return ret;
11560
}
11561
11562
/******************************************************************************
11563
* wolfSSL_X509_VERIFY_PARAM_set1_host - sets the DNS hostname to name
11564
* Hostname is cleared if name is NULL or empty.
11565
*
11566
* If nameSz is zero, name must be NUL-terminated.
11567
* Otherwise, nameSz specifies the input length and may include one
11568
* trailing NUL. Embedded NULs are rejected without changing the
11569
* previously configured hostname.
11570
*
11571
* RETURNS:
11572
* WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on invalid input.
11573
*
11574
*/
11575
int wolfSSL_X509_VERIFY_PARAM_set1_host(WOLFSSL_X509_VERIFY_PARAM* pParam,
11576
                                         const char* name,
11577
                                         unsigned int nameSz)
11578
{
11579
    unsigned int i;
11580
11581
    WOLFSSL_ENTER("wolfSSL_X509_VERIFY_PARAM_set1_host");
11582
11583
    if (pParam == NULL)
11584
        return WOLFSSL_FAILURE;
11585
11586
    /* If name is NULL, clear hostname. */
11587
    if (name == NULL) {
11588
        XMEMSET(pParam->hostName, 0, WOLFSSL_HOST_NAME_MAX);
11589
        return WOLFSSL_SUCCESS;
11590
    }
11591
11592
    /* If name is NULL-terminated, namelen can be set to zero. */
11593
    if (nameSz == 0) {
11594
        nameSz = (unsigned int)XSTRLEN(name);
11595
    }
11596
11597
    if (nameSz > 0 && name[nameSz - 1] == '\0')
11598
        nameSz--;
11599
11600
    /* Reject embedded NULs before changing the hostname policy. */
11601
    for (i = 0; i < nameSz; i++) {
11602
        if (name[i] == '\0') {
11603
            return WOLFSSL_FAILURE;
11604
        }
11605
    }
11606
11607
    if (nameSz > WOLFSSL_HOST_NAME_MAX-1) {
11608
        WOLFSSL_MSG("Truncating name");
11609
        nameSz = WOLFSSL_HOST_NAME_MAX-1;
11610
    }
11611
11612
    if (nameSz > 0) {
11613
        XMEMCPY(pParam->hostName, name, nameSz);
11614
        XMEMSET(pParam->hostName + nameSz, 0,
11615
                WOLFSSL_HOST_NAME_MAX - nameSz);
11616
    }
11617
11618
    pParam->hostName[nameSz] = '\0';
11619
11620
    return WOLFSSL_SUCCESS;
11621
}
11622
11623
/* Set VERIFY PARAM from "from" pointer to "to" pointer */
11624
int wolfSSL_X509_VERIFY_PARAM_set1(WOLFSSL_X509_VERIFY_PARAM *to,
11625
                                   const WOLFSSL_X509_VERIFY_PARAM *from)
11626
{
11627
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
11628
    unsigned int _inherit_flags;
11629
11630
    if (!to) {
11631
        return ret;
11632
    }
11633
    /* keeps the inherit flags for save */
11634
    _inherit_flags = to->inherit_flags;
11635
11636
    /* Ored DEFAULT inherit flag property to copy "from" contents to "to"
11637
    *  contents
11638
    */
11639
    to->inherit_flags |= WOLFSSL_VPARAM_DEFAULT;
11640
11641
    ret = wolfSSL_X509_VERIFY_PARAM_inherit(to, from);
11642
11643
    /* restore inherit flag */
11644
    to->inherit_flags = _inherit_flags;
11645
11646
    return ret;
11647
}
11648
11649
/* Set the host flag in the X509_VERIFY_PARAM structure */
11650
void wolfSSL_X509_VERIFY_PARAM_set_hostflags(WOLFSSL_X509_VERIFY_PARAM* param,
11651
                                             unsigned int flags)
11652
{
11653
    if (param != NULL) {
11654
        param->hostFlags = flags;
11655
    }
11656
}
11657
11658
/* Sets the expected IP address to ipasc.
11659
 *
11660
 * param is a pointer to the X509_VERIFY_PARAM structure
11661
 * ipasc is a NULL-terminated string with N.N.N.N for IPv4 and
11662
 *       HH:HH ... HH:HH for IPv6. There is no validation performed on the
11663
 *       parameter, and it must be an exact match with the IP in the cert.
11664
 *
11665
 * return 1 for success and 0 for failure*/
11666
int wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(WOLFSSL_X509_VERIFY_PARAM *param,
11667
        const char *ipasc)
11668
{
11669
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
11670
11671
    if (param != NULL) {
11672
        if (ipasc == NULL) {
11673
            param->ipasc[0] = '\0';
11674
        }
11675
        else {
11676
            XSTRLCPY(param->ipasc, ipasc, WOLFSSL_MAX_IPSTR);
11677
            param->ipasc[WOLFSSL_MAX_IPSTR-1] = '\0';
11678
        }
11679
        ret = WOLFSSL_SUCCESS;
11680
    }
11681
11682
    return ret;
11683
}
11684
/* Sets the expected IP address to ip(asc)
11685
 *          by re-constructing IP address in ascii
11686
 * @param  param is a pointer to the X509_VERIFY_PARAM structure
11687
 * @param  ip    in binary format of ip address
11688
 * @param  iplen size of ip, 4 for ipv4, 16 for ipv6
11689
 * @return 1 for success and 0 for failure
11690
 */
11691
int wolfSSL_X509_VERIFY_PARAM_set1_ip(WOLFSSL_X509_VERIFY_PARAM* param,
11692
    const unsigned char* ip, size_t iplen)
11693
{
11694
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
11695
#ifndef NO_FILESYSTEM
11696
    char* buf = NULL;
11697
    word32 val = 0;
11698
    int i;
11699
    int n;
11700
    int runStart = 0;
11701
    int runLen = 0;
11702
    int zeroStart = -1;
11703
    int zeroLen = 0;
11704
    size_t idx = 0;
11705
    const size_t max_ipv6_len = 40;
11706
#endif
11707
11708
    /* sanity check */
11709
    if (param == NULL || (iplen != 0 && iplen != 4 && iplen != 16)) {
11710
        WOLFSSL_MSG("bad function arg");
11711
        return ret;
11712
    }
11713
    if (ip == NULL && iplen != 0) {
11714
        WOLFSSL_MSG("bad function arg");
11715
        return ret;
11716
    }
11717
#ifndef NO_FILESYSTEM
11718
    if (iplen == 4) {
11719
        /* ipv4 www.xxx.yyy.zzz max 15 length + Null termination */
11720
        buf = (char*)XMALLOC(16, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11721
        if (!buf) {
11722
            WOLFSSL_MSG("failed malloc");
11723
            return ret;
11724
        }
11725
11726
        (void)XSNPRINTF(buf, 16, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
11727
        buf[15] = '\0'; /* null terminate */
11728
    }
11729
    else if (iplen == 16) {
11730
        /* ipv6 normal address scheme
11731
        *   y1:y2:y3:y4:y5:y6:y7:y8, len(yx):4, len(y1-y8):32. len(":"):7
11732
        *   Max len is 32 + 7 + 1(Termination) = 40 bytes
11733
        *
11734
        *   ipv6 dual address
11735
        *   Or y1:y2:y3:y4:y:y6:x.x.x.x yx is 4, y1-y6 is 24, ":" is 6
11736
        *   x.x.x.x is 15.
11737
        *   Max len is 24 + 6 + 15 + 1(Termination) = 46 bytes
11738
        *
11739
        *   Expect data in ip[16]
11740
        *   e.g (aaaa):(bbbb):(cccc):....(hhhh)
11741
        *   (aaaa) = (ip[0<<8)|ip[1]
11742
        *   ......
11743
        *   (hhhh) = (ip[14]<<8)|(ip[15])
11744
        *
11745
        *   e.g ::(gggg):(hhhh)
11746
        *   ip[0]-[11] = 0
11747
        *   (gggg) = (ip[12]<<8) |(ip[13])
11748
        *   (hhhh) = (ip[14]<<8) |(ip[15])
11749
        *
11750
        *   Because it is not able to know which ivp6 scheme uses from data to
11751
        *   reconstruct IP address, this function assumes
11752
        *   ivp6 normal address scheme, not dual address scheme,
11753
        *   to re-construct IP address in ascii.
11754
        */
11755
        buf = (char*)XMALLOC(max_ipv6_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11756
        if (!buf) {
11757
            WOLFSSL_MSG("failed malloc");
11758
            return ret;
11759
        }
11760
        /* RFC 5952 4.2: compress only the first longest run of two or more
11761
         * zero groups, every other zero group is written as 0. */
11762
        for (i = 0; i < 8; i++) {
11763
            if (ip[2 * i] == 0 && ip[2 * i + 1] == 0) {
11764
                if (runLen == 0)
11765
                    runStart = i;
11766
                runLen++;
11767
                if (runLen > zeroLen) {
11768
                    zeroStart = runStart;
11769
                    zeroLen = runLen;
11770
                }
11771
            }
11772
            else {
11773
                runLen = 0;
11774
            }
11775
        }
11776
        if (zeroLen < 2) {
11777
            zeroStart = -1;
11778
            zeroLen = 0;
11779
        }
11780
11781
        for (i = 0; i < 8 && buf != NULL; i++) {
11782
            if (i == zeroStart) {
11783
                n = XSNPRINTF(buf + idx, max_ipv6_len - idx, "::");
11784
            }
11785
            else if (i > zeroStart && i < zeroStart + zeroLen) {
11786
                n = 0;
11787
            }
11788
            else {
11789
                val = ((word32)ip[2 * i] << 8) | ip[2 * i + 1];
11790
                n = XSNPRINTF(buf + idx, max_ipv6_len - idx, "%s%x",
11791
                    (i == 0 || i == zeroStart + zeroLen) ? "" : ":",
11792
                    (unsigned int)val);
11793
            }
11794
            if (n < 0 || (size_t)n >= max_ipv6_len - idx) {
11795
                WOLFSSL_MSG("The target ip address exceeds buffer length(40)");
11796
                XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11797
                buf = NULL;
11798
            }
11799
            else {
11800
                idx += (size_t)n;
11801
            }
11802
        }
11803
    }
11804
    else {
11805
        WOLFSSL_MSG("iplen is zero, do nothing");
11806
        return WOLFSSL_SUCCESS;
11807
    }
11808
11809
    if (buf) {
11810
        /* set address to ip asc */
11811
        ret = wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(param, buf);
11812
        XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11813
    }
11814
#else
11815
    (void)param;
11816
    (void)ip;
11817
    (void)iplen;
11818
#endif
11819
11820
    return ret;
11821
}
11822
11823
#ifndef NO_WOLFSSL_STUB
11824
void wolfSSL_X509_OBJECT_free_contents(WOLFSSL_X509_OBJECT* obj)
11825
{
11826
    (void)obj;
11827
    WOLFSSL_STUB("X509_OBJECT_free_contents");
11828
}
11829
#endif
11830
11831
#ifndef NO_ASN_TIME
11832
int wolfSSL_X509_cmp_current_time(const WOLFSSL_ASN1_TIME* asnTime)
11833
{
11834
    return wolfSSL_X509_cmp_time(asnTime, NULL);
11835
}
11836
11837
/* return WOLFSSL_FATAL_ERROR if asnTime is earlier than or equal to cmpTime,
11838
 * and 1 otherwise
11839
 * return 0 on error
11840
 */
11841
int wolfSSL_X509_cmp_time(const WOLFSSL_ASN1_TIME* asnTime, time_t* cmpTime)
11842
{
11843
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
11844
    time_t tmpTime, *pTime = &tmpTime;
11845
    struct tm ts, *tmpTs, *ct;
11846
#if defined(NEED_TMP_TIME)
11847
    /* for use with gmtime_r */
11848
    struct tm tmpTimeStorage;
11849
11850
    tmpTs = &tmpTimeStorage;
11851
#else
11852
    tmpTs = NULL;
11853
#endif
11854
    (void)tmpTs;
11855
11856
    if (asnTime == NULL) {
11857
        return WOLFSSL_FAILURE;
11858
    }
11859
11860
    if (cmpTime == NULL) {
11861
        /* Use current time */
11862
        *pTime = wc_Time(0);
11863
    }
11864
    else {
11865
        pTime = cmpTime;
11866
    }
11867
11868
    if (wolfSSL_ASN1_TIME_to_tm((WOLFSSL_ASN1_TIME*)asnTime, &ts) !=
11869
                                                              WOLFSSL_SUCCESS) {
11870
        WOLFSSL_MSG("Failed to convert WOLFSSL_ASN1_TIME to struct tm.");
11871
        return WOLFSSL_FAILURE;
11872
    }
11873
11874
    /* Convert to time struct*/
11875
    ct = XGMTIME(pTime, tmpTs);
11876
11877
    if (ct == NULL)
11878
        return GETTIME_ERROR;
11879
11880
    /* DateGreaterThan returns 1 for >; 0 for <= */
11881
    ret = DateGreaterThan(&ts, ct) ? 1 : -1;
11882
11883
    return ret;
11884
}
11885
#endif /* !NO_ASN_TIME */
11886
11887
#if (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)) && \
11888
    !defined(NO_ASN_TIME) && !defined(USER_TIME) && !defined(TIME_OVERRIDES)
11889
WOLFSSL_ASN1_TIME *wolfSSL_X509_time_adj_ex(WOLFSSL_ASN1_TIME *asnTime,
11890
    int offset_day, long offset_sec, time_t *in_tm)
11891
{
11892
    /* get current time if in_tm is null */
11893
    time_t t = in_tm ? *in_tm : wc_Time(0);
11894
    return wolfSSL_ASN1_TIME_adj(asnTime, t, offset_day, offset_sec);
11895
}
11896
11897
WOLFSSL_ASN1_TIME *wolfSSL_X509_time_adj(WOLFSSL_ASN1_TIME *asnTime,
11898
    long offset_sec, time_t *in_tm)
11899
{
11900
    return wolfSSL_X509_time_adj_ex(asnTime, 0, offset_sec, in_tm);
11901
}
11902
11903
WOLFSSL_ASN1_TIME* wolfSSL_X509_gmtime_adj(WOLFSSL_ASN1_TIME *s, long adj)
11904
{
11905
    return wolfSSL_X509_time_adj(s, adj, NULL);
11906
}
11907
#endif
11908
11909
int wolfSSL_sk_X509_REVOKED_num(WOLFSSL_STACK* sk)
11910
{
11911
    WOLFSSL_ENTER("wolfSSL_sk_X509_REVOKED_num");
11912
    if (sk != NULL) {
11913
        return (int)sk->num;
11914
    }
11915
    return 0;
11916
}
11917
11918
/* Free a WOLFSSL_X509_REVOKED and all its owned memory. */
11919
void wolfSSL_X509_REVOKED_free(WOLFSSL_X509_REVOKED* rev)
11920
{
11921
    if (rev == NULL) {
11922
        return;
11923
    }
11924
11925
    wolfSSL_ASN1_INTEGER_free(rev->serialNumber);
11926
    wolfSSL_ASN1_TIME_free(rev->revocationDate);
11927
11928
    if (rev->extensions != NULL) {
11929
        wolfSSL_sk_pop_free(rev->extensions, NULL);
11930
    }
11931
    if (rev->issuer != NULL) {
11932
        wolfSSL_sk_pop_free(rev->issuer, NULL);
11933
    }
11934
11935
    XFREE(rev, NULL, DYNAMIC_TYPE_OPENSSL);
11936
}
11937
11938
#ifdef HAVE_CRL
11939
/* Build a WOLFSSL_X509_REVOKED from an internal RevokedCert.
11940
 * Caller takes ownership of the returned object. */
11941
static WOLFSSL_X509_REVOKED* RevokedCertToRevoked(RevokedCert* rc, int seq)
11942
{
11943
    WOLFSSL_X509_REVOKED* rev;
11944
    WOLFSSL_ASN1_INTEGER* serial;
11945
11946
    if (rc == NULL) {
11947
        return NULL;
11948
    }
11949
11950
    rev = (WOLFSSL_X509_REVOKED*)XMALLOC(sizeof(WOLFSSL_X509_REVOKED), NULL,
11951
                                          DYNAMIC_TYPE_OPENSSL);
11952
    if (rev == NULL) {
11953
        return NULL;
11954
    }
11955
    XMEMSET(rev, 0, sizeof(WOLFSSL_X509_REVOKED));
11956
11957
    /* Serial number */
11958
    serial = wolfSSL_ASN1_INTEGER_new();
11959
    if (serial == NULL) {
11960
        XFREE(rev, NULL, DYNAMIC_TYPE_OPENSSL);
11961
        return NULL;
11962
    }
11963
    if (rc->serialSz > 0 && rc->serialSz <= EXTERNAL_SERIAL_SIZE) {
11964
        serial->data = (unsigned char*)XMALLOC((size_t)rc->serialSz, NULL,
11965
                                               DYNAMIC_TYPE_OPENSSL);
11966
        if (serial->data == NULL) {
11967
            wolfSSL_ASN1_INTEGER_free(serial);
11968
            XFREE(rev, NULL, DYNAMIC_TYPE_OPENSSL);
11969
            return NULL;
11970
        }
11971
        XMEMCPY(serial->data, rc->serialNumber, (size_t)rc->serialSz);
11972
        serial->length = rc->serialSz;
11973
        serial->dataMax = rc->serialSz;
11974
        serial->isDynamic = 1;
11975
    }
11976
    rev->serialNumber = serial;
11977
11978
    /* Revocation date */
11979
    {
11980
        WOLFSSL_ASN1_TIME* revDate = wolfSSL_ASN1_TIME_new();
11981
        if (revDate != NULL) {
11982
            int dateLen = 0;
11983
            /* Determine date length from the format byte */
11984
            if (rc->revDateFormat == ASN_UTC_TIME ||
11985
                    rc->revDateFormat == ASN_GENERALIZED_TIME) {
11986
                /* Find actual length: dates are null-terminated strings in
11987
                 * revDate buffer up to MAX_DATE_SIZE */
11988
                while (dateLen < MAX_DATE_SIZE && rc->revDate[dateLen] != 0)
11989
                    dateLen++;
11990
            }
11991
            if (dateLen > 0 && dateLen < MAX_DATE_SIZE) {
11992
                XMEMCPY(revDate->data, rc->revDate, (size_t)dateLen);
11993
                revDate->length = dateLen;
11994
                revDate->type = rc->revDateFormat;
11995
            }
11996
        }
11997
        rev->revocationDate = revDate;
11998
    }
11999
12000
    /* Reason code */
12001
    rev->reason = rc->reasonCode;
12002
12003
    /* Sequence (load order) */
12004
    rev->sequence = seq;
12005
12006
    /* issuer: left as NULL (indirect CRL not yet supported) */
12007
    /* extensions: left as NULL for now (raw DER available in RevokedCert
12008
     * but decoded STACK_OF(X509_EXTENSION) build not yet implemented) */
12009
12010
    return rev;
12011
}
12012
#endif /* HAVE_CRL */
12013
12014
WOLFSSL_STACK* wolfSSL_X509_CRL_get_REVOKED(WOLFSSL_X509_CRL* crl)
12015
{
12016
    WOLFSSL_ENTER("wolfSSL_X509_CRL_get_REVOKED");
12017
12018
    if (crl == NULL) {
12019
        return NULL;
12020
    }
12021
12022
#if defined(OPENSSL_EXTRA) && defined(HAVE_CRL)
12023
    /* Return cached stack if already built */
12024
    if (crl->revokedStack != NULL) {
12025
        return crl->revokedStack;
12026
    }
12027
12028
    /* Build the stack from the internal RevokedCert linked list */
12029
    if (crl->crlList != NULL) {
12030
        WOLFSSL_STACK* sk;
12031
        RevokedCert* rc;
12032
        int seq = 0;
12033
12034
        sk = wolfSSL_sk_new_null();
12035
        if (sk == NULL) {
12036
            return NULL;
12037
        }
12038
        sk->type = STACK_TYPE_X509_REVOKED;
12039
12040
        for (rc = crl->crlList->certs; rc != NULL; rc = rc->next) {
12041
            WOLFSSL_X509_REVOKED* rev = RevokedCertToRevoked(rc, seq);
12042
            if (rev == NULL) {
12043
                /* Clean up on failure */
12044
                wolfSSL_sk_pop_free(sk, NULL);
12045
                return NULL;
12046
            }
12047
            /* Push to stack. wolfSSL_sk_push returns total count on success. */
12048
            if (wolfSSL_sk_push(sk, rev) <= 0) {
12049
                wolfSSL_X509_REVOKED_free(rev);
12050
                wolfSSL_sk_pop_free(sk, NULL);
12051
                return NULL;
12052
            }
12053
            seq++;
12054
        }
12055
12056
        crl->revokedStack = sk;
12057
        return sk;
12058
    }
12059
#endif /* OPENSSL_EXTRA && HAVE_CRL */
12060
12061
    return NULL;
12062
}
12063
12064
WOLFSSL_X509_REVOKED* wolfSSL_sk_X509_REVOKED_value(
12065
                                    WOLFSSL_STACK* sk, int idx)
12066
{
12067
    WOLFSSL_ENTER("wolfSSL_sk_X509_REVOKED_value");
12068
12069
    if (sk == NULL) {
12070
        return NULL;
12071
    }
12072
12073
    return (WOLFSSL_X509_REVOKED*)wolfSSL_sk_value(sk, idx);
12074
}
12075
12076
/* Extension accessors for WOLFSSL_X509_REVOKED */
12077
int wolfSSL_X509_REVOKED_get_ext_count(const WOLFSSL_X509_REVOKED* rev)
12078
{
12079
    WOLFSSL_ENTER("wolfSSL_X509_REVOKED_get_ext_count");
12080
    if (rev != NULL && rev->extensions != NULL) {
12081
        return (int)rev->extensions->num;
12082
    }
12083
    return 0;
12084
}
12085
12086
WOLFSSL_X509_EXTENSION* wolfSSL_X509_REVOKED_get_ext(
12087
                                     const WOLFSSL_X509_REVOKED* rev, int loc)
12088
{
12089
    WOLFSSL_ENTER("wolfSSL_X509_REVOKED_get_ext");
12090
    if (rev != NULL && rev->extensions != NULL) {
12091
        return (WOLFSSL_X509_EXTENSION*)wolfSSL_sk_value(rev->extensions, loc);
12092
    }
12093
    return NULL;
12094
}
12095
12096
#endif /* OPENSSL_EXTRA */
12097
12098
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
12099
12100
WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509* x509)
12101
{
12102
    WOLFSSL_ASN1_INTEGER* a;
12103
    int i = 0;
12104
12105
    WOLFSSL_ENTER("wolfSSL_X509_get_serialNumber");
12106
12107
    if (x509 == NULL) {
12108
        WOLFSSL_MSG("NULL function argument");
12109
        return NULL;
12110
    }
12111
12112
    if (x509->serialNumber != NULL)
12113
       return x509->serialNumber;
12114
12115
    if (x509->serialSz < 0) {
12116
        WOLFSSL_MSG("Invalid serial number size");
12117
        return NULL;
12118
    }
12119
12120
    a = wolfSSL_ASN1_INTEGER_new();
12121
    if (a == NULL)
12122
        return NULL;
12123
12124
    /* Make sure there is space for the data, ASN.1 type and length. */
12125
    if (x509->serialSz > (WOLFSSL_ASN1_INTEGER_MAX - 2)) {
12126
        /* dynamically create data buffer, +2 for type and length */
12127
        a->data = (unsigned char*)XMALLOC(x509->serialSz + 2, NULL,
12128
                DYNAMIC_TYPE_OPENSSL);
12129
        if (a->data == NULL) {
12130
            wolfSSL_ASN1_INTEGER_free(a);
12131
            return NULL;
12132
        }
12133
        a->dataMax   = (unsigned int)x509->serialSz + 2;
12134
        a->isDynamic = 1;
12135
    }
12136
    else {
12137
        /* Use array instead of dynamic memory */
12138
        a->data    = a->intData;
12139
        a->dataMax = WOLFSSL_ASN1_INTEGER_MAX;
12140
    }
12141
12142
    #if defined(WOLFSSL_QT) || defined(WOLFSSL_HAPROXY)
12143
        XMEMCPY(&a->data[i], x509->serial, x509->serialSz);
12144
        a->length = x509->serialSz;
12145
    #else
12146
        a->data[i++] = ASN_INTEGER;
12147
        i += SetLength(x509->serialSz, a->data + i);
12148
        XMEMCPY(&a->data[i], x509->serial, x509->serialSz);
12149
        a->length = x509->serialSz + 2;
12150
    #endif
12151
12152
    x509->serialNumber = a;
12153
12154
    return a;
12155
}
12156
12157
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
12158
12159
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
12160
12161
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
12162
    defined(WOLFSSL_APACHE_HTTPD) || defined(WOLFSSL_HAPROXY) || \
12163
    defined(WOLFSSL_WPAS)
12164
WOLFSSL_X509_ALGOR* wolfSSL_X509_ALGOR_new(void)
12165
{
12166
    WOLFSSL_X509_ALGOR* ret;
12167
    ret = (WOLFSSL_X509_ALGOR*)XMALLOC(sizeof(WOLFSSL_X509_ALGOR), NULL,
12168
                                       DYNAMIC_TYPE_OPENSSL);
12169
    if (ret) {
12170
        XMEMSET(ret, 0, sizeof(WOLFSSL_X509_ALGOR));
12171
    }
12172
    return ret;
12173
}
12174
12175
void wolfSSL_X509_ALGOR_free(WOLFSSL_X509_ALGOR *alg)
12176
{
12177
    if (alg) {
12178
        wolfSSL_ASN1_OBJECT_free(alg->algorithm);
12179
        wolfSSL_ASN1_TYPE_free(alg->parameter);
12180
        XFREE(alg, NULL, DYNAMIC_TYPE_OPENSSL);
12181
    }
12182
}
12183
12184
/* Returns X509_ALGOR struct with signature algorithm */
12185
const WOLFSSL_X509_ALGOR* wolfSSL_X509_get0_tbs_sigalg(const WOLFSSL_X509 *x509)
12186
{
12187
    WOLFSSL_ENTER("wolfSSL_X509_get0_tbs_sigalg");
12188
12189
    if (x509 == NULL) {
12190
        WOLFSSL_MSG("x509 struct NULL error");
12191
        return NULL;
12192
    }
12193
12194
    return &x509->algor;
12195
}
12196
12197
/* Sets paobj pointer to X509_ALGOR signature algorithm */
12198
void wolfSSL_X509_ALGOR_get0(const WOLFSSL_ASN1_OBJECT **paobj, int *pptype,
12199
                            const void **ppval, const WOLFSSL_X509_ALGOR *algor)
12200
{
12201
    WOLFSSL_ENTER("wolfSSL_X509_ALGOR_get0");
12202
12203
    if (!algor) {
12204
        WOLFSSL_MSG("algor object is NULL");
12205
        return;
12206
    }
12207
12208
    if (paobj)
12209
        *paobj = algor->algorithm;
12210
    if (ppval && algor->parameter)
12211
        *ppval = algor->parameter->value.ptr;
12212
    if (pptype) {
12213
        if (algor->parameter) {
12214
            *pptype = algor->parameter->type;
12215
        }
12216
        else {
12217
            /* Default to WOLFSSL_V_ASN1_OBJECT */
12218
            *pptype = WOLFSSL_V_ASN1_OBJECT;
12219
        }
12220
    }
12221
}
12222
12223
/**
12224
 * Populate algor members.
12225
 *
12226
 * @param algor The object to be set
12227
 * @param aobj The value to be set in algor->algorithm
12228
 * @param ptype The type of algor->parameter
12229
 * @param pval The value of algor->parameter
12230
 * @return WOLFSSL_SUCCESS on success
12231
 *         WOLFSSL_FAILURE on missing parameters or bad malloc
12232
 */
12233
int wolfSSL_X509_ALGOR_set0(WOLFSSL_X509_ALGOR *algor,
12234
                            WOLFSSL_ASN1_OBJECT *aobj, int ptype, void *pval)
12235
{
12236
    if (!algor) {
12237
        return WOLFSSL_FAILURE;
12238
    }
12239
12240
    if (!algor->parameter) {
12241
        algor->parameter = wolfSSL_ASN1_TYPE_new();
12242
        if (!algor->parameter) {
12243
            return WOLFSSL_FAILURE;
12244
        }
12245
    }
12246
12247
    if (aobj) {
12248
        algor->algorithm = aobj;
12249
    }
12250
    wolfSSL_ASN1_TYPE_set(algor->parameter, ptype, pval);
12251
12252
    return WOLFSSL_SUCCESS;
12253
}
12254
12255
/**
12256
 * Serialize object to DER encoding
12257
 *
12258
 * @param alg Object to serialize
12259
 * @param pp  Output
12260
 * @return Length on success
12261
 *         Negative number on failure
12262
 */
12263
int wolfSSL_i2d_X509_ALGOR(const WOLFSSL_X509_ALGOR* alg,
12264
        unsigned char** pp)
12265
{
12266
    int len;
12267
    word32 oid = 0;
12268
    word32 idx = 0;
12269
    unsigned char* buf = NULL;
12270
12271
    if (alg == NULL || alg->algorithm == 0) {
12272
        WOLFSSL_MSG("alg is NULL or algorithm not set");
12273
        return WOLFSSL_FATAL_ERROR;
12274
    }
12275
12276
    if (GetObjectId(alg->algorithm->obj, &idx, &oid,
12277
            (word32)alg->algorithm->grp, alg->algorithm->objSz) < 0) {
12278
        WOLFSSL_MSG("Issue getting OID of object");
12279
        return WOLFSSL_FATAL_ERROR;
12280
    }
12281
12282
    len = (int)SetAlgoID((int)oid, NULL, alg->algorithm->grp, 0);
12283
    if (len == 0) {
12284
        WOLFSSL_MSG("SetAlgoID error");
12285
        return WOLFSSL_FATAL_ERROR;
12286
    }
12287
12288
    if (pp != NULL) {
12289
        if (*pp != NULL)
12290
            buf = *pp;
12291
        else {
12292
            buf = (byte*)XMALLOC((size_t)len, NULL, DYNAMIC_TYPE_ASN1);
12293
            if (buf == NULL)
12294
                return WOLFSSL_FATAL_ERROR;
12295
        }
12296
12297
        len = (int)SetAlgoID((int)oid, buf, alg->algorithm->grp, 0);
12298
        if (len == 0) {
12299
            WOLFSSL_MSG("SetAlgoID error");
12300
            if (*pp == NULL)
12301
                XFREE(buf, NULL, DYNAMIC_TYPE_ASN1);
12302
            return WOLFSSL_FATAL_ERROR;
12303
        }
12304
12305
        if (*pp != NULL)
12306
            *pp += len;
12307
        else
12308
            *pp = buf;
12309
    }
12310
12311
    return len;
12312
}
12313
12314
WOLFSSL_X509_ALGOR* wolfSSL_d2i_X509_ALGOR(WOLFSSL_X509_ALGOR** out,
12315
        const byte** src, long len)
12316
{
12317
    WOLFSSL_X509_ALGOR* ret = NULL;
12318
    word32 idx = 0;
12319
    word32 oid = 0;
12320
    int grp;
12321
12322
    WOLFSSL_ENTER("wolfSSL_d2i_X509_ALGOR");
12323
12324
    if (src == NULL || *src == NULL || len <= 0)
12325
        return NULL;
12326
12327
    if (GetAlgoId(*src, &idx, &oid, oidIgnoreType, (word32)len) != 0)
12328
        return NULL;
12329
12330
    /* Try to guess the type */
12331
    for (grp = 0; grp < oidIgnoreType; grp++) {
12332
        word32 oidSz;
12333
        if (OidFromId(oid, (word32)grp, &oidSz) != NULL)
12334
            break;
12335
    }
12336
    if (grp == oidIgnoreType)
12337
        return NULL;
12338
12339
    ret = wolfSSL_X509_ALGOR_new();
12340
    if (ret == NULL)
12341
        return NULL;
12342
12343
    ret->algorithm = wolfSSL_OBJ_nid2obj(oid2nid(oid, grp));
12344
    if (ret->algorithm == NULL) {
12345
        wolfSSL_X509_ALGOR_free(ret);
12346
        return NULL;
12347
    }
12348
    *src += idx;
12349
12350
    if (out != NULL) {
12351
        if (*out != NULL)
12352
            wolfSSL_X509_ALGOR_free(*out);
12353
        *out = ret;
12354
    }
12355
12356
    return ret;
12357
}
12358
12359
/**
12360
 * Allocate a new WOLFSSL_X509_PUBKEY object.
12361
 *
12362
 * @return New zero'ed WOLFSSL_X509_PUBKEY object
12363
 */
12364
WOLFSSL_X509_PUBKEY *wolfSSL_X509_PUBKEY_new(void)
12365
{
12366
    WOLFSSL_X509_PUBKEY *ret;
12367
    ret = (WOLFSSL_X509_PUBKEY*)XMALLOC(sizeof(WOLFSSL_X509_PUBKEY), NULL,
12368
                                        DYNAMIC_TYPE_OPENSSL);
12369
    if (!ret) {
12370
        return NULL;
12371
    }
12372
    XMEMSET(ret, 0, sizeof(WOLFSSL_X509_PUBKEY));
12373
    ret->algor = wolfSSL_X509_ALGOR_new();
12374
    if (!ret->algor) {
12375
        wolfSSL_X509_PUBKEY_free(ret);
12376
        return NULL;
12377
    }
12378
    return ret;
12379
}
12380
12381
/**
12382
 * Free WOLFSSL_X509_PUBKEY and all its members.
12383
 *
12384
 * @param at Object to free
12385
 */
12386
void wolfSSL_X509_PUBKEY_free(WOLFSSL_X509_PUBKEY *x)
12387
{
12388
    if (x) {
12389
        if (x->algor) {
12390
            wolfSSL_X509_ALGOR_free(x->algor);
12391
        }
12392
        if (x->pkey) {
12393
            wolfSSL_EVP_PKEY_free(x->pkey);
12394
        }
12395
        XFREE(x, NULL, DYNAMIC_TYPE_OPENSSL);
12396
    }
12397
}
12398
12399
/* Returns X509_PUBKEY structure containing X509_ALGOR and EVP_PKEY */
12400
WOLFSSL_X509_PUBKEY* wolfSSL_X509_get_X509_PUBKEY(const WOLFSSL_X509* x509)
12401
{
12402
    WOLFSSL_ENTER("wolfSSL_X509_get_X509_PUBKEY");
12403
12404
    if (x509 == NULL) {
12405
        WOLFSSL_MSG("x509 struct NULL error");
12406
        return NULL;
12407
    }
12408
12409
    /* OpenSSL also takes a const X509 and returns a mutable X509_PUBKEY.
12410
     * Only the lazily decoded key cache is written here. */
12411
    (void)X509CachedPubKey((WOLFSSL_X509*)x509);
12412
12413
    return (WOLFSSL_X509_PUBKEY*)&x509->key;
12414
}
12415
12416
/* Step over SubjectPublicKeyInfo to its subjectPublicKey BIT STRING.
12417
 *
12418
 * @param [in, out] der    On in, the SPKI. On out, the BIT STRING contents.
12419
 * @param [in, out] derSz  On in, size of the encoding. On out, size of the
12420
 *                         BIT STRING contents.
12421
 * @return  0 on success.
12422
 * @return  WOLFSSL_FATAL_ERROR when the encoding does not parse.
12423
 */
12424
static int x509_pubkey_bit_string(const unsigned char** der, int* derSz)
12425
{
12426
    word32 idx = 0;
12427
    int len = 0;
12428
12429
    if ((*der == NULL) || (*derSz <= 0)) {
12430
        return WOLFSSL_FATAL_ERROR;
12431
    }
12432
    if (GetSequence(*der, &idx, &len, (word32)*derSz) < 0) {
12433
        return WOLFSSL_FATAL_ERROR;
12434
    }
12435
    /* spki length must span the whole encoding */
12436
    if (idx + (word32)len != (word32)*derSz) {
12437
        return WOLFSSL_FATAL_ERROR;
12438
    }
12439
    /* step over AlgorithmIdentifier */
12440
    if (GetSequence(*der, &idx, &len, (word32)*derSz) < 0) {
12441
        return WOLFSSL_FATAL_ERROR;
12442
    }
12443
    idx += (word32)len;
12444
    /* subjectPublicKey is the last field */
12445
    if (CheckBitString(*der, &idx, &len, (word32)*derSz, 1, NULL) < 0) {
12446
        return WOLFSSL_FATAL_ERROR;
12447
    }
12448
    if (idx + (word32)len != (word32)*derSz) {
12449
        return WOLFSSL_FATAL_ERROR;
12450
    }
12451
12452
    *der += idx;
12453
    *derSz = len;
12454
12455
    return 0;
12456
}
12457
12458
/* Sets ppkalg pointer to X509_PUBKEY algorithm. Returns WOLFSSL_SUCCESS on
12459
    success or WOLFSSL_FAILURE on error. */
12460
int wolfSSL_X509_PUBKEY_get0_param(WOLFSSL_ASN1_OBJECT **ppkalg,
12461
     const unsigned char **pk, int *ppklen, WOLFSSL_X509_ALGOR **pa,
12462
     WOLFSSL_X509_PUBKEY *pub)
12463
{
12464
    const unsigned char* bitStr;
12465
    int bitStrSz;
12466
    WOLFSSL_EVP_PKEY* pkey;
12467
    WOLFSSL_X509_ALGOR* algor;
12468
12469
    WOLFSSL_ENTER("wolfSSL_X509_PUBKEY_get0_param");
12470
12471
    if (!pub || !pub->pubKeyOID) {
12472
        WOLFSSL_MSG("X509_PUBKEY struct not populated");
12473
        return WOLFSSL_FAILURE;
12474
    }
12475
    /* The key and algorithm are cached and read once, as other threads may
12476
     * be storing them. */
12477
    pkey = (WOLFSSL_EVP_PKEY*)X509_CACHE_LOAD(pub->pkey);
12478
    if ((pk || ppklen) && (pkey == NULL)) {
12479
        WOLFSSL_MSG("X509_PUBKEY has no decoded key");
12480
        return WOLFSSL_FAILURE;
12481
    }
12482
12483
    algor = (WOLFSSL_X509_ALGOR*)X509_CACHE_LOAD(pub->algor);
12484
    if (algor == NULL) {
12485
    #ifndef SINGLE_THREADED
12486
        void* current = NULL;
12487
    #endif
12488
12489
        /* Build the algorithm fully before storing it, so a failure
12490
         * never leaves a half built one behind. */
12491
        algor = wolfSSL_X509_ALGOR_new();
12492
        if (algor == NULL) {
12493
            return WOLFSSL_FAILURE;
12494
        }
12495
        algor->algorithm = wolfSSL_OBJ_nid2obj(
12496
            oid2nid((word32)pub->pubKeyOID, oidKeyType));
12497
        if (algor->algorithm == NULL) {
12498
            WOLFSSL_MSG("Failed to create object from NID");
12499
            wolfSSL_X509_ALGOR_free(algor);
12500
            return WOLFSSL_FAILURE;
12501
        }
12502
    #ifndef SINGLE_THREADED
12503
        /* Threads may build the algorithm of a shared X509 at the same
12504
         * time. Only the first is stored. */
12505
        if (!wolfSSL_Atomic_Ptr_CompareExchange(
12506
                (void* volatile*)&pub->algor, &current, algor)) {
12507
            wolfSSL_X509_ALGOR_free(algor);
12508
            algor = (WOLFSSL_X509_ALGOR*)current;
12509
        }
12510
    #else
12511
        pub->algor = algor;
12512
    #endif
12513
    }
12514
12515
    if (pa)
12516
        *pa = algor;
12517
    if (ppkalg)
12518
        *ppkalg = algor->algorithm;
12519
12520
    if ((pk != NULL) || (ppklen != NULL)) {
12521
        bitStr = (const unsigned char*)pkey->pkey.ptr;
12522
        bitStrSz = pkey->pkey_sz;
12523
12524
        /* try to parse BIT STRING from SPKI, otherwise return the
12525
         * pointer as is */
12526
        if (x509_pubkey_bit_string(&bitStr, &bitStrSz) != 0) {
12527
            WOLFSSL_MSG("No SubjectPublicKeyInfo wrapper found");
12528
        }
12529
12530
        if (pk)
12531
            *pk = bitStr;
12532
        if (ppklen)
12533
            *ppklen = bitStrSz;
12534
    }
12535
12536
    return WOLFSSL_SUCCESS;
12537
}
12538
12539
/* Returns a pointer to the pkey when passed a key */
12540
WOLFSSL_EVP_PKEY* wolfSSL_X509_PUBKEY_get(WOLFSSL_X509_PUBKEY* key)
12541
{
12542
    WOLFSSL_EVP_PKEY* pkey = NULL;
12543
12544
    WOLFSSL_ENTER("wolfSSL_X509_PUBKEY_get");
12545
    if (key != NULL) {
12546
        pkey = (WOLFSSL_EVP_PKEY*)X509_CACHE_LOAD(key->pkey);
12547
    }
12548
    if (pkey == NULL) {
12549
        WOLFSSL_LEAVE("wolfSSL_X509_PUBKEY_get", BAD_FUNC_ARG);
12550
        return NULL;
12551
    }
12552
    if (wolfSSL_EVP_PKEY_up_ref(pkey) != WOLFSSL_SUCCESS) {
12553
        WOLFSSL_LEAVE("wolfSSL_X509_PUBKEY_get", BAD_MUTEX_E);
12554
        return NULL;
12555
    }
12556
    WOLFSSL_LEAVE("wolfSSL_X509_PUBKEY_get", WOLFSSL_SUCCESS);
12557
    return pkey;
12558
}
12559
12560
/* Returns the pkey without a new reference. */
12561
WOLFSSL_EVP_PKEY* wolfSSL_X509_PUBKEY_get0(const WOLFSSL_X509_PUBKEY* key)
12562
{
12563
    WOLFSSL_ENTER("wolfSSL_X509_PUBKEY_get0");
12564
    if (key == NULL)
12565
        return NULL;
12566
    return (WOLFSSL_EVP_PKEY*)X509_CACHE_LOAD(
12567
        ((WOLFSSL_X509_PUBKEY*)key)->pkey);
12568
}
12569
12570
int wolfSSL_X509_PUBKEY_set(WOLFSSL_X509_PUBKEY **x, WOLFSSL_EVP_PKEY *key)
12571
{
12572
    WOLFSSL_X509_PUBKEY *pk = NULL;
12573
    int ptype;
12574
    void *pval;
12575
#ifndef NO_DSA
12576
    WOLFSSL_ASN1_STRING *str;
12577
#endif
12578
#ifdef HAVE_ECC
12579
    int nid;
12580
    const WOLFSSL_EC_GROUP *group;
12581
#endif
12582
    WOLFSSL_ASN1_OBJECT *keyTypeObj;
12583
12584
    WOLFSSL_ENTER("wolfSSL_X509_PUBKEY_set");
12585
12586
    if (!x || !key) {
12587
        return WOLFSSL_FAILURE;
12588
    }
12589
12590
    if (!(pk = wolfSSL_X509_PUBKEY_new())) {
12591
        return WOLFSSL_FAILURE;
12592
    }
12593
12594
    switch (key->type) {
12595
#ifndef NO_RSA
12596
    case WC_EVP_PKEY_RSA:
12597
        pval = NULL;
12598
        ptype = WOLFSSL_V_ASN1_NULL;
12599
        pk->pubKeyOID = RSAk;
12600
        break;
12601
#endif
12602
#ifndef NO_DSA
12603
    case WC_EVP_PKEY_DSA:
12604
        if (!key->dsa->p || !key->dsa->q || !key->dsa->g)
12605
            goto error;
12606
12607
        str = wolfSSL_ASN1_STRING_new();
12608
        if (str == NULL)
12609
            goto error;
12610
12611
        str->length = wolfSSL_i2d_DSAparams(key->dsa,
12612
             (unsigned char **)&str->data);
12613
        if (str->length <= 0) {
12614
            wolfSSL_ASN1_STRING_free(str);
12615
            goto error;
12616
        }
12617
        str->isDynamic = 1;
12618
12619
        pval = str;
12620
        ptype = WOLFSSL_V_ASN1_SEQUENCE;
12621
        pk->pubKeyOID = DSAk;
12622
        break;
12623
#endif
12624
#ifdef HAVE_ECC
12625
    case WC_EVP_PKEY_EC:
12626
        group = wolfSSL_EC_KEY_get0_group(key->ecc);
12627
        if (!group)
12628
            goto error;
12629
12630
        nid = wolfSSL_EC_GROUP_get_curve_name(group);
12631
        if (nid <= 0) {
12632
            /* TODO: Add support for no nid case */
12633
            WOLFSSL_MSG("nid not found");
12634
            goto error;
12635
        }
12636
12637
        pval = wolfSSL_OBJ_nid2obj(nid);
12638
        if (!pval)
12639
            goto error;
12640
12641
        ptype = WOLFSSL_V_ASN1_OBJECT;
12642
        pk->pubKeyOID = ECDSAk;
12643
        break;
12644
#endif
12645
    default:
12646
        WOLFSSL_MSG("Unknown key type");
12647
        goto error;
12648
    }
12649
12650
    keyTypeObj = wolfSSL_OBJ_nid2obj(key->type);
12651
    if (keyTypeObj == NULL) {
12652
        if (ptype == WOLFSSL_V_ASN1_OBJECT)
12653
            wolfSSL_ASN1_OBJECT_free((WOLFSSL_ASN1_OBJECT *)pval);
12654
        else
12655
            wolfSSL_ASN1_STRING_free((WOLFSSL_ASN1_STRING *)pval);
12656
        goto error;
12657
    }
12658
    if (!wolfSSL_X509_ALGOR_set0(pk->algor, keyTypeObj, ptype, pval)) {
12659
        WOLFSSL_MSG("Failed to create algorithm object");
12660
        wolfSSL_ASN1_OBJECT_free(keyTypeObj);
12661
        if (ptype == WOLFSSL_V_ASN1_OBJECT)
12662
            wolfSSL_ASN1_OBJECT_free((WOLFSSL_ASN1_OBJECT *)pval);
12663
        else
12664
            wolfSSL_ASN1_STRING_free((WOLFSSL_ASN1_STRING *)pval);
12665
        goto error;
12666
    }
12667
12668
    if (!wolfSSL_EVP_PKEY_up_ref(key)) {
12669
        WOLFSSL_MSG("Failed to up key reference");
12670
        goto error;
12671
    }
12672
    pk->pkey = key;
12673
12674
    wolfSSL_X509_PUBKEY_free(*x);
12675
    *x = pk;
12676
    return WOLFSSL_SUCCESS;
12677
error:
12678
    if (pk) {
12679
        wolfSSL_X509_PUBKEY_free(pk);
12680
    }
12681
    return WOLFSSL_FAILURE;
12682
}
12683
12684
#endif /* OPENSSL_ALL || OPENSSL_EXTRA || WOLFSSL_APACHE_HTTPD ||
12685
        * WOLFSSL_HAPROXY || WOLFSSL_WPAS */
12686
12687
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_ASN)
12688
12689
int wolfSSL_i2d_X509_PUBKEY(WOLFSSL_X509_PUBKEY* x509_PubKey,
12690
    unsigned char** der)
12691
{
12692
    if (x509_PubKey == NULL)
12693
        return WOLFSSL_FATAL_ERROR;
12694
    return wolfSSL_i2d_PUBKEY(x509_PubKey->pkey, der);
12695
}
12696
12697
#endif /* OPENSSL_EXTRA && !NO_CERTS && !NO_ASN */
12698
12699
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
12700
12701
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
12702
WOLFSSL_BASIC_CONSTRAINTS* wolfSSL_BASIC_CONSTRAINTS_new(void)
12703
{
12704
    WOLFSSL_BASIC_CONSTRAINTS* bc;
12705
    bc = (WOLFSSL_BASIC_CONSTRAINTS*)
12706
          XMALLOC(sizeof(WOLFSSL_BASIC_CONSTRAINTS), NULL,
12707
          DYNAMIC_TYPE_X509_EXT);
12708
    if (bc == NULL) {
12709
        WOLFSSL_MSG("Failed to malloc basic constraints");
12710
        return NULL;
12711
    }
12712
    XMEMSET(bc, 0, sizeof(WOLFSSL_BASIC_CONSTRAINTS));
12713
    return bc;
12714
}
12715
12716
/* frees the wolfSSL_BASIC_CONSTRAINTS object */
12717
void wolfSSL_BASIC_CONSTRAINTS_free(WOLFSSL_BASIC_CONSTRAINTS *bc)
12718
{
12719
    WOLFSSL_ENTER("wolfSSL_BASIC_CONSTRAINTS_free");
12720
    if (bc == NULL) {
12721
        WOLFSSL_MSG("Argument is NULL");
12722
        return;
12723
    }
12724
    if (bc->pathlen) {
12725
        wolfSSL_ASN1_INTEGER_free(bc->pathlen);
12726
    }
12727
    XFREE(bc, NULL, DYNAMIC_TYPE_OPENSSL);
12728
}
12729
12730
WOLFSSL_AUTHORITY_KEYID* wolfSSL_AUTHORITY_KEYID_new(void)
12731
{
12732
    WOLFSSL_AUTHORITY_KEYID* akey = (WOLFSSL_AUTHORITY_KEYID*)XMALLOC(
12733
          sizeof(WOLFSSL_AUTHORITY_KEYID), NULL, DYNAMIC_TYPE_OPENSSL);
12734
    if (!akey) {
12735
        WOLFSSL_MSG("Issue creating WOLFSSL_AUTHORITY_KEYID struct");
12736
        return NULL;
12737
    }
12738
    XMEMSET(akey, 0, sizeof(WOLFSSL_AUTHORITY_KEYID));
12739
    return akey;
12740
}
12741
12742
/* frees the wolfSSL_AUTHORITY_KEYID object */
12743
void wolfSSL_AUTHORITY_KEYID_free(WOLFSSL_AUTHORITY_KEYID *id)
12744
{
12745
    WOLFSSL_ENTER("wolfSSL_AUTHORITY_KEYID_free");
12746
    if (id == NULL) {
12747
        WOLFSSL_MSG("Argument is NULL");
12748
        return;
12749
    }
12750
    if (id->keyid) {
12751
        wolfSSL_ASN1_STRING_free(id->keyid);
12752
    }
12753
    if (id->issuer) {
12754
        wolfSSL_ASN1_OBJECT_free(id->issuer);
12755
    }
12756
    if (id->serial) {
12757
        wolfSSL_ASN1_INTEGER_free(id->serial);
12758
    }
12759
    XFREE(id, NULL, DYNAMIC_TYPE_OPENSSL);
12760
}
12761
12762
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
12763
12764
#ifdef KEEP_PEER_CERT
12765
char*  wolfSSL_X509_get_subjectCN(WOLFSSL_X509* x509)
12766
{
12767
    if (x509 == NULL)
12768
        return NULL;
12769
12770
    return x509->subjectCN;
12771
}
12772
#endif /* KEEP_PEER_CERT */
12773
12774
#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA)
12775
/* increments ref count of WOLFSSL_X509. Return 1 on success, 0 on error */
12776
int wolfSSL_X509_up_ref(WOLFSSL_X509* x509)
12777
{
12778
    if (x509) {
12779
        int ret;
12780
        wolfSSL_RefInc(&x509->ref, &ret);
12781
        if (ret != 0) {
12782
            WOLFSSL_MSG("Failed to lock x509 mutex");
12783
            return WOLFSSL_FAILURE;
12784
        }
12785
12786
        return WOLFSSL_SUCCESS;
12787
    }
12788
12789
    return WOLFSSL_FAILURE;
12790
}
12791
#endif /* OPENSSL_EXTRA_X509_SMALL || OPENSSL_EXTRA */
12792
12793
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
12794
WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_chain_up_ref(
12795
        WOLF_STACK_OF(WOLFSSL_X509)* chain)
12796
{
12797
    /* wolfSSL_sk_dup takes care of doing a deep copy */
12798
    return wolfSSL_sk_dup(chain);
12799
}
12800
#endif
12801
12802
#if defined(OPENSSL_EXTRA)
12803
12804
WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* wolfSSL_sk_X509_OBJECT_deep_copy(
12805
    const WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk,
12806
    WOLFSSL_X509_OBJECT* (*c)(const WOLFSSL_X509_OBJECT*),
12807
    void (*f)(WOLFSSL_X509_OBJECT*))
12808
{
12809
    (void)f; /* free function */
12810
    (void)c; /* copy function */
12811
    return wolfSSL_sk_dup((WOLFSSL_STACK*)sk);
12812
}
12813
#endif
12814
12815
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
12816
    void wolfSSL_X509_NAME_free(WOLFSSL_X509_NAME *name)
12817
    {
12818
        WOLFSSL_ENTER_VERBOSE("wolfSSL_X509_NAME_free");
12819
        FreeX509Name(name);
12820
        if (name != NULL) {
12821
            XFREE(name, name->heap, DYNAMIC_TYPE_X509);
12822
        }
12823
    }
12824
12825
12826
    /* Malloc's a new WOLFSSL_X509_NAME structure
12827
     *
12828
     * returns NULL on failure, otherwise returns a new structure.
12829
     */
12830
    WOLFSSL_X509_NAME* wolfSSL_X509_NAME_new_ex(void *heap)
12831
    {
12832
        WOLFSSL_X509_NAME* name;
12833
12834
        WOLFSSL_ENTER_VERBOSE("wolfSSL_X509_NAME_new_ex");
12835
12836
        name = (WOLFSSL_X509_NAME*)XMALLOC(sizeof(WOLFSSL_X509_NAME), heap,
12837
                DYNAMIC_TYPE_X509);
12838
        if (name != NULL) {
12839
            InitX509Name(name, 1, heap);
12840
        }
12841
        return name;
12842
    }
12843
12844
    WOLFSSL_X509_NAME* wolfSSL_X509_NAME_new(void) {
12845
        return wolfSSL_X509_NAME_new_ex(NULL);
12846
    }
12847
12848
#if !defined(WOLFSSL_NO_CA_NAMES) && defined(OPENSSL_EXTRA)
12849
    /* Set the encoding of a copy of a certificate's issuer or subject name
12850
     * from the certificate's encoding.
12851
     *
12852
     * A certificate's names are not given an encoding when it is parsed, but
12853
     * where they are in the certificate's DER is recorded. Nothing is set when
12854
     * the name is not a certificate's name as parsed (it was replaced or
12855
     * changed since, or the certificate was encoded again).
12856
     *
12857
     * @param [in, out] copy  Copy of name.
12858
     * @param [in]      name  Name that was copied.
12859
     * @return  0 on success.
12860
     * @return  ASN_PARSE_E when the certificate's DER has no name there.
12861
     * @return  MEMORY_E when dynamic memory allocation fails.
12862
     */
12863
    static int X509NameRawFromCert(WOLFSSL_X509_NAME* copy,
12864
        const WOLFSSL_X509_NAME* name)
12865
    {
12866
        const DerBuffer* der;
12867
12868
        if ((name->rawCertOff == 0) || (name->x509 == NULL)) {
12869
            return 0;
12870
        }
12871
        der = name->x509->derCert;
12872
        if ((der == NULL) || (name->rawCertOff >= der->length)) {
12873
            return 0;
12874
        }
12875
12876
        return SetX509NameRawFromDer(copy, der->buffer + name->rawCertOff,
12877
            der->length - name->rawCertOff);
12878
    }
12879
#endif /* !WOLFSSL_NO_CA_NAMES && OPENSSL_EXTRA */
12880
12881
    /* Creates a duplicate of a WOLFSSL_X509_NAME structure.
12882
       Returns a new WOLFSSL_X509_NAME structure or NULL on failure */
12883
    WOLFSSL_X509_NAME* wolfSSL_X509_NAME_dup(const WOLFSSL_X509_NAME *name)
12884
    {
12885
        WOLFSSL_X509_NAME* copy = NULL;
12886
12887
        WOLFSSL_ENTER("wolfSSL_X509_NAME_dup");
12888
12889
        if (name == NULL) {
12890
            WOLFSSL_MSG("NULL parameter");
12891
            return NULL;
12892
        }
12893
12894
        if (!(copy = wolfSSL_X509_NAME_new_ex(name->heap))) {
12895
            return NULL;
12896
        }
12897
12898
        /* copy contents */
12899
        InitX509Name(copy, 1, name->heap);
12900
        if (wolfSSL_X509_NAME_copy(name, copy) != WOLFSSL_SUCCESS) {
12901
            wolfSSL_X509_NAME_free(copy);
12902
            return NULL;
12903
        }
12904
12905
        return copy;
12906
    }
12907
12908
#ifdef WOLFSSL_CERT_GEN
12909
12910
#if defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT) || \
12911
    defined(OPENSSL_EXTRA)
12912
    /* Helper function to copy cert name from a WOLFSSL_X509_NAME structure to
12913
    * a Cert structure.
12914
    *
12915
    * returns length of DER on success and a negative error value on failure
12916
    */
12917
    static int CopyX509NameToCert(WOLFSSL_X509_NAME* n, byte* out)
12918
    {
12919
        unsigned char* der = NULL;
12920
        int length = WC_NO_ERR_TRACE(BAD_FUNC_ARG), ret;
12921
        word32 idx = 0;
12922
12923
        ret = wolfSSL_i2d_X509_NAME(n, &der);
12924
        if (ret > (int)sizeof(CertName) || ret < 0) {
12925
            WOLFSSL_MSG("Name conversion error");
12926
            ret = MEMORY_E;
12927
        }
12928
12929
        if (ret > 0) {
12930
            /* strip off sequence, this gets added on certificate creation */
12931
            ret = GetSequence(der, &idx, &length, (word32)ret);
12932
        }
12933
12934
        if (ret > 0) {
12935
            XMEMCPY(out, der + idx, length);
12936
        }
12937
12938
        XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
12939
12940
        return length;
12941
    }
12942
#endif
12943
12944
#ifdef WOLFSSL_CERT_REQ
12945
    static int ReqCertFromX509(Cert* cert, WOLFSSL_X509* req)
12946
    {
12947
        int ret;
12948
12949
        if (wc_InitCert(cert) != 0)
12950
            return WOLFSSL_FAILURE;
12951
12952
12953
        ret = CopyX509NameToCert(&req->subject, cert->sbjRaw);
12954
        if (ret < 0) {
12955
            WOLFSSL_MSG("REQ subject conversion error");
12956
            ret = MEMORY_E;
12957
        }
12958
        else {
12959
            ret = WOLFSSL_SUCCESS;
12960
        }
12961
12962
        if (ret == WOLFSSL_SUCCESS) {
12963
            cert->version = req->version;
12964
            cert->isCA = req->isCa;
12965
            cert->basicConstSet = req->basicConstSet;
12966
            cert->basicConstCrit = req->basicConstCrit;
12967
            if (req->pathLengthSet) {
12968
                if (req->pathLength > WOLFSSL_MAX_PATH_LEN) {
12969
                    WOLFSSL_MSG("Basic Constraints path length too large");
12970
                    WOLFSSL_ERROR_VERBOSE(ASN_PATHLEN_SIZE_E);
12971
                    ret = WOLFSSL_FAILURE;
12972
                }
12973
                else {
12974
                    cert->pathLen = (byte)req->pathLength;
12975
                    cert->pathLenSet = req->pathLengthSet;
12976
                }
12977
            }
12978
    #ifdef WOLFSSL_CERT_EXT
12979
            if (req->subjKeyIdSz != 0) {
12980
                if (req->subjKeyIdSz > CTC_MAX_SKID_SIZE) {
12981
                    WOLFSSL_MSG("Subject Key ID too large");
12982
                    WOLFSSL_ERROR_VERBOSE(BUFFER_E);
12983
                    ret = WOLFSSL_FAILURE;
12984
                }
12985
                else if (req->subjKeyId == NULL) {
12986
                    WOLFSSL_MSG("Subject Key ID missing");
12987
                    WOLFSSL_ERROR_VERBOSE(BAD_FUNC_ARG);
12988
                    ret = WOLFSSL_FAILURE;
12989
                }
12990
                else {
12991
                    XMEMCPY(cert->skid, req->subjKeyId, req->subjKeyIdSz);
12992
                    cert->skidSz = (int)req->subjKeyIdSz;
12993
                }
12994
            }
12995
            if (req->keyUsageSet)
12996
                cert->keyUsage = req->keyUsage;
12997
12998
            cert->extKeyUsage = req->extKeyUsage;
12999
    #endif
13000
        }
13001
13002
        if (ret == WOLFSSL_SUCCESS) {
13003
        #if defined(OPENSSL_ALL)
13004
            int idx;
13005
        #endif
13006
13007
            XMEMCPY(cert->challengePw, req->challengePw, CTC_NAME_SIZE);
13008
            cert->challengePwPrintableString = req->challengePw[0] != 0;
13009
13010
        #if defined(OPENSSL_ALL)
13011
            idx = wolfSSL_X509_REQ_get_attr_by_NID(req,
13012
                    WC_NID_pkcs9_unstructuredName, -1);
13013
            if (idx != WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) {
13014
                WOLFSSL_X509_ATTRIBUTE *attr;
13015
                attr = wolfSSL_X509_REQ_get_attr(req, idx);
13016
                if (attr != NULL) {
13017
                    const unsigned char *attrData;
13018
                    int attrDataSz;
13019
13020
                    attrData = wolfSSL_ASN1_STRING_get0_data(
13021
                            attr->value->value.asn1_string);
13022
                    attrDataSz = wolfSSL_ASN1_STRING_length(
13023
                            attr->value->value.asn1_string);
13024
13025
                    /* +1 to make sure is terminated string */
13026
                    if (attrDataSz + 1 > CTC_NAME_SIZE) {
13027
                        WOLFSSL_MSG("attribute size was too large to copy");
13028
                        ret = REQ_ATTRIBUTE_E;
13029
                    }
13030
                    else {
13031
                        XMEMCPY(cert->unstructuredName, attrData, attrDataSz);
13032
                        cert->unstructuredName[attrDataSz] = '\0';
13033
                    }
13034
                }
13035
            }
13036
13037
        #ifdef WOLFSSL_CUSTOM_OID
13038
            if (ret == WOLFSSL_SUCCESS) {
13039
                if ((req->customExtCount < 0) ||
13040
                    (req->customExtCount >= NUM_CUSTOM_EXT)) {
13041
                    WOLFSSL_MSG("Bad value for customExtCount.");
13042
                    ret = WOLFSSL_FAILURE;
13043
                }
13044
13045
                if (ret == WOLFSSL_SUCCESS) {
13046
                    for (idx = 0; idx < req->customExtCount; idx++) {
13047
                        /* Note that ownership is NOT transferred.
13048
                         * req->custom_exts buffers still need to be cleaned
13049
                         * up. */
13050
                        cert->customCertExt[idx] = req->custom_exts[idx];
13051
                    }
13052
                    cert->customCertExtCount = req->customExtCount;
13053
                }
13054
            }
13055
        #endif /* WOLFSSL_CUSTOM_OID */
13056
        #endif /* OPENSSL_ALL */
13057
13058
    #ifdef WOLFSSL_ALT_NAMES
13059
            if (ret == WOLFSSL_SUCCESS) {
13060
                cert->altNamesSz = FlattenAltNames(cert->altNames,
13061
                        sizeof(cert->altNames), req->altNames);
13062
            }
13063
    #endif /* WOLFSSL_ALT_NAMES */
13064
        }
13065
13066
        return ret;
13067
    }
13068
#endif /* WOLFSSL_CERT_REQ */
13069
13070
/* converts WOLFSSL_AN1_TIME to Cert form, returns positive size on
13071
 * success */
13072
static int CertDateFromX509(byte* out, int outSz, WOLFSSL_ASN1_TIME* t)
13073
{
13074
    int sz, i;
13075
13076
    if (t->length + 1 >= outSz) {
13077
        return BUFFER_E;
13078
    }
13079
13080
    out[0] = (byte) t->type;
13081
    sz = (int)SetLength((word32)t->length, out + 1) + 1;  /* gen tag */
13082
    for (i = 0; i < t->length; i++) {
13083
        out[sz + i] = t->data[i];
13084
    }
13085
    return t->length + sz;
13086
}
13087
13088
/* convert a WOLFSSL_X509 to a Cert structure for writing out */
13089
static int CertFromX509(Cert* cert, WOLFSSL_X509* x509)
13090
{
13091
    int ret;
13092
#ifdef WOLFSSL_CERT_EXT
13093
    int i;
13094
#endif
13095
13096
    WOLFSSL_ENTER("wolfSSL_X509_to_Cert");
13097
13098
    if (x509 == NULL || cert == NULL) {
13099
        return BAD_FUNC_ARG;
13100
    }
13101
13102
    wc_InitCert(cert);
13103
13104
    cert->version = (int)wolfSSL_X509_get_version(x509);
13105
13106
    if (x509->notBefore.length > 0) {
13107
        cert->beforeDateSz = CertDateFromX509(cert->beforeDate,
13108
                    CTC_DATE_SIZE, &x509->notBefore);
13109
        if (cert->beforeDateSz <= 0) {
13110
            WOLFSSL_MSG("Error converting WOLFSSL_X509 not before date");
13111
            return WOLFSSL_FAILURE;
13112
        }
13113
    }
13114
    else {
13115
        cert->beforeDateSz = 0;
13116
    }
13117
13118
    if (x509->notAfter.length > 0) {
13119
        cert->afterDateSz = CertDateFromX509(cert->afterDate,
13120
                    CTC_DATE_SIZE, &x509->notAfter);
13121
        if (cert->afterDateSz <= 0) {
13122
            WOLFSSL_MSG("Error converting WOLFSSL_X509 not after date");
13123
            return WOLFSSL_FAILURE;
13124
        }
13125
    }
13126
    else {
13127
        cert->afterDateSz = 0;
13128
    }
13129
13130
#ifdef WOLFSSL_ALT_NAMES
13131
    cert->altNamesSz = FlattenAltNames(cert->altNames,
13132
            sizeof(cert->altNames), x509->altNames);
13133
#endif /* WOLFSSL_ALT_NAMES */
13134
13135
    cert->sigType = wolfSSL_X509_get_signature_type(x509);
13136
    cert->keyType = x509->pubKeyOID;
13137
    cert->isCA    = wolfSSL_X509_get_isCA(x509);
13138
    cert->basicConstCrit = x509->basicConstCrit;
13139
    cert->basicConstSet = x509->basicConstSet;
13140
    if (x509->pathLengthSet) {
13141
        if (x509->pathLength > WOLFSSL_MAX_PATH_LEN) {
13142
            WOLFSSL_MSG("Basic Constraints path length too large");
13143
            WOLFSSL_ERROR_VERBOSE(ASN_PATHLEN_SIZE_E);
13144
            return WOLFSSL_FAILURE;
13145
        }
13146
        cert->pathLen = (byte)x509->pathLength;
13147
        cert->pathLenSet = x509->pathLengthSet;
13148
    }
13149
13150
#ifdef WOLFSSL_CERT_EXT
13151
    if (x509->subjKeyIdSz <= CTC_MAX_SKID_SIZE) {
13152
        if (x509->subjKeyId) {
13153
            XMEMCPY(cert->skid, x509->subjKeyId, x509->subjKeyIdSz);
13154
        }
13155
        cert->skidSz = (int)x509->subjKeyIdSz;
13156
    }
13157
    else {
13158
        WOLFSSL_MSG("Subject Key ID too large");
13159
        WOLFSSL_ERROR_VERBOSE(BUFFER_E);
13160
        return WOLFSSL_FAILURE;
13161
    }
13162
13163
    #ifdef WOLFSSL_AKID_NAME
13164
    cert->rawAkid = 0;
13165
    if (x509->authKeyIdSrc) {
13166
        if (x509->authKeyIdSrcSz > sizeof(cert->akid)) {
13167
            WOLFSSL_MSG("Auth Key ID too large");
13168
            WOLFSSL_ERROR_VERBOSE(BUFFER_E);
13169
            return WOLFSSL_FAILURE;
13170
        }
13171
        XMEMCPY(cert->akid, x509->authKeyIdSrc, x509->authKeyIdSrcSz);
13172
        cert->akidSz = (int)x509->authKeyIdSrcSz;
13173
        cert->rawAkid = 1;
13174
    }
13175
    else
13176
    #endif
13177
    if (x509->authKeyId) {
13178
        if (x509->authKeyIdSz > sizeof(cert->akid)) {
13179
            WOLFSSL_MSG("Auth Key ID too large");
13180
            WOLFSSL_ERROR_VERBOSE(BUFFER_E);
13181
            return WOLFSSL_FAILURE;
13182
        }
13183
        XMEMCPY(cert->akid, x509->authKeyId, x509->authKeyIdSz);
13184
        cert->akidSz = (int)x509->authKeyIdSz;
13185
    }
13186
13187
    for (i = 0; i < x509->certPoliciesNb; i++) {
13188
        /* copy the smaller of MAX macros, by default they are currently equal*/
13189
        if ((int)CTC_MAX_CERTPOL_SZ <= (int)MAX_CERTPOL_SZ) {
13190
            XMEMCPY(cert->certPolicies[i], x509->certPolicies[i],
13191
                    CTC_MAX_CERTPOL_SZ);
13192
        }
13193
        else {
13194
            XMEMCPY(cert->certPolicies[i], x509->certPolicies[i],
13195
                    MAX_CERTPOL_SZ);
13196
        }
13197
    }
13198
    cert->certPoliciesNb = (word16)x509->certPoliciesNb;
13199
13200
    cert->keyUsage = x509->keyUsage;
13201
    cert->extKeyUsage = x509->extKeyUsage;
13202
    cert->nsCertType = x509->nsCertType;
13203
13204
    if (x509->rawCRLInfo != NULL) {
13205
        if (x509->rawCRLInfoSz > CTC_MAX_CRLINFO_SZ) {
13206
            WOLFSSL_MSG("CRL Info too large");
13207
            WOLFSSL_ERROR_VERBOSE(BUFFER_E);
13208
            return WOLFSSL_FAILURE;
13209
        }
13210
        XMEMCPY(cert->crlInfo, x509->rawCRLInfo, x509->rawCRLInfoSz);
13211
        cert->crlInfoSz = x509->rawCRLInfoSz;
13212
    }
13213
13214
#ifdef WOLFSSL_DUAL_ALG_CERTS
13215
    /* We point to instance in x509 so DON'T need to be free'd. */
13216
    cert->sapkiDer = x509->sapkiDer;
13217
    cert->sapkiLen = x509->sapkiLen;
13218
    cert->sapkiCrit = x509->sapkiCrit;
13219
    cert->altSigAlgDer = x509->altSigAlgDer;
13220
    cert->altSigAlgLen  = x509->altSigAlgLen;
13221
    cert->altSigAlgCrit = x509->altSigAlgCrit;
13222
    cert->altSigValDer = x509->altSigValDer;
13223
    cert->altSigValLen = x509->altSigValLen;
13224
    cert->altSigValCrit = x509->altSigValCrit;
13225
#endif /* WOLFSSL_DUAL_ALG_CERTS */
13226
13227
#if defined(WOLFSSL_ASN_TEMPLATE) && defined(WOLFSSL_CUSTOM_OID) && \
13228
    defined(HAVE_OID_ENCODING)
13229
13230
    if ((x509->customExtCount < 0) ||
13231
            (x509->customExtCount >= NUM_CUSTOM_EXT)) {
13232
        WOLFSSL_MSG("Bad value for customExtCount.");
13233
        return WOLFSSL_FAILURE;
13234
    }
13235
13236
    for (i = 0; i < x509->customExtCount; i++) {
13237
        if (wc_SetCustomExtension(cert, x509->custom_exts[i].crit,
13238
                x509->custom_exts[i].oid, x509->custom_exts[i].val,
13239
                x509->custom_exts[i].valSz))
13240
        {
13241
            return WOLFSSL_FAILURE;
13242
        }
13243
    }
13244
#endif /* WOLFSSL_ASN_TEMPLATE && WOLFSSL_CUSTOM_OID && HAVE_OID_ENCODING */
13245
13246
#endif /* WOLFSSL_CERT_EXT */
13247
13248
#ifdef WOLFSSL_CERT_REQ
13249
    /* copy over challenge password for REQ certs */
13250
    XMEMCPY(cert->challengePw, x509->challengePw, CTC_NAME_SIZE);
13251
#endif
13252
13253
    /* Only makes sense to do this for OPENSSL_EXTRA because without
13254
     * this define the function will error out below */
13255
    #ifdef OPENSSL_EXTRA
13256
    if (x509->serialSz == 0 && x509->serialNumber != NULL &&
13257
            /* Check if the buffer contains more than just the
13258
             * ASN tag and length */
13259
            x509->serialNumber->length > 2) {
13260
        if (wolfSSL_X509_set_serialNumber(x509, x509->serialNumber)
13261
                != WOLFSSL_SUCCESS) {
13262
            WOLFSSL_MSG("Failed to set serial number");
13263
            return WOLFSSL_FAILURE;
13264
        }
13265
    }
13266
    #endif
13267
13268
    /* set serial number */
13269
    if (x509->serialSz > 0) {
13270
    #if defined(OPENSSL_EXTRA)
13271
        byte serial[EXTERNAL_SERIAL_SIZE];
13272
        int  serialSz = EXTERNAL_SERIAL_SIZE;
13273
13274
        ret = wolfSSL_X509_get_serial_number(x509, serial, &serialSz);
13275
        if (ret != WOLFSSL_SUCCESS) {
13276
            WOLFSSL_MSG("Serial size error");
13277
            return WOLFSSL_FAILURE;
13278
        }
13279
13280
        if (serialSz > EXTERNAL_SERIAL_SIZE ||
13281
                serialSz > CTC_SERIAL_SIZE) {
13282
            WOLFSSL_MSG("Serial size too large error");
13283
            WOLFSSL_ERROR_VERBOSE(BUFFER_E);
13284
            return WOLFSSL_FAILURE;
13285
        }
13286
        XMEMCPY(cert->serial, serial, serialSz);
13287
        cert->serialSz = serialSz;
13288
    #else
13289
        WOLFSSL_MSG("Getting X509 serial number not supported");
13290
        return WOLFSSL_FAILURE;
13291
    #endif
13292
    }
13293
13294
    /* copy over Name structures */
13295
    if (x509->issuerSet)
13296
        cert->selfSigned = 0;
13297
13298
#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
13299
    ret = CopyX509NameToCert(&x509->subject, cert->sbjRaw);
13300
    if (ret < 0) {
13301
        WOLFSSL_MSG("Subject conversion error");
13302
        return MEMORY_E;
13303
    }
13304
    if (cert->selfSigned) {
13305
        XMEMCPY(cert->issRaw, cert->sbjRaw, sizeof(CertName));
13306
    }
13307
    else {
13308
        ret = CopyX509NameToCert(&x509->issuer, cert->issRaw);
13309
        if (ret < 0) {
13310
            WOLFSSL_MSG("Issuer conversion error");
13311
            return MEMORY_E;
13312
        }
13313
    }
13314
#endif
13315
13316
    cert->heap = x509->heap;
13317
13318
    (void)ret;
13319
    return WOLFSSL_SUCCESS;
13320
}
13321
13322
13323
#if defined(WOLFSSL_HAVE_MLDSA) && defined(WOLFSSL_MLDSA_PRIVATE_KEY) && \
13324
    !defined(WOLFSSL_MLDSA_NO_ASN1) && !defined(WOLFSSL_MLDSA_NO_SIGN)
13325
    /* ML-DSA X.509 signing needs private key decode and sign support; keep
13326
     * every gate that decides "can we sign with ML-DSA" identical so that
13327
     * verify-only builds reject the key type up front. */
13328
    #define WOLFSSL_MLDSA_X509_SIGN
13329
#endif
13330
13331
    /* returns the sig type to use on success i.e CTC_SHAwRSA and WOLFSSL_FALURE
13332
     * on fail case */
13333
    static int wolfSSL_sigTypeFromPKEY(WOLFSSL_EVP_MD* md,
13334
            WOLFSSL_EVP_PKEY* pkey)
13335
    {
13336
    #if defined(OPENSSL_EXTRA)
13337
        int hashType;
13338
        int sigType = WOLFSSL_FAILURE;
13339
    #endif
13340
13341
        if (pkey == NULL) {
13342
            return WOLFSSL_FAILURE;
13343
        }
13344
13345
    #if defined(HAVE_ED25519)
13346
        /* Ed25519 carries its own hash and needs no hash/PWDBASED info, so
13347
         * resolve it outside the guard below (works in --disable-pwdbased).
13348
         * OpenSSL rejects a non-NULL digest for Ed25519 -- match that rather
13349
         * than silently ignoring the caller's md. */
13350
        if (pkey->type == WC_EVP_PKEY_ED25519) {
13351
            if (md != NULL)
13352
                return WOLFSSL_FAILURE;
13353
            return CTC_ED25519;
13354
        }
13355
    #endif
13356
13357
    #if !defined(NO_PWDBASED) && defined(OPENSSL_EXTRA)
13358
    #ifdef WOLFSSL_MLDSA_X509_SIGN
13359
        if (pkey->type == WC_EVP_PKEY_DILITHIUM) {
13360
            /* ML-DSA does not use a separate hash. A NULL md matches
13361
             * OpenSSL's X509_sign(x, pkey, NULL); unlike OpenSSL, a
13362
             * non-NULL md is deliberately ignored rather than rejected to
13363
             * keep hash-passing callers working. */
13364
            if (md != NULL) {
13365
                WOLFSSL_MSG("Ignoring md for ML-DSA signing");
13366
            }
13367
            switch (WOLFSSL_ATOMIC_LOAD(pkey->mldsaOID)) {
13368
                case ML_DSA_44k:
13369
                    sigType = CTC_ML_DSA_44;
13370
                    break;
13371
                case ML_DSA_65k:
13372
                    sigType = CTC_ML_DSA_65;
13373
                    break;
13374
                case ML_DSA_87k:
13375
                    sigType = CTC_ML_DSA_87;
13376
                    break;
13377
            #ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
13378
                case DILITHIUM_LEVEL2k:
13379
                    sigType = CTC_DILITHIUM_LEVEL2;
13380
                    break;
13381
                case DILITHIUM_LEVEL3k:
13382
                    sigType = CTC_DILITHIUM_LEVEL3;
13383
                    break;
13384
                case DILITHIUM_LEVEL5k:
13385
                    sigType = CTC_DILITHIUM_LEVEL5;
13386
                    break;
13387
            #endif
13388
                default:
13389
                    return WOLFSSL_FAILURE;
13390
            }
13391
            return sigType;
13392
        }
13393
    #endif /* WOLFSSL_MLDSA_X509_SIGN */
13394
13395
        /* Every remaining key type signs a digest, and
13396
         * wolfSSL_EVP_get_hashinfo() below dereferences md without a NULL
13397
         * check of its own.  (Checked after ML-DSA, which accepts a NULL md.)
13398
         */
13399
        if (md == NULL) {
13400
            return WOLFSSL_FAILURE;
13401
        }
13402
13403
        /* Convert key type and hash algorithm to a signature algorithm */
13404
        if (wolfSSL_EVP_get_hashinfo(md, &hashType, NULL)
13405
            == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
13406
        {
13407
            return WOLFSSL_FAILURE;
13408
        }
13409
13410
        if (pkey->type == WC_EVP_PKEY_RSA) {
13411
            switch (hashType) {
13412
                case WC_HASH_TYPE_SHA:
13413
                    sigType = CTC_SHAwRSA;
13414
                    break;
13415
                case WC_HASH_TYPE_SHA224:
13416
                    sigType = CTC_SHA224wRSA;
13417
                    break;
13418
                case WC_HASH_TYPE_SHA256:
13419
                    sigType = CTC_SHA256wRSA;
13420
                    break;
13421
                case WC_HASH_TYPE_SHA384:
13422
                    sigType = CTC_SHA384wRSA;
13423
                    break;
13424
                case WC_HASH_TYPE_SHA512:
13425
                    sigType = CTC_SHA512wRSA;
13426
                    break;
13427
            #ifdef WOLFSSL_SHA3
13428
                case WC_HASH_TYPE_SHA3_224:
13429
                    sigType = CTC_SHA3_224wRSA;
13430
                    break;
13431
                case WC_HASH_TYPE_SHA3_256:
13432
                    sigType = CTC_SHA3_256wRSA;
13433
                    break;
13434
                case WC_HASH_TYPE_SHA3_384:
13435
                    sigType = CTC_SHA3_384wRSA;
13436
                    break;
13437
                case WC_HASH_TYPE_SHA3_512:
13438
                    sigType = CTC_SHA3_512wRSA;
13439
                    break;
13440
            #endif
13441
                default:
13442
                    return WOLFSSL_FAILURE;
13443
            }
13444
        }
13445
        else if (pkey->type == WC_EVP_PKEY_EC) {
13446
            switch (hashType) {
13447
                case WC_HASH_TYPE_SHA:
13448
                    sigType = CTC_SHAwECDSA;
13449
                    break;
13450
                case WC_HASH_TYPE_SHA224:
13451
                    sigType = CTC_SHA224wECDSA;
13452
                    break;
13453
                case WC_HASH_TYPE_SHA256:
13454
                    sigType = CTC_SHA256wECDSA;
13455
                    break;
13456
                case WC_HASH_TYPE_SHA384:
13457
                    sigType = CTC_SHA384wECDSA;
13458
                    break;
13459
                case WC_HASH_TYPE_SHA512:
13460
                    sigType = CTC_SHA512wECDSA;
13461
                    break;
13462
            #ifdef WOLFSSL_SHA3
13463
                case WC_HASH_TYPE_SHA3_224:
13464
                    sigType = CTC_SHA3_224wECDSA;
13465
                    break;
13466
                case WC_HASH_TYPE_SHA3_256:
13467
                    sigType = CTC_SHA3_256wECDSA;
13468
                    break;
13469
                case WC_HASH_TYPE_SHA3_384:
13470
                    sigType = CTC_SHA3_384wECDSA;
13471
                    break;
13472
                case WC_HASH_TYPE_SHA3_512:
13473
                    sigType = CTC_SHA3_512wECDSA;
13474
                    break;
13475
            #endif
13476
                default:
13477
                    return WOLFSSL_FAILURE;
13478
            }
13479
        }
13480
        else
13481
            return WOLFSSL_FAILURE;
13482
        return sigType;
13483
#else
13484
        (void)md;
13485
        (void)pkey;
13486
        WOLFSSL_MSG("Cannot get signature type without OPENSSL_EXTRA");
13487
        return WOLFSSL_FAILURE;
13488
#endif /* OPENSSL_EXTRA */
13489
    }
13490
13491
13492
    /* generates DER buffer from WOLFSSL_X509
13493
     * If req == 1 then creates a request DER buffer
13494
     *
13495
     * updates derSz with certificate body size on success
13496
     * return WOLFSSL_SUCCESS on success
13497
     */
13498
    static int wolfssl_x509_make_der(WOLFSSL_X509* x509, int req,
13499
            unsigned char* der, int* derSz, int includeSig)
13500
    {
13501
        int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
13502
        int totalLen;
13503
        Cert* cert = NULL;
13504
        void* key = NULL;
13505
        int type = -1;
13506
    #ifndef NO_RSA
13507
        RsaKey* rsa = NULL;
13508
    #endif
13509
    #ifdef HAVE_ECC
13510
        ecc_key* ecc = NULL;
13511
    #endif
13512
    #ifndef NO_DSA
13513
        DsaKey* dsa = NULL;
13514
    #endif
13515
    #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
13516
        ed25519_key* ed25519 = NULL;
13517
    #endif
13518
    #if defined(HAVE_FALCON)
13519
        falcon_key* falcon = NULL;
13520
    #endif
13521
    #if defined(WOLFSSL_HAVE_MLDSA)
13522
        wc_MlDsaKey* mldsa = NULL;
13523
    #endif
13524
    #if defined(WOLFSSL_HAVE_SLHDSA)
13525
        SlhDsaKey* slhdsa = NULL;
13526
    #endif
13527
        WC_RNG rng;
13528
        word32 idx = 0;
13529
13530
        if (x509 == NULL || der == NULL || derSz == NULL)
13531
            return BAD_FUNC_ARG;
13532
13533
    #ifndef WOLFSSL_CERT_REQ
13534
        if (req) {
13535
            WOLFSSL_MSG("WOLFSSL_CERT_REQ needed for certificate request");
13536
            return WOLFSSL_FAILURE;
13537
        }
13538
    #endif
13539
13540
        /* allocate Cert struct on heap since it is large */
13541
        cert = (Cert*)XMALLOC(sizeof(Cert), NULL, DYNAMIC_TYPE_CERT);
13542
        if (cert == NULL) {
13543
            WOLFSSL_MSG("Failed to allocate memory for Cert struct");
13544
            return WOLFSSL_FAILURE;
13545
        }
13546
        XMEMSET(cert, 0, sizeof(Cert));
13547
13548
    #ifdef WOLFSSL_CERT_REQ
13549
        if (req) {
13550
            if (ReqCertFromX509(cert, x509) != WOLFSSL_SUCCESS) {
13551
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13552
                return WOLFSSL_FAILURE;
13553
            }
13554
        }
13555
        else
13556
    #endif
13557
        {
13558
            /* Create a Cert that has the certificate fields. */
13559
            if (CertFromX509(cert, x509) != WOLFSSL_SUCCESS) {
13560
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13561
                return WOLFSSL_FAILURE;
13562
            }
13563
        }
13564
13565
        /* Create a public key object from requests public key. */
13566
    #ifndef NO_RSA
13567
        if (x509->pubKeyOID == RSAk) {
13568
13569
            rsa = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
13570
            if (rsa == NULL) {
13571
                WOLFSSL_MSG("Failed to allocate memory for RsaKey");
13572
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13573
                return WOLFSSL_FAILURE;
13574
            }
13575
13576
            type = RSA_TYPE;
13577
            ret = wc_InitRsaKey(rsa, x509->heap);
13578
            if (ret != 0) {
13579
                XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
13580
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13581
                return ret;
13582
            }
13583
            ret = wc_RsaPublicKeyDecode(x509->pubKey.buffer, &idx, rsa,
13584
                                                           x509->pubKey.length);
13585
            if (ret != 0) {
13586
                WOLFSSL_ERROR_VERBOSE(ret);
13587
                wc_FreeRsaKey(rsa);
13588
                XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
13589
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13590
                return ret;
13591
            }
13592
            key = (void*)rsa;
13593
        }
13594
    #endif
13595
    #ifdef HAVE_ECC
13596
        if (x509->pubKeyOID == ECDSAk) {
13597
13598
            ecc = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
13599
            if (ecc == NULL) {
13600
                WOLFSSL_MSG("Failed to allocate memory for ecc_key");
13601
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13602
                return WOLFSSL_FAILURE;
13603
            }
13604
13605
            type = ECC_TYPE;
13606
            ret = wc_ecc_init(ecc);
13607
            if (ret != 0) {
13608
                XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
13609
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13610
                return ret;
13611
            }
13612
            ret = wc_EccPublicKeyDecode(x509->pubKey.buffer, &idx, ecc,
13613
                                                           x509->pubKey.length);
13614
            if (ret != 0) {
13615
                WOLFSSL_ERROR_VERBOSE(ret);
13616
                wc_ecc_free(ecc);
13617
                XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
13618
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13619
                return ret;
13620
            }
13621
            key = (void*)ecc;
13622
        }
13623
    #endif
13624
    #ifndef NO_DSA
13625
        if (x509->pubKeyOID == DSAk) {
13626
13627
            dsa = (DsaKey*)XMALLOC(sizeof(DsaKey), NULL, DYNAMIC_TYPE_DSA);
13628
            if (dsa == NULL) {
13629
                WOLFSSL_MSG("Failed to allocate memory for DsaKey");
13630
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13631
                return WOLFSSL_FAILURE;
13632
            }
13633
13634
            type = DSA_TYPE;
13635
            ret = wc_InitDsaKey(dsa);
13636
            if (ret != 0) {
13637
                XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
13638
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13639
                return ret;
13640
            }
13641
            ret = wc_DsaPublicKeyDecode(x509->pubKey.buffer, &idx, dsa,
13642
                                                           x509->pubKey.length);
13643
            if (ret != 0) {
13644
                WOLFSSL_ERROR_VERBOSE(ret);
13645
                wc_FreeDsaKey(dsa);
13646
                XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
13647
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13648
                return ret;
13649
            }
13650
            key = (void*)dsa;
13651
        }
13652
    #endif
13653
    #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
13654
        if (x509->pubKeyOID == ED25519k) {
13655
            ed25519 = wolfSSL_ED25519_new(x509->heap, INVALID_DEVID);
13656
            if (ed25519 == NULL) {
13657
                WOLFSSL_MSG("Failed to allocate memory for ed25519_key");
13658
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13659
                return WOLFSSL_FAILURE;
13660
            }
13661
13662
            type = ED25519_TYPE;
13663
            /* The X.509 public key buffer holds the raw Ed25519 key. */
13664
            ret = wc_ed25519_import_public(x509->pubKey.buffer,
13665
                                           x509->pubKey.length, ed25519);
13666
            if (ret != 0) {
13667
                WOLFSSL_ERROR_VERBOSE(ret);
13668
                wolfSSL_ED25519_free(ed25519);
13669
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13670
                return ret;
13671
            }
13672
            key = (void*)ed25519;
13673
        }
13674
    #endif
13675
    #if defined(HAVE_FALCON)
13676
        if ((x509->pubKeyOID == FALCON_LEVEL1k) ||
13677
            (x509->pubKeyOID == FALCON_LEVEL5k)) {
13678
            falcon = (falcon_key*)XMALLOC(sizeof(falcon_key), NULL,
13679
                                          DYNAMIC_TYPE_FALCON);
13680
            if (falcon == NULL) {
13681
                WOLFSSL_MSG("Failed to allocate memory for falcon_key");
13682
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13683
                return WOLFSSL_FAILURE;
13684
            }
13685
13686
            ret = wc_falcon_init(falcon);
13687
            if (ret != 0) {
13688
                XFREE(falcon, NULL, DYNAMIC_TYPE_FALCON);
13689
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13690
                return ret;
13691
            }
13692
13693
            if (x509->pubKeyOID == FALCON_LEVEL1k) {
13694
                type = FALCON_LEVEL1_TYPE;
13695
                ret = wc_falcon_set_level(falcon, 1);
13696
            }
13697
            else if (x509->pubKeyOID == FALCON_LEVEL5k) {
13698
                type = FALCON_LEVEL5_TYPE;
13699
                ret = wc_falcon_set_level(falcon, 5);
13700
            }
13701
13702
            if (ret == 0) {
13703
                ret = wc_Falcon_PublicKeyDecode(x509->pubKey.buffer, &idx,
13704
                                                falcon, x509->pubKey.length);
13705
            }
13706
            if (ret != 0) {
13707
                WOLFSSL_ERROR_VERBOSE(ret);
13708
                wc_falcon_free(falcon);
13709
                XFREE(falcon, NULL, DYNAMIC_TYPE_FALCON);
13710
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13711
                return ret;
13712
            }
13713
            key = (void*)falcon;
13714
        }
13715
    #endif
13716
    #if defined(WOLFSSL_HAVE_MLDSA)
13717
        if ((x509->pubKeyOID == ML_DSA_44k) ||
13718
            (x509->pubKeyOID == ML_DSA_65k) ||
13719
            (x509->pubKeyOID == ML_DSA_87k)
13720
            #ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
13721
         || (x509->pubKeyOID == DILITHIUM_LEVEL2k)
13722
         || (x509->pubKeyOID == DILITHIUM_LEVEL3k)
13723
         || (x509->pubKeyOID == DILITHIUM_LEVEL5k)
13724
            #endif /* WOLFSSL_MLDSA_FIPS204_DRAFT */
13725
            ) {
13726
            mldsa = (wc_MlDsaKey*)XMALLOC(sizeof(wc_MlDsaKey), NULL,
13727
                                          DYNAMIC_TYPE_MLDSA);
13728
            if (mldsa == NULL) {
13729
                WOLFSSL_MSG("Failed to allocate memory for wc_MlDsaKey");
13730
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13731
                return WOLFSSL_FAILURE;
13732
            }
13733
13734
            ret = wc_MlDsaKey_Init(mldsa, NULL, INVALID_DEVID);
13735
            if (ret != 0) {
13736
                XFREE(mldsa, NULL, DYNAMIC_TYPE_MLDSA);
13737
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13738
                return ret;
13739
            }
13740
13741
            if (x509->pubKeyOID == ML_DSA_44k) {
13742
                type = ML_DSA_44_TYPE;
13743
                wc_MlDsaKey_SetParams(mldsa, WC_ML_DSA_44);
13744
            }
13745
            else if (x509->pubKeyOID == ML_DSA_65k) {
13746
                type = ML_DSA_65_TYPE;
13747
                wc_MlDsaKey_SetParams(mldsa, WC_ML_DSA_65);
13748
            }
13749
            else if (x509->pubKeyOID == ML_DSA_87k) {
13750
                type = ML_DSA_87_TYPE;
13751
                wc_MlDsaKey_SetParams(mldsa, WC_ML_DSA_87);
13752
            }
13753
            #ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
13754
            else if (x509->pubKeyOID == DILITHIUM_LEVEL2k) {
13755
                type = DILITHIUM_LEVEL2_TYPE;
13756
                wc_MlDsaKey_SetParams(mldsa, WC_ML_DSA_44_DRAFT);
13757
            }
13758
            else if (x509->pubKeyOID == DILITHIUM_LEVEL3k) {
13759
                type = DILITHIUM_LEVEL3_TYPE;
13760
                wc_MlDsaKey_SetParams(mldsa, WC_ML_DSA_65_DRAFT);
13761
            }
13762
            else if (x509->pubKeyOID == DILITHIUM_LEVEL5k) {
13763
                type = DILITHIUM_LEVEL5_TYPE;
13764
                wc_MlDsaKey_SetParams(mldsa, WC_ML_DSA_87_DRAFT);
13765
            }
13766
            #endif /* WOLFSSL_MLDSA_FIPS204_DRAFT */
13767
13768
            ret = wc_MlDsaKey_PublicKeyDecode(mldsa, x509->pubKey.buffer,
13769
                                    x509->pubKey.length, &idx);
13770
            if (ret != 0) {
13771
                WOLFSSL_ERROR_VERBOSE(ret);
13772
                wc_MlDsaKey_Free(mldsa);
13773
                XFREE(mldsa, NULL, DYNAMIC_TYPE_MLDSA);
13774
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13775
                return ret;
13776
            }
13777
            key = (void*)mldsa;
13778
        }
13779
    #endif
13780
    #if defined(WOLFSSL_HAVE_SLHDSA)
13781
        if (wc_IsSlhDsaOid(x509->pubKeyOID)) {
13782
            int paramInt = wc_SlhDsaOidToParam(x509->pubKeyOID);
13783
            int certType = wc_SlhDsaOidToCertType(x509->pubKeyOID);
13784
13785
            /* The OID is a recognised SLH-DSA OID but the parameter set
13786
             * isn't built in; surface NOT_COMPILED_IN directly so
13787
             * callers can render an accurate diagnostic. */
13788
            if (paramInt == WC_NO_ERR_TRACE(NOT_COMPILED_IN) ||
13789
                    certType == WC_NO_ERR_TRACE(NOT_COMPILED_IN)) {
13790
                WOLFSSL_MSG("SLH-DSA variant not compiled in");
13791
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13792
                return NOT_COMPILED_IN;
13793
            }
13794
            /* Defensive: wc_IsSlhDsaOid already implies both lookups
13795
             * succeed, but check explicitly so any future drift between the
13796
             * three OID helpers surfaces as a clean failure rather than
13797
             * undefined behaviour from casting -1 to enum SlhDsaParam. */
13798
            if (paramInt < 0 || certType < 0) {
13799
                WOLFSSL_MSG("SLH-DSA OID helper mismatch");
13800
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13801
                return WOLFSSL_FAILURE;
13802
            }
13803
13804
            slhdsa = (SlhDsaKey*)XMALLOC(sizeof(SlhDsaKey), NULL,
13805
                                          DYNAMIC_TYPE_SLHDSA);
13806
            if (slhdsa == NULL) {
13807
                WOLFSSL_MSG("Failed to allocate memory for SlhDsaKey");
13808
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13809
                return WOLFSSL_FAILURE;
13810
            }
13811
13812
            type = certType;
13813
13814
            ret = wc_SlhDsaKey_Init(slhdsa, (enum SlhDsaParam)paramInt, NULL,
13815
                                    INVALID_DEVID);
13816
            if (ret != 0) {
13817
                XFREE(slhdsa, NULL, DYNAMIC_TYPE_SLHDSA);
13818
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13819
                return ret;
13820
            }
13821
13822
            ret = wc_SlhDsaKey_PublicKeyDecode(x509->pubKey.buffer, &idx,
13823
                                               slhdsa, x509->pubKey.length);
13824
            if (ret != 0) {
13825
                WOLFSSL_ERROR_VERBOSE(ret);
13826
                wc_SlhDsaKey_Free(slhdsa);
13827
                XFREE(slhdsa, NULL, DYNAMIC_TYPE_SLHDSA);
13828
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13829
                return ret;
13830
            }
13831
            key = (void*)slhdsa;
13832
        }
13833
    #endif
13834
        if (key == NULL) {
13835
            WOLFSSL_MSG("No public key found for certificate");
13836
            XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13837
            return WOLFSSL_FAILURE;
13838
        }
13839
13840
        /* Make the body of the certificate request. */
13841
    #ifdef WOLFSSL_CERT_REQ
13842
        if (req) {
13843
            ret = wc_MakeCertReq_ex(cert, der, *derSz, type, key);
13844
        }
13845
        else
13846
    #endif
13847
        {
13848
            ret = wc_InitRng(&rng);
13849
            if (ret != 0) {
13850
                ret = WOLFSSL_FAILURE;
13851
                goto cleanup;
13852
            }
13853
13854
            ret = wc_MakeCert_ex(cert, der, *derSz, type, key, &rng);
13855
            wc_FreeRng(&rng);
13856
        }
13857
        if (ret <= 0) {
13858
            WOLFSSL_ERROR_VERBOSE(ret);
13859
            ret = WOLFSSL_FAILURE;
13860
            goto cleanup;
13861
        }
13862
13863
        if ((x509->serialSz == 0) &&
13864
                (cert->serialSz <= EXTERNAL_SERIAL_SIZE) &&
13865
                (cert->serialSz > 0)) {
13866
        #if defined(OPENSSL_EXTRA)
13867
            WOLFSSL_ASN1_INTEGER *i = wolfSSL_ASN1_INTEGER_new();
13868
13869
            if (i == NULL) {
13870
                WOLFSSL_MSG("wolfSSL_ASN1_INTEGER_new error");
13871
                ret = WOLFSSL_FAILURE;
13872
                goto cleanup;
13873
            }
13874
            else {
13875
                i->length = cert->serialSz + 2;
13876
                i->data[0] = ASN_INTEGER;
13877
                i->data[1] = (unsigned char)cert->serialSz;
13878
                XMEMCPY(i->data + 2, cert->serial, cert->serialSz);
13879
                if (wolfSSL_X509_set_serialNumber(x509, i) != WOLFSSL_SUCCESS) {
13880
                    WOLFSSL_MSG("Issue setting generated serial number");
13881
                    wolfSSL_ASN1_INTEGER_free(i);
13882
                    ret = WOLFSSL_FAILURE;
13883
                    goto cleanup;
13884
                }
13885
                wolfSSL_ASN1_INTEGER_free(i);
13886
            }
13887
        #else
13888
            WOLFSSL_MSG("ASN1_INTEGER API not in build");
13889
13890
            ret = WOLFSSL_FAILURE;
13891
            goto cleanup;
13892
        #endif /* OPENSSL_EXTRA */
13893
        }
13894
13895
        if (includeSig) {
13896
            if (!x509->sig.buffer) {
13897
                WOLFSSL_MSG("No signature buffer");
13898
                ret = WOLFSSL_FAILURE;
13899
                goto cleanup;
13900
            }
13901
            totalLen = AddSignature(NULL, ret, NULL, x509->sig.length,
13902
                                  x509->sigOID);
13903
            if (totalLen > *derSz) {
13904
                WOLFSSL_MSG("Output der buffer too short");
13905
                ret = WOLFSSL_FAILURE;
13906
                goto cleanup;
13907
            }
13908
            ret = AddSignature(der, ret, x509->sig.buffer,
13909
                               x509->sig.length, x509->sigOID);
13910
        }
13911
13912
        *derSz = ret;
13913
        ret = WOLFSSL_SUCCESS;
13914
cleanup:
13915
        /* Dispose of the public key object. */
13916
    #ifndef NO_RSA
13917
        if (x509->pubKeyOID == RSAk) {
13918
            wc_FreeRsaKey(rsa);
13919
            XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
13920
        }
13921
    #endif
13922
    #ifdef HAVE_ECC
13923
        if (x509->pubKeyOID == ECDSAk) {
13924
            wc_ecc_free(ecc);
13925
            XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
13926
        }
13927
    #endif
13928
    #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
13929
        if (x509->pubKeyOID == ED25519k) {
13930
            wolfSSL_ED25519_free(ed25519);
13931
        }
13932
    #endif
13933
    #ifndef NO_DSA
13934
        if (x509->pubKeyOID == DSAk) {
13935
            wc_FreeDsaKey(dsa);
13936
            XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
13937
        }
13938
    #endif
13939
    #if defined(HAVE_FALCON)
13940
        if ((x509->pubKeyOID == FALCON_LEVEL1k) ||
13941
            (x509->pubKeyOID == FALCON_LEVEL5k)) {
13942
            wc_falcon_free(falcon);
13943
            XFREE(falcon, NULL, DYNAMIC_TYPE_FALCON);
13944
        }
13945
    #endif
13946
    #if defined(WOLFSSL_HAVE_MLDSA)
13947
        if ((x509->pubKeyOID == ML_DSA_44k) ||
13948
            (x509->pubKeyOID == ML_DSA_65k) ||
13949
            (x509->pubKeyOID == ML_DSA_87k)
13950
        #ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
13951
         || (x509->pubKeyOID == DILITHIUM_LEVEL2k)
13952
         || (x509->pubKeyOID == DILITHIUM_LEVEL3k)
13953
         || (x509->pubKeyOID == DILITHIUM_LEVEL5k)
13954
        #endif
13955
        ) {
13956
            wc_MlDsaKey_Free(mldsa);
13957
            XFREE(mldsa, NULL, DYNAMIC_TYPE_MLDSA);
13958
        }
13959
    #endif
13960
    #if defined(WOLFSSL_HAVE_SLHDSA)
13961
        /* wc_IsSlhDsaOid returns 1 even for OIDs whose backend is
13962
         * NOT_COMPILED_IN; the early-return at the top of the SLH-DSA
13963
         * branch keeps slhdsa==NULL in that case. Guard the cleanup so
13964
         * future restructuring (a goto cleanup from inside the
13965
         * unbuilt-variant handler) cannot dereference a NULL key. */
13966
        if (wc_IsSlhDsaOid(x509->pubKeyOID) && slhdsa != NULL) {
13967
            wc_SlhDsaKey_Free(slhdsa);
13968
            XFREE(slhdsa, NULL, DYNAMIC_TYPE_SLHDSA);
13969
        }
13970
    #endif
13971
        XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
13972
13973
        return ret;
13974
    }
13975
13976
13977
    /* signs a der buffer for the WOLFSSL_X509 structure using the PKEY and MD
13978
     * hash passed in
13979
     *
13980
     * WARNING: this free's and replaces the existing DER buffer in the
13981
     *          WOLFSSL_X509 with the newly signed buffer.
13982
     * returns size of signed buffer on success and negative values on fail
13983
     */
13984
    static int wolfSSL_X509_resign_cert(WOLFSSL_X509* x509, int req,
13985
            unsigned char* der, int derSz, int certBodySz, WOLFSSL_EVP_MD* md,
13986
            WOLFSSL_EVP_PKEY* pkey)
13987
    {
13988
        int ret;
13989
        void* key = NULL;
13990
        int type = -1;
13991
        int sigType;
13992
        WC_RNG rng;
13993
    #ifdef WOLFSSL_MLDSA_X509_SIGN
13994
        wc_MlDsaKey* mldsa = NULL;
13995
    #endif
13996
13997
        (void)req;
13998
        WOLFSSL_ENTER("wolfSSL_X509_resign_cert");
13999
14000
        sigType = wolfSSL_sigTypeFromPKEY(md, pkey);
14001
        if (sigType == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
14002
            WOLFSSL_MSG("Error getting signature type from pkey");
14003
            return WOLFSSL_FATAL_ERROR;
14004
        }
14005
14006
14007
        /* Get the private key object and type from pkey. */
14008
    #ifndef NO_RSA
14009
        if (pkey->type == WC_EVP_PKEY_RSA) {
14010
            type = RSA_TYPE;
14011
            key = pkey->rsa->internal;
14012
        }
14013
    #endif
14014
    #ifdef HAVE_ECC
14015
        if (pkey->type == WC_EVP_PKEY_EC) {
14016
            type = ECC_TYPE;
14017
            key = pkey->ecc->internal;
14018
        }
14019
    #endif
14020
    #ifdef WOLFSSL_MLDSA_X509_SIGN
14021
        if (pkey->type == WC_EVP_PKEY_DILITHIUM) {
14022
            /* Decode the ML-DSA private key held as DER in pkey.ptr. */
14023
            word32 idx = 0;
14024
            int oidSum = 0;
14025
            int decRet;
14026
14027
            mldsa = (wc_MlDsaKey*)XMALLOC(sizeof(wc_MlDsaKey), x509->heap,
14028
                    DYNAMIC_TYPE_MLDSA);
14029
            if (mldsa == NULL) {
14030
                WOLFSSL_MSG("Failed to allocate memory for wc_MlDsaKey");
14031
                return WOLFSSL_FATAL_ERROR;
14032
            }
14033
            if (wc_MlDsaKey_Init(mldsa, x509->heap, INVALID_DEVID) != 0) {
14034
                WOLFSSL_MSG("wc_MlDsaKey_Init error");
14035
                XFREE(mldsa, x509->heap, DYNAMIC_TYPE_MLDSA);
14036
                return WOLFSSL_FATAL_ERROR;
14037
            }
14038
            PRIVATE_KEY_UNLOCK();
14039
            decRet = wc_MlDsaKey_PrivateKeyDecode(mldsa,
14040
                    (const byte*)pkey->pkey.ptr, (word32)pkey->pkey_sz,
14041
                    &idx);
14042
            PRIVATE_KEY_LOCK();
14043
            /* Map the parameter set to its OID with mldsa_get_oid_sum():
14044
             * unlike wc_MlDsaKey_GetParams() it distinguishes FIPS204-draft
14045
             * levels. */
14046
            if (decRet != 0 ||
14047
                    mldsa_get_oid_sum(mldsa, &oidSum) != 0) {
14048
                WOLFSSL_MSG("Error decoding ML-DSA private key");
14049
                wc_MlDsaKey_Free(mldsa);
14050
                XFREE(mldsa, x509->heap, DYNAMIC_TYPE_MLDSA);
14051
                return WOLFSSL_FATAL_ERROR;
14052
            }
14053
            /* sigType above came from the cached pkey->mldsaOID; require
14054
             * the decoded key to agree so a stale cache cannot emit a
14055
             * certificate whose signatureAlgorithm disagrees with the
14056
             * actual signature. */
14057
            if (oidSum != WOLFSSL_ATOMIC_LOAD(pkey->mldsaOID)) {
14058
                WOLFSSL_MSG("ML-DSA key does not match cached pkey OID");
14059
                wc_MlDsaKey_Free(mldsa);
14060
                XFREE(mldsa, x509->heap, DYNAMIC_TYPE_MLDSA);
14061
                return WOLFSSL_FATAL_ERROR;
14062
            }
14063
            switch (oidSum) {
14064
                case ML_DSA_44k:
14065
                    type = ML_DSA_44_TYPE;
14066
                    break;
14067
                case ML_DSA_65k:
14068
                    type = ML_DSA_65_TYPE;
14069
                    break;
14070
                case ML_DSA_87k:
14071
                    type = ML_DSA_87_TYPE;
14072
                    break;
14073
            #ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
14074
                case DILITHIUM_LEVEL2k:
14075
                    type = DILITHIUM_LEVEL2_TYPE;
14076
                    break;
14077
                case DILITHIUM_LEVEL3k:
14078
                    type = DILITHIUM_LEVEL3_TYPE;
14079
                    break;
14080
                case DILITHIUM_LEVEL5k:
14081
                    type = DILITHIUM_LEVEL5_TYPE;
14082
                    break;
14083
            #endif
14084
                default:
14085
                    WOLFSSL_MSG("Unsupported ML-DSA parameter set");
14086
                    wc_MlDsaKey_Free(mldsa);
14087
                    XFREE(mldsa, x509->heap, DYNAMIC_TYPE_MLDSA);
14088
                    return WOLFSSL_FATAL_ERROR;
14089
            }
14090
            key = mldsa;
14091
        }
14092
    #endif /* WOLFSSL_MLDSA_X509_SIGN */
14093
    #if defined(HAVE_ED25519)
14094
        if (pkey->type == WC_EVP_PKEY_ED25519) {
14095
            /* Reject a missing key here, as the other Ed25519 entry points do,
14096
             * so a public-only or uninitialised EVP_PKEY fails clearly instead
14097
             * of reaching wc_SignCert_ex() with a NULL key and coming back as
14098
             * an algorithm-id error. */
14099
            if (pkey->ed25519 == NULL) {
14100
                WOLFSSL_MSG("No Ed25519 key in EVP_PKEY");
14101
                return WOLFSSL_FATAL_ERROR;
14102
            }
14103
            type = ED25519_TYPE;
14104
            key = pkey->ed25519;
14105
        }
14106
    #endif
14107
14108
        /* Sign the certificate (request) body. */
14109
        ret = wc_InitRng(&rng);
14110
        if (ret != 0) {
14111
        #ifdef WOLFSSL_MLDSA_X509_SIGN
14112
            if (mldsa != NULL) {
14113
                wc_MlDsaKey_Free(mldsa);
14114
                XFREE(mldsa, x509->heap, DYNAMIC_TYPE_MLDSA);
14115
            }
14116
        #endif
14117
            return ret;
14118
        }
14119
        ret = wc_SignCert_ex(certBodySz, sigType, der, (word32)derSz, type, key,
14120
            &rng);
14121
        wc_FreeRng(&rng);
14122
    #ifdef WOLFSSL_MLDSA_X509_SIGN
14123
        if (mldsa != NULL) {
14124
            wc_MlDsaKey_Free(mldsa);
14125
            XFREE(mldsa, x509->heap, DYNAMIC_TYPE_MLDSA);
14126
        }
14127
    #endif
14128
        if (ret < 0) {
14129
            WOLFSSL_LEAVE("wolfSSL_X509_resign_cert", ret);
14130
            return ret;
14131
        }
14132
        derSz = ret;
14133
14134
        /* Extract signature from buffer */
14135
        {
14136
            word32 idx = 0;
14137
            int    len = 0;
14138
14139
            /* Read top level sequence */
14140
            if (GetSequence(der, &idx, &len, (word32)derSz) < 0) {
14141
                WOLFSSL_MSG("GetSequence error");
14142
                return WOLFSSL_FATAL_ERROR;
14143
            }
14144
            /* Move idx to signature */
14145
            idx += certBodySz;
14146
            /* Read signature algo sequence */
14147
            if (GetSequence(der, &idx, &len, (word32)derSz) < 0) {
14148
                WOLFSSL_MSG("GetSequence error");
14149
                return WOLFSSL_FATAL_ERROR;
14150
            }
14151
            idx += len;
14152
            /* Read signature bit string */
14153
            if (CheckBitString(der, &idx, &len, (word32)derSz, 0, NULL) != 0) {
14154
                WOLFSSL_MSG("CheckBitString error");
14155
                return WOLFSSL_FATAL_ERROR;
14156
            }
14157
            /* Sanity check */
14158
            if (idx + len != (word32)derSz) {
14159
                WOLFSSL_MSG("unexpected asn1 structure");
14160
                return WOLFSSL_FATAL_ERROR;
14161
            }
14162
            x509->sig.length = 0;
14163
            if (x509->sig.buffer)
14164
                XFREE(x509->sig.buffer, x509->heap, DYNAMIC_TYPE_SIGNATURE);
14165
            x509->sig.buffer = (byte*)XMALLOC(len, x509->heap,
14166
                                              DYNAMIC_TYPE_SIGNATURE);
14167
            if (!x509->sig.buffer) {
14168
                WOLFSSL_MSG("malloc error");
14169
                return WOLFSSL_FATAL_ERROR;
14170
            }
14171
            XMEMCPY(x509->sig.buffer, der + idx, len);
14172
            x509->sig.length = (unsigned int)len;
14173
        }
14174
14175
        /* Put in the new certificate encoding into the x509 object. */
14176
        FreeDer(&x509->derCert);
14177
    #if !defined(WOLFSSL_NO_CA_NAMES) && defined(OPENSSL_EXTRA)
14178
        /* The names are encoded again, not as they were in the old encoding
14179
         * or in the names they were set from, and not where they were. */
14180
        ClearX509NameRaw(&x509->issuer);
14181
        ClearX509NameRaw(&x509->subject);
14182
    #endif
14183
        type = CERT_TYPE;
14184
    #ifdef WOLFSSL_CERT_REQ
14185
        if (req) {
14186
            type = CERTREQ_TYPE;
14187
        }
14188
    #endif
14189
        if (AllocDer(&x509->derCert, (word32)derSz, type, NULL) != 0)
14190
            return WOLFSSL_FATAL_ERROR;
14191
        XMEMCPY(x509->derCert->buffer, der, derSz);
14192
        x509->derCert->length = (word32)derSz;
14193
14194
        return ret;
14195
    }
14196
14197
14198
#ifndef WC_MAX_X509_GEN
14199
    /* able to override max size until dynamic buffer created */
14200
    #define WC_MAX_X509_GEN 4096
14201
#endif
14202
#if defined(WOLFSSL_HAVE_MLDSA) && !defined(WC_MAX_X509_GEN_MLDSA)
14203
    /* Base size plus the largest compiled-in ML-DSA signature and its
14204
     * ASN.1 overhead; the subject key is added in x509_gen_buf_sz(). */
14205
    #define WC_MAX_X509_GEN_MLDSA \
14206
        (WC_MAX_X509_GEN + MLDSA_MAX_SIG_SIZE + MAX_ALGO_SZ + \
14207
         MAX_SEQ_SZ * 2)
14208
#endif
14209
14210
/* DER buffer size for certificate/CSR signing: chosen from the signing
14211
 * key type, plus the subject public key held in the x509 so that a
14212
 * large (e.g. ML-DSA) public key fits under a classic signing key too. */
14213
static int x509_gen_buf_sz(const WOLFSSL_X509* x509,
14214
    const WOLFSSL_EVP_PKEY* pkey)
14215
{
14216
    int sz = WC_MAX_X509_GEN;
14217
14218
#ifdef WOLFSSL_HAVE_MLDSA
14219
    if (pkey != NULL && pkey->type == WC_EVP_PKEY_DILITHIUM) {
14220
        sz = WC_MAX_X509_GEN_MLDSA;
14221
    }
14222
#else
14223
    (void)pkey;
14224
#endif
14225
    return sz + (int)x509->pubKey.length;
14226
}
14227
14228
/* returns the size of signature on success */
14229
int wolfSSL_X509_sign(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey,
14230
        const WOLFSSL_EVP_MD* md)
14231
{
14232
    int  ret;
14233
    byte *der = NULL;
14234
    int  bufSz = 0;
14235
    int  derSz = 0;
14236
    int  sigType;
14237
14238
    WOLFSSL_ENTER("wolfSSL_X509_sign");
14239
14240
    if (x509 == NULL || pkey == NULL) {
14241
        ret = WOLFSSL_FAILURE;
14242
        goto out;
14243
    }
14244
14245
    bufSz = x509_gen_buf_sz(x509, pkey);
14246
    derSz = bufSz;
14247
    der = (byte *)XMALLOC((size_t)bufSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14248
    if (der == NULL) {
14249
        ret = WOLFSSL_FAILURE;
14250
        goto out;
14251
    }
14252
14253
    /* Resolves the (pkey, md) combination - most key types require an explicit
14254
     * digest, Ed25519 requires a NULL one, ML-DSA ignores it - and only
14255
     * updates sigOID on success, so the object is unmodified on a rejected
14256
     * key/md combination. */
14257
    sigType = wolfSSL_sigTypeFromPKEY((WOLFSSL_EVP_MD*)md, pkey);
14258
    if (sigType == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
14259
        WOLFSSL_MSG("Unsupported key/md combination for signing");
14260
        ret = WOLFSSL_FAILURE;
14261
        goto out;
14262
    }
14263
    x509->sigOID = sigType;
14264
    if ((ret = wolfssl_x509_make_der(x509, 0, der, &derSz, 0)) !=
14265
            WOLFSSL_SUCCESS) {
14266
        WOLFSSL_MSG("Unable to make DER for X509");
14267
        WOLFSSL_LEAVE("wolfSSL_X509_sign", ret);
14268
        (void)ret;
14269
        ret = WOLFSSL_FAILURE;
14270
        goto out;
14271
    }
14272
14273
    ret = wolfSSL_X509_resign_cert(x509, 0, der, bufSz, derSz,
14274
            (WOLFSSL_EVP_MD*)md, pkey);
14275
    if (ret <= 0) {
14276
        WOLFSSL_LEAVE("wolfSSL_X509_sign", ret);
14277
        ret = WOLFSSL_FAILURE;
14278
        goto out;
14279
    }
14280
14281
out:
14282
    XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14283
14284
    return ret;
14285
}
14286
14287
#if defined(OPENSSL_EXTRA)
14288
int wolfSSL_X509_sign_ctx(WOLFSSL_X509 *x509, WOLFSSL_EVP_MD_CTX *ctx)
14289
{
14290
    WOLFSSL_ENTER("wolfSSL_X509_sign_ctx");
14291
14292
    if (!x509 || !ctx || !ctx->pctx || !ctx->pctx->pkey) {
14293
        WOLFSSL_MSG("Bad parameter");
14294
        return WOLFSSL_FAILURE;
14295
    }
14296
14297
    return wolfSSL_X509_sign(x509, ctx->pctx->pkey,
14298
        wolfSSL_EVP_MD_CTX_md(ctx));
14299
}
14300
#endif /* OPENSSL_EXTRA */
14301
#endif /* WOLFSSL_CERT_GEN */
14302
14303
14304
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
14305
    defined(OPENSSL_EXTRA_X509_SMALL) || defined(WOLFSSL_WPAS_SMALL)
14306
/* Converts from WC_NID_* value to wolfSSL value if needed.
14307
 *
14308
 * @param [in] nid  Numeric Id of a domain name component.
14309
 * @return  Domain name tag values - wolfSSL internal values.
14310
 * @return  -1 when nid isn't known.
14311
 */
14312
static int ConvertNIDToWolfSSL(int nid)
14313
{
14314
    switch (nid) {
14315
        case WC_NID_commonName : return ASN_COMMON_NAME;
14316
    #ifdef WOLFSSL_CERT_NAME_ALL
14317
        case WC_NID_name :       return ASN_NAME;
14318
        case WC_NID_givenName:   return ASN_GIVEN_NAME;
14319
        case WC_NID_dnQualifier :   return ASN_DNQUALIFIER;
14320
        case WC_NID_initials:   return ASN_INITIALS;
14321
    #endif /* WOLFSSL_CERT_NAME_ALL */
14322
        case WC_NID_surname :    return ASN_SUR_NAME;
14323
        case WC_NID_countryName: return ASN_COUNTRY_NAME;
14324
        case WC_NID_localityName: return ASN_LOCALITY_NAME;
14325
        case WC_NID_stateOrProvinceName: return ASN_STATE_NAME;
14326
        case WC_NID_streetAddress: return ASN_STREET_ADDR;
14327
        case WC_NID_organizationName: return ASN_ORG_NAME;
14328
        case WC_NID_organizationalUnitName: return ASN_ORGUNIT_NAME;
14329
        case WC_NID_emailAddress: return ASN_EMAIL_NAME;
14330
        case WC_NID_pkcs9_contentType: return ASN_CONTENT_TYPE;
14331
        case WC_NID_serialNumber: return ASN_SERIAL_NUMBER;
14332
        case WC_NID_userId: return ASN_USER_ID;
14333
        case WC_NID_x500UniqueIdentifier: return ASN_X500_UNIQUE_ID;
14334
        case WC_NID_businessCategory: return ASN_BUS_CAT;
14335
        case WC_NID_domainComponent: return ASN_DOMAIN_COMPONENT;
14336
        case WC_NID_postalCode: return ASN_POSTAL_CODE;
14337
        case WC_NID_rfc822Mailbox: return ASN_RFC822_MAILBOX;
14338
        case WC_NID_favouriteDrink: return ASN_FAVOURITE_DRINK;
14339
        default:
14340
            WOLFSSL_MSG("Attribute NID not found");
14341
            return WOLFSSL_FATAL_ERROR;
14342
    }
14343
}
14344
#endif /* OPENSSL_ALL || OPENSSL_EXTRA ||
14345
          OPENSSL_EXTRA_X509_SMALL || WOLFSSL_WPAS_SMALL*/
14346
14347
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
14348
    defined(OPENSSL_EXTRA_X509_SMALL)
14349
/* This is to convert the x509 name structure into canonical DER format     */
14350
/*  , which has the following rules:                                        */
14351
/*   convert to UTF8                                                        */
14352
/*   convert to lower case                                                  */
14353
/*   multi-spaces collapsed                                                 */
14354
/*   leading SEQUENCE header is skipped                                     */
14355
/* @param  name a pointer to X509_NAME that is to be converted              */
14356
/* @param  out  a pointer to converted data                                 */
14357
/* @return a number of converted bytes, otherwise <=0 error code            */
14358
int wolfSSL_i2d_X509_NAME_canon(WOLFSSL_X509_NAME* name, unsigned char** out)
14359
{
14360
    int  totalBytes = 0, i, idx;
14361
    byte *output, *local = NULL;
14362
    WC_DECLARE_VAR(names, EncodedName, MAX_NAME_ENTRIES, 0);
14363
14364
    if (name == NULL)
14365
        return BAD_FUNC_ARG;
14366
14367
    WC_ALLOC_VAR_EX(names, EncodedName, MAX_NAME_ENTRIES, NULL,
14368
        DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E);
14369
14370
    XMEMSET(names, 0, sizeof(EncodedName) * MAX_NAME_ENTRIES);
14371
14372
    for (i = 0; i < MAX_NAME_ENTRIES; i++) {
14373
        WOLFSSL_X509_NAME_ENTRY* entry;
14374
        int ret;
14375
14376
        entry = wolfSSL_X509_NAME_get_entry(name, i);
14377
        if (entry != NULL && entry->set >= 1) {
14378
            const char* nameStr;
14379
            WOLFSSL_ASN1_STRING* data;
14380
            WOLFSSL_ASN1_STRING* cano_data;
14381
14382
            cano_data = wolfSSL_ASN1_STRING_new();
14383
            if (cano_data == NULL) {
14384
                WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14385
                return MEMORY_E;
14386
            }
14387
14388
            data = wolfSSL_X509_NAME_ENTRY_get_data(entry);
14389
            if (data == NULL) {
14390
                WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14391
                wolfSSL_ASN1_STRING_free(cano_data);
14392
                WOLFSSL_MSG("Error getting entry data");
14393
                return WOLFSSL_FATAL_ERROR;
14394
            }
14395
            if (wolfSSL_ASN1_STRING_canon(cano_data, data) != WOLFSSL_SUCCESS) {
14396
                WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14397
                wolfSSL_ASN1_STRING_free(cano_data);
14398
                return WOLFSSL_FAILURE;
14399
            }
14400
            nameStr = (const char*)wolfSSL_ASN1_STRING_data(cano_data);
14401
14402
            /* allow for blank values in the name structure, eg OU= */
14403
            if (nameStr)
14404
            {
14405
                ret = wc_EncodeNameCanonical(&names[i], nameStr, CTC_UTF8,
14406
                    (byte)ConvertNIDToWolfSSL(entry->nid));
14407
                if (ret < 0) {
14408
                    WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14409
                    wolfSSL_ASN1_STRING_free(cano_data);
14410
                    WOLFSSL_MSG("EncodeName failed");
14411
                    return WOLFSSL_FATAL_ERROR;
14412
                }
14413
                totalBytes += ret;
14414
            }
14415
14416
            wolfSSL_ASN1_STRING_free(cano_data);
14417
        }
14418
    }
14419
14420
    if (out == NULL) {
14421
        /* If out is NULL, caller just wants length. */
14422
        WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14423
        return totalBytes;
14424
    }
14425
14426
    /* skip header */
14427
    /* check if using buffer passed in */
14428
    if (*out == NULL) {
14429
        *out = local = (unsigned char*)XMALLOC(totalBytes, NULL,
14430
                DYNAMIC_TYPE_OPENSSL);
14431
        if (*out == NULL) {
14432
            return MEMORY_E;
14433
        }
14434
    }
14435
    output = *out;
14436
    idx = 0;
14437
14438
    for (i = 0; i < MAX_NAME_ENTRIES; i++) {
14439
        if (names[i].used) {
14440
            XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
14441
            idx += names[i].totalLen;
14442
        }
14443
    }
14444
14445
    WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14446
14447
    /* used existing buffer passed in, so increment pointer */
14448
    if (local == NULL) {
14449
        *out += totalBytes;
14450
    }
14451
    return totalBytes;
14452
}
14453
#endif /* OPENSSL_ALL || OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
14454
14455
#ifdef WOLFSSL_CERT_GEN
14456
/* Guarded by either
14457
 * A) WOLFSSL_WPAS_SMALL is on or
14458
 * B) (OPENSSL_EXTRA or OPENSSL_EXTRA_X509_SMALL) + WOLFSSL_CERT_GEN +
14459
 *    (WOLFSSL_CERT_REQ or WOLFSSL_CERT_EXT or OPENSSL_EXTRA) has been
14460
 *    defined
14461
 */
14462
#if defined(WOLFSSL_WPAS_SMALL) || \
14463
    (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
14464
    defined(WOLFSSL_CERT_GEN) && \
14465
    (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT) || \
14466
     defined(OPENSSL_EXTRA))
14467
14468
/* Converts the x509 name structure into DER format.
14469
 *
14470
 * out  pointer to either a pre setup buffer or a pointer to null for
14471
 *      creating a dynamic buffer. In the case that a pre-existing buffer is
14472
 *      used out will be incremented the size of the DER buffer on success. If
14473
 *      out is NULL, the function returns the necessary output buffer length.
14474
 *
14475
 * returns the size of the buffer on success, or negative value with failure
14476
 */
14477
int wolfSSL_i2d_X509_NAME(WOLFSSL_X509_NAME* name, unsigned char** out)
14478
{
14479
    int  totalBytes = 0, i, idx;
14480
    byte temp[MAX_SEQ_SZ];
14481
    byte *output, *local = NULL;
14482
    WC_DECLARE_VAR(names, EncodedName, MAX_NAME_ENTRIES, 0);
14483
14484
    if (name == NULL)
14485
        return BAD_FUNC_ARG;
14486
14487
    WC_ALLOC_VAR_EX(names, EncodedName, MAX_NAME_ENTRIES, NULL,
14488
        DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E);
14489
14490
    XMEMSET(names, 0, sizeof(EncodedName) * MAX_NAME_ENTRIES);
14491
14492
    for (i = 0; i < MAX_NAME_ENTRIES; i++) {
14493
        WOLFSSL_X509_NAME_ENTRY* entry;
14494
        int ret;
14495
14496
        entry = wolfSSL_X509_NAME_get_entry(name, i);
14497
        if (entry != NULL && entry->set >= 1) {
14498
            const char* nameStr;
14499
            int type;
14500
            WOLFSSL_ASN1_STRING* data;
14501
14502
            data = wolfSSL_X509_NAME_ENTRY_get_data(entry);
14503
            if (data == NULL) {
14504
                WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14505
                WOLFSSL_MSG("Error getting entry data");
14506
                return WOLFSSL_FATAL_ERROR;
14507
            }
14508
14509
            nameStr = (const char*)wolfSSL_ASN1_STRING_data(data);
14510
            type    = wolfSSL_ASN1_STRING_type(data);
14511
14512
            switch (type) {
14513
                case WOLFSSL_MBSTRING_UTF8:
14514
                    type = CTC_UTF8;
14515
                    break;
14516
                case WOLFSSL_MBSTRING_ASC:
14517
                case WOLFSSL_V_ASN1_PRINTABLESTRING:
14518
                    type = CTC_PRINTABLE;
14519
                    break;
14520
                default:
14521
                    WOLFSSL_MSG(
14522
                        "Unknown encoding type conversion UTF8 by default");
14523
                    type = CTC_UTF8;
14524
            }
14525
            ret = wc_EncodeName(&names[i], nameStr, (char)type,
14526
                (byte)ConvertNIDToWolfSSL(entry->nid));
14527
            if (ret < 0) {
14528
                WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14529
                WOLFSSL_MSG("EncodeName failed");
14530
                return WOLFSSL_FATAL_ERROR;
14531
            }
14532
            totalBytes += ret;
14533
        }
14534
    }
14535
14536
    /* header */
14537
    idx = (int)SetSequence((word32)totalBytes, temp);
14538
    if (totalBytes + idx > ASN_NAME_MAX) {
14539
        WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14540
        WOLFSSL_MSG("Total Bytes is greater than ASN_NAME_MAX");
14541
        return BUFFER_E;
14542
    }
14543
14544
    if (out == NULL) {
14545
        /* If out is NULL, caller just wants length. */
14546
        totalBytes += idx;
14547
        WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14548
        return totalBytes;
14549
    }
14550
14551
    /* check if using buffer passed in */
14552
    if (*out == NULL) {
14553
        *out = local = (unsigned char*)XMALLOC(totalBytes + idx, name->heap,
14554
                DYNAMIC_TYPE_OPENSSL);
14555
        if (*out == NULL) {
14556
            return MEMORY_E;
14557
        }
14558
    }
14559
    output = *out;
14560
14561
    idx = (int)SetSequence((word32)totalBytes, output);
14562
    totalBytes += idx;
14563
    for (i = 0; i < MAX_NAME_ENTRIES; i++) {
14564
        if (names[i].used) {
14565
            XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
14566
            idx += names[i].totalLen;
14567
        }
14568
    }
14569
14570
    WC_FREE_VAR_EX(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14571
14572
    /* used existing buffer passed in, so increment pointer */
14573
    if (local == NULL) {
14574
        *out += totalBytes;
14575
    }
14576
    return totalBytes;
14577
}
14578
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
14579
#endif /* WOLFSSL_CERT_GEN */
14580
14581
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) || \
14582
    defined (WOLFSSL_WPAS_SMALL)
14583
14584
    WOLFSSL_X509_NAME *wolfSSL_d2i_X509_NAME(WOLFSSL_X509_NAME **name,
14585
                                             unsigned char **in, long length)
14586
    {
14587
        WOLFSSL_X509_NAME* tmp = NULL;
14588
        WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
14589
14590
        WOLFSSL_ENTER("wolfSSL_d2i_X509_NAME");
14591
14592
        if (!in || !*in || length <= 0) {
14593
            WOLFSSL_MSG("Bad argument");
14594
            return NULL;
14595
        }
14596
14597
        WC_ALLOC_VAR_EX(cert, DecodedCert, 1, NULL, DYNAMIC_TYPE_DCERT,
14598
            return NULL);
14599
14600
        /* Set the X509_NAME buffer as the input data for cert.
14601
         * in is NOT a full certificate. Just the name. */
14602
        InitDecodedCert(cert, *in, (word32)length, NULL);
14603
14604
        /* Parse the X509 subject name */
14605
        if (GetName(cert, ASN_SUBJECT, (int)length) != 0) {
14606
            WOLFSSL_MSG("WOLFSSL_X509_NAME parse error");
14607
            goto cleanup;
14608
        }
14609
14610
        if (!(tmp = wolfSSL_X509_NAME_new_ex(cert->heap))) {
14611
            WOLFSSL_MSG("wolfSSL_X509_NAME_new_ex error");
14612
            goto cleanup;
14613
        }
14614
14615
        if (wolfSSL_X509_NAME_copy((WOLFSSL_X509_NAME*)cert->subjectName,
14616
                    tmp) != WOLFSSL_SUCCESS) {
14617
            wolfSSL_X509_NAME_free(tmp);
14618
            tmp = NULL;
14619
            goto cleanup;
14620
        }
14621
    #if !defined(WOLFSSL_NO_CA_NAMES) && defined(OPENSSL_EXTRA)
14622
        /* Keep the encoding to send in a list of CA names. */
14623
        if (SetX509NameRawFromDer(tmp, *in, (word32)length) != 0) {
14624
            wolfSSL_X509_NAME_free(tmp);
14625
            tmp = NULL;
14626
            goto cleanup;
14627
        }
14628
    #endif
14629
14630
        if (name)
14631
            *name = tmp;
14632
cleanup:
14633
        FreeDecodedCert(cert);
14634
        WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
14635
        return tmp;
14636
    }
14637
#endif /* OPENSSL_EXTRA || OPENSSL_ALL || WOLFSSL_WPAS_SMALL */
14638
14639
14640
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
14641
14642
    /* Compares the two X509 names. If the size of x is larger then y then a
14643
     * positive value is returned if x is smaller a negative value is returned.
14644
     * In the case that the sizes are equal a the value of strcmp between the
14645
     * two names is returned.
14646
     *
14647
     * x First name for comparison
14648
     * y Second name to compare with x
14649
     */
14650
    int wolfSSL_X509_NAME_cmp(const WOLFSSL_X509_NAME* x,
14651
            const WOLFSSL_X509_NAME* y)
14652
    {
14653
        const char* _x;
14654
        const char* _y;
14655
        WOLFSSL_ENTER("wolfSSL_X509_NAME_cmp");
14656
14657
        if (x == NULL || y == NULL) {
14658
            WOLFSSL_MSG("Bad argument passed in");
14659
            return -2;
14660
        }
14661
14662
        if (x == y) {
14663
            return 0; /* match */
14664
        }
14665
14666
        if (x->sz != y->sz) {
14667
            return x->sz - y->sz;
14668
        }
14669
14670
        /*
14671
         * If the name member is not set or is immediately null terminated then
14672
         * compare the staticName member
14673
         */
14674
        _x = (x->name && *x->name) ? x->name : x->staticName;
14675
        _y = (y->name && *y->name) ? y->name : y->staticName;
14676
14677
        return XSTRNCASECMP(_x, _y, x->sz); /* y sz is the same */
14678
    }
14679
14680
#ifndef NO_BIO
14681
14682
static WOLFSSL_X509 *loadX509orX509REQFromPemBio(WOLFSSL_BIO *bp,
14683
        WOLFSSL_X509 **x, wc_pem_password_cb *cb, void *u, int type)
14684
{
14685
    WOLFSSL_X509* x509 = NULL;
14686
#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
14687
    unsigned char* pem = NULL;
14688
    int pemSz;
14689
    long  i = 0, l, footerSz;
14690
    const char* footer = NULL;
14691
    int streaming = 0;  /* Flag to indicate if source is streaming (FIFO) */
14692
    const char* altFooter = NULL;
14693
    long altFooterSz = 0;
14694
14695
    WOLFSSL_ENTER("loadX509orX509REQFromPemBio");
14696
14697
    if (bp == NULL || (type != CERT_TYPE && type != CERTREQ_TYPE &&
14698
                       type != TRUSTED_CERT_TYPE)) {
14699
        WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_X509", BAD_FUNC_ARG);
14700
        return NULL;
14701
    }
14702
14703
    if ((l = wolfSSL_BIO_get_len(bp)) <= 0) {
14704
        /* No certificate size available - could be FIFO or other streaming
14705
         * source. Use MAX_X509_SIZE as initial buffer, will resize if needed. */
14706
        l = MAX_X509_SIZE;
14707
        streaming = 1;
14708
    }
14709
14710
    pemSz = (int)l;
14711
    pem   = (unsigned char*)XMALLOC(pemSz, 0, DYNAMIC_TYPE_PEM);
14712
    if (pem == NULL)
14713
        return NULL;
14714
    XMEMSET(pem, 0, pemSz);
14715
14716
    i = 0;
14717
    if (wc_PemGetHeaderFooter(type, NULL, &footer) != 0) {
14718
        XFREE(pem, 0, DYNAMIC_TYPE_PEM);
14719
        return NULL;
14720
    }
14721
    footerSz = (long)XSTRLEN(footer);
14722
14723
    /* For TRUSTED_CERT_TYPE, also prepare to check for regular CERT footer
14724
     * as the file might contain regular certificates instead of TRUSTED
14725
     * format */
14726
    if (type == TRUSTED_CERT_TYPE) {
14727
        wc_PemGetHeaderFooter(CERT_TYPE, NULL, &altFooter);
14728
        if (altFooter != NULL) {
14729
            altFooterSz = (long)XSTRLEN(altFooter);
14730
        }
14731
    }
14732
14733
    /* TODO: Inefficient
14734
     * reading in one byte at a time until see the footer
14735
     */
14736
    while ((l = wolfSSL_BIO_read(bp, (char *)&pem[i], 1)) == 1) {
14737
        int foundFooter = 0;
14738
        i++;
14739
        /* Check if buffer is full and we're reading from streaming source */
14740
        if (i >= pemSz && streaming) {
14741
            /* Double the buffer size for streaming sources */
14742
            int newSz = pemSz * 2;
14743
            unsigned char* newPem;
14744
14745
            /* Sanity check: don't grow beyond reasonable limit */
14746
            if (newSz > MAX_BIO_READ_BUFFER) {
14747
                WOLFSSL_MSG("PEM data too large for streaming source");
14748
                XFREE(pem, 0, DYNAMIC_TYPE_PEM);
14749
                return NULL;
14750
            }
14751
14752
            newPem = (unsigned char*)XREALLOC(pem, newSz, 0, DYNAMIC_TYPE_PEM);
14753
            if (newPem == NULL) {
14754
                WOLFSSL_MSG("Failed to resize PEM buffer");
14755
                XFREE(pem, 0, DYNAMIC_TYPE_PEM);
14756
                return NULL;
14757
            }
14758
14759
            pem = newPem;
14760
            pemSz = newSz;
14761
        }
14762
        else if (i >= pemSz) {
14763
            /* Buffer full for non-streaming source - this shouldn't happen */
14764
            break;
14765
        }
14766
14767
        /* Check for the expected footer OR alternate footer (for
14768
         * TRUSTED_CERT_TYPE) */
14769
        if (i > footerSz &&
14770
            XMEMCMP((char *)&pem[i-footerSz], footer, footerSz) == 0) {
14771
            foundFooter = 1;
14772
        }
14773
        else if (i > altFooterSz && altFooter != NULL &&
14774
            XMEMCMP((char *)&pem[i-altFooterSz], altFooter, altFooterSz) == 0) {
14775
            foundFooter = 1;
14776
        }
14777
14778
        if (foundFooter) {
14779
            if (i < pemSz && wolfSSL_BIO_read(bp, (char *)&pem[i], 1) == 1) {
14780
                /* attempt to read newline following footer */
14781
                i++;
14782
                if (i < pemSz && pem[i-1] == '\r') {
14783
                    /* found \r , Windows line ending is \r\n so try to read one
14784
                     * more byte for \n, ignoring return value */
14785
                    (void)wolfSSL_BIO_read(bp, (char *)&pem[i++], 1);
14786
                }
14787
            }
14788
            break;
14789
        }
14790
    }
14791
    if (l == 0 && i == 0) {
14792
        WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
14793
    }
14794
    if (i > pemSz) {
14795
        WOLFSSL_MSG("Error parsing PEM");
14796
    }
14797
    else {
14798
        pemSz = (int)i;
14799
    #ifdef WOLFSSL_CERT_REQ
14800
        if (type == CERTREQ_TYPE)
14801
            x509 = loadX509orX509REQFromBuffer(pem, pemSz, WOLFSSL_FILETYPE_PEM,
14802
                CERTREQ_TYPE, cb, u);
14803
        else
14804
    #endif
14805
        /* Use TRUSTED_CERT_TYPE if input was TRUSTED CERTIFICATE format,
14806
         * otherwise use CERT_TYPE for regular certificates */
14807
        if (type == TRUSTED_CERT_TYPE)
14808
            x509 = loadX509orX509REQFromBuffer(pem, pemSz, WOLFSSL_FILETYPE_PEM,
14809
                TRUSTED_CERT_TYPE, cb, u);
14810
        else
14811
            x509 = loadX509orX509REQFromBuffer(pem, pemSz, WOLFSSL_FILETYPE_PEM,
14812
                CERT_TYPE, cb, u);
14813
    }
14814
14815
    if (x != NULL) {
14816
        *x = x509;
14817
    }
14818
14819
    XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
14820
14821
#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
14822
    (void)bp;
14823
    (void)x;
14824
    (void)cb;
14825
    (void)u;
14826
14827
    return x509;
14828
}
14829
14830
14831
WC_MAYBE_UNUSED
14832
static unsigned char* ReadPemFromBioToBuffer(WOLFSSL_BIO *bp, int *pemSz)
14833
{
14834
    unsigned char* pem = NULL;
14835
14836
    WOLFSSL_ENTER("ReadPemFromBioToBuffer");
14837
14838
    if (bp == NULL || pemSz == NULL) {
14839
        WOLFSSL_LEAVE("ReadPemFromBioToBuffer", BAD_FUNC_ARG);
14840
        return NULL;
14841
    }
14842
14843
    if ((*pemSz = wolfSSL_BIO_get_len(bp)) <= 0) {
14844
        /* No certificate size available - could be FIFO or other streaming
14845
         * source. Use MAX_X509_SIZE as initial buffer, read in loop. */
14846
        int totalRead = 0;
14847
        int readSz;
14848
14849
        *pemSz = MAX_X509_SIZE;
14850
        pem = (unsigned char*)XMALLOC(*pemSz, 0, DYNAMIC_TYPE_PEM);
14851
        if (pem == NULL) {
14852
            return NULL;
14853
        }
14854
14855
        /* Read from streaming source until EOF or buffer full */
14856
        while ((readSz = wolfSSL_BIO_read(bp, pem + totalRead,
14857
                                          *pemSz - totalRead)) > 0) {
14858
            totalRead += readSz;
14859
14860
            /* If buffer is full, try to grow it */
14861
            if (totalRead >= *pemSz) {
14862
                int newSz = *pemSz * 2;
14863
                unsigned char* newPem;
14864
14865
                /* Sanity check */
14866
                if (newSz > MAX_BIO_READ_BUFFER) {
14867
                    WOLFSSL_MSG("PEM data too large for streaming source");
14868
                    XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
14869
                    return NULL;
14870
                }
14871
14872
                newPem = (unsigned char*)XREALLOC(pem, newSz, 0,
14873
                        DYNAMIC_TYPE_PEM);
14874
                if (newPem == NULL) {
14875
                    XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
14876
                    return NULL;
14877
                }
14878
                pem = newPem;
14879
                *pemSz = newSz;
14880
            }
14881
        }
14882
14883
        *pemSz = totalRead;
14884
        if (*pemSz <= 0) {
14885
            XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
14886
            return NULL;
14887
        }
14888
    }
14889
    else {
14890
        /* Known size - allocate and read */
14891
        pem = (unsigned char*)XMALLOC(*pemSz, 0, DYNAMIC_TYPE_PEM);
14892
        if (pem == NULL) {
14893
            return NULL;
14894
        }
14895
14896
        XMEMSET(pem, 0, *pemSz);
14897
14898
        *pemSz = wolfSSL_BIO_read(bp, pem, *pemSz);
14899
        if (*pemSz <= 0) {
14900
            XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
14901
            return NULL;
14902
        }
14903
    }
14904
14905
    WOLFSSL_LEAVE("ReadPemFromBioToBuffer", 0);
14906
    return pem;
14907
}
14908
14909
14910
14911
#if defined(WOLFSSL_ACERT)
14912
    WOLFSSL_X509_ACERT *wolfSSL_PEM_read_bio_X509_ACERT(WOLFSSL_BIO *bp,
14913
                                                        WOLFSSL_X509_ACERT **x,
14914
                                                        wc_pem_password_cb *cb,
14915
                                                        void *u)
14916
    {
14917
        WOLFSSL_X509_ACERT* x509 = NULL;
14918
#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
14919
        unsigned char * pem = NULL;
14920
        int             pemSz;
14921
14922
        WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509_ACERT");
14923
14924
        if (bp == NULL) {
14925
            return NULL;
14926
        }
14927
14928
        pem = ReadPemFromBioToBuffer(bp, &pemSz);
14929
        if (pem == NULL) {
14930
            return NULL;
14931
        }
14932
14933
        x509 = wolfSSL_X509_ACERT_load_certificate_buffer(pem, pemSz,
14934
                                                          WOLFSSL_FILETYPE_PEM);
14935
14936
        if (x != NULL) {
14937
            *x = x509;
14938
        }
14939
14940
        XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
14941
14942
#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
14943
        (void)bp;
14944
        (void)x;
14945
        (void)cb;
14946
        (void)u;
14947
14948
        return x509;
14949
14950
    }
14951
#endif /* WOLFSSL_ACERT */
14952
14953
    WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x,
14954
                                            wc_pem_password_cb *cb, void *u)
14955
    {
14956
        return loadX509orX509REQFromPemBio(bp, x, cb, u, CERT_TYPE);
14957
    }
14958
14959
    /*
14960
     * bp : bio to read X509 from
14961
     * x  : x509 to write to
14962
     * cb : password call back for reading PEM
14963
     * u  : password
14964
     * _AUX is for working with a trusted X509 certificate
14965
     */
14966
    WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_AUX(WOLFSSL_BIO *bp,
14967
                               WOLFSSL_X509 **x, wc_pem_password_cb *cb,
14968
                               void *u)
14969
    {
14970
        WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509_AUX");
14971
14972
        /* AUX info is; trusted/rejected uses, friendly name, private key id,
14973
         * and potentially a stack of "other" info. wolfSSL does not store
14974
         * friendly name or private key id yet in WOLFSSL_X509 for human
14975
         * readability and does not support extra trusted/rejected uses for
14976
         * root CA. Use TRUSTED_CERT_TYPE to properly parse TRUSTED CERTIFICATE
14977
         * format and strip auxiliary data. */
14978
        return loadX509orX509REQFromPemBio(bp, x, cb, u, TRUSTED_CERT_TYPE);
14979
    }
14980
14981
#ifdef WOLFSSL_CERT_REQ
14982
WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_REQ(WOLFSSL_BIO *bp, WOLFSSL_X509 **x,
14983
                                                wc_pem_password_cb *cb, void *u)
14984
{
14985
    return loadX509orX509REQFromPemBio(bp, x, cb, u, CERTREQ_TYPE);
14986
}
14987
14988
#ifndef NO_FILESYSTEM
14989
    WOLFSSL_X509* wolfSSL_PEM_read_X509_REQ(XFILE fp, WOLFSSL_X509** x,
14990
                                            wc_pem_password_cb* cb, void* u)
14991
    {
14992
        int err = 0;
14993
        WOLFSSL_X509* ret = NULL;
14994
        WOLFSSL_BIO* bio = NULL;
14995
14996
        WOLFSSL_ENTER("wolfSSL_PEM_read_X509_REQ");
14997
14998
        if (fp == XBADFILE) {
14999
            WOLFSSL_MSG("Invalid file.");
15000
            err = 1;
15001
        }
15002
15003
        if (err == 0) {
15004
            bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
15005
            if (bio == NULL) {
15006
                WOLFSSL_MSG("Failed to create new BIO with input file.");
15007
                err = 1;
15008
            }
15009
        }
15010
        if (err == 0 && wolfSSL_BIO_set_fp(bio, fp, WOLFSSL_BIO_CLOSE)
15011
                != WOLFSSL_SUCCESS) {
15012
            WOLFSSL_MSG("Failed to set BIO file pointer.");
15013
            err = 1;
15014
        }
15015
        if (err == 0) {
15016
            ret = wolfSSL_PEM_read_bio_X509_REQ(bio, x, cb, u);
15017
        }
15018
15019
        wolfSSL_BIO_free(bio);
15020
15021
        return ret;
15022
    }
15023
#endif /* !NO_FILESYSTEM */
15024
#endif /* WOLFSSL_CERT_REQ */
15025
15026
    WOLFSSL_X509_CRL *wolfSSL_PEM_read_bio_X509_CRL(WOLFSSL_BIO *bp,
15027
            WOLFSSL_X509_CRL **x, wc_pem_password_cb *cb, void *u)
15028
    {
15029
#if defined(WOLFSSL_PEM_TO_DER) && defined(HAVE_CRL)
15030
        WOLFSSL_X509_CRL* crl = NULL;
15031
15032
        WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509_CRL");
15033
15034
        /* OpenSSL's PEM_read_bio_X509_CRL skips intervening cert/key blocks
15035
         * and returns the next CRL in the stream (NULL only at EOF). Mirror
15036
         * that by looping over the per-block reader until we get a CRL or
15037
         * the BIO has nothing left to parse. */
15038
        for (;;) {
15039
            WOLFSSL_X509*      x509   = NULL;
15040
            WOLFSSL_X509_PKEY* x_pkey = NULL;
15041
            if (wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio(bp, cb,
15042
                        &x509, &crl, &x_pkey) != WOLFSSL_SUCCESS) {
15043
                break;
15044
            }
15045
            if (crl != NULL) {
15046
                break;
15047
            }
15048
            wolfSSL_X509_free(x509);
15049
            wolfSSL_X509_PKEY_free(x_pkey);
15050
        }
15051
15052
        if (x != NULL) {
15053
            if (*x != NULL && *x != crl) {
15054
                wolfSSL_X509_CRL_free(*x);
15055
            }
15056
            *x = crl;
15057
        }
15058
15059
        (void)u;
15060
15061
        return crl;
15062
#else
15063
        (void)bp;
15064
        (void)x;
15065
        (void)cb;
15066
        (void)u;
15067
15068
        return NULL;
15069
#endif
15070
    }
15071
15072
#endif /* !NO_BIO */
15073
15074
#if !defined(NO_FILESYSTEM)
15075
static void* wolfSSL_PEM_read_X509_ex(XFILE fp, void **x,
15076
    wc_pem_password_cb *cb, void *u, int type)
15077
{
15078
    unsigned char* pem = NULL;
15079
    int pemSz;
15080
    long i = 0, l;
15081
    void *newx509;
15082
    int derSz;
15083
    DerBuffer* der = NULL;
15084
15085
    WOLFSSL_ENTER("wolfSSL_PEM_read_X509");
15086
15087
    if (fp == XBADFILE) {
15088
        WOLFSSL_LEAVE("wolfSSL_PEM_read_X509", BAD_FUNC_ARG);
15089
        return NULL;
15090
    }
15091
    /* Read cert from file */
15092
    i = XFTELL(fp);
15093
    if (i < 0) {
15094
        WOLFSSL_LEAVE("wolfSSL_PEM_read_X509", BAD_FUNC_ARG);
15095
        return NULL;
15096
    }
15097
15098
    if (XFSEEK(fp, 0, XSEEK_END) != 0)
15099
        return NULL;
15100
    l = XFTELL(fp);
15101
    if (l < 0)
15102
        return NULL;
15103
    if (XFSEEK(fp, i, SEEK_SET) != 0)
15104
        return NULL;
15105
    pemSz = (int)(l - i);
15106
15107
    /* check calculated length */
15108
    if (pemSz > MAX_WOLFSSL_FILE_SIZE || pemSz <= 0) {
15109
        WOLFSSL_MSG("PEM_read_X509_ex file size error");
15110
        return NULL;
15111
    }
15112
15113
    /* allocate pem buffer */
15114
    pem = (unsigned char*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_PEM);
15115
    if (pem == NULL)
15116
        return NULL;
15117
15118
    if ((int)XFREAD((char *)pem, 1, (size_t)pemSz, fp) != pemSz)
15119
        goto err_exit;
15120
15121
    switch (type) {
15122
        case CERT_TYPE:
15123
            newx509 = (void *)wolfSSL_X509_load_certificate_buffer(pem,
15124
                pemSz, WOLFSSL_FILETYPE_PEM);
15125
            break;
15126
15127
    #ifdef HAVE_CRL
15128
        case CRL_TYPE:
15129
            if ((PemToDer(pem, pemSz, CRL_TYPE, &der, NULL, NULL, NULL)) < 0)
15130
                goto err_exit;
15131
            derSz = (int)der->length;
15132
            newx509 = (void*)wolfSSL_d2i_X509_CRL((WOLFSSL_X509_CRL **)x,
15133
                (const unsigned char *)der->buffer, derSz);
15134
            if (newx509 == NULL)
15135
                goto err_exit;
15136
            FreeDer(&der);
15137
            break;
15138
    #endif
15139
15140
        default:
15141
            goto err_exit;
15142
    }
15143
    if (x != NULL) {
15144
        *x = newx509;
15145
    }
15146
    XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
15147
    return newx509;
15148
15149
err_exit:
15150
    XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
15151
    if (der != NULL)
15152
        FreeDer(&der);
15153
15154
    /* unused */
15155
    (void)cb;
15156
    (void)u;
15157
    (void)derSz;
15158
15159
    return NULL;
15160
}
15161
15162
WOLFSSL_X509* wolfSSL_PEM_read_X509(XFILE fp, WOLFSSL_X509 **x,
15163
                                                wc_pem_password_cb *cb, void *u)
15164
{
15165
    return (WOLFSSL_X509* )wolfSSL_PEM_read_X509_ex(fp, (void **)x, cb, u,
15166
         CERT_TYPE);
15167
}
15168
15169
#if defined(HAVE_CRL)
15170
WOLFSSL_X509_CRL* wolfSSL_PEM_read_X509_CRL(XFILE fp,
15171
                        WOLFSSL_X509_CRL **crl, wc_pem_password_cb *cb, void *u)
15172
{
15173
    return (WOLFSSL_X509_CRL* )wolfSSL_PEM_read_X509_ex(fp, (void **)crl, cb, u,
15174
         CRL_TYPE);
15175
}
15176
15177
/* Store CRL to file in DER or PEM format.
15178
 * Returns WOLFSSL_SUCCESS on success, negative on failure.
15179
 */
15180
int wolfSSL_write_X509_CRL(WOLFSSL_X509_CRL* crl, const char* path, int type)
15181
{
15182
    int ret;
15183
    WOLFSSL_ENTER("wolfSSL_write_X509_CRL");
15184
    ret = StoreCRL(crl, path, type);
15185
    WOLFSSL_LEAVE("wolfSSL_write_X509_CRL", ret);
15186
    return ret;
15187
}
15188
#endif
15189
15190
#ifdef WOLFSSL_CERT_GEN
15191
#ifndef NO_BIO
15192
    int wolfSSL_PEM_write_X509(XFILE fp, WOLFSSL_X509* x)
15193
    {
15194
        int ret;
15195
        WOLFSSL_BIO* bio;
15196
15197
        if (x == NULL || fp == XBADFILE)
15198
            return 0;
15199
15200
        bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
15201
        if (bio == NULL)
15202
            return 0;
15203
15204
        if (wolfSSL_BIO_set_fp(bio, fp, WOLFSSL_BIO_NOCLOSE) != WOLFSSL_SUCCESS) {
15205
            wolfSSL_BIO_free(bio);
15206
            bio = NULL;
15207
        }
15208
15209
        ret = wolfSSL_PEM_write_bio_X509(bio, x);
15210
15211
        if (bio != NULL)
15212
            wolfSSL_BIO_free(bio);
15213
15214
        return ret;
15215
    }
15216
#endif /* !NO_BIO */
15217
#endif /* WOLFSSL_CERT_GEN */
15218
#endif /* !NO_FILESYSTEM */
15219
15220
#endif /* OPENSSL_EXTRA || OPENSSL_ALL */
15221
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
15222
15223
#ifndef NO_BIO
15224
    /* create and return a new WOLFSSL_X509_PKEY structure or NULL on failure */
15225
    static WOLFSSL_X509_PKEY* wolfSSL_X509_PKEY_new(void* heap)
15226
    {
15227
        WOLFSSL_X509_PKEY* ret;
15228
15229
        ret = (WOLFSSL_X509_PKEY*)XMALLOC(sizeof(WOLFSSL_X509_PKEY), heap,
15230
            DYNAMIC_TYPE_KEY);
15231
        if (ret != NULL) {
15232
            XMEMSET(ret, 0, sizeof(WOLFSSL_X509_PKEY));
15233
            ret->heap = heap;
15234
        }
15235
        return ret;
15236
    }
15237
#endif /* !NO_BIO */
15238
15239
15240
    /* free up all memory used by "xPkey" passed in */
15241
    void wolfSSL_X509_PKEY_free(WOLFSSL_X509_PKEY* xPkey)
15242
    {
15243
        if (xPkey != NULL) {
15244
            wolfSSL_EVP_PKEY_free(xPkey->dec_pkey);
15245
            XFREE(xPkey, xPkey->heap, DYNAMIC_TYPE_KEY);
15246
        }
15247
    }
15248
15249
15250
#ifndef NO_BIO
15251
15252
#define PEM_COMPARE_HEADER(start, end, header) \
15253
        ((end) - (start) == XSTR_SIZEOF(header) && XMEMCMP(start, header, \
15254
                XSTR_SIZEOF(header)) == 0)
15255
15256
    /**
15257
     * This read one structure from bio and returns the read structure
15258
     * in the appropriate output parameter (x509, crl, x_pkey). The
15259
     * output parameters must be set to NULL.
15260
     * @param bio    Input for reading structures
15261
     * @param cb     Password callback
15262
     * @param x509   Output
15263
     * @param crl    Output
15264
     * @param x_pkey Output
15265
     * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE otherwise
15266
     */
15267
    int wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio(
15268
            WOLFSSL_BIO* bio, wc_pem_password_cb* cb, WOLFSSL_X509** x509,
15269
            WOLFSSL_X509_CRL** crl, WOLFSSL_X509_PKEY** x_pkey)
15270
    {
15271
15272
#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
15273
        char* pem = NULL;
15274
        long  i = pem_struct_min_sz, l;
15275
        const char* header = NULL;
15276
        const char* headerEnd = NULL;
15277
        const char* footer = NULL;
15278
        const char* footerEnd = NULL;
15279
        long searchPos = 0;
15280
    #ifdef HAVE_CRL
15281
        DerBuffer* der = NULL;
15282
    #endif
15283
        WOLFSSL_BIO* pemBio = NULL;
15284
15285
        if (!bio || !x509 || *x509 || !crl || *crl || !x_pkey || *x_pkey) {
15286
            WOLFSSL_MSG("Bad input parameter or output parameters "
15287
                        "not set to a NULL value.");
15288
            return WOLFSSL_FAILURE;
15289
        }
15290
15291
        l = wolfSSL_BIO_get_len(bio);
15292
15293
        if (l < 0) {
15294
            WOLFSSL_ERROR(BAD_FUNC_ARG);
15295
            return WOLFSSL_FAILURE;
15296
        }
15297
15298
        if (l == 0) {
15299
            /* Streaming BIO (pipe/FIFO/socket): size unknown, use the cap. */
15300
            l = MAX_BIO_READ_BUFFER;
15301
        }
15302
        else if (l <= pem_struct_min_sz) {
15303
            /* No certificate in buffer */
15304
            WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
15305
            return WOLFSSL_FAILURE;
15306
        }
15307
15308
        pem = (char*)XMALLOC(l, 0, DYNAMIC_TYPE_PEM);
15309
        if (pem == NULL)
15310
            return WOLFSSL_FAILURE;
15311
15312
        if (wolfSSL_BIO_read(bio, &pem[0], pem_struct_min_sz) !=
15313
                pem_struct_min_sz) {
15314
            WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
15315
            goto err;
15316
        }
15317
15318
        /* Read the header and footer */
15319
        while (i < l && wolfSSL_BIO_read(bio, &pem[i], 1) == 1) {
15320
            i++;
15321
            if (!header) {
15322
                header = XSTRNSTR(pem + searchPos, "-----BEGIN ",
15323
                        (size_t)(i - searchPos));
15324
                if (header == NULL) {
15325
                    searchPos = i > (long)(XSTR_SIZEOF("-----BEGIN ") - 1)
15326
                        ? i - (XSTR_SIZEOF("-----BEGIN ") - 1) : 0;
15327
                }
15328
            }
15329
            else if (!headerEnd) {
15330
                headerEnd = XSTRNSTR(header + XSTR_SIZEOF("-----BEGIN "),
15331
                        "-----",
15332
                        i - (header + XSTR_SIZEOF("-----BEGIN ") - pem));
15333
                if (headerEnd) {
15334
                    headerEnd += XSTR_SIZEOF("-----");
15335
                    if (i >= l ||
15336
                            wolfSSL_BIO_read(bio, &pem[i], 1) != 1) {
15337
                        WOLFSSL_MSG("wolfSSL_BIO_read error");
15338
                        goto err;
15339
                    }
15340
                    i++;
15341
                    if (*headerEnd != '\n' && *headerEnd != '\r') {
15342
                        WOLFSSL_MSG("Missing newline after header");
15343
                        goto err;
15344
                    }
15345
                    searchPos = (long)(headerEnd - pem);
15346
                }
15347
            }
15348
            else if (!footer) {
15349
                footer = XSTRNSTR(pem + searchPos, "-----END ",
15350
                        (size_t)(i - searchPos));
15351
                if (footer == NULL) {
15352
                    if (i > (long)(XSTR_SIZEOF("-----END ") - 1))
15353
                        searchPos = i - (XSTR_SIZEOF("-----END ") - 1);
15354
                }
15355
            }
15356
            else if (!footerEnd) {
15357
                footerEnd = XSTRNSTR(footer + XSTR_SIZEOF("-----"),
15358
                        "-----",
15359
                        i - (footer + XSTR_SIZEOF("-----") - pem));
15360
                if (footerEnd) {
15361
                    footerEnd += XSTR_SIZEOF("-----");
15362
                    /* Now check that footer matches header */
15363
                    if ((headerEnd - (header + XSTR_SIZEOF("-----BEGIN "))) ==
15364
                        (footerEnd - (footer + XSTR_SIZEOF("-----END "))) &&
15365
                        XMEMCMP(header + XSTR_SIZEOF("-----BEGIN "),
15366
                                footer + XSTR_SIZEOF("-----END "),
15367
                        headerEnd - (header + XSTR_SIZEOF("-----BEGIN ")))
15368
                            != 0) {
15369
                        WOLFSSL_MSG("Header and footer don't match");
15370
                        goto err;
15371
                    }
15372
                    /* header and footer match */
15373
                    break;
15374
                }
15375
            }
15376
        }
15377
        if (!footerEnd) {
15378
            /* Only check footerEnd since it is set last */
15379
            WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
15380
            goto err;
15381
        }
15382
        else {
15383
            if (PEM_COMPARE_HEADER(header, headerEnd,
15384
                    "-----BEGIN CERTIFICATE-----")) {
15385
                /* We have a certificate */
15386
                WOLFSSL_MSG("Parsing x509 cert");
15387
                *x509 = wolfSSL_X509_load_certificate_buffer(
15388
                        (const unsigned char*) header,
15389
                        (int)(footerEnd - header), WOLFSSL_FILETYPE_PEM);
15390
                if (!*x509) {
15391
                    WOLFSSL_MSG("wolfSSL_X509_load_certificate_buffer error");
15392
                    goto err;
15393
                }
15394
            }
15395
    #ifdef HAVE_CRL
15396
            else if (PEM_COMPARE_HEADER(header, headerEnd,
15397
                        "-----BEGIN X509 CRL-----")) {
15398
                /* We have a crl */
15399
                WOLFSSL_MSG("Parsing crl");
15400
                if ((PemToDer((const unsigned char*) header,
15401
                        (long)(footerEnd - header), CRL_TYPE, &der, NULL, NULL,
15402
                        NULL)) < 0) {
15403
                    WOLFSSL_MSG("PemToDer error");
15404
                    goto err;
15405
                }
15406
                *crl = wolfSSL_d2i_X509_CRL(NULL, der->buffer, der->length);
15407
                if (!*crl) {
15408
                    WOLFSSL_MSG("wolfSSL_d2i_X509_CRL error");
15409
                    goto err;
15410
                }
15411
            }
15412
    #endif
15413
            else {
15414
                WOLFSSL_MSG("Parsing x509 key");
15415
15416
                if (!(*x_pkey = wolfSSL_X509_PKEY_new(NULL))) {
15417
                    WOLFSSL_MSG("wolfSSL_X509_PKEY_new error");
15418
                    goto err;
15419
                }
15420
15421
                if (!(pemBio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()))) {
15422
                    WOLFSSL_MSG("wolfSSL_BIO_new error");
15423
                    goto err;
15424
                }
15425
15426
                if (wolfSSL_BIO_write(pemBio, header,
15427
                        (int)(footerEnd - header)) != footerEnd - header) {
15428
                    WOLFSSL_MSG("wolfSSL_BIO_new error");
15429
                    goto err;
15430
                }
15431
15432
                if (wolfSSL_PEM_read_bio_PrivateKey(pemBio,
15433
                        &(*x_pkey)->dec_pkey, cb, NULL) == NULL) {
15434
                    WOLFSSL_MSG("wolfSSL_PEM_read_bio_PrivateKey error");
15435
                    goto err;
15436
                }
15437
15438
                wolfSSL_BIO_free(pemBio);
15439
            }
15440
        }
15441
15442
        XFREE(pem, 0, DYNAMIC_TYPE_PEM);
15443
    #ifdef HAVE_CRL
15444
        if (der)
15445
            FreeDer(&der);
15446
    #endif
15447
        return WOLFSSL_SUCCESS;
15448
err:
15449
        XFREE(pem, 0, DYNAMIC_TYPE_PEM);
15450
    #ifdef HAVE_CRL
15451
        if (der)
15452
            FreeDer(&der);
15453
    #endif
15454
        if (*x_pkey) {
15455
            wolfSSL_X509_PKEY_free(*x_pkey);
15456
            *x_pkey = NULL;
15457
        }
15458
        if (pemBio)
15459
            wolfSSL_BIO_free(pemBio);
15460
        return WOLFSSL_FAILURE;
15461
#else /* ! (WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM) */
15462
        return WOLFSSL_FAILURE;
15463
#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
15464
    }
15465
15466
#endif /* OPENSSL_EXTRA || OPENSSL_ALL */
15467
#ifdef OPENSSL_ALL
15468
15469
#ifndef NO_FILESYSTEM
15470
    WOLF_STACK_OF(WOLFSSL_X509_INFO)* wolfSSL_PEM_X509_INFO_read(
15471
            XFILE fp, WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
15472
            pem_password_cb* cb, void* u)
15473
    {
15474
        WOLFSSL_BIO* fileBio = wolfSSL_BIO_new_fp(fp, WOLFSSL_BIO_NOCLOSE);
15475
        WOLF_STACK_OF(WOLFSSL_X509_INFO)* ret = NULL;
15476
15477
        WOLFSSL_ENTER("wolfSSL_PEM_X509_INFO_read");
15478
        if (fileBio != NULL) {
15479
            ret = wolfSSL_PEM_X509_INFO_read_bio(fileBio, sk, cb, u);
15480
            wolfSSL_BIO_free(fileBio);
15481
        }
15482
        return ret;
15483
    }
15484
#endif /* !NO_FILESYSTEM */
15485
15486
    /*
15487
     * bio WOLFSSL_BIO to read certificates from
15488
     * sk  possible stack to push more X509_INFO structs to. Can be NULL
15489
     * cb  callback password for encrypted PEM certificates
15490
     * u   user input such as password
15491
     *
15492
     * returns stack on success and NULL or default stack passed in on fail
15493
     */
15494
    WOLF_STACK_OF(WOLFSSL_X509_INFO)* wolfSSL_PEM_X509_INFO_read_bio(
15495
        WOLFSSL_BIO* bio, WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
15496
        wc_pem_password_cb* cb, void* u)
15497
    {
15498
        WOLF_STACK_OF(WOLFSSL_X509_INFO)* localSk = NULL;
15499
        int ret = WOLFSSL_SUCCESS;
15500
        WOLFSSL_X509_INFO* current = NULL;
15501
        WOLFSSL_X509*      x509 = NULL;
15502
        WOLFSSL_X509_CRL*  crl  = NULL;
15503
        WOLFSSL_X509_PKEY* x_pkey = NULL;
15504
15505
        (void)u;
15506
15507
        WOLFSSL_ENTER("wolfSSL_PEM_X509_INFO_read_bio");
15508
15509
        /* attempt to use passed in stack or create a new one */
15510
        if (sk != NULL) {
15511
            localSk = sk;
15512
        }
15513
        else {
15514
            localSk = wolfSSL_sk_X509_INFO_new_null();
15515
        }
15516
        if (localSk == NULL) {
15517
            WOLFSSL_LEAVE("wolfSSL_PEM_X509_INFO_read_bio",
15518
                    MEMORY_E);
15519
            return NULL;
15520
        }
15521
15522
        /* parse through BIO and push new info's found onto stack */
15523
        while (1) {
15524
            x509 = NULL;
15525
            crl  = NULL;
15526
            x_pkey = NULL;
15527
15528
            if (wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio(bio, cb,
15529
                    &x509, &crl, &x_pkey) == WOLFSSL_SUCCESS) {
15530
                if (current == NULL ||
15531
                        (x509 && current->x509) ||
15532
                        (crl && current->crl) ||
15533
                        (x_pkey && current->x_pkey)) {
15534
                    /* Need to create new current since existing one already
15535
                     * has the member filled or this is the first successful
15536
                     * read. */
15537
                    current = wolfSSL_X509_INFO_new();
15538
                    if (current == NULL) {
15539
                        ret = MEMORY_E;
15540
                        break;
15541
                    }
15542
                    if (wolfSSL_sk_X509_INFO_push(localSk, current) <= 0) {
15543
                        wolfSSL_X509_INFO_free(current);
15544
                        current = NULL;
15545
                        ret = WOLFSSL_FAILURE;
15546
                        break;
15547
                    }
15548
                }
15549
15550
                if (x509) {
15551
                    current->x509 = x509;
15552
                }
15553
                else if (crl) {
15554
                    current->crl = crl;
15555
                }
15556
                else if (x_pkey) {
15557
                    current->x_pkey = x_pkey;
15558
                }
15559
                else {
15560
                    WOLFSSL_MSG("No output parameters set");
15561
                    ret = WOLFSSL_FAILURE;
15562
                    break;
15563
                }
15564
            }
15565
            else {
15566
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
15567
                unsigned long err;
15568
                CLEAR_ASN_NO_PEM_HEADER_ERROR(err);
15569
                if (ERR_GET_LIB(err) != ERR_LIB_PEM ||
15570
                    ERR_GET_REASON(err) != PEM_R_NO_START_LINE) {
15571
                    ret = WOLFSSL_FAILURE;
15572
                }
15573
#else
15574
                if (wolfSSL_sk_X509_INFO_num(localSk) > 0) {
15575
                    WOLFSSL_MSG("At least one X509_INFO object on stack."
15576
                                "Assuming error means EOF or no more PEM"
15577
                                "headers found.");
15578
                }
15579
                else {
15580
                    ret = WOLFSSL_FAILURE;
15581
                }
15582
#endif
15583
                break;
15584
            }
15585
        }
15586
        if (ret != WOLFSSL_SUCCESS ||
15587
                wolfSSL_sk_X509_INFO_num(localSk) == 0) {
15588
            /* current should always be pushed onto the localsk stack at this
15589
             * point. The only case when it isn't is when
15590
             * wolfSSL_sk_X509_INFO_push fails but in that case the current
15591
             * free is handled inside the loop. */
15592
            if (localSk != sk) {
15593
                wolfSSL_sk_pop_free(localSk, NULL);
15594
            }
15595
            wolfSSL_X509_free(x509);
15596
#ifdef HAVE_CRL
15597
            wolfSSL_X509_CRL_free(crl);
15598
#endif
15599
            wolfSSL_X509_PKEY_free(x_pkey);
15600
            localSk = NULL;
15601
        }
15602
        WOLFSSL_LEAVE("wolfSSL_PEM_X509_INFO_read_bio", ret);
15603
        return localSk;
15604
    }
15605
#endif /* !NO_BIO */
15606
#endif /* OPENSSL_EXTRA || OPENSSL_ALL */
15607
15608
    void wolfSSL_X509_NAME_ENTRY_free(WOLFSSL_X509_NAME_ENTRY* ne)
15609
    {
15610
        WOLFSSL_ENTER_VERBOSE("wolfSSL_X509_NAME_ENTRY_free");
15611
        if (ne != NULL) {
15612
            wolfSSL_ASN1_OBJECT_free(ne->object);
15613
            if (ne->value != NULL) {
15614
                wolfSSL_ASN1_STRING_free(ne->value);
15615
            }
15616
            XFREE(ne, NULL, DYNAMIC_TYPE_NAME_ENTRY);
15617
        }
15618
    }
15619
15620
15621
    WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_new(void)
15622
    {
15623
        WOLFSSL_X509_NAME_ENTRY* ne;
15624
15625
        ne = (WOLFSSL_X509_NAME_ENTRY*)XMALLOC(sizeof(WOLFSSL_X509_NAME_ENTRY),
15626
                NULL, DYNAMIC_TYPE_NAME_ENTRY);
15627
        if (ne != NULL) {
15628
            XMEMSET(ne, 0, sizeof(WOLFSSL_X509_NAME_ENTRY));
15629
        }
15630
15631
        return ne;
15632
    }
15633
15634
15635
    /* Encoding of the OBJECT IDENTIFIER in a name attribute's object: as made
15636
     * by wolfSSL_OBJ_nid2obj(), which has no OIDs for name attributes. */
15637
    static const byte x509NameObjDer[] = { ASN_OBJECT_ID, 0x00 };
15638
15639
#ifdef OPENSSL_EXTRA
15640
    #define X509_NAME_OBJ_CA_INIT   0, NULL,
15641
#else
15642
    #define X509_NAME_OBJ_CA_INIT
15643
#endif
15644
#ifdef WOLFSSL_APACHE_HTTPD
15645
    #define X509_NAME_OBJ_GN_INIT   NULL,
15646
#else
15647
    #define X509_NAME_OBJ_GN_INIT
15648
#endif
15649
#ifdef __cplusplus
15650
    /* g++ warns of each member that { 0 } leaves out, but not of { }. */
15651
    #define X509_NAME_OBJ_D_INIT    { }
15652
#else
15653
    #define X509_NAME_OBJ_D_INIT    { 0 }
15654
#endif
15655
    /* Object for a name attribute as wolfSSL_OBJ_nid2obj() fills it in, but
15656
     * not dynamic so that it is never freed. The fields of
15657
     * WOLFSSL_ASN1_OBJECT before d are given in order: change this with them.
15658
     * test_wolfSSL_X509_NAME_ENTRY_shared_object checks each field. */
15659
    #define X509_NAME_OBJ(nid, oidSum, sn)                                     \
15660
        { NULL, x509NameObjDer, sn, oidSum, oidCertNameType, nid,             \
15661
          (unsigned int)sizeof(x509NameObjDer), X509_NAME_OBJ_CA_INIT 0,       \
15662
          X509_NAME_OBJ_GN_INIT X509_NAME_OBJ_D_INIT }
15663
15664
    /* Read-only objects shared by the name entries of the common attributes.
15665
     * Other attributes have an object of the entry's own. */
15666
    static const WOLFSSL_ASN1_OBJECT x509NameObjs[] = {
15667
        X509_NAME_OBJ(WC_NID_commonName, WC_NAME_COMMON_NAME_OID, "CN"),
15668
        X509_NAME_OBJ(WC_NID_organizationName, WC_NAME_ORGANIZATION_NAME_OID,
15669
            "O"),
15670
        X509_NAME_OBJ(WC_NID_organizationalUnitName,
15671
            WC_NAME_ORGANIZATION_UNIT_NAME_OID, "OU"),
15672
        X509_NAME_OBJ(WC_NID_countryName, WC_NAME_COUNTRY_NAME_OID, "C"),
15673
        X509_NAME_OBJ(WC_NID_stateOrProvinceName, WC_NAME_STATE_NAME_OID,
15674
            "ST"),
15675
        X509_NAME_OBJ(WC_NID_localityName, WC_NAME_LOCALITY_NAME_OID, "L"),
15676
        X509_NAME_OBJ(WC_NID_emailAddress, WC_NAME_EMAIL_ADDRESS_OID,
15677
            "emailAddress"),
15678
        X509_NAME_OBJ(WC_NID_serialNumber, WC_NAME_SERIAL_NUMBER_OID,
15679
            "serialNumber"),
15680
        X509_NAME_OBJ(WC_NID_domainComponent, WC_NAME_DOMAIN_COMPONENT_OID,
15681
            "DC")
15682
    };
15683
    #undef X509_NAME_OBJ
15684
    #undef X509_NAME_OBJ_CA_INIT
15685
    #undef X509_NAME_OBJ_GN_INIT
15686
    #undef X509_NAME_OBJ_D_INIT
15687
15688
    /* Get the shared object for a name attribute.
15689
     *
15690
     * @param [in] nid  NID of name attribute.
15691
     * @return  Shared object on success.
15692
     * @return  NULL when the attribute has no shared object.
15693
     */
15694
    static WOLFSSL_ASN1_OBJECT* X509NameSharedObject(int nid)
15695
    {
15696
        size_t i;
15697
15698
        for (i = 0; i < XELEM_CNT(x509NameObjs); i++) {
15699
            if (x509NameObjs[i].nid == nid) {
15700
                /* Never written to: see wolfssl_x509_name_entry_set(). */
15701
                return (WOLFSSL_ASN1_OBJECT*)&x509NameObjs[i];
15702
            }
15703
        }
15704
        return NULL;
15705
    }
15706
15707
    static void wolfssl_x509_name_entry_set(WOLFSSL_X509_NAME_ENTRY* ne,
15708
        int nid, int type, const unsigned char *data, int dataSz)
15709
    {
15710
        WOLFSSL_ASN1_OBJECT* obj = X509NameSharedObject(nid);
15711
15712
        ne->nid = nid;
15713
        if (obj != NULL) {
15714
            /* Use the shared object, freeing any object of the entry's own. */
15715
            wolfSSL_ASN1_OBJECT_free(ne->object);
15716
            ne->object = obj;
15717
        }
15718
        else {
15719
            /* Reuse the entry's own object. A shared object is not dynamic
15720
             * and must not be written to. */
15721
            if ((ne->object != NULL) &&
15722
                    ((ne->object->dynamic & WOLFSSL_ASN1_DYNAMIC) == 0)) {
15723
                ne->object = NULL;
15724
            }
15725
            ne->object = wolfSSL_OBJ_nid2obj_ex(nid, ne->object);
15726
        }
15727
        if (ne->value == NULL) {
15728
            ne->value = wolfSSL_ASN1_STRING_type_new(type);
15729
        }
15730
        if (ne->value != NULL) {
15731
            if (wolfSSL_ASN1_STRING_set(ne->value, (const void*)data,
15732
                                            dataSz) == WOLFSSL_SUCCESS) {
15733
                ne->set = 1;
15734
            }
15735
            else {
15736
                /* Free the ASN1_STRING if it is not set. */
15737
                wolfSSL_ASN1_STRING_free(ne->value);
15738
                ne->value = NULL;
15739
            }
15740
        }
15741
    }
15742
15743
    /* Create a new WOLFSSL_X509_NAME_ENTRY structure based on the text passed
15744
     * in. Returns NULL on failure */
15745
    WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_create_by_txt(
15746
            WOLFSSL_X509_NAME_ENTRY **neIn, const char *txt, int type,
15747
            const unsigned char *data, int dataSz)
15748
    {
15749
        int nid = -1;
15750
        WOLFSSL_X509_NAME_ENTRY* ne = NULL;
15751
15752
        WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_create_by_txt");
15753
15754
        if (txt == NULL) {
15755
            return NULL;
15756
        }
15757
15758
        if (neIn != NULL) {
15759
            ne = *neIn;
15760
        }
15761
15762
        nid = wolfSSL_OBJ_txt2nid(txt);
15763
        if (nid == WC_NID_undef) {
15764
            WOLFSSL_MSG("Unable to find text");
15765
            ne = NULL;
15766
        }
15767
        else {
15768
            if (ne == NULL) {
15769
                ne = wolfSSL_X509_NAME_ENTRY_new();
15770
                if (ne == NULL) {
15771
                    return NULL;
15772
                }
15773
            }
15774
15775
            wolfssl_x509_name_entry_set(ne, nid, type, data, dataSz);
15776
        }
15777
15778
        return ne;
15779
    }
15780
15781
15782
    /* Creates a new entry given the NID, type, and data
15783
     * "dataSz" is number of bytes in data, if set to -1 then XSTRLEN is used
15784
     * "out" can be used to store the new entry data in an existing structure
15785
     *       if NULL then a new WOLFSSL_X509_NAME_ENTRY structure is created
15786
     * returns a pointer to WOLFSSL_X509_NAME_ENTRY on success and NULL on fail
15787
     */
15788
    WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_create_by_NID(
15789
            WOLFSSL_X509_NAME_ENTRY** out, int nid, int type,
15790
            const unsigned char* data, int dataSz)
15791
    {
15792
        WOLFSSL_X509_NAME_ENTRY* ne;
15793
15794
        WOLFSSL_ENTER_VERBOSE("wolfSSL_X509_NAME_ENTRY_create_by_NID");
15795
15796
        if (!data) {
15797
            WOLFSSL_MSG("Bad parameter");
15798
            return NULL;
15799
        }
15800
15801
        if (out == NULL || *out == NULL) {
15802
            ne = wolfSSL_X509_NAME_ENTRY_new();
15803
            if (ne == NULL) {
15804
                return NULL;
15805
            }
15806
            if (out != NULL) {
15807
                *out = ne;
15808
            }
15809
        }
15810
        else {
15811
            ne = *out;
15812
        }
15813
15814
        wolfssl_x509_name_entry_set(ne, nid, type, data, dataSz);
15815
15816
        return ne;
15817
    }
15818
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
15819
15820
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
15821
    defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
15822
    defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
15823
    defined(HAVE_POCO_LIB) || defined(WOLFSSL_HAPROXY)
15824
WOLFSSL_ASN1_OBJECT* wolfSSL_X509_NAME_ENTRY_get_object(
15825
    const WOLFSSL_X509_NAME_ENTRY *ne)
15826
{
15827
    WOLFSSL_ENTER_VERBOSE("wolfSSL_X509_NAME_ENTRY_get_object");
15828
15829
    if (ne == NULL) {
15830
        return NULL;
15831
    }
15832
    /* Object is set when the entry's NID is set. */
15833
    return ne->object;
15834
}
15835
#endif /* OPENSSL_ALL || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE ||
15836
        * HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_POCO_LIB || WOLFSSL_HAPROXY */
15837
15838
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
15839
    /* Get the object of an entry in a name.
15840
     * The object set with the entry is used when it is for the entry's NID,
15841
     * rather than filling it in from the OID table again.
15842
     */
15843
    static WOLFSSL_ASN1_OBJECT* X509NameEntryObject(WOLFSSL_X509_NAME_ENTRY* e)
15844
    {
15845
        if ((e->object != NULL) && (e->object->nid == e->nid)) {
15846
            return e->object;
15847
        }
15848
        return wolfSSL_X509_NAME_ENTRY_get_object(e);
15849
    }
15850
15851
    /* add all entry of type "nid" to the buffer "fullName" and advance "idx"
15852
     * since number of entries is small, a brute force search is used here
15853
     * returns the number of entries added
15854
     */
15855
    static int AddAllEntry(WOLFSSL_X509_NAME* name, char* fullName,
15856
            word32 fullNameSz, int* idx)
15857
    {
15858
        int i;
15859
        int ret = 0;
15860
15861
        for (i = 0; i < MAX_NAME_ENTRIES; i++) {
15862
            if (name->entry[i].set) {
15863
                WOLFSSL_X509_NAME_ENTRY* e;
15864
                WOLFSSL_ASN1_OBJECT* obj;
15865
15866
                int sz;
15867
                unsigned char* data;
15868
15869
                e = &name->entry[i];
15870
                obj = X509NameEntryObject(e);
15871
                if (obj == NULL) {
15872
                    return BAD_FUNC_ARG;
15873
                }
15874
15875
                XMEMCPY(fullName + *idx, "/", 1); *idx = *idx + 1;
15876
                sz = (int)XSTRLEN(obj->sName);
15877
                XMEMCPY(fullName + *idx, obj->sName, sz);
15878
                *idx += sz;
15879
                XMEMCPY(fullName + *idx, "=", 1); *idx = *idx + 1;
15880
15881
                data = wolfSSL_ASN1_STRING_data(e->value);
15882
                if (data != NULL) {
15883
                    sz = (int)XSTRLEN((const char*)data);
15884
                    if ((fullNameSz - (word32)*idx) >=
15885
                            X509CertEscapeName(NULL, (const char*)data,
15886
                                (word32)sz)) {
15887
                        *idx += (int)X509CertEscapeName(fullName + *idx,
15888
                                (const char*)data, (word32)sz);
15889
                    }
15890
                    else {
15891
                        return BUFFER_E;
15892
                    }
15893
                }
15894
15895
                ret++;
15896
            }
15897
        }
15898
        return ret;
15899
    }
15900
15901
15902
    /* Converts a list of entries in WOLFSSL_X509_NAME struct into a string
15903
     * returns 0 on success */
15904
    static int RebuildFullName(WOLFSSL_X509_NAME* name)
15905
    {
15906
        word32 totalLen = 0;
15907
        int i, idx, entryCount = 0;
15908
15909
        if (name == NULL)
15910
            return BAD_FUNC_ARG;
15911
15912
        for (i = 0; i < MAX_NAME_ENTRIES; i++) {
15913
            if (name->entry[i].set) {
15914
                WOLFSSL_X509_NAME_ENTRY* e;
15915
                WOLFSSL_ASN1_OBJECT* obj;
15916
                const char* data;
15917
                word32 intermediateVal = 0;
15918
15919
                e = &name->entry[i];
15920
                obj = X509NameEntryObject(e);
15921
                if (obj == NULL)
15922
                    return BAD_FUNC_ARG;
15923
15924
                /* +2 for '/' and '=' */
15925
                intermediateVal = (word32)XSTRLEN(obj->sName) + 2;
15926
                if (intermediateVal > (word32)INT_MAX - 1 - totalLen)
15927
                    return BUFFER_E;
15928
                totalLen += intermediateVal;
15929
15930
                data = (const char*)wolfSSL_ASN1_STRING_data(e->value);
15931
                if (data == NULL) {
15932
                    continue;
15933
                }
15934
                /* Certain characters need to be escaped, so ask for the
15935
                 * length of the value once escaped. */
15936
                intermediateVal = X509CertEscapeName(NULL, data,
15937
                    (word32)XSTRLEN(data));
15938
                if (intermediateVal > (word32)INT_MAX - 1 - totalLen)
15939
                    return BUFFER_E;
15940
                totalLen += intermediateVal;
15941
            }
15942
        }
15943
15944
        if (name->dynamicName) {
15945
            XFREE(name->name, name->heap, DYNAMIC_TYPE_X509);
15946
            name->name = name->staticName;
15947
            name->dynamicName = 0;
15948
        }
15949
15950
        if (totalLen >= ASN_NAME_MAX) {
15951
            name->name = (char*)XMALLOC(totalLen + 1, name->heap,
15952
                    DYNAMIC_TYPE_X509);
15953
            if (name->name == NULL)
15954
                return MEMORY_E;
15955
            name->dynamicName = 1;
15956
        }
15957
15958
        idx = 0;
15959
        entryCount = AddAllEntry(name, name->name, totalLen, &idx);
15960
        if (entryCount < 0)
15961
            return entryCount;
15962
15963
        name->name[idx] = '\0';
15964
        name->sz = idx + 1; /* size includes null terminator */
15965
        name->entrySz = entryCount;
15966
15967
        return 0;
15968
    }
15969
15970
    /* Set an entry in name from the NID, string type and data.
15971
     * idx is the index to place the entry at or -1 for the first unset one.
15972
     * returns 1 for success and 0 for error */
15973
    static int X509NameAddEntry(WOLFSSL_X509_NAME* name, int nid, int type,
15974
            const unsigned char* data, int dataSz, int idx)
15975
    {
15976
        WOLFSSL_X509_NAME_ENTRY* current = NULL;
15977
        int ret, i;
15978
15979
        if (idx >= 0) {
15980
            /* place in specific index */
15981
15982
            if (idx >= MAX_NAME_ENTRIES) {
15983
                WOLFSSL_MSG("Error index to insert entry is larger than array");
15984
                return WOLFSSL_FAILURE;
15985
            }
15986
            i = idx;
15987
        }
15988
        else {
15989
            /* iterate through and find first open spot */
15990
            for (i = 0; i < MAX_NAME_ENTRIES; i++) {
15991
                if (name->entry[i].set == 0) { /* not set so overwritten */
15992
                    WOLFSSL_MSG_VERBOSE("Found place for name entry");
15993
                    break;
15994
                }
15995
            }
15996
15997
            if (i == MAX_NAME_ENTRIES) {
15998
                WOLFSSL_MSG("No spot found for name entry");
15999
                return WOLFSSL_FAILURE;
16000
            }
16001
        }
16002
16003
        current = &name->entry[i];
16004
        if (current->set == 0)
16005
            name->entrySz++;
16006
    #if !defined(WOLFSSL_NO_CA_NAMES) && defined(OPENSSL_EXTRA)
16007
        /* No longer the name as encoded. */
16008
        ClearX509NameRaw(name);
16009
    #endif
16010
16011
        if ((wolfSSL_X509_NAME_ENTRY_create_by_NID(&current, nid, type, data,
16012
                dataSz) != NULL) && (current->value != NULL))
16013
        {
16014
            ret = WOLFSSL_SUCCESS;
16015
        #ifdef OPENSSL_ALL
16016
            if (name->entries == NULL) {
16017
                name->entries = wolfSSL_sk_X509_NAME_new(NULL);
16018
            }
16019
            if (wolfSSL_sk_X509_NAME_ENTRY_push(name->entries, current) <= 0) {
16020
                ret = WOLFSSL_FAILURE;
16021
            }
16022
        #endif
16023
        }
16024
        else {
16025
            ret = WOLFSSL_FAILURE;
16026
        }
16027
16028
        if (ret != WOLFSSL_SUCCESS) {
16029
            WOLFSSL_MSG("Error adding the name entry");
16030
            if (current->set == 0)
16031
                name->entrySz--;
16032
            return WOLFSSL_FAILURE;
16033
        }
16034
16035
#ifdef WOLFSSL_PYTHON
16036
        /* Set name index for OpenSSL stack index position and so Python can
16037
         * generate tuples/sets from the list. */
16038
        for (i = 0; i < MAX_NAME_ENTRIES; i++) {
16039
            if (name->entry[i].set != 0)
16040
                name->entry[i].set = i + 1;
16041
        }
16042
#endif
16043
16044
        if (RebuildFullName(name) != 0)
16045
            return WOLFSSL_FAILURE;
16046
16047
        return WOLFSSL_SUCCESS;
16048
    }
16049
16050
    /* Copies entry into name. With it being copied freeing entry becomes the
16051
     * callers responsibility.
16052
     * returns 1 for success and 0 for error */
16053
    int wolfSSL_X509_NAME_add_entry(WOLFSSL_X509_NAME* name,
16054
            WOLFSSL_X509_NAME_ENTRY* entry, int idx, int set)
16055
    {
16056
        WOLFSSL_ENTER_VERBOSE("wolfSSL_X509_NAME_add_entry");
16057
16058
        if (name == NULL || entry == NULL || entry->value == NULL) {
16059
            WOLFSSL_MSG("NULL argument passed in");
16060
            return WOLFSSL_FAILURE;
16061
        }
16062
16063
        (void)set;
16064
        return X509NameAddEntry(name, entry->nid,
16065
            wolfSSL_ASN1_STRING_type(entry->value),
16066
            wolfSSL_ASN1_STRING_data(entry->value),
16067
            wolfSSL_ASN1_STRING_length(entry->value), idx);
16068
    }
16069
16070
    int wolfSSL_X509_NAME_add_entry_by_txt(WOLFSSL_X509_NAME *name,
16071
                                           const char *field, int type,
16072
                                           const unsigned char *bytes, int len,
16073
                                           int loc, int set)
16074
    {
16075
        int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
16076
        int nid;
16077
        WOLFSSL_X509_NAME_ENTRY* entry;
16078
16079
        (void)type;
16080
        WOLFSSL_ENTER("wolfSSL_X509_NAME_add_entry_by_txt");
16081
16082
        if (name == NULL || field == NULL)
16083
            return WOLFSSL_FAILURE;
16084
16085
        if ((nid = wolfSSL_OBJ_txt2nid(field)) == WC_NID_undef) {
16086
            WOLFSSL_MSG("Unable convert text to NID");
16087
            return WOLFSSL_FAILURE;
16088
        }
16089
16090
        entry = wolfSSL_X509_NAME_ENTRY_create_by_NID(NULL,
16091
                  nid, type, (unsigned char*)bytes, len);
16092
        if (entry == NULL)
16093
            return WOLFSSL_FAILURE;
16094
16095
        ret = wolfSSL_X509_NAME_add_entry(name, entry, loc, set);
16096
        wolfSSL_X509_NAME_ENTRY_free(entry);
16097
16098
        return ret;
16099
    }
16100
16101
    int wolfSSL_X509_NAME_add_entry_by_NID(WOLFSSL_X509_NAME *name, int nid,
16102
                                           int type, const unsigned char *bytes,
16103
                                           int len, int loc, int set)
16104
    {
16105
        WOLFSSL_ENTER_VERBOSE("wolfSSL_X509_NAME_add_entry_by_NID");
16106
        if (name == NULL || bytes == NULL) {
16107
            WOLFSSL_MSG("NULL argument passed in");
16108
            return WOLFSSL_FAILURE;
16109
        }
16110
        (void)set;
16111
        /* Set the entry in place rather than copying a temporary one. */
16112
        return X509NameAddEntry(name, nid, type, bytes, len, loc);
16113
    }
16114
16115
    WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_delete_entry(
16116
            WOLFSSL_X509_NAME *name, int loc)
16117
    {
16118
        WOLFSSL_X509_NAME_ENTRY* ret;
16119
        WOLFSSL_ENTER("wolfSSL_X509_NAME_delete_entry");
16120
16121
        if (!name) {
16122
            WOLFSSL_MSG("Bad parameter");
16123
            return NULL;
16124
        }
16125
16126
        ret = wolfSSL_X509_NAME_get_entry(name, loc);
16127
        if (!ret) {
16128
            WOLFSSL_MSG("loc entry not found");
16129
            return NULL;
16130
        }
16131
        name->entry[loc].set = 0;
16132
    #if !defined(WOLFSSL_NO_CA_NAMES) && defined(OPENSSL_EXTRA)
16133
        /* No longer the name as encoded. */
16134
        ClearX509NameRaw(name);
16135
    #endif
16136
#ifdef WOLFSSL_PYTHON
16137
        {
16138
            int i;
16139
            /* Set name index for OpenSSL stack index position and so Python can
16140
            * generate tuples/sets from the list. */
16141
            for (i = 0; i < MAX_NAME_ENTRIES; i++) {
16142
                if (name->entry[i].set != 0)
16143
                    name->entry[i].set = i + 1;
16144
            }
16145
        }
16146
#endif
16147
        return ret;
16148
    }
16149
16150
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
16151
16152
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN)
16153
    int wolfSSL_X509_NAME_get_index_by_OBJ(const WOLFSSL_X509_NAME *name,
16154
                                           const WOLFSSL_ASN1_OBJECT *obj,
16155
                                           int idx) {
16156
        if (!name || idx >= MAX_NAME_ENTRIES ||
16157
                !obj || !obj->obj) {
16158
            return WOLFSSL_FATAL_ERROR;
16159
        }
16160
16161
        if (idx < 0) {
16162
            idx = -1;
16163
        }
16164
16165
        for (idx++; idx < MAX_NAME_ENTRIES; idx++) {
16166
            /* Find index of desired name */
16167
            if (name->entry[idx].set) {
16168
                if (XSTRLEN(obj->sName) ==
16169
                        XSTRLEN(name->entry[idx].object->sName) &&
16170
                    XSTRNCMP((const char*) obj->sName,
16171
                        name->entry[idx].object->sName, obj->objSz - 1) == 0) {
16172
                    return idx;
16173
                }
16174
            }
16175
        }
16176
        return WOLFSSL_FATAL_ERROR;
16177
    }
16178
#endif
16179
16180
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
16181
    defined(OPENSSL_EXTRA_X509_SMALL)
16182
16183
#ifdef OPENSSL_EXTRA
16184
    int wolfSSL_X509_NAME_ENTRY_set(const WOLFSSL_X509_NAME_ENTRY *ne)
16185
    {
16186
        if (ne != NULL) {
16187
            return ne->set;
16188
        }
16189
        return 0;
16190
    }
16191
#endif
16192
16193
16194
    /* returns a pointer to the internal entry at location 'loc' on success,
16195
     * a null pointer is returned in fail cases */
16196
    WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_get_entry(
16197
                                        const WOLFSSL_X509_NAME *name, int loc)
16198
    {
16199
        WOLFSSL_ENTER_VERBOSE("wolfSSL_X509_NAME_get_entry");
16200
16201
        if (name == NULL) {
16202
            return NULL;
16203
        }
16204
16205
        if (loc < 0 || loc >= MAX_NAME_ENTRIES) {
16206
            WOLFSSL_MSG("Bad argument");
16207
            return NULL;
16208
        }
16209
16210
        if (name->entry[loc].set) {
16211
            return (WOLFSSL_X509_NAME_ENTRY*)&name->entry[loc];
16212
        }
16213
        else {
16214
            return NULL;
16215
        }
16216
    }
16217
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
16218
16219
#ifdef OPENSSL_EXTRA
16220
16221
int wolfSSL_X509_check_private_key(WOLFSSL_X509 *x509, WOLFSSL_EVP_PKEY *key)
16222
{
16223
    WOLFSSL_ENTER("wolfSSL_X509_check_private_key");
16224
16225
    if (!x509 || !key) {
16226
        WOLFSSL_MSG("Bad parameter");
16227
        return WOLFSSL_FAILURE;
16228
    }
16229
16230
#ifndef NO_CHECK_PRIVATE_KEY
16231
    return wc_CheckPrivateKey((byte*)key->pkey.ptr, key->pkey_sz,
16232
            x509->pubKey.buffer, x509->pubKey.length,
16233
            (enum Key_Sum)x509->pubKeyOID, key->heap) == 1 ?
16234
                    WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
16235
#else
16236
    /* not compiled in */
16237
    return WOLFSSL_SUCCESS;
16238
#endif
16239
}
16240
16241
#endif /* OPENSSL_EXTRA */
16242
16243
#if defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL) \
16244
    || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA)
16245
#ifndef NO_BIO
16246
16247
#ifdef WOLFSSL_CERT_GEN
16248
16249
#ifdef WOLFSSL_CERT_REQ
16250
/* writes the x509 from x to the WOLFSSL_BIO bp
16251
 *
16252
 * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on fail
16253
 */
16254
int wolfSSL_PEM_write_bio_X509_REQ(WOLFSSL_BIO *bp, WOLFSSL_X509 *x)
16255
{
16256
    byte* pem;
16257
    int   pemSz = 0;
16258
    const unsigned char* der;
16259
    int derSz;
16260
    int ret;
16261
16262
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509_REQ");
16263
16264
    if (x == NULL || bp == NULL) {
16265
        return WOLFSSL_FAILURE;
16266
    }
16267
16268
    der = wolfSSL_X509_get_der(x, &derSz);
16269
    if (der == NULL) {
16270
        return WOLFSSL_FAILURE;
16271
    }
16272
16273
    /* get PEM size */
16274
    pemSz = wc_DerToPemEx(der, (word32)derSz, NULL, 0, NULL, CERTREQ_TYPE);
16275
    if (pemSz < 0) {
16276
        return WOLFSSL_FAILURE;
16277
    }
16278
16279
    /* create PEM buffer and convert from DER */
16280
    pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16281
    if (pem == NULL) {
16282
        return WOLFSSL_FAILURE;
16283
    }
16284
    if (wc_DerToPemEx(der, (word32)derSz, pem, pemSz, NULL, CERTREQ_TYPE) < 0) {
16285
        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16286
        return WOLFSSL_FAILURE;
16287
    }
16288
16289
    /* write the PEM to BIO */
16290
    ret = wolfSSL_BIO_write(bp, pem, pemSz);
16291
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16292
16293
    if (ret <= 0) return WOLFSSL_FAILURE;
16294
    return WOLFSSL_SUCCESS;
16295
}
16296
#endif /* WOLFSSL_CERT_REQ */
16297
16298
16299
/* writes the x509 from x to the WOLFSSL_BIO bp
16300
 *
16301
 * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on fail
16302
 */
16303
int wolfSSL_PEM_write_bio_X509_AUX(WOLFSSL_BIO *bp, WOLFSSL_X509 *x)
16304
{
16305
    byte* pem;
16306
    int   pemSz = 0;
16307
    const unsigned char* der;
16308
    int derSz;
16309
    int ret;
16310
16311
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509_AUX");
16312
16313
    if (bp == NULL || x == NULL) {
16314
        WOLFSSL_MSG("NULL argument passed in");
16315
        return WOLFSSL_FAILURE;
16316
    }
16317
16318
    der = wolfSSL_X509_get_der(x, &derSz);
16319
    if (der == NULL) {
16320
        return WOLFSSL_FAILURE;
16321
    }
16322
16323
    /* get PEM size */
16324
    pemSz = wc_DerToPemEx(der, (word32)derSz, NULL, 0, NULL, CERT_TYPE);
16325
    if (pemSz < 0) {
16326
        return WOLFSSL_FAILURE;
16327
    }
16328
16329
    /* create PEM buffer and convert from DER */
16330
    pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16331
    if (pem == NULL) {
16332
        return WOLFSSL_FAILURE;
16333
    }
16334
    if (wc_DerToPemEx(der, (word32)derSz, pem, pemSz, NULL, CERT_TYPE) < 0) {
16335
        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16336
        return WOLFSSL_FAILURE;
16337
    }
16338
16339
    /* write the PEM to BIO */
16340
    ret = wolfSSL_BIO_write(bp, pem, pemSz);
16341
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16342
16343
    if (ret <= 0) return WOLFSSL_FAILURE;
16344
    return WOLFSSL_SUCCESS;
16345
}
16346
16347
int wolfSSL_PEM_write_bio_X509(WOLFSSL_BIO *bio, WOLFSSL_X509 *cert)
16348
{
16349
    byte* pem = NULL;
16350
    int   pemSz = 0;
16351
    /* Get large buffer to hold cert der */
16352
    const byte* der = NULL;
16353
    int derSz = X509_BUFFER_SZ;
16354
    int ret;
16355
16356
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509");
16357
16358
    if (bio == NULL || cert == NULL) {
16359
        WOLFSSL_MSG("NULL argument passed in");
16360
        return WOLFSSL_FAILURE;
16361
    }
16362
16363
    /* Do not call wolfssl_x509_make_der() here. If we did, then need to re-sign
16364
     * because we don't know the original order of the extensions and so we must
16365
     * assume our extensions are in a different order, thus need to re-sign. */
16366
    der = wolfSSL_X509_get_der(cert, &derSz);
16367
    if (der == NULL) {
16368
        goto error;
16369
    }
16370
16371
    /* get PEM size */
16372
    pemSz = wc_DerToPemEx(der, (word32)derSz, NULL, 0, NULL, CERT_TYPE);
16373
    if (pemSz < 0) {
16374
        goto error;
16375
    }
16376
16377
    /* create PEM buffer and convert from DER */
16378
    pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16379
    if (pem == NULL) {
16380
        goto error;
16381
    }
16382
    if (wc_DerToPemEx(der, (word32)derSz, pem, pemSz, NULL, CERT_TYPE) < 0) {
16383
        goto error;
16384
    }
16385
16386
    /* write the PEM to BIO */
16387
    ret = wolfSSL_BIO_write(bio, pem, pemSz);
16388
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16389
16390
    if (ret <= 0) return WOLFSSL_FAILURE;
16391
    return WOLFSSL_SUCCESS;
16392
16393
error:
16394
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16395
    return WOLFSSL_FAILURE;
16396
}
16397
#endif /* WOLFSSL_CERT_GEN */
16398
16399
#endif /* !NO_BIO */
16400
#endif /* HAVE_LIGHTY || HAVE_STUNNEL || WOLFSSL_MYSQL_COMPATIBLE */
16401
16402
#if defined(OPENSSL_EXTRA) || defined(HAVE_STUNNEL) || \
16403
        defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY) || \
16404
        defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_OPENSSH) || \
16405
        defined(HAVE_SBLIM_SFCB)
16406
16407
WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_sk_X509_NAME_new(
16408
        WOLF_SK_COMPARE_CB(WOLFSSL_X509_NAME, cb))
16409
{
16410
    WOLFSSL_STACK* sk;
16411
    (void)cb;
16412
16413
    WOLFSSL_ENTER_VERBOSE("wolfSSL_sk_X509_NAME_new");
16414
16415
    sk = wolfSSL_sk_new_node(NULL);
16416
    if (sk != NULL) {
16417
        sk->type = STACK_TYPE_X509_NAME;
16418
    }
16419
16420
    return sk;
16421
}
16422
16423
int wolfSSL_sk_X509_NAME_num(const WOLF_STACK_OF(WOLFSSL_X509_NAME) *sk)
16424
{
16425
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_num");
16426
16427
    if (sk == NULL)
16428
        return BAD_FUNC_ARG;
16429
16430
    return (int)sk->num;
16431
}
16432
16433
/* Getter function for WOLFSSL_X509_NAME pointer
16434
 *
16435
 * sk is the stack to retrieve pointer from
16436
 * i  is the index value in stack
16437
 *
16438
 * returns a pointer to a WOLFSSL_X509_NAME structure on success and NULL on
16439
 *         fail
16440
 */
16441
WOLFSSL_X509_NAME* wolfSSL_sk_X509_NAME_value(
16442
    const WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, int i)
16443
{
16444
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_value");
16445
    return (WOLFSSL_X509_NAME*)wolfSSL_sk_value(sk, i);
16446
}
16447
16448
WOLFSSL_X509_NAME* wolfSSL_sk_X509_NAME_pop(
16449
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk)
16450
{
16451
    return (WOLFSSL_X509_NAME*)wolfSSL_sk_pop(sk);
16452
}
16453
16454
void wolfSSL_sk_X509_NAME_pop_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk,
16455
    void (*f) (WOLFSSL_X509_NAME*))
16456
{
16457
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_pop_free");
16458
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
16459
}
16460
16461
/* Free only the sk structure, NOT X509_NAME members */
16462
void wolfSSL_sk_X509_NAME_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk)
16463
{
16464
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_free");
16465
    wolfSSL_sk_free(sk);
16466
}
16467
16468
int wolfSSL_sk_X509_NAME_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk,
16469
    WOLFSSL_X509_NAME* name)
16470
{
16471
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_push");
16472
16473
    return wolfSSL_sk_push(sk, name);
16474
}
16475
16476
/* return index of found, or negative to indicate not found */
16477
int wolfSSL_sk_X509_NAME_find(const WOLF_STACK_OF(WOLFSSL_X509_NAME) *sk,
16478
    WOLFSSL_X509_NAME *name)
16479
{
16480
    int i;
16481
16482
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_find");
16483
16484
    if (sk == NULL)
16485
        return BAD_FUNC_ARG;
16486
16487
    for (i = 0; sk; i++, sk = sk->next) {
16488
        if (wolfSSL_X509_NAME_cmp(sk->data.name, name) == 0) {
16489
            return i;
16490
        }
16491
    }
16492
    return WOLFSSL_FATAL_ERROR;
16493
}
16494
16495
/* Name Entry */
16496
WOLF_STACK_OF(WOLFSSL_X509_NAME_ENTRY)* wolfSSL_sk_X509_NAME_ENTRY_new(
16497
    WOLF_SK_COMPARE_CB(WOLFSSL_X509_NAME_ENTRY, cb))
16498
{
16499
    WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL);
16500
    if (sk != NULL) {
16501
        sk->type = STACK_TYPE_X509_NAME_ENTRY;
16502
        (void)cb;
16503
    }
16504
    return sk;
16505
}
16506
16507
int wolfSSL_sk_X509_NAME_ENTRY_push(WOLF_STACK_OF(WOLFSSL_X509_NAME_ENTRY)* sk,
16508
    WOLFSSL_X509_NAME_ENTRY* name_entry)
16509
{
16510
    return wolfSSL_sk_push(sk, name_entry);
16511
}
16512
16513
WOLFSSL_X509_NAME_ENTRY* wolfSSL_sk_X509_NAME_ENTRY_value(
16514
    const WOLF_STACK_OF(WOLFSSL_X509_NAME_ENTRY)* sk, int i)
16515
{
16516
    return (WOLFSSL_X509_NAME_ENTRY*)wolfSSL_sk_value(sk, i);
16517
}
16518
16519
int wolfSSL_sk_X509_NAME_ENTRY_num(
16520
    const WOLF_STACK_OF(WOLFSSL_X509_NAME_ENTRY)* sk)
16521
{
16522
    if (sk == NULL)
16523
        return BAD_FUNC_ARG;
16524
    return (int)sk->num;
16525
}
16526
16527
void wolfSSL_sk_X509_NAME_ENTRY_free(WOLF_STACK_OF(WOLFSSL_X509_NAME_ENTRY)* sk)
16528
{
16529
    wolfSSL_sk_free(sk);
16530
}
16531
16532
#endif /* OPENSSL_EXTRA || HAVE_STUNNEL || WOLFSSL_NGINX ||
16533
            HAVE_LIGHTY || WOLFSSL_HAPROXY ||
16534
            WOLFSSL_OPENSSH || HAVE_SBLIM_SFCB */
16535
16536
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
16537
    (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
16538
    defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
16539
    defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB))
16540
16541
#if defined(OPENSSL_ALL)
16542
WOLFSSL_X509_INFO* wolfSSL_X509_INFO_new(void)
16543
{
16544
    WOLFSSL_X509_INFO* info;
16545
    info = (WOLFSSL_X509_INFO*)XMALLOC(sizeof(WOLFSSL_X509_INFO), NULL,
16546
        DYNAMIC_TYPE_X509);
16547
    if (info) {
16548
        XMEMSET(info, 0, sizeof(*info));
16549
    }
16550
    return info;
16551
}
16552
16553
void wolfSSL_X509_INFO_free(WOLFSSL_X509_INFO* info)
16554
{
16555
    if (info == NULL)
16556
        return;
16557
16558
    if (info->x509) {
16559
        wolfSSL_X509_free(info->x509);
16560
        info->x509 = NULL;
16561
    }
16562
#ifdef HAVE_CRL
16563
    if (info->crl) {
16564
        wolfSSL_X509_CRL_free(info->crl);
16565
        info->crl = NULL;
16566
    }
16567
#endif
16568
    wolfSSL_X509_PKEY_free(info->x_pkey);
16569
    info->x_pkey = NULL;
16570
16571
    XFREE(info, NULL, DYNAMIC_TYPE_X509);
16572
}
16573
#endif
16574
16575
WOLFSSL_STACK* wolfSSL_sk_X509_INFO_new_null(void)
16576
{
16577
    WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL);
16578
    if (sk) {
16579
        sk->type = STACK_TYPE_X509_INFO;
16580
    }
16581
    return sk;
16582
}
16583
16584
int wolfSSL_sk_X509_INFO_num(const WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk)
16585
{
16586
    WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_num");
16587
16588
    return wolfSSL_sk_num(sk);
16589
}
16590
16591
WOLFSSL_X509_INFO* wolfSSL_sk_X509_INFO_value(
16592
        const WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk, int i)
16593
{
16594
    WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_value");
16595
16596
    return (WOLFSSL_X509_INFO *)wolfSSL_sk_value(sk, i);
16597
}
16598
16599
WOLFSSL_X509_INFO* wolfSSL_sk_X509_INFO_pop(
16600
        WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk)
16601
{
16602
    return (WOLFSSL_X509_INFO*)wolfSSL_sk_pop(sk);
16603
}
16604
16605
#if defined(OPENSSL_ALL)
16606
void wolfSSL_sk_X509_INFO_pop_free(WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
16607
    void (*f) (WOLFSSL_X509_INFO*))
16608
{
16609
    WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_pop_free");
16610
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
16611
}
16612
16613
void wolfSSL_sk_X509_INFO_free(WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk)
16614
{
16615
    WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_free");
16616
    wolfSSL_sk_free(sk);
16617
}
16618
16619
/* Adds the WOLFSSL_X509_INFO to the stack "sk". "sk" takes control of "in" and
16620
 * tries to free it when the stack is free'd.
16621
 *
16622
 * return number of elements on success 0 on fail
16623
 */
16624
int wolfSSL_sk_X509_INFO_push(WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
16625
                                                      WOLFSSL_X509_INFO* in)
16626
{
16627
    return wolfSSL_sk_push(sk, in);
16628
}
16629
16630
/* Creates a duplicate of WOLF_STACK_OF(WOLFSSL_X509_NAME).
16631
 * Returns a new WOLF_STACK_OF(WOLFSSL_X509_NAME) or NULL on failure */
16632
WOLF_STACK_OF(WOLFSSL_X509_NAME) *wolfSSL_dup_CA_list(
16633
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk)
16634
{
16635
    int i;
16636
    const int num = wolfSSL_sk_X509_NAME_num(sk);
16637
    WOLF_STACK_OF(WOLFSSL_X509_NAME) *copy;
16638
    WOLFSSL_X509_NAME *name;
16639
16640
    WOLFSSL_ENTER("wolfSSL_dup_CA_list");
16641
16642
    copy = wolfSSL_sk_X509_NAME_new(NULL);
16643
    if (copy == NULL) {
16644
        WOLFSSL_MSG("Memory error");
16645
        return NULL;
16646
    }
16647
16648
    for (i = 0; i < num; i++) {
16649
        name = wolfSSL_X509_NAME_dup(wolfSSL_sk_X509_NAME_value(sk, i));
16650
        if (name == NULL || wolfSSL_sk_X509_NAME_push(copy, name) <= 0) {
16651
            WOLFSSL_MSG("Memory error");
16652
            wolfSSL_sk_X509_NAME_pop_free(copy, wolfSSL_X509_NAME_free);
16653
            wolfSSL_X509_NAME_free(name);
16654
            return NULL;
16655
        }
16656
    }
16657
16658
    return copy;
16659
}
16660
16661
void* wolfSSL_sk_X509_OBJECT_value(WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk,
16662
    int i)
16663
{
16664
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_value");
16665
    for (; sk != NULL && i > 0; i--)
16666
        sk = sk->next;
16667
16668
    if (i != 0 || sk == NULL)
16669
        return NULL;
16670
    return sk->data.x509_obj;
16671
}
16672
16673
int wolfSSL_sk_X509_OBJECT_num(const WOLF_STACK_OF(WOLFSSL_X509_OBJECT) *s)
16674
{
16675
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_num");
16676
    if (s) {
16677
        return (int)s->num;
16678
    }
16679
    else {
16680
        return 0;
16681
    }
16682
}
16683
16684
int wolfSSL_sk_X509_NAME_set_cmp_func(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk,
16685
    WOLF_SK_COMPARE_CB(WOLFSSL_X509_NAME, cb))
16686
{
16687
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_set_cmp_func");
16688
16689
    if (sk == NULL)
16690
        return BAD_FUNC_ARG;
16691
16692
    WOLFSSL_MSG("Stack comparison not used in wolfSSL");
16693
    (void)cb;
16694
    return 0;
16695
}
16696
#endif /* OPENSSL_ALL */
16697
16698
#ifndef NO_BIO
16699
16700
/* Helper function for X509_NAME_print_ex. Sets *buf to string for domain
16701
   name attribute based on NID. Returns size of buf */
16702
static int get_dn_attr_by_nid(int n, const char** buf)
16703
{
16704
    int len = 0;
16705
    const char *str;
16706
16707
    switch(n)
16708
    {
16709
        case WC_NID_commonName :
16710
            str = "CN";
16711
            len = 2;
16712
            break;
16713
        case WC_NID_countryName:
16714
            str = "C";
16715
            len = 1;
16716
            break;
16717
        case WC_NID_localityName:
16718
            str = "L";
16719
            len = 1;
16720
            break;
16721
        case WC_NID_stateOrProvinceName:
16722
            str = "ST";
16723
            len = 2;
16724
            break;
16725
        case WC_NID_streetAddress:
16726
            str = "street";
16727
            len = 6;
16728
            break;
16729
        case WC_NID_organizationName:
16730
            str = "O";
16731
            len = 1;
16732
            break;
16733
        case WC_NID_organizationalUnitName:
16734
            str = "OU";
16735
            len = 2;
16736
            break;
16737
        case WC_NID_postalCode:
16738
            str = "postalCode";
16739
            len = 10;
16740
            break;
16741
        case WC_NID_emailAddress:
16742
            str = "emailAddress";
16743
            len = 12;
16744
            break;
16745
        case WC_NID_surname:
16746
            str = "SN";
16747
            len = 2;
16748
            break;
16749
        case WC_NID_givenName:
16750
            str = "GN";
16751
            len = 2;
16752
            break;
16753
        case WC_NID_dnQualifier:
16754
            str = "dnQualifier";
16755
            len = 11;
16756
            break;
16757
        case WC_NID_name:
16758
            str = "name";
16759
            len = 4;
16760
            break;
16761
        case WC_NID_initials:
16762
            str = "initials";
16763
            len = 8;
16764
            break;
16765
        case WC_NID_domainComponent:
16766
            str = "DC";
16767
            len = 2;
16768
            break;
16769
        case WC_NID_pkcs9_contentType:
16770
            str = "contentType";
16771
            len = 11;
16772
            break;
16773
        case WC_NID_userId:
16774
            str = "UID";
16775
            len = 3;
16776
            break;
16777
        case WC_NID_x500UniqueIdentifier:
16778
            str = "x500UniqueIdentifier";
16779
            len = 20;
16780
            break;
16781
        case WC_NID_serialNumber:
16782
            str = "serialNumber";
16783
            len = 12;
16784
            break;
16785
        case WC_NID_title:
16786
            str = "title";
16787
            len = 5;
16788
            break;
16789
        case WC_NID_rfc822Mailbox:
16790
            str = "mail";
16791
            len = 4;
16792
            break;
16793
        default:
16794
            WOLFSSL_MSG("Attribute type not found");
16795
            str = NULL;
16796
16797
    }
16798
    if (buf != NULL)
16799
        *buf = str;
16800
    return len;
16801
}
16802
16803
/* Escape a name entry value. Mirrors OpenSSL's do_esc_char() for single
16804
 * byte characters. Only ASN1_STRFLGS_ESC_2253, ASN1_STRFLGS_ESC_CTRL and
16805
 * ASN1_STRFLGS_ESC_MSB are implemented. ASN1_STRFLGS_ESC_QUOTE does not
16806
 * quote but, as in OpenSSL, still causes the backslash to be escaped.
16807
 *
16808
 * in    - value to escape, may contain NUL bytes
16809
 * inSz  - length of in
16810
 * flags - ASN1_STRFLGS_* flags
16811
 * out   - buffer for escaped value, NULL to only get the length
16812
 *
16813
 * Returns number of bytes written, or needed when out is NULL.
16814
 */
16815
static int wolfssl_x509_name_esc_value(const char* in, int inSz,
16816
                                       unsigned long flags, char* out)
16817
{
16818
    static const char hexDigit[] = "0123456789ABCDEF";
16819
    const unsigned long escFlags = WOLFSSL_ASN1_STRFLGS_ESC_2253 |
16820
        WOLFSSL_ASN1_STRFLGS_ESC_CTRL | WOLFSSL_ASN1_STRFLGS_ESC_MSB |
16821
        WOLFSSL_ASN1_STRFLGS_ESC_QUOTE;
16822
    int i;
16823
    int outIdx = 0;
16824
16825
    for (i = 0; i < inSz; i++) {
16826
        unsigned char c = (unsigned char)in[i];
16827
        int hex = 0;
16828
        int bs = 0;
16829
16830
        if (c >= 0x80) {
16831
            hex = (flags & WOLFSSL_ASN1_STRFLGS_ESC_MSB) != 0;
16832
        }
16833
        else if ((flags & WOLFSSL_ASN1_STRFLGS_ESC_2253) &&
16834
                 (c == ',' || c == '+' || c == '"' || c == '\\' ||
16835
                  c == '<' || c == '>' || c == ';' ||
16836
                  (i == 0 && (c == ' ' || c == '#')) ||
16837
                  (i == inSz - 1 && c == ' '))) {
16838
            bs = 1;
16839
        }
16840
        else if ((flags & WOLFSSL_ASN1_STRFLGS_ESC_CTRL) &&
16841
                 (c < 0x20 || c == 0x7F)) {
16842
            hex = 1;
16843
        }
16844
        else if (c == '\\' && (flags & escFlags)) {
16845
            /* Any escaping means the escape character itself is escaped. */
16846
            bs = 1;
16847
        }
16848
16849
        if (hex) {
16850
            if (out != NULL) {
16851
                out[outIdx]     = '\\';
16852
                out[outIdx + 1] = hexDigit[c >> 4];
16853
                out[outIdx + 2] = hexDigit[c & 0x0F];
16854
            }
16855
            outIdx += 3;
16856
        }
16857
        else {
16858
            if (bs) {
16859
                if (out != NULL)
16860
                    out[outIdx] = '\\';
16861
                outIdx++;
16862
            }
16863
            if (out != NULL)
16864
                out[outIdx] = (char)c;
16865
            outIdx++;
16866
        }
16867
    }
16868
16869
    return outIdx;
16870
}
16871
16872
/*
16873
 * Print human readable version of X509_NAME to provided BIO.
16874
 *
16875
 * bio    - output BIO to place name string. Does not include null terminator.
16876
 * name   - input name to convert to string
16877
 * indent - number of indent spaces to prepend to name string, and to every
16878
 *          line with XN_FLAG_SEP_MULTILINE
16879
 * flags  - flags to control function behavior, as in OpenSSL:
16880
 *              XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_CPLUS_SPC,
16881
 *              XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MULTILINE - entry
16882
 *                                      separator, ", " when none is set
16883
 *              XN_FLAG_FN_SN, XN_FLAG_FN_LN, XN_FLAG_FN_NONE - attribute
16884
 *                                      name style, XN_FLAG_FN_OID prints
16885
 *                                      short names
16886
 *              XN_FLAG_FN_ALIGN      - pad the attribute name
16887
 *              XN_FLAG_DN_REV        - print name reversed
16888
 *              XN_FLAG_SPC_EQ        - spaces before and after '='
16889
 *              ASN1_STRFLGS_ESC_2253 - backslash escape the RFC 2253
16890
 *                                      special characters in values
16891
 *              ASN1_STRFLGS_ESC_CTRL - escape control characters as \XX
16892
 *              ASN1_STRFLGS_ESC_MSB  - escape bytes above 0x7F as \XX
16893
 *          Multi-valued RDNs are flattened: their attributes are separated
16894
 *          like RDNs.
16895
 *
16896
 * Returns WOLFSSL_SUCCESS (1) on success, WOLFSSL_FAILURE (0) on failure.
16897
 */
16898
int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name,
16899
                int indent, unsigned long flags)
16900
{
16901
    int i, count = 0;
16902
    int eqSz = 1;
16903
    const char* eqStr = "=";
16904
    int sepSz = 2;
16905
    const char* sep = ", ";
16906
    int lineIndent = 0;
16907
    int fnOpt;
16908
    int fnWidth = 0;
16909
    WOLFSSL_X509_NAME_ENTRY* ne;
16910
    WOLFSSL_ASN1_STRING* str;
16911
16912
    WOLFSSL_ENTER("wolfSSL_X509_NAME_print_ex");
16913
16914
    if ((name == NULL) || (bio == NULL))
16915
        return WOLFSSL_FAILURE;
16916
16917
    if (indent < 0)
16918
        indent = 0;
16919
16920
    switch (flags & WOLFSSL_XN_FLAG_SEP_MASK) {
16921
        case WOLFSSL_XN_FLAG_SEP_COMMA_PLUS:
16922
            sep = ",";
16923
            sepSz = 1;
16924
            break;
16925
        case WOLFSSL_XN_FLAG_SEP_SPLUS_SPC:
16926
            sep = "; ";
16927
            sepSz = 2;
16928
            break;
16929
        case WOLFSSL_XN_FLAG_SEP_MULTILINE:
16930
            sep = "\n";
16931
            sepSz = 1;
16932
            lineIndent = indent;
16933
            break;
16934
        default:
16935
            /* XN_FLAG_SEP_CPLUS_SPC or no separator flag */
16936
            break;
16937
    }
16938
16939
    if (flags & WOLFSSL_XN_FLAG_SPC_EQ) {
16940
        eqStr = " = ";
16941
        eqSz = 3;
16942
    }
16943
16944
    fnOpt = (int)(flags & WOLFSSL_XN_FLAG_FN_MASK);
16945
    if (flags & WOLFSSL_XN_FLAG_FN_ALIGN) {
16946
        if (fnOpt == WOLFSSL_XN_FLAG_FN_SN)
16947
            fnWidth = 10;
16948
        else if (fnOpt == WOLFSSL_XN_FLAG_FN_LN)
16949
            fnWidth = 25;
16950
    }
16951
16952
    for (i = 0; i < indent; i++) {
16953
        if (wolfSSL_BIO_write(bio, " ", 1) != 1)
16954
            return WOLFSSL_FAILURE;
16955
    }
16956
16957
    count = wolfSSL_X509_NAME_entry_count(name);
16958
16959
    for (i = 0; i < count; i++) {
16960
        const char* attr = NULL;
16961
        int attrSz = 0;
16962
        int padSz = 0;
16963
        int valSz;
16964
        int tmpSz;
16965
        int idx;
16966
        int j;
16967
        char* tmp;
16968
16969
        if (flags & WOLFSSL_XN_FLAG_DN_REV) {
16970
            ne = wolfSSL_X509_NAME_get_entry(name, count - i - 1);
16971
        }
16972
        else {
16973
            ne = wolfSSL_X509_NAME_get_entry(name, i);
16974
        }
16975
        if (ne == NULL)
16976
            return WOLFSSL_FAILURE;
16977
16978
        str = wolfSSL_X509_NAME_ENTRY_get_data(ne);
16979
        if (str == NULL)
16980
            return WOLFSSL_FAILURE;
16981
16982
        if (fnOpt == WOLFSSL_XN_FLAG_FN_NONE) {
16983
            /* no attribute name */
16984
        }
16985
#ifdef OPENSSL_EXTRA
16986
        else if (fnOpt == WOLFSSL_XN_FLAG_FN_LN) {
16987
            attr = wolfSSL_OBJ_nid2ln(ne->nid);
16988
            if (attr == NULL)
16989
                return WOLFSSL_FAILURE;
16990
            attrSz = (int)XSTRLEN(attr);
16991
        }
16992
#endif
16993
        else {
16994
            /* attrSz is without null terminator */
16995
            attrSz = get_dn_attr_by_nid(ne->nid, &attr);
16996
            if (attrSz == 0 || attr == NULL)
16997
                return WOLFSSL_FAILURE;
16998
        }
16999
        if (attrSz < fnWidth)
17000
            padSz = fnWidth - attrSz;
17001
17002
        /* escaping can triple the value length */
17003
        if (str->length < 0 || str->length > INT_MAX / 4)
17004
            return WOLFSSL_FAILURE;
17005
17006
        valSz = wolfssl_x509_name_esc_value(str->data, str->length, flags,
17007
                                            NULL);
17008
17009
        /* attribute, padding, '=', value and separator, +1 for empty */
17010
        tmpSz = attrSz + padSz + eqSz + valSz + sepSz + 1;
17011
        tmp = (char*)XMALLOC((size_t)tmpSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
17012
        if (tmp == NULL)
17013
            return WOLFSSL_FAILURE;
17014
17015
        idx = 0;
17016
        if (fnOpt != WOLFSSL_XN_FLAG_FN_NONE) {
17017
            XMEMCPY(tmp, attr, (size_t)attrSz);
17018
            idx = attrSz;
17019
            XMEMSET(tmp + idx, ' ', (size_t)padSz);
17020
            idx += padSz;
17021
            XMEMCPY(tmp + idx, eqStr, (size_t)eqSz);
17022
            idx += eqSz;
17023
        }
17024
        (void)wolfssl_x509_name_esc_value(str->data, str->length, flags,
17025
                                          tmp + idx);
17026
        idx += valSz;
17027
        if (i < count - 1) {
17028
            XMEMCPY(tmp + idx, sep, (size_t)sepSz);
17029
            idx += sepSz;
17030
        }
17031
17032
        if (wolfSSL_BIO_write(bio, tmp, idx) != idx) {
17033
            XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
17034
            return WOLFSSL_FAILURE;
17035
        }
17036
17037
        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
17038
17039
        if (i < count - 1) {
17040
            for (j = 0; j < lineIndent; j++) {
17041
                if (wolfSSL_BIO_write(bio, " ", 1) != 1)
17042
                    return WOLFSSL_FAILURE;
17043
            }
17044
        }
17045
    }
17046
17047
    return WOLFSSL_SUCCESS;
17048
}
17049
17050
#ifndef NO_FILESYSTEM
17051
int wolfSSL_X509_NAME_print_ex_fp(XFILE file, WOLFSSL_X509_NAME* name,
17052
        int indent, unsigned long flags)
17053
{
17054
    WOLFSSL_BIO* bio;
17055
    int ret;
17056
17057
    WOLFSSL_ENTER("wolfSSL_X509_NAME_print_ex_fp");
17058
17059
    if (!(bio = wolfSSL_BIO_new_fp(file, WOLFSSL_BIO_NOCLOSE))) {
17060
        WOLFSSL_MSG("wolfSSL_BIO_new_fp error");
17061
        return WOLFSSL_FAILURE;
17062
    }
17063
17064
    ret = wolfSSL_X509_NAME_print_ex(bio, name, indent, flags);
17065
17066
    wolfSSL_BIO_free(bio);
17067
17068
    return ret;
17069
}
17070
#endif /* NO_FILESYSTEM */
17071
#endif /* !NO_BIO */
17072
17073
#ifndef NO_WOLFSSL_STUB
17074
WOLFSSL_ASN1_BIT_STRING* wolfSSL_X509_get0_pubkey_bitstr(const WOLFSSL_X509* x)
17075
{
17076
    (void)x;
17077
    WOLFSSL_ENTER("wolfSSL_X509_get0_pubkey_bitstr");
17078
    WOLFSSL_STUB("X509_get0_pubkey_bitstr");
17079
17080
    return NULL;
17081
}
17082
#endif
17083
17084
#ifdef OPENSSL_ALL
17085
WOLFSSL_X509_LOOKUP_TYPE wolfSSL_X509_OBJECT_get_type(
17086
        const WOLFSSL_X509_OBJECT* obj)
17087
{
17088
    if (obj == NULL)
17089
        return WOLFSSL_X509_LU_NONE;
17090
    return obj->type;
17091
}
17092
17093
WOLFSSL_X509_OBJECT* wolfSSL_X509_OBJECT_new(void)
17094
{
17095
    WOLFSSL_X509_OBJECT* ret = (WOLFSSL_X509_OBJECT*)
17096
            XMALLOC(sizeof(WOLFSSL_X509_OBJECT), NULL, DYNAMIC_TYPE_OPENSSL);
17097
    if (ret != NULL)
17098
        XMEMSET(ret, 0, sizeof(WOLFSSL_X509_OBJECT));
17099
    return ret;
17100
}
17101
17102
void wolfSSL_X509_OBJECT_free(WOLFSSL_X509_OBJECT *obj)
17103
{
17104
    WOLFSSL_ENTER("wolfSSL_X509_OBJECT_free");
17105
    if (obj != NULL) {
17106
        if (obj->type == WOLFSSL_X509_LU_X509) {
17107
            wolfSSL_X509_free(obj->data.x509);
17108
        }
17109
    #ifdef HAVE_CRL
17110
        else if (obj->type == WOLFSSL_X509_LU_CRL) {
17111
            wolfSSL_X509_CRL_free(obj->data.crl);
17112
        }
17113
    #endif
17114
        else {
17115
            /* We don't free as this will point to
17116
             * store->cm->crl which we don't own */
17117
            WOLFSSL_MSG("Not free'ing CRL in WOLFSSL_X509_OBJECT");
17118
        }
17119
        XFREE(obj, NULL, DYNAMIC_TYPE_OPENSSL);
17120
    }
17121
}
17122
17123
WOLFSSL_X509_OBJECT *wolfSSL_X509_OBJECT_retrieve_by_subject(
17124
        WOLF_STACK_OF(WOLFSSL_X509_OBJECT) *sk,
17125
        WOLFSSL_X509_LOOKUP_TYPE type,
17126
        WOLFSSL_X509_NAME *name)
17127
{
17128
    int i;
17129
17130
    WOLFSSL_ENTER("wolfSSL_X509_OBJECT_retrieve_by_subject");
17131
17132
    if (sk == NULL || name == NULL)
17133
        return NULL;
17134
17135
    for (i = 0; i < wolfSSL_sk_X509_OBJECT_num(sk); i++) {
17136
        WOLFSSL_X509_OBJECT* obj = (WOLFSSL_X509_OBJECT *)
17137
            wolfSSL_sk_X509_OBJECT_value(sk, i);
17138
        if (obj != NULL && obj->type == type &&
17139
            wolfSSL_X509_NAME_cmp(
17140
                wolfSSL_X509_get_subject_name(obj->data.x509), name) == 0)
17141
            return obj;
17142
    }
17143
    return NULL;
17144
}
17145
#endif /* OPENSSL_ALL */
17146
17147
#ifndef NO_WOLFSSL_STUB
17148
WOLFSSL_X509_OBJECT* wolfSSL_sk_X509_OBJECT_delete(
17149
    WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk, int i)
17150
{
17151
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_delete");
17152
    WOLFSSL_STUB("wolfSSL_sk_X509_OBJECT_delete");
17153
    (void)sk;
17154
    (void)i;
17155
    return NULL;
17156
}
17157
#endif
17158
17159
WOLFSSL_X509 *wolfSSL_X509_OBJECT_get0_X509(const WOLFSSL_X509_OBJECT *obj)
17160
{
17161
    if (obj != NULL && obj->type == WOLFSSL_X509_LU_X509)
17162
        return obj->data.x509;
17163
    return NULL;
17164
}
17165
17166
WOLFSSL_X509_CRL *wolfSSL_X509_OBJECT_get0_X509_CRL(WOLFSSL_X509_OBJECT *obj)
17167
{
17168
    if (obj != NULL && obj->type == WOLFSSL_X509_LU_CRL)
17169
        return obj->data.crl;
17170
    return NULL;
17171
}
17172
17173
#endif /* OPENSSL_ALL || (OPENSSL_EXTRA && (HAVE_STUNNEL || WOLFSSL_NGINX ||
17174
        * HAVE_LIGHTY || WOLFSSL_HAPROXY || WOLFSSL_OPENSSH ||
17175
        * HAVE_SBLIM_SFCB)) */
17176
17177
17178
#if defined(OPENSSL_EXTRA)
17179
17180
int wolfSSL_sk_X509_num(const WOLF_STACK_OF(WOLFSSL_X509) *s)
17181
{
17182
    WOLFSSL_ENTER("wolfSSL_sk_X509_num");
17183
17184
    if (s == NULL)
17185
        return WOLFSSL_FATAL_ERROR;
17186
    return (int)s->num;
17187
}
17188
17189
#endif /* OPENSSL_EXTRA */
17190
17191
#ifdef HAVE_EX_DATA_CRYPTO
17192
int wolfSSL_X509_get_ex_new_index(int idx, void *arg,
17193
                                  WOLFSSL_CRYPTO_EX_new* new_func,
17194
                                  WOLFSSL_CRYPTO_EX_dup* dup_func,
17195
                                  WOLFSSL_CRYPTO_EX_free* free_func)
17196
{
17197
    WOLFSSL_ENTER("wolfSSL_X509_get_ex_new_index");
17198
17199
    return wolfssl_local_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_X509, idx, arg,
17200
                                    new_func, dup_func, free_func);
17201
}
17202
#endif
17203
17204
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
17205
void *wolfSSL_X509_get_ex_data(WOLFSSL_X509 *x509, int idx)
17206
{
17207
    WOLFSSL_ENTER("wolfSSL_X509_get_ex_data");
17208
#ifdef HAVE_EX_DATA
17209
    if (x509 != NULL) {
17210
        return wolfSSL_CRYPTO_get_ex_data(&x509->ex_data, idx);
17211
    }
17212
#else
17213
    (void)x509;
17214
    (void)idx;
17215
#endif
17216
    return NULL;
17217
}
17218
17219
int wolfSSL_X509_set_ex_data(WOLFSSL_X509 *x509, int idx, void *data)
17220
{
17221
    WOLFSSL_ENTER("wolfSSL_X509_set_ex_data");
17222
#ifdef HAVE_EX_DATA
17223
    if (x509 != NULL) {
17224
        return wolfSSL_CRYPTO_set_ex_data(&x509->ex_data, idx, data);
17225
    }
17226
#else
17227
    (void)x509;
17228
    (void)idx;
17229
    (void)data;
17230
#endif
17231
    return WOLFSSL_FAILURE;
17232
}
17233
17234
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
17235
int wolfSSL_X509_set_ex_data_with_cleanup(
17236
    WOLFSSL_X509 *x509,
17237
    int idx,
17238
    void *data,
17239
    wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
17240
{
17241
    WOLFSSL_ENTER("wolfSSL_X509_set_ex_data_with_cleanup");
17242
    if (x509 != NULL)
17243
    {
17244
        return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&x509->ex_data, idx,
17245
                                                       data, cleanup_routine);
17246
    }
17247
    return WOLFSSL_FAILURE;
17248
}
17249
#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
17250
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
17251
17252
17253
#ifndef NO_ASN
17254
int wolfSSL_X509_check_host(WOLFSSL_X509 *x, const char *chk, size_t chklen,
17255
                    unsigned int flags, char **peername)
17256
0
{
17257
0
    int         ret;
17258
0
    size_t      i;
17259
0
    WC_DECLARE_VAR(dCert, DecodedCert, 1, 0);
17260
17261
0
    WOLFSSL_ENTER("wolfSSL_X509_check_host");
17262
17263
    /* flags and peername not needed for Nginx. */
17264
0
    (void)peername;
17265
17266
0
    if ((x == NULL) || (chk == NULL)) {
17267
0
        WOLFSSL_MSG("Invalid parameter");
17268
0
        return WOLFSSL_FAILURE;
17269
0
    }
17270
17271
0
    if (flags & WOLFSSL_NO_WILDCARDS) {
17272
0
        WOLFSSL_MSG("X509_CHECK_FLAG_NO_WILDCARDS not yet implemented");
17273
0
        return WOLFSSL_FAILURE;
17274
0
    }
17275
0
    if (flags & WOLFSSL_NO_PARTIAL_WILDCARDS) {
17276
0
        WOLFSSL_MSG("X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS not yet implemented");
17277
0
        return WOLFSSL_FAILURE;
17278
0
    }
17279
0
    if (flags & WOLFSSL_MULTI_LABEL_WILDCARDS) {
17280
0
        WOLFSSL_MSG("X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS not yet implemented");
17281
0
        return WOLFSSL_FAILURE;
17282
0
    }
17283
17284
0
#ifdef WOLFSSL_SMALL_STACK
17285
0
    dCert = (DecodedCert *)XMALLOC(sizeof(*dCert), x->heap,
17286
0
                                   DYNAMIC_TYPE_DCERT);
17287
0
    if (dCert == NULL) {
17288
0
        WOLFSSL_MSG("\tout of memory");
17289
0
        return WOLFSSL_FATAL_ERROR;
17290
0
    }
17291
0
#endif
17292
17293
0
    InitDecodedCert(dCert, x->derCert->buffer, x->derCert->length, NULL);
17294
0
    ret = ParseCertRelative(dCert, CERT_TYPE, 0, NULL, NULL);
17295
0
    if (ret != 0) {
17296
0
        goto out;
17297
0
    }
17298
17299
    /* Replicate openssl behavior for checklen */
17300
0
    if (chklen == 0) {
17301
0
        chklen = (size_t)(XSTRLEN(chk));
17302
0
    }
17303
0
    else {
17304
0
        for (i = 0; i < (chklen > 1 ? chklen - 1 : chklen); i++) {
17305
0
            if (chk[i] == '\0') {
17306
0
                ret = WOLFSSL_FATAL_ERROR;
17307
0
                goto out;
17308
0
            }
17309
0
        }
17310
0
    }
17311
0
    if (chklen > 1 && (chk[chklen - 1] == '\0')) {
17312
0
        chklen--;
17313
0
    }
17314
17315
#ifdef WOLFSSL_IP_ALT_NAME
17316
    ret = CheckIPAddr(dCert, (char *)chk, chklen);
17317
    if (ret == 0) {
17318
        goto out;
17319
    }
17320
#endif /* WOLFSSL_IP_ALT_NAME */
17321
17322
0
    ret = CheckHostName(dCert, (char *)chk, chklen, flags, 0);
17323
17324
0
out:
17325
17326
0
    FreeDecodedCert(dCert);
17327
0
    WC_FREE_VAR_EX(dCert, x->heap, DYNAMIC_TYPE_DCERT);
17328
17329
0
    if (ret != 0)
17330
0
        return WOLFSSL_FAILURE;
17331
0
    return WOLFSSL_SUCCESS;
17332
0
}
17333
17334
17335
int wolfSSL_X509_check_ip_asc(WOLFSSL_X509 *x, const char *ipasc,
17336
        unsigned int flags)
17337
0
{
17338
0
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
17339
0
    WC_DECLARE_VAR(dCert, DecodedCert, 1, 0);
17340
17341
0
    WOLFSSL_ENTER("wolfSSL_X509_check_ip_asc");
17342
17343
    /* flags not yet implemented */
17344
0
    (void)flags;
17345
17346
0
    if ((x == NULL) || (x->derCert == NULL) || (ipasc == NULL)) {
17347
0
        WOLFSSL_MSG("Invalid parameter");
17348
0
    }
17349
0
    else {
17350
0
        ret = WOLFSSL_SUCCESS;
17351
0
    }
17352
17353
0
#ifdef WOLFSSL_SMALL_STACK
17354
0
    if (ret == WOLFSSL_SUCCESS) {
17355
0
        dCert = (DecodedCert *)XMALLOC(sizeof(*dCert), x->heap,
17356
0
                                       DYNAMIC_TYPE_DCERT);
17357
0
        if (dCert == NULL) {
17358
0
            WOLFSSL_MSG("\tout of memory");
17359
0
            ret = WOLFSSL_FAILURE;
17360
0
        }
17361
0
    }
17362
0
#endif
17363
17364
0
    if (ret == WOLFSSL_SUCCESS) {
17365
0
        InitDecodedCert(dCert, x->derCert->buffer, x->derCert->length, NULL);
17366
0
        ret = ParseCertRelative(dCert, CERT_TYPE, 0, NULL, NULL);
17367
0
        if (ret != 0) {
17368
0
            ret = WOLFSSL_FAILURE;
17369
0
        }
17370
0
        else {
17371
0
            ret = CheckIPAddr(dCert, ipasc, (size_t)XSTRLEN(ipasc));
17372
0
            if (ret != 0) {
17373
0
                ret = WOLFSSL_FAILURE;
17374
0
            }
17375
0
            else {
17376
0
                ret = WOLFSSL_SUCCESS;
17377
0
            }
17378
0
        }
17379
0
        FreeDecodedCert(dCert);
17380
0
    }
17381
17382
0
#ifdef WOLFSSL_SMALL_STACK
17383
0
    if (x != NULL) {
17384
0
        XFREE(dCert, x->heap, DYNAMIC_TYPE_DCERT);
17385
0
    }
17386
0
#endif
17387
17388
0
    return ret;
17389
0
}
17390
#endif
17391
17392
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN)
17393
/* Compare a certificate email address against chk (which must not contain
17394
 * NULs) as RFC 5280 7.5 requires: the local-part exactly and the domain after
17395
 * the last '@' case-insensitively.
17396
 *
17397
 * returns 1 on a match and 0 otherwise.
17398
 */
17399
static int X509EmailMatch(const char *email, size_t emailLen, const char *chk,
17400
                          size_t chkLen)
17401
{
17402
    size_t at;
17403
17404
    if (emailLen != chkLen)
17405
        return 0;
17406
17407
    /* at is the index just past the last '@' in chk, or 0 when there is
17408
     * none. */
17409
    for (at = chkLen; at > 0 && chk[at - 1] != '@'; at--)
17410
        ;
17411
17412
    return (XMEMCMP(email, chk, at) == 0) &&
17413
           (XSTRNCASECMP(email + at, chk + at, chkLen - at) == 0);
17414
}
17415
17416
int wolfSSL_X509_check_email(WOLFSSL_X509 *x, const char *chk, size_t chkLen,
17417
                             unsigned int flags)
17418
{
17419
    WOLFSSL_X509_NAME *subjName;
17420
    int emailLen;
17421
    char *emailBuf;
17422
    DNS_entry *entry;
17423
    int haveSanEmail = 0;
17424
    size_t i;
17425
17426
    (void)flags;
17427
17428
    WOLFSSL_ENTER("wolfSSL_X509_check_email");
17429
17430
    if ((x == NULL) || (chk == NULL)) {
17431
        WOLFSSL_MSG("Invalid parameter");
17432
        return WOLFSSL_FAILURE;
17433
    }
17434
17435
    /* Replicate openssl behavior for chkLen: reject embedded NULs and drop a
17436
     * single trailing NUL. */
17437
    if (chkLen == 0) {
17438
        chkLen = XSTRLEN(chk);
17439
    }
17440
    else {
17441
        for (i = 0; i < (chkLen > 1 ? chkLen - 1 : chkLen); i++) {
17442
            if (chk[i] == '\0') {
17443
                WOLFSSL_MSG("Embedded NUL in email address");
17444
                return WOLFSSL_FAILURE;
17445
            }
17446
        }
17447
        if (chkLen > 1 && chk[chkLen - 1] == '\0')
17448
            chkLen--;
17449
    }
17450
17451
    /* rfc822Name SANs take precedence: the subject emailAddress is only
17452
     * checked when the certificate has none (RFC 6125 6.4.4). */
17453
    for (entry = x->altNames; entry != NULL; entry = entry->next) {
17454
        if (entry->type == ASN_RFC822_TYPE) {
17455
            haveSanEmail = 1;
17456
            if (entry->len >= 0 && X509EmailMatch(entry->name,
17457
                    (size_t)entry->len, chk, chkLen)) {
17458
                return WOLFSSL_SUCCESS;
17459
            }
17460
        }
17461
    }
17462
    if (haveSanEmail)
17463
        return WOLFSSL_FAILURE;
17464
17465
#if defined(IGNORE_NAME_CONSTRAINTS) || \
17466
    (defined(WOLFSSL_X509_TINY) && !defined(WOLFSSL_X509_TINY_SAN_EMAIL))
17467
    /* rfc822Name SANs are not kept when a certificate is decoded in this
17468
     * build, so a SAN extension may hold email identities that cannot be seen
17469
     * here. Do not fall back to the subject when one is present. */
17470
    if (x->subjAltNameSet) {
17471
        WOLFSSL_MSG("rfc822Name SANs not available, not checking subject");
17472
        return WOLFSSL_FAILURE;
17473
    }
17474
#endif
17475
17476
    subjName = wolfSSL_X509_get_subject_name(x);
17477
    if (subjName == NULL)
17478
        return WOLFSSL_FAILURE;
17479
17480
    /* Call with NULL buffer to get required length. */
17481
    emailLen = wolfSSL_X509_NAME_get_text_by_NID(subjName, WC_NID_emailAddress,
17482
                                                 NULL, 0);
17483
    if (emailLen < 0)
17484
        return WOLFSSL_FAILURE;
17485
17486
    ++emailLen; /* Add 1 for the NUL. */
17487
17488
    emailBuf = (char*)XMALLOC(emailLen, x->heap, DYNAMIC_TYPE_OPENSSL);
17489
    if (emailBuf == NULL)
17490
        return WOLFSSL_FAILURE;
17491
17492
    emailLen = wolfSSL_X509_NAME_get_text_by_NID(subjName, WC_NID_emailAddress,
17493
                                                 emailBuf, emailLen);
17494
    if (emailLen < 0) {
17495
        XFREE(emailBuf, x->heap, DYNAMIC_TYPE_OPENSSL);
17496
        return WOLFSSL_FAILURE;
17497
    }
17498
17499
    if (!X509EmailMatch(emailBuf, (size_t)emailLen, chk, chkLen)) {
17500
        XFREE(emailBuf, x->heap, DYNAMIC_TYPE_OPENSSL);
17501
        return WOLFSSL_FAILURE;
17502
    }
17503
17504
    XFREE(emailBuf, x->heap, DYNAMIC_TYPE_OPENSSL);
17505
    return WOLFSSL_SUCCESS;
17506
}
17507
#endif /* OPENSSL_EXTRA && WOLFSSL_CERT_GEN */
17508
17509
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \
17510
    || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY)
17511
17512
int wolfSSL_X509_NAME_digest(const WOLFSSL_X509_NAME *name,
17513
        const WOLFSSL_EVP_MD *type, unsigned char *md, unsigned int *len)
17514
{
17515
    WOLFSSL_ENTER("wolfSSL_X509_NAME_digest");
17516
17517
    if (name == NULL || type == NULL)
17518
        return WOLFSSL_FAILURE;
17519
17520
/* wolfSSL_EVP_Digest() is only compiled with these defines. */
17521
#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL)
17522
    return wolfSSL_EVP_Digest((unsigned char*)name->name,
17523
                              name->sz, md, len, type, NULL);
17524
#else
17525
    (void)md;
17526
    (void)len;
17527
    return NOT_COMPILED_IN;
17528
#endif
17529
}
17530
17531
#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY ||
17532
    OPENSSL_EXTRA || HAVE_LIGHTY */
17533
17534
#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
17535
    defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
17536
17537
void wolfSSL_X509_email_free(WOLF_STACK_OF(WOLFSSL_STRING) *sk)
17538
{
17539
    wolfSSL_sk_pop_free(sk, NULL);
17540
}
17541
17542
static int x509_aia_append_string(WOLFSSL_STACK* list, const byte* uri,
17543
        word32 uriSz)
17544
{
17545
    WOLFSSL_STRING url = (WOLFSSL_STRING)XMALLOC(uriSz + 1, NULL,
17546
            DYNAMIC_TYPE_OPENSSL);
17547
    if (url == NULL)
17548
        return -1;
17549
    XMEMCPY(url, uri, uriSz);
17550
    url[uriSz] = '\0';
17551
17552
    if (wolfSSL_sk_push(list, url) <= 0) {
17553
        XFREE(url, NULL, DYNAMIC_TYPE_OPENSSL);
17554
        return -1;
17555
    }
17556
17557
    return 0;
17558
}
17559
17560
static WOLFSSL_STACK* x509_get1_aia_by_method(WOLFSSL_X509* x, word32 method,
17561
    const byte* fallback, int fallbackSz)
17562
{
17563
    WOLFSSL_STACK* ret = NULL;
17564
    int i;
17565
17566
    if (x == NULL)
17567
        return NULL;
17568
17569
    ret = wolfSSL_sk_WOLFSSL_STRING_new();
17570
    if (ret == NULL)
17571
        return NULL;
17572
17573
    /* Build from multi-entry list when available; otherwise fall back to the
17574
     * legacy single-entry fields to preserve previous behavior. */
17575
    if (x->authInfoListSz > 0) {
17576
        for (i = 0; i < x->authInfoListSz; i++) {
17577
            if (x->authInfoList[i].method != method ||
17578
                    x->authInfoList[i].uri == NULL ||
17579
                    x->authInfoList[i].uriSz == 0) {
17580
                continue;
17581
            }
17582
17583
            if (x509_aia_append_string(ret, x->authInfoList[i].uri,
17584
                    x->authInfoList[i].uriSz) != 0) {
17585
                wolfSSL_X509_email_free(ret);
17586
                return NULL;
17587
            }
17588
        }
17589
    }
17590
    /* Only use fallback when nothing was found in the list */
17591
    if (wolfSSL_sk_num(ret) == 0 && fallback != NULL && fallbackSz > 0) {
17592
        if (x509_aia_append_string(ret, fallback, (word32)fallbackSz) != 0) {
17593
            wolfSSL_X509_email_free(ret);
17594
            return NULL;
17595
        }
17596
    }
17597
17598
    /* Return NULL when empty */
17599
    if (wolfSSL_sk_num(ret) == 0) {
17600
        wolfSSL_X509_email_free(ret);
17601
        ret = NULL;
17602
    }
17603
17604
    return ret;
17605
}
17606
17607
WOLF_STACK_OF(WOLFSSL_STRING) *wolfSSL_X509_get1_ocsp(WOLFSSL_X509 *x)
17608
{
17609
    if (x == NULL)
17610
        return NULL;
17611
    return x509_get1_aia_by_method(x, AIA_OCSP_OID, x->authInfo, x->authInfoSz);
17612
}
17613
17614
int wolfSSL_X509_get_aia_overflow(WOLFSSL_X509 *x)
17615
{
17616
    int overflow = 0;
17617
17618
    WOLFSSL_ENTER("wolfSSL_X509_get_aia_overflow");
17619
17620
    if (x != NULL) {
17621
        overflow = x->authInfoListOverflow;
17622
    }
17623
17624
    WOLFSSL_LEAVE("wolfSSL_X509_get_aia_overflow", overflow);
17625
17626
    return overflow;
17627
}
17628
17629
#ifdef WOLFSSL_ASN_CA_ISSUER
17630
WOLF_STACK_OF(WOLFSSL_STRING) *wolfSSL_X509_get1_ca_issuers(WOLFSSL_X509 *x)
17631
{
17632
    if (x == NULL)
17633
        return NULL;
17634
    return x509_get1_aia_by_method(x, AIA_CA_ISSUER_OID, x->authInfoCaIssuer,
17635
            x->authInfoCaIssuerSz);
17636
}
17637
#endif /* WOLFSSL_ASN_CA_ISSUER */
17638
17639
int wolfSSL_X509_check_issued(WOLFSSL_X509 *issuer, WOLFSSL_X509 *subject)
17640
{
17641
    WOLFSSL_X509_NAME *issuerName = wolfSSL_X509_get_issuer_name(subject);
17642
    WOLFSSL_X509_NAME *subjectName = wolfSSL_X509_get_subject_name(issuer);
17643
17644
    if (issuerName == NULL || subjectName == NULL)
17645
        return WOLFSSL_X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
17646
17647
    /* Literal matching of encoded names and key ids. */
17648
    if (issuerName->sz != subjectName->sz ||
17649
           XMEMCMP(issuerName->name, subjectName->name, subjectName->sz) != 0) {
17650
        return WOLFSSL_X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
17651
    }
17652
17653
    if (subject->authKeyId != NULL && issuer->subjKeyId != NULL) {
17654
        if (subject->authKeyIdSz != issuer->subjKeyIdSz ||
17655
                XMEMCMP(subject->authKeyId, issuer->subjKeyId,
17656
                        issuer->subjKeyIdSz) != 0) {
17657
            return WOLFSSL_X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
17658
        }
17659
    }
17660
17661
    return WOLFSSL_X509_V_OK;
17662
}
17663
17664
#endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */
17665
17666
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
17667
    defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
17668
WOLFSSL_X509* wolfSSL_X509_dup(WOLFSSL_X509 *x)
17669
{
17670
    WOLFSSL_ENTER("wolfSSL_X509_dup");
17671
17672
    if (x == NULL) {
17673
        WOLFSSL_MSG("Error: NULL input");
17674
        return NULL;
17675
    }
17676
17677
    if (x->derCert == NULL) {
17678
        WOLFSSL_MSG("Error: NULL derCert parameter");
17679
        return NULL;
17680
    }
17681
17682
    return wolfSSL_X509_d2i_ex(NULL, x->derCert->buffer, x->derCert->length,
17683
        x->heap);
17684
}
17685
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || KEEP_PEER_CERT || \
17686
          SESSION_CERTS */
17687
17688
#if defined(OPENSSL_EXTRA)
17689
int wolfSSL_X509_check_ca(WOLFSSL_X509 *x509)
17690
{
17691
    WOLFSSL_ENTER("wolfSSL_X509_check_ca");
17692
17693
    if (x509 == NULL)
17694
        return WOLFSSL_FAILURE;
17695
    if (x509->isCa)
17696
        return 1;
17697
    if (x509->extKeyUsageCrit)
17698
        return 4;
17699
17700
    return 0;
17701
}
17702
#endif /* OPENSSL_EXTRA */
17703
17704
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
17705
long wolfSSL_X509_get_version(const WOLFSSL_X509 *x509)
17706
{
17707
    int version = 0;
17708
17709
    WOLFSSL_ENTER("wolfSSL_X509_get_version");
17710
17711
    if (x509 == NULL) {
17712
        WOLFSSL_MSG("invalid parameter");
17713
        return 0L;
17714
    }
17715
    version = x509->version;
17716
    if (version != 0)
17717
        return (long)version - 1L;
17718
17719
    return 0L;
17720
}
17721
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
17722
17723
#if defined(OPENSSL_EXTRA)
17724
int wolfSSL_X509_get_signature_nid(const WOLFSSL_X509 *x)
17725
{
17726
    if (x == NULL)
17727
        return 0;
17728
17729
    return oid2nid((word32)x->sigOID, oidSigType);
17730
}
17731
#endif  /* OPENSSL_EXTRA */
17732
17733
#if defined(OPENSSL_EXTRA)
17734
WOLFSSL_STACK* wolfSSL_sk_X509_new(WOLF_SK_COMPARE_CB(WOLFSSL_X509, cb))
17735
{
17736
    (void)cb;
17737
    return wolfSSL_sk_X509_new_null();
17738
}
17739
17740
WOLFSSL_STACK* wolfSSL_sk_X509_new_null(void)
17741
{
17742
    WOLFSSL_STACK* s = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
17743
            DYNAMIC_TYPE_OPENSSL);
17744
    if (s != NULL) {
17745
        XMEMSET(s, 0, sizeof(*s));
17746
        s->type = STACK_TYPE_X509;
17747
    }
17748
17749
    return s;
17750
}
17751
#endif  /* OPENSSL_EXTRA */
17752
17753
#ifdef OPENSSL_ALL
17754
17755
WOLFSSL_STACK* wolfSSL_sk_X509_OBJECT_new(void)
17756
{
17757
    WOLFSSL_STACK* s = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
17758
            DYNAMIC_TYPE_OPENSSL);
17759
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_new");
17760
    if (s != NULL) {
17761
        XMEMSET(s, 0, sizeof(*s));
17762
        s->type = STACK_TYPE_X509_OBJ;
17763
    }
17764
    return s;
17765
}
17766
17767
void wolfSSL_sk_X509_OBJECT_free(WOLFSSL_STACK* s)
17768
{
17769
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_free");
17770
    wolfSSL_sk_free(s);
17771
}
17772
17773
void wolfSSL_sk_X509_OBJECT_pop_free(WOLFSSL_STACK* s,
17774
        void (*f) (WOLFSSL_X509_OBJECT*))
17775
{
17776
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_pop_free");
17777
    wolfSSL_sk_pop_free(s, (wolfSSL_sk_freefunc)f);
17778
}
17779
17780
int wolfSSL_sk_X509_OBJECT_push(WOLFSSL_STACK* sk, WOLFSSL_X509_OBJECT* obj)
17781
{
17782
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_push");
17783
17784
    if (sk == NULL || obj == NULL) {
17785
        return WOLFSSL_FAILURE;
17786
    }
17787
17788
    return wolfSSL_sk_push(sk, obj);
17789
}
17790
17791
#endif /* OPENSSL_ALL */
17792
17793
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
17794
/* unlike wolfSSL_X509_NAME_dup this does not malloc a duplicate, only deep
17795
 * copy. "to" is expected to be a fresh blank name, if not pointers could be
17796
 * lost */
17797
int wolfSSL_X509_NAME_copy(const WOLFSSL_X509_NAME* from, WOLFSSL_X509_NAME* to)
17798
{
17799
    int i;
17800
17801
    WOLFSSL_ENTER("wolfSSL_X509_NAME_copy");
17802
17803
    if (from == NULL || to == NULL) {
17804
        WOLFSSL_MSG("NULL parameter");
17805
        return BAD_FUNC_ARG;
17806
    }
17807
17808
    if (from->dynamicName) {
17809
        to->name = (char*)XMALLOC(from->sz, to->heap, DYNAMIC_TYPE_SUBJECT_CN);
17810
        if (to->name == NULL)
17811
            return WOLFSSL_FAILURE;
17812
        to->dynamicName = 1;
17813
    }
17814
    XMEMCPY(to->name, from->name, from->sz);
17815
    to->sz = from->sz;
17816
17817
    for (i = 0; i < MAX_NAME_ENTRIES; i++) {
17818
        WOLFSSL_X509_NAME_ENTRY* ne = wolfSSL_X509_NAME_get_entry(from, i);
17819
        if (ne != NULL) {
17820
            if (wolfSSL_X509_NAME_add_entry(to, ne, i, 1) != WOLFSSL_SUCCESS) {
17821
                return WOLFSSL_FAILURE;
17822
            }
17823
        }
17824
    }
17825
    to->entrySz = from->entrySz;
17826
17827
#if !defined(WOLFSSL_NO_CA_NAMES) && defined(OPENSSL_EXTRA)
17828
    /* The copy has the encoding of the name, or of the certificate the name
17829
     * is from, to send in a list of CA names. Set after the entries, as
17830
     * adding an entry drops the encoding. */
17831
    if (from->rawLen > 0) {
17832
        if (SetX509NameRaw(to, from->raw, from->rawLen) != 0) {
17833
            return WOLFSSL_FAILURE;
17834
        }
17835
    }
17836
    else if (X509NameRawFromCert(to, from) != 0) {
17837
        return WOLFSSL_FAILURE;
17838
    }
17839
#endif
17840
    return WOLFSSL_SUCCESS;
17841
}
17842
17843
17844
/* copies over information from "name" to the "cert" subject name
17845
 * returns WOLFSSL_SUCCESS on success */
17846
int wolfSSL_X509_set_subject_name(WOLFSSL_X509 *cert, WOLFSSL_X509_NAME *name)
17847
{
17848
    WOLFSSL_ENTER("wolfSSL_X509_set_subject_name");
17849
    if (cert == NULL || name == NULL)
17850
        return WOLFSSL_FAILURE;
17851
17852
    FreeX509Name(&cert->subject);
17853
    InitX509Name(&cert->subject, 0, cert->heap);
17854
17855
    if (wolfSSL_X509_NAME_copy(name, &cert->subject) != WOLFSSL_SUCCESS) {
17856
        FreeX509Name(&cert->subject);
17857
        return WOLFSSL_FAILURE;
17858
    }
17859
17860
    cert->subject.x509 = cert;
17861
    return WOLFSSL_SUCCESS;
17862
}
17863
17864
17865
/* copies over information from "name" to the "cert" issuer name
17866
 * returns WOLFSSL_SUCCESS on success */
17867
int wolfSSL_X509_set_issuer_name(WOLFSSL_X509 *cert, WOLFSSL_X509_NAME *name)
17868
{
17869
    WOLFSSL_ENTER("wolfSSL_X509_set_issuer_name");
17870
    if (cert == NULL || name == NULL)
17871
        return WOLFSSL_FAILURE;
17872
17873
    FreeX509Name(&cert->issuer);
17874
    InitX509Name(&cert->issuer, 0, cert->heap);
17875
17876
    if (wolfSSL_X509_NAME_copy(name, &cert->issuer) != WOLFSSL_SUCCESS) {
17877
        FreeX509Name(&cert->issuer);
17878
        return WOLFSSL_FAILURE;
17879
    }
17880
17881
    cert->issuer.x509 = cert;
17882
    cert->issuerSet = 1;
17883
17884
    return WOLFSSL_SUCCESS;
17885
}
17886
17887
17888
int wolfSSL_X509_set_notAfter(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME* t)
17889
{
17890
    if (x509 == NULL || t == NULL) {
17891
        return WOLFSSL_FAILURE;
17892
    }
17893
17894
    if (t->length < 0 || t->length > CTC_DATE_SIZE - 2) {
17895
        return WOLFSSL_FAILURE;
17896
    }
17897
17898
    x509->notAfter.type = t->type;
17899
    x509->notAfter.length = t->length;
17900
17901
    XMEMCPY(x509->notAfter.data, t->data, CTC_DATE_SIZE);
17902
17903
    return WOLFSSL_SUCCESS;
17904
}
17905
17906
int wolfSSL_X509_set_notBefore(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME* t)
17907
{
17908
    if (x509 == NULL || t == NULL) {
17909
        return WOLFSSL_FAILURE;
17910
    }
17911
17912
    if (t->length < 0 || t->length > CTC_DATE_SIZE - 2) {
17913
        return WOLFSSL_FAILURE;
17914
    }
17915
17916
    x509->notBefore.type = t->type;
17917
    x509->notBefore.length = t->length;
17918
17919
    XMEMCPY(x509->notBefore.data, t->data, CTC_DATE_SIZE);
17920
17921
    return WOLFSSL_SUCCESS;
17922
}
17923
17924
int wolfSSL_X509_set1_notAfter(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME *t)
17925
{
17926
    return wolfSSL_X509_set_notAfter(x509, t);
17927
}
17928
17929
int wolfSSL_X509_set1_notBefore(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME *t)
17930
{
17931
    return wolfSSL_X509_set_notBefore(x509, t);
17932
}
17933
17934
int wolfSSL_X509_set_serialNumber(WOLFSSL_X509* x509, WOLFSSL_ASN1_INTEGER* s)
17935
{
17936
    WOLFSSL_ENTER("wolfSSL_X509_set_serialNumber");
17937
    if (x509 == NULL || s == NULL || s->data == NULL ||
17938
            s->length >= EXTERNAL_SERIAL_SIZE)
17939
        return WOLFSSL_FAILURE;
17940
17941
    /* WOLFSSL_ASN1_INTEGER has type | size | data
17942
     * Sanity check that the data is actually in ASN format */
17943
    if (s->length < 3 || s->data[0] != ASN_INTEGER ||
17944
            s->data[1] != s->length - 2) {
17945
        return WOLFSSL_FAILURE;
17946
    }
17947
    XMEMCPY(x509->serial, s->data + 2, s->length - 2);
17948
    x509->serialSz = s->length - 2;
17949
    x509->serial[x509->serialSz] = 0;
17950
17951
    return WOLFSSL_SUCCESS;
17952
}
17953
17954
int wolfSSL_X509_set_pubkey(WOLFSSL_X509 *cert, WOLFSSL_EVP_PKEY *pkey)
17955
{
17956
    byte* p = NULL;
17957
    int derSz = 0;
17958
    WOLFSSL_ENTER("wolfSSL_X509_set_pubkey");
17959
17960
    if (cert == NULL || pkey == NULL)
17961
        return WOLFSSL_FAILURE;
17962
17963
    /* Regenerate since pkey->pkey.ptr may contain private key */
17964
    switch (pkey->type) {
17965
#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(NO_RSA)
17966
    case WC_EVP_PKEY_RSA:
17967
        {
17968
            RsaKey* rsa;
17969
17970
            if (pkey->rsa == NULL || pkey->rsa->internal == NULL)
17971
                return WOLFSSL_FAILURE;
17972
17973
            rsa = (RsaKey*)pkey->rsa->internal;
17974
            derSz = wc_RsaPublicKeyDerSize(rsa, 1);
17975
            if (derSz <= 0)
17976
                return WOLFSSL_FAILURE;
17977
17978
            p = (byte*)XMALLOC(derSz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
17979
            if (p == NULL)
17980
                return WOLFSSL_FAILURE;
17981
17982
            if ((derSz = wc_RsaKeyToPublicDer(rsa, p, (word32)derSz)) <= 0) {
17983
                XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
17984
                return WOLFSSL_FAILURE;
17985
            }
17986
            cert->pubKeyOID = RSAk;
17987
        }
17988
        break;
17989
#endif /* (WOLFSSL_KEY_GEN || OPENSSL_EXTRA) && !NO_RSA */
17990
#if !defined(HAVE_SELFTEST) && (defined(WOLFSSL_KEY_GEN) || \
17991
        defined(WOLFSSL_CERT_GEN)) && !defined(NO_DSA)
17992
    case WC_EVP_PKEY_DSA:
17993
        {
17994
            DsaKey* dsa;
17995
17996
            if (pkey->dsa == NULL || pkey->dsa->internal == NULL)
17997
                return WOLFSSL_FAILURE;
17998
17999
            dsa = (DsaKey*)pkey->dsa->internal;
18000
            /* size of pub, priv, p, q, g + ASN.1 additional information */
18001
            derSz = 5 * mp_unsigned_bin_size(&dsa->g) + MAX_ALGO_SZ;
18002
            p = (byte*)XMALLOC(derSz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
18003
            if (p == NULL)
18004
                return WOLFSSL_FAILURE;
18005
18006
            if ((derSz = wc_DsaKeyToPublicDer(dsa, p, (word32)derSz)) <= 0) {
18007
                XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
18008
                return WOLFSSL_FAILURE;
18009
            }
18010
            cert->pubKeyOID = DSAk;
18011
        }
18012
        break;
18013
#endif /* !HAVE_SELFTEST && (WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN) && !NO_DSA */
18014
#ifdef HAVE_ECC
18015
    case WC_EVP_PKEY_EC:
18016
        {
18017
            ecc_key* ecc;
18018
18019
            if (pkey->ecc == NULL || pkey->ecc->internal == NULL)
18020
                return WOLFSSL_FAILURE;
18021
18022
            ecc = (ecc_key*)pkey->ecc->internal;
18023
            derSz = wc_EccPublicKeyDerSize(ecc, 1);
18024
            if (derSz <= 0)
18025
                return WOLFSSL_FAILURE;
18026
18027
            p = (byte*)XMALLOC(derSz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
18028
            if (p == NULL)
18029
                return WOLFSSL_FAILURE;
18030
18031
            if ((derSz = wc_EccPublicKeyToDer(ecc, p, (word32)derSz, 1)) <= 0) {
18032
                XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
18033
                return WOLFSSL_FAILURE;
18034
            }
18035
            cert->pubKeyOID = ECDSAk;
18036
            cert->pkCurveOID = ecc->dp->oidSum;
18037
        }
18038
        break;
18039
#endif
18040
#if defined(WOLFSSL_HAVE_MLDSA) && defined(WOLFSSL_MLDSA_PUBLIC_KEY) && \
18041
    !defined(WOLFSSL_MLDSA_NO_ASN1) && defined(WC_ENABLE_ASYM_KEY_EXPORT)
18042
    case WC_EVP_PKEY_DILITHIUM:
18043
        {
18044
            /* Decode key DER (private or public) and export public part. */
18045
            wc_MlDsaKey* mldsa;
18046
            word32 idx = 0;
18047
            word32 rawLen = 0;
18048
            int oidSum = 0;
18049
            int decodeOk = 0;
18050
18051
            mldsa = (wc_MlDsaKey*)XMALLOC(sizeof(wc_MlDsaKey), cert->heap,
18052
                    DYNAMIC_TYPE_MLDSA);
18053
            if (mldsa == NULL) {
18054
                WOLFSSL_MSG("Failed to allocate memory for wc_MlDsaKey");
18055
                return WOLFSSL_FAILURE;
18056
            }
18057
            if (wc_MlDsaKey_Init(mldsa, cert->heap, INVALID_DEVID) != 0) {
18058
                WOLFSSL_MSG("wc_MlDsaKey_Init error");
18059
                XFREE(mldsa, cert->heap, DYNAMIC_TYPE_MLDSA);
18060
                return WOLFSSL_FAILURE;
18061
            }
18062
        #ifdef WOLFSSL_MLDSA_PRIVATE_KEY
18063
            PRIVATE_KEY_UNLOCK();
18064
            if (wc_MlDsaKey_PrivateKeyDecode(mldsa,
18065
                    (const byte*)pkey->pkey.ptr, (word32)pkey->pkey_sz,
18066
                    &idx) == 0) {
18067
                decodeOk = 1;
18068
            }
18069
            PRIVATE_KEY_LOCK();
18070
        #endif
18071
            if (!decodeOk) {
18072
            #ifdef WOLFSSL_MLDSA_PRIVATE_KEY
18073
                /* A failed PrivateKeyDecode may leave the level pinned;
18074
                 * reset the key so PublicKeyDecode auto-detects it from
18075
                 * the SPKI OID. */
18076
                wc_MlDsaKey_Free(mldsa);
18077
                if (wc_MlDsaKey_Init(mldsa, cert->heap, INVALID_DEVID) != 0) {
18078
                    WOLFSSL_MSG("wc_MlDsaKey_Init error");
18079
                    XFREE(mldsa, cert->heap, DYNAMIC_TYPE_MLDSA);
18080
                    return WOLFSSL_FAILURE;
18081
                }
18082
            #endif
18083
                idx = 0;
18084
                if (wc_MlDsaKey_PublicKeyDecode(mldsa,
18085
                        (const byte*)pkey->pkey.ptr, (word32)pkey->pkey_sz,
18086
                        &idx) != 0) {
18087
                    WOLFSSL_MSG("Error decoding ML-DSA public key");
18088
                    wc_MlDsaKey_Free(mldsa);
18089
                    XFREE(mldsa, cert->heap, DYNAMIC_TYPE_MLDSA);
18090
                    return WOLFSSL_FAILURE;
18091
                }
18092
            }
18093
            /* Map the parameter set to its OID with mldsa_get_oid_sum():
18094
             * unlike wc_MlDsaKey_GetParams() it distinguishes FIPS204-draft
18095
             * levels, keeping pubKeyOID consistent with the exported key. */
18096
            if (mldsa_get_oid_sum(mldsa, &oidSum) != 0) {
18097
                WOLFSSL_MSG("Error getting ML-DSA OID");
18098
                wc_MlDsaKey_Free(mldsa);
18099
                XFREE(mldsa, cert->heap, DYNAMIC_TYPE_MLDSA);
18100
                return WOLFSSL_FAILURE;
18101
            }
18102
18103
            /* Store the RAW public key */
18104
            if (wc_MlDsaKey_GetPubLen(mldsa, &derSz) != 0) {
18105
                WOLFSSL_MSG("Error getting ML-DSA public key length");
18106
                wc_MlDsaKey_Free(mldsa);
18107
                XFREE(mldsa, cert->heap, DYNAMIC_TYPE_MLDSA);
18108
                return WOLFSSL_FAILURE;
18109
            }
18110
            p = (byte*)XMALLOC(derSz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
18111
            if (p == NULL) {
18112
                WOLFSSL_MSG("malloc error");
18113
                wc_MlDsaKey_Free(mldsa);
18114
                XFREE(mldsa, cert->heap, DYNAMIC_TYPE_MLDSA);
18115
                return WOLFSSL_FAILURE;
18116
            }
18117
            rawLen = (word32)derSz;
18118
            if (wc_MlDsaKey_ExportPubRaw(mldsa, p, &rawLen) != 0) {
18119
                WOLFSSL_MSG("Error exporting ML-DSA public key");
18120
                wc_MlDsaKey_Free(mldsa);
18121
                XFREE(mldsa, cert->heap, DYNAMIC_TYPE_MLDSA);
18122
                XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
18123
                return WOLFSSL_FAILURE;
18124
            }
18125
            wc_MlDsaKey_Free(mldsa);
18126
            XFREE(mldsa, cert->heap, DYNAMIC_TYPE_MLDSA);
18127
            derSz = (int)rawLen;
18128
            cert->pubKeyOID = oidSum;
18129
        }
18130
        break;
18131
#endif /* WOLFSSL_HAVE_MLDSA && WOLFSSL_MLDSA_PUBLIC_KEY &&
18132
        * !WOLFSSL_MLDSA_NO_ASN1 && WC_ENABLE_ASYM_KEY_EXPORT */
18133
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
18134
    case WC_EVP_PKEY_ED25519:
18135
        {
18136
            word32 rawLen = ED25519_PUB_KEY_SIZE;
18137
18138
            if (pkey->ed25519 == NULL)
18139
                return WOLFSSL_FAILURE;
18140
18141
            /* Store the RAW public key: wolfSSL keeps an X.509 Ed25519
18142
             * public key as the bare key bytes (see StoreKey /
18143
             * CopyDecodedToX509), not a SubjectPublicKeyInfo. */
18144
            p = (byte*)XMALLOC(rawLen, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
18145
            if (p == NULL)
18146
                return WOLFSSL_FAILURE;
18147
18148
            if (wc_ed25519_export_public(pkey->ed25519, p, &rawLen) != 0) {
18149
                XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
18150
                return WOLFSSL_FAILURE;
18151
            }
18152
            derSz = (int)rawLen;
18153
            cert->pubKeyOID = ED25519k;
18154
        }
18155
        break;
18156
#endif
18157
    default:
18158
        return WOLFSSL_FAILURE;
18159
    }
18160
    XFREE(cert->pubKey.buffer, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
18161
    cert->pubKey.buffer = p;
18162
    cert->pubKey.length = (unsigned int)derSz;
18163
    /* Drop what was decoded from the previous public key, unless the caller
18164
     * passed that very key. */
18165
    if (cert->key.pkey != pkey) {
18166
        wolfSSL_EVP_PKEY_free(cert->key.pkey);
18167
        cert->key.pkey = NULL;
18168
    }
18169
    cert->key.pubKeyOID = cert->pubKeyOID;
18170
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
18171
    defined(WOLFSSL_APACHE_HTTPD) || defined(WOLFSSL_HAPROXY) || \
18172
    defined(WOLFSSL_WPAS)
18173
    wolfSSL_X509_ALGOR_free(cert->key.algor);
18174
    cert->key.algor = NULL;
18175
#endif
18176
18177
    return WOLFSSL_SUCCESS;
18178
}
18179
18180
int wolfSSL_X509_set_version(WOLFSSL_X509* x509, long v)
18181
{
18182
    WOLFSSL_ENTER("wolfSSL_X509_set_version");
18183
    if ((x509 == NULL) || (v < 0) || (v >= INT_MAX)) {
18184
        return WOLFSSL_FAILURE;
18185
    }
18186
    x509->version = (int) v + 1;
18187
18188
    return WOLFSSL_SUCCESS;
18189
}
18190
18191
#ifdef WOLFSSL_CERT_EXT
18192
/* Set Subject Key Identifier from raw bytes.
18193
 *
18194
 * x509  - Certificate to modify
18195
 * skid  - Raw SKID bytes
18196
 * skidSz - Size of SKID in bytes
18197
 *
18198
 * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
18199
 */
18200
int wolfSSL_X509_set_subject_key_id(WOLFSSL_X509* x509,
18201
    const unsigned char* skid, int skidSz)
18202
{
18203
    WOLFSSL_ENTER("wolfSSL_X509_set_subject_key_id");
18204
18205
    if (x509 == NULL || skid == NULL || skidSz <= 0) {
18206
        return WOLFSSL_FAILURE;
18207
    }
18208
18209
    /* Allocate/reallocate memory for subjKeyId */
18210
    if (x509->subjKeyId == NULL || (int)x509->subjKeyIdSz < skidSz) {
18211
        if (x509->subjKeyId != NULL) {
18212
            XFREE(x509->subjKeyId, x509->heap, DYNAMIC_TYPE_X509_EXT);
18213
        }
18214
        x509->subjKeyId = (byte*)XMALLOC((word32)skidSz, x509->heap,
18215
                                          DYNAMIC_TYPE_X509_EXT);
18216
        if (x509->subjKeyId == NULL) {
18217
            return WOLFSSL_FAILURE;
18218
        }
18219
    }
18220
18221
    XMEMCPY(x509->subjKeyId, skid, (word32)skidSz);
18222
    x509->subjKeyIdSz = (word32)skidSz;
18223
    x509->subjKeyIdSet = 1;
18224
18225
    return WOLFSSL_SUCCESS;
18226
}
18227
18228
#ifndef NO_SHA
18229
/* Set Subject Key Identifier by computing SHA-1 hash of the public key.
18230
 *
18231
 * x509 - Certificate to modify (must have public key set)
18232
 *
18233
 * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
18234
 */
18235
int wolfSSL_X509_set_subject_key_id_ex(WOLFSSL_X509* x509)
18236
{
18237
    byte hash[WC_SHA_DIGEST_SIZE];
18238
    int ret;
18239
18240
    WOLFSSL_ENTER("wolfSSL_X509_set_subject_key_id_ex");
18241
18242
    if (x509 == NULL) {
18243
        return WOLFSSL_FAILURE;
18244
    }
18245
18246
    /* Check if public key has been set */
18247
    if (x509->pubKey.buffer == NULL || x509->pubKey.length == 0) {
18248
        WOLFSSL_MSG("Public key not set");
18249
        return WOLFSSL_FAILURE;
18250
    }
18251
18252
    /* Compute SHA-1 hash of the public key */
18253
    ret = wc_ShaHash(x509->pubKey.buffer, x509->pubKey.length, hash);
18254
    if (ret != 0) {
18255
        WOLFSSL_MSG("wc_ShaHash failed");
18256
        return WOLFSSL_FAILURE;
18257
    }
18258
18259
    return wolfSSL_X509_set_subject_key_id(x509, hash, WC_SHA_DIGEST_SIZE);
18260
}
18261
#endif /* !NO_SHA */
18262
18263
/* Set Authority Key Identifier from raw bytes.
18264
 * The bytes passed in are the keyIdentifier OCTET STRING contents only,
18265
 * they must not be a pre-encoded AuthorityKeyIdentifier SEQUENCE.
18266
 * The cert encoder wraps them in SEQUENCE { [0] keyIdentifier } at sign time.
18267
 *
18268
 * x509   - Certificate to modify
18269
 * akid   - Raw AKID bytes
18270
 * akidSz - Size of AKID in bytes
18271
 *
18272
 * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
18273
 */
18274
int wolfSSL_X509_set_authority_key_id(WOLFSSL_X509* x509,
18275
    const unsigned char* akid, int akidSz)
18276
{
18277
    byte* newAkid = NULL;
18278
18279
    WOLFSSL_ENTER("wolfSSL_X509_set_authority_key_id");
18280
18281
    if (x509 == NULL || akid == NULL || akidSz <= 0) {
18282
        return WOLFSSL_FAILURE;
18283
    }
18284
18285
    /* Allocate new buffer up front so failure leaves prior state intact */
18286
    newAkid = (byte*)XMALLOC((word32)akidSz, x509->heap, DYNAMIC_TYPE_X509_EXT);
18287
    if (newAkid == NULL) {
18288
        return WOLFSSL_FAILURE;
18289
    }
18290
    XMEMCPY(newAkid, akid, (word32)akidSz);
18291
18292
    /* Free any prior storage. authKeyIdSrc may be populated from a prior
18293
     * parse cert operation. authKeyId aliases inside that buffer, so
18294
     * authKeyIdSrc must be freed first to avoid a dangling authKeyId. */
18295
    if (x509->authKeyIdSrc != NULL) {
18296
        XFREE(x509->authKeyIdSrc, x509->heap, DYNAMIC_TYPE_X509_EXT);
18297
        x509->authKeyIdSrc = NULL;
18298
        x509->authKeyIdSrcSz = 0;
18299
    }
18300
    else if (x509->authKeyId != NULL) {
18301
        XFREE(x509->authKeyId, x509->heap, DYNAMIC_TYPE_X509_EXT);
18302
    }
18303
18304
    /* Store newAkid as authKeyId only, do not populate authKeyIdSrc.
18305
     * When authKeyIdSrc is non-NULL, the encoder writes those bytes without
18306
     * SEQUENCE/[0] wrapper. authKeyIdSrc must be NULL here so encoder does
18307
     * wrap them. */
18308
    x509->authKeyId = newAkid;
18309
    x509->authKeyIdSz = (word32)akidSz;
18310
    x509->authKeyIdSet = 1;
18311
18312
    return WOLFSSL_SUCCESS;
18313
}
18314
18315
#ifndef NO_SHA
18316
/* Set Authority Key Identifier from issuer certificate.
18317
 * Extracts SKID from issuer (or computes from issuer's public key).
18318
 *
18319
 * x509   - Certificate to modify
18320
 * issuer - Issuer certificate
18321
 *
18322
 * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
18323
 */
18324
int wolfSSL_X509_set_authority_key_id_ex(WOLFSSL_X509* x509,
18325
    WOLFSSL_X509* issuer)
18326
{
18327
    byte hash[WC_SHA_DIGEST_SIZE];
18328
    int ret;
18329
18330
    WOLFSSL_ENTER("wolfSSL_X509_set_authority_key_id_ex");
18331
18332
    if (x509 == NULL || issuer == NULL) {
18333
        return WOLFSSL_FAILURE;
18334
    }
18335
18336
    /* First try to use issuer's SKID if it's set */
18337
    if (issuer->subjKeyIdSet && issuer->subjKeyId != NULL &&
18338
        issuer->subjKeyIdSz > 0) {
18339
        return wolfSSL_X509_set_authority_key_id(x509, issuer->subjKeyId,
18340
                                                  (int)issuer->subjKeyIdSz);
18341
    }
18342
18343
    /* Otherwise compute from issuer's public key */
18344
    if (issuer->pubKey.buffer == NULL || issuer->pubKey.length == 0) {
18345
        WOLFSSL_MSG("Issuer public key not available");
18346
        return WOLFSSL_FAILURE;
18347
    }
18348
18349
    ret = wc_ShaHash(issuer->pubKey.buffer, issuer->pubKey.length, hash);
18350
    if (ret != 0) {
18351
        WOLFSSL_MSG("wc_ShaHash failed");
18352
        return WOLFSSL_FAILURE;
18353
    }
18354
18355
    return wolfSSL_X509_set_authority_key_id(x509, hash, WC_SHA_DIGEST_SIZE);
18356
}
18357
#endif /* !NO_SHA */
18358
#endif /* WOLFSSL_CERT_EXT */
18359
18360
#ifndef IGNORE_NETSCAPE_CERT_TYPE
18361
/* Set Netscape Certificate Type extension.
18362
 *
18363
 * x509       - Certificate to modify
18364
 * nsCertType - Bitwise OR of NS_SSL_CLIENT, NS_SSL_SERVER, etc.
18365
 *
18366
 * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
18367
 */
18368
int wolfSSL_X509_set_ns_cert_type(WOLFSSL_X509* x509, int nsCertType)
18369
{
18370
    WOLFSSL_ENTER("wolfSSL_X509_set_ns_cert_type");
18371
18372
    if (x509 == NULL) {
18373
        return WOLFSSL_FAILURE;
18374
    }
18375
18376
    x509->nsCertType = (byte)nsCertType;
18377
18378
    return WOLFSSL_SUCCESS;
18379
}
18380
#endif /* !IGNORE_NETSCAPE_CERT_TYPE */
18381
18382
#endif /* (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) && WOLFSSL_CERT_GEN */
18383
18384
#if (defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)) &&           \
18385
    defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ)
18386
18387
void wolfSSL_X509V3_set_ctx(WOLFSSL_X509V3_CTX* ctx, WOLFSSL_X509* issuer,
18388
        WOLFSSL_X509* subject, WOLFSSL_X509* req, WOLFSSL_X509_CRL* crl,
18389
        int flag)
18390
{
18391
    int ret = WOLFSSL_SUCCESS;
18392
    WOLFSSL_ENTER("wolfSSL_X509V3_set_ctx");
18393
    if (!ctx) {
18394
        ret = WOLFSSL_FAILURE;
18395
        WOLFSSL_MSG("wolfSSL_X509V3_set_ctx() called with null ctx.");
18396
    }
18397
18398
    if (ret == WOLFSSL_SUCCESS && (ctx->x509 != NULL)) {
18399
        ret = WOLFSSL_FAILURE;
18400
        WOLFSSL_MSG("wolfSSL_X509V3_set_ctx() called "
18401
                    "with ctx->x509 already allocated.");
18402
    }
18403
18404
    if (ret == WOLFSSL_SUCCESS) {
18405
        ctx->x509 = wolfSSL_X509_new_ex(
18406
            (issuer && issuer->heap) ? issuer->heap :
18407
            (subject && subject->heap) ? subject->heap :
18408
            (req && req->heap) ? req->heap :
18409
            NULL);
18410
        if (!ctx->x509) {
18411
            ret = WOLFSSL_FAILURE;
18412
            WOLFSSL_MSG("wolfSSL_X509_new_ex() failed "
18413
                        "in wolfSSL_X509V3_set_ctx().");
18414
        }
18415
    }
18416
18417
    /* Set parameters in ctx as long as ret == WOLFSSL_SUCCESS */
18418
    if (ret == WOLFSSL_SUCCESS && issuer)
18419
        ret = wolfSSL_X509_set_issuer_name(ctx->x509, &issuer->issuer);
18420
18421
    if (ret == WOLFSSL_SUCCESS && subject)
18422
        ret = wolfSSL_X509_set_subject_name(ctx->x509, &subject->subject);
18423
18424
    if (ret == WOLFSSL_SUCCESS && req) {
18425
        WOLFSSL_MSG("req not implemented.");
18426
    }
18427
18428
    if (ret == WOLFSSL_SUCCESS && crl) {
18429
        WOLFSSL_MSG("crl not implemented.");
18430
    }
18431
18432
    if (ret == WOLFSSL_SUCCESS && flag) {
18433
        WOLFSSL_MSG("flag not implemented.");
18434
    }
18435
18436
    if (ret != WOLFSSL_SUCCESS) {
18437
        WOLFSSL_MSG("Error setting WOLFSSL_X509V3_CTX parameters.");
18438
    }
18439
}
18440
18441
#ifndef NO_BIO
18442
int wolfSSL_i2d_X509_REQ(WOLFSSL_X509* req, unsigned char** out)
18443
{
18444
    int derSz = 0;
18445
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
18446
    WOLFSSL_BIO* bio = NULL;
18447
    WOLFSSL_ENTER("wolfSSL_i2d_X509_REQ");
18448
18449
    if (req == NULL || out == NULL) {
18450
        return BAD_FUNC_ARG;
18451
    }
18452
18453
    if (!(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()))) {
18454
        return WOLFSSL_FAILURE;
18455
    }
18456
18457
    if (wolfSSL_i2d_X509_REQ_bio(bio, req) != WOLFSSL_SUCCESS) {
18458
        WOLFSSL_MSG("wolfSSL_i2d_X509_REQ_bio error");
18459
        goto cleanup;
18460
    }
18461
18462
    derSz = wolfSSL_BIO_get_len(bio);
18463
18464
    if (*out == NULL) {
18465
        *out = (unsigned char*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL);
18466
        if (!*out) {
18467
            WOLFSSL_MSG("malloc error");
18468
            ret = MEMORY_E;
18469
            goto cleanup;
18470
        }
18471
    }
18472
18473
    if (wolfSSL_BIO_read(bio, *out, derSz) != derSz) {
18474
        WOLFSSL_MSG("wolfSSL_BIO_read error");
18475
        goto cleanup;
18476
    }
18477
18478
    ret = derSz;
18479
cleanup:
18480
    wolfSSL_BIO_free(bio);
18481
18482
    return ret;
18483
}
18484
#endif /* !NO_BIO */
18485
18486
WOLFSSL_X509* wolfSSL_X509_REQ_new(void)
18487
{
18488
    return wolfSSL_X509_new();
18489
}
18490
18491
void wolfSSL_X509_REQ_free(WOLFSSL_X509* req)
18492
{
18493
    wolfSSL_X509_free(req);
18494
}
18495
18496
int wolfSSL_X509_REQ_set_version(WOLFSSL_X509 *x, long version)
18497
{
18498
    WOLFSSL_ENTER("wolfSSL_X509_REQ_set_version");
18499
    if ((x == NULL) || (version < 0) || (version >= INT_MAX)) {
18500
        return WOLFSSL_FAILURE;
18501
    }
18502
    x->version = (int)version;
18503
    return WOLFSSL_SUCCESS;
18504
}
18505
18506
long wolfSSL_X509_REQ_get_version(const WOLFSSL_X509 *req)
18507
{
18508
    WOLFSSL_ENTER("wolfSSL_X509_REQ_get_version");
18509
    if (req == NULL) {
18510
        return 0; /* invalid arg */
18511
    }
18512
    return (long)req->version;
18513
}
18514
18515
int wolfSSL_X509_REQ_sign(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey,
18516
                          const WOLFSSL_EVP_MD *md)
18517
{
18518
    int ret;
18519
    byte* der = NULL;
18520
    int bufSz;
18521
    int derSz;
18522
    int sigType;
18523
18524
    if (req == NULL || pkey == NULL) {
18525
        WOLFSSL_LEAVE("wolfSSL_X509_REQ_sign", BAD_FUNC_ARG);
18526
        return WOLFSSL_FAILURE;
18527
    }
18528
18529
    bufSz = x509_gen_buf_sz(req, pkey);
18530
    derSz = bufSz;
18531
    der = (byte*)XMALLOC((size_t)bufSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18532
    if (der == NULL) {
18533
        return WOLFSSL_FAILURE;
18534
    }
18535
18536
    /* Create a Cert that has the certificate request fields.  The (pkey, md)
18537
     * combination is resolved by wolfSSL_sigTypeFromPKEY() - Ed25519 CSRs sign
18538
     * with a NULL digest, ML-DSA ignores the digest, every other key type
18539
     * requires one - and sigOID is only updated on success, so the object is
18540
     * unmodified on a rejected key/md combination. */
18541
    sigType = wolfSSL_sigTypeFromPKEY((WOLFSSL_EVP_MD*)md, pkey);
18542
    if (sigType == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
18543
        WOLFSSL_MSG("Unsupported key/md combination for signing");
18544
        XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18545
        return WOLFSSL_FAILURE;
18546
    }
18547
    req->sigOID = sigType;
18548
    ret = wolfssl_x509_make_der(req, 1, der, &derSz, 0);
18549
    if (ret != WOLFSSL_SUCCESS) {
18550
        XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18551
        WOLFSSL_MSG("Unable to make DER for X509");
18552
        WOLFSSL_LEAVE("wolfSSL_X509_REQ_sign", ret);
18553
        return WOLFSSL_FAILURE;
18554
    }
18555
18556
    if (wolfSSL_X509_resign_cert(req, 1, der, bufSz, derSz,
18557
            (WOLFSSL_EVP_MD*)md, pkey) <= 0) {
18558
        XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18559
        return WOLFSSL_FAILURE;
18560
    }
18561
    XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18562
    return WOLFSSL_SUCCESS;
18563
}
18564
18565
int wolfSSL_X509_REQ_sign_ctx(WOLFSSL_X509 *req,
18566
                              WOLFSSL_EVP_MD_CTX* md_ctx)
18567
{
18568
    if (md_ctx && md_ctx->pctx)
18569
        return wolfSSL_X509_REQ_sign(req, md_ctx->pctx->pkey,
18570
                wolfSSL_EVP_MD_CTX_md(md_ctx));
18571
    else
18572
        return WOLFSSL_FAILURE;
18573
}
18574
18575
static int regenX509REQDerBuffer(WOLFSSL_X509* x509)
18576
{
18577
    int derSz = X509_BUFFER_SZ;
18578
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
18579
#ifndef WOLFSSL_SMALL_STACK
18580
    byte der[X509_BUFFER_SZ];
18581
#else
18582
    byte* der;
18583
18584
    der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18585
    if (!der) {
18586
        WOLFSSL_MSG("malloc failed");
18587
        return WOLFSSL_FAILURE;
18588
    }
18589
#endif
18590
18591
    if (wolfssl_x509_make_der(x509, 1, der, &derSz, 0) == WOLFSSL_SUCCESS) {
18592
        FreeDer(&x509->derCert);
18593
    #if !defined(WOLFSSL_NO_CA_NAMES) && defined(OPENSSL_EXTRA)
18594
        /* The names are encoded again, not as they were in the old encoding
18595
         * or in the names they were set from, and not where they were. */
18596
        ClearX509NameRaw(&x509->issuer);
18597
        ClearX509NameRaw(&x509->subject);
18598
    #endif
18599
        if (AllocDer(&x509->derCert, (word32)derSz, CERT_TYPE,
18600
                                                             x509->heap) == 0) {
18601
            XMEMCPY(x509->derCert->buffer, der, derSz);
18602
            ret = WOLFSSL_SUCCESS;
18603
        }
18604
        else {
18605
            WOLFSSL_MSG("Failed to allocate DER buffer for X509");
18606
        }
18607
    }
18608
    else {
18609
        WOLFSSL_MSG("Unable to make DER for X509 REQ");
18610
    }
18611
    WC_FREE_VAR_EX(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18612
    return ret;
18613
}
18614
18615
int wolfSSL_X509_REQ_add_extensions(WOLFSSL_X509* req,
18616
        WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* ext_sk)
18617
{
18618
    WOLFSSL_X509_EXTENSION* ext = NULL;
18619
18620
    if (!req || !ext_sk) {
18621
        WOLFSSL_MSG("Bad parameter");
18622
        return WOLFSSL_FAILURE;
18623
    }
18624
18625
    /* It is not an error if the stack is empty. */
18626
    ext = ext_sk->data.ext;
18627
    if (ext == NULL) {
18628
        return WOLFSSL_SUCCESS;
18629
    }
18630
18631
    while (ext_sk) {
18632
        ext = ext_sk->data.ext;
18633
18634
        if (wolfSSL_X509_add_ext(req, ext, -1) != WOLFSSL_SUCCESS) {
18635
            WOLFSSL_MSG("wolfSSL_X509_add_ext error");
18636
            return WOLFSSL_FAILURE;
18637
        }
18638
18639
        ext_sk = ext_sk->next;
18640
    }
18641
18642
    return regenX509REQDerBuffer(req);
18643
}
18644
18645
int wolfSSL_X509_REQ_add1_attr_by_txt(WOLFSSL_X509 *req,
18646
                              const char *attrname, int type,
18647
                              const unsigned char *bytes, int len)
18648
{
18649
    WOLFSSL_ENTER("wolfSSL_X509_REQ_add1_attr_by_txt");
18650
18651
#ifdef HAVE_LIBEST
18652
    if (!req || !attrname || !bytes || type != MBSTRING_ASC) {
18653
        WOLFSSL_MSG("Bad parameter");
18654
        return WOLFSSL_FAILURE;
18655
    }
18656
18657
    if (len < 0) {
18658
        len = (int)XSTRLEN((char*)bytes);
18659
    }
18660
18661
    /* For now just pretend that we support this for libest testing */
18662
    if (len == XSTR_SIZEOF("1.3.6.1.1.1.1.22") &&
18663
            XMEMCMP("1.3.6.1.1.1.1.22", bytes, len) == 0) {
18664
        /* MAC Address */
18665
    }
18666
    else if (len == XSTR_SIZEOF("1.2.840.10045.2.1") &&
18667
            XMEMCMP("1.2.840.10045.2.1", bytes, len) == 0) {
18668
        /* ecPublicKey */
18669
    }
18670
    else if (len == XSTR_SIZEOF("1.2.840.10045.4.3.3") &&
18671
            XMEMCMP("1.2.840.10045.4.3.3", bytes, len) == 0) {
18672
        /* ecdsa-with-SHA384 */
18673
    }
18674
    else {
18675
        return WOLFSSL_FAILURE;
18676
    }
18677
18678
    /* return error if not built for libest */
18679
    return WOLFSSL_SUCCESS;
18680
#else
18681
    (void)req;
18682
    (void)attrname;
18683
    (void)type;
18684
    (void)bytes;
18685
    (void)len;
18686
    return WOLFSSL_FAILURE;
18687
#endif
18688
}
18689
18690
18691
static int wolfSSL_X509_ATTRIBUTE_set(WOLFSSL_X509_ATTRIBUTE* attr,
18692
        const char* data, int dataSz, int type, int nid)
18693
{
18694
    if (attr) {
18695
        attr->value->value.asn1_string = wolfSSL_ASN1_STRING_new();
18696
        if (wolfSSL_ASN1_STRING_set(attr->value->value.asn1_string,
18697
                data, dataSz) != WOLFSSL_SUCCESS) {
18698
            wolfSSL_ASN1_STRING_free(attr->value->value.asn1_string);
18699
            WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
18700
            return WOLFSSL_FAILURE;
18701
        }
18702
        attr->value->type = type;
18703
        attr->object->nid = nid;
18704
    }
18705
    else {
18706
        WOLFSSL_MSG("wolfSSL_X509_ATTRIBUTE_new error");
18707
        return WOLFSSL_FAILURE;
18708
    }
18709
18710
    return WOLFSSL_SUCCESS;
18711
}
18712
18713
18714
int wolfSSL_X509_REQ_add1_attr_by_NID(WOLFSSL_X509 *req,
18715
                                      int nid, int type,
18716
                                      const unsigned char *bytes,
18717
                                      int len)
18718
{
18719
    int ret;
18720
    WOLFSSL_X509_ATTRIBUTE* attr;
18721
18722
    WOLFSSL_ENTER("wolfSSL_X509_REQ_add1_attr_by_NID");
18723
18724
    if (!req || !bytes || type != WOLFSSL_MBSTRING_ASC) {
18725
        WOLFSSL_MSG("Bad parameter");
18726
        return WOLFSSL_FAILURE;
18727
    }
18728
18729
    switch (nid) {
18730
    case WC_NID_pkcs9_challengePassword:
18731
        if (len < 0)
18732
            len = (int)XSTRLEN((char*)bytes);
18733
        if (len < CTC_NAME_SIZE) {
18734
            XMEMCPY(req->challengePw, bytes, len);
18735
            req->challengePw[len] = '\0';
18736
        }
18737
        else {
18738
            WOLFSSL_MSG("Challenge password too long");
18739
            WOLFSSL_ERROR_VERBOSE(BUFFER_E);
18740
            return WOLFSSL_FAILURE;
18741
        }
18742
        break;
18743
    case WC_NID_serialNumber:
18744
        if (len < 0)
18745
            len = (int)XSTRLEN((char*)bytes);
18746
        if (len + 1 > EXTERNAL_SERIAL_SIZE) {
18747
            WOLFSSL_MSG("SerialNumber too long");
18748
            WOLFSSL_ERROR_VERBOSE(BUFFER_E);
18749
            return WOLFSSL_FAILURE;
18750
        }
18751
        XMEMCPY(req->serial, bytes, len);
18752
        req->serialSz = len;
18753
        break;
18754
18755
    case WC_NID_pkcs9_unstructuredName:
18756
    case WC_NID_pkcs9_contentType:
18757
    case WC_NID_surname:
18758
    case WC_NID_initials:
18759
    case WC_NID_givenName:
18760
    case WC_NID_dnQualifier:
18761
        break;
18762
18763
    default:
18764
        WOLFSSL_MSG("Unsupported attribute");
18765
        return WOLFSSL_FAILURE;
18766
    }
18767
18768
    attr = wolfSSL_X509_ATTRIBUTE_new();
18769
    ret = wolfSSL_X509_ATTRIBUTE_set(attr, (const char*)bytes, len,
18770
            WOLFSSL_V_ASN1_PRINTABLESTRING, nid);
18771
    if (ret != WOLFSSL_SUCCESS) {
18772
        wolfSSL_X509_ATTRIBUTE_free(attr);
18773
    }
18774
    else {
18775
        if (req->reqAttributes == NULL) {
18776
            req->reqAttributes = wolfSSL_sk_new_node(req->heap);
18777
            if (req->reqAttributes != NULL) {
18778
                req->reqAttributes->type = STACK_TYPE_X509_REQ_ATTR;
18779
            }
18780
        }
18781
        if ((req->reqAttributes != NULL) &&
18782
                (req->reqAttributes->type == STACK_TYPE_X509_REQ_ATTR)) {
18783
            /* Using wolfSSL_sk_insert to maintain backwards compatibility with
18784
             * earlier versions of _push API that pushed items to the start of
18785
             * the list instead of the end. */
18786
            ret = wolfSSL_sk_insert(req->reqAttributes, attr, 0) > 0
18787
                    ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
18788
        }
18789
        else {
18790
            ret = WOLFSSL_FAILURE;
18791
        }
18792
        if (ret != WOLFSSL_SUCCESS)
18793
            wolfSSL_X509_ATTRIBUTE_free(attr);
18794
    }
18795
18796
    return ret;
18797
}
18798
18799
WOLFSSL_X509 *wolfSSL_X509_to_X509_REQ(WOLFSSL_X509 *x,
18800
        WOLFSSL_EVP_PKEY *pkey, const WOLFSSL_EVP_MD *md)
18801
{
18802
    WOLFSSL_ENTER("wolfSSL_X509_to_X509_REQ");
18803
    (void)pkey;
18804
    (void)md;
18805
    return wolfSSL_X509_dup(x);
18806
}
18807
18808
int wolfSSL_X509_REQ_set_subject_name(WOLFSSL_X509 *req,
18809
                                      WOLFSSL_X509_NAME *name)
18810
{
18811
    return wolfSSL_X509_set_subject_name(req, name);
18812
}
18813
18814
int wolfSSL_X509_REQ_set_pubkey(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey)
18815
{
18816
    return wolfSSL_X509_set_pubkey(req, pkey);
18817
}
18818
#endif /* OPENSSL_ALL && WOLFSSL_CERT_GEN && WOLFSSL_CERT_REQ */
18819
18820
#if (defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)) && \
18821
    (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_REQ))
18822
18823
WOLFSSL_ASN1_TYPE *wolfSSL_X509_ATTRIBUTE_get0_type(
18824
        WOLFSSL_X509_ATTRIBUTE *attr, int idx)
18825
{
18826
    WOLFSSL_ENTER("wolfSSL_X509_ATTRIBUTE_get0_type");
18827
18828
    if (!attr || idx != 0) {
18829
        WOLFSSL_MSG("Bad parameter");
18830
        return NULL;
18831
    }
18832
18833
    return attr->value;
18834
}
18835
18836
18837
/**
18838
 * @param req X509_REQ containing attribute
18839
 * @return the number of attributes
18840
 */
18841
int wolfSSL_X509_REQ_get_attr_count(const WOLFSSL_X509 *req)
18842
{
18843
    if (req == NULL || req->reqAttributes == NULL)
18844
        return 0;
18845
18846
    return wolfSSL_sk_num(req->reqAttributes);
18847
}
18848
18849
18850
/**
18851
 * @param req X509_REQ containing attribute
18852
 * @param loc NID of the attribute to return
18853
 */
18854
WOLFSSL_X509_ATTRIBUTE *wolfSSL_X509_REQ_get_attr(
18855
        const WOLFSSL_X509 *req, int loc)
18856
{
18857
    WOLFSSL_ENTER("wolfSSL_X509_REQ_get_attr");
18858
18859
    if (!req || req->reqAttributes == NULL) {
18860
        WOLFSSL_MSG("Bad parameter");
18861
        return NULL;
18862
    }
18863
18864
    return (WOLFSSL_X509_ATTRIBUTE*)wolfSSL_sk_value(req->reqAttributes, loc);
18865
}
18866
18867
/* Return NID as the attr index */
18868
int wolfSSL_X509_REQ_get_attr_by_NID(const WOLFSSL_X509 *req,
18869
        int nid, int lastpos)
18870
{
18871
    int idx;
18872
18873
    WOLFSSL_ENTER("wolfSSL_X509_REQ_get_attr_by_NID");
18874
18875
    if (!req) {
18876
        WOLFSSL_MSG("Bad parameter");
18877
        return WOLFSSL_FATAL_ERROR;
18878
    }
18879
18880
    /* search through stack for first matching nid */
18881
    for (idx = lastpos + 1; idx < wolfSSL_sk_num(req->reqAttributes); idx++) {
18882
        WOLFSSL_X509_ATTRIBUTE* attr =
18883
             (WOLFSSL_X509_ATTRIBUTE*)wolfSSL_sk_value(req->reqAttributes, idx);
18884
        if (attr != NULL && attr->object != NULL && attr->object->nid == nid)
18885
            return idx;
18886
    }
18887
18888
    return WOLFSSL_FATAL_ERROR;
18889
}
18890
18891
WOLFSSL_X509_ATTRIBUTE* wolfSSL_X509_ATTRIBUTE_new(void)
18892
{
18893
    WOLFSSL_X509_ATTRIBUTE* ret;
18894
    WOLFSSL_ENTER("wolfSSL_X509_ATTRIBUTE_new");
18895
    ret = (WOLFSSL_X509_ATTRIBUTE*)XMALLOC(sizeof(WOLFSSL_X509_ATTRIBUTE),
18896
            NULL, DYNAMIC_TYPE_OPENSSL);
18897
    if (!ret) {
18898
        WOLFSSL_MSG("malloc error");
18899
        return NULL;
18900
    }
18901
    XMEMSET(ret, 0, sizeof(WOLFSSL_X509_ATTRIBUTE));
18902
    ret->object = wolfSSL_ASN1_OBJECT_new();
18903
    ret->value = wolfSSL_ASN1_TYPE_new();
18904
    /* Don't allocate ret->set since WOLFSSL_ASN1_TYPE
18905
     * is not supported as a stack type */
18906
    if (!ret->object || !ret->value) {
18907
        WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new or wolfSSL_ASN1_TYPE_new error");
18908
        wolfSSL_X509_ATTRIBUTE_free(ret);
18909
        return NULL;
18910
    }
18911
    return ret;
18912
}
18913
18914
void wolfSSL_X509_ATTRIBUTE_free(WOLFSSL_X509_ATTRIBUTE* attr)
18915
{
18916
    WOLFSSL_ENTER("wolfSSL_X509_ATTRIBUTE_free");
18917
    if (attr) {
18918
        if (attr->object) {
18919
            wolfSSL_ASN1_OBJECT_free(attr->object);
18920
        }
18921
        if (attr->value) {
18922
            wolfSSL_ASN1_TYPE_free(attr->value);
18923
        }
18924
        if (attr->set) {
18925
            wolfSSL_sk_pop_free(attr->set, NULL);
18926
        }
18927
        XFREE(attr, NULL, DYNAMIC_TYPE_OPENSSL);
18928
    }
18929
}
18930
#endif /* (OPENSSL_ALL || OPENSSL_EXTRA) &&
18931
          (WOLFSSL_CERT_GEN || WOLFSSL_CERT_REQ) */
18932
18933
#if defined(WOLFSSL_ACERT) && \
18934
   (defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA))
18935
18936
/* Allocate and return a new WOLFSSL_X509_ACERT struct pointer.
18937
 *
18938
 * @param [in]      heap        heap hint
18939
 *
18940
 * @return  pointer  on success
18941
 * @return  NULL     on error
18942
 * */
18943
WOLFSSL_X509_ACERT * wolfSSL_X509_ACERT_new_ex(void* heap)
18944
{
18945
    WOLFSSL_X509_ACERT * x509 = NULL;
18946
18947
    WOLFSSL_ENTER("wolfSSL_X509_ACERT_new");
18948
18949
    x509 = (WOLFSSL_X509_ACERT*) XMALLOC(sizeof(WOLFSSL_X509_ACERT), heap,
18950
                                         DYNAMIC_TYPE_X509_ACERT);
18951
18952
    if (x509 != NULL) {
18953
        wolfSSL_X509_ACERT_init(x509, 1, heap);
18954
    }
18955
18956
    return x509;
18957
}
18958
18959
WOLFSSL_X509_ACERT * wolfSSL_X509_ACERT_new(void)
18960
{
18961
    return wolfSSL_X509_ACERT_new_ex(NULL);
18962
}
18963
18964
/* Initialize a WOLFSSL_X509_ACERT struct.
18965
 *
18966
 * If dynamic == 1, then the x509 pointer will be freed
18967
 * in wolfSSL_X509_ACERT_free.
18968
 *
18969
 * @param [in]      x509        x509 acert pointer
18970
 * @param [in]      dynamic     dynamic mem flag
18971
 * @param [in]      heap        heap hint
18972
 *
18973
 * @return  void
18974
 * */
18975
void wolfSSL_X509_ACERT_init(WOLFSSL_X509_ACERT * x509, int dynamic, void* heap)
18976
{
18977
    WOLFSSL_ENTER("wolfSSL_X509_ACERT_init");
18978
18979
    if (x509 == NULL) {
18980
        WOLFSSL_MSG("error: InitX509Acert: null parameter");
18981
        return;
18982
    }
18983
18984
    XMEMSET(x509, 0, sizeof(*x509));
18985
18986
    x509->heap = heap;
18987
    x509->dynamic = dynamic;
18988
}
18989
18990
/* Free a WOLFSSL_X509_ACERT struct and its sub-fields.
18991
 *
18992
 * If this ACERT was initialized with dynamic == 1, then
18993
 * the x509 pointer itself will be freed as well.
18994
 *
18995
 * @param [in]      x509        x509 acert pointer
18996
 *
18997
 * @return  void
18998
 * */
18999
void wolfSSL_X509_ACERT_free(WOLFSSL_X509_ACERT * x509)
19000
{
19001
    int    dynamic = 0;
19002
    void * heap = NULL;
19003
19004
    WOLFSSL_ENTER("wolfSSL_X509_ACERT_free");
19005
19006
    if (x509 == NULL) {
19007
        WOLFSSL_MSG("error: wolfSSL_X509_ACERT_free: null parameter");
19008
        return;
19009
    }
19010
19011
    dynamic = x509->dynamic;
19012
    heap = x509->heap;
19013
19014
    /* Free holder and att cert issuer structures. */
19015
    if (x509->holderIssuerName) {
19016
        FreeAltNames(x509->holderIssuerName, heap);
19017
        x509->holderIssuerName = NULL;
19018
    }
19019
19020
    if (x509->holderEntityName) {
19021
        FreeAltNames(x509->holderEntityName, heap);
19022
        x509->holderEntityName = NULL;
19023
    }
19024
19025
    if (x509->AttCertIssuerName) {
19026
        FreeAltNames(x509->AttCertIssuerName, heap);
19027
        x509->AttCertIssuerName = NULL;
19028
    }
19029
19030
    if (x509->rawAttr != NULL) {
19031
        XFREE(x509->rawAttr, heap, DYNAMIC_TYPE_X509_EXT);
19032
        x509->rawAttr = NULL;
19033
        x509->rawAttrLen = 0;
19034
    }
19035
19036
    /* Free derCert source and signature buffer. */
19037
    FreeDer(&x509->derCert);
19038
19039
    if (x509->sig.buffer != NULL) {
19040
        XFREE(x509->sig.buffer, heap, DYNAMIC_TYPE_SIGNATURE);
19041
        x509->sig.buffer = NULL;
19042
    }
19043
19044
    /* Finally memset and free x509 acert structure. */
19045
    XMEMSET(x509, 0, sizeof(*x509));
19046
19047
    if (dynamic == 1) {
19048
        XFREE(x509, heap, DYNAMIC_TYPE_X509_ACERT);
19049
    }
19050
19051
    return;
19052
}
19053
19054
#if defined(OPENSSL_EXTRA)
19055
long wolfSSL_X509_ACERT_get_version(const WOLFSSL_X509_ACERT* x509)
19056
{
19057
    int version = 0;
19058
19059
    if (x509 == NULL) {
19060
        return 0L;
19061
    }
19062
19063
    version = x509->version;
19064
19065
    return version != 0 ? (long)version - 1L : 0L;
19066
}
19067
#endif /* OPENSSL_EXTRA */
19068
19069
int wolfSSL_X509_ACERT_version(WOLFSSL_X509_ACERT* x509)
19070
{
19071
    if (x509 == NULL) {
19072
        return 0;
19073
    }
19074
19075
    return x509->version;
19076
}
19077
19078
/* Retrieve the serial number from an ACERT.
19079
 *
19080
 * @param [in]       x509    the x509 attribute certificate
19081
 * @param [in, out]  buf     the serial number buffer pointer
19082
 * @param [in, out]  bufSz   the serial number buffer size pointer
19083
 *
19084
 * buf may be null, but bufSz is required. On success, sets
19085
 * bufSz pointer to signature length, and copies signature
19086
 * to buf if provided.
19087
 *
19088
 * Returns  WWOLFSSL_FATAL_ERROR if bufSz is null or too small.
19089
 * Returns  WOLFSSL_SUCCESS on success.
19090
 */
19091
int wolfSSL_X509_ACERT_get_serial_number(WOLFSSL_X509_ACERT* x509,
19092
                                         byte* buf, int* bufSz)
19093
{
19094
    WOLFSSL_ENTER("wolfSSL_X509_ACERT_get_serial_number");
19095
19096
    if (x509 == NULL || bufSz == NULL) {
19097
        WOLFSSL_MSG("error: null argument passed in");
19098
        return BAD_FUNC_ARG;
19099
    }
19100
19101
    if (buf != NULL) {
19102
        if (*bufSz < x509->serialSz) {
19103
            WOLFSSL_MSG("error: serial buffer too small");
19104
            return BUFFER_E;
19105
        }
19106
19107
        XMEMCPY(buf, x509->serial, x509->serialSz);
19108
    }
19109
19110
    *bufSz = x509->serialSz;
19111
19112
    return WOLFSSL_SUCCESS;
19113
}
19114
19115
/* Sets buf pointer and len to raw Attribute buffer and buffer len
19116
 * in X509 struct.
19117
 *
19118
 * Returns WOLFSSL_SUCCESS on success.
19119
 * Returns BAD_FUNC_ARG if input pointers are null.
19120
 * */
19121
int wolfSSL_X509_ACERT_get_attr_buf(const WOLFSSL_X509_ACERT* x509,
19122
                                                const byte ** rawAttr,
19123
                                                word32 * rawAttrLen)
19124
{
19125
    if (x509 == NULL || rawAttr == NULL || rawAttrLen == NULL) {
19126
        return BAD_FUNC_ARG;
19127
    }
19128
19129
    *rawAttr = x509->rawAttr;
19130
    *rawAttrLen = x509->rawAttrLen;
19131
19132
    return WOLFSSL_SUCCESS;
19133
}
19134
19135
#ifndef NO_WOLFSSL_STUB
19136
int wolfSSL_X509_ACERT_sign(WOLFSSL_X509_ACERT * x509,
19137
                                        WOLFSSL_EVP_PKEY * pkey,
19138
                                        const WOLFSSL_EVP_MD * md)
19139
{
19140
    WOLFSSL_STUB("X509_ACERT_sign");
19141
    (void) x509;
19142
    (void) pkey;
19143
    (void) md;
19144
    return WOLFSSL_NOT_IMPLEMENTED;
19145
}
19146
#endif /* NO_WOLFSSL_STUB */
19147
19148
/* Helper function for ACERT_verify.
19149
 *
19150
 * @param [in]       x509    the x509 attribute certificate
19151
 * @param [in, out]  outSz   the x509 der length
19152
 *
19153
 * @return  der buffer on success
19154
 * @return  NULL on error
19155
 * */
19156
static const byte* acert_get_der(WOLFSSL_X509_ACERT * x509, int* outSz)
19157
{
19158
    if (x509 == NULL || x509->derCert == NULL || outSz == NULL) {
19159
        return NULL;
19160
    }
19161
19162
    *outSz = (int)x509->derCert->length;
19163
    return x509->derCert->buffer;
19164
}
19165
19166
/* Given an X509_ACERT and EVP_PKEY, verify the acert's signature.
19167
 *
19168
 * @param [in]    x509    the x509 attribute certificate
19169
 * @param [in]    pkey    the evp_pkey
19170
 *
19171
 * @return  WOLFSSL_SUCCESS on verify success
19172
 * @return  < 0 on error
19173
 * */
19174
int wolfSSL_X509_ACERT_verify(WOLFSSL_X509_ACERT* x509, WOLFSSL_EVP_PKEY* pkey)
19175
{
19176
    int          ret = 0;
19177
    const byte * der = NULL;
19178
    int          derSz = 0;
19179
    int          pkey_type;
19180
19181
    if (x509 == NULL || pkey == NULL) {
19182
        WOLFSSL_MSG("error: wolfSSL_X509_ACERT_verify: bad arg");
19183
        return WOLFSSL_FATAL_ERROR;
19184
    }
19185
19186
    WOLFSSL_ENTER("wolfSSL_X509_ACERT_verify");
19187
19188
    der = acert_get_der(x509, &derSz);
19189
19190
    if (der == NULL || derSz <= 0) {
19191
        WOLFSSL_MSG("error: wolfSSL_X509_ACERT_verify: get der failed");
19192
        return WOLFSSL_FATAL_ERROR;
19193
    }
19194
19195
    switch (pkey->type) {
19196
    case WC_EVP_PKEY_RSA:
19197
        pkey_type = RSAk;
19198
        break;
19199
19200
    case WC_EVP_PKEY_EC:
19201
        pkey_type = ECDSAk;
19202
        break;
19203
19204
    case WC_EVP_PKEY_DSA:
19205
        pkey_type = DSAk;
19206
        break;
19207
19208
    default:
19209
        WOLFSSL_MSG("error: wolfSSL_X509_ACERT_verify: unknown pkey type");
19210
        return WOLFSSL_FATAL_ERROR;
19211
    }
19212
19213
19214
    ret = VerifyX509Acert(der, (word32)derSz,
19215
                          (const byte *)pkey->pkey.ptr, pkey->pkey_sz,
19216
                          pkey_type, x509->heap);
19217
19218
    return ret == 0 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
19219
}
19220
19221
/* Loads an x509 attribute certificate from buffer, and returns
19222
 * pointer to new WOLFSSL_X509_ACERT struct on success.
19223
 *
19224
 * @param [in]  buf    The acert buffer to load.
19225
 * @param [in]  sz     The size of the buffer.
19226
 * @param [in]  format The format of the buffer data.
19227
 * @param [in]  heap   Dynamic memory allocation hint.
19228
 *
19229
 * @return  pointer to WOLFSSL_X509_ACERT on success.
19230
 * @return  NULL on error.
19231
 * */
19232
WOLFSSL_X509_ACERT * wolfSSL_X509_ACERT_load_certificate_buffer_ex(
19233
    const unsigned char* buf, int sz, int format, void * heap)
19234
{
19235
    int                  ret = 0;
19236
    WOLFSSL_X509_ACERT * x509 = NULL;
19237
    DerBuffer *          der = NULL;
19238
    WC_DECLARE_VAR(acert, DecodedAcert, 1, 0);
19239
19240
    WOLFSSL_ENTER("wolfSSL_X509_ACERT_load_certificate_buffer");
19241
19242
    if (format == WOLFSSL_FILETYPE_PEM) {
19243
    #ifdef WOLFSSL_PEM_TO_DER
19244
        ret = PemToDer(buf, sz, ACERT_TYPE, &der, heap, NULL, NULL);
19245
19246
        if (ret != 0 || der == NULL || der->buffer == NULL) {
19247
            WOLFSSL_ERROR(ret);
19248
19249
            if (der != NULL) {
19250
                FreeDer(&der);
19251
            }
19252
19253
            return NULL;
19254
        }
19255
    #else
19256
        WOLFSSL_ERROR(NOT_COMPILED_IN);
19257
        return NULL;
19258
    #endif
19259
    }
19260
    else {
19261
        ret = AllocDer(&der, (word32)sz, ACERT_TYPE, heap);
19262
19263
        if (ret != 0 || der == NULL || der->buffer == NULL) {
19264
            WOLFSSL_ERROR(ret);
19265
            return NULL;
19266
        }
19267
19268
        XMEMCPY(der->buffer, buf, sz);
19269
    }
19270
19271
    #ifdef WOLFSSL_SMALL_STACK
19272
    acert = (DecodedAcert*)XMALLOC(sizeof(DecodedAcert), heap,
19273
                                   DYNAMIC_TYPE_DCERT);
19274
    if (acert == NULL) {
19275
        WOLFSSL_ERROR(MEMORY_ERROR);
19276
        FreeDer(&der);
19277
        return NULL;
19278
    }
19279
    #endif
19280
19281
    InitDecodedAcert(acert, der->buffer, der->length, heap);
19282
19283
    ret = ParseX509Acert(acert, VERIFY_SKIP_DATE);
19284
19285
    if (ret == 0) {
19286
        x509 = wolfSSL_X509_ACERT_new_ex(heap);
19287
19288
        if (x509 != NULL) {
19289
            ret = CopyDecodedAcertToX509(x509, acert);
19290
19291
            if (ret != 0) {
19292
                wolfSSL_X509_ACERT_free(x509);
19293
                x509 = NULL;
19294
            }
19295
        }
19296
        else {
19297
            ret = MEMORY_ERROR;
19298
        }
19299
    }
19300
19301
    FreeDecodedAcert(acert);
19302
19303
    WC_FREE_VAR_EX(acert, heap, DYNAMIC_TYPE_DCERT);
19304
19305
    FreeDer(&der);
19306
19307
    if (ret != 0) {
19308
        WOLFSSL_ERROR(ret);
19309
    }
19310
19311
    return x509;
19312
}
19313
19314
WOLFSSL_X509_ACERT * wolfSSL_X509_ACERT_load_certificate_buffer(
19315
    const unsigned char* buf, int sz, int format)
19316
{
19317
    return wolfSSL_X509_ACERT_load_certificate_buffer_ex(buf, sz, format, NULL);
19318
}
19319
19320
/* Retrieve the signature from an ACERT.
19321
 *
19322
 * @param [in]       x509    the x509 attribute certificate
19323
 * @param [in, out]  buf     the signature buffer pointer
19324
 * @param [in, out]  bufSz   the signature buffer size pointer
19325
 *
19326
 * buf may be null, but bufSz is required. On success, sets
19327
 * bufSz pointer to signature length, and copies signature
19328
 * to buf if provided.
19329
 *
19330
 * Returns  WWOLFSSL_FATAL_ERROR if bufSz is null or too small.
19331
 * Returns  WOLFSSL_SUCCESS on success.
19332
 */
19333
int wolfSSL_X509_ACERT_get_signature(WOLFSSL_X509_ACERT* x509,
19334
                                     unsigned char* buf, int* bufSz)
19335
{
19336
    WOLFSSL_ENTER("wolfSSL_X509_ACERT_get_signature");
19337
19338
    if (x509 == NULL || bufSz == NULL) {
19339
        return WOLFSSL_FATAL_ERROR;
19340
    }
19341
19342
    /* If buf array is provided, it must be long enough. */
19343
    if (buf != NULL && *bufSz < (int)x509->sig.length) {
19344
        return WOLFSSL_FATAL_ERROR;
19345
    }
19346
19347
    if (buf != NULL) {
19348
        /* Copy in buffer if provided. */
19349
        XMEMCPY(buf, x509->sig.buffer, x509->sig.length);
19350
    }
19351
19352
    *bufSz = (int)x509->sig.length;
19353
19354
    return WOLFSSL_SUCCESS;
19355
}
19356
#endif /* WOLFSSL_ACERT && (OPENSSL_EXTRA_X509_SMALL || OPENSSL_EXTRA) */
19357
19358
#endif /* !NO_CERTS */
19359
19360
#endif /* !WOLFCRYPT_ONLY */
19361
19362
#endif /* WOLFSSL_X509_INCLUDED */