Coverage Report

Created: 2025-07-23 06:59

/src/wolfssl/src/x509.c
Line
Count
Source (jump to first uncovered line)
1
/* x509.c
2
 *
3
 * Copyright (C) 2006-2025 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
23
24
#if !defined(WOLFSSL_X509_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
38
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
39
unsigned int wolfSSL_X509_get_extension_flags(WOLFSSL_X509* x509)
40
{
41
    unsigned int flags = 0;
42
43
    WOLFSSL_ENTER("wolfSSL_X509_get_extension_flags");
44
45
    if (x509 != NULL) {
46
        if (x509->keyUsageSet) {
47
            flags |= WOLFSSL_EXFLAG_KUSAGE;
48
        }
49
        if (x509->extKeyUsageSrc != NULL) {
50
            flags |= WOLFSSL_EXFLAG_XKUSAGE;
51
        }
52
    }
53
54
    WOLFSSL_LEAVE("wolfSSL_X509_get_extension_flags", flags);
55
56
    return flags;
57
}
58
59
unsigned int wolfSSL_X509_get_key_usage(WOLFSSL_X509* x509)
60
{
61
    unsigned int ret = 0;
62
63
    WOLFSSL_ENTER("wolfSSL_X509_get_key_usage");
64
65
    if (x509 == NULL) {
66
        WOLFSSL_MSG("x509 is NULL");
67
    }
68
    else {
69
        if (x509->keyUsageSet) {
70
            ret = wolfSSL_X509_get_keyUsage(x509);
71
        }
72
        else {
73
            ret = (unsigned int)-1;
74
        }
75
    }
76
77
    WOLFSSL_LEAVE("wolfSSL_X509_get_key_usage", ret);
78
79
    return ret;
80
}
81
82
unsigned int wolfSSL_X509_get_extended_key_usage(WOLFSSL_X509* x509)
83
{
84
    int ret = 0;
85
86
    WOLFSSL_ENTER("wolfSSL_X509_get_extended_key_usage");
87
88
    if (x509 != NULL) {
89
        if (x509->extKeyUsage & EXTKEYUSE_OCSP_SIGN)
90
            ret |= WOLFSSL_XKU_OCSP_SIGN;
91
        if (x509->extKeyUsage & EXTKEYUSE_TIMESTAMP)
92
            ret |= WOLFSSL_XKU_TIMESTAMP;
93
        if (x509->extKeyUsage & EXTKEYUSE_EMAILPROT)
94
            ret |= WOLFSSL_XKU_SMIME;
95
        if (x509->extKeyUsage & EXTKEYUSE_CODESIGN)
96
            ret |= WOLFSSL_XKU_CODE_SIGN;
97
        if (x509->extKeyUsage & EXTKEYUSE_CLIENT_AUTH)
98
            ret |= WOLFSSL_XKU_SSL_CLIENT;
99
        if (x509->extKeyUsage & EXTKEYUSE_SERVER_AUTH)
100
            ret |= WOLFSSL_XKU_SSL_SERVER;
101
        if (x509->extKeyUsage & EXTKEYUSE_ANY)
102
            ret |= WOLFSSL_XKU_ANYEKU;
103
    }
104
105
    WOLFSSL_LEAVE("wolfSSL_X509_get_extended_key_usage", ret);
106
107
    return (unsigned int)ret;
108
}
109
110
/* Returns the number of X509V3 extensions in X509 object, or 0 on failure */
111
int wolfSSL_X509_get_ext_count(const WOLFSSL_X509* passedCert)
112
{
113
    int extCount = 0;
114
    int length = 0;
115
    int outSz = 0;
116
    const byte* rawCert;
117
    int sz = 0;
118
    word32 idx = 0;
119
    const byte* input;
120
#ifdef WOLFSSL_SMALL_STACK
121
    DecodedCert *cert;
122
#else
123
    DecodedCert cert[1];
124
#endif
125
126
    WOLFSSL_ENTER("wolfSSL_X509_get_ext_count");
127
    if (passedCert == NULL) {
128
        WOLFSSL_MSG("\tNot passed a certificate");
129
        return WOLFSSL_FAILURE;
130
    }
131
132
    rawCert = wolfSSL_X509_get_der((WOLFSSL_X509*)passedCert, &outSz);
133
    if (rawCert == NULL) {
134
        WOLFSSL_MSG("\tpassedCert has no internal DerBuffer set.");
135
        return WOLFSSL_FAILURE;
136
    }
137
138
#ifdef WOLFSSL_SMALL_STACK
139
    cert = (DecodedCert *)XMALLOC(sizeof(*cert), NULL, DYNAMIC_TYPE_DCERT);
140
    if (cert == NULL) {
141
        WOLFSSL_MSG("out of memory");
142
        return WOLFSSL_FAILURE;
143
    }
144
#endif
145
146
    InitDecodedCert(cert, rawCert, (word32)outSz, 0);
147
148
    if (ParseCert(cert,
149
#ifdef WOLFSSL_CERT_REQ
150
            passedCert->isCSR ? CERTREQ_TYPE :
151
#endif
152
                    CA_TYPE,
153
            NO_VERIFY, NULL) < 0) {
154
        WOLFSSL_MSG("\tCertificate parsing failed");
155
        goto out;
156
    }
157
158
    input = cert->extensions;
159
    sz = cert->extensionsSz;
160
161
    if (input == NULL || sz == 0) {
162
        WOLFSSL_MSG("\tsz or input NULL error");
163
        goto out;
164
    }
165
166
#ifdef WOLFSSL_CERT_REQ
167
    if (!passedCert->isCSR)
168
#endif
169
    {
170
        if (input[idx++] != ASN_EXTENSIONS) {
171
            WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
172
            goto out;
173
        }
174
175
        if (GetLength(input, &idx, &length, (word32)sz) < 0) {
176
            WOLFSSL_MSG("\tfail: invalid length");
177
            goto out;
178
        }
179
    }
180
181
    if (GetSequence(input, &idx, &length, (word32)sz) < 0) {
182
        WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
183
        goto out;
184
    }
185
186
    while (idx < (word32)sz) {
187
        if (GetSequence(input, &idx, &length, (word32)sz) < 0) {
188
            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
189
            FreeDecodedCert(cert);
190
            return WOLFSSL_FAILURE;
191
        }
192
        idx += length;
193
        extCount++;
194
    }
195
196
out:
197
198
    FreeDecodedCert(cert);
199
#ifdef WOLFSSL_SMALL_STACK
200
    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
201
#endif
202
    return extCount;
203
}
204
205
/* Creates and returns pointer to a new X509_EXTENSION object in memory */
206
WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_new(void)
207
{
208
    WOLFSSL_X509_EXTENSION* newExt;
209
210
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_new");
211
212
    newExt = (WOLFSSL_X509_EXTENSION*)XMALLOC(sizeof(WOLFSSL_X509_EXTENSION),
213
              NULL, DYNAMIC_TYPE_X509_EXT);
214
    if (newExt == NULL)
215
        return NULL;
216
    XMEMSET(newExt, 0, sizeof(WOLFSSL_X509_EXTENSION));
217
218
    return newExt;
219
}
220
221
222
/* Clear out and free internal pointers of ASN.1 STRING object.
223
 *
224
 * @param [in] asn1  ASN.1 STRING object.
225
 */
226
static void wolfSSL_ASN1_STRING_clear(WOLFSSL_ASN1_STRING* asn1)
227
{
228
    /* Check we have an object to free. */
229
    if (asn1 != NULL) {
230
        /* Dispose of dynamic data. */
231
        if ((asn1->length > 0) && asn1->isDynamic) {
232
            XFREE(asn1->data, NULL, DYNAMIC_TYPE_OPENSSL);
233
        }
234
        XMEMSET(asn1, 0, sizeof(WOLFSSL_ASN1_STRING));
235
    }
236
}
237
238
239
void wolfSSL_X509_EXTENSION_free(WOLFSSL_X509_EXTENSION* x)
240
{
241
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_free");
242
    if (x == NULL)
243
        return;
244
245
    if (x->obj != NULL) {
246
        wolfSSL_ASN1_OBJECT_free(x->obj);
247
    }
248
249
    wolfSSL_ASN1_STRING_clear(&x->value);
250
    wolfSSL_sk_pop_free(x->ext_sk, NULL);
251
252
    XFREE(x, NULL, DYNAMIC_TYPE_X509_EXT);
253
}
254
255
WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_dup(WOLFSSL_X509_EXTENSION* src)
256
{
257
    WOLFSSL_X509_EXTENSION* ret = NULL;
258
    int err = 0;
259
260
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_dup");
261
262
    if (src == NULL) {
263
        err = 1;
264
    }
265
266
    if (err == 0) {
267
        ret = wolfSSL_X509_EXTENSION_new();
268
        if (ret == NULL) {
269
            err = 1;
270
        }
271
    }
272
    if (err == 0 && src->obj != NULL) {
273
        ret->obj = wolfSSL_ASN1_OBJECT_dup(src->obj);
274
        if (ret->obj == NULL) {
275
            err = 1;
276
        }
277
    }
278
    if (err == 0) {
279
        ret->crit = src->crit;
280
        if (wolfSSL_ASN1_STRING_copy(&ret->value, &src->value) !=
281
                WOLFSSL_SUCCESS) {
282
            err = 1;
283
        }
284
    }
285
286
    if (err == 1 && ret != NULL) {
287
        wolfSSL_X509_EXTENSION_free(ret);
288
        ret = NULL;
289
    }
290
291
    return ret;
292
}
293
294
WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_create_by_OBJ(
295
    WOLFSSL_X509_EXTENSION* ex, WOLFSSL_ASN1_OBJECT *obj, int crit,
296
    WOLFSSL_ASN1_STRING *data)
297
{
298
    int err = 0;
299
    WOLFSSL_X509_EXTENSION *ret = ex;
300
301
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_create_by_OBJ");
302
303
    if ((obj == NULL) || (data == NULL)) {
304
       return NULL;
305
    }
306
307
    if (ret == NULL) {
308
        ret = wolfSSL_X509_EXTENSION_new();
309
        if (ret == NULL) {
310
            err = 1;
311
        }
312
    }
313
    else {
314
        /* Prevent potential memory leaks and dangling pointers. */
315
        wolfSSL_ASN1_OBJECT_free(ret->obj);
316
        ret->obj = NULL;
317
        wolfSSL_ASN1_STRING_clear(&ret->value);
318
    }
319
320
    if (err == 0) {
321
        ret->crit = crit;
322
        ret->obj = wolfSSL_ASN1_OBJECT_dup(obj);
323
        if (ret->obj == NULL) {
324
            err = 1;
325
        }
326
    }
327
328
    if (err == 0) {
329
        if (wolfSSL_ASN1_STRING_copy(&ret->value, data) != WOLFSSL_SUCCESS) {
330
            err = 1;
331
        }
332
    }
333
334
    if (err == 1) {
335
        if (ret != ex) {
336
            wolfSSL_X509_EXTENSION_free(ret);
337
        }
338
        ret = NULL;
339
    }
340
    return ret;
341
}
342
343
/* Creates and returns a new WOLFSSL_X509_EXTENSION stack. */
344
WOLFSSL_STACK* wolfSSL_sk_new_x509_ext(void)
345
{
346
    WOLFSSL_STACK* sk;
347
    WOLFSSL_ENTER("wolfSSL_sk_new_x509_ext");
348
349
    sk = wolfSSL_sk_new_null();
350
    if (sk) {
351
        sk->type = STACK_TYPE_X509_EXT;
352
    }
353
    return sk;
354
}
355
356
/* This function does NOT return 1 on success. It returns 0 on fail, and the
357
 * number of items in the stack upon success. This is for compatibility with
358
 * OpenSSL. */
359
int wolfSSL_sk_X509_EXTENSION_push(WOLFSSL_STACK* sk,
360
    WOLFSSL_X509_EXTENSION* ext)
361
{
362
    WOLFSSL_ENTER("wolfSSL_sk_X509_EXTENSION_push");
363
364
    return wolfSSL_sk_push(sk, ext);
365
}
366
367
static WOLFSSL_STACK* generateExtStack(const WOLFSSL_X509 *x)
368
{
369
    int numOfExt, i;
370
    WOLFSSL_X509 *x509 = (WOLFSSL_X509*)x;
371
    WOLFSSL_STACK* ret;
372
    WOLFSSL_STACK* tmp;
373
374
    if (!x509) {
375
        WOLFSSL_MSG("Bad parameter");
376
        return NULL;
377
    }
378
379
    /* Save x509->ext_sk */
380
    tmp = x509->ext_sk;
381
    x509->ext_sk = NULL;
382
    numOfExt = wolfSSL_X509_get_ext_count(x509);
383
384
    for (i = 0; i < numOfExt; i++) {
385
        /* Build the extension stack */
386
        (void)wolfSSL_X509_set_ext(x509, i);
387
    }
388
389
    /* Restore */
390
    ret = x509->ext_sk;
391
    x509->ext_sk = tmp;
392
    return ret;
393
}
394
395
/**
396
 * @param x Certificate to extract extensions from
397
 * @return STACK_OF(X509_EXTENSION)*
398
 */
399
const WOLFSSL_STACK *wolfSSL_X509_get0_extensions(const WOLFSSL_X509 *x)
400
{
401
    int numOfExt;
402
    WOLFSSL_X509 *x509 = (WOLFSSL_X509*)x;
403
    WOLFSSL_ENTER("wolfSSL_X509_get0_extensions");
404
405
    if (!x509) {
406
        WOLFSSL_MSG("Bad parameter");
407
        return NULL;
408
    }
409
410
    numOfExt = wolfSSL_X509_get_ext_count(x509);
411
412
    if (numOfExt != wolfSSL_sk_num(x509->ext_sk_full)) {
413
        wolfSSL_sk_pop_free(x509->ext_sk_full, NULL);
414
        x509->ext_sk_full = generateExtStack(x);
415
    }
416
417
    return x509->ext_sk_full;
418
}
419
420
/**
421
 * Caller is responsible for freeing the returned stack.
422
 */
423
const WOLFSSL_STACK *wolfSSL_X509_REQ_get_extensions(const WOLFSSL_X509 *x)
424
{
425
    return generateExtStack(x);
426
}
427
428
/* Gets the X509_EXTENSION* ext based on it's location in WOLFSSL_X509* x509.
429
 *
430
 * x509   : The X509 structure to look for the extension.
431
 * loc    : Location of the extension. If the extension is found at the given
432
 * location, a new X509_EXTENSION structure is populated with extension-specific
433
 * data based on the extension type.
434
435
 * Returns NULL on error or pointer to X509_EXTENSION structure containing the
436
 * extension. The returned X509_EXTENSION should not be free'd by caller.
437
 * The returned X509_EXTENSION is pushed onto a stack inside the x509 argument.
438
 * This is later free'd when x509 is free'd.
439
 *
440
 * NOTE: for unknown extension NIDs, a X509_EXTENSION is populated with the
441
 * extension oid as the ASN1_OBJECT (QT compatibility)
442
 */
443
WOLFSSL_X509_EXTENSION* wolfSSL_X509_get_ext(const WOLFSSL_X509* x509, int loc)
444
{
445
    WOLFSSL_X509_EXTENSION* ext = NULL;
446
    WOLFSSL_ENTER("wolfSSL_X509_get_ext");
447
    if (x509 == NULL)
448
        return NULL;
449
450
   ext = wolfSSL_X509_set_ext((WOLFSSL_X509*) x509, loc);
451
   return ext;
452
}
453
454
int wolfSSL_X509_get_ext_by_OBJ(const WOLFSSL_X509 *x,
455
        const WOLFSSL_ASN1_OBJECT *obj, int lastpos)
456
{
457
    const WOLF_STACK_OF(WOLFSSL_X509_EXTENSION) *sk;
458
459
    if (!x || !obj) {
460
        WOLFSSL_MSG("Bad parameter");
461
        return WOLFSSL_FATAL_ERROR;
462
    }
463
464
    sk = wolfSSL_X509_get0_extensions(x);
465
    if (!sk) {
466
        WOLFSSL_MSG("No extensions");
467
        return WOLFSSL_FATAL_ERROR;
468
    }
469
    lastpos++;
470
    if (lastpos < 0)
471
        lastpos = 0;
472
    for (; lastpos < wolfSSL_sk_num(sk); lastpos++)
473
        if (wolfSSL_OBJ_cmp(wolfSSL_sk_X509_EXTENSION_value(sk,
474
                        lastpos)->obj, obj) == 0)
475
            return lastpos;
476
    return WOLFSSL_FATAL_ERROR;
477
}
478
479
480
int wolfSSL_X509_OBJECT_set1_X509(WOLFSSL_X509_OBJECT *a, WOLFSSL_X509 *obj)
481
{
482
    WOLFSSL_STUB("wolfSSL_X509_OBJECT_set1_X509");
483
    (void)a;
484
    (void)obj;
485
    return 0;
486
}
487
488
int wolfSSL_X509_OBJECT_set1_X509_CRL(WOLFSSL_X509_OBJECT *a,
489
    WOLFSSL_X509_CRL *obj)
490
{
491
    WOLFSSL_STUB("wolfSSL_X509_OBJECT_set1_X509_CRL");
492
    (void)a;
493
    (void)obj;
494
    return 0;
495
}
496
497
#endif /* OPENSSL_ALL || OPENSSL_EXTRA */
498
499
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
500
    defined(WOLFSSL_WPAS_SMALL)
501
/* Set a general name from the DNS entry data.
502
 *
503
 * @param [in]      dns  DNS entry.
504
 * @param [in, out] gn   General name to place data in.
505
 * @return  1 on success.
506
 * @return  0 on failure.
507
 */
508
static int wolfssl_dns_entry_othername_to_gn(DNS_entry* dns,
509
    WOLFSSL_GENERAL_NAME* gn)
510
{
511
    int ret = 0;
512
    WOLFSSL_ASN1_OBJECT* obj = NULL;
513
    WOLFSSL_ASN1_TYPE* type = NULL;
514
    WOLFSSL_ASN1_STRING* str = NULL;
515
    byte tag = 0;
516
    unsigned char* p = (unsigned char *)dns->name;
517
    long len = dns->len;
518
519
#ifdef WOLFSSL_FPKI
520
    if (dns->oidSum != 0) {
521
        /* UPN OID: 1.3.6.1.4.1.311.20.2.3 */
522
        static const unsigned char upn_oid[] = {
523
            0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x03
524
        };
525
        /* FASCN OID: 2.16.840.1.101.3.6.6 */
526
        static const unsigned char fascn_oid[] = {
527
            0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x06, 0x06
528
        };
529
        const unsigned char* oid;
530
        word32 oidSz;
531
532
        if ((oid = OidFromId(dns->oidSum, oidCertAltNameType, &oidSz)) ==
533
                NULL) {
534
            if (dns->oidSum == UPN_OID) {
535
                oid = upn_oid;
536
                oidSz = (word32)sizeof(upn_oid);
537
            }
538
            else if (dns->oidSum == FASCN_OID) {
539
                oid = fascn_oid;
540
                oidSz = (word32)sizeof(fascn_oid);
541
            }
542
            else {
543
                goto err;
544
            }
545
        }
546
        if ((obj = wolfSSL_c2i_ASN1_OBJECT(NULL, &oid, oidSz)) == NULL) {
547
            goto err;
548
        }
549
550
        tag = WOLFSSL_V_ASN1_UTF8STRING;
551
    }
552
    else
553
#endif
554
    {
555
        word32 idx = 0;
556
        int nameLen;
557
558
        /* Create an object id for general name from DER encoding. */
559
        obj = wolfSSL_d2i_ASN1_OBJECT(NULL, (const unsigned char**)&p, len);
560
        if (obj == NULL)
561
            goto err;
562
        /* Pointer moved on and now update length of remaining data. */
563
        len -= (long)((size_t)p - (size_t)dns->name);
564
565
        /* Next is "value      [0] EXPLICIT ANY DEFINED BY type-id" */
566
        if (GetASNHeader(p, ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0,
567
                &idx, &nameLen, (word32)len) < 0)
568
            goto err;
569
        p += idx;
570
        len -= idx;
571
572
        /* Set the tag to object so that it gets output in raw form */
573
        tag = WOLFSSL_V_ASN1_SEQUENCE;
574
    }
575
576
577
    /* Create a WOLFSSL_ASN1_STRING from the DER. */
578
    str = wolfSSL_ASN1_STRING_type_new(tag);
579
    if (str == NULL) {
580
        goto err;
581
    }
582
    wolfSSL_ASN1_STRING_set(str, p, (int)len);
583
584
    /* Wrap string in a WOLFSSL_ASN1_TYPE. */
585
    type = wolfSSL_ASN1_TYPE_new();
586
    if (type == NULL)
587
        goto err;
588
    wolfSSL_ASN1_TYPE_set(type, tag, str);
589
590
    /* Store the object and string in general name. */
591
    gn->d.otherName->type_id = obj;
592
    gn->d.otherName->value = type;
593
594
    ret = 1;
595
err:
596
    if (ret != 1) {
597
        wolfSSL_ASN1_OBJECT_free(obj);
598
        wolfSSL_ASN1_STRING_free(str);
599
    }
600
    return ret;
601
}
602
#endif /* OPENSSL_ALL || WOLFSSL_WPAS_SMALL */
603
604
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
605
static int DNS_to_GENERAL_NAME(WOLFSSL_GENERAL_NAME* gn, DNS_entry* dns)
606
{
607
    gn->type = dns->type;
608
    switch (gn->type) {
609
        case WOLFSSL_GEN_OTHERNAME:
610
                if (!wolfssl_dns_entry_othername_to_gn(dns, gn)) {
611
                    WOLFSSL_MSG("OTHERNAME set failed");
612
                    return WOLFSSL_FAILURE;
613
                }
614
            break;
615
616
        case WOLFSSL_GEN_EMAIL:
617
        case WOLFSSL_GEN_DNS:
618
        case WOLFSSL_GEN_URI:
619
        case WOLFSSL_GEN_IPADD:
620
        case WOLFSSL_GEN_IA5:
621
                gn->d.ia5->length = dns->len;
622
                if (wolfSSL_ASN1_STRING_set(gn->d.ia5, dns->name,
623
                        gn->d.ia5->length) != WOLFSSL_SUCCESS) {
624
                    WOLFSSL_MSG("ASN1_STRING_set failed");
625
                    return WOLFSSL_FAILURE;
626
                }
627
                break;
628
629
630
        case WOLFSSL_GEN_DIRNAME:
631
            /* wolfSSL_GENERAL_NAME_new() mallocs this by default */
632
            wolfSSL_ASN1_STRING_free(gn->d.ia5);
633
            gn->d.ia5 = NULL;
634
635
            gn->d.dirn = wolfSSL_X509_NAME_new();;
636
            /* @TODO extract dir name info from DNS_entry */
637
            break;
638
639
#ifdef WOLFSSL_RID_ALT_NAME
640
        case WOLFSSL_GEN_RID:
641
            /* wolfSSL_GENERAL_NAME_new() mallocs this by default */
642
            wolfSSL_ASN1_STRING_free(gn->d.ia5);
643
            gn->d.ia5 = NULL;
644
645
            gn->d.registeredID = wolfSSL_ASN1_OBJECT_new();
646
            if (gn->d.registeredID == NULL) {
647
                return WOLFSSL_FAILURE;
648
            }
649
            gn->d.registeredID->obj = (const unsigned char*)XMALLOC(dns->len,
650
                gn->d.registeredID->heap, DYNAMIC_TYPE_ASN1);
651
            if (gn->d.registeredID->obj == NULL) {
652
                /* registeredID gets free'd up by caller after failure */
653
                return WOLFSSL_FAILURE;
654
            }
655
            gn->d.registeredID->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA;
656
            XMEMCPY((byte*)gn->d.registeredID->obj, dns->ridString, dns->len);
657
            gn->d.registeredID->objSz = dns->len;
658
            gn->d.registeredID->grp = oidCertExtType;
659
            gn->d.registeredID->nid = WC_NID_registeredAddress;
660
            break;
661
#endif
662
663
        case WOLFSSL_GEN_X400:
664
            /* Unsupported: fall through */
665
        case WOLFSSL_GEN_EDIPARTY:
666
            /* Unsupported: fall through */
667
        default:
668
            WOLFSSL_MSG("Unsupported type conversion");
669
            return WOLFSSL_FAILURE;
670
    }
671
    return WOLFSSL_SUCCESS;
672
}
673
674
675
static int wolfssl_x509_alt_names_to_gn(WOLFSSL_X509* x509,
676
    WOLFSSL_X509_EXTENSION* ext)
677
{
678
    int ret = 0;
679
    WOLFSSL_GENERAL_NAME* gn = NULL;
680
    DNS_entry* dns = NULL;
681
    WOLFSSL_STACK* sk;
682
683
#ifdef OPENSSL_ALL
684
    ret = wolfSSL_ASN1_STRING_set(&ext->value, x509->subjAltNameSrc,
685
              x509->subjAltNameSz);
686
    if (ret != WOLFSSL_SUCCESS) {
687
        WOLFSSL_MSG("ASN1_STRING_set() failed");
688
        goto err;
689
    }
690
#endif
691
692
    sk = (WOLFSSL_GENERAL_NAMES*)XMALLOC(sizeof(WOLFSSL_GENERAL_NAMES), NULL,
693
        DYNAMIC_TYPE_ASN1);
694
    if (sk == NULL) {
695
        goto err;
696
    }
697
    XMEMSET(sk, 0, sizeof(WOLFSSL_GENERAL_NAMES));
698
    sk->type = STACK_TYPE_GEN_NAME;
699
700
    if (x509->subjAltNameSet && x509->altNames != NULL) {
701
        /* alt names are DNS_entry structs */
702
        dns = x509->altNames;
703
        /* Currently only support GEN_DNS type */
704
        while (dns != NULL) {
705
            gn = wolfSSL_GENERAL_NAME_new();
706
            if (gn == NULL) {
707
                WOLFSSL_MSG("Error creating GENERAL_NAME");
708
                wolfSSL_sk_pop_free(sk, NULL);
709
                goto err;
710
            }
711
712
            if (DNS_to_GENERAL_NAME(gn, dns) != WOLFSSL_SUCCESS) {
713
                wolfSSL_GENERAL_NAME_free(gn);
714
                wolfSSL_sk_pop_free(sk, NULL);
715
                goto err;
716
            }
717
718
            if (wolfSSL_sk_GENERAL_NAME_push(sk, gn) <= 0) {
719
                WOLFSSL_MSG("Error pushing onto stack");
720
                wolfSSL_GENERAL_NAME_free(gn);
721
                wolfSSL_sk_pop_free(sk, NULL);
722
                goto err;
723
            }
724
725
            dns = dns->next;
726
        }
727
    }
728
    ext->ext_sk = sk;
729
    ext->crit = x509->subjAltNameCrit;
730
731
    ret = 1;
732
err:
733
    return ret;
734
}
735
736
/* Pushes a new X509_EXTENSION* ext onto the stack inside WOLFSSL_X509* x509.
737
 * This is currently a helper function for wolfSSL_X509_get_ext
738
 * Caller does not free the returned WOLFSSL_X509_EXTENSION*
739
 */
740
WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc)
741
{
742
    int extCount = 0, length = 0, outSz = 0, sz = 0, ret = 0;
743
    int objSz = 0, isSet = 0;
744
    const byte* rawCert;
745
    const byte* input;
746
    byte* oidBuf;
747
    word32 oid, idx = 0, tmpIdx = 0, nid;
748
    WOLFSSL_X509_EXTENSION* ext = NULL;
749
    WOLFSSL_ASN1_INTEGER* a;
750
    WOLFSSL_STACK* sk;
751
#ifdef WOLFSSL_SMALL_STACK
752
    DecodedCert* cert = NULL;
753
#else
754
    DecodedCert cert[1];
755
#endif
756
757
    WOLFSSL_ENTER("wolfSSL_X509_set_ext");
758
759
    if (x509 == NULL) {
760
        WOLFSSL_MSG("\tNot passed a certificate");
761
        return NULL;
762
    }
763
764
    if (loc < 0 || (loc > wolfSSL_X509_get_ext_count(x509))) {
765
        WOLFSSL_MSG("\tBad location argument");
766
        return NULL;
767
    }
768
769
    ext = wolfSSL_X509_EXTENSION_new();
770
    if (ext == NULL) {
771
        WOLFSSL_MSG("\tX509_EXTENSION_new() failed");
772
        return NULL;
773
    }
774
775
    rawCert = wolfSSL_X509_get_der((WOLFSSL_X509*)x509, &outSz);
776
    if (rawCert == NULL) {
777
        WOLFSSL_MSG("\tX509_get_der() failed");
778
        wolfSSL_X509_EXTENSION_free(ext);
779
        return NULL;
780
    }
781
782
#ifdef WOLFSSL_SMALL_STACK
783
    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT);
784
    if (cert == NULL) {
785
        WOLFSSL_MSG("Failed to allocate memory for DecodedCert");
786
        wolfSSL_X509_EXTENSION_free(ext);
787
        return NULL;
788
    }
789
#endif
790
791
    InitDecodedCert(cert, rawCert, (word32)outSz, 0);
792
793
    if (ParseCert(cert,
794
#ifdef WOLFSSL_CERT_REQ
795
            x509->isCSR ? CERTREQ_TYPE :
796
#endif
797
                    CA_TYPE,
798
            NO_VERIFY, NULL) < 0) {
799
        WOLFSSL_MSG("\tCertificate parsing failed");
800
        wolfSSL_X509_EXTENSION_free(ext);
801
        FreeDecodedCert(cert);
802
    #ifdef WOLFSSL_SMALL_STACK
803
        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
804
    #endif
805
        return NULL;
806
    }
807
808
    input = cert->extensions;
809
    sz = cert->extensionsSz;
810
811
    if (input == NULL || sz == 0) {
812
        WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
813
        wolfSSL_X509_EXTENSION_free(ext);
814
        FreeDecodedCert(cert);
815
#ifdef WOLFSSL_SMALL_STACK
816
        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
817
#endif
818
        return NULL;
819
    }
820
821
#ifdef WOLFSSL_CERT_REQ
822
    if (!x509->isCSR)
823
#endif
824
    {
825
        if (input[idx++] != ASN_EXTENSIONS) {
826
            WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
827
            wolfSSL_X509_EXTENSION_free(ext);
828
            FreeDecodedCert(cert);
829
    #ifdef WOLFSSL_SMALL_STACK
830
            XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
831
    #endif
832
            return NULL;
833
        }
834
835
        if (GetLength(input, &idx, &length, (word32)sz) < 0) {
836
            WOLFSSL_MSG("\tfail: invalid length");
837
            wolfSSL_X509_EXTENSION_free(ext);
838
            FreeDecodedCert(cert);
839
    #ifdef WOLFSSL_SMALL_STACK
840
            XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
841
    #endif
842
            return NULL;
843
        }
844
    }
845
846
    if (GetSequence(input, &idx, &length, (word32)sz) < 0) {
847
        WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
848
        wolfSSL_X509_EXTENSION_free(ext);
849
        FreeDecodedCert(cert);
850
#ifdef WOLFSSL_SMALL_STACK
851
        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
852
#endif
853
        return NULL;
854
    }
855
856
    while (idx < (word32)sz) {
857
        oid = 0;
858
859
        if (GetSequence(input, &idx, &length, (word32)sz) < 0) {
860
            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
861
            wolfSSL_X509_EXTENSION_free(ext);
862
            FreeDecodedCert(cert);
863
    #ifdef WOLFSSL_SMALL_STACK
864
            XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
865
    #endif
866
            return NULL;
867
        }
868
869
        tmpIdx = idx;
870
        ret = GetObjectId(input, &idx, &oid, oidCertExtType, (word32)sz);
871
        if (ret < 0) {
872
            WOLFSSL_MSG("\tfail: OBJECT ID");
873
            wolfSSL_X509_EXTENSION_free(ext);
874
            FreeDecodedCert(cert);
875
        #ifdef WOLFSSL_SMALL_STACK
876
            XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
877
        #endif
878
            return NULL;
879
        }
880
        idx = tmpIdx;
881
        nid = (word32)oid2nid(oid, oidCertExtType);
882
883
        /* Continue while loop until extCount == loc or idx > sz */
884
        if (extCount != loc) {
885
            idx += length;
886
            extCount++;
887
            continue;
888
        }
889
        /* extCount == loc. Now get the extension. */
890
        /* Check if extension has been set */
891
        isSet = wolfSSL_X509_ext_isSet_by_NID((WOLFSSL_X509*)x509, (int)nid);
892
893
        if (wolfSSL_OBJ_nid2ln((int)nid) != NULL) {
894
            /* This is NOT an unknown OID. */
895
            ext->obj = wolfSSL_OBJ_nid2obj((int)nid);
896
            if (ext->obj == NULL) {
897
                WOLFSSL_MSG("\tfail: Invalid OBJECT");
898
                wolfSSL_X509_EXTENSION_free(ext);
899
                FreeDecodedCert(cert);
900
            #ifdef WOLFSSL_SMALL_STACK
901
                XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
902
            #endif
903
                return NULL;
904
            }
905
        }
906
907
        if (ext->obj) {
908
            ext->obj->nid = (int)nid;
909
        }
910
911
        switch (oid) {
912
            case BASIC_CA_OID:
913
            {
914
                word32 dataIdx = idx;
915
                word32 dummyOid;
916
                int dataLen = 0;
917
918
                if (!isSet)
919
                    break;
920
                /* Set pathlength */
921
                a = wolfSSL_ASN1_INTEGER_new();
922
923
                /* Set the data */
924
                ret = GetObjectId(input, &dataIdx, &dummyOid, oidCertExtType,
925
                        (word32)sz) == 0;
926
                if (ret && dataIdx < (word32)sz) {
927
                    /* Skip the critical information */
928
                    if (input[dataIdx] == ASN_BOOLEAN) {
929
                        dataIdx++;
930
                        ret = GetLength(input, &dataIdx, &dataLen, sz) >= 0;
931
                        dataIdx += dataLen;
932
                    }
933
                }
934
                if (ret) {
935
                    ret = GetOctetString(input, &dataIdx, &dataLen,
936
                            (word32)sz) > 0;
937
                }
938
                if (ret) {
939
                    ret = wolfSSL_ASN1_STRING_set(&ext->value, input + dataIdx,
940
                            dataLen) == 1;
941
                }
942
943
                if (a == NULL || !ret) {
944
                    wolfSSL_X509_EXTENSION_free(ext);
945
                    FreeDecodedCert(cert);
946
                #ifdef WOLFSSL_SMALL_STACK
947
                    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
948
                #endif
949
                    return NULL;
950
                }
951
                a->length = (int)x509->pathLength;
952
953
                /* Save ASN1_INTEGER in x509 extension */
954
                ext->obj->pathlen = a;
955
956
                ext->obj->ca = x509->isCa;
957
                ext->crit = x509->basicConstCrit;
958
                break;
959
            }
960
            case AUTH_INFO_OID:
961
                if (!isSet)
962
                    break;
963
964
                /* Create a stack to hold both the caIssuer and ocsp objects
965
                    in X509_EXTENSION structure */
966
                sk = wolfSSL_sk_new_asn1_obj();
967
                if (sk == NULL) {
968
                    WOLFSSL_MSG("Failed to malloc stack");
969
                    wolfSSL_X509_EXTENSION_free(ext);
970
                    FreeDecodedCert(cert);
971
                #ifdef WOLFSSL_SMALL_STACK
972
                    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
973
                #endif
974
                    return NULL;
975
                }
976
977
                /* Add CaIssuers object to stack */
978
                if (x509->authInfoCaIssuer != NULL &&
979
                    x509->authInfoCaIssuerSz > 0)
980
                {
981
                    WOLFSSL_ASN1_OBJECT* obj;
982
                    obj = wolfSSL_ASN1_OBJECT_new();
983
                    if (obj == NULL) {
984
                        WOLFSSL_MSG("Error creating ASN1 object");
985
                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
986
                        wolfSSL_X509_EXTENSION_free(ext);
987
                        FreeDecodedCert(cert);
988
                    #ifdef WOLFSSL_SMALL_STACK
989
                        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
990
                    #endif
991
                        return NULL;
992
                    }
993
                    obj->obj = (byte*)x509->authInfoCaIssuer;
994
                    obj->objSz = (unsigned int)x509->authInfoCaIssuerSz;
995
                    obj->grp = oidCertAuthInfoType;
996
                    obj->nid = WC_NID_ad_ca_issuers;
997
998
                    ret = wolfSSL_sk_ASN1_OBJECT_push(sk, obj) > 0
999
                            ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
1000
                    if (ret != WOLFSSL_SUCCESS) {
1001
                        WOLFSSL_MSG("Error pushing ASN1 object onto stack");
1002
                        wolfSSL_ASN1_OBJECT_free(obj);
1003
                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
1004
                        wolfSSL_X509_EXTENSION_free(ext);
1005
                        FreeDecodedCert(cert);
1006
                    #ifdef WOLFSSL_SMALL_STACK
1007
                        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1008
                    #endif
1009
                        return NULL;
1010
                    }
1011
                }
1012
1013
                /* Add OCSP object to stack */
1014
                if (x509->authInfo != NULL &&
1015
                    x509->authInfoSz > 0)
1016
                {
1017
                    WOLFSSL_ASN1_OBJECT* obj;
1018
                    obj = wolfSSL_ASN1_OBJECT_new();
1019
                    if (obj == NULL) {
1020
                        WOLFSSL_MSG("Error creating ASN1 object");
1021
                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
1022
                        wolfSSL_X509_EXTENSION_free(ext);
1023
                        FreeDecodedCert(cert);
1024
                    #ifdef WOLFSSL_SMALL_STACK
1025
                        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1026
                    #endif
1027
                        return NULL;
1028
                    }
1029
                    obj->obj = x509->authInfo;
1030
                    obj->objSz = (unsigned int)x509->authInfoSz;
1031
                    obj->grp = oidCertAuthInfoType;
1032
                    obj->nid = WC_NID_ad_OCSP;
1033
1034
                    ret = wolfSSL_sk_ASN1_OBJECT_push(sk, obj) > 0
1035
                            ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
1036
                    if (ret != WOLFSSL_SUCCESS) {
1037
                        WOLFSSL_MSG("Error pushing ASN1 object onto stack");
1038
                        wolfSSL_ASN1_OBJECT_free(obj);
1039
                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
1040
                        wolfSSL_X509_EXTENSION_free(ext);
1041
                        FreeDecodedCert(cert);
1042
                    #ifdef WOLFSSL_SMALL_STACK
1043
                        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1044
                    #endif
1045
                        return NULL;
1046
                    }
1047
                }
1048
                ext->ext_sk = sk;
1049
                ext->crit = x509->authInfoCrit;
1050
                break;
1051
1052
            case AUTH_KEY_OID:
1053
                if (!isSet)
1054
                    break;
1055
1056
                ret = wolfSSL_ASN1_STRING_set(&ext->value, x509->authKeyId,
1057
                                        x509->authKeyIdSz);
1058
                if (ret != WOLFSSL_SUCCESS) {
1059
                    WOLFSSL_MSG("ASN1_STRING_set() failed");
1060
                    wolfSSL_X509_EXTENSION_free(ext);
1061
                    FreeDecodedCert(cert);
1062
                #ifdef WOLFSSL_SMALL_STACK
1063
                    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1064
                #endif
1065
                    return NULL;
1066
                }
1067
                ext->crit = x509->authKeyIdCrit;
1068
                break;
1069
1070
            case SUBJ_KEY_OID:
1071
                if (!isSet)
1072
                    break;
1073
1074
                ret = wolfSSL_ASN1_STRING_set(&ext->value, x509->subjKeyId,
1075
                                        x509->subjKeyIdSz);
1076
                if (ret != WOLFSSL_SUCCESS) {
1077
                    WOLFSSL_MSG("ASN1_STRING_set() failed");
1078
                    wolfSSL_X509_EXTENSION_free(ext);
1079
                    FreeDecodedCert(cert);
1080
                #ifdef WOLFSSL_SMALL_STACK
1081
                    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1082
                #endif
1083
                    return NULL;
1084
                }
1085
                ext->crit = x509->subjKeyIdCrit;
1086
                break;
1087
1088
            case CERT_POLICY_OID:
1089
                if (!isSet)
1090
                    break;
1091
            #ifdef WOLFSSL_SEP
1092
                ext->crit = x509->certPolicyCrit;
1093
            #endif
1094
                break;
1095
1096
            case KEY_USAGE_OID:
1097
                if (!isSet)
1098
                    break;
1099
1100
                ret = wolfSSL_ASN1_STRING_set(&ext->value,
1101
                                  (byte*)&(x509->keyUsage), sizeof(word16));
1102
                if (ret != WOLFSSL_SUCCESS) {
1103
                    WOLFSSL_MSG("ASN1_STRING_set() failed");
1104
                    wolfSSL_X509_EXTENSION_free(ext);
1105
                    FreeDecodedCert(cert);
1106
                #ifdef WOLFSSL_SMALL_STACK
1107
                    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1108
                #endif
1109
                    return NULL;
1110
                }
1111
                ext->crit = x509->keyUsageCrit;
1112
                break;
1113
1114
            case EXT_KEY_USAGE_OID:
1115
                if (!isSet)
1116
                    break;
1117
1118
                ret = wolfSSL_ASN1_STRING_set(&ext->value, x509->extKeyUsageSrc,
1119
                                              x509->extKeyUsageSz);
1120
                if (ret != WOLFSSL_SUCCESS) {
1121
                    WOLFSSL_MSG("ASN1_STRING_set() failed");
1122
                    wolfSSL_X509_EXTENSION_free(ext);
1123
                    FreeDecodedCert(cert);
1124
                #ifdef WOLFSSL_SMALL_STACK
1125
                    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1126
                #endif
1127
                    return NULL;
1128
                }
1129
                ext->crit = x509->extKeyUsageCrit;
1130
                break;
1131
1132
            case CRL_DIST_OID:
1133
                if (!isSet)
1134
                    break;
1135
                ext->crit = x509->CRLdistCrit;
1136
                break;
1137
1138
            case ALT_NAMES_OID:
1139
                if (!isSet)
1140
                    break;
1141
                if (!wolfssl_x509_alt_names_to_gn(x509, ext)) {
1142
                    wolfSSL_X509_EXTENSION_free(ext);
1143
                    FreeDecodedCert(cert);
1144
                #ifdef WOLFSSL_SMALL_STACK
1145
                    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1146
                #endif
1147
                    return NULL;
1148
                }
1149
                break;
1150
1151
            default:
1152
                WOLFSSL_MSG("Unknown extension type found, parsing OID");
1153
                /* If the extension type is not recognized/supported,
1154
                 *  set the ASN1_OBJECT in the extension with the
1155
                 *  parsed oid for access in later function calls */
1156
1157
                /* Get OID from input */
1158
                if (GetASNObjectId(input, &idx, &length, (word32)sz) != 0) {
1159
                    WOLFSSL_MSG("Failed to Get ASN Object Id");
1160
                    wolfSSL_X509_EXTENSION_free(ext);
1161
                    FreeDecodedCert(cert);
1162
                #ifdef WOLFSSL_SMALL_STACK
1163
                    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1164
                #endif
1165
                    return NULL;
1166
                }
1167
                oidBuf = (byte*)XMALLOC(length+1+MAX_LENGTH_SZ, NULL,
1168
                                    DYNAMIC_TYPE_TMP_BUFFER);
1169
                if (oidBuf == NULL) {
1170
                    WOLFSSL_MSG("Failed to malloc tmp buffer");
1171
                    wolfSSL_X509_EXTENSION_free(ext);
1172
                    FreeDecodedCert(cert);
1173
                #ifdef WOLFSSL_SMALL_STACK
1174
                    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1175
                #endif
1176
                    return NULL;
1177
                }
1178
                oidBuf[0] = ASN_OBJECT_ID;
1179
                objSz++;
1180
                objSz += SetLength(length, oidBuf + 1);
1181
                objSz += length;
1182
1183
                /* Set object size and reallocate space in object buffer */
1184
                if (ext->obj == NULL) {
1185
                    ext->obj = wolfSSL_ASN1_OBJECT_new();
1186
                    if (ext->obj == NULL) {
1187
                        XFREE(oidBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1188
                        wolfSSL_X509_EXTENSION_free(ext);
1189
                        FreeDecodedCert(cert);
1190
                #ifdef WOLFSSL_SMALL_STACK
1191
                        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1192
                #endif
1193
                        return NULL;
1194
                    }
1195
                }
1196
1197
                if (((ext->obj->dynamic & WOLFSSL_ASN1_DYNAMIC_DATA) != 0) ||
1198
                    (ext->obj->obj == NULL)) {
1199
                #ifdef WOLFSSL_NO_REALLOC
1200
                    byte* tmp = NULL;
1201
1202
                    tmp = (byte*)XMALLOC(objSz, NULL, DYNAMIC_TYPE_ASN1);
1203
                    if (tmp != NULL && ext->obj->obj != NULL) {
1204
                        XMEMCPY(tmp, ext->obj->obj, ext->obj->objSz);
1205
                        XFREE((byte*)ext->obj->obj, NULL, DYNAMIC_TYPE_ASN1);
1206
                    }
1207
                    else if (tmp == NULL) {
1208
                        ext->obj->obj = tmp;
1209
                    }
1210
                    ext->obj->obj = tmp;
1211
                #else
1212
                    ext->obj->obj = (byte*)XREALLOC((byte*)ext->obj->obj, objSz,
1213
                                           NULL, DYNAMIC_TYPE_ASN1);
1214
                #endif
1215
                    if (ext->obj->obj == NULL) {
1216
                        wolfSSL_X509_EXTENSION_free(ext);
1217
                        FreeDecodedCert(cert);
1218
                        XFREE(oidBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1219
                    #ifdef WOLFSSL_SMALL_STACK
1220
                        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1221
                    #endif
1222
                        return NULL;
1223
                    }
1224
                    ext->obj->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA;
1225
                }
1226
                else {
1227
                    ext->obj->dynamic &= ~WOLFSSL_ASN1_DYNAMIC_DATA;
1228
                }
1229
                ext->obj->objSz = (unsigned int)objSz;
1230
1231
                /* Get OID from input and copy to ASN1_OBJECT buffer */
1232
                XMEMCPY(oidBuf+2, input+idx, length);
1233
                XMEMCPY((byte*)ext->obj->obj, oidBuf, ext->obj->objSz);
1234
                XFREE(oidBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1235
                oidBuf = NULL;
1236
                ext->obj->grp = oidCertExtType;
1237
                ext->crit = 0;
1238
1239
                /* Get extension data and copy as ASN1_STRING */
1240
                tmpIdx = idx + length;
1241
                if ((tmpIdx >= (word32)sz) ||
1242
                    (input[tmpIdx] != ASN_OCTET_STRING))
1243
                {
1244
                    WOLFSSL_MSG("Error decoding unknown extension data");
1245
                    wolfSSL_ASN1_OBJECT_free(ext->obj);
1246
                    wolfSSL_X509_EXTENSION_free(ext);
1247
                    FreeDecodedCert(cert);
1248
                #ifdef WOLFSSL_SMALL_STACK
1249
                    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1250
                #endif
1251
                    return NULL;
1252
                }
1253
1254
                tmpIdx++;
1255
1256
                if (GetLength(input, &tmpIdx, &length, (word32)sz) <= 0) {
1257
                    WOLFSSL_MSG("Error: Invalid Input Length.");
1258
                    wolfSSL_ASN1_OBJECT_free(ext->obj);
1259
                    wolfSSL_X509_EXTENSION_free(ext);
1260
                    FreeDecodedCert(cert);
1261
                #ifdef WOLFSSL_SMALL_STACK
1262
                    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1263
                #endif
1264
                    return NULL;
1265
                }
1266
                ext->value.data = (char*)XMALLOC(length, NULL,
1267
                    DYNAMIC_TYPE_ASN1);
1268
                ext->value.isDynamic = 1;
1269
                if (ext->value.data == NULL) {
1270
                    WOLFSSL_MSG("Failed to malloc ASN1_STRING data");
1271
                    wolfSSL_X509_EXTENSION_free(ext);
1272
                    FreeDecodedCert(cert);
1273
                #ifdef WOLFSSL_SMALL_STACK
1274
                    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1275
                #endif
1276
                    return NULL;
1277
                }
1278
                XMEMCPY(ext->value.data,input+tmpIdx,length);
1279
                ext->value.length = length;
1280
        } /* switch(oid) */
1281
1282
        break; /* Got the Extension. Now exit while loop. */
1283
1284
    } /* while(idx < sz) */
1285
1286
    /* Store the new extension in a stack inside x509
1287
     * The extensions on the stack are free'd internally when FreeX509 is called
1288
     */
1289
    if (x509->ext_sk == NULL)
1290
        x509->ext_sk = wolfSSL_sk_new_x509_ext();
1291
    if (wolfSSL_sk_insert(x509->ext_sk, ext, -1) <= 0) {
1292
        wolfSSL_X509_EXTENSION_free(ext);
1293
        ext = NULL;
1294
    }
1295
1296
    FreeDecodedCert(cert);
1297
#ifdef WOLFSSL_SMALL_STACK
1298
    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1299
#endif
1300
    return ext;
1301
}
1302
1303
/**
1304
 * @param str String to copy
1305
 * @param buf Output buffer. If this contains a pointer then it is free'd
1306
 *            with the DYNAMIC_TYPE_X509_EXT hint.
1307
 * @param len Output length
1308
 * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on error
1309
 */
1310
static int asn1_string_copy_to_buffer(WOLFSSL_ASN1_STRING* str, byte** buf,
1311
        word32* len, void* heap)
1312
{
1313
    if (str->data && str->length > 0) {
1314
        if (*buf)
1315
            XFREE(*buf, heap, DYNAMIC_TYPE_X509_EXT);
1316
        *len = 0;
1317
        *buf = (byte*)XMALLOC(str->length, heap, DYNAMIC_TYPE_X509_EXT);
1318
        if (!*buf) {
1319
            WOLFSSL_MSG("malloc error");
1320
            return WOLFSSL_FAILURE;
1321
        }
1322
        *len = (word32)str->length;
1323
        XMEMCPY(*buf, str->data, str->length);
1324
    }
1325
1326
    (void)heap;
1327
    return WOLFSSL_SUCCESS;
1328
}
1329
1330
int wolfSSL_X509_add_ext(WOLFSSL_X509 *x509, WOLFSSL_X509_EXTENSION *ext,
1331
    int loc)
1332
{
1333
    int nid;
1334
1335
    WOLFSSL_ENTER("wolfSSL_X509_add_ext");
1336
1337
    if (!x509 || !ext || loc >= 0) {
1338
        WOLFSSL_MSG("Bad parameter");
1339
        return WOLFSSL_FAILURE;
1340
    }
1341
    nid = (ext->obj != NULL) ? ext->obj->type : ext->value.nid;
1342
1343
    switch (nid) {
1344
    case WC_NID_authority_key_identifier:
1345
        if (x509->authKeyIdSrc != NULL) {
1346
            /* If authKeyId points into authKeyIdSrc then free it and
1347
             * revert to old functionality */
1348
            XFREE(x509->authKeyIdSrc, x509->heap, DYNAMIC_TYPE_X509_EXT);
1349
            x509->authKeyIdSrc = NULL;
1350
            x509->authKeyId = NULL;
1351
        }
1352
        if (asn1_string_copy_to_buffer(&ext->value, &x509->authKeyId,
1353
                &x509->authKeyIdSz, x509->heap) != WOLFSSL_SUCCESS) {
1354
            WOLFSSL_MSG("asn1_string_copy_to_buffer error");
1355
            return WOLFSSL_FAILURE;
1356
        }
1357
        x509->authKeyIdCrit = (byte)ext->crit;
1358
        break;
1359
    case WC_NID_subject_key_identifier:
1360
        if (asn1_string_copy_to_buffer(&ext->value, &x509->subjKeyId,
1361
                &x509->subjKeyIdSz, x509->heap) != WOLFSSL_SUCCESS) {
1362
            WOLFSSL_MSG("asn1_string_copy_to_buffer error");
1363
            return WOLFSSL_FAILURE;
1364
        }
1365
        x509->subjKeyIdCrit = (byte)ext->crit;
1366
        break;
1367
    case WC_NID_subject_alt_name:
1368
    {
1369
        WOLFSSL_GENERAL_NAMES* gns = ext->ext_sk;
1370
        while (gns) {
1371
            WOLFSSL_GENERAL_NAME* gn = gns->data.gn;
1372
            if ((gn != NULL) && (gn->type == ASN_OTHER_TYPE)) {
1373
                char *buf = NULL;
1374
                int ret = 0;
1375
                word32 len = 0;
1376
1377
                len = SetOthername(gn->d.otherName, NULL);
1378
                if (len == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
1379
                    return WOLFSSL_FAILURE;
1380
                }
1381
1382
                buf = (char*)XMALLOC(len, x509->heap, DYNAMIC_TYPE_X509_EXT);
1383
                if (buf == NULL) {
1384
                    WOLFSSL_MSG("Couldn't allocate memory for othername");
1385
                    return WOLFSSL_FAILURE;
1386
                }
1387
1388
                /* SetOthername() cannot fail; already passed above. */
1389
                SetOthername(gn->d.otherName, (byte*)buf);
1390
1391
                ret = wolfSSL_X509_add_altname_ex(x509, buf, len,
1392
                                                  ASN_OTHER_TYPE);
1393
                XFREE(buf, x509->heap, DYNAMIC_TYPE_X509_EXT);
1394
                if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
1395
                     WOLFSSL_MSG("wolfSSL_X509_add_altname_ex() failed");
1396
                     return WOLFSSL_FAILURE;
1397
                }
1398
            }
1399
            else if (!gn || !gn->d.ia5 ||
1400
                wolfSSL_X509_add_altname_ex(x509, gn->d.ia5->data,
1401
                    gn->d.ia5->length, gn->type) != WOLFSSL_SUCCESS) {
1402
                WOLFSSL_MSG("Subject alternative name missing extension");
1403
                return WOLFSSL_FAILURE;
1404
            }
1405
            gns = gns->next;
1406
        }
1407
        x509->subjAltNameSet = 1;
1408
        x509->subjAltNameCrit = (byte)ext->crit;
1409
        break;
1410
    }
1411
    case WC_NID_key_usage:
1412
        if (ext && ext->value.data) {
1413
            if (ext->value.length == sizeof(word16)) {
1414
                /* if ext->value is already word16, set directly */
1415
                x509->keyUsage = *(word16*)ext->value.data;
1416
#ifdef BIG_ENDIAN_ORDER
1417
                x509->keyUsage = rotlFixed16(x509->keyUsage, 8U);
1418
#endif
1419
                x509->keyUsageCrit = (byte)ext->crit;
1420
                x509->keyUsageSet = 1;
1421
            }
1422
            else if (ext->value.length > 0) {
1423
                /* ext->value is comma-delimited string, convert to word16 */
1424
                if (ParseKeyUsageStr(ext->value.data, &x509->keyUsage,
1425
                                     x509->heap) != 0) {
1426
                    return WOLFSSL_FAILURE;
1427
                }
1428
                x509->keyUsageCrit = (byte)ext->crit;
1429
                x509->keyUsageSet = 1;
1430
            }
1431
            else {
1432
                return WOLFSSL_FAILURE;
1433
            }
1434
        }
1435
        break;
1436
    case WC_NID_ext_key_usage:
1437
        if (ext && ext->value.data) {
1438
            if (ext->value.length == sizeof(byte)) {
1439
                /* if ext->value is already 1 byte, set directly */
1440
                x509->extKeyUsage = *(byte*)ext->value.data;
1441
                x509->extKeyUsageCrit = (byte)ext->crit;
1442
            }
1443
            else if (ext->value.length > 0) {
1444
                /* ext->value is comma-delimited string, convert to word16 */
1445
                if (ParseExtKeyUsageStr(ext->value.data, &x509->extKeyUsage,
1446
                                        x509->heap) != 0) {
1447
                    return WOLFSSL_FAILURE;
1448
                }
1449
                x509->extKeyUsageCrit = (byte)ext->crit;
1450
            }
1451
            else {
1452
                return WOLFSSL_FAILURE;
1453
            }
1454
        }
1455
        break;
1456
    case WC_NID_basic_constraints:
1457
        if (ext->obj) {
1458
            x509->isCa = (byte)ext->obj->ca;
1459
            x509->basicConstCrit = (byte)ext->crit;
1460
            if (ext->obj->pathlen) {
1461
                x509->pathLength = (word32)ext->obj->pathlen->length;
1462
                x509->basicConstPlSet = 1;
1463
            }
1464
            x509->basicConstSet = 1;
1465
        }
1466
        break;
1467
    default:
1468
#ifdef WOLFSSL_CUSTOM_OID
1469
    {
1470
        char *oid = NULL;
1471
        byte *val = NULL;
1472
        int err = 0;
1473
1474
        if ((ext->obj == NULL) || (ext->value.length == 0)) {
1475
            WOLFSSL_MSG("Extension has insufficient information.");
1476
            return WOLFSSL_FAILURE;
1477
        }
1478
1479
        if ((x509->customExtCount < 0) ||
1480
            (x509->customExtCount >= NUM_CUSTOM_EXT)) {
1481
            WOLFSSL_MSG("Bad value for customExtCount.");
1482
            return WOLFSSL_FAILURE;
1483
        }
1484
1485
        /* This is a viable custom extension. */
1486
        oid = (char*)XMALLOC(MAX_OID_STRING_SZ, x509->heap,
1487
            DYNAMIC_TYPE_X509_EXT);
1488
        val = (byte*)XMALLOC(ext->value.length, x509->heap,
1489
            DYNAMIC_TYPE_X509_EXT);
1490
        if ((oid == NULL) || (val == NULL)) {
1491
            WOLFSSL_MSG("Memory allocation failure.\n");
1492
            err = 1;
1493
        }
1494
1495
        if (err == 0) {
1496
            XMEMCPY(val, ext->value.data, ext->value.length);
1497
            if (wolfSSL_OBJ_obj2txt(oid, MAX_OID_STRING_SZ, ext->obj, 1) < 0) {
1498
                err = 1;
1499
            }
1500
        }
1501
1502
        if (err == 1) {
1503
            XFREE(val, x509->heap, DYNAMIC_TYPE_X509_EXT);
1504
            XFREE(oid, x509->heap, DYNAMIC_TYPE_X509_EXT);
1505
            return WOLFSSL_FAILURE;
1506
        }
1507
1508
        /* ext->crit is WOLFSSL_ASN1_BOOLEAN */
1509
        if (ext->crit != 0 && ext->crit != -1) {
1510
            XFREE(val, x509->heap, DYNAMIC_TYPE_X509_EXT);
1511
            XFREE(oid, x509->heap, DYNAMIC_TYPE_X509_EXT);
1512
            return WOLFSSL_FAILURE;
1513
        }
1514
1515
        /* x509->custom_exts now owns the buffers and they must be managed. */
1516
        x509->custom_exts[x509->customExtCount].oid = oid;
1517
        x509->custom_exts[x509->customExtCount].crit = (byte)ext->crit;
1518
        x509->custom_exts[x509->customExtCount].val = val;
1519
        x509->custom_exts[x509->customExtCount].valSz = ext->value.length;
1520
        x509->customExtCount++;
1521
        break;
1522
    }
1523
#else
1524
        WOLFSSL_MSG("Unsupported extension to add");
1525
        return WOLFSSL_FAILURE;
1526
#endif /* WOLFSSL_CUSTOM_OID */
1527
    } /* switch (nid) */
1528
1529
    return WOLFSSL_SUCCESS;
1530
}
1531
1532
#ifndef NO_BIO
1533
/* Return 0 on success and 1 on failure. Copies ext data to bio, using indent
1534
 *  to pad the output. flag is ignored. */
1535
int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, WOLFSSL_X509_EXTENSION *ext,
1536
        unsigned long flag, int indent)
1537
{
1538
    WOLFSSL_ASN1_OBJECT* obj;
1539
    WOLFSSL_ASN1_STRING* str;
1540
    int nid;
1541
    int rc = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
1542
    char tmp[CTC_NAME_SIZE*2 + 1];
1543
    const int tmpSz = sizeof(tmp);
1544
    int tmpLen = 0;
1545
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_print");
1546
1547
    if ((out == NULL) || (ext == NULL)) {
1548
        WOLFSSL_MSG("NULL parameter error");
1549
        return rc;
1550
    }
1551
1552
    obj = wolfSSL_X509_EXTENSION_get_object(ext);
1553
    if (obj == NULL) {
1554
        WOLFSSL_MSG("Error getting ASN1_OBJECT from X509_EXTENSION");
1555
        return rc;
1556
    }
1557
1558
    str = wolfSSL_X509_EXTENSION_get_data(ext);
1559
    if (str == NULL) {
1560
        WOLFSSL_MSG("Error getting ASN1_STRING from X509_EXTENSION");
1561
        return rc;
1562
    }
1563
1564
    /* Print extension based on the type */
1565
    nid = wolfSSL_OBJ_obj2nid(obj);
1566
    switch (nid) {
1567
        case BASIC_CA_OID:
1568
        {
1569
            char isCa[] = "TRUE";
1570
            char notCa[] = "FALSE";
1571
            if ((tmpLen = XSNPRINTF(tmp, tmpSz, "%*sCA:%s", indent, "",
1572
                                     obj->ca ? isCa : notCa))
1573
                >= tmpSz)
1574
                return rc;
1575
            break;
1576
        }
1577
        case ALT_NAMES_OID:
1578
        {
1579
            WOLFSSL_STACK* sk;
1580
            char* val;
1581
            int valLen;
1582
            int len;
1583
1584
            sk = ext->ext_sk;
1585
            while (sk != NULL) {
1586
                if (sk->type == STACK_TYPE_GEN_NAME && sk->data.gn) {
1587
                    /* str is GENERAL_NAME for subject alternative name ext */
1588
                    str = sk->data.gn->d.ia5;
1589
                    len = str->length + 2; /* + 2 for NULL char and "," */
1590
                    if (len > tmpSz) {
1591
                        WOLFSSL_MSG("len greater than buffer size");
1592
                        return rc;
1593
                    }
1594
1595
                    val = (char*)XMALLOC(len + indent, NULL,
1596
                                                       DYNAMIC_TYPE_TMP_BUFFER);
1597
                    if (val == NULL) {
1598
                        WOLFSSL_MSG("Memory error");
1599
                        return rc;
1600
                    }
1601
                    valLen = XSNPRINTF(val, (size_t)len, "%*s%s", indent, "",
1602
                            str->strData);
1603
                    if ((valLen < 0) || (valLen >= len)
1604
                            || ((tmpLen + valLen) >= tmpSz)) {
1605
                        XFREE(val, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1606
                        return rc;
1607
                    }
1608
                    XMEMCPY(tmp + tmpLen, val, valLen);
1609
                    tmpLen += valLen;
1610
                    XFREE(val, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1611
                }
1612
                sk = sk->next;
1613
            }
1614
            break;
1615
        }
1616
        case AUTH_KEY_OID:
1617
        case SUBJ_KEY_OID:
1618
        {
1619
            char* asn1str;
1620
            asn1str = wolfSSL_i2s_ASN1_STRING(NULL, str);
1621
            tmpLen = XSNPRINTF(tmp, tmpSz, "%*s%s", indent, "", asn1str);
1622
            XFREE(asn1str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1623
            if (tmpLen >= tmpSz) return rc;
1624
            break;
1625
        }
1626
        case AUTH_INFO_OID:
1627
        case CERT_POLICY_OID:
1628
        case CRL_DIST_OID:
1629
        case KEY_USAGE_OID:
1630
            WOLFSSL_MSG("X509V3_EXT_print not yet implemented for ext type");
1631
            break;
1632
1633
        default:
1634
            if ((tmpLen = XSNPRINTF(
1635
                     tmp, tmpSz, "%*s%s", indent, "", str->strData))
1636
                >= tmpSz)
1637
                return rc;
1638
    }
1639
1640
    if (wolfSSL_BIO_write(out, tmp, tmpLen) == tmpLen) {
1641
        rc = WOLFSSL_SUCCESS;
1642
    }
1643
    (void) flag;
1644
1645
    return rc;
1646
}
1647
#endif /* !NO_BIO */
1648
1649
#ifndef NO_WOLFSSL_STUB
1650
int wolfSSL_X509V3_EXT_add_nconf(WOLFSSL_CONF *conf, WOLFSSL_X509V3_CTX *ctx,
1651
        const char *section, WOLFSSL_X509 *cert)
1652
{
1653
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_add_nconf");
1654
    WOLFSSL_STUB("wolfSSL_X509V3_EXT_add_nconf");
1655
    (void)conf;
1656
    (void)ctx;
1657
    (void)section;
1658
    (void)cert;
1659
    return WOLFSSL_SUCCESS;
1660
}
1661
#endif
1662
1663
/* Find extension by NID in a stack of extensions.
1664
 *
1665
 * @param sk Stack of extensions
1666
 * @param nid ID to search for
1667
 * @param lastpos Start search from this position (not inclusive, -1 means start from beginning)
1668
 * @return Index of matching extension or -1 on error/not found
1669
 */
1670
int wolfSSL_X509v3_get_ext_by_NID(const WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk,
1671
                                 int nid, int lastpos)
1672
{
1673
    int i;
1674
    WOLFSSL_ENTER("wolfSSL_X509v3_get_ext_by_NID");
1675
1676
    if (sk == NULL) {
1677
        WOLFSSL_MSG("Stack pointer is NULL");
1678
        return WOLFSSL_FATAL_ERROR;
1679
    }
1680
1681
    if (lastpos < -1 || lastpos >= wolfSSL_sk_num(sk)) {
1682
        WOLFSSL_MSG("Invalid position argument");
1683
        return WOLFSSL_FATAL_ERROR;
1684
    }
1685
1686
    for (i = lastpos + 1; i < wolfSSL_sk_num(sk); i++) {
1687
        WOLFSSL_X509_EXTENSION* ext = wolfSSL_sk_X509_EXTENSION_value(sk, i);
1688
        if (ext && ext->obj) {
1689
            if (wolfSSL_OBJ_obj2nid(ext->obj) == nid)
1690
                return i;
1691
        }
1692
    }
1693
1694
    /* Not found */
1695
    return -1;
1696
}
1697
1698
/* Get extension from a stack of extensions by location.
1699
 *
1700
 * @param sk Stack of extensions
1701
 * @param loc Index of extension to retrieve
1702
 * @return Pointer to extension or NULL on error
1703
 */
1704
WOLFSSL_X509_EXTENSION* wolfSSL_X509v3_get_ext(
1705
    const WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk, int loc)
1706
{
1707
    WOLFSSL_ENTER("wolfSSL_X509v3_get_ext");
1708
1709
    if (sk == NULL) {
1710
        WOLFSSL_MSG("Stack pointer is NULL");
1711
        return NULL;
1712
    }
1713
1714
    if (loc < 0 || loc >= wolfSSL_sk_num(sk)) {
1715
        WOLFSSL_MSG("Invalid location argument");
1716
        return NULL;
1717
    }
1718
1719
    return wolfSSL_sk_X509_EXTENSION_value(sk, loc);
1720
}
1721
1722
/* Returns crit flag in X509_EXTENSION object */
1723
int wolfSSL_X509_EXTENSION_get_critical(const WOLFSSL_X509_EXTENSION* ex)
1724
{
1725
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_get_critical");
1726
    if (ex == NULL)
1727
        return BAD_FUNC_ARG;
1728
    return ex->crit;
1729
}
1730
1731
/* Sets if the extension is critical
1732
 * returns WOLFSSL_SUCCESS on success
1733
 */
1734
int wolfSSL_X509_EXTENSION_set_critical(WOLFSSL_X509_EXTENSION* ex, int crit)
1735
{
1736
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_set_critical");
1737
    if (ex == NULL)
1738
        return WOLFSSL_FAILURE;
1739
    ex->crit = crit;
1740
    return WOLFSSL_SUCCESS;
1741
}
1742
1743
/* Creates v3_ext_method for a given X509v3 extension
1744
 *
1745
 * ex   : The X509_EXTENSION used to create v3_ext_method. If the extension is
1746
 * not NULL, get the NID of the extension object and populate the
1747
 * extension type-specific X509V3_EXT_* function(s) in v3_ext_method.
1748
 *
1749
 * Returns NULL on error or pointer to the v3_ext_method populated with
1750
 * extension type-specific X509V3_EXT_* function(s).
1751
 *
1752
 * NOTE: WC_NID_subject_key_identifier is currently the only extension
1753
 * implementing the X509V3_EXT_* functions, as it is the only type called
1754
 * directly by QT. The other extension types return a pointer to a
1755
 * v3_ext_method struct that contains only the NID.
1756
 */
1757
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
1758
const WOLFSSL_v3_ext_method* wolfSSL_X509V3_EXT_get(WOLFSSL_X509_EXTENSION* ex)
1759
#else
1760
WOLFSSL_v3_ext_method* wolfSSL_X509V3_EXT_get(WOLFSSL_X509_EXTENSION* ex)
1761
#endif
1762
{
1763
    int nid;
1764
    WOLFSSL_v3_ext_method method;
1765
1766
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_get");
1767
    if ((ex == NULL) || (ex->obj == NULL)) {
1768
        WOLFSSL_MSG("Passed an invalid X509_EXTENSION*");
1769
        return NULL;
1770
    }
1771
    /* Initialize method to 0 */
1772
    XMEMSET(&method, 0, sizeof(struct WOLFSSL_v3_ext_method));
1773
1774
    nid = ex->obj->nid;
1775
    if (nid <= 0) {
1776
        WOLFSSL_MSG("Failed to get nid from passed extension object");
1777
        return NULL;
1778
    }
1779
    switch (nid) {
1780
        case WC_NID_basic_constraints:
1781
            break;
1782
        case WC_NID_subject_key_identifier:
1783
            method.i2s = (WOLFSSL_X509V3_EXT_I2S)wolfSSL_i2s_ASN1_STRING;
1784
            break;
1785
        case WC_NID_subject_alt_name:
1786
            WOLFSSL_MSG("i2v function not yet implemented for Subject "
1787
                        "Alternative Name");
1788
            break;
1789
        case WC_NID_key_usage:
1790
            WOLFSSL_MSG("i2v function not yet implemented for Key Usage");
1791
            break;
1792
        case WC_NID_authority_key_identifier:
1793
            WOLFSSL_MSG("i2v function not yet implemented for Auth Key Id");
1794
            break;
1795
        case WC_NID_info_access:
1796
            WOLFSSL_MSG("i2v function not yet implemented for Info Access");
1797
            break;
1798
        case WC_NID_ext_key_usage:
1799
            WOLFSSL_MSG("i2v function not yet implemented for Ext Key Usage");
1800
            break;
1801
        case WC_NID_certificate_policies:
1802
            WOLFSSL_MSG("r2i function not yet implemented for Cert Policies");
1803
            break;
1804
        case WC_NID_crl_distribution_points:
1805
            WOLFSSL_MSG("r2i function not yet implemented for CRL Dist Points");
1806
            break;
1807
        default:
1808
            /* If extension type is unknown, return NULL -- QT makes call to
1809
                X509_EXTENSION_get_data() if there is no v3_ext_method */
1810
            WOLFSSL_MSG("X509V3_EXT_get(): Unknown extension type found");
1811
            return NULL;
1812
    }
1813
1814
    method.ext_nid = nid;
1815
    ex->ext_method = method;
1816
1817
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
1818
    return (const WOLFSSL_v3_ext_method*)&ex->ext_method;
1819
#else
1820
    return (WOLFSSL_v3_ext_method*)&ex->ext_method;
1821
#endif
1822
}
1823
1824
/* Create an Authority Info Access (AIA) from the contents of the extension.
1825
 *
1826
 * AIA is a stack of Access Descriptions.
1827
 *
1828
 * RFC 5280: 4.2.2.1
1829
 *
1830
 * @param [in] ext  X509v3 extension.
1831
 * @return  Stack of Access Descriptions as an AIA on success.
1832
 * @return  NULL on error.
1833
 */
1834
static WOLFSSL_AUTHORITY_INFO_ACCESS* wolfssl_x509v3_ext_aia_d2i(
1835
    WOLFSSL_X509_EXTENSION* ext)
1836
{
1837
    int err = 0;
1838
    int ret;
1839
    WOLFSSL_AUTHORITY_INFO_ACCESS* aia = NULL;
1840
    WOLFSSL_STACK* sk;
1841
    WOLFSSL_ACCESS_DESCRIPTION* ad = NULL;
1842
1843
    /* Get the type specific data of this extension. */
1844
    sk = ext->ext_sk;
1845
    if (sk == NULL) {
1846
        WOLFSSL_MSG("ACCESS_DESCRIPTION stack NULL");
1847
        err = 1;
1848
    }
1849
1850
    if (!err) {
1851
        /* AUTHORITY_INFO_ACCESS is a stack of ACCESS_DESCRIPTION entries. */
1852
        aia = wolfSSL_sk_new_null();
1853
        if (aia == NULL) {
1854
            WOLFSSL_MSG("Failed to malloc AUTHORITY_INFO_ACCESS");
1855
            err = 1;
1856
        }
1857
    }
1858
    if (!err) {
1859
        /* AIA is a stack of Access Descriptions. */
1860
        aia->type = STACK_TYPE_ACCESS_DESCRIPTION;
1861
    }
1862
1863
    while ((!err) && (sk != NULL)) {
1864
        WOLFSSL_ASN1_OBJECT* aiaEntry;
1865
1866
        /* Looking for objects in extension's data. */
1867
        if (sk->type != STACK_TYPE_OBJ) {
1868
            sk = sk->next;
1869
            continue;
1870
        }
1871
1872
        /* Get ASN.1 Object from the stack entry's data. */
1873
        aiaEntry = sk->data.obj;
1874
1875
        /* ACCESS_DESCRIPTION has two members: method and location.
1876
         *  method: ASN1_OBJECT as either AIA_OCSP_OID or AIA_CA_ISSUER_OID
1877
         *  location: GENERAL_NAME structure containing the URI.
1878
         */
1879
1880
        /* Allocate a new Access Description. */
1881
        ad = (WOLFSSL_ACCESS_DESCRIPTION*)XMALLOC(
1882
            sizeof(WOLFSSL_ACCESS_DESCRIPTION), NULL, DYNAMIC_TYPE_X509_EXT);
1883
        if (ad == NULL) {
1884
            WOLFSSL_MSG("Failed to malloc ACCESS_DESCRIPTION");
1885
            err = 1;
1886
            break;
1887
        }
1888
        XMEMSET(ad, 0, sizeof(WOLFSSL_ACCESS_DESCRIPTION));
1889
1890
        /* Create new ASN1_OBJECT from NID. */
1891
        ad->method = wolfSSL_OBJ_nid2obj(aiaEntry->nid);
1892
        if (ad->method == NULL) {
1893
            WOLFSSL_MSG("OBJ_nid2obj() failed");
1894
            err = 1;
1895
            break;
1896
        }
1897
1898
        /* Allocate memory for GENERAL NAME. */
1899
        ad->location = wolfSSL_GENERAL_NAME_new();
1900
        if (ad->location == NULL) {
1901
            WOLFSSL_MSG("Failed to malloc GENERAL_NAME");
1902
            err = 1;
1903
            break;
1904
        }
1905
1906
        /* Set the type of general name to URI (only type supported). */
1907
        ret = wolfSSL_GENERAL_NAME_set_type(ad->location, WOLFSSL_GEN_URI);
1908
        if (ret != WOLFSSL_SUCCESS) {
1909
            err = 1;
1910
            break;
1911
        }
1912
1913
        /* Set the URI into GENERAL_NAME. */
1914
        ret = wolfSSL_ASN1_STRING_set(ad->location->d.uniformResourceIdentifier,
1915
            aiaEntry->obj, aiaEntry->objSz);
1916
        if (ret != WOLFSSL_SUCCESS) {
1917
            WOLFSSL_MSG("ASN1_STRING_set() failed");
1918
            err = 1;
1919
            break;
1920
        }
1921
        /* Push onto AUTHORITY_INFO_ACCESS stack. */
1922
        ret = wolfSSL_sk_ACCESS_DESCRIPTION_push(aia, ad) > 0
1923
                ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
1924
        if (ret != WOLFSSL_SUCCESS) {
1925
            WOLFSSL_MSG("Error pushing ASN1 AD onto stack");
1926
            err = 1;
1927
            break;
1928
        }
1929
        /* Set to NULL so that it doesn't get freed now it is in AIA stack. */
1930
        ad = NULL;
1931
1932
        sk = sk->next;
1933
    }
1934
1935
    if (err) {
1936
        /* Dispose of Access Description if not put in stack. */
1937
        if (ad != NULL) {
1938
            wolfSSL_ASN1_OBJECT_free(ad->method);
1939
            wolfSSL_GENERAL_NAME_free(ad->location);
1940
            XFREE(ad, NULL, DYNAMIC_TYPE_X509_EXT);
1941
        }
1942
        /* Dispose of incomplete Access Description stack. */
1943
        wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(aia, NULL);
1944
        aia = NULL;
1945
    }
1946
    return aia;
1947
}
1948
1949
/* Parses and returns an x509v3 extension internal structure.
1950
 *
1951
 * ext   : The X509_EXTENSION for parsing internal structure. If extension is
1952
 * not NULL, get the NID of the extension object and create a new
1953
 * extension-specific internal structure based on the extension type.
1954
 *
1955
 * Returns NULL on error or if NID is not found, otherwise returns a pointer to
1956
 * the extension type-specific X509_EXTENSION internal structure.
1957
 * Return is expected to be free'd by caller.
1958
 */
1959
void* wolfSSL_X509V3_EXT_d2i(WOLFSSL_X509_EXTENSION* ext)
1960
{
1961
    const WOLFSSL_v3_ext_method* method;
1962
    int ret;
1963
    WOLFSSL_ASN1_OBJECT* object;
1964
    WOLFSSL_BASIC_CONSTRAINTS* bc;
1965
    WOLFSSL_AUTHORITY_KEYID* akey;
1966
    WOLFSSL_ASN1_STRING* asn1String, *newString;
1967
    WOLFSSL_STACK* sk;
1968
1969
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_d2i");
1970
1971
    if (ext == NULL) {
1972
        WOLFSSL_MSG("Bad function Argument");
1973
        return NULL;
1974
    }
1975
1976
    object = wolfSSL_X509_EXTENSION_get_object(ext);
1977
    if (object == NULL) {
1978
        WOLFSSL_MSG("X509_EXTENSION_get_object failed");
1979
        return NULL;
1980
    }
1981
    /* extract extension info */
1982
    method = wolfSSL_X509V3_EXT_get(ext);
1983
    if (method == NULL) {
1984
        WOLFSSL_MSG("wolfSSL_X509V3_EXT_get error");
1985
        return NULL;
1986
    }
1987
1988
    /* Return pointer to proper internal structure based on NID */
1989
    switch (object->type) {
1990
        /* basicConstraints */
1991
        case WC_NID_basic_constraints:
1992
            WOLFSSL_MSG("basicConstraints");
1993
            /* Allocate new BASIC_CONSTRAINTS structure */
1994
            bc = wolfSSL_BASIC_CONSTRAINTS_new();
1995
            if (bc == NULL) {
1996
                WOLFSSL_MSG("Failed to malloc basic constraints");
1997
                return NULL;
1998
            }
1999
            /* Copy pathlen and CA into BASIC_CONSTRAINTS from object */
2000
            bc->ca = object->ca;
2001
            if (object->pathlen != NULL && object->pathlen->length > 0) {
2002
                bc->pathlen = wolfSSL_ASN1_INTEGER_dup(object->pathlen);
2003
                if (bc->pathlen == NULL) {
2004
                    WOLFSSL_MSG("Failed to duplicate ASN1_INTEGER");
2005
                    wolfSSL_BASIC_CONSTRAINTS_free(bc);
2006
                    return NULL;
2007
                }
2008
            }
2009
            else
2010
                bc->pathlen = NULL;
2011
            return bc;
2012
2013
        /* subjectKeyIdentifier */
2014
        case WC_NID_subject_key_identifier:
2015
            WOLFSSL_MSG("subjectKeyIdentifier");
2016
            asn1String = wolfSSL_X509_EXTENSION_get_data(ext);
2017
            if (asn1String == NULL) {
2018
                WOLFSSL_MSG("X509_EXTENSION_get_data() failed");
2019
                return NULL;
2020
            }
2021
            newString = wolfSSL_ASN1_STRING_new();
2022
            if (newString == NULL) {
2023
                WOLFSSL_MSG("Failed to malloc ASN1_STRING");
2024
                return NULL;
2025
            }
2026
            ret = wolfSSL_ASN1_STRING_set(newString, asn1String->data,
2027
                                                            asn1String->length);
2028
            if (ret != WOLFSSL_SUCCESS) {
2029
                WOLFSSL_MSG("ASN1_STRING_set() failed");
2030
                wolfSSL_ASN1_STRING_free(newString);
2031
                return NULL;
2032
            };
2033
            newString->type = asn1String->type;
2034
            return newString;
2035
2036
        /* authorityKeyIdentifier */
2037
        case WC_NID_authority_key_identifier:
2038
            WOLFSSL_MSG("AuthorityKeyIdentifier");
2039
2040
            akey = (WOLFSSL_AUTHORITY_KEYID*)
2041
                    XMALLOC(sizeof(WOLFSSL_AUTHORITY_KEYID), NULL,
2042
                    DYNAMIC_TYPE_X509_EXT);
2043
            if (akey == NULL) {
2044
                WOLFSSL_MSG("Failed to malloc authority key id");
2045
                return NULL;
2046
            }
2047
2048
            XMEMSET(akey, 0, sizeof(WOLFSSL_AUTHORITY_KEYID));
2049
2050
            akey->keyid = wolfSSL_ASN1_STRING_new();
2051
            if (akey->keyid == NULL) {
2052
                WOLFSSL_MSG("ASN1_STRING_new() failed");
2053
                wolfSSL_AUTHORITY_KEYID_free(akey);
2054
                return NULL;
2055
            }
2056
2057
            asn1String = wolfSSL_X509_EXTENSION_get_data(ext);
2058
            if (asn1String == NULL) {
2059
                WOLFSSL_MSG("X509_EXTENSION_get_data() failed");
2060
                wolfSSL_AUTHORITY_KEYID_free(akey);
2061
                return NULL;
2062
            }
2063
2064
            ret = wolfSSL_ASN1_STRING_set(akey->keyid, asn1String->data,
2065
                                                            asn1String->length);
2066
            if (ret != WOLFSSL_SUCCESS) {
2067
                WOLFSSL_MSG("ASN1_STRING_set() failed");
2068
                wolfSSL_AUTHORITY_KEYID_free(akey);
2069
                return NULL;
2070
            };
2071
            akey->keyid->type   = asn1String->type;
2072
2073
            /* For now, set issuer and serial to NULL. This may need to be
2074
                updated for future use */
2075
            akey->issuer = NULL;
2076
            akey->serial = NULL;
2077
            return akey;
2078
2079
        /* keyUsage */
2080
        case WC_NID_key_usage:
2081
            WOLFSSL_MSG("keyUsage");
2082
            /* This may need to be updated for future use. The i2v method for
2083
                keyUsage is not currently set. For now, return the ASN1_STRING
2084
                representation of KeyUsage bit string */
2085
            asn1String = wolfSSL_X509_EXTENSION_get_data(ext);
2086
            if (asn1String == NULL) {
2087
                WOLFSSL_MSG("X509_EXTENSION_get_data() failed");
2088
                return NULL;
2089
            }
2090
            newString = wolfSSL_ASN1_STRING_new();
2091
            if (newString == NULL) {
2092
                WOLFSSL_MSG("Failed to malloc ASN1_STRING");
2093
                return NULL;
2094
            }
2095
            ret = wolfSSL_ASN1_STRING_set(newString, asn1String->data,
2096
                                                            asn1String->length);
2097
            if (ret != WOLFSSL_SUCCESS) {
2098
                WOLFSSL_MSG("ASN1_STRING_set() failed");
2099
                wolfSSL_ASN1_STRING_free(newString);
2100
                return NULL;
2101
            };
2102
            newString->type = asn1String->type;
2103
            return newString;
2104
2105
        /* extKeyUsage */
2106
        case WC_NID_ext_key_usage:
2107
            WOLFSSL_MSG("extKeyUsage not supported yet");
2108
            return NULL;
2109
2110
        /* certificatePolicies */
2111
        case WC_NID_certificate_policies:
2112
            WOLFSSL_MSG("certificatePolicies not supported yet");
2113
            return NULL;
2114
2115
        /* cRLDistributionPoints */
2116
        case WC_NID_crl_distribution_points:
2117
            WOLFSSL_MSG("cRLDistributionPoints not supported yet");
2118
            return NULL;
2119
2120
        case WC_NID_subject_alt_name:
2121
            if (ext->ext_sk == NULL) {
2122
                WOLFSSL_MSG("Subject alt name stack NULL");
2123
                return NULL;
2124
            }
2125
            sk = wolfSSL_sk_dup(ext->ext_sk);
2126
            if (sk == NULL) {
2127
                WOLFSSL_MSG("Failed to duplicate subject alt names stack.");
2128
                return NULL;
2129
            }
2130
            return sk;
2131
2132
        /* authorityInfoAccess */
2133
        case WC_NID_info_access:
2134
            WOLFSSL_MSG("AuthorityInfoAccess");
2135
            return wolfssl_x509v3_ext_aia_d2i(ext);
2136
2137
        default:
2138
            WOLFSSL_MSG("Extension NID not in table, returning NULL");
2139
            break;
2140
    }
2141
    return NULL;
2142
}
2143
2144
/* Looks for the extension matching the passed in nid
2145
 *
2146
 * x509 : certificate to get parse through for extension.
2147
 * nid : Extension OID to be found.
2148
 * lastPos : Start search from extension after lastPos.
2149
 *           Set to -1 to search from index 0.
2150
 * return >= 0 If successful the extension index is returned.
2151
 * return WOLFSSL_FATAL_ERROR If extension is not found or error is encountered.
2152
 */
2153
int wolfSSL_X509_get_ext_by_NID(const WOLFSSL_X509* x509, int nid, int lastPos)
2154
{
2155
    int extCount = 0, length = 0, outSz = 0, sz = 0, ret = 0;
2156
    int isSet = 0, found = 0, loc;
2157
    const byte* rawCert;
2158
    const byte* input;
2159
    word32 oid, idx = 0, tmpIdx = 0, foundNID;
2160
#ifdef WOLFSSL_SMALL_STACK
2161
    DecodedCert *cert;
2162
#else
2163
    DecodedCert cert[1];
2164
#endif
2165
2166
    WOLFSSL_ENTER("wolfSSL_X509_get_ext_by_NID");
2167
2168
    if (x509 == NULL) {
2169
        WOLFSSL_MSG("\tNot passed a certificate");
2170
        return WOLFSSL_FATAL_ERROR;
2171
    }
2172
2173
    if (lastPos < -1 || (lastPos > (wolfSSL_X509_get_ext_count(x509) - 1))) {
2174
        WOLFSSL_MSG("\tBad location argument");
2175
        return WOLFSSL_FATAL_ERROR;
2176
    }
2177
2178
    loc = lastPos + 1;
2179
2180
    rawCert = wolfSSL_X509_get_der((WOLFSSL_X509*)x509, &outSz);
2181
    if (rawCert == NULL) {
2182
        WOLFSSL_MSG("\tX509_get_der() failed");
2183
        return WOLFSSL_FATAL_ERROR;
2184
    }
2185
2186
#ifdef WOLFSSL_SMALL_STACK
2187
    cert = (DecodedCert *)XMALLOC(sizeof(*cert), x509->heap,
2188
                                  DYNAMIC_TYPE_DCERT);
2189
    if (cert == NULL) {
2190
        WOLFSSL_MSG("\tout of memory");
2191
        return WOLFSSL_FATAL_ERROR;
2192
    }
2193
#endif
2194
2195
    InitDecodedCert( cert, rawCert, (word32)outSz, 0);
2196
2197
    if (ParseCert(cert,
2198
#ifdef WOLFSSL_CERT_REQ
2199
            x509->isCSR ? CERTREQ_TYPE :
2200
#endif
2201
            CA_TYPE,
2202
            NO_VERIFY, NULL) < 0) {
2203
        WOLFSSL_MSG("\tCertificate parsing failed");
2204
        goto out;
2205
    }
2206
2207
    input = cert->extensions;
2208
    sz = cert->extensionsSz;
2209
2210
    if (input == NULL || sz == 0) {
2211
        WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
2212
        goto out;
2213
    }
2214
2215
#ifdef WOLFSSL_CERT_REQ
2216
    if (!x509->isCSR)
2217
#endif
2218
    {
2219
        if (input[idx++] != ASN_EXTENSIONS) {
2220
            WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
2221
            goto out;
2222
        }
2223
2224
        if (GetLength(input, &idx, &length, (word32)sz) < 0) {
2225
            WOLFSSL_MSG("\tfail: invalid length");
2226
            goto out;
2227
        }
2228
    }
2229
2230
    if (GetSequence(input, &idx, &length, (word32)sz) < 0) {
2231
        WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
2232
        goto out;
2233
    }
2234
2235
    while (idx < (word32)sz) {
2236
        oid = 0;
2237
2238
        if (GetSequence(input, &idx, &length, (word32)sz) < 0) {
2239
            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
2240
            goto out;
2241
        }
2242
2243
        tmpIdx = idx;
2244
        ret = GetObjectId(input, &idx, &oid, oidCertExtType, (word32)sz);
2245
        if (ret < 0) {
2246
            WOLFSSL_MSG("\tfail: OBJECT ID");
2247
            goto out;
2248
        }
2249
        idx = tmpIdx;
2250
        foundNID = (word32)oid2nid(oid, oidCertExtType);
2251
2252
        if (extCount >= loc) {
2253
            /* extCount >= loc. Now check if extension has been set */
2254
            isSet = wolfSSL_X509_ext_isSet_by_NID((WOLFSSL_X509*)x509,
2255
                (int)foundNID);
2256
            if (isSet && ((word32)nid == foundNID)) {
2257
                found = 1;
2258
                break;
2259
            }
2260
        }
2261
2262
        idx += length;
2263
        extCount++;
2264
    } /* while(idx < sz) */
2265
2266
out:
2267
2268
    FreeDecodedCert(cert);
2269
#ifdef WOLFSSL_SMALL_STACK
2270
    XFREE(cert, x509->heap, DYNAMIC_TYPE_DCERT);
2271
#endif
2272
2273
    return found ? extCount : WOLFSSL_FATAL_ERROR;
2274
}
2275
2276
#endif /* OPENSSL_ALL || OPENSSL_EXTRA */
2277
2278
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
2279
/* Looks for the extension matching the passed in nid
2280
 *
2281
 * c   : if not null then is set to status value -2 if multiple occurrences
2282
 *       of the extension are found, -1 if not found, 0 if found and not
2283
 *       critical, and 1 if found and critical.
2284
 * nid : Extension OID to be found.
2285
 * idx : if NULL return first extension found match, otherwise start search at
2286
 *       idx location and set idx to the location of extension returned.
2287
 * returns NULL or a pointer to an WOLFSSL_ASN1_BIT_STRING (for KEY_USAGE_OID)
2288
 * or WOLFSSL_STACK (for other)
2289
 * holding extension structure
2290
 *
2291
 * NOTE code for decoding extensions is in asn.c DecodeCertExtensions --
2292
 * use already decoded extension in this function to avoid decoding twice.
2293
 * Currently we do not make use of idx since getting pre decoded extensions.
2294
 */
2295
void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c,
2296
    int* idx)
2297
{
2298
    void* ret = NULL;
2299
    WOLFSSL_STACK* sk = NULL;
2300
    WOLFSSL_ASN1_OBJECT* obj = NULL;
2301
    WOLFSSL_GENERAL_NAME* gn = NULL;
2302
#ifdef OPENSSL_EXTRA
2303
    WOLFSSL_DIST_POINT* dp = NULL;
2304
#endif
2305
    WOLFSSL_BASIC_CONSTRAINTS* bc = NULL;
2306
2307
    WOLFSSL_ENTER("wolfSSL_X509_get_ext_d2i");
2308
2309
    if (x509 == NULL) {
2310
        return NULL;
2311
    }
2312
2313
    if (c != NULL) {
2314
        *c = -1; /* default to not found */
2315
    }
2316
2317
    switch (nid) {
2318
        case BASIC_CA_OID:
2319
            if (x509->basicConstSet) {
2320
                WOLFSSL_ASN1_INTEGER* a;
2321
2322
                bc = wolfSSL_BASIC_CONSTRAINTS_new();
2323
                if (!bc) {
2324
                    WOLFSSL_MSG("wolfSSL_BASIC_CONSTRAINTS_new error");
2325
                    return NULL;
2326
                }
2327
2328
                a = wolfSSL_ASN1_INTEGER_new();
2329
                if (!a) {
2330
                    WOLFSSL_MSG("wolfSSL_ASN1_INTEGER_new error");
2331
                    wolfSSL_BASIC_CONSTRAINTS_free(bc);
2332
                    return NULL;
2333
                }
2334
                a->length = (int)x509->pathLength;
2335
2336
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) || \
2337
        defined(WOLFSSL_APACHE_HTTPD)
2338
                bc->ca = x509->isCa;
2339
#endif
2340
                bc->pathlen = a;
2341
                if (c != NULL) {
2342
                    *c = x509->basicConstCrit;
2343
                }
2344
            }
2345
            else {
2346
                WOLFSSL_MSG("No Basic Constraint set");
2347
            }
2348
            return bc;
2349
2350
        case ALT_NAMES_OID:
2351
        {
2352
            DNS_entry* dns = NULL;
2353
2354
            if (x509->subjAltNameSet && x509->altNames != NULL) {
2355
                /* Malloc GENERAL_NAME stack */
2356
                sk = wolfSSL_sk_new_null();
2357
                if (sk == NULL)
2358
                    return NULL;
2359
                sk->type = STACK_TYPE_GEN_NAME;
2360
2361
                /* alt names are DNS_entry structs */
2362
                if (c != NULL) {
2363
                    if (x509->altNames->next != NULL) {
2364
                        *c = -2; /* more then one found */
2365
                    }
2366
                    else {
2367
                        *c = x509->subjAltNameCrit;
2368
                    }
2369
                }
2370
2371
                dns = x509->altNames;
2372
                /* Currently only support GEN_DNS type */
2373
                while (dns != NULL) {
2374
                    gn = wolfSSL_GENERAL_NAME_new();
2375
                    if (gn == NULL) {
2376
                        WOLFSSL_MSG("Error creating GENERAL_NAME");
2377
                        goto err;
2378
                    }
2379
2380
                    gn->type = dns->type;
2381
                    switch (gn->type) {
2382
                        case ASN_DIR_TYPE:
2383
                            {
2384
                                int localIdx = 0;
2385
                                unsigned char* n = (unsigned char*)XMALLOC(
2386
                                        dns->len + MAX_SEQ_SZ, x509->heap,
2387
                                        DYNAMIC_TYPE_TMP_BUFFER);
2388
                                if (n == NULL) {
2389
                                    goto err;
2390
                                }
2391
2392
                                localIdx += SetSequence(dns->len, n);
2393
                                XMEMCPY(n + localIdx, dns->name, dns->len);
2394
                                gn->d.dirn =  wolfSSL_d2i_X509_NAME(NULL, &n,
2395
                                        dns->len + localIdx);
2396
                                XFREE(n, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
2397
                                if (gn->d.dirn == NULL) {
2398
                                    WOLFSSL_MSG("Convert altDirName to X509 "
2399
                                            "NAME failed");
2400
                                    goto err;
2401
                                }
2402
                            }
2403
                            break;
2404
2405
                        case ASN_OTHER_TYPE:
2406
                            if (!wolfssl_dns_entry_othername_to_gn(dns, gn)) {
2407
                                goto err;
2408
                            }
2409
                            break;
2410
2411
                        case ASN_IP_TYPE:
2412
                            if (wolfSSL_ASN1_STRING_set(gn->d.iPAddress,
2413
                                    dns->name, dns->len) != WOLFSSL_SUCCESS) {
2414
                                WOLFSSL_MSG("ASN1_STRING_set failed");
2415
                                goto err;
2416
                            }
2417
                            gn->d.iPAddress->type = WOLFSSL_V_ASN1_OCTET_STRING;
2418
                            break;
2419
2420
                        default:
2421
                            if (wolfSSL_ASN1_STRING_set(gn->d.dNSName,
2422
                                    dns->name, dns->len) != WOLFSSL_SUCCESS) {
2423
                                WOLFSSL_MSG("ASN1_STRING_set failed");
2424
                                goto err;
2425
                            }
2426
                            gn->d.dNSName->type = WOLFSSL_V_ASN1_IA5STRING;
2427
                    }
2428
2429
                    dns = dns->next;
2430
                    /* Using wolfSSL_sk_insert to maintain backwards
2431
                     * compatibility with earlier versions of _push API that
2432
                     * pushed items to the start of the list instead of the
2433
                     * end. */
2434
                    if (wolfSSL_sk_insert(sk, gn, 0) <= 0) {
2435
                        WOLFSSL_MSG("Error pushing ASN1 object onto stack");
2436
                        goto err;
2437
                    }
2438
                    /* null so that it doesn't get pushed again after switch */
2439
                    gn = NULL;
2440
                }
2441
            }
2442
            else {
2443
                WOLFSSL_MSG("No Alt Names set");
2444
            }
2445
2446
            break;
2447
        }
2448
2449
        case CRL_DIST_OID:
2450
    #if defined(OPENSSL_EXTRA)
2451
            if (x509->CRLdistSet && x509->CRLInfo != NULL) {
2452
                if (c != NULL) {
2453
                    *c = x509->CRLdistCrit;
2454
                }
2455
2456
                sk = wolfSSL_sk_new_null();
2457
                if (sk == NULL) {
2458
                    return NULL;
2459
                }
2460
                sk->type = STACK_TYPE_DIST_POINT;
2461
2462
                gn = wolfSSL_GENERAL_NAME_new();
2463
                if (gn == NULL) {
2464
                    WOLFSSL_MSG("Error creating GENERAL_NAME");
2465
                    goto err;
2466
                }
2467
2468
                if (wolfSSL_GENERAL_NAME_set_type(gn, WOLFSSL_GEN_URI) !=
2469
                        WOLFSSL_SUCCESS) {
2470
                    WOLFSSL_MSG("Error setting GENERAL_NAME type");
2471
                    goto err;
2472
                }
2473
2474
                if (wolfSSL_ASN1_STRING_set(gn->d.uniformResourceIdentifier,
2475
                        x509->CRLInfo, x509->CRLInfoSz) != WOLFSSL_SUCCESS) {
2476
                    WOLFSSL_MSG("ASN1_STRING_set failed");
2477
                    goto err;
2478
                }
2479
2480
                /* wolfSSL only decodes one dist point */
2481
                dp = wolfSSL_DIST_POINT_new();
2482
                if (dp == NULL) {
2483
                    WOLFSSL_MSG("Error creating DIST_POINT");
2484
                    goto err;
2485
                }
2486
2487
                /* push GENERAL_NAME onto fullname stack */
2488
                if (wolfSSL_sk_GENERAL_NAME_push(dp->distpoint->name.fullname,
2489
                                                 gn) <= 0) {
2490
                    WOLFSSL_MSG("wolfSSL_sk_GENERAL_NAME_push error");
2491
                    goto err;
2492
                }
2493
2494
                /* push DIST_POINT onto stack */
2495
                if (wolfSSL_sk_DIST_POINT_push(sk, dp) <= 0) {
2496
                    WOLFSSL_MSG("Error pushing DIST_POINT onto stack");
2497
                    goto err;
2498
                }
2499
2500
                gn = NULL;
2501
                dp = NULL;
2502
2503
            }
2504
            else {
2505
                WOLFSSL_MSG("No CRL dist set");
2506
            }
2507
    #endif /* OPENSSL_EXTRA */
2508
            break;
2509
2510
        case AUTH_INFO_OID:
2511
            if (x509->authInfoSet && x509->authInfo != NULL) {
2512
                if (c != NULL) {
2513
                    *c = x509->authInfoCrit;
2514
                }
2515
                obj = wolfSSL_ASN1_OBJECT_new();
2516
                if (obj == NULL) {
2517
                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
2518
                    return NULL;
2519
                }
2520
                obj->type  = AUTH_INFO_OID;
2521
                obj->grp   = oidCertExtType;
2522
                obj->obj   = x509->authInfo;
2523
                obj->objSz = (unsigned int)x509->authInfoSz;
2524
            }
2525
            else {
2526
                WOLFSSL_MSG("No Auth Info set");
2527
            }
2528
            break;
2529
2530
        case AUTH_KEY_OID:
2531
            if (x509->authKeyIdSet) {
2532
                WOLFSSL_AUTHORITY_KEYID* akey = wolfSSL_AUTHORITY_KEYID_new();
2533
                if (!akey) {
2534
                    WOLFSSL_MSG(
2535
                        "Issue creating WOLFSSL_AUTHORITY_KEYID struct");
2536
                    return NULL;
2537
                }
2538
2539
                if (c != NULL) {
2540
                    *c = x509->authKeyIdCrit;
2541
                }
2542
                obj = wolfSSL_ASN1_OBJECT_new();
2543
                if (obj == NULL) {
2544
                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
2545
                    wolfSSL_AUTHORITY_KEYID_free(akey);
2546
                    return NULL;
2547
                }
2548
                obj->type  = AUTH_KEY_OID;
2549
                obj->grp   = oidCertExtType;
2550
                obj->obj   = x509->authKeyId;
2551
                obj->objSz = x509->authKeyIdSz;
2552
                akey->issuer = obj;
2553
                return akey;
2554
            }
2555
            else {
2556
                WOLFSSL_MSG("No Auth Key set");
2557
            }
2558
            break;
2559
2560
        case SUBJ_KEY_OID:
2561
            if (x509->subjKeyIdSet) {
2562
                if (c != NULL) {
2563
                    *c = x509->subjKeyIdCrit;
2564
                }
2565
                obj = wolfSSL_ASN1_OBJECT_new();
2566
                if (obj == NULL) {
2567
                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
2568
                    return NULL;
2569
                }
2570
                obj->type  = SUBJ_KEY_OID;
2571
                obj->grp   = oidCertExtType;
2572
                obj->obj   = x509->subjKeyId;
2573
                obj->objSz = x509->subjKeyIdSz;
2574
            }
2575
            else {
2576
                WOLFSSL_MSG("No Subject Key set");
2577
            }
2578
            break;
2579
2580
        case CERT_POLICY_OID:
2581
        {
2582
        #ifdef WOLFSSL_CERT_EXT
2583
            int i;
2584
2585
            if (x509->certPoliciesNb > 0) {
2586
                if (c != NULL) {
2587
                    if (x509->certPoliciesNb > 1) {
2588
                        *c = -2;
2589
                    }
2590
                    else {
2591
                        *c = 0;
2592
                    }
2593
                }
2594
2595
                sk = wolfSSL_sk_new_asn1_obj();
2596
                if (sk == NULL) {
2597
                    return NULL;
2598
                }
2599
2600
                for (i = 0; i < x509->certPoliciesNb - 1; i++) {
2601
                    obj = wolfSSL_ASN1_OBJECT_new();
2602
                    if (obj == NULL) {
2603
                        WOLFSSL_MSG(
2604
                            "Issue creating WOLFSSL_ASN1_OBJECT struct");
2605
                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
2606
                        return NULL;
2607
                    }
2608
                    obj->type  = CERT_POLICY_OID;
2609
                    obj->grp   = oidCertExtType;
2610
                    obj->obj   = (byte*)(x509->certPolicies[i]);
2611
                    obj->objSz = MAX_CERTPOL_SZ;
2612
                    if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) <= 0) {
2613
                        WOLFSSL_MSG("Error pushing ASN1 object onto stack");
2614
                        wolfSSL_ASN1_OBJECT_free(obj);
2615
                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
2616
                        sk = NULL;
2617
                    }
2618
                }
2619
2620
                obj = wolfSSL_ASN1_OBJECT_new();
2621
                if (obj == NULL) {
2622
                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
2623
                    wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
2624
                    return NULL;
2625
                }
2626
                obj->type  = CERT_POLICY_OID;
2627
                obj->grp   = oidCertExtType;
2628
                obj->obj   = (byte*)(x509->certPolicies[i]);
2629
                obj->objSz = MAX_CERTPOL_SZ;
2630
2631
                if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) <= 0) {
2632
                    WOLFSSL_MSG("Error pushing ASN1 object onto stack");
2633
                    wolfSSL_ASN1_OBJECT_free(obj);
2634
                    wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
2635
                    sk = NULL;
2636
                }
2637
2638
                obj = NULL;
2639
            }
2640
            else {
2641
                WOLFSSL_MSG("No Cert Policy set");
2642
            }
2643
        #endif /* WOLFSSL_CERT_EXT */
2644
        #ifdef WOLFSSL_SEP
2645
            if (x509->certPolicySet) {
2646
                if (c != NULL) {
2647
                    *c = x509->certPolicyCrit;
2648
                }
2649
                obj = wolfSSL_ASN1_OBJECT_new();
2650
                if (obj == NULL) {
2651
                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
2652
                    return NULL;
2653
                }
2654
                obj->type  = CERT_POLICY_OID;
2655
                obj->grp   = oidCertExtType;
2656
            }
2657
            else {
2658
                WOLFSSL_MSG("No Cert Policy set");
2659
            }
2660
        #endif
2661
            break;
2662
        }
2663
        case KEY_USAGE_OID:
2664
        {
2665
            WOLFSSL_ASN1_STRING* asn1str = NULL;
2666
            if (x509->keyUsageSet) {
2667
                if (c != NULL) {
2668
                    *c = x509->keyUsageCrit;
2669
                }
2670
2671
                asn1str = wolfSSL_ASN1_STRING_new();
2672
                if (asn1str == NULL) {
2673
                    WOLFSSL_MSG("Failed to malloc ASN1_STRING");
2674
                    return NULL;
2675
                }
2676
2677
                if (wolfSSL_ASN1_STRING_set(asn1str, &x509->keyUsage,
2678
                        sizeof(word16)) != WOLFSSL_SUCCESS) {
2679
                    WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
2680
                    wolfSSL_ASN1_STRING_free(asn1str);
2681
                    return NULL;
2682
                }
2683
2684
                asn1str->type = KEY_USAGE_OID;
2685
            }
2686
            else {
2687
                WOLFSSL_MSG("No Key Usage set");
2688
            }
2689
            /* don't add stack of and return bit string directly */
2690
            return asn1str;
2691
        }
2692
        case INHIBIT_ANY_OID:
2693
            WOLFSSL_MSG("INHIBIT ANY extension not supported");
2694
            break;
2695
2696
        case EXT_KEY_USAGE_OID:
2697
            if (x509->extKeyUsageSrc != NULL) {
2698
                const byte* ekuSrc = x509->extKeyUsageSrc;
2699
                word32 i;
2700
2701
                sk = wolfSSL_sk_new_asn1_obj();
2702
                if (sk == NULL) {
2703
                    WOLFSSL_MSG("Issue creating stack");
2704
                    return NULL;
2705
                }
2706
2707
                for (i = 0; i < x509->extKeyUsageCount; i++) {
2708
                    long ekuSrcLen = (long)(x509->extKeyUsageSz -
2709
                            (word32)(ekuSrc - x509->extKeyUsageSrc));
2710
                    WOLFSSL_ASN1_OBJECT* ekuObj = wolfSSL_d2i_ASN1_OBJECT(NULL,
2711
                            &ekuSrc, ekuSrcLen);
2712
                    if (ekuObj == NULL) {
2713
                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
2714
                        WOLFSSL_MSG("d2i obj error");
2715
                        return NULL;
2716
                    }
2717
                    ekuObj->type  = EXT_KEY_USAGE_OID;
2718
                    ekuObj->grp   = oidCertExtType;
2719
                    /* Push to end to maintain order */
2720
                    if (wolfSSL_sk_insert(sk, ekuObj, -1) <= 0) {
2721
                        wolfSSL_ASN1_OBJECT_free(ekuObj);
2722
                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
2723
                        WOLFSSL_MSG("d2i obj error");
2724
                        return NULL;
2725
                    }
2726
                }
2727
2728
                if ((word32)(ekuSrc - x509->extKeyUsageSrc)
2729
                        != x509->extKeyUsageSz ||
2730
                        i != x509->extKeyUsageCount) {
2731
                    wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
2732
                    WOLFSSL_MSG("incorrect eku count or buffer not exhausted");
2733
                    return NULL;
2734
                }
2735
2736
                if (c != NULL) {
2737
                    if (x509->extKeyUsageCount > 1) {
2738
                        *c = -2;
2739
                    }
2740
                    else {
2741
                        *c = x509->extKeyUsageCrit;
2742
                    }
2743
                }
2744
            }
2745
            else {
2746
                WOLFSSL_MSG("No Extended Key Usage set");
2747
            }
2748
            break;
2749
2750
        case NAME_CONS_OID:
2751
            WOLFSSL_MSG("Name Constraint OID extension not supported");
2752
            break;
2753
2754
        case PRIV_KEY_USAGE_PERIOD_OID:
2755
            WOLFSSL_MSG("Private Key Usage Period extension not supported");
2756
            break;
2757
2758
        case SUBJ_INFO_ACC_OID:
2759
            WOLFSSL_MSG("Subject Info Access extension not supported");
2760
            break;
2761
2762
        case POLICY_MAP_OID:
2763
            WOLFSSL_MSG("Policy Map extension not supported");
2764
            break;
2765
2766
        case POLICY_CONST_OID:
2767
            WOLFSSL_MSG("Policy Constraint extension not supported");
2768
            break;
2769
2770
        case ISSUE_ALT_NAMES_OID:
2771
            WOLFSSL_MSG("Issue Alt Names extension not supported");
2772
            break;
2773
2774
        case TLS_FEATURE_OID:
2775
            WOLFSSL_MSG("TLS Feature extension not supported");
2776
            break;
2777
2778
        default:
2779
            WOLFSSL_MSG("Unsupported/Unknown extension OID");
2780
    }
2781
2782
    /* make sure stack of is allocated */
2783
    if ((obj || gn) && sk == NULL) {
2784
        sk = wolfSSL_sk_new_asn1_obj();
2785
        if (sk == NULL) {
2786
            goto err;
2787
        }
2788
    }
2789
    if (obj) {
2790
        if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) <= 0) {
2791
            WOLFSSL_MSG("Error pushing ASN1_OBJECT object onto "
2792
                        "stack.");
2793
            goto err;
2794
        }
2795
    }
2796
2797
    ret = sk;
2798
2799
    (void)idx;
2800
2801
    return ret;
2802
2803
err:
2804
    if (obj) {
2805
        wolfSSL_ASN1_OBJECT_free(obj);
2806
    }
2807
    if (gn) {
2808
        wolfSSL_GENERAL_NAME_free(gn);
2809
    }
2810
    #ifdef OPENSSL_EXTRA
2811
    if (dp) {
2812
        wolfSSL_DIST_POINT_free(dp);
2813
    }
2814
    #endif
2815
    if (sk) {
2816
        wolfSSL_sk_pop_free(sk, NULL);
2817
    }
2818
    return NULL;
2819
}
2820
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
2821
2822
#ifdef OPENSSL_EXTRA
2823
int wolfSSL_X509_add_altname_ex(WOLFSSL_X509* x509, const char* name,
2824
        word32 nameSz, int type)
2825
{
2826
    DNS_entry* newAltName = NULL;
2827
    char* nameCopy = NULL;
2828
2829
    if (x509 == NULL)
2830
        return WOLFSSL_FAILURE;
2831
2832
    if ((name == NULL) || (nameSz == 0))
2833
        return WOLFSSL_SUCCESS;
2834
2835
    newAltName = AltNameNew(x509->heap);
2836
    if (newAltName == NULL)
2837
        return WOLFSSL_FAILURE;
2838
2839
    nameCopy = (char*)XMALLOC(nameSz + 1, x509->heap, DYNAMIC_TYPE_ALTNAME);
2840
    if (nameCopy == NULL) {
2841
        XFREE(newAltName, x509->heap, DYNAMIC_TYPE_ALTNAME);
2842
        return WOLFSSL_FAILURE;
2843
    }
2844
2845
    XMEMCPY(nameCopy, name, nameSz);
2846
2847
    nameCopy[nameSz] = '\0';
2848
2849
    newAltName->next = x509->altNames;
2850
    newAltName->type = type;
2851
    newAltName->len = (int)nameSz;
2852
    newAltName->name = nameCopy;
2853
    x509->altNames = newAltName;
2854
2855
    return WOLFSSL_SUCCESS;
2856
}
2857
2858
int wolfSSL_X509_add_altname(WOLFSSL_X509* x509, const char* name, int type)
2859
{
2860
    word32 nameSz;
2861
2862
    if (name == NULL)
2863
        return WOLFSSL_SUCCESS;
2864
2865
    nameSz = (word32)XSTRLEN(name);
2866
    if (nameSz == 0)
2867
        return WOLFSSL_SUCCESS;
2868
2869
    if (type == ASN_IP_TYPE) {
2870
        WOLFSSL_MSG("Type not supported, use wolfSSL_X509_add_altname_ex");
2871
        return WOLFSSL_FAILURE;
2872
    }
2873
2874
    return wolfSSL_X509_add_altname_ex(x509, name, nameSz, type);
2875
}
2876
2877
#ifndef NO_WOLFSSL_STUB
2878
WOLFSSL_X509_EXTENSION *wolfSSL_X509_delete_ext(WOLFSSL_X509 *x509, int loc)
2879
{
2880
    WOLFSSL_STUB("wolfSSL_X509_delete_ext");
2881
    (void)x509;
2882
    (void)loc;
2883
    return NULL;
2884
}
2885
2886
/* currently LHASH is not implemented (and not needed for Apache port) */
2887
WOLFSSL_X509_EXTENSION* wolfSSL_X509V3_EXT_conf_nid(
2888
        WOLF_LHASH_OF(CONF_VALUE)* conf, WOLFSSL_X509V3_CTX* ctx, int nid,
2889
        char* value)
2890
{
2891
    WOLFSSL_STUB("wolfSSL_X509V3_EXT_conf_nid");
2892
2893
    if (conf != NULL) {
2894
        WOLFSSL_MSG("Handling LHASH not implemented yet");
2895
        return NULL;
2896
    }
2897
2898
    (void)conf;
2899
    (void)ctx;
2900
    (void)nid;
2901
    (void)value;
2902
    return NULL;
2903
}
2904
2905
void wolfSSL_X509V3_set_ctx_nodb(WOLFSSL_X509V3_CTX* ctx)
2906
{
2907
    WOLFSSL_STUB("wolfSSL_X509V3_set_ctx_nodb");
2908
    (void)ctx;
2909
}
2910
#endif /* !NO_WOLFSSL_STUB */
2911
2912
#ifdef OPENSSL_EXTRA
2913
static WOLFSSL_X509_EXTENSION* createExtFromStr(int nid, const char *value)
2914
{
2915
    WOLFSSL_X509_EXTENSION* ext;
2916
2917
    ext = wolfSSL_X509_EXTENSION_new();
2918
    if (ext == NULL) {
2919
        WOLFSSL_MSG("memory error");
2920
        return NULL;
2921
    }
2922
    ext->value.nid = nid;
2923
2924
    switch (nid) {
2925
        case WC_NID_subject_key_identifier:
2926
        case WC_NID_authority_key_identifier:
2927
            if (wolfSSL_ASN1_STRING_set(&ext->value, value, -1)
2928
                    != WOLFSSL_SUCCESS) {
2929
                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
2930
                goto err_cleanup;
2931
            }
2932
            ext->value.type = CTC_UTF8;
2933
            break;
2934
        case WC_NID_subject_alt_name:
2935
        {
2936
            WOLFSSL_GENERAL_NAMES* gns;
2937
            WOLFSSL_GENERAL_NAME* gn;
2938
2939
            if (wolfSSL_ASN1_STRING_set(&ext->value, value, -1)
2940
                    != WOLFSSL_SUCCESS) {
2941
                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
2942
                goto err_cleanup;
2943
            }
2944
            ext->value.type = ASN_DNS_TYPE;
2945
2946
            /* add stack of general names */
2947
            gns = wolfSSL_sk_new_null();
2948
            if (gns == NULL) {
2949
                WOLFSSL_MSG("wolfSSL_sk_new_null error");
2950
                goto err_cleanup;
2951
            }
2952
            ext->ext_sk = gns; /* wolfSSL_X509_EXTENSION_free will handle
2953
                                * free'ing gns */
2954
            gns->type = STACK_TYPE_GEN_NAME;
2955
            gn = wolfSSL_GENERAL_NAME_new();
2956
            if (gn == NULL) {
2957
                WOLFSSL_MSG("wolfSSL_GENERAL_NAME_new error");
2958
                goto err_cleanup;
2959
            }
2960
            if (wolfSSL_sk_GENERAL_NAME_push(gns, gn) <= 0) {
2961
                WOLFSSL_MSG("wolfSSL_sk_GENERAL_NAME_push error");
2962
                wolfSSL_GENERAL_NAME_free(gn);
2963
                goto err_cleanup;
2964
            }
2965
            if (wolfSSL_ASN1_STRING_set(gn->d.ia5, value, -1)
2966
                    != WOLFSSL_SUCCESS) {
2967
                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set failed");
2968
                goto err_cleanup;
2969
            }
2970
            gn->type = ASN_DNS_TYPE;
2971
            break;
2972
        }
2973
        case WC_NID_key_usage:
2974
            if (wolfSSL_ASN1_STRING_set(&ext->value, value, -1)
2975
                    != WOLFSSL_SUCCESS) {
2976
                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
2977
                goto err_cleanup;
2978
            }
2979
            ext->value.type = KEY_USAGE_OID;
2980
            break;
2981
        case WC_NID_ext_key_usage:
2982
            if (wolfSSL_ASN1_STRING_set(&ext->value, value, -1)
2983
                    != WOLFSSL_SUCCESS) {
2984
                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
2985
                goto err_cleanup;
2986
            }
2987
            ext->value.type = EXT_KEY_USAGE_OID;
2988
            break;
2989
        default:
2990
            WOLFSSL_MSG("invalid or unsupported NID");
2991
            goto err_cleanup;
2992
    }
2993
    return ext;
2994
err_cleanup:
2995
    wolfSSL_X509_EXTENSION_free(ext);
2996
    return NULL;
2997
}
2998
2999
/**
3000
 * Create a WOLFSSL_X509_EXTENSION from the input arguments.
3001
 * @param conf  Not used
3002
 * @param ctx   Not used
3003
 * @param nid   Interprets the value parameter as the x509 extension that
3004
 *              corresponds to this NID.
3005
 * @param value A NULL terminated string that is taken as the value of the
3006
 *              newly created extension object.
3007
 * @return WOLFSSL_X509_EXTENSION* on success or NULL on failure.
3008
 */
3009
WOLFSSL_X509_EXTENSION* wolfSSL_X509V3_EXT_nconf_nid(WOLFSSL_CONF* conf,
3010
        WOLFSSL_X509V3_CTX *ctx, int nid, const char *value)
3011
{
3012
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_nconf_nid");
3013
3014
    if (value == NULL) {
3015
        WOLFSSL_MSG("value NULL parameter");
3016
        return NULL;
3017
    }
3018
3019
    if (conf != NULL || ctx != NULL) {
3020
        WOLFSSL_MSG("wolfSSL_X509V3_EXT_nconf_nid does not handle either "
3021
                    "conf or ctx parameters");
3022
    }
3023
3024
    return createExtFromStr(nid, value);
3025
}
3026
3027
/**
3028
 * Create a WOLFSSL_X509_EXTENSION from the input arguments.
3029
 * @param conf  Not used
3030
 * @param ctx   Not used
3031
 * @param sName The textual representation of the NID that the value parameter
3032
 *              should be interpreted as.
3033
 * @param value A NULL terminated string that is taken as the value of the
3034
 *              newly created extension object.
3035
 * @return WOLFSSL_X509_EXTENSION* on success or NULL on failure.
3036
 */
3037
WOLFSSL_X509_EXTENSION* wolfSSL_X509V3_EXT_nconf(WOLFSSL_CONF *conf,
3038
        WOLFSSL_X509V3_CTX *ctx, const char *sName, const char *value)
3039
{
3040
    const WOLFSSL_ObjectInfo* info = wolfssl_object_info;
3041
    size_t i;
3042
3043
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_nconf");
3044
3045
    if (value == NULL) {
3046
        WOLFSSL_MSG("value NULL parameter");
3047
        return NULL;
3048
    }
3049
3050
    if (conf != NULL || ctx != NULL) {
3051
        WOLFSSL_MSG("wolfSSL_X509V3_EXT_nconf does not handle either "
3052
                    "conf or ctx parameters");
3053
    }
3054
3055
    for (i = 0; i < wolfssl_object_info_sz; i++, info++) {
3056
        if (XSTRCMP(info->sName, sName) == 0)
3057
            return createExtFromStr(info->nid, value);
3058
    }
3059
3060
    WOLFSSL_MSG("value didn't match any known NID");
3061
    return NULL;
3062
}
3063
3064
static void wolfSSL_X509V3_EXT_METHOD_populate(WOLFSSL_v3_ext_method *method,
3065
                                               int nid)
3066
{
3067
    if (!method)
3068
        return;
3069
3070
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_METHOD_populate");
3071
    switch (nid) {
3072
    case WC_NID_subject_key_identifier:
3073
        method->i2s = (WOLFSSL_X509V3_EXT_I2S)wolfSSL_i2s_ASN1_STRING;
3074
        FALL_THROUGH;
3075
    case WC_NID_authority_key_identifier:
3076
    case WC_NID_key_usage:
3077
    case WC_NID_certificate_policies:
3078
    case WC_NID_policy_mappings:
3079
    case WC_NID_subject_alt_name:
3080
    case WC_NID_issuer_alt_name:
3081
    case WC_NID_basic_constraints:
3082
    case WC_NID_name_constraints:
3083
    case WC_NID_policy_constraints:
3084
    case WC_NID_ext_key_usage:
3085
    case WC_NID_crl_distribution_points:
3086
    case WC_NID_inhibit_any_policy:
3087
    case WC_NID_info_access:
3088
        WOLFSSL_MSG("Nothing to populate for current NID");
3089
        break;
3090
    default:
3091
        WOLFSSL_MSG("Unknown or unsupported NID");
3092
        break;
3093
    }
3094
3095
    return;
3096
}
3097
3098
/**
3099
 * @param nid One of the WC_NID_* constants defined in asn.h
3100
 * @param crit
3101
 * @param data This data is copied to the returned extension.
3102
 * @return
3103
 */
3104
WOLFSSL_X509_EXTENSION *wolfSSL_X509V3_EXT_i2d(int nid, int crit,
3105
                                               void *data)
3106
{
3107
    WOLFSSL_X509_EXTENSION *ext = NULL;
3108
    WOLFSSL_ASN1_STRING* asn1str = NULL;
3109
3110
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_i2d");
3111
3112
    if (!data) {
3113
        return NULL;
3114
    }
3115
3116
    if (!(ext = wolfSSL_X509_EXTENSION_new())) {
3117
        return NULL;
3118
    }
3119
3120
    wolfSSL_X509V3_EXT_METHOD_populate(&ext->ext_method, nid);
3121
3122
    switch (nid) {
3123
    case WC_NID_subject_key_identifier:
3124
        /* WOLFSSL_ASN1_STRING */
3125
    case WC_NID_key_usage:
3126
        /* WOLFSSL_ASN1_STRING */
3127
    {
3128
        asn1str = (WOLFSSL_ASN1_STRING*)data;
3129
        ext->value = *asn1str;
3130
        if (asn1str->isDynamic) {
3131
            ext->value.data = (char*)XMALLOC(asn1str->length, NULL,
3132
                                             DYNAMIC_TYPE_OPENSSL);
3133
            if (!ext->value.data) {
3134
                WOLFSSL_MSG("malloc failed");
3135
                /* Zero so that no existing memory is freed */
3136
                XMEMSET(&ext->value, 0, sizeof(WOLFSSL_ASN1_STRING));
3137
                goto err_cleanup;
3138
            }
3139
            XMEMCPY(ext->value.data, asn1str->data, asn1str->length);
3140
        }
3141
        else {
3142
            ext->value.data = ext->value.strData;
3143
        }
3144
3145
        if (!(ext->obj = wolfSSL_OBJ_nid2obj(nid))) {
3146
            WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new failed");
3147
            goto err_cleanup;
3148
        }
3149
3150
        break;
3151
    }
3152
    case WC_NID_subject_alt_name:
3153
        /* typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES */
3154
    case WC_NID_issuer_alt_name:
3155
        /* typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES */
3156
    case WC_NID_ext_key_usage:
3157
        /* typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE */
3158
    case WC_NID_info_access:
3159
        /* typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS */
3160
    {
3161
        WOLFSSL_STACK* sk = (WOLFSSL_STACK*)data;
3162
3163
        if (ext->ext_sk) {
3164
            wolfSSL_sk_pop_free(ext->ext_sk, NULL);
3165
        }
3166
3167
        if (!(ext->ext_sk = wolfSSL_sk_dup(sk))) {
3168
            WOLFSSL_MSG("wolfSSL_sk_dup failed");
3169
            goto err_cleanup;
3170
        }
3171
3172
        if (!(ext->obj = wolfSSL_OBJ_nid2obj(nid))) {
3173
            WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new failed");
3174
            goto err_cleanup;
3175
        }
3176
3177
        break;
3178
    }
3179
    case WC_NID_basic_constraints:
3180
    {
3181
        /* WOLFSSL_BASIC_CONSTRAINTS */
3182
        WOLFSSL_BASIC_CONSTRAINTS* bc = (WOLFSSL_BASIC_CONSTRAINTS*)data;
3183
3184
        if (!(ext->obj = wolfSSL_ASN1_OBJECT_new())) {
3185
            WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new failed");
3186
            goto err_cleanup;
3187
        }
3188
3189
        ext->obj->ca = bc->ca;
3190
        if (bc->pathlen) {
3191
            ext->obj->pathlen = wolfSSL_ASN1_INTEGER_dup(bc->pathlen);
3192
            if (!ext->obj->pathlen) {
3193
                WOLFSSL_MSG("wolfSSL_ASN1_INTEGER_dup failed");
3194
                goto err_cleanup;
3195
            }
3196
        }
3197
        break;
3198
    }
3199
    case WC_NID_authority_key_identifier:
3200
    {
3201
        /* AUTHORITY_KEYID */
3202
        WOLFSSL_AUTHORITY_KEYID* akey = (WOLFSSL_AUTHORITY_KEYID*)data;
3203
3204
        if (akey->keyid) {
3205
            if (wolfSSL_ASN1_STRING_set(&ext->value, akey->keyid->data,
3206
                                    akey->keyid->length) != WOLFSSL_SUCCESS) {
3207
                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set failed");
3208
                goto err_cleanup;
3209
            }
3210
            ext->value.type = akey->keyid->type;
3211
3212
            if (!(ext->obj = wolfSSL_OBJ_nid2obj(nid))) {
3213
                WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new failed");
3214
                goto err_cleanup;
3215
            }
3216
3217
        }
3218
        else if (akey->issuer) {
3219
            ext->obj = wolfSSL_ASN1_OBJECT_dup(akey->issuer);
3220
            if (!ext->obj) {
3221
                WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_dup failed");
3222
                goto err_cleanup;
3223
            }
3224
        }
3225
        else {
3226
            WOLFSSL_MSG("WC_NID_authority_key_identifier empty data");
3227
            goto err_cleanup;
3228
        }
3229
        break;
3230
    }
3231
    case WC_NID_inhibit_any_policy:
3232
        /* ASN1_INTEGER */
3233
    case WC_NID_certificate_policies:
3234
        /* STACK_OF(POLICYINFO) */
3235
    case WC_NID_policy_mappings:
3236
        /* STACK_OF(POLICY_MAPPING) */
3237
    case WC_NID_name_constraints:
3238
        /* NAME_CONSTRAINTS */
3239
    case WC_NID_policy_constraints:
3240
        /* POLICY_CONSTRAINTS */
3241
    case WC_NID_crl_distribution_points:
3242
        /* typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS */
3243
    default:
3244
        WOLFSSL_MSG("Unknown or unsupported NID");
3245
        break;
3246
    }
3247
3248
    ext->crit = crit;
3249
3250
    return ext;
3251
err_cleanup:
3252
    if (ext) {
3253
        wolfSSL_X509_EXTENSION_free(ext);
3254
    }
3255
    return NULL;
3256
}
3257
3258
/* Returns pointer to ASN1_OBJECT from an X509_EXTENSION object */
3259
WOLFSSL_ASN1_OBJECT* wolfSSL_X509_EXTENSION_get_object(
3260
    WOLFSSL_X509_EXTENSION* ext)
3261
{
3262
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_get_object");
3263
    if (ext == NULL)
3264
        return NULL;
3265
    return ext->obj;
3266
}
3267
3268
3269
/**
3270
 * duplicates the 'obj' input and sets it into the 'ext' structure
3271
 * returns WOLFSSL_SUCCESS on success
3272
 */
3273
int wolfSSL_X509_EXTENSION_set_object(WOLFSSL_X509_EXTENSION* ext,
3274
        const WOLFSSL_ASN1_OBJECT* obj)
3275
{
3276
    WOLFSSL_ASN1_OBJECT *current;
3277
3278
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_set_object");
3279
    if (ext == NULL)
3280
        return WOLFSSL_FAILURE;
3281
3282
    current = wolfSSL_X509_EXTENSION_get_object(ext);
3283
    if (current != NULL) {
3284
        wolfSSL_ASN1_OBJECT_free(current);
3285
    }
3286
    ext->obj = wolfSSL_ASN1_OBJECT_dup((WOLFSSL_ASN1_OBJECT*)obj);
3287
    return WOLFSSL_SUCCESS;
3288
}
3289
#endif /* OPENSSL_ALL */
3290
3291
/* Returns pointer to ASN1_STRING in X509_EXTENSION object */
3292
WOLFSSL_ASN1_STRING* wolfSSL_X509_EXTENSION_get_data(
3293
    WOLFSSL_X509_EXTENSION* ext)
3294
{
3295
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_get_data");
3296
    if (ext == NULL)
3297
        return NULL;
3298
    return &ext->value;
3299
}
3300
3301
3302
/**
3303
 * Creates a duplicate of input 'data' and sets it into 'ext' structure
3304
 * returns WOLFSSL_SUCCESS on success
3305
 */
3306
int wolfSSL_X509_EXTENSION_set_data(WOLFSSL_X509_EXTENSION* ext,
3307
        WOLFSSL_ASN1_STRING* data)
3308
{
3309
    WOLFSSL_ASN1_STRING* current;
3310
3311
    if (ext == NULL || data == NULL)
3312
        return WOLFSSL_FAILURE;
3313
3314
    current = wolfSSL_X509_EXTENSION_get_data(ext);
3315
    if (current->length > 0 && current->data != NULL && current->isDynamic) {
3316
        XFREE(current->data, NULL, DYNAMIC_TYPE_OPENSSL);
3317
    }
3318
3319
    return wolfSSL_ASN1_STRING_copy(&ext->value, data);
3320
}
3321
3322
#if !defined(NO_PWDBASED)
3323
int wolfSSL_X509_digest(const WOLFSSL_X509* x509, const WOLFSSL_EVP_MD* digest,
3324
        unsigned char* buf, unsigned int* len)
3325
{
3326
    int ret;
3327
3328
    WOLFSSL_ENTER("wolfSSL_X509_digest");
3329
3330
    if (x509 == NULL || digest == NULL) {
3331
        WOLFSSL_MSG("Null argument found");
3332
        return WOLFSSL_FAILURE;
3333
    }
3334
3335
    if (x509->derCert == NULL) {
3336
        WOLFSSL_MSG("No DER certificate stored in X509");
3337
        return WOLFSSL_FAILURE;
3338
    }
3339
3340
    ret = wolfSSL_EVP_Digest(x509->derCert->buffer, x509->derCert->length, buf,
3341
                              len, digest, NULL);
3342
    WOLFSSL_LEAVE("wolfSSL_X509_digest", ret);
3343
    return ret;
3344
}
3345
3346
int wolfSSL_X509_pubkey_digest(const WOLFSSL_X509 *x509,
3347
        const WOLFSSL_EVP_MD *digest, unsigned char* buf, unsigned int* len)
3348
{
3349
    int ret;
3350
3351
    WOLFSSL_ENTER("wolfSSL_X509_pubkey_digest");
3352
3353
    if (x509 == NULL || digest == NULL) {
3354
        WOLFSSL_MSG("Null argument found");
3355
        return WOLFSSL_FAILURE;
3356
    }
3357
3358
    if (x509->pubKey.buffer == NULL || x509->pubKey.length == 0) {
3359
        WOLFSSL_MSG("No DER public key stored in X509");
3360
        return WOLFSSL_FAILURE;
3361
    }
3362
3363
    ret = wolfSSL_EVP_Digest(x509->pubKey.buffer, x509->pubKey.length, buf,
3364
                              len, digest, NULL);
3365
    WOLFSSL_LEAVE("wolfSSL_X509_pubkey_digest", ret);
3366
    return ret;
3367
}
3368
#endif
3369
3370
#endif /* OPENSSL_EXTRA */
3371
3372
#ifdef OPENSSL_EXTRA
3373
3374
    #ifndef NO_WOLFSSL_STUB
3375
    const char* wolfSSL_X509_get_default_cert_file_env(void)
3376
    {
3377
        WOLFSSL_STUB("X509_get_default_cert_file_env");
3378
        return NULL;
3379
    }
3380
3381
    const char* wolfSSL_X509_get_default_cert_file(void)
3382
    {
3383
        WOLFSSL_STUB("X509_get_default_cert_file");
3384
        return NULL;
3385
    }
3386
3387
    const char* wolfSSL_X509_get_default_cert_dir_env(void)
3388
    {
3389
        WOLFSSL_STUB("X509_get_default_cert_dir_env");
3390
        return NULL;
3391
    }
3392
3393
    const char* wolfSSL_X509_get_default_cert_dir(void)
3394
    {
3395
        WOLFSSL_STUB("X509_get_default_cert_dir");
3396
        return NULL;
3397
    }
3398
    #endif
3399
3400
#endif /* OPENSSL_EXTRA */
3401
3402
#if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS) || \
3403
    defined(KEEP_OUR_CERT) || \
3404
    defined(OPENSSL_EXTRA)  || defined(OPENSSL_EXTRA_X509_SMALL)
3405
3406
/* user externally called free X509, if dynamic go ahead with free, otherwise
3407
 * don't */
3408
static void ExternalFreeX509(WOLFSSL_X509* x509)
3409
{
3410
#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA)
3411
    int doFree = 0;
3412
#endif
3413
3414
    WOLFSSL_ENTER("ExternalFreeX509");
3415
    if (x509) {
3416
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
3417
        wolfSSL_CRYPTO_cleanup_ex_data(&x509->ex_data);
3418
#endif
3419
        if (x509->dynamicMemory) {
3420
        #if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA)
3421
            int ret;
3422
            wolfSSL_RefDec(&x509->ref, &doFree, &ret);
3423
            if (ret != 0) {
3424
                WOLFSSL_MSG("Couldn't lock x509 mutex");
3425
            }
3426
            if (doFree)
3427
        #endif /* OPENSSL_EXTRA_X509_SMALL || OPENSSL_EXTRA */
3428
            {
3429
                FreeX509(x509);
3430
                XFREE(x509, x509->heap, DYNAMIC_TYPE_X509);
3431
            }
3432
        }
3433
        else {
3434
            WOLFSSL_MSG("free called on non dynamic object, not freeing");
3435
        }
3436
    }
3437
}
3438
3439
/* Frees an external WOLFSSL_X509 structure */
3440
WOLFSSL_ABI
3441
void wolfSSL_X509_free(WOLFSSL_X509* x509)
3442
{
3443
    WOLFSSL_ENTER("wolfSSL_X509_free");
3444
    ExternalFreeX509(x509);
3445
}
3446
#endif
3447
3448
#if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS) || \
3449
    defined(OPENSSL_EXTRA)  || defined(OPENSSL_EXTRA_X509_SMALL)
3450
3451
/* copy name into in buffer, at most sz bytes, if buffer is null will
3452
   malloc buffer, call responsible for freeing                     */
3453
WOLFSSL_ABI
3454
char* wolfSSL_X509_NAME_oneline(WOLFSSL_X509_NAME* name, char* in, int sz)
3455
{
3456
    int copySz;
3457
3458
    WOLFSSL_ENTER("wolfSSL_X509_NAME_oneline");
3459
3460
    if (name == NULL) {
3461
        WOLFSSL_MSG("WOLFSSL_X509_NAME pointer was NULL");
3462
        return NULL;
3463
    }
3464
3465
    if (name->sz == 0)
3466
        return in;
3467
3468
    if (!in) {
3469
    #ifdef WOLFSSL_STATIC_MEMORY
3470
        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
3471
        return NULL;
3472
    #else
3473
        in = (char*)XMALLOC(name->sz, NULL, DYNAMIC_TYPE_OPENSSL);
3474
        if (!in)
3475
            return in;
3476
        copySz = name->sz;
3477
    #endif
3478
    }
3479
    else {
3480
        copySz = (int)min((word32)sz, (word32)name->sz);
3481
        if (copySz <= 0)
3482
            return in;
3483
    }
3484
3485
    XMEMCPY(in, name->name, copySz - 1);
3486
    in[copySz - 1] = 0;
3487
3488
    return in;
3489
}
3490
3491
#ifdef OPENSSL_EXTRA
3492
/* Given an X509_NAME, convert it to canonical form and then hash
3493
 * with the provided hash type. Returns the first 4 bytes of the hash
3494
 * as unsigned long on success, and 0 otherwise. */
3495
static unsigned long X509NameHash(WOLFSSL_X509_NAME* name,
3496
    enum wc_HashType hashType)
3497
{
3498
    unsigned long  hash = 0;
3499
    unsigned char* canonName = NULL;
3500
    byte           digest[WC_MAX_DIGEST_SIZE];
3501
    int            size = 0;
3502
    int            rc;
3503
3504
    WOLFSSL_ENTER("X509NameHash");
3505
3506
    if (name == NULL) {
3507
        WOLFSSL_ERROR_MSG("WOLFSSL_X509_NAME pointer was NULL");
3508
        return 0;
3509
    }
3510
3511
    if (name->sz == 0) {
3512
        WOLFSSL_ERROR_MSG("Nothing to hash in WOLFSSL_X509_NAME");
3513
        return 0;
3514
    }
3515
3516
    size = wolfSSL_i2d_X509_NAME_canon(name, &canonName);
3517
3518
    if (size <= 0 || canonName == NULL) {
3519
        WOLFSSL_ERROR_MSG("wolfSSL_i2d_X509_NAME_canon error");
3520
        return 0;
3521
    }
3522
3523
    rc = wc_Hash(hashType, (const byte*)canonName, (word32)size, digest,
3524
        sizeof(digest));
3525
3526
    if (rc == 0) {
3527
        hash = (((unsigned long)digest[3] << 24) |
3528
                ((unsigned long)digest[2] << 16) |
3529
                ((unsigned long)digest[1] <<  8) |
3530
                ((unsigned long)digest[0]));
3531
    }
3532
    else if (rc == WC_NO_ERR_TRACE(HASH_TYPE_E)) {
3533
        WOLFSSL_ERROR_MSG("Hash function not compiled in");
3534
    }
3535
    else {
3536
        WOLFSSL_ERROR_MSG("Error hashing name");
3537
    }
3538
3539
    XFREE(canonName, NULL, DYNAMIC_TYPE_OPENSSL);
3540
    return hash;
3541
}
3542
3543
unsigned long wolfSSL_X509_NAME_hash(WOLFSSL_X509_NAME* name)
3544
{
3545
    return X509NameHash(name, WC_HASH_TYPE_SHA);
3546
}
3547
3548
/******************************************************************************
3549
* wolfSSL_X509_subject_name_hash
3550
* wolfSSL_X509_issuer_name_hash
3551
* Compute the hash digest of the subject / issuer name.
3552
* These functions prefer SHA-1 (if available) for compatibility. Otherwise
3553
* they use SHA-256.
3554
*
3555
* RETURNS:
3556
* The first 4 bytes of SHA-1 (or SHA-256) hash in little endian order as
3557
* unsigned long.
3558
* Otherwise, returns zero.
3559
*
3560
* Note:
3561
* Returns the same hash value as OpenSSL's X509_X_name_hash() API
3562
* if SHA-1 support is compiled in. SHA-256 will be used if SHA-1 is
3563
* not available.
3564
*/
3565
unsigned long wolfSSL_X509_subject_name_hash(const WOLFSSL_X509* x509)
3566
{
3567
    if (x509 == NULL) {
3568
        WOLFSSL_ERROR_MSG("WOLFSSL_X509 pointer was NULL");
3569
        return 0;
3570
    }
3571
3572
    #ifndef NO_SHA
3573
    return X509NameHash((WOLFSSL_X509_NAME*) &x509->subject, WC_HASH_TYPE_SHA);
3574
    #elif !defined(NO_SHA256)
3575
    return X509NameHash((WOLFSSL_X509_NAME*) &x509->subject,
3576
                        WC_HASH_TYPE_SHA256);
3577
    #else
3578
    WOLFSSL_ERROR_MSG("Hash function not compiled in");
3579
    return 0;
3580
    #endif
3581
}
3582
3583
unsigned long wolfSSL_X509_issuer_name_hash(const WOLFSSL_X509* x509)
3584
{
3585
    if (x509 == NULL) {
3586
        WOLFSSL_ERROR_MSG("WOLFSSL_X509 pointer was NULL");
3587
        return 0;
3588
    }
3589
3590
    #ifndef NO_SHA
3591
    return X509NameHash((WOLFSSL_X509_NAME*) &x509->issuer, WC_HASH_TYPE_SHA);
3592
    #elif !defined(NO_SHA256)
3593
    return X509NameHash((WOLFSSL_X509_NAME*) &x509->issuer,
3594
                        WC_HASH_TYPE_SHA256);
3595
    #else
3596
    WOLFSSL_ERROR_MSG("Hash function not compiled in");
3597
    return 0;
3598
    #endif
3599
}
3600
#endif /* OPENSSL_EXTRA */
3601
3602
#if defined(OPENSSL_EXTRA) && defined(XSNPRINTF)
3603
/* Copies X509 subject name into a buffer, with comma-separated name entries
3604
 *   (matching OpenSSL v1.0.0 format)
3605
 * Example Output for Issuer:
3606
 *
3607
 * C=US, ST=Montana, L=Bozeman, O=Sawtooth, OU=Consulting,
3608
 *  CN=www.wolfssl.com, emailAddress=info@wolfssl.com
3609
 */
3610
char* wolfSSL_X509_get_name_oneline(WOLFSSL_X509_NAME* name, char* in, int sz)
3611
{
3612
    int count, i;
3613
    int totalLen = 0;
3614
    char tmpBuf[256];
3615
    WOLFSSL_ENTER("wolfSSL_X509_get_name_oneline");
3616
3617
    if (name == NULL) {
3618
        WOLFSSL_MSG("wolfSSL_X509_get_name_oneline failed");
3619
        return NULL;
3620
    }
3621
    #ifdef WOLFSSL_STATIC_MEMORY
3622
    if (!in) {
3623
        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
3624
        return NULL;
3625
    }
3626
    #endif
3627
3628
    /* Loop through X509 name entries and copy new format to buffer */
3629
    count = wolfSSL_X509_NAME_entry_count(name);
3630
    for (i = 0; i < count; i++) {
3631
        WOLFSSL_X509_NAME_ENTRY* entry;
3632
        int nameSz;
3633
        int strSz;
3634
        int strLen;
3635
        char *str;
3636
        const int tmpBufSz = sizeof(tmpBuf);
3637
        char buf[80];
3638
        const char* sn;
3639
3640
        /* Get name entry and size */
3641
        entry = wolfSSL_X509_NAME_get_entry(name, i);
3642
        if (entry == NULL) {
3643
            WOLFSSL_MSG("wolfSSL_X509_NAME_get_entry failed");
3644
            return NULL;
3645
        }
3646
        nameSz = wolfSSL_X509_NAME_get_text_by_NID(name, entry->nid, buf,
3647
                                                                   sizeof(buf));
3648
        if (nameSz < 0) {
3649
            WOLFSSL_MSG("wolfSSL_X509_NAME_get_text_by_NID failed");
3650
            return NULL;
3651
        }
3652
3653
        /* Get short name */
3654
        sn = wolfSSL_OBJ_nid2sn(entry->nid);
3655
        if (sn == NULL) {
3656
            WOLFSSL_MSG("OBJ_nid2sn failed");
3657
            return NULL;
3658
        }
3659
3660
        /* Copy sn and name text to buffer
3661
         * Add extra strSz for '=', ',', ' ' and '\0' characters in XSNPRINTF.
3662
         */
3663
        if (i != count - 1) {
3664
            strSz = (int)XSTRLEN(sn) + nameSz + 4;
3665
            str = (char*)XMALLOC(strSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3666
            if (str == NULL) {
3667
                WOLFSSL_MSG("Memory error");
3668
                return NULL;
3669
            }
3670
            strLen = XSNPRINTF(str, (size_t)strSz, "%s=%s, ", sn, buf);
3671
            if ((strLen  < 0) || (strLen  >= strSz)) {
3672
                WOLFSSL_MSG("buffer overrun");
3673
                XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3674
                return NULL;
3675
            }
3676
        }
3677
        else {
3678
            /* Copy last name entry
3679
            * Add extra strSz for '=' and '\0' characters in XSNPRINTF.
3680
            */
3681
            strSz = (int)XSTRLEN(sn) + nameSz + 2;
3682
            str = (char*)XMALLOC(strSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3683
            if (str == NULL) {
3684
                WOLFSSL_MSG("Memory error");
3685
                return NULL;
3686
            }
3687
            strLen = XSNPRINTF(str, (size_t)strSz, "%s=%s", sn, buf);
3688
            if ((strLen  < 0) || (strLen  >= strSz)) {
3689
                WOLFSSL_MSG("buffer overrun");
3690
                XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3691
                return NULL;
3692
            }
3693
        }
3694
        /* Copy string to tmpBuf */
3695
        if (totalLen + strLen > tmpBufSz) {
3696
            WOLFSSL_MSG("buffer overrun");
3697
            XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3698
            return NULL;
3699
        }
3700
        XMEMCPY(tmpBuf + totalLen, str, strLen);
3701
        totalLen += strLen;
3702
        XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3703
    }
3704
3705
    /* Allocate space based on total string size if no buffer was provided */
3706
    if (!in) {
3707
        in = (char*)XMALLOC(totalLen+1, NULL, DYNAMIC_TYPE_OPENSSL);
3708
        if (in == NULL) {
3709
            WOLFSSL_MSG("Memory error");
3710
            return in;
3711
        }
3712
    }
3713
    else {
3714
        if (totalLen + 1 > sz) {
3715
            WOLFSSL_MSG("buffer overrun");
3716
            return NULL;
3717
        }
3718
    }
3719
3720
    XMEMCPY(in, tmpBuf, totalLen); /* cppcheck-suppress uninitvar */
3721
    in[totalLen] = '\0';
3722
3723
    return in;
3724
}
3725
#endif
3726
3727
3728
/* Wraps wolfSSL_X509_d2i
3729
 *
3730
 * returns a WOLFSSL_X509 structure pointer on success and NULL on fail
3731
 */
3732
WOLFSSL_X509* wolfSSL_d2i_X509(WOLFSSL_X509** x509, const unsigned char** in,
3733
        int len)
3734
{
3735
    WOLFSSL_X509* newX509 = NULL;
3736
    WOLFSSL_ENTER("wolfSSL_d2i_X509");
3737
3738
    if (in == NULL) {
3739
        WOLFSSL_MSG("NULL input for wolfSSL_d2i_X509");
3740
        return NULL;
3741
    }
3742
3743
    newX509 = wolfSSL_X509_d2i(x509, *in, len);
3744
    if (newX509 != NULL) {
3745
        *in += newX509->derCert->length;
3746
    }
3747
    return newX509;
3748
}
3749
3750
static WOLFSSL_X509* d2i_X509orX509REQ(WOLFSSL_X509** x509,
3751
                                  const byte* in, int len, int req, void* heap)
3752
{
3753
    WOLFSSL_X509 *newX509 = NULL;
3754
    int type = req ? CERTREQ_TYPE : CERT_TYPE;
3755
3756
    WOLFSSL_ENTER("wolfSSL_X509_d2i");
3757
3758
    if (in != NULL && len != 0
3759
    #ifndef WOLFSSL_CERT_REQ
3760
            && req == 0
3761
    #else
3762
            && (req == 0 || req == 1)
3763
    #endif
3764
            ) {
3765
    #ifdef WOLFSSL_SMALL_STACK
3766
        DecodedCert* cert;
3767
    #else
3768
        DecodedCert  cert[1];
3769
    #endif
3770
3771
    #ifdef WOLFSSL_SMALL_STACK
3772
        cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
3773
                                     DYNAMIC_TYPE_DCERT);
3774
        if (cert == NULL)
3775
            return NULL;
3776
    #endif
3777
3778
        InitDecodedCert(cert, (byte*)in, (word32)len, heap);
3779
    #ifdef WOLFSSL_CERT_REQ
3780
        cert->isCSR = (byte)req;
3781
    #endif
3782
        if (ParseCertRelative(cert, type, 0, NULL, NULL) == 0) {
3783
            newX509 = wolfSSL_X509_new_ex(heap);
3784
            if (newX509 != NULL) {
3785
                if (CopyDecodedToX509(newX509, cert) != 0) {
3786
                    wolfSSL_X509_free(newX509);
3787
                    newX509 = NULL;
3788
                }
3789
            }
3790
        }
3791
        FreeDecodedCert(cert);
3792
    #ifdef WOLFSSL_SMALL_STACK
3793
        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
3794
    #endif
3795
    }
3796
3797
    if (x509 != NULL)
3798
        *x509 = newX509;
3799
3800
    return newX509;
3801
}
3802
3803
int wolfSSL_X509_get_isCA(WOLFSSL_X509* x509)
3804
{
3805
    int isCA = 0;
3806
3807
    WOLFSSL_ENTER("wolfSSL_X509_get_isCA");
3808
3809
    if (x509 != NULL)
3810
        isCA = x509->isCa;
3811
3812
    WOLFSSL_LEAVE("wolfSSL_X509_get_isCA", isCA);
3813
3814
    return isCA;
3815
}
3816
3817
WOLFSSL_X509* wolfSSL_X509_d2i_ex(WOLFSSL_X509** x509, const byte* in, int len,
3818
    void* heap)
3819
{
3820
    return d2i_X509orX509REQ(x509, in, len, 0, heap);
3821
}
3822
3823
WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len)
3824
{
3825
    return wolfSSL_X509_d2i_ex(x509, in, len, NULL);
3826
}
3827
3828
#ifdef WOLFSSL_CERT_REQ
3829
WOLFSSL_X509* wolfSSL_X509_REQ_d2i(WOLFSSL_X509** x509,
3830
        const unsigned char* in, int len)
3831
{
3832
    return d2i_X509orX509REQ(x509, in, len, 1, NULL);
3833
}
3834
3835
WOLFSSL_X509* wolfSSL_d2i_X509_REQ_INFO(WOLFSSL_X509** req,
3836
        const unsigned char** in, int len)
3837
{
3838
    WOLFSSL_X509* ret = NULL;
3839
    WOLFSSL_ENTER("wolfSSL_d2i_X509_REQ_INFO");
3840
3841
    if (in == NULL) {
3842
        WOLFSSL_MSG("NULL input for wolfSSL_d2i_X509");
3843
        return NULL;
3844
    }
3845
3846
    ret = wolfSSL_X509_REQ_d2i(req, *in, len);
3847
    if (ret != NULL) {
3848
        *in += ret->derCert->length;
3849
    }
3850
    return ret;
3851
}
3852
#endif
3853
3854
#endif /* KEEP_PEER_CERT || SESSION_CERTS || OPENSSL_EXTRA ||
3855
          OPENSSL_EXTRA_X509_SMALL */
3856
3857
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
3858
/* returns the number of entries in the WOLFSSL_X509_NAME */
3859
int wolfSSL_X509_NAME_entry_count(WOLFSSL_X509_NAME* name)
3860
{
3861
    int count = 0;
3862
3863
    WOLFSSL_ENTER("wolfSSL_X509_NAME_entry_count");
3864
3865
    if (name != NULL)
3866
        count = name->entrySz;
3867
3868
    WOLFSSL_LEAVE("wolfSSL_X509_NAME_entry_count", count);
3869
    return count;
3870
}
3871
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
3872
3873
#if defined(OPENSSL_EXTRA) || \
3874
    defined(KEEP_OUR_CERT) || defined(KEEP_PEER_CERT)
3875
3876
/* return the next, if any, altname from the peer cert */
3877
WOLFSSL_ABI
3878
char* wolfSSL_X509_get_next_altname(WOLFSSL_X509* cert)
3879
{
3880
    char* ret = NULL;
3881
    WOLFSSL_ENTER("wolfSSL_X509_get_next_altname");
3882
3883
    /* don't have any to work with */
3884
    if (cert == NULL || cert->altNames == NULL)
3885
        return NULL;
3886
3887
    /* already went through them */
3888
    if (cert->altNamesNext == NULL) {
3889
#ifdef WOLFSSL_MULTICIRCULATE_ALTNAMELIST
3890
        /* Reset altNames List to head
3891
         * so that caller can circulate the list again
3892
         */
3893
        cert->altNamesNext = cert->altNames;
3894
#endif
3895
        return NULL;
3896
    }
3897
3898
    ret = cert->altNamesNext->name;
3899
#ifdef WOLFSSL_IP_ALT_NAME
3900
    /* return the IP address as a string */
3901
    if (cert->altNamesNext->type == ASN_IP_TYPE) {
3902
        ret = cert->altNamesNext->ipString;
3903
    }
3904
#endif
3905
    cert->altNamesNext = cert->altNamesNext->next;
3906
3907
    return ret;
3908
}
3909
3910
int wolfSSL_X509_get_signature(WOLFSSL_X509* x509,
3911
                                                unsigned char* buf, int* bufSz)
3912
{
3913
    WOLFSSL_ENTER("wolfSSL_X509_get_signature");
3914
    if (x509 == NULL || bufSz == NULL || (*bufSz < (int)x509->sig.length &&
3915
                buf != NULL))
3916
        return WOLFSSL_FATAL_ERROR;
3917
3918
    if (buf != NULL)
3919
        XMEMCPY(buf, x509->sig.buffer, x509->sig.length);
3920
    *bufSz = (int)x509->sig.length;
3921
3922
    return WOLFSSL_SUCCESS;
3923
}
3924
3925
3926
/* Getter function that copies over the DER public key buffer to "buf" and
3927
    * sets the size in bufSz. If "buf" is NULL then just bufSz is set to needed
3928
    * buffer size. "bufSz" passed in should initially be set by the user to be
3929
    * the size of "buf". This gets checked to make sure the buffer is large
3930
    * enough to hold the public key.
3931
    *
3932
    * Note: this is the X.509 form of key with "header" info.
3933
    * return WOLFSSL_SUCCESS on success
3934
    */
3935
int wolfSSL_X509_get_pubkey_buffer(WOLFSSL_X509* x509,
3936
                                            unsigned char* buf, int* bufSz)
3937
{
3938
#ifdef WOLFSSL_SMALL_STACK
3939
    DecodedCert* cert;
3940
#else
3941
    DecodedCert cert[1];
3942
#endif
3943
    const byte*  der;
3944
    int length = 0;
3945
    int    ret = 0, derSz = 0;
3946
    int badDate = 0;
3947
    const byte* pubKeyX509 = NULL;
3948
    int   pubKeyX509Sz = 0;
3949
3950
    WOLFSSL_ENTER("wolfSSL_X509_get_pubkey_buffer");
3951
    if (x509 == NULL || bufSz == NULL) {
3952
        WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", BAD_FUNC_ARG);
3953
        return WOLFSSL_FATAL_ERROR;
3954
    }
3955
3956
3957
#ifdef WOLFSSL_SMALL_STACK
3958
    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert),
3959
                                    x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
3960
    if (cert == NULL) {
3961
        WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", MEMORY_E);
3962
        return WOLFSSL_FATAL_ERROR;
3963
    }
3964
#endif
3965
3966
    der = wolfSSL_X509_get_der(x509, &derSz);
3967
    if (der != NULL) {
3968
        InitDecodedCert(cert, der, (word32)derSz, NULL);
3969
        ret = wc_GetPubX509(cert, 0, &badDate);
3970
        if (ret >= 0) {
3971
            word32 idx = cert->srcIdx;
3972
            pubKeyX509 = cert->source + cert->srcIdx;
3973
            ret = GetSequence(cert->source, &cert->srcIdx, &length,
3974
                    cert->maxIdx);
3975
            pubKeyX509Sz = length + (cert->srcIdx - idx);
3976
        }
3977
        FreeDecodedCert(cert);
3978
    }
3979
#ifdef WOLFSSL_SMALL_STACK
3980
    XFREE(cert, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
3981
#endif
3982
3983
    if (ret < 0) {
3984
        WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", ret);
3985
        return WOLFSSL_FATAL_ERROR;
3986
    }
3987
3988
    if (buf != NULL && pubKeyX509 != NULL) {
3989
        if (pubKeyX509Sz > *bufSz) {
3990
            WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", BUFFER_E);
3991
            return WOLFSSL_FATAL_ERROR;
3992
        }
3993
        XMEMCPY(buf, pubKeyX509, pubKeyX509Sz);
3994
    }
3995
    *bufSz = pubKeyX509Sz;
3996
3997
    return WOLFSSL_SUCCESS;
3998
}
3999
4000
4001
/* Getter function for the public key OID value
4002
    * return public key OID stored in WOLFSSL_X509 structure */
4003
int wolfSSL_X509_get_pubkey_type(WOLFSSL_X509* x509)
4004
{
4005
    if (x509 == NULL)
4006
        return WOLFSSL_FAILURE;
4007
    return x509->pubKeyOID;
4008
}
4009
4010
#endif /* OPENSSL_EXTRA || KEEP_OUR_CERT || KEEP_PEER_CERT || SESSION_CERTS */
4011
4012
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
4013
    defined(KEEP_OUR_CERT) || defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
4014
4015
/* write X509 serial number in unsigned binary to buffer
4016
    buffer needs to be at least EXTERNAL_SERIAL_SIZE (32) for all cases
4017
    return WOLFSSL_SUCCESS on success */
4018
int wolfSSL_X509_get_serial_number(WOLFSSL_X509* x509,
4019
                                    byte* in, int* inOutSz)
4020
{
4021
    WOLFSSL_ENTER("wolfSSL_X509_get_serial_number");
4022
    if (x509 == NULL || inOutSz == NULL) {
4023
        WOLFSSL_MSG("Null argument passed in");
4024
        return BAD_FUNC_ARG;
4025
    }
4026
4027
    if (in != NULL) {
4028
        if (*inOutSz < x509->serialSz) {
4029
            WOLFSSL_MSG("Serial buffer too small");
4030
            return BUFFER_E;
4031
        }
4032
        XMEMCPY(in, x509->serial, x509->serialSz);
4033
    }
4034
    *inOutSz = x509->serialSz;
4035
4036
    return WOLFSSL_SUCCESS;
4037
}
4038
4039
/* not an openssl compatibility function - getting for derCert */
4040
const byte* wolfSSL_X509_get_der(WOLFSSL_X509* x509, int* outSz)
4041
{
4042
    WOLFSSL_ENTER("wolfSSL_X509_get_der");
4043
4044
    if (x509 == NULL || x509->derCert == NULL || outSz == NULL)
4045
        return NULL;
4046
4047
    *outSz = (int)x509->derCert->length;
4048
    return x509->derCert->buffer;
4049
}
4050
4051
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || KEEP_OUR_CERT ||
4052
        * KEEP_PEER_CERT || SESSION_CERTS */
4053
4054
#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) || \
4055
    defined(OPENSSL_ALL) || defined(KEEP_OUR_CERT) || \
4056
    defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
4057
4058
/* used by JSSE (not a standard compatibility function) */
4059
WOLFSSL_ABI
4060
const byte* wolfSSL_X509_notBefore(WOLFSSL_X509* x509)
4061
{
4062
    WOLFSSL_ENTER("wolfSSL_X509_notBefore");
4063
4064
    if (x509 == NULL)
4065
        return NULL;
4066
4067
    XMEMSET(x509->notBeforeData, 0, sizeof(x509->notBeforeData));
4068
    x509->notBeforeData[0] = (byte)x509->notBefore.type;
4069
    x509->notBeforeData[1] = (byte)x509->notBefore.length;
4070
    XMEMCPY(&x509->notBeforeData[2], x509->notBefore.data,
4071
        x509->notBefore.length);
4072
4073
    return x509->notBeforeData;
4074
}
4075
4076
/* used by JSSE (not a standard compatibility function) */
4077
WOLFSSL_ABI
4078
const byte* wolfSSL_X509_notAfter(WOLFSSL_X509* x509)
4079
{
4080
    WOLFSSL_ENTER("wolfSSL_X509_notAfter");
4081
4082
    if (x509 == NULL)
4083
        return NULL;
4084
4085
    XMEMSET(x509->notAfterData, 0, sizeof(x509->notAfterData));
4086
    x509->notAfterData[0] = (byte)x509->notAfter.type;
4087
    x509->notAfterData[1] = (byte)x509->notAfter.length;
4088
    XMEMCPY(&x509->notAfterData[2], x509->notAfter.data, x509->notAfter.length);
4089
4090
    return x509->notAfterData;
4091
}
4092
4093
int wolfSSL_X509_version(WOLFSSL_X509* x509)
4094
{
4095
    WOLFSSL_ENTER("wolfSSL_X509_version");
4096
4097
    if (x509 == NULL)
4098
        return 0;
4099
4100
    return x509->version;
4101
}
4102
#endif
4103
4104
#ifdef OPENSSL_EXTRA
4105
4106
/* get the buffer to be signed (tbs) from the WOLFSSL_X509 certificate
4107
    *
4108
    * outSz : gets set to the size of the buffer
4109
    * returns a pointer to the internal buffer at the location of TBS on
4110
    *         on success and NULL on failure.
4111
    */
4112
const unsigned char* wolfSSL_X509_get_tbs(WOLFSSL_X509* x509, int* outSz)
4113
{
4114
    int sz = 0, len;
4115
    unsigned int idx = 0, tmpIdx;
4116
    const unsigned char* der = NULL;
4117
    const unsigned char* tbs = NULL;
4118
4119
    if (x509 == NULL || outSz == NULL) {
4120
        return NULL;
4121
    }
4122
4123
    der = wolfSSL_X509_get_der(x509, &sz);
4124
    if (der == NULL) {
4125
        return NULL;
4126
    }
4127
4128
    if (GetSequence(der, &idx, &len, (word32)sz) < 0) {
4129
        return NULL;
4130
    }
4131
    tbs = der + idx;
4132
    tmpIdx = idx;
4133
    if (GetSequence(der, &idx, &len, (word32)sz) < 0) {
4134
        return NULL;
4135
    }
4136
    *outSz = len + (idx - tmpIdx);
4137
    return tbs;
4138
}
4139
4140
#ifdef WOLFSSL_SEP
4141
4142
/* copy oid into in buffer, at most *inOutSz bytes, if buffer is null will
4143
   malloc buffer, call responsible for freeing. Actual size returned in
4144
   *inOutSz. Requires inOutSz be non-null */
4145
byte* wolfSSL_X509_get_device_type(WOLFSSL_X509* x509, byte* in, int *inOutSz)
4146
{
4147
    int copySz;
4148
4149
    WOLFSSL_ENTER("wolfSSL_X509_get_dev_type");
4150
    if (x509 == NULL) return NULL;
4151
    if (inOutSz == NULL) return NULL;
4152
    if (!x509->deviceTypeSz) return in;
4153
4154
    copySz = min(*inOutSz, x509->deviceTypeSz);
4155
4156
    if (!in) {
4157
    #ifdef WOLFSSL_STATIC_MEMORY
4158
        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
4159
        return NULL;
4160
    #else
4161
        in = (byte*)XMALLOC(x509->deviceTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
4162
        if (!in) return in;
4163
        copySz = x509->deviceTypeSz;
4164
    #endif
4165
    }
4166
4167
    XMEMCPY(in, x509->deviceType, copySz);
4168
    *inOutSz = copySz;
4169
4170
    return in;
4171
}
4172
4173
4174
byte* wolfSSL_X509_get_hw_type(WOLFSSL_X509* x509, byte* in, int* inOutSz)
4175
{
4176
    int copySz;
4177
4178
    WOLFSSL_ENTER("wolfSSL_X509_get_hw_type");
4179
    if (x509 == NULL) return NULL;
4180
    if (inOutSz == NULL) return NULL;
4181
    if (!x509->hwTypeSz) return in;
4182
4183
    copySz = min(*inOutSz, x509->hwTypeSz);
4184
4185
    if (!in) {
4186
    #ifdef WOLFSSL_STATIC_MEMORY
4187
        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
4188
        return NULL;
4189
    #else
4190
        in = (byte*)XMALLOC(x509->hwTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
4191
        if (!in) return in;
4192
        copySz = x509->hwTypeSz;
4193
    #endif
4194
    }
4195
4196
    XMEMCPY(in, x509->hwType, copySz);
4197
    *inOutSz = copySz;
4198
4199
    return in;
4200
}
4201
4202
4203
byte* wolfSSL_X509_get_hw_serial_number(WOLFSSL_X509* x509,byte* in,
4204
                                        int* inOutSz)
4205
{
4206
    int copySz;
4207
4208
    WOLFSSL_ENTER("wolfSSL_X509_get_hw_serial_number");
4209
    if (x509 == NULL) return NULL;
4210
    if (inOutSz == NULL) return NULL;
4211
    if (!x509->hwTypeSz) return in;
4212
4213
    copySz = min(*inOutSz, x509->hwSerialNumSz);
4214
4215
    if (!in) {
4216
    #ifdef WOLFSSL_STATIC_MEMORY
4217
        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
4218
        return NULL;
4219
    #else
4220
        in = (byte*)XMALLOC(x509->hwSerialNumSz, 0, DYNAMIC_TYPE_OPENSSL);
4221
        if (!in) return in;
4222
        copySz = x509->hwSerialNumSz;
4223
    #endif
4224
    }
4225
4226
    XMEMCPY(in, x509->hwSerialNum, copySz);
4227
    *inOutSz = copySz;
4228
4229
    return in;
4230
}
4231
4232
#endif /* WOLFSSL_SEP */
4233
#endif /* OPENSSL_EXTRA */
4234
4235
/* require OPENSSL_EXTRA since wolfSSL_X509_free is wrapped by OPENSSL_EXTRA */
4236
#if defined(OPENSSL_EXTRA)
4237
4238
WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notBefore(const WOLFSSL_X509* x509)
4239
{
4240
    WOLFSSL_ENTER("wolfSSL_X509_get_notBefore");
4241
4242
    if (x509 == NULL)
4243
        return NULL;
4244
4245
    return (WOLFSSL_ASN1_TIME*)&x509->notBefore;
4246
}
4247
4248
4249
WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notAfter(const WOLFSSL_X509* x509)
4250
{
4251
    WOLFSSL_ENTER("wolfSSL_X509_get_notAfter");
4252
4253
    if (x509 == NULL)
4254
        return NULL;
4255
4256
    return (WOLFSSL_ASN1_TIME*)&x509->notAfter;
4257
}
4258
4259
4260
/* return number of elements on success 0 on fail */
4261
int wolfSSL_sk_X509_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk,
4262
    WOLFSSL_X509* x509)
4263
{
4264
    WOLFSSL_ENTER("wolfSSL_sk_X509_push");
4265
4266
    if (sk == NULL || x509 == NULL) {
4267
        return WOLFSSL_FAILURE;
4268
    }
4269
4270
    return wolfSSL_sk_push(sk, x509);
4271
}
4272
4273
4274
/* Return and remove the last x509 pushed on stack */
4275
WOLFSSL_X509* wolfSSL_sk_X509_pop(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk)
4276
{
4277
    return (WOLFSSL_X509*)wolfSSL_sk_pop(sk);
4278
}
4279
4280
/* Getter function for WOLFSSL_X509 pointer
4281
 *
4282
 * sk is the stack to retrieve pointer from
4283
 * i  is the index value in stack
4284
 *
4285
 * returns a pointer to a WOLFSSL_X509 structure on success and NULL on
4286
 *         fail
4287
 */
4288
WOLFSSL_X509* wolfSSL_sk_X509_value(WOLF_STACK_OF(WOLFSSL_X509)* sk, int i)
4289
{
4290
    WOLFSSL_ENTER("wolfSSL_sk_X509_value");
4291
4292
    for (; sk != NULL && i > 0; i--)
4293
        sk = sk->next;
4294
4295
    if (i != 0 || sk == NULL)
4296
        return NULL;
4297
    return sk->data.x509;
4298
}
4299
4300
4301
/* Return and remove the first x509 pushed on stack */
4302
WOLFSSL_X509* wolfSSL_sk_X509_shift(WOLF_STACK_OF(WOLFSSL_X509)* sk)
4303
{
4304
    return (WOLFSSL_X509*)wolfSSL_sk_pop_node(sk, 0);
4305
}
4306
4307
#endif /* OPENSSL_EXTRA */
4308
4309
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
4310
/* Free's all nodes in X509 stack. This is different then wolfSSL_sk_X509_free
4311
 * in that it free's the underlying objects pushed to the stack.
4312
 *
4313
 * sk  stack to free nodes in
4314
 * f   X509 free function
4315
 */
4316
void wolfSSL_sk_X509_pop_free(WOLF_STACK_OF(WOLFSSL_X509)* sk,
4317
    void (*f) (WOLFSSL_X509*))
4318
{
4319
    WOLFSSL_ENTER("wolfSSL_sk_X509_pop_free");
4320
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
4321
}
4322
4323
4324
/* free just the stack structure */
4325
void wolfSSL_sk_X509_free(WOLF_STACK_OF(WOLFSSL_X509)* sk)
4326
{
4327
    wolfSSL_sk_free(sk);
4328
}
4329
4330
#ifdef HAVE_CRL
4331
WOLFSSL_STACK* wolfSSL_sk_X509_CRL_new(void)
4332
{
4333
    WOLFSSL_STACK* s = wolfSSL_sk_new_node(NULL);
4334
    if (s != NULL)
4335
        s->type = STACK_TYPE_X509_CRL;
4336
    return s;
4337
}
4338
4339
void wolfSSL_sk_X509_CRL_pop_free(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk,
4340
    void (*f) (WOLFSSL_X509_CRL*))
4341
{
4342
    WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_pop_free");
4343
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
4344
}
4345
4346
void wolfSSL_sk_X509_CRL_free(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk)
4347
{
4348
    wolfSSL_sk_X509_CRL_pop_free(sk, NULL);
4349
}
4350
4351
/* return number of elements on success 0 on fail */
4352
int wolfSSL_sk_X509_CRL_push(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk,
4353
    WOLFSSL_X509_CRL* crl)
4354
{
4355
    WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_push");
4356
4357
    if (sk == NULL || crl == NULL) {
4358
        return WOLFSSL_FAILURE;
4359
    }
4360
4361
    return wolfSSL_sk_push(sk, crl);
4362
}
4363
4364
WOLFSSL_X509_CRL* wolfSSL_sk_X509_CRL_value(WOLF_STACK_OF(WOLFSSL_X509)* sk,
4365
                                            int i)
4366
{
4367
    WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_value");
4368
    if (sk)
4369
        return (WOLFSSL_X509_CRL*)wolfSSL_sk_value(sk, i);
4370
    return NULL;
4371
}
4372
4373
int wolfSSL_sk_X509_CRL_num(WOLF_STACK_OF(WOLFSSL_X509)* sk)
4374
{
4375
    WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_num");
4376
    if (sk)
4377
        return wolfSSL_sk_num(sk);
4378
    return 0;
4379
}
4380
#endif /* HAVE_CRL */
4381
4382
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
4383
4384
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_QT)
4385
/* return number of elements on success 0 on fail */
4386
int wolfSSL_sk_ACCESS_DESCRIPTION_push(WOLF_STACK_OF(ACCESS_DESCRIPTION)* sk,
4387
                                              WOLFSSL_ACCESS_DESCRIPTION* a)
4388
{
4389
    WOLFSSL_ENTER("wolfSSL_sk_ACCESS_DESCRIPTION_push");
4390
4391
    return wolfSSL_sk_push(sk, a);
4392
}
4393
4394
/* Frees all nodes in ACCESS_DESCRIPTION stack
4395
*
4396
* sk stack of nodes to free
4397
* f  free function to use
4398
*/
4399
void wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(WOLFSSL_STACK* sk,
4400
    void (*f) (WOLFSSL_ACCESS_DESCRIPTION*))
4401
{
4402
   WOLFSSL_ENTER("wolfSSL_sk_ACCESS_DESCRIPTION_pop_free");
4403
   wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
4404
}
4405
4406
void wolfSSL_sk_ACCESS_DESCRIPTION_free(WOLFSSL_STACK* sk)
4407
{
4408
    wolfSSL_sk_free(sk);
4409
}
4410
4411
4412
/* AUTHORITY_INFO_ACCESS object is a stack of ACCESS_DESCRIPTION objects,
4413
 * to free the stack the WOLFSSL_ACCESS_DESCRIPTION stack free function is
4414
 * used */
4415
void wolfSSL_AUTHORITY_INFO_ACCESS_free(
4416
        WOLF_STACK_OF(WOLFSSL_ACCESS_DESCRIPTION)* sk)
4417
{
4418
    WOLFSSL_ENTER("wolfSSL_AUTHORITY_INFO_ACCESS_free");
4419
    wolfSSL_sk_ACCESS_DESCRIPTION_free(sk);
4420
}
4421
4422
void wolfSSL_AUTHORITY_INFO_ACCESS_pop_free(
4423
        WOLF_STACK_OF(WOLFSSL_ACCESS_DESCRIPTION)* sk,
4424
        void (*f) (WOLFSSL_ACCESS_DESCRIPTION*))
4425
{
4426
    WOLFSSL_ENTER("wolfSSL_AUTHORITY_INFO_ACCESS_free");
4427
    wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(sk, f);
4428
}
4429
4430
4431
void wolfSSL_ACCESS_DESCRIPTION_free(WOLFSSL_ACCESS_DESCRIPTION* a)
4432
{
4433
    WOLFSSL_ENTER("wolfSSL_ACCESS_DESCRIPTION_free");
4434
    if (a == NULL)
4435
        return;
4436
4437
    if (a->method)
4438
        wolfSSL_ASN1_OBJECT_free(a->method);
4439
    if (a->location)
4440
        wolfSSL_GENERAL_NAME_free(a->location);
4441
    XFREE(a, NULL, DYNAMIC_TYPE_X509_EXT);
4442
4443
    /* a = NULL, don't try to a or double free it */
4444
}
4445
#endif /* OPENSSL_EXTRA || WOLFSSL_QT */
4446
4447
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
4448
4449
/* Creates and returns new GENERAL_NAME structure */
4450
WOLFSSL_GENERAL_NAME* wolfSSL_GENERAL_NAME_new(void)
4451
{
4452
    WOLFSSL_GENERAL_NAME* gn;
4453
    WOLFSSL_ENTER("GENERAL_NAME_new");
4454
4455
    gn = (WOLFSSL_GENERAL_NAME*)XMALLOC(sizeof(WOLFSSL_GENERAL_NAME), NULL,
4456
                                                             DYNAMIC_TYPE_ASN1);
4457
    if (gn == NULL) {
4458
        return NULL;
4459
    }
4460
    XMEMSET(gn, 0, sizeof(WOLFSSL_GENERAL_NAME));
4461
4462
    gn->d.ia5 = wolfSSL_ASN1_STRING_new();
4463
    if (gn->d.ia5 == NULL) {
4464
        WOLFSSL_MSG("Issue creating ASN1_STRING struct");
4465
        wolfSSL_GENERAL_NAME_free(gn);
4466
        return NULL;
4467
    }
4468
    gn->type = WOLFSSL_GEN_IA5;
4469
    return gn;
4470
}
4471
4472
WOLFSSL_GENERAL_NAME* wolfSSL_GENERAL_NAME_dup(WOLFSSL_GENERAL_NAME* gn)
4473
{
4474
    WOLFSSL_GENERAL_NAME* dupl = NULL;
4475
4476
    WOLFSSL_ENTER("wolfSSL_GENERAL_NAME_dup");
4477
4478
    if (!gn) {
4479
        WOLFSSL_MSG("Bad parameter");
4480
        return NULL;
4481
    }
4482
4483
    if (!(dupl = wolfSSL_GENERAL_NAME_new())) {
4484
        WOLFSSL_MSG("wolfSSL_GENERAL_NAME_new error");
4485
        return NULL;
4486
    }
4487
4488
    wolfSSL_ASN1_STRING_free(dupl->d.ia5);
4489
    dupl->d.ia5 = NULL;
4490
    switch (gn->type) {
4491
    /* WOLFSSL_ASN1_STRING types */
4492
    case WOLFSSL_GEN_DNS:
4493
        if (!(dupl->d.dNSName = wolfSSL_ASN1_STRING_dup(gn->d.dNSName))) {
4494
            WOLFSSL_MSG("wolfSSL_ASN1_STRING_dup error");
4495
            goto error;
4496
        }
4497
        break;
4498
    case WOLFSSL_GEN_IPADD:
4499
        if (!(dupl->d.iPAddress = wolfSSL_ASN1_STRING_dup(gn->d.iPAddress))) {
4500
            WOLFSSL_MSG("wolfSSL_ASN1_STRING_dup error");
4501
            goto error;
4502
        }
4503
        break;
4504
    case WOLFSSL_GEN_EMAIL:
4505
        if (!(dupl->d.rfc822Name = wolfSSL_ASN1_STRING_dup(gn->d.rfc822Name))) {
4506
            WOLFSSL_MSG("wolfSSL_ASN1_STRING_dup error");
4507
            goto error;
4508
        }
4509
        break;
4510
    case WOLFSSL_GEN_URI:
4511
        if (!(dupl->d.uniformResourceIdentifier =
4512
                wolfSSL_ASN1_STRING_dup(gn->d.uniformResourceIdentifier))) {
4513
            WOLFSSL_MSG("wolfSSL_ASN1_STRING_dup error");
4514
            goto error;
4515
        }
4516
        break;
4517
    case WOLFSSL_GEN_OTHERNAME:
4518
        if (gn->d.otherName->value->type != WOLFSSL_V_ASN1_UTF8STRING) {
4519
            WOLFSSL_MSG("Unsupported othername value type");
4520
            goto error;
4521
        }
4522
        dupl->d.otherName = (WOLFSSL_ASN1_OTHERNAME*)XMALLOC(
4523
            sizeof(WOLFSSL_ASN1_OTHERNAME), NULL, DYNAMIC_TYPE_ASN1);
4524
        if (dupl->d.otherName == NULL) {
4525
            WOLFSSL_MSG("XMALLOC error");
4526
            goto error;
4527
        }
4528
        dupl->d.otherName->type_id = wolfSSL_ASN1_OBJECT_dup(
4529
            gn->d.otherName->type_id);
4530
        dupl->d.otherName->value = (WOLFSSL_ASN1_TYPE*)XMALLOC(
4531
            sizeof(WOLFSSL_ASN1_TYPE), NULL, DYNAMIC_TYPE_ASN1);
4532
        if (dupl->d.otherName->value != NULL) {
4533
            dupl->d.otherName->value->type = gn->d.otherName->value->type;
4534
            dupl->d.otherName->value->value.utf8string =
4535
                wolfSSL_ASN1_STRING_dup(
4536
                                      gn->d.otherName->value->value.utf8string);
4537
        }
4538
        if ((dupl->d.otherName->type_id == NULL) ||
4539
            (dupl->d.otherName->value == NULL) ||
4540
            (dupl->d.otherName->value->value.utf8string == NULL)) {
4541
            wolfSSL_ASN1_OBJECT_free(dupl->d.otherName->type_id);
4542
            wolfSSL_ASN1_TYPE_free(dupl->d.otherName->value);
4543
            XFREE(dupl->d.otherName, NULL, DYNAMIC_TYPE_ASN1);
4544
            dupl->d.otherName = NULL;
4545
            WOLFSSL_MSG("error duping othername");
4546
            goto error;
4547
        }
4548
        break;
4549
    case WOLFSSL_GEN_X400:
4550
    case WOLFSSL_GEN_DIRNAME:
4551
    case WOLFSSL_GEN_EDIPARTY:
4552
    case WOLFSSL_GEN_RID:
4553
    default:
4554
        WOLFSSL_MSG("Unrecognized or unsupported GENERAL_NAME type");
4555
        goto error;
4556
    }
4557
    dupl->type = gn->type;
4558
4559
    return dupl;
4560
error:
4561
    wolfSSL_GENERAL_NAME_free(dupl);
4562
    return NULL;
4563
}
4564
4565
/* Set an Othername in a general name.
4566
 *
4567
 * @param [out] gen     Pointer to the GENERAL_NAME where the othername is set.
4568
 * @param [in]  oid     Object ID (ie UPN).
4569
 * @param [in]  name    The actual name.
4570
 * @return  WOLFSSL_FAILURE on invalid parameter or memory error,
4571
 *          WOLFSSL_SUCCESS otherwise.
4572
 */
4573
int wolfSSL_GENERAL_NAME_set0_othername(WOLFSSL_GENERAL_NAME* gen,
4574
                                        WOLFSSL_ASN1_OBJECT* oid,
4575
                                        WOLFSSL_ASN1_TYPE* value)
4576
{
4577
    WOLFSSL_ASN1_OBJECT *x = NULL;
4578
4579
    if ((gen == NULL) || (oid == NULL) || (value == NULL)) {
4580
        return WOLFSSL_FAILURE;
4581
    }
4582
4583
    x = wolfSSL_ASN1_OBJECT_dup(oid);
4584
    if (x == NULL) {
4585
        WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_dup() failed");
4586
        return WOLFSSL_FAILURE;
4587
    }
4588
4589
    gen->type = WOLFSSL_GEN_OTHERNAME;
4590
    gen->d.otherName->type_id = x;
4591
    gen->d.otherName->value = value;
4592
    return WOLFSSL_SUCCESS;
4593
}
4594
4595
/* return number of elements on success 0 on fail */
4596
int wolfSSL_sk_GENERAL_NAME_push(WOLFSSL_GENERAL_NAMES* sk,
4597
                                 WOLFSSL_GENERAL_NAME* gn)
4598
{
4599
    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_push");
4600
4601
    return wolfSSL_sk_push(sk, gn);
4602
}
4603
4604
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
4605
4606
#ifdef OPENSSL_EXTRA
4607
4608
/* Returns the general name at index i from the stack
4609
 *
4610
 * sk  stack to get general name from
4611
 * idx index to get
4612
 *
4613
 * return a pointer to the internal node of the stack
4614
 */
4615
WOLFSSL_GENERAL_NAME* wolfSSL_sk_GENERAL_NAME_value(WOLFSSL_STACK* sk, int idx)
4616
{
4617
    return (WOLFSSL_GENERAL_NAME*)wolfSSL_sk_value(sk, idx);
4618
}
4619
4620
/* Gets the number of nodes in the stack
4621
 *
4622
 * sk  stack to get the number of nodes from
4623
 *
4624
 * returns the number of nodes, -1 if no nodes
4625
 */
4626
int wolfSSL_sk_GENERAL_NAME_num(WOLFSSL_STACK* sk)
4627
{
4628
    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_num");
4629
4630
    return wolfSSL_sk_num(sk);
4631
}
4632
4633
/* Allocates an empty GENERAL NAME stack */
4634
WOLFSSL_STACK* wolfSSL_sk_GENERAL_NAME_new(void *cmpFunc) {
4635
    WOLFSSL_STACK* sk = NULL;
4636
    (void)cmpFunc;
4637
    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_new");
4638
4639
    sk = wolfSSL_sk_new_null();
4640
    if (sk != NULL) {
4641
        sk->type = STACK_TYPE_GEN_NAME;
4642
    }
4643
4644
    return sk;
4645
}
4646
#endif /* OPENSSL_EXTRA */
4647
4648
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
4649
4650
/* Frees all nodes in a GENERAL NAME stack
4651
 *
4652
 * sk stack of nodes to free
4653
 * f  free function to use, not called with wolfSSL
4654
 */
4655
void wolfSSL_sk_GENERAL_NAME_pop_free(WOLFSSL_STACK* sk,
4656
        void (*f) (WOLFSSL_GENERAL_NAME*))
4657
{
4658
    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_pop_free");
4659
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
4660
}
4661
4662
void wolfSSL_sk_GENERAL_NAME_free(WOLFSSL_STACK* sk)
4663
{
4664
    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_free");
4665
    wolfSSL_sk_X509_pop_free(sk, NULL);
4666
}
4667
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
4668
4669
#ifdef OPENSSL_EXTRA
4670
static void wolfSSL_DIST_POINT_NAME_free(WOLFSSL_DIST_POINT_NAME* dpn)
4671
{
4672
    if (dpn != NULL) {
4673
        if (dpn->name.fullname != NULL) {
4674
            wolfSSL_sk_X509_pop_free(dpn->name.fullname, NULL);
4675
        }
4676
        XFREE(dpn, NULL, DYNAMIC_TYPE_OPENSSL);
4677
    }
4678
}
4679
4680
4681
/* returns new pointer on success and NULL on fail */
4682
static WOLFSSL_DIST_POINT_NAME* wolfSSL_DIST_POINT_NAME_new(void)
4683
{
4684
    WOLFSSL_DIST_POINT_NAME* dpn = NULL;
4685
    WOLFSSL_GENERAL_NAMES* gns = NULL;
4686
4687
    dpn = (WOLFSSL_DIST_POINT_NAME*)XMALLOC(sizeof(WOLFSSL_DIST_POINT_NAME),
4688
                                            NULL, DYNAMIC_TYPE_OPENSSL);
4689
    if (dpn == NULL) {
4690
        return NULL;
4691
    }
4692
    XMEMSET(dpn, 0, sizeof(WOLFSSL_DIST_POINT_NAME));
4693
4694
    gns = wolfSSL_sk_new_null();
4695
    if (gns == NULL) {
4696
        WOLFSSL_MSG("wolfSSL_sk_new_null error");
4697
        XFREE(dpn, NULL, DYNAMIC_TYPE_OPENSSL);
4698
        return NULL;
4699
    }
4700
    gns->type = STACK_TYPE_GEN_NAME;
4701
4702
    /* DIST_POINT_NAME type may be 0 or 1, indicating whether fullname or
4703
     * relativename is used. See: RFC 5280 section 4.2.1.13 */
4704
    dpn->name.fullname = gns;
4705
    dpn->type = 0;
4706
4707
    return dpn;
4708
}
4709
4710
4711
/* Creates and returns new DIST_POINT structure */
4712
WOLFSSL_DIST_POINT* wolfSSL_DIST_POINT_new(void)
4713
{
4714
    WOLFSSL_DIST_POINT* dp = NULL;
4715
    WOLFSSL_DIST_POINT_NAME* dpn = NULL;
4716
4717
    WOLFSSL_ENTER("wolfSSL_DIST_POINT_new");
4718
4719
    dp = (WOLFSSL_DIST_POINT*)XMALLOC(sizeof(WOLFSSL_DIST_POINT), NULL,
4720
                                      DYNAMIC_TYPE_OPENSSL);
4721
    if (dp == NULL) {
4722
        return NULL;
4723
    }
4724
    XMEMSET(dp, 0, sizeof(WOLFSSL_DIST_POINT));
4725
4726
    dpn = wolfSSL_DIST_POINT_NAME_new();
4727
    if (dpn == NULL) {
4728
        XFREE(dp, NULL, DYNAMIC_TYPE_OPENSSL);
4729
        return NULL;
4730
    }
4731
    dp->distpoint = dpn;
4732
4733
    return dp;
4734
}
4735
4736
4737
/* Frees DIST_POINT objects.
4738
*/
4739
void wolfSSL_DIST_POINT_free(WOLFSSL_DIST_POINT* dp)
4740
{
4741
    WOLFSSL_ENTER("wolfSSL_DIST_POINT_free");
4742
    if (dp != NULL) {
4743
        wolfSSL_DIST_POINT_NAME_free(dp->distpoint);
4744
        XFREE(dp, NULL, DYNAMIC_TYPE_OPENSSL);
4745
    }
4746
}
4747
4748
void wolfSSL_DIST_POINTS_free(WOLFSSL_DIST_POINTS *dps)
4749
{
4750
    WOLFSSL_ENTER("wolfSSL_DIST_POINTS_free");
4751
4752
    if (dps == NULL) {
4753
        return;
4754
    }
4755
4756
    wolfSSL_sk_free(dps);
4757
}
4758
4759
/* return number of elements on success 0 on fail */
4760
int wolfSSL_sk_DIST_POINT_push(WOLFSSL_DIST_POINTS* sk, WOLFSSL_DIST_POINT* dp)
4761
{
4762
    WOLFSSL_ENTER("wolfSSL_sk_DIST_POINT_push");
4763
4764
    if (sk == NULL || dp == NULL) {
4765
        return WOLFSSL_FAILURE;
4766
    }
4767
4768
    return wolfSSL_sk_push(sk, dp);
4769
}
4770
4771
/* Returns the CRL dist point at index i from the stack
4772
 *
4773
 * sk  stack to get general name from
4774
 * idx index to get
4775
 *
4776
 * return a pointer to the internal node of the stack
4777
 */
4778
WOLFSSL_DIST_POINT* wolfSSL_sk_DIST_POINT_value(WOLFSSL_STACK* sk, int idx)
4779
{
4780
    if (sk == NULL) {
4781
        return NULL;
4782
    }
4783
4784
    return (WOLFSSL_DIST_POINT*)wolfSSL_sk_value(sk, idx);
4785
}
4786
4787
/* Gets the number of nodes in the stack
4788
 *
4789
 * sk  stack to get the number of nodes from
4790
 *
4791
 * returns the number of nodes, -1 if no nodes
4792
 */
4793
int wolfSSL_sk_DIST_POINT_num(WOLFSSL_STACK* sk)
4794
{
4795
    WOLFSSL_ENTER("wolfSSL_sk_DIST_POINT_num");
4796
4797
    if (sk == NULL) {
4798
        return WOLFSSL_FATAL_ERROR;
4799
    }
4800
4801
    return wolfSSL_sk_num(sk);
4802
}
4803
4804
/* Frees all nodes in a DIST_POINT stack
4805
 *
4806
 * sk stack of nodes to free
4807
 * f  free function to use
4808
 */
4809
void wolfSSL_sk_DIST_POINT_pop_free(WOLFSSL_STACK* sk,
4810
        void (*f) (WOLFSSL_DIST_POINT*))
4811
{
4812
    WOLFSSL_ENTER("wolfSSL_sk_DIST_POINT_pop_free");
4813
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
4814
}
4815
4816
void wolfSSL_sk_DIST_POINT_free(WOLFSSL_STACK* sk)
4817
{
4818
    WOLFSSL_ENTER("wolfSSL_sk_DIST_POINT_free");
4819
    wolfSSL_sk_free(sk);
4820
}
4821
4822
/* returns the number of nodes in stack on success and WOLFSSL_FATAL_ERROR
4823
 * on fail */
4824
int wolfSSL_sk_ACCESS_DESCRIPTION_num(WOLFSSL_STACK* sk)
4825
{
4826
    if (sk == NULL) {
4827
        return WOLFSSL_FATAL_ERROR;
4828
    }
4829
4830
    return (int)sk->num;
4831
}
4832
4833
/* returns NULL on fail and pointer to internal data on success */
4834
WOLFSSL_ACCESS_DESCRIPTION* wolfSSL_sk_ACCESS_DESCRIPTION_value(
4835
        WOLFSSL_STACK* sk, int idx)
4836
{
4837
    WOLFSSL_STACK* ret;
4838
4839
    if (sk == NULL) {
4840
        return NULL;
4841
    }
4842
4843
    ret = wolfSSL_sk_get_node(sk, idx);
4844
    if (ret != NULL) {
4845
        return ret->data.access;
4846
    }
4847
    return NULL;
4848
}
4849
#endif /* OPENSSL_EXTRA */
4850
4851
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
4852
/* free's the internal type for the general name */
4853
static void wolfSSL_GENERAL_NAME_type_free(WOLFSSL_GENERAL_NAME* name)
4854
{
4855
    if (name != NULL) {
4856
        switch (name->type) {
4857
        case WOLFSSL_GEN_IA5:
4858
            wolfSSL_ASN1_STRING_free(name->d.ia5);
4859
            name->d.ia5 = NULL;
4860
            break;
4861
        case WOLFSSL_GEN_EMAIL:
4862
            wolfSSL_ASN1_STRING_free(name->d.rfc822Name);
4863
            name->d.rfc822Name = NULL;
4864
            break;
4865
        case WOLFSSL_GEN_DNS:
4866
            wolfSSL_ASN1_STRING_free(name->d.dNSName);
4867
            name->d.dNSName = NULL;
4868
            break;
4869
        case WOLFSSL_GEN_DIRNAME:
4870
            wolfSSL_X509_NAME_free(name->d.dirn);
4871
            name->d.dirn = NULL;
4872
            break;
4873
        case WOLFSSL_GEN_URI:
4874
            wolfSSL_ASN1_STRING_free(name->d.uniformResourceIdentifier);
4875
            name->d.uniformResourceIdentifier = NULL;
4876
            break;
4877
        case WOLFSSL_GEN_IPADD:
4878
            wolfSSL_ASN1_STRING_free(name->d.iPAddress);
4879
            name->d.iPAddress = NULL;
4880
            break;
4881
        case WOLFSSL_GEN_RID:
4882
            wolfSSL_ASN1_OBJECT_free(name->d.registeredID);
4883
            name->d.registeredID = NULL;
4884
            break;
4885
        case WOLFSSL_GEN_OTHERNAME:
4886
            if (name->d.otherName != NULL) {
4887
                wolfSSL_ASN1_OBJECT_free(name->d.otherName->type_id);
4888
                wolfSSL_ASN1_TYPE_free(name->d.otherName->value);
4889
                XFREE(name->d.otherName, NULL, DYNAMIC_TYPE_ASN1);
4890
                name->d.otherName = NULL;
4891
            }
4892
            break;
4893
        case WOLFSSL_GEN_X400:
4894
            /* Unsupported: fall through */
4895
        case WOLFSSL_GEN_EDIPARTY:
4896
            /* Unsupported: fall through */
4897
        default:
4898
            WOLFSSL_MSG("wolfSSL_GENERAL_NAME_type_free: possible leak");
4899
            break;
4900
        }
4901
    }
4902
}
4903
4904
/* sets the general name type and free's the existing one
4905
 * can fail with a memory error if malloc fails or bad arg error
4906
 * otherwise return WOLFSSL_SUCCESS */
4907
int wolfSSL_GENERAL_NAME_set_type(WOLFSSL_GENERAL_NAME* name, int typ)
4908
{
4909
    int ret = WOLFSSL_SUCCESS;
4910
4911
    if (name != NULL) {
4912
        wolfSSL_GENERAL_NAME_type_free(name);
4913
        name->type = typ;
4914
4915
        switch (typ) {
4916
            case WOLFSSL_GEN_URI:
4917
                name->d.uniformResourceIdentifier = wolfSSL_ASN1_STRING_new();
4918
                if (name->d.uniformResourceIdentifier == NULL)
4919
                    ret = MEMORY_E;
4920
                break;
4921
            default:
4922
                name->type = WOLFSSL_GEN_IA5;
4923
                name->d.ia5 = wolfSSL_ASN1_STRING_new();
4924
                if (name->d.ia5 == NULL)
4925
                    ret = MEMORY_E;
4926
        }
4927
    }
4928
    else {
4929
        ret = BAD_FUNC_ARG;
4930
    }
4931
4932
    return ret;
4933
}
4934
4935
/* Set the value in a general name. This is a compat layer API.
4936
 *
4937
 * @param [out] a       Pointer to the GENERAL_NAME where the othername is set.
4938
 * @param [in]  type    The type of this general name.
4939
 * @param [in]  value   The ASN.1 string that is the value.
4940
 * @return none
4941
 * @note the set0 indicates we take ownership so the user does NOT free value.
4942
 */
4943
void wolfSSL_GENERAL_NAME_set0_value(WOLFSSL_GENERAL_NAME *a, int type,
4944
                                     void *value)
4945
{
4946
    WOLFSSL_ASN1_STRING *val = (WOLFSSL_ASN1_STRING *)value;
4947
    if (a == NULL) {
4948
        WOLFSSL_MSG("a is NULL");
4949
        return;
4950
    }
4951
4952
    if (val == NULL) {
4953
        WOLFSSL_MSG("value is NULL");
4954
        return;
4955
    }
4956
4957
    if (type != WOLFSSL_GEN_DNS) {
4958
        WOLFSSL_MSG("Only WOLFSSL_GEN_DNS is supported");
4959
        return;
4960
    }
4961
4962
    wolfSSL_GENERAL_NAME_type_free(a);
4963
    a->type = type;
4964
    /* Only when WOLFSSL_GEN_DNS. */
4965
    a->d.dNSName = val;
4966
}
4967
4968
/* Frees GENERAL_NAME objects.
4969
*/
4970
void wolfSSL_GENERAL_NAME_free(WOLFSSL_GENERAL_NAME* name)
4971
{
4972
    WOLFSSL_ENTER("wolfSSL_GENERAL_NAME_Free");
4973
    if (name != NULL) {
4974
        wolfSSL_GENERAL_NAME_type_free(name);
4975
        XFREE(name, NULL, DYNAMIC_TYPE_OPENSSL);
4976
    }
4977
}
4978
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL*/
4979
4980
#ifdef OPENSSL_EXTRA
4981
void wolfSSL_GENERAL_NAMES_free(WOLFSSL_GENERAL_NAMES *gens)
4982
{
4983
    WOLFSSL_ENTER("wolfSSL_GENERAL_NAMES_free");
4984
4985
    if (gens == NULL) {
4986
        return;
4987
    }
4988
4989
    wolfSSL_sk_GENERAL_NAME_free(gens);
4990
}
4991
4992
void wolfSSL_EXTENDED_KEY_USAGE_free(WOLFSSL_STACK * sk)
4993
{
4994
    WOLFSSL_ENTER("wolfSSL_EXTENDED_KEY_USAGE_free");
4995
4996
    if (sk == NULL) {
4997
        return;
4998
    }
4999
5000
    wolfSSL_sk_X509_pop_free(sk, NULL);
5001
}
5002
5003
#if defined(OPENSSL_ALL) && !defined(NO_BIO)
5004
/* Outputs name string of the given WOLFSSL_GENERAL_NAME_OBJECT to WOLFSSL_BIO.
5005
 * Can handle following GENERAL_NAME_OBJECT types:
5006
 *  - GEN_OTHERNAME #
5007
 *  - GEN_EMAIL
5008
 *  - GEN_DNS
5009
 *  - GEN_X400  #
5010
 *  - GEN_DIRNAME
5011
 *  - GEN_EDIPARTY #
5012
 *  - GEN_URI
5013
 *  - GEN_RID
5014
 * The each name string to be output has "typename:namestring" format.
5015
 * For instance, email name string will be output as "email:info@wolfssl.com".
5016
 * However,some types above marked with "#" will be output with
5017
 * "typename:<unsupported>".
5018
 *
5019
 * Parameters:
5020
 *  - out: WOLFSSL_BIO object which is the output destination
5021
 *  - gen: WOLFSSL_GENERAL_NAME object to be output its name
5022
 *
5023
 * Returns WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure.
5024
 */
5025
int wolfSSL_GENERAL_NAME_print(WOLFSSL_BIO* out, WOLFSSL_GENERAL_NAME* gen)
5026
{
5027
    int ret, i;
5028
    unsigned int wd;
5029
    unsigned char* p;
5030
    (void)wd;
5031
    (void)p;
5032
    (void)i;
5033
    WOLFSSL_ENTER("wolfSSL_GENERAL_NAME_print");
5034
5035
    if (out == NULL || gen == NULL)
5036
        return WOLFSSL_FAILURE;
5037
5038
    ret = WOLFSSL_FAILURE;
5039
    switch (gen->type)
5040
    {
5041
    case GEN_OTHERNAME:
5042
        ret = wolfSSL_BIO_printf(out, "othername:<unsupported>");
5043
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
5044
        break;
5045
5046
    case GEN_EMAIL:
5047
        ret = wolfSSL_BIO_printf(out, "email:");
5048
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
5049
        if (ret == WOLFSSL_SUCCESS)
5050
        {
5051
            ret = wolfSSL_ASN1_STRING_print(out, gen->d.rfc822Name);
5052
        }
5053
        break;
5054
5055
    case GEN_DNS:
5056
        ret = wolfSSL_BIO_printf(out, "DNS:");
5057
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
5058
        if (ret == WOLFSSL_SUCCESS) {
5059
            ret = wolfSSL_BIO_printf(out, "%s", gen->d.dNSName->strData);
5060
            ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
5061
        }
5062
        break;
5063
5064
    case GEN_X400:
5065
        ret = wolfSSL_BIO_printf(out, "X400Name:<unsupported>");
5066
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
5067
        break;
5068
5069
    case GEN_DIRNAME:
5070
        ret = wolfSSL_BIO_printf(out, "DirName:");
5071
        if (ret == WOLFSSL_SUCCESS) {
5072
            ret = wolfSSL_X509_NAME_print_ex(out, gen->d.directoryName, 0,
5073
                                                         XN_FLAG_ONELINE);
5074
        }
5075
        break;
5076
5077
    case GEN_EDIPARTY:
5078
        ret = wolfSSL_BIO_printf(out, "EdiPartyName:<unsupported>");
5079
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
5080
        break;
5081
5082
    case GEN_URI:
5083
        ret = wolfSSL_BIO_printf(out, "URI:");
5084
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
5085
        if (ret == WOLFSSL_SUCCESS) {
5086
            ret = wolfSSL_ASN1_STRING_print(out,
5087
                                    gen->d.uniformResourceIdentifier);
5088
        }
5089
        break;
5090
5091
    case GEN_IPADD:
5092
        ret = wolfSSL_BIO_printf(out, "IP Address");
5093
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
5094
        if (ret == WOLFSSL_SUCCESS) {
5095
5096
            if (!gen->d.iPAddress->length) {
5097
                ret = WOLFSSL_FAILURE;
5098
                break;
5099
            }
5100
            p = (unsigned char*)gen->d.iPAddress->strData;
5101
5102
            if (gen->d.iPAddress->length == 4) {
5103
                ret = wolfSSL_BIO_printf(out, ":%d.%d.%d.%d",
5104
                                  p[0],p[1],p[2],p[3]);
5105
            }
5106
            else if (gen->d.iPAddress->length == 16) {
5107
5108
                for (i = 0; i < 16 && ret == WOLFSSL_SUCCESS;) {
5109
                    wd = p[i] << 8 | p[i+1];
5110
5111
                    i += 2;
5112
                    ret = wolfSSL_BIO_printf(out, ":%X", wd);
5113
                    ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
5114
                }
5115
            }
5116
            else {
5117
                ret = wolfSSL_BIO_printf(out, "<unsupported>");
5118
            }
5119
            ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
5120
        }
5121
        break;
5122
5123
    case GEN_RID:
5124
        ret = wolfSSL_BIO_printf(out, "Registered ID:");
5125
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
5126
        if (ret == WOLFSSL_SUCCESS) {
5127
            ret = wolfSSL_i2a_ASN1_OBJECT(out, gen->d.registeredID);
5128
        }
5129
        break;
5130
5131
    default:
5132
        /* unsupported type */
5133
        break;
5134
    }
5135
5136
    if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
5137
        return WOLFSSL_FAILURE;
5138
    else
5139
        return WOLFSSL_SUCCESS;
5140
}
5141
#endif /* OPENSSL_ALL */
5142
5143
WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* wolfSSL_sk_X509_EXTENSION_new_null(void)
5144
{
5145
    WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL);
5146
    if (sk) {
5147
        sk->type = STACK_TYPE_X509_EXT;
5148
    }
5149
5150
    return (WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)*)sk;;
5151
}
5152
5153
/* returns the number of nodes on the stack */
5154
int wolfSSL_sk_X509_EXTENSION_num(WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk)
5155
{
5156
    if (sk != NULL) {
5157
        return (int)sk->num;
5158
    }
5159
    return WOLFSSL_FATAL_ERROR;
5160
}
5161
5162
5163
/* returns null on failure and pointer to internal value on success */
5164
WOLFSSL_X509_EXTENSION* wolfSSL_sk_X509_EXTENSION_value(
5165
        const WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk, int idx)
5166
{
5167
    return (WOLFSSL_X509_EXTENSION*)wolfSSL_sk_value(sk, idx);
5168
}
5169
5170
/* frees all of the nodes and the values in stack */
5171
void wolfSSL_sk_X509_EXTENSION_pop_free(
5172
        WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk,
5173
        void (*f) (WOLFSSL_X509_EXTENSION*))
5174
{
5175
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
5176
}
5177
5178
void wolfSSL_sk_X509_EXTENSION_free(WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk)
5179
{
5180
    wolfSSL_sk_pop_free(sk, NULL);
5181
}
5182
5183
#endif /* OPENSSL_EXTRA */
5184
5185
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && \
5186
    !defined(NO_STDIO_FILESYSTEM)
5187
5188
WOLFSSL_X509* wolfSSL_X509_d2i_fp(WOLFSSL_X509** x509, XFILE file)
5189
{
5190
    WOLFSSL_X509* newX509 = NULL;
5191
5192
    WOLFSSL_ENTER("wolfSSL_X509_d2i_fp");
5193
5194
    if (file != XBADFILE) {
5195
        byte* fileBuffer = NULL;
5196
        long sz = 0;
5197
5198
        if (XFSEEK(file, 0, XSEEK_END) != 0)
5199
            return NULL;
5200
        sz = XFTELL(file);
5201
        if (XFSEEK(file, 0, XSEEK_SET) != 0)
5202
            return NULL;
5203
5204
        if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
5205
            WOLFSSL_MSG("X509_d2i file size error");
5206
            return NULL;
5207
        }
5208
5209
        fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
5210
        if (fileBuffer != NULL) {
5211
            int ret = (int)XFREAD(fileBuffer, 1, (size_t)sz, file);
5212
            if (ret == sz) {
5213
                newX509 = wolfSSL_X509_d2i(NULL, fileBuffer, (int)sz);
5214
            }
5215
            XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
5216
        }
5217
    }
5218
5219
    if (x509 != NULL)
5220
        *x509 = newX509;
5221
5222
    return newX509;
5223
}
5224
5225
#endif /* OPENSSL_EXTRA && !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM */
5226
5227
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
5228
    defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
5229
5230
#ifndef NO_FILESYSTEM
5231
WOLFSSL_ABI
5232
WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format)
5233
{
5234
#ifdef WOLFSSL_SMALL_STACK
5235
    byte  staticBuffer[1]; /* force heap usage */
5236
#else
5237
    byte  staticBuffer[FILE_BUFFER_SIZE];
5238
#endif
5239
    byte* fileBuffer = staticBuffer;
5240
    int   dynamic = 0;
5241
    int   ret;
5242
    long  sz = 0;
5243
    XFILE file;
5244
5245
    WOLFSSL_X509* x509 = NULL;
5246
5247
    /* Check the inputs */
5248
    if ((fname == NULL) ||
5249
        (format != WOLFSSL_FILETYPE_ASN1 && format != WOLFSSL_FILETYPE_PEM))
5250
        return NULL;
5251
5252
    file = XFOPEN(fname, "rb");
5253
    if (file == XBADFILE)
5254
        return NULL;
5255
5256
    if (XFSEEK(file, 0, XSEEK_END) != 0) {
5257
        XFCLOSE(file);
5258
        return NULL;
5259
    }
5260
    sz = XFTELL(file);
5261
    if (XFSEEK(file, 0, XSEEK_SET) != 0) {
5262
        XFCLOSE(file);
5263
        return NULL;
5264
    }
5265
5266
    if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
5267
        WOLFSSL_MSG("X509_load_certificate_file size error");
5268
        XFCLOSE(file);
5269
        return NULL;
5270
    }
5271
5272
    if (sz > (long)sizeof(staticBuffer)) {
5273
        fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
5274
        if (fileBuffer == NULL) {
5275
            XFCLOSE(file);
5276
            return NULL;
5277
        }
5278
        dynamic = 1;
5279
    }
5280
5281
    ret = (int)XFREAD(fileBuffer, 1, (size_t)sz, file);
5282
    if (ret != sz) {
5283
        XFCLOSE(file);
5284
        if (dynamic)
5285
            XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
5286
        return NULL;
5287
    }
5288
5289
    XFCLOSE(file);
5290
5291
    x509 = wolfSSL_X509_load_certificate_buffer(fileBuffer, (int)sz, format);
5292
5293
    if (dynamic)
5294
        XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
5295
5296
    return x509;
5297
}
5298
#endif /* !NO_FILESYSTEM */
5299
5300
static WOLFSSL_X509* loadX509orX509REQFromBuffer(
5301
    const unsigned char* buf, int sz, int format, int type,
5302
    wc_pem_password_cb *cb, void *u)
5303
{
5304
5305
    int ret = 0;
5306
    WOLFSSL_X509* x509 = NULL;
5307
    DerBuffer* der = NULL;
5308
5309
    WOLFSSL_ENTER("wolfSSL_X509_load_certificate_ex");
5310
5311
    if (format == WOLFSSL_FILETYPE_PEM) {
5312
        EncryptedInfo info;
5313
        XMEMSET(&info, 0, sizeof(EncryptedInfo));
5314
    #ifdef WOLFSSL_ENCRYPTED_KEYS
5315
        info.passwd_cb       = cb;
5316
        info.passwd_userdata = u;
5317
    #endif
5318
5319
    #ifdef WOLFSSL_PEM_TO_DER
5320
        ret = PemToDer(buf, sz, type, &der, NULL, &info, NULL);
5321
        if (ret != 0) {
5322
            FreeDer(&der);
5323
        }
5324
    #else
5325
        ret = NOT_COMPILED_IN;
5326
    #endif
5327
    }
5328
    else {
5329
        ret = AllocDer(&der, (word32)sz, type, NULL);
5330
        if (ret == 0) {
5331
            XMEMCPY(der->buffer, buf, sz);
5332
        }
5333
    }
5334
5335
    /* At this point we want `der` to have the certificate in DER format */
5336
    /* ready to be decoded. */
5337
    if (der != NULL && der->buffer != NULL) {
5338
    #ifdef WOLFSSL_SMALL_STACK
5339
        DecodedCert* cert;
5340
    #else
5341
        DecodedCert  cert[1];
5342
    #endif
5343
5344
    #ifdef WOLFSSL_SMALL_STACK
5345
        cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
5346
                                     DYNAMIC_TYPE_DCERT);
5347
        if (cert == NULL) {
5348
            ret = MEMORY_ERROR;
5349
        }
5350
        else
5351
    #endif
5352
        {
5353
            InitDecodedCert(cert, der->buffer, der->length, NULL);
5354
            ret = ParseCertRelative(cert, type, 0, NULL, NULL);
5355
            if (ret == 0) {
5356
                x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
5357
                                                             DYNAMIC_TYPE_X509);
5358
                if (x509 != NULL) {
5359
                    InitX509(x509, 1, NULL);
5360
                    ret = CopyDecodedToX509(x509, cert);
5361
                    if (ret != 0) {
5362
                        wolfSSL_X509_free(x509);
5363
                        x509 = NULL;
5364
                    }
5365
                }
5366
                else {
5367
                    ret = MEMORY_ERROR;
5368
                }
5369
            }
5370
5371
            FreeDecodedCert(cert);
5372
        #ifdef WOLFSSL_SMALL_STACK
5373
            XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
5374
        #endif
5375
        }
5376
5377
        FreeDer(&der);
5378
    }
5379
5380
    if (ret != 0) {
5381
        WOLFSSL_ERROR(ret);
5382
    }
5383
5384
    /* unused parameter when built without WOLFSSL_ENCRYPTED_KEYS */
5385
    (void)cb;
5386
    (void)u;
5387
    return x509;
5388
}
5389
5390
WOLFSSL_X509* wolfSSL_X509_load_certificate_buffer(
5391
    const unsigned char* buf, int sz, int format)
5392
{
5393
    return loadX509orX509REQFromBuffer(buf, sz,
5394
            format, CERT_TYPE, NULL, NULL);
5395
}
5396
5397
#ifdef WOLFSSL_CERT_REQ
5398
WOLFSSL_X509* wolfSSL_X509_REQ_load_certificate_buffer(
5399
    const unsigned char* buf, int sz, int format)
5400
{
5401
    return loadX509orX509REQFromBuffer(buf, sz,
5402
            format, CERTREQ_TYPE, NULL, NULL);
5403
}
5404
#endif
5405
5406
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || KEEP_PEER_CERT || \
5407
          SESSION_CERTS */
5408
5409
#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(KEEP_PEER_CERT) || \
5410
    defined(SESSION_CERTS)
5411
/* Smaller subset of X509 compatibility functions. Avoid increasing the size of
5412
 * this subset and its memory usage */
5413
5414
/* returns a pointer to a new WOLFSSL_X509 structure on success and NULL on
5415
 * fail
5416
 */
5417
WOLFSSL_X509* wolfSSL_X509_new_ex(void* heap)
5418
{
5419
    WOLFSSL_X509* x509;
5420
5421
    x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), heap,
5422
            DYNAMIC_TYPE_X509);
5423
    if (x509 != NULL) {
5424
        InitX509(x509, 1, heap);
5425
    }
5426
5427
    return x509;
5428
}
5429
5430
WOLFSSL_X509* wolfSSL_X509_new(void)
5431
{
5432
    return wolfSSL_X509_new_ex(NULL);
5433
}
5434
5435
WOLFSSL_ABI
5436
WOLFSSL_X509_NAME* wolfSSL_X509_get_subject_name(WOLFSSL_X509* cert)
5437
{
5438
    WOLFSSL_ENTER("wolfSSL_X509_get_subject_name");
5439
    if (cert)
5440
        return &cert->subject;
5441
    return NULL;
5442
}
5443
5444
WOLFSSL_ABI
5445
WOLFSSL_X509_NAME* wolfSSL_X509_get_issuer_name(WOLFSSL_X509* cert)
5446
{
5447
    WOLFSSL_ENTER("wolfSSL_X509_get_issuer_name");
5448
    if (cert)
5449
        return &cert->issuer;
5450
    return NULL;
5451
}
5452
5453
5454
int wolfSSL_X509_get_signature_type(WOLFSSL_X509* x509)
5455
{
5456
    int type = 0;
5457
5458
    WOLFSSL_ENTER("wolfSSL_X509_get_signature_type");
5459
5460
    if (x509 != NULL)
5461
        type = x509->sigOID;
5462
5463
    return type;
5464
}
5465
5466
#if defined(OPENSSL_EXTRA_X509_SMALL)
5467
5468
int wolfSSL_X509_NAME_get_sz(WOLFSSL_X509_NAME* name)
5469
{
5470
    WOLFSSL_ENTER("wolfSSL_X509_NAME_get_sz");
5471
    if (!name)
5472
        return WOLFSSL_FATAL_ERROR;
5473
    return name->sz;
5474
}
5475
5476
/* Searches for the first ENTRY of type NID
5477
 * idx is the location to start searching from, the value at when the entry was
5478
 *     found is stored into idx
5479
 * returns a pointer to the entry on success and null on fail */
5480
static WOLFSSL_X509_NAME_ENTRY* GetEntryByNID(WOLFSSL_X509_NAME* name, int nid,
5481
        int* idx)
5482
{
5483
    int i;
5484
    WOLFSSL_X509_NAME_ENTRY* ret = NULL;
5485
5486
    for (i = *idx; i < MAX_NAME_ENTRIES; i++) {
5487
        if (name->entry[i].nid == nid) {
5488
            ret = &name->entry[i];
5489
            *idx = i;
5490
            break;
5491
        }
5492
    }
5493
    return ret;
5494
}
5495
5496
5497
/* Used to get a string from the WOLFSSL_X509_NAME structure that
5498
 * corresponds with the NID value passed in. This finds the first entry with
5499
 * matching NID value, if searching for the case where there is multiple
5500
 * entries with the same NID value than other functions should be used
5501
 * (i.e. wolfSSL_X509_NAME_get_index_by_NID, wolfSSL_X509_NAME_get_entry)
5502
 *
5503
 * name structure to get string from
5504
 * nid  NID value to search for
5505
 * buf  [out] buffer to hold results. If NULL then the buffer size minus the
5506
 *      null char is returned.
5507
 * len  size of "buf" passed in
5508
 *
5509
 * returns the length of string found, not including the NULL terminator.
5510
 *         It's possible the function could return a negative value in the
5511
 *         case that len is less than or equal to 0. A negative value is
5512
 *         considered an error case.
5513
 */
5514
int wolfSSL_X509_NAME_get_text_by_NID(WOLFSSL_X509_NAME* name,
5515
                                      int nid, char* buf, int len)
5516
{
5517
    WOLFSSL_X509_NAME_ENTRY* e;
5518
    unsigned char *text = NULL;
5519
    int textSz = 0;
5520
    int idx    = 0;
5521
5522
    WOLFSSL_ENTER("wolfSSL_X509_NAME_get_text_by_NID");
5523
5524
    if (name == NULL) {
5525
        WOLFSSL_MSG("NULL argument passed in");
5526
        return WOLFSSL_FATAL_ERROR;
5527
    }
5528
5529
    e = GetEntryByNID(name, nid, &idx);
5530
    if (e == NULL) {
5531
        WOLFSSL_MSG("Entry type not found");
5532
        return WOLFSSL_FATAL_ERROR;
5533
    }
5534
    text   = wolfSSL_ASN1_STRING_data(e->value);
5535
    textSz = wolfSSL_ASN1_STRING_length(e->value);
5536
5537
    if (text == NULL) {
5538
        WOLFSSL_MSG("Unable to get entry text");
5539
        return WOLFSSL_FATAL_ERROR;
5540
    }
5541
5542
    /* if buf is NULL return size of buffer needed (minus null char) */
5543
    if (buf == NULL) {
5544
        WOLFSSL_MSG("Buffer is NULL, returning buffer size only");
5545
        return textSz;
5546
    }
5547
    if (len <= 0) {
5548
        return 0;
5549
    }
5550
5551
    /* + 1 to account for null char */
5552
    textSz = (int)min((word32)textSz + 1, (word32)len);
5553
    if (textSz > 0) {
5554
        XMEMCPY(buf, text, textSz - 1);
5555
        buf[textSz - 1] = '\0';
5556
    }
5557
5558
    WOLFSSL_LEAVE("wolfSSL_X509_NAME_get_text_by_NID", textSz);
5559
    return (textSz - 1); /* do not include null character in size */
5560
}
5561
5562
/* Creates a new WOLFSSL_EVP_PKEY structure that has the public key from x509
5563
 *
5564
 * returns a pointer to the created WOLFSSL_EVP_PKEY on success and NULL on fail
5565
 */
5566
WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
5567
{
5568
    WOLFSSL_EVP_PKEY* key = NULL;
5569
    int ret = 0;
5570
5571
    (void)ret;
5572
5573
    WOLFSSL_ENTER("wolfSSL_X509_get_pubkey");
5574
    if (x509 != NULL) {
5575
        key = wolfSSL_EVP_PKEY_new_ex(x509->heap);
5576
        if (key != NULL) {
5577
            if (x509->pubKeyOID == RSAk) {
5578
                key->type = WC_EVP_PKEY_RSA;
5579
            }
5580
            else if (x509->pubKeyOID == DSAk) {
5581
                key->type = WC_EVP_PKEY_DSA;
5582
            }
5583
            else {
5584
                key->type = WC_EVP_PKEY_EC;
5585
            }
5586
            key->save_type = 0;
5587
            key->pkey.ptr = (char*)XMALLOC(
5588
                        x509->pubKey.length, x509->heap,
5589
                                                       DYNAMIC_TYPE_PUBLIC_KEY);
5590
            if (key->pkey.ptr == NULL) {
5591
                wolfSSL_EVP_PKEY_free(key);
5592
                return NULL;
5593
            }
5594
            XMEMCPY(key->pkey.ptr, x509->pubKey.buffer, x509->pubKey.length);
5595
            key->pkey_sz = (int)x509->pubKey.length;
5596
5597
            #ifdef HAVE_ECC
5598
                key->pkey_curve = (int)x509->pkCurveOID;
5599
            #endif /* HAVE_ECC */
5600
5601
            /* decode RSA key */
5602
            #ifndef NO_RSA
5603
            if (key->type == WC_EVP_PKEY_RSA) {
5604
                key->ownRsa = 1;
5605
                key->rsa = wolfSSL_RSA_new();
5606
                if (key->rsa == NULL) {
5607
                    wolfSSL_EVP_PKEY_free(key);
5608
                    return NULL;
5609
                }
5610
5611
                if (wolfSSL_RSA_LoadDer_ex(key->rsa,
5612
                            (const unsigned char*)key->pkey.ptr, key->pkey_sz,
5613
                            WOLFSSL_RSA_LOAD_PUBLIC) != WOLFSSL_SUCCESS) {
5614
                    wolfSSL_EVP_PKEY_free(key);
5615
                    return NULL;
5616
                }
5617
            }
5618
            #endif /* NO_RSA */
5619
5620
            /* decode ECC key */
5621
            #if defined(HAVE_ECC) && defined(OPENSSL_EXTRA)
5622
            if (key->type == WC_EVP_PKEY_EC) {
5623
                word32 idx = 0;
5624
5625
                key->ownEcc = 1;
5626
                key->ecc = wolfSSL_EC_KEY_new();
5627
                if (key->ecc == NULL || key->ecc->internal == NULL) {
5628
                    wolfSSL_EVP_PKEY_free(key);
5629
                    return NULL;
5630
                }
5631
5632
                /* not using wolfSSL_EC_KEY_LoadDer because public key in x509
5633
                 * is in the format of x963 (no sequence at start of buffer) */
5634
                ret = wc_EccPublicKeyDecode((const unsigned char*)key->pkey.ptr,
5635
                                            &idx, (ecc_key*)key->ecc->internal,
5636
                                            key->pkey_sz);
5637
                if (ret < 0) {
5638
                    WOLFSSL_ERROR_VERBOSE(ret);
5639
                    WOLFSSL_MSG("wc_EccPublicKeyDecode failed");
5640
                    wolfSSL_EVP_PKEY_free(key);
5641
                    return NULL;
5642
                }
5643
5644
                if (SetECKeyExternal(key->ecc) != WOLFSSL_SUCCESS) {
5645
                    WOLFSSL_MSG("SetECKeyExternal failed");
5646
                    wolfSSL_EVP_PKEY_free(key);
5647
                    return NULL;
5648
                }
5649
5650
                key->ecc->inSet = 1;
5651
            }
5652
            #endif /* HAVE_ECC && OPENSSL_EXTRA */
5653
5654
            #ifndef NO_DSA
5655
            if (key->type == WC_EVP_PKEY_DSA) {
5656
                key->ownDsa = 1;
5657
                key->dsa = wolfSSL_DSA_new();
5658
                if (key->dsa == NULL) {
5659
                    wolfSSL_EVP_PKEY_free(key);
5660
                    return NULL;
5661
                }
5662
5663
                if (wolfSSL_DSA_LoadDer_ex(key->dsa,
5664
                            (const unsigned char*)key->pkey.ptr, key->pkey_sz, \
5665
                            WOLFSSL_DSA_LOAD_PUBLIC) != WOLFSSL_SUCCESS) {
5666
                    wolfSSL_DSA_free(key->dsa);
5667
                    key->dsa = NULL;
5668
                    wolfSSL_EVP_PKEY_free(key);
5669
                    return NULL;
5670
                }
5671
            }
5672
            #endif /* NO_DSA */
5673
        }
5674
    }
5675
    return key;
5676
}
5677
#endif /* OPENSSL_EXTRA_X509_SMALL */
5678
5679
/* End of smaller subset of X509 compatibility functions. Avoid increasing the
5680
 * size of this subset and its memory usage */
5681
#endif /* OPENSSL_EXTRA_X509_SMALL || KEEP_PEER_CERT || SESSION_CERTS */
5682
5683
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
5684
/*
5685
 * Converts a and b to DER and then does an XMEMCMP to check if they match.
5686
 * Returns 0 when certificates match and WOLFSSL_FATAL_ERROR when they don't.
5687
 */
5688
int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b)
5689
{
5690
        const byte* derA;
5691
        const byte* derB;
5692
        int outSzA = 0;
5693
        int outSzB = 0;
5694
5695
        if (a == NULL || b == NULL) {
5696
            return BAD_FUNC_ARG;
5697
        }
5698
5699
        derA = wolfSSL_X509_get_der((WOLFSSL_X509*)a, &outSzA);
5700
        if (derA == NULL) {
5701
            WOLFSSL_MSG("wolfSSL_X509_get_der - certificate A has failed");
5702
            return WOLFSSL_FATAL_ERROR;
5703
        }
5704
        derB = wolfSSL_X509_get_der((WOLFSSL_X509*)b, &outSzB);
5705
        if (derB == NULL) {
5706
            WOLFSSL_MSG("wolfSSL_X509_get_der - certificate B has failed");
5707
            return WOLFSSL_FATAL_ERROR;
5708
        }
5709
5710
        if (outSzA != outSzB || XMEMCMP(derA, derB, outSzA) != 0) {
5711
            WOLFSSL_LEAVE("wolfSSL_X509_cmp", WOLFSSL_FATAL_ERROR);
5712
            return WOLFSSL_FATAL_ERROR;
5713
        }
5714
5715
        WOLFSSL_LEAVE("wolfSSL_X509_cmp", 0);
5716
5717
        return 0;
5718
    }
5719
#endif /* OPENSSL_ALL */
5720
5721
#if defined(OPENSSL_EXTRA)
5722
    int wolfSSL_X509_ext_isSet_by_NID(WOLFSSL_X509* x509, int nid)
5723
    {
5724
        int isSet = 0;
5725
5726
        WOLFSSL_ENTER("wolfSSL_X509_ext_isSet_by_NID");
5727
5728
        if (x509 != NULL) {
5729
            switch (nid) {
5730
                case WC_NID_basic_constraints:
5731
                    isSet = x509->basicConstSet; break;
5732
                case WC_NID_subject_alt_name:
5733
                    isSet = x509->subjAltNameSet; break;
5734
                case WC_NID_authority_key_identifier:
5735
                    isSet = x509->authKeyIdSet; break;
5736
                case WC_NID_subject_key_identifier:
5737
                    isSet = x509->subjKeyIdSet; break;
5738
                case WC_NID_key_usage:
5739
                    isSet = x509->keyUsageSet; break;
5740
                case WC_NID_crl_distribution_points:
5741
                    isSet = x509->CRLdistSet; break;
5742
                case WC_NID_ext_key_usage:
5743
                    isSet = ((x509->extKeyUsageSrc) ? 1 : 0); break;
5744
                case WC_NID_info_access:
5745
                    isSet = x509->authInfoSet; break;
5746
            #if defined(WOLFSSL_SEP) || defined(WOLFSSL_QT)
5747
                case WC_NID_certificate_policies:
5748
                    isSet = x509->certPolicySet; break;
5749
            #endif /* WOLFSSL_SEP || WOLFSSL_QT */
5750
                default:
5751
                    WOLFSSL_MSG("NID not in table");
5752
            }
5753
        }
5754
5755
        WOLFSSL_LEAVE("wolfSSL_X509_ext_isSet_by_NID", isSet);
5756
5757
        return isSet;
5758
    }
5759
5760
5761
    int wolfSSL_X509_ext_get_critical_by_NID(WOLFSSL_X509* x509, int nid)
5762
    {
5763
        int crit = 0;
5764
5765
        WOLFSSL_ENTER("wolfSSL_X509_ext_get_critical_by_NID");
5766
5767
        if (x509 != NULL) {
5768
            switch (nid) {
5769
                case WC_NID_basic_constraints:
5770
                    crit = x509->basicConstCrit; break;
5771
                case WC_NID_subject_alt_name:
5772
                    crit = x509->subjAltNameCrit; break;
5773
                case WC_NID_authority_key_identifier:
5774
                    crit = x509->authKeyIdCrit; break;
5775
                case WC_NID_subject_key_identifier:
5776
                    crit = x509->subjKeyIdCrit; break;
5777
                case WC_NID_key_usage:
5778
                    crit = x509->keyUsageCrit; break;
5779
                case WC_NID_crl_distribution_points:
5780
                    crit= x509->CRLdistCrit; break;
5781
                case WC_NID_ext_key_usage:
5782
                    crit= x509->extKeyUsageCrit; break;
5783
            #ifdef WOLFSSL_SEP
5784
                case WC_NID_certificate_policies:
5785
                    crit = x509->certPolicyCrit; break;
5786
            #endif /* WOLFSSL_SEP */
5787
            }
5788
        }
5789
5790
        WOLFSSL_LEAVE("wolfSSL_X509_ext_get_critical_by_NID", crit);
5791
5792
        return crit;
5793
    }
5794
5795
5796
    int wolfSSL_X509_get_isSet_pathLength(WOLFSSL_X509* x509)
5797
    {
5798
        int isSet = 0;
5799
5800
        WOLFSSL_ENTER("wolfSSL_X509_get_isSet_pathLength");
5801
5802
        if (x509 != NULL)
5803
            isSet = x509->basicConstPlSet;
5804
5805
        WOLFSSL_LEAVE("wolfSSL_X509_get_isSet_pathLength", isSet);
5806
5807
        return isSet;
5808
    }
5809
5810
5811
    word32 wolfSSL_X509_get_pathLength(WOLFSSL_X509* x509)
5812
    {
5813
        word32 pathLength = 0;
5814
5815
        WOLFSSL_ENTER("wolfSSL_X509_get_pathLength");
5816
5817
        if (x509 != NULL)
5818
            pathLength = x509->pathLength;
5819
5820
        WOLFSSL_LEAVE("wolfSSL_X509_get_pathLength", pathLength);
5821
5822
        return pathLength;
5823
    }
5824
5825
5826
    unsigned int wolfSSL_X509_get_keyUsage(WOLFSSL_X509* x509)
5827
    {
5828
        word16 usage = 0;
5829
5830
        WOLFSSL_ENTER("wolfSSL_X509_get_keyUsage");
5831
5832
        if (x509 != NULL)
5833
            usage = x509->keyUsage;
5834
5835
        WOLFSSL_LEAVE("wolfSSL_X509_get_keyUsage", usage);
5836
5837
        return usage;
5838
    }
5839
5840
5841
    byte* wolfSSL_X509_get_authorityKeyID(WOLFSSL_X509* x509,
5842
                                          byte* dst, int* dstLen)
5843
    {
5844
        byte *id = NULL;
5845
        int copySz = 0;
5846
5847
        WOLFSSL_ENTER("wolfSSL_X509_get_authorityKeyID");
5848
5849
        if (x509 != NULL) {
5850
            if (x509->authKeyIdSet) {
5851
                copySz = (int)min(dstLen != NULL ? (word32)*dstLen : 0,
5852
                                  x509->authKeyIdSz);
5853
                id = x509->authKeyId;
5854
            }
5855
5856
            if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
5857
                XMEMCPY(dst, id, copySz);
5858
                id = dst;
5859
                *dstLen = copySz;
5860
            }
5861
        }
5862
5863
        WOLFSSL_LEAVE("wolfSSL_X509_get_authorityKeyID", copySz);
5864
5865
        return id;
5866
    }
5867
5868
    byte* wolfSSL_X509_get_subjectKeyID(WOLFSSL_X509* x509,
5869
                                        byte* dst, int* dstLen)
5870
    {
5871
        byte *id = NULL;
5872
        int copySz = 0;
5873
5874
        WOLFSSL_ENTER("wolfSSL_X509_get_subjectKeyID");
5875
5876
        if (x509 != NULL) {
5877
            if (x509->subjKeyIdSet) {
5878
                copySz = (int)min(dstLen != NULL ? (word32) *dstLen : 0,
5879
                                  x509->subjKeyIdSz);
5880
                id = x509->subjKeyId;
5881
            }
5882
5883
            if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
5884
                XMEMCPY(dst, id, copySz);
5885
                id = dst;
5886
                *dstLen = copySz;
5887
            }
5888
        }
5889
5890
        WOLFSSL_LEAVE("wolfSSL_X509_get_subjectKeyID", copySz);
5891
5892
        return id;
5893
    }
5894
5895
    const WOLFSSL_ASN1_STRING *wolfSSL_X509_get0_subject_key_id(
5896
            WOLFSSL_X509 *x509)
5897
    {
5898
        WOLFSSL_ASN1_STRING* ret = NULL;
5899
5900
        WOLFSSL_ENTER("wolfSSL_X509_get0_subject_key_id");
5901
5902
        if (x509 != NULL && x509->subjKeyIdSet) {
5903
            if (x509->subjKeyIdStr == NULL) {
5904
                x509->subjKeyIdStr = wolfSSL_ASN1_STRING_new();
5905
                if (x509->subjKeyIdStr != NULL) {
5906
                    if (wolfSSL_ASN1_STRING_set(x509->subjKeyIdStr,
5907
                            x509->subjKeyId, x509->subjKeyIdSz) == 1) {
5908
                    }
5909
                    else {
5910
                        wolfSSL_ASN1_STRING_free(x509->subjKeyIdStr);
5911
                        x509->subjKeyIdStr = NULL;
5912
                    }
5913
                }
5914
            }
5915
            ret = x509->subjKeyIdStr;
5916
        }
5917
5918
        WOLFSSL_LEAVE("wolfSSL_X509_get0_subject_key_id", ret != NULL);
5919
5920
        return ret;
5921
    }
5922
#endif /* OPENSSL_EXTRA */
5923
5924
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
5925
    defined(OPENSSL_EXTRA_X509_SMALL)
5926
5927
    /* Looks up the index of the first entry encountered with matching NID
5928
     * The search starts from index 'pos'
5929
     * returns a negative value on failure and positive index value on success*/
5930
    int wolfSSL_X509_NAME_get_index_by_NID(WOLFSSL_X509_NAME* name,
5931
                                          int nid, int pos)
5932
    {
5933
        int value = nid, i;
5934
5935
        WOLFSSL_ENTER("wolfSSL_X509_NAME_get_index_by_NID");
5936
5937
        if (name == NULL) {
5938
            return BAD_FUNC_ARG;
5939
        }
5940
5941
        i = pos + 1; /* start search after index passed in */
5942
        if (i < 0) {
5943
            i = 0;
5944
        }
5945
5946
        for (;i < name->entrySz && i < MAX_NAME_ENTRIES; i++) {
5947
            if (name->entry[i].nid == value) {
5948
                return i;
5949
            }
5950
        }
5951
        return WOLFSSL_FATAL_ERROR;
5952
    }
5953
5954
5955
    WOLFSSL_ASN1_STRING*  wolfSSL_X509_NAME_ENTRY_get_data(
5956
                                                    WOLFSSL_X509_NAME_ENTRY* in)
5957
    {
5958
        WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_get_data");
5959
        if (in == NULL)
5960
            return NULL;
5961
5962
        return in->value;
5963
    }
5964
5965
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
5966
5967
#ifdef OPENSSL_EXTRA
5968
#ifndef NO_BIO
5969
5970
#ifndef MAX_WIDTH
5971
    #define MAX_WIDTH 80
5972
#endif
5973
5974
#if defined(WOLFSSL_ACERT)
5975
#define ACERT_NUM_DIR_TAGS 4
5976
5977
/* Convenience struct and function for printing the Holder sub fields
5978
 * of an X509 Attribute struct. */
5979
struct acert_dir_print_t {
5980
    const char * pfx;
5981
    const byte   tag[3];
5982
};
5983
5984
static struct acert_dir_print_t acert_dir_print[ACERT_NUM_DIR_TAGS] =
5985
{
5986
    { "C=", {0x55, 0x04, ASN_COUNTRY_NAME} },
5987
    { "O=", {0x55, 0x04, ASN_ORG_NAME} },
5988
    { "OU=", {0x55, 0x04, ASN_ORGUNIT_NAME} },
5989
    { "CN=", {0x55, 0x04, ASN_COMMON_NAME} },
5990
};
5991
5992
/* Print an entry of ASN_DIR_TYPE into dst of length max_len.
5993
 *
5994
 * Returns total_len of str on success.
5995
 * Returns < 0 on failure.
5996
 * */
5997
static int X509PrintDirType(char * dst, int max_len, const DNS_entry * entry)
5998
{
5999
    word32       k = 0;
6000
    word32       i = 0;
6001
    const char * src = entry->name;
6002
    word32       src_len = (word32)XSTRLEN(src);
6003
    int          total_len = 0;
6004
    int          bytes_left = max_len;
6005
    int          fld_len = 0;
6006
    int          match_found = 0;
6007
6008
    XMEMSET(dst, 0, max_len);
6009
6010
    /* loop over printable DIR tags. */
6011
    for (k = 0; k < ACERT_NUM_DIR_TAGS; ++k) {
6012
        const char * pfx = acert_dir_print[k].pfx;
6013
        const byte * tag = acert_dir_print[k].tag;
6014
        byte         asn_tag;
6015
6016
        /* walk through entry looking for matches. */
6017
        for (i = 0; i < src_len - 5; ++i) {
6018
            if (XMEMCMP(tag, &src[i], 3) == 0) {
6019
                if (bytes_left < 5) {
6020
                    /* Not enough space left for name oid + tag + len. */
6021
                    break;
6022
                }
6023
6024
                if (match_found) {
6025
                    /* append a {',', ' '} before doing anything else. */
6026
                    *dst++ = ',';
6027
                    *dst++ = ' ';
6028
                    total_len += 2;
6029
                    bytes_left -= 2;
6030
                }
6031
6032
                i += 3;
6033
6034
                /* Get the ASN Tag. */
6035
                if (GetASNTag((const byte *)src, &i, &asn_tag, src_len) < 0) {
6036
                    WOLFSSL_MSG("error: GetASNTag failed");
6037
                    break;
6038
                }
6039
6040
                /* Check it is printable. */
6041
                if ((asn_tag != ASN_PRINTABLE_STRING) &&
6042
                    (asn_tag != ASN_IA5_STRING) &&
6043
                    (asn_tag != ASN_UTF8STRING)) {
6044
                    /* Don't know what this is but we can't print it. */
6045
                    WOLFSSL_MSG("error: asn tag not printable string");
6046
                    break;
6047
                }
6048
6049
                /* Now get the length of the printable string. */
6050
                if (GetLength((const byte *)src, &i, &fld_len, src_len) < 0) {
6051
                    break;
6052
                }
6053
6054
                /* Make sure we have space to fit it. */
6055
                if ((int) XSTRLEN(pfx) > bytes_left) {
6056
                    /* Not enough space left. */
6057
                    break;
6058
                }
6059
6060
                /* Copy it in, decrement available space. */
6061
                XSTRNCPY(dst, pfx, bytes_left);
6062
                dst += XSTRLEN(pfx);
6063
                total_len += (int)XSTRLEN(pfx);
6064
                bytes_left -= (int)XSTRLEN(pfx);
6065
6066
                if (fld_len > bytes_left) {
6067
                    /* Not enough space left. */
6068
                    break;
6069
                }
6070
6071
                XMEMCPY(dst, &src[i], fld_len);
6072
                i += fld_len;
6073
                dst += fld_len;
6074
                total_len += fld_len;
6075
                bytes_left -= fld_len;
6076
6077
                match_found = 1;
6078
            }
6079
        }
6080
    }
6081
6082
    return total_len;
6083
}
6084
6085
static int X509_ACERT_print_name_entry(WOLFSSL_BIO* bio,
6086
                                       const DNS_entry* entry, int indent)
6087
{
6088
    int  ret = WOLFSSL_SUCCESS;
6089
    int  nameCount = 0;
6090
    char scratch[MAX_WIDTH];
6091
    int  len;
6092
6093
    if (bio == NULL || entry == NULL) {
6094
        return WOLFSSL_FAILURE;
6095
    }
6096
6097
    len = XSNPRINTF(scratch, MAX_WIDTH, "%*s", indent, "");
6098
    if (len >= MAX_WIDTH) {
6099
        return WOLFSSL_FAILURE;
6100
    }
6101
6102
    if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) {
6103
        return WOLFSSL_FAILURE;
6104
    }
6105
6106
    while (entry != NULL) {
6107
        ++nameCount;
6108
        if (nameCount > 1) {
6109
            if (wolfSSL_BIO_write(bio, ", ", 2) <= 0) {
6110
                ret = WOLFSSL_FAILURE;
6111
                break;
6112
            }
6113
        }
6114
6115
        if (entry->type == ASN_DNS_TYPE) {
6116
            len = XSNPRINTF(scratch, MAX_WIDTH, "DNS:%s", entry->name);
6117
            if (len >= MAX_WIDTH) {
6118
                ret = WOLFSSL_FAILURE;
6119
                break;
6120
            }
6121
        }
6122
    #if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
6123
        else if (entry->type == ASN_IP_TYPE) {
6124
            len = XSNPRINTF(scratch, MAX_WIDTH, "IP Address:%s",
6125
                    entry->ipString);
6126
            if (len >= MAX_WIDTH) {
6127
                ret = WOLFSSL_FAILURE;
6128
                break;
6129
            }
6130
        }
6131
    #endif /* OPENSSL_ALL || WOLFSSL_IP_ALT_NAME */
6132
        else if (entry->type == ASN_RFC822_TYPE) {
6133
            len = XSNPRINTF(scratch, MAX_WIDTH, "email:%s",
6134
                    entry->name);
6135
            if (len >= MAX_WIDTH) {
6136
                ret = WOLFSSL_FAILURE;
6137
                break;
6138
            }
6139
        }
6140
        else if (entry->type == ASN_DIR_TYPE) {
6141
            len = X509PrintDirType(scratch, MAX_WIDTH, entry);
6142
            if (len >= MAX_WIDTH) {
6143
                ret = WOLFSSL_FAILURE;
6144
                break;
6145
            }
6146
        }
6147
        else if (entry->type == ASN_URI_TYPE) {
6148
            len = XSNPRINTF(scratch, MAX_WIDTH, "URI:%s",
6149
                entry->name);
6150
             if (len >= MAX_WIDTH) {
6151
                ret = WOLFSSL_FAILURE;
6152
                break;
6153
            }
6154
        }
6155
    #if defined(OPENSSL_ALL)
6156
        else if (entry->type == ASN_RID_TYPE) {
6157
            len = XSNPRINTF(scratch, MAX_WIDTH, "Registered ID:%s",
6158
                entry->ridString);
6159
            if (len >= MAX_WIDTH) {
6160
                ret = WOLFSSL_FAILURE;
6161
                break;
6162
            }
6163
        }
6164
    #endif
6165
        else if (entry->type == ASN_OTHER_TYPE) {
6166
            len = XSNPRINTF(scratch, MAX_WIDTH,
6167
                "othername <unsupported>");
6168
            if (len >= MAX_WIDTH) {
6169
                ret = WOLFSSL_FAILURE;
6170
                break;
6171
            }
6172
        }
6173
        else {
6174
            WOLFSSL_MSG("Bad alt name type.");
6175
            ret = WOLFSSL_FAILURE;
6176
            break;
6177
        }
6178
6179
        if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch))
6180
                <= 0) {
6181
            ret = WOLFSSL_FAILURE;
6182
            break;
6183
        }
6184
6185
        entry = entry->next;
6186
    }
6187
6188
    if (ret == WOLFSSL_SUCCESS && wolfSSL_BIO_write(bio, "\n", 1) <= 0) {
6189
        ret = WOLFSSL_FAILURE;
6190
    }
6191
6192
    return ret;
6193
}
6194
6195
#endif /* if WOLFSSL_ACERT*/
6196
6197
static int X509PrintSubjAltName(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
6198
        int indent)
6199
{
6200
    int ret = WOLFSSL_SUCCESS;
6201
    DNS_entry* entry;
6202
6203
    if (bio == NULL || x509 == NULL) {
6204
        ret = WOLFSSL_FAILURE;
6205
    }
6206
6207
    if (ret == WOLFSSL_SUCCESS && x509->subjAltNameSet &&
6208
            x509->altNames != NULL) {
6209
        char scratch[MAX_WIDTH];
6210
        int len;
6211
6212
        len = XSNPRINTF(scratch, MAX_WIDTH, "%*s", indent, "");
6213
        if (len >= MAX_WIDTH)
6214
            ret = WOLFSSL_FAILURE;
6215
        if (ret == WOLFSSL_SUCCESS) {
6216
            if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) {
6217
                ret = WOLFSSL_FAILURE;
6218
            }
6219
        }
6220
        if (ret == WOLFSSL_SUCCESS) {
6221
            int nameCount = 0;
6222
6223
            entry = x509->altNames;
6224
            while (entry != NULL) {
6225
                ++nameCount;
6226
                if (nameCount > 1) {
6227
                    if (wolfSSL_BIO_write(bio, ", ", 2) <= 0) {
6228
                        ret = WOLFSSL_FAILURE;
6229
                        break;
6230
                    }
6231
                }
6232
6233
                if (entry->type == ASN_DNS_TYPE) {
6234
                    len = XSNPRINTF(scratch, MAX_WIDTH, "DNS:%s", entry->name);
6235
                    if (len >= MAX_WIDTH) {
6236
                        ret = WOLFSSL_FAILURE;
6237
                        break;
6238
                    }
6239
                }
6240
            #ifdef WOLFSSL_IP_ALT_NAME
6241
                else if (entry->type == ASN_IP_TYPE) {
6242
                    len = XSNPRINTF(scratch, MAX_WIDTH, "IP Address:%s",
6243
                            entry->ipString);
6244
                    if (len >= MAX_WIDTH) {
6245
                        ret = WOLFSSL_FAILURE;
6246
                        break;
6247
                    }
6248
                }
6249
            #endif /* OPENSSL_ALL || WOLFSSL_IP_ALT_NAME */
6250
                else if (entry->type == ASN_RFC822_TYPE) {
6251
                    len = XSNPRINTF(scratch, MAX_WIDTH, "email:%s",
6252
                            entry->name);
6253
                    if (len >= MAX_WIDTH) {
6254
                        ret = WOLFSSL_FAILURE;
6255
                        break;
6256
                    }
6257
                }
6258
                else if (entry->type == ASN_DIR_TYPE) {
6259
                    /* @TODO entry->name in ASN1 syntax */
6260
                    len = XSNPRINTF(scratch, MAX_WIDTH,
6261
                        "DirName:<print out not supported yet>");
6262
                    if (len >= MAX_WIDTH) {
6263
                        ret = WOLFSSL_FAILURE;
6264
                        break;
6265
                    }
6266
                }
6267
                else if (entry->type == ASN_URI_TYPE) {
6268
                    len = XSNPRINTF(scratch, MAX_WIDTH, "URI:%s",
6269
                        entry->name);
6270
                     if (len >= MAX_WIDTH) {
6271
                        ret = WOLFSSL_FAILURE;
6272
                        break;
6273
                    }
6274
                }
6275
            #if defined(OPENSSL_ALL)
6276
                else if (entry->type == ASN_RID_TYPE) {
6277
                    len = XSNPRINTF(scratch, MAX_WIDTH, "Registered ID:%s",
6278
                        entry->ridString);
6279
                    if (len >= MAX_WIDTH) {
6280
                        ret = WOLFSSL_FAILURE;
6281
                        break;
6282
                    }
6283
                }
6284
            #endif
6285
                else if (entry->type == ASN_OTHER_TYPE) {
6286
                    len = XSNPRINTF(scratch, MAX_WIDTH,
6287
                        "othername <unsupported>");
6288
                    if (len >= MAX_WIDTH) {
6289
                        ret = WOLFSSL_FAILURE;
6290
                        break;
6291
                    }
6292
                }
6293
                else {
6294
                    WOLFSSL_MSG("Bad alt name type.");
6295
                    ret = WOLFSSL_FAILURE;
6296
                    break;
6297
                }
6298
6299
                if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch))
6300
                        <= 0) {
6301
                    ret = WOLFSSL_FAILURE;
6302
                    break;
6303
                }
6304
6305
                entry = entry->next;
6306
            }
6307
        }
6308
6309
        if (ret == WOLFSSL_SUCCESS && wolfSSL_BIO_write(bio, "\n", 1) <= 0) {
6310
            ret = WOLFSSL_FAILURE;
6311
        }
6312
    }
6313
6314
    return ret;
6315
}
6316
6317
#ifdef XSNPRINTF
6318
static int X509PrintKeyUsage(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
6319
{
6320
    int ret = WOLFSSL_SUCCESS;
6321
    const int usages[] = {
6322
        KEYUSE_DIGITAL_SIG,
6323
        KEYUSE_CONTENT_COMMIT,
6324
        KEYUSE_KEY_ENCIPHER,
6325
        KEYUSE_DATA_ENCIPHER,
6326
        KEYUSE_KEY_AGREE,
6327
        KEYUSE_KEY_CERT_SIGN,
6328
        KEYUSE_CRL_SIGN,
6329
        KEYUSE_ENCIPHER_ONLY,
6330
        KEYUSE_DECIPHER_ONLY
6331
    };
6332
    const char* usageStrs[] = {
6333
        "Digital Signature",
6334
        "Non Repudiation",
6335
        "Key Encipherment",
6336
        "Data Encipherment",
6337
        "Key Agreement",
6338
        "Certificate Sign",
6339
        "CRL Sign",
6340
        "Encipher Only",
6341
        "Decipher Only"
6342
    };
6343
6344
    if (bio == NULL || x509 == NULL) {
6345
        ret = WOLFSSL_FAILURE;
6346
    }
6347
6348
    if (ret == WOLFSSL_SUCCESS && x509->keyUsageSet && x509->keyUsage != 0) {
6349
        char scratch[MAX_WIDTH];
6350
        int len;
6351
        word32 i = 0;
6352
        int usageCount = 0;
6353
6354
        len = XSNPRINTF(scratch, MAX_WIDTH, "%*s", indent, "");
6355
        if (len >= MAX_WIDTH)
6356
            ret = WOLFSSL_FAILURE;
6357
        if (ret == WOLFSSL_SUCCESS) {
6358
            if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) {
6359
                ret = WOLFSSL_FAILURE;
6360
            }
6361
        }
6362
        for (; ret == WOLFSSL_SUCCESS && i < sizeof(usages) / sizeof(usages[i]);
6363
             i++) {
6364
            if (x509->keyUsage & usages[i]) {
6365
                ++usageCount;
6366
                if (usageCount > 1 && wolfSSL_BIO_write(bio, ", ", 2) <= 0) {
6367
                    ret = WOLFSSL_FAILURE;
6368
                    break;
6369
                }
6370
                if (wolfSSL_BIO_write(bio, usageStrs[i],
6371
                                      (int)XSTRLEN(usageStrs[i])) <= 0) {
6372
                    ret = WOLFSSL_FAILURE;
6373
                    break;
6374
                }
6375
            }
6376
        }
6377
        if (ret == WOLFSSL_SUCCESS && wolfSSL_BIO_write(bio, "\n", 1) <= 0) {
6378
            ret = WOLFSSL_FAILURE;
6379
        }
6380
    }
6381
6382
    return ret;
6383
}
6384
6385
static int X509PrintExtendedKeyUsage(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
6386
        int indent)
6387
{
6388
    int ret = WOLFSSL_SUCCESS;
6389
    const int usages[] = {
6390
        EXTKEYUSE_OCSP_SIGN,
6391
        EXTKEYUSE_TIMESTAMP,
6392
        EXTKEYUSE_EMAILPROT,
6393
        EXTKEYUSE_CODESIGN,
6394
        EXTKEYUSE_CLIENT_AUTH,
6395
        EXTKEYUSE_SERVER_AUTH
6396
    };
6397
    const char* usageStrs[] = {
6398
        "OCSP Signing",
6399
        "Time Stamping",
6400
        "E-mail Protection",
6401
        "Code Signing",
6402
        "TLS Web Client Authentication",
6403
        "TLS Web Server Authentication"
6404
    };
6405
6406
    if (bio == NULL || x509 == NULL) {
6407
        ret = WOLFSSL_FAILURE;
6408
    }
6409
6410
    if (ret == WOLFSSL_SUCCESS && x509->extKeyUsageCount > 0
6411
            && x509->extKeyUsage != 0) {
6412
        char scratch[MAX_WIDTH];
6413
        int len;
6414
        word32 i = 0;
6415
        int usageCount = 0;
6416
6417
        len = XSNPRINTF(scratch, MAX_WIDTH, "%*s", indent, "");
6418
        if (len >= MAX_WIDTH)
6419
            ret = WOLFSSL_FAILURE;
6420
        if (ret == WOLFSSL_SUCCESS) {
6421
            if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) {
6422
                ret = WOLFSSL_FAILURE;
6423
            }
6424
        }
6425
        for (; ret == WOLFSSL_SUCCESS && i < sizeof(usages) / sizeof(usages[i]);
6426
             i++) {
6427
            if (x509->extKeyUsage & usages[i]) {
6428
                ++usageCount;
6429
                if (usageCount > 1 && wolfSSL_BIO_write(bio, ", ", 2) <= 0) {
6430
                    ret = WOLFSSL_FAILURE;
6431
                    break;
6432
                }
6433
                if (wolfSSL_BIO_write(bio, usageStrs[i],
6434
                                      (int)XSTRLEN(usageStrs[i])) <= 0) {
6435
                    ret = WOLFSSL_FAILURE;
6436
                    break;
6437
                }
6438
            }
6439
        }
6440
        if (ret == WOLFSSL_SUCCESS && wolfSSL_BIO_write(bio, "\n", 1) <= 0) {
6441
            ret = WOLFSSL_FAILURE;
6442
        }
6443
    }
6444
6445
    return ret;
6446
}
6447
6448
6449
/* print serial number out
6450
 * return WOLFSSL_SUCCESS on success
6451
 */
6452
static int X509PrintSerial_ex(WOLFSSL_BIO* bio, byte* serial, int sz,
6453
        int delimiter, int indent)
6454
{
6455
    char scratch[MAX_WIDTH];
6456
    const int scratchSz = sizeof(scratch);
6457
    int scratchLen;
6458
6459
    if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*sSerial Number:",
6460
                                 indent, "")) >= MAX_WIDTH) {
6461
        WOLFSSL_MSG("buffer overrun");
6462
        return WOLFSSL_FAILURE;
6463
    }
6464
    if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
6465
        return WOLFSSL_FAILURE;
6466
    }
6467
6468
    if (sz > (int)sizeof(byte)) {
6469
        int i;
6470
6471
        /* serial is larger than int size so print off hex values */
6472
        if ((scratchLen = XSNPRINTF(
6473
                 scratch, MAX_WIDTH, "\n%*s", indent + 4, ""))
6474
                >= MAX_WIDTH) {
6475
            WOLFSSL_MSG("buffer overrun");
6476
            return WOLFSSL_FAILURE;
6477
        }
6478
        for (i = 0; i < sz; i++) {
6479
            int valLen;
6480
6481
            if ((valLen = XSNPRINTF(
6482
                     scratch + scratchLen, scratchSz - scratchLen,
6483
                     "%02x%s", serial[i], (i < sz - 1) ?
6484
                     (delimiter ? ":" : "") : "\n"))
6485
                >= scratchSz - scratchLen) {
6486
                WOLFSSL_MSG("buffer overrun");
6487
                return WOLFSSL_FAILURE;
6488
            }
6489
            scratchLen += valLen;
6490
        }
6491
        if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
6492
            return WOLFSSL_FAILURE;
6493
        }
6494
    }
6495
6496
    /* if serial can fit into byte then print on the same line */
6497
    else  {
6498
        if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, " %d (0x%x)\n",
6499
                (char)serial[0], serial[0])) >= MAX_WIDTH) {
6500
            WOLFSSL_MSG("buffer overrun");
6501
            return WOLFSSL_FAILURE;
6502
        }
6503
        if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
6504
            return WOLFSSL_FAILURE;
6505
        }
6506
    }
6507
    return WOLFSSL_SUCCESS;
6508
}
6509
6510
static int X509PrintSerial(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
6511
{
6512
    unsigned char serial[32];
6513
    int  sz = sizeof(serial);
6514
6515
    XMEMSET(serial, 0, sz);
6516
    if (wolfSSL_X509_get_serial_number(x509, serial, &sz) == WOLFSSL_SUCCESS) {
6517
        X509PrintSerial_ex(bio, serial, sz, 1, indent);
6518
    }
6519
    return WOLFSSL_SUCCESS;
6520
}
6521
6522
#ifndef NO_ASN_TIME
6523
static int X509PrintValidity(WOLFSSL_BIO* bio, WOLFSSL_ASN1_TIME * notBefore,
6524
                             WOLFSSL_ASN1_TIME * notAfter, int indent)
6525
{
6526
    char tmp[80];
6527
    (void) indent;
6528
6529
    if (wolfSSL_BIO_write(bio, "        Validity\n",
6530
                  (int)XSTRLEN("        Validity\n")) <= 0) {
6531
        return WOLFSSL_FAILURE;
6532
    }
6533
6534
    if (wolfSSL_BIO_write(bio, "            Not Before: ",
6535
                  (int)XSTRLEN("            Not Before: ")) <= 0) {
6536
        return WOLFSSL_FAILURE;
6537
    }
6538
    if (notBefore->length > 0) {
6539
        if (GetTimeString(notBefore->data, ASN_UTC_TIME,
6540
            tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
6541
            if (GetTimeString(notBefore->data, ASN_GENERALIZED_TIME,
6542
            tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
6543
                WOLFSSL_MSG("Error getting not before date");
6544
                return WOLFSSL_FAILURE;
6545
            }
6546
        }
6547
    }
6548
    else {
6549
        XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
6550
    }
6551
    tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
6552
    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
6553
        return WOLFSSL_FAILURE;
6554
    }
6555
6556
    if (wolfSSL_BIO_write(bio, "\n            Not After : ",
6557
                  (int)XSTRLEN("\n            Not After : ")) <= 0) {
6558
        return WOLFSSL_FAILURE;
6559
    }
6560
    if (notAfter->length > 0) {
6561
        if (GetTimeString(notAfter->data, ASN_UTC_TIME,
6562
            tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
6563
            if (GetTimeString(notAfter->data, ASN_GENERALIZED_TIME,
6564
                tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
6565
                WOLFSSL_MSG("Error getting not after date");
6566
                return WOLFSSL_FAILURE;
6567
            }
6568
        }
6569
    }
6570
    else {
6571
        XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
6572
    }
6573
    tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
6574
    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
6575
        return WOLFSSL_FAILURE;
6576
    }
6577
6578
    if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
6579
        return WOLFSSL_FAILURE;
6580
    }
6581
6582
    return WOLFSSL_SUCCESS;
6583
}
6584
#endif /* ifndef NO_ASN_TIME */
6585
6586
/* iterate through certificate extensions printing them out in human readable
6587
 * form
6588
 * return WOLFSSL_SUCCESS on success
6589
 */
6590
static int X509PrintExtensions(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
6591
{
6592
    int  ret = WOLFSSL_SUCCESS;
6593
    char scratch[MAX_WIDTH];
6594
    const int scratchSz = sizeof(scratch);
6595
    int scratchLen;
6596
    int  count, i;
6597
    char* buf = NULL;
6598
6599
    count = wolfSSL_X509_get_ext_count(x509);
6600
    if (count <= 0)
6601
        return WOLFSSL_SUCCESS;
6602
6603
#ifdef WOLFSSL_CERT_REQ
6604
    if (x509->isCSR) {
6605
        if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*s%s\n", indent, "",
6606
                      "Requested extensions:")) >= MAX_WIDTH) {
6607
            return WOLFSSL_FAILURE;
6608
        }
6609
    }
6610
    else
6611
#endif
6612
    {
6613
        if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*s%s\n", indent, "",
6614
                                     "X509v3 extensions:")) >= MAX_WIDTH) {
6615
            return WOLFSSL_FAILURE;
6616
        }
6617
    }
6618
    if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
6619
        return WOLFSSL_FAILURE;
6620
    }
6621
6622
    buf = (char*)XMALLOC(MAX_WIDTH, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
6623
    if (buf == NULL) {
6624
        return WOLFSSL_FAILURE;
6625
    }
6626
6627
    for (i = 0; (i < count) && (ret != WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); i++) {
6628
        WOLFSSL_X509_EXTENSION* ext;
6629
6630
        ext = wolfSSL_X509_get_ext(x509, i);
6631
        if (ext != NULL) {
6632
            WOLFSSL_ASN1_OBJECT* obj;
6633
            int nid;
6634
            char val[6];
6635
            int valLen;
6636
            word32 j;
6637
6638
            obj = wolfSSL_X509_EXTENSION_get_object(ext);
6639
            if (obj == NULL) {
6640
                ret = WOLFSSL_FAILURE;
6641
                break;
6642
            }
6643
            if (wolfSSL_OBJ_obj2txt(buf, MAX_WIDTH, obj, 0)
6644
                == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
6645
            {
6646
                ret = WOLFSSL_FAILURE;
6647
                break;
6648
            }
6649
            if ((scratchLen = XSNPRINTF(
6650
                     scratch, MAX_WIDTH, "%*s%s%s\n", indent + 4, "",
6651
                     buf,
6652
                     (wolfSSL_X509_EXTENSION_get_critical(ext)
6653
                      ? ": critical"
6654
                      : ": ")))
6655
                >= MAX_WIDTH)
6656
            {
6657
                ret = WOLFSSL_FAILURE;
6658
                break;
6659
            }
6660
6661
            if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
6662
                ret = WOLFSSL_FAILURE;
6663
                break;
6664
            }
6665
            nid = wolfSSL_OBJ_obj2nid(obj);
6666
            switch (nid) {
6667
            case WC_NID_subject_alt_name:
6668
                ret = X509PrintSubjAltName(bio, x509, indent + 8);
6669
                break;
6670
6671
            case WC_NID_subject_key_identifier:
6672
                if (!x509->subjKeyIdSet || x509->subjKeyId == NULL ||
6673
                    x509->subjKeyIdSz == 0)
6674
                {
6675
                    ret = WOLFSSL_FAILURE;
6676
                    break;
6677
                }
6678
6679
                if ((scratchLen = XSNPRINTF(
6680
                         scratch, scratchSz,
6681
                         "%*s", indent + 8, "")) >= scratchSz)
6682
                {
6683
                    ret = WOLFSSL_FAILURE;
6684
                    break;
6685
                }
6686
                for (j = 0; j < x509->subjKeyIdSz; j++) {
6687
                    if ((valLen = XSNPRINTF(
6688
                             val, sizeof(val), "%02X%s",
6689
                             x509->subjKeyId[j],
6690
                             (j < x509->subjKeyIdSz - 1) ? ":" : "\n"))
6691
                        >= (int)sizeof(val))
6692
                    {
6693
                        ret = WOLFSSL_FAILURE;
6694
                        break;
6695
                    }
6696
                    if (scratchLen + valLen >= scratchSz) {
6697
                        if (wolfSSL_BIO_write(bio, scratch,
6698
                                              scratchLen) <= 0) {
6699
                            ret = WOLFSSL_FAILURE;
6700
                            break;
6701
                        }
6702
                        scratchLen = 0;
6703
                    }
6704
                    XMEMCPY(scratch + scratchLen, val, valLen);
6705
                    scratchLen += valLen;
6706
                }
6707
                if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
6708
                    break;
6709
                if (wolfSSL_BIO_write(bio, scratch,
6710
                                      scratchLen) <= 0) {
6711
                    ret = WOLFSSL_FAILURE;
6712
                    break;
6713
                }
6714
                break;
6715
6716
            case WC_NID_authority_key_identifier:
6717
                if (!x509->authKeyIdSet || x509->authKeyId == NULL ||
6718
                    x509->authKeyIdSz == 0) {
6719
                    ret = WOLFSSL_FAILURE;
6720
                    break;
6721
                }
6722
6723
                if ((scratchLen = XSNPRINTF(
6724
                         scratch, scratchSz, "%*s%s",
6725
                         indent + 8, "", "keyid:")) >= scratchSz)
6726
                {
6727
                    ret = WOLFSSL_FAILURE;
6728
                    break;
6729
                }
6730
                for (j = 0; j < x509->authKeyIdSz; j++) {
6731
                    if ((valLen = XSNPRINTF(
6732
                             val, sizeof(val), "%02X%s",
6733
                             x509->authKeyId[j],
6734
                             (j < x509->authKeyIdSz - 1) ? ":" : "\n\n"))
6735
                        >= (int)sizeof(val))
6736
                    {
6737
                        ret = WOLFSSL_FAILURE;
6738
                        break;
6739
                    }
6740
                    if (scratchLen >= scratchSz - valLen) {
6741
                        if (wolfSSL_BIO_write(bio, scratch,
6742
                                              scratchLen) <= 0)
6743
                        {
6744
                            ret = WOLFSSL_FAILURE;
6745
                            break;
6746
                        }
6747
                        scratchLen = 0;
6748
                    }
6749
                    if (scratchLen + valLen >= scratchSz) {
6750
                        ret = WOLFSSL_FAILURE;
6751
                        break;
6752
                    }
6753
                    XMEMCPY(scratch + scratchLen, val, valLen);
6754
                    scratchLen += valLen;
6755
                }
6756
                if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
6757
                    break;
6758
                if (wolfSSL_BIO_write(bio, scratch,
6759
                                      scratchLen) <= 0) {
6760
                    ret = WOLFSSL_FAILURE;
6761
                    break;
6762
                }
6763
                break;
6764
6765
            case WC_NID_basic_constraints:
6766
                if (!x509->basicConstSet) {
6767
                    ret = WOLFSSL_FAILURE;
6768
                    break;
6769
                }
6770
                if ((scratchLen = XSNPRINTF(
6771
                         scratch, scratchSz,
6772
                         "%*sCA:%s\n",
6773
                         indent + 8, "", (x509->isCa)? "TRUE": "FALSE"))
6774
                    >= scratchSz)
6775
                {
6776
                    ret = WOLFSSL_FAILURE;
6777
                    break;
6778
                }
6779
                if (wolfSSL_BIO_write(bio, scratch,
6780
                                      scratchLen) <= 0) {
6781
                    ret = WOLFSSL_FAILURE;
6782
                    break;
6783
                }
6784
                break;
6785
6786
            case WC_NID_key_usage:
6787
                ret = X509PrintKeyUsage(bio, x509, indent + 8);
6788
                break;
6789
6790
            case WC_NID_ext_key_usage:
6791
                ret = X509PrintExtendedKeyUsage(bio, x509, indent + 8);
6792
                break;
6793
6794
            default:
6795
                /* extension nid not yet supported */
6796
                if ((scratchLen = XSNPRINTF(
6797
                         scratch, MAX_WIDTH,
6798
                         "%*sNID %d print not yet supported\n",
6799
                         indent + 8, "", nid)) >= MAX_WIDTH)
6800
                {
6801
                    ret = WOLFSSL_FAILURE;
6802
                    break;
6803
                }
6804
6805
                if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
6806
                    ret = WOLFSSL_FAILURE;
6807
                    break;
6808
                }
6809
            }
6810
        }
6811
    }
6812
6813
    XFREE(buf, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
6814
6815
    return ret;
6816
}
6817
6818
6819
/* print out the signature in human readable format for use with
6820
 * wolfSSL_X509_print()
6821
 * return WOLFSSL_SUCCESS on success
6822
 */
6823
static int X509PrintSignature_ex(WOLFSSL_BIO* bio, byte* sig,
6824
        int sigSz, int sigNid, int algOnly, int indent)
6825
{
6826
    char scratch[MAX_WIDTH];
6827
    int scratchLen;
6828
    WOLFSSL_ASN1_OBJECT* obj = NULL;
6829
    int ret = WOLFSSL_SUCCESS;
6830
    char tmp[100];
6831
    int tmpLen = 0;
6832
6833
    if (sigSz <= 0) {
6834
        return WOLFSSL_SUCCESS;
6835
    }
6836
6837
    if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*s%s", indent, "",
6838
                                "Signature Algorithm: ")) >= MAX_WIDTH) {
6839
        ret = WOLFSSL_FAILURE;
6840
    }
6841
6842
    if (ret == WOLFSSL_SUCCESS) {
6843
        if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0)
6844
            ret = WOLFSSL_FAILURE;
6845
    }
6846
6847
    if (ret == WOLFSSL_SUCCESS) {
6848
        obj = wolfSSL_OBJ_nid2obj(sigNid);
6849
        if (obj == NULL)
6850
            ret = WOLFSSL_FAILURE;
6851
    }
6852
    if (ret == WOLFSSL_SUCCESS) {
6853
        if (wolfSSL_OBJ_obj2txt(scratch, MAX_WIDTH, obj, 0)
6854
            == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
6855
        {
6856
            ret = WOLFSSL_FAILURE;
6857
        }
6858
    }
6859
6860
    if (ret == WOLFSSL_SUCCESS) {
6861
        if ((tmpLen = XSNPRINTF(tmp, sizeof(tmp),"%s\n", scratch))
6862
            >= (int)sizeof(tmp))
6863
        {
6864
            ret = WOLFSSL_FAILURE;
6865
        }
6866
    }
6867
    if (ret == WOLFSSL_SUCCESS) {
6868
        if (wolfSSL_BIO_write(bio, tmp, tmpLen) <= 0)
6869
            ret = WOLFSSL_FAILURE;
6870
    }
6871
6872
    /* Leave function if the desired content to print
6873
     * is only the signature algorithm */
6874
    if (algOnly) {
6875
        if (obj != NULL)
6876
            wolfSSL_ASN1_OBJECT_free(obj);
6877
6878
        return ret;
6879
    }
6880
6881
    if (ret == WOLFSSL_SUCCESS) {
6882
        if ((tmpLen = XSNPRINTF(tmp, sizeof(tmp), "%*s", indent + 5, ""))
6883
            >= (int)sizeof(tmp))
6884
        {
6885
            ret = WOLFSSL_FAILURE;
6886
        }
6887
    }
6888
6889
    if (ret == WOLFSSL_SUCCESS) {
6890
        int i;
6891
6892
        for (i = 0; i < sigSz; i++) {
6893
            char val[6];
6894
            int valLen;
6895
6896
            if (i == 0) {
6897
                if ((valLen = XSNPRINTF(val, sizeof(val), "%02x", sig[i]))
6898
                    >= (int)sizeof(val))
6899
                {
6900
                    ret = WOLFSSL_FAILURE;
6901
                    break;
6902
                }
6903
            }
6904
            else if (((i % 18) == 0)) {
6905
                if (wolfSSL_BIO_write(bio, tmp, tmpLen)
6906
                    <= 0) {
6907
                    ret = WOLFSSL_FAILURE;
6908
                    break;
6909
                }
6910
                if ((tmpLen = XSNPRINTF(tmp, sizeof(tmp), ":\n%*s",
6911
                                        indent + 5, ""))
6912
                    >= (int)sizeof(tmp))
6913
                {
6914
                    ret = WOLFSSL_FAILURE;
6915
                    break;
6916
                }
6917
                if ((valLen = XSNPRINTF(val, sizeof(val), "%02x", sig[i]))
6918
                    >= (int)sizeof(val))
6919
                {
6920
                    ret = WOLFSSL_FAILURE;
6921
                    break;
6922
                }
6923
            }
6924
            else {
6925
                if ((valLen = XSNPRINTF(val, sizeof(val), ":%02x", sig[i]))
6926
                    >= (int)sizeof(val))
6927
                {
6928
                    ret = WOLFSSL_FAILURE;
6929
                    break;
6930
                }
6931
            }
6932
            if ((tmpLen < 0) || (valLen < 0) ||
6933
                    (valLen >= ((int)sizeof(tmp) - tmpLen - 1))) {
6934
                ret = WOLFSSL_FAILURE;
6935
                break;
6936
            }
6937
            XMEMCPY(tmp + tmpLen, val, valLen);
6938
            tmpLen += valLen;
6939
            tmp[tmpLen] = 0;
6940
        }
6941
    }
6942
6943
    /* print out remaining sig values */
6944
    if (ret == WOLFSSL_SUCCESS) {
6945
        if (tmpLen > 0) {
6946
            if (wolfSSL_BIO_write(bio, tmp, tmpLen)
6947
                <= 0)
6948
            {
6949
                ret = WOLFSSL_FAILURE;
6950
            }
6951
        }
6952
    }
6953
6954
    if (obj != NULL)
6955
        wolfSSL_ASN1_OBJECT_free(obj);
6956
6957
    return ret;
6958
}
6959
6960
static int X509PrintSignature(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
6961
        int algOnly, int indent)
6962
{
6963
    int sigSz = 0;
6964
    if (wolfSSL_X509_get_signature(x509, NULL, &sigSz) <= 0) {
6965
        return WOLFSSL_FAILURE;
6966
    }
6967
6968
    if (sigSz > 0) {
6969
        unsigned char* sig;
6970
        int sigNid;
6971
6972
        sigNid = wolfSSL_X509_get_signature_nid(x509);
6973
        if (sigNid <= 0) {
6974
            return WOLFSSL_FAILURE;
6975
        }
6976
6977
        sig = (unsigned char*)XMALLOC(sigSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6978
        if (sig == NULL) {
6979
            return WOLFSSL_FAILURE;
6980
        }
6981
6982
        if (wolfSSL_X509_get_signature(x509, sig, &sigSz) <= 0) {
6983
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6984
            return WOLFSSL_FAILURE;
6985
        }
6986
6987
        if (X509PrintSignature_ex(bio, sig, sigSz, sigNid, algOnly, indent)
6988
                != WOLFSSL_SUCCESS) {
6989
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6990
            return WOLFSSL_FAILURE;
6991
        }
6992
6993
        XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6994
6995
    }
6996
6997
    return WOLFSSL_SUCCESS;
6998
}
6999
7000
7001
/* print out the public key in human readable format for use with
7002
 * wolfSSL_X509_print()
7003
 * return WOLFSSL_SUCCESS on success
7004
 */
7005
static int X509PrintPubKey(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
7006
{
7007
    char scratch[MAX_WIDTH];
7008
    WOLFSSL_EVP_PKEY* pubKey;
7009
    int len;
7010
    int ret = WOLFSSL_SUCCESS;
7011
7012
    if (bio == NULL || x509 == NULL)
7013
        return BAD_FUNC_ARG;
7014
7015
    len = XSNPRINTF(scratch, MAX_WIDTH, "%*sSubject Public Key Info:\n", indent,
7016
        "");
7017
    if (len >= MAX_WIDTH)
7018
        return WOLFSSL_FAILURE;
7019
    if (wolfSSL_BIO_write(bio, scratch, len) <= 0)
7020
        return WOLFSSL_FAILURE;
7021
7022
    switch (x509->pubKeyOID) {
7023
    #ifndef NO_RSA
7024
        case RSAk:
7025
            len = XSNPRINTF(scratch, MAX_WIDTH,
7026
                    "%*sPublic Key Algorithm: rsaEncryption\n", indent + 4, "");
7027
            if (len >= MAX_WIDTH)
7028
                return WOLFSSL_FAILURE;
7029
            if (wolfSSL_BIO_write(bio, scratch, len) <= 0)
7030
                return WOLFSSL_FAILURE;
7031
            break;
7032
    #endif
7033
    #ifdef HAVE_ECC
7034
        case ECDSAk:
7035
            len = XSNPRINTF(scratch, MAX_WIDTH,
7036
                    "%*sPublic Key Algorithm: EC\n", indent + 4, "");
7037
            if ((len < 0) || (len >= MAX_WIDTH))
7038
                return WOLFSSL_FAILURE;
7039
            if (wolfSSL_BIO_write(bio, scratch, len) <= 0)
7040
                return WOLFSSL_FAILURE;
7041
            break;
7042
    #endif
7043
        default:
7044
                WOLFSSL_MSG("Unknown key type");
7045
                return WOLFSSL_FAILURE;
7046
    }
7047
7048
    pubKey = wolfSSL_X509_get_pubkey(x509);
7049
    if (pubKey == NULL)
7050
        return WOLFSSL_FAILURE;
7051
7052
    ret = wolfSSL_EVP_PKEY_print_public(bio, pubKey, indent + 8, NULL);
7053
7054
    wolfSSL_EVP_PKEY_free(pubKey);
7055
7056
    return ret;
7057
}
7058
7059
7060
/* human readable print out of x509 name formatted for use with
7061
 * wolfSSL_X509_print()
7062
 * return WOLFSSL_SUCCESS on success
7063
 */
7064
static int X509PrintName(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name,
7065
        char* type, int indent)
7066
{
7067
    if (name != NULL) {
7068
        char scratch[MAX_WIDTH];
7069
        int scratchLen;
7070
7071
        if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH,
7072
                                     "%*s%s", indent, "", type))
7073
            >= MAX_WIDTH)
7074
        {
7075
            return WOLFSSL_FAILURE;
7076
        }
7077
        if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
7078
            return WOLFSSL_FAILURE;
7079
        }
7080
        if (wolfSSL_X509_NAME_print_ex(bio, name, 1, 0) <= 0) {
7081
            return WOLFSSL_FAILURE;
7082
        }
7083
        if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) {
7084
            return WOLFSSL_FAILURE;
7085
        }
7086
    }
7087
    return WOLFSSL_SUCCESS;
7088
}
7089
7090
7091
/* human readable print out of x509 version
7092
 * return WOLFSSL_SUCCESS on success
7093
 */
7094
static int X509PrintVersion(WOLFSSL_BIO* bio, int version, int indent)
7095
{
7096
    char scratch[MAX_WIDTH];
7097
    int scratchLen;
7098
7099
    scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*s%s", indent, "", "Version:");
7100
    if ((scratchLen < 0) || (scratchLen >= MAX_WIDTH)) {
7101
        return WOLFSSL_FAILURE;
7102
    }
7103
7104
    if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
7105
        return WOLFSSL_FAILURE;
7106
    }
7107
7108
    scratchLen = XSNPRINTF(scratch, MAX_WIDTH, " %d (0x%x)\n",
7109
                    version, (byte)version-1);
7110
    if ((scratchLen < 0) || (scratchLen >= MAX_WIDTH)) {
7111
        return WOLFSSL_FAILURE;
7112
    }
7113
7114
    if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
7115
        return WOLFSSL_FAILURE;
7116
    }
7117
    return WOLFSSL_SUCCESS;
7118
}
7119
7120
#ifdef WOLFSSL_CERT_REQ
7121
/* Print out of REQ attributes
7122
 * return WOLFSSL_SUCCESS on success
7123
 */
7124
static int X509PrintReqAttributes(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
7125
        int indent)
7126
{
7127
    WOLFSSL_X509_ATTRIBUTE* attr;
7128
    char scratch[MAX_WIDTH];
7129
    int scratchLen;
7130
    int i = 0;
7131
7132
    if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH,
7133
                                 "%*s%s", indent, "", "Attributes: \n"))
7134
        >= MAX_WIDTH)
7135
    {
7136
        return WOLFSSL_FAILURE;
7137
    }
7138
    if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
7139
        return WOLFSSL_FAILURE;
7140
    }
7141
    do {
7142
        attr = wolfSSL_X509_REQ_get_attr(x509, i);
7143
        if (attr != NULL) {
7144
            char lName[NAME_SZ/4]; /* NAME_SZ default is 80 */
7145
            int lNameSz = NAME_SZ/4;
7146
            const byte* data;
7147
7148
            if (wolfSSL_OBJ_obj2txt(lName, lNameSz, attr->object, 0)
7149
                == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
7150
            {
7151
                return WOLFSSL_FAILURE;
7152
            }
7153
            lNameSz = (int)XSTRLEN(lName);
7154
            data = wolfSSL_ASN1_STRING_get0_data(
7155
                    attr->value->value.asn1_string);
7156
            if (data == NULL) {
7157
                WOLFSSL_MSG("No REQ attribute found when expected");
7158
                return WOLFSSL_FAILURE;
7159
            }
7160
            if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH,
7161
                          "%*s%s%*s:%s\n", indent+4, "",
7162
                          lName, (NAME_SZ/4)-lNameSz, "", data))
7163
                >= MAX_WIDTH)
7164
            {
7165
                return WOLFSSL_FAILURE;
7166
            }
7167
            if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
7168
                WOLFSSL_MSG("Error writing REQ attribute");
7169
                return WOLFSSL_FAILURE;
7170
            }
7171
        }
7172
        i++;
7173
    } while (attr != NULL);
7174
7175
    return WOLFSSL_SUCCESS;
7176
}
7177
7178
7179
/*
7180
 * return WOLFSSL_SUCCESS on success
7181
 */
7182
int wolfSSL_X509_REQ_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
7183
{
7184
    char subjType[] = "Subject: ";
7185
7186
    if (bio == NULL || x509 == NULL) {
7187
        return WOLFSSL_FAILURE;
7188
    }
7189
7190
    if (wolfSSL_BIO_write(bio, "Certificate Request:\n",
7191
                  (int)XSTRLEN("Certificate Request:\n")) <= 0) {
7192
            return WOLFSSL_FAILURE;
7193
    }
7194
7195
    if (wolfSSL_BIO_write(bio, "    Data:\n",
7196
                  (int)XSTRLEN("    Data:\n")) <= 0) {
7197
            return WOLFSSL_FAILURE;
7198
    }
7199
7200
    /* print version of cert.  Note that we increment by 1 because for REQs,
7201
     * the value stored in x509->version is the actual value of the field; not
7202
     * the version. */
7203
    if (X509PrintVersion(bio, (int)wolfSSL_X509_REQ_get_version(x509) + 1, 8)
7204
            != WOLFSSL_SUCCESS) {
7205
        return WOLFSSL_FAILURE;
7206
    }
7207
7208
    if (X509PrintSerial(bio, x509, 8) != WOLFSSL_SUCCESS) {
7209
        return WOLFSSL_FAILURE;
7210
    }
7211
7212
    /* print subject */
7213
    if (X509PrintName(bio, wolfSSL_X509_get_subject_name(x509), subjType, 8)
7214
            != WOLFSSL_SUCCESS) {
7215
        return WOLFSSL_FAILURE;
7216
    }
7217
7218
    /* get and print public key */
7219
    if (X509PrintPubKey(bio, x509, 8) != WOLFSSL_SUCCESS) {
7220
        return WOLFSSL_FAILURE;
7221
    }
7222
7223
    /* print out extensions */
7224
    if (X509PrintExtensions(bio, x509, 4) != WOLFSSL_SUCCESS) {
7225
        return WOLFSSL_FAILURE;
7226
    }
7227
7228
    /* print out req attributes */
7229
    if (X509PrintReqAttributes(bio, x509, 4) != WOLFSSL_SUCCESS) {
7230
        return WOLFSSL_FAILURE;
7231
    }
7232
7233
    /* print out signature */
7234
    if (X509PrintSignature(bio, x509, 0, 4) != WOLFSSL_SUCCESS) {
7235
        return WOLFSSL_FAILURE;
7236
    }
7237
7238
    /* done with print out */
7239
    if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
7240
        return WOLFSSL_FAILURE;
7241
    }
7242
7243
    return WOLFSSL_SUCCESS;
7244
}
7245
#endif /* WOLFSSL_CERT_REQ */
7246
7247
7248
/* Writes the human readable form of x509 to bio.
7249
 *
7250
 * bio  WOLFSSL_BIO to write to.
7251
 * x509 Certificate to write.
7252
 *
7253
 * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
7254
 */
7255
int wolfSSL_X509_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
7256
    unsigned long nmflags, unsigned long cflag)
7257
{
7258
    char issuType[] = "Issuer:";
7259
    char subjType[] = "Subject:";
7260
7261
    WOLFSSL_ENTER("wolfSSL_X509_print_ex");
7262
7263
    /* flags currently not supported */
7264
    (void)nmflags;
7265
    (void)cflag;
7266
7267
    if (bio == NULL || x509 == NULL) {
7268
        return WOLFSSL_FAILURE;
7269
    }
7270
7271
    if (wolfSSL_BIO_write(bio, "Certificate:\n",
7272
                  (int)XSTRLEN("Certificate:\n")) <= 0) {
7273
            return WOLFSSL_FAILURE;
7274
    }
7275
7276
    if (wolfSSL_BIO_write(bio, "    Data:\n",
7277
                  (int)XSTRLEN("    Data:\n")) <= 0) {
7278
            return WOLFSSL_FAILURE;
7279
    }
7280
7281
    /* print version of cert */
7282
    if (X509PrintVersion(bio, wolfSSL_X509_version(x509), 8)
7283
            != WOLFSSL_SUCCESS) {
7284
        return WOLFSSL_FAILURE;
7285
    }
7286
7287
    /* print serial number out */
7288
    if (X509PrintSerial(bio, x509, 8) != WOLFSSL_SUCCESS) {
7289
        return WOLFSSL_FAILURE;
7290
    }
7291
7292
    /* print out signature algo*/
7293
    if (X509PrintSignature(bio, x509, 1, 8) != WOLFSSL_SUCCESS) {
7294
        return WOLFSSL_FAILURE;
7295
    }
7296
7297
    /* print issuer */
7298
    if (X509PrintName(bio, wolfSSL_X509_get_issuer_name(x509), issuType, 8)
7299
            != WOLFSSL_SUCCESS) {
7300
        return WOLFSSL_FAILURE;
7301
    }
7302
7303
    #ifndef NO_ASN_TIME
7304
    /* print validity */
7305
    if (X509PrintValidity(bio, &x509->notBefore, &x509->notAfter, 8)
7306
        != WOLFSSL_SUCCESS) {
7307
        return WOLFSSL_FAILURE;
7308
    }
7309
    #endif /* NO_ASN_TIME */
7310
7311
    /* print subject */
7312
    if (X509PrintName(bio, wolfSSL_X509_get_subject_name(x509), subjType, 8)
7313
            != WOLFSSL_SUCCESS) {
7314
        return WOLFSSL_FAILURE;
7315
    }
7316
7317
    /* get and print public key */
7318
    if (X509PrintPubKey(bio, x509, 8) != WOLFSSL_SUCCESS) {
7319
        return WOLFSSL_FAILURE;
7320
    }
7321
7322
    /* print out extensions */
7323
    if (X509PrintExtensions(bio, x509, 8) != WOLFSSL_SUCCESS) {
7324
        return WOLFSSL_FAILURE;
7325
    }
7326
7327
    /* print out signature */
7328
    if (X509PrintSignature(bio, x509, 0, 4) != WOLFSSL_SUCCESS) {
7329
        return WOLFSSL_FAILURE;
7330
    }
7331
7332
    /* done with print out */
7333
    if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
7334
        return WOLFSSL_FAILURE;
7335
    }
7336
7337
    return WOLFSSL_SUCCESS;
7338
}
7339
int wolfSSL_X509_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
7340
{
7341
    return wolfSSL_X509_print_ex(bio, x509, 0, 0);
7342
}
7343
7344
#if defined(WOLFSSL_ACERT)
7345
/* Retrieve sig NID from an ACERT.
7346
 *
7347
 * returns  NID on success
7348
 * returns  0 on failure
7349
 */
7350
int wolfSSL_X509_ACERT_get_signature_nid(const WOLFSSL_X509_ACERT *x509)
7351
{
7352
    if (x509 == NULL) {
7353
        return 0;
7354
    }
7355
7356
    return oid2nid((word32)x509->sigOID, oidSigType);
7357
}
7358
7359
static int X509AcertPrintSignature(WOLFSSL_BIO* bio, WOLFSSL_X509_ACERT* x509,
7360
                                   int algOnly, int indent)
7361
{
7362
    int sigSz = 0;
7363
    if (wolfSSL_X509_ACERT_get_signature(x509, NULL, &sigSz) <= 0) {
7364
        return WOLFSSL_FAILURE;
7365
    }
7366
7367
    if (sigSz > 0) {
7368
        unsigned char* sig;
7369
        int sigNid;
7370
7371
        sigNid = wolfSSL_X509_ACERT_get_signature_nid(x509);
7372
        if (sigNid <= 0) {
7373
            return WOLFSSL_FAILURE;
7374
        }
7375
7376
        sig = (unsigned char*)XMALLOC(sigSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7377
        if (sig == NULL) {
7378
            return WOLFSSL_FAILURE;
7379
        }
7380
7381
        if (wolfSSL_X509_ACERT_get_signature(x509, sig, &sigSz) <= 0) {
7382
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7383
            return WOLFSSL_FAILURE;
7384
        }
7385
7386
        if (X509PrintSignature_ex(bio, sig, sigSz, sigNid, algOnly, indent)
7387
                != WOLFSSL_SUCCESS) {
7388
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7389
            return WOLFSSL_FAILURE;
7390
        }
7391
7392
        if (sig != NULL) {
7393
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7394
        }
7395
7396
    }
7397
7398
    return WOLFSSL_SUCCESS;
7399
}
7400
7401
static int X509AcertPrintSerial(WOLFSSL_BIO* bio, WOLFSSL_X509_ACERT* x509,
7402
                                int indent)
7403
{
7404
    unsigned char serial[32];
7405
    int  sz = sizeof(serial);
7406
7407
    XMEMSET(serial, 0, sz);
7408
    if (wolfSSL_X509_ACERT_get_serial_number(x509, serial, &sz)
7409
        == WOLFSSL_SUCCESS) {
7410
        X509PrintSerial_ex(bio, serial, sz, 1, indent);
7411
    }
7412
    return WOLFSSL_SUCCESS;
7413
}
7414
7415
int wolfSSL_X509_ACERT_print(WOLFSSL_BIO* bio, WOLFSSL_X509_ACERT* x509)
7416
{
7417
    const char * hdr =                "Attribute Certificate:\n";
7418
    const char * data_hdr =           "    Data:\n";
7419
    const char * holder_hdr =         "        Holder:\n";
7420
    const char * holder_issuer_hdr =  "            Issuer:";
7421
    const char * holder_name_hdr =    "            Name:";
7422
    const char * attcert_issuer_hdr = "        Issuer:";
7423
7424
    if (bio == NULL || x509 == NULL) {
7425
        return WOLFSSL_FAILURE;
7426
    }
7427
7428
    /* print acert header */
7429
    if (wolfSSL_BIO_write(bio, hdr, (int)XSTRLEN(hdr)) <= 0) {
7430
        return WOLFSSL_FAILURE;
7431
    }
7432
7433
    /* print data header */
7434
    if (wolfSSL_BIO_write(bio, data_hdr, (int)XSTRLEN(data_hdr)) <= 0) {
7435
        return WOLFSSL_FAILURE;
7436
    }
7437
7438
    /* print version of cert */
7439
    if (X509PrintVersion(bio, wolfSSL_X509_ACERT_version(x509), 8)
7440
            != WOLFSSL_SUCCESS) {
7441
        return WOLFSSL_FAILURE;
7442
    }
7443
7444
    /* print serial number out */
7445
    if (X509AcertPrintSerial(bio, x509, 8) != WOLFSSL_SUCCESS) {
7446
        return WOLFSSL_FAILURE;
7447
    }
7448
7449
    /* print holder field */
7450
    if (wolfSSL_BIO_write(bio, holder_hdr, (int)XSTRLEN(holder_hdr)) <= 0) {
7451
        return WOLFSSL_FAILURE;
7452
    }
7453
7454
    if (x509->holderEntityName != NULL) {
7455
        /* print issuer header */
7456
        if (wolfSSL_BIO_write(bio, holder_name_hdr,
7457
            (int)XSTRLEN(holder_name_hdr)) <= 0) {
7458
            return WOLFSSL_FAILURE;
7459
        }
7460
7461
        if (X509_ACERT_print_name_entry(bio, x509->holderEntityName, 1)
7462
                != WOLFSSL_SUCCESS) {
7463
            return WOLFSSL_FAILURE;
7464
        }
7465
    }
7466
7467
    if (x509->holderIssuerName != NULL) {
7468
        /* print issuer header */
7469
        if (wolfSSL_BIO_write(bio, holder_issuer_hdr,
7470
            (int)XSTRLEN(holder_issuer_hdr)) <= 0) {
7471
            return WOLFSSL_FAILURE;
7472
        }
7473
7474
        if (X509_ACERT_print_name_entry(bio, x509->holderIssuerName, 1)
7475
            != WOLFSSL_SUCCESS) {
7476
            return WOLFSSL_FAILURE;
7477
        }
7478
    }
7479
7480
    if (x509->holderSerialSz > 0) {
7481
        X509PrintSerial_ex(bio, x509->holderSerial, x509->holderSerialSz,
7482
                           1, 12);
7483
    }
7484
7485
    /* print issuer header */
7486
    if (wolfSSL_BIO_write(bio, attcert_issuer_hdr,
7487
        (int)XSTRLEN(attcert_issuer_hdr)) <= 0) {
7488
        return WOLFSSL_FAILURE;
7489
    }
7490
7491
    if (x509->AttCertIssuerName != NULL) {
7492
        if (X509_ACERT_print_name_entry(bio, x509->AttCertIssuerName, 1)
7493
                != WOLFSSL_SUCCESS) {
7494
            return WOLFSSL_FAILURE;
7495
        }
7496
    }
7497
    else {
7498
        const char * msg = " Issuer type not supported.\n";
7499
        if (wolfSSL_BIO_write(bio, msg, (int)XSTRLEN(msg)) <= 0) {
7500
            return WOLFSSL_FAILURE;
7501
        }
7502
    }
7503
7504
    #ifndef NO_ASN_TIME
7505
    /* print validity */
7506
    if (X509PrintValidity(bio, &x509->notBefore, &x509->notAfter, 8)
7507
        != WOLFSSL_SUCCESS) {
7508
        return WOLFSSL_FAILURE;
7509
    }
7510
    #endif /* NO_ASN_TIME */
7511
7512
    /* print raw attributes */
7513
    if (x509->rawAttr && x509->rawAttrLen > 0) {
7514
        char attr_hdr[128]; /* buffer for XSNPRINTF */
7515
7516
        if (XSNPRINTF(attr_hdr, 128, "%*s%s: %d bytes\n", 8, "",
7517
                    "Attributes", x509->rawAttrLen) >= 128) {
7518
            return WOLFSSL_FAILURE;
7519
        }
7520
7521
        if (wolfSSL_BIO_write(bio, attr_hdr, (int)XSTRLEN(attr_hdr)) <= 0) {
7522
                return WOLFSSL_FAILURE;
7523
        }
7524
    }
7525
7526
    /* print out sig algo and signature */
7527
    if (X509AcertPrintSignature(bio, x509, 0, 8) != WOLFSSL_SUCCESS) {
7528
        return WOLFSSL_FAILURE;
7529
    }
7530
7531
    /* done with print out */
7532
    if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
7533
        return WOLFSSL_FAILURE;
7534
    }
7535
7536
    return WOLFSSL_SUCCESS;
7537
}
7538
#endif /* WOLFSSL_ACERT */
7539
7540
#ifndef NO_FILESYSTEM
7541
int wolfSSL_X509_print_fp(XFILE fp, WOLFSSL_X509 *x509)
7542
{
7543
    WOLFSSL_BIO* bio;
7544
    int ret;
7545
7546
    WOLFSSL_ENTER("wolfSSL_X509_print_fp");
7547
7548
    if (!fp || !x509) {
7549
        WOLFSSL_MSG("Bad parameter");
7550
        return WOLFSSL_FAILURE;
7551
    }
7552
7553
    if (!(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file()))) {
7554
        WOLFSSL_MSG("wolfSSL_BIO_new wolfSSL_BIO_s_file error");
7555
        return WOLFSSL_FAILURE;
7556
    }
7557
7558
    if (wolfSSL_BIO_set_fp(bio, fp, WOLFSSL_BIO_NOCLOSE) != WOLFSSL_SUCCESS) {
7559
        WOLFSSL_MSG("wolfSSL_BIO_set_fp error");
7560
        wolfSSL_BIO_free(bio);
7561
        return WOLFSSL_FAILURE;
7562
    }
7563
7564
    ret = wolfSSL_X509_print(bio, x509);
7565
7566
    wolfSSL_BIO_free(bio);
7567
7568
    return ret;
7569
}
7570
#endif /* NO_FILESYSTEM */
7571
7572
#endif /* XSNPRINTF */
7573
7574
int wolfSSL_X509_signature_print(WOLFSSL_BIO *bp,
7575
        const WOLFSSL_X509_ALGOR *sigalg, const WOLFSSL_ASN1_STRING *sig)
7576
{
7577
    int length = 0;
7578
    word32 idx = 0;
7579
    int i;
7580
7581
    (void)sig;
7582
7583
    WOLFSSL_ENTER("wolfSSL_X509_signature_print");
7584
7585
    if (!bp || !sigalg) {
7586
        WOLFSSL_MSG("Bad parameter");
7587
        return WOLFSSL_FAILURE;
7588
    }
7589
7590
    if ((sigalg->algorithm->obj == NULL) ||
7591
        (sigalg->algorithm->obj[idx] != ASN_OBJECT_ID)) {
7592
        WOLFSSL_MSG("Bad ASN1 Object");
7593
        return WOLFSSL_FAILURE;
7594
    }
7595
    idx++; /* skip object id */
7596
7597
    if (GetLength((const byte*)sigalg->algorithm->obj, &idx, &length,
7598
                  sigalg->algorithm->objSz) < 0 || length < 0) {
7599
        return WOLFSSL_FAILURE;
7600
    }
7601
7602
    if (wolfSSL_BIO_puts(bp, "    Raw Signature Algorithm:") <= 0) {
7603
        WOLFSSL_MSG("wolfSSL_BIO_puts error");
7604
        return WOLFSSL_FAILURE;
7605
    }
7606
7607
    for (i = 0; i < length; ++i) {
7608
        char hex_digits[4];
7609
        if (XSNPRINTF(hex_digits, sizeof(hex_digits), "%c%02X", i>0 ? ':' : ' ',
7610
                  (unsigned int)sigalg->algorithm->obj[idx+i])
7611
            >= (int)sizeof(hex_digits))
7612
        {
7613
            WOLFSSL_MSG("buffer overrun");
7614
            return WOLFSSL_FAILURE;
7615
        }
7616
        if (wolfSSL_BIO_puts(bp, hex_digits) <= 0)
7617
            return WOLFSSL_FAILURE;
7618
    }
7619
7620
    if (wolfSSL_BIO_puts(bp, "\n") <= 0)
7621
        return WOLFSSL_FAILURE;
7622
7623
    return WOLFSSL_SUCCESS;
7624
}
7625
#endif /* !NO_BIO */
7626
7627
#ifndef NO_WOLFSSL_STUB
7628
void wolfSSL_X509_get0_signature(const WOLFSSL_ASN1_BIT_STRING **psig,
7629
        const WOLFSSL_X509_ALGOR **palg, const WOLFSSL_X509 *x509)
7630
{
7631
    (void)psig;
7632
    (void)palg;
7633
    (void)x509;
7634
    WOLFSSL_STUB("wolfSSL_X509_get0_signature");
7635
}
7636
#endif
7637
7638
#endif /* OPENSSL_EXTRA */
7639
7640
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
7641
const char* wolfSSL_X509_verify_cert_error_string(long err)
7642
{
7643
    return wolfSSL_ERR_reason_error_string((unsigned long)err);
7644
}
7645
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
7646
7647
#ifdef OPENSSL_EXTRA
7648
7649
/* Add directory path that will be used for loading certs and CRLs
7650
 * which have the <hash>.rn name format.
7651
 * type may be WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
7652
 * returns WOLFSSL_SUCCESS on successful, otherwise negative or zero. */
7653
int wolfSSL_X509_LOOKUP_add_dir(WOLFSSL_X509_LOOKUP* lookup, const char* dir,
7654
                               long type)
7655
{
7656
    return wolfSSL_X509_LOOKUP_ctrl(lookup, WOLFSSL_X509_L_ADD_DIR, dir, type,
7657
                                    NULL);
7658
}
7659
7660
int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP* lookup,
7661
                                 const char* file, long type)
7662
{
7663
#if !defined(NO_FILESYSTEM) && \
7664
    (defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM))
7665
    int           ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
7666
    XFILE         fp;
7667
    long          sz;
7668
    byte*         pem = NULL;
7669
    byte*         curr = NULL;
7670
    byte*         prev = NULL;
7671
    const char* header = NULL;
7672
    const char* footer = NULL;
7673
7674
    if (type != WOLFSSL_FILETYPE_PEM)
7675
        return WS_RETURN_CODE(BAD_FUNC_ARG, (int)WOLFSSL_FAILURE);
7676
7677
    fp = XFOPEN(file, "rb");
7678
    if (fp == XBADFILE)
7679
        return WS_RETURN_CODE(BAD_FUNC_ARG, (int)WOLFSSL_FAILURE);
7680
7681
    if (XFSEEK(fp, 0, XSEEK_END) != 0) {
7682
        XFCLOSE(fp);
7683
        return WS_RETURN_CODE(WOLFSSL_BAD_FILE,WOLFSSL_FAILURE);
7684
    }
7685
    sz = XFTELL(fp);
7686
    if (XFSEEK(fp, 0, XSEEK_SET) != 0) {
7687
        XFCLOSE(fp);
7688
        return WS_RETURN_CODE(WOLFSSL_BAD_FILE,WOLFSSL_FAILURE);
7689
    }
7690
7691
    if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
7692
        WOLFSSL_MSG("X509_LOOKUP_load_file size error");
7693
        goto end;
7694
    }
7695
7696
    pem = (byte*)XMALLOC(sz, 0, DYNAMIC_TYPE_PEM);
7697
    if (pem == NULL) {
7698
        ret = MEMORY_ERROR;
7699
        goto end;
7700
    }
7701
7702
    /* Read in file which may be CRLs or certificates. */
7703
    if (XFREAD(pem, (size_t)sz, 1, fp) != 1)
7704
        goto end;
7705
7706
    prev = curr = pem;
7707
    do {
7708
        /* get PEM header and footer based on type */
7709
        if (wc_PemGetHeaderFooter(CRL_TYPE, &header, &footer) == 0 &&
7710
                XSTRNSTR((char*)curr, header, (unsigned int)sz) != NULL) {
7711
#ifdef HAVE_CRL
7712
            WOLFSSL_CERT_MANAGER* cm = lookup->store->cm;
7713
7714
            if (cm->crl == NULL) {
7715
                if (wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECK)
7716
                    != WOLFSSL_SUCCESS) {
7717
                    WOLFSSL_MSG("Enable CRL failed");
7718
                    goto end;
7719
                }
7720
            }
7721
7722
            ret = BufferLoadCRL(cm->crl, curr, sz, WOLFSSL_FILETYPE_PEM,
7723
                NO_VERIFY);
7724
            if (ret != WOLFSSL_SUCCESS)
7725
                goto end;
7726
#endif
7727
            curr = (byte*)XSTRNSTR((char*)curr, footer, (unsigned int)sz);
7728
        }
7729
        else if (wc_PemGetHeaderFooter(CERT_TYPE, &header, &footer) == 0 &&
7730
                XSTRNSTR((char*)curr, header, (unsigned int)sz) != NULL) {
7731
            ret = X509StoreLoadCertBuffer(lookup->store, curr,
7732
                                        (word32)sz, WOLFSSL_FILETYPE_PEM);
7733
            if (ret != WOLFSSL_SUCCESS)
7734
                goto end;
7735
            curr = (byte*)XSTRNSTR((char*)curr, footer, (unsigned int)sz);
7736
        }
7737
        else
7738
            goto end;
7739
7740
        if (curr == NULL)
7741
            goto end;
7742
7743
        curr++;
7744
        sz -= (long)(curr - prev);
7745
        prev = curr;
7746
    }
7747
    while (ret == WOLFSSL_SUCCESS);
7748
7749
end:
7750
    XFREE(pem, 0, DYNAMIC_TYPE_PEM);
7751
    XFCLOSE(fp);
7752
    return WS_RETURN_CODE(ret, (int)WOLFSSL_FAILURE);
7753
#else
7754
    (void)lookup;
7755
    (void)file;
7756
    (void)type;
7757
    return WS_RETURN_CODE(WOLFSSL_FAILURE,WOLFSSL_FAILURE);
7758
#endif
7759
}
7760
7761
WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_hash_dir(void)
7762
{
7763
    /* Method implementation in functions. */
7764
    static WOLFSSL_X509_LOOKUP_METHOD meth = { 1 };
7765
    return &meth;
7766
}
7767
7768
WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_file(void)
7769
{
7770
    /* Method implementation in functions. */
7771
    static WOLFSSL_X509_LOOKUP_METHOD meth = { 0 };
7772
    return &meth;
7773
}
7774
7775
/* set directory path to load certificate or CRL which have the hash.N form */
7776
/* for late use                                                             */
7777
/* @param ctx    a pointer to WOLFSSL_BY_DIR structure                      */
7778
/* @param argc   directory path                                             */
7779
/* @param argl   file type, either WOLFSSL_FILETYPE_PEM or                  */
7780
/*                                          WOLFSSL_FILETYPE_ASN1           */
7781
/* @return WOLFSSL_SUCCESS on successful, otherwise negative or zero        */
7782
static int x509AddCertDir(WOLFSSL_BY_DIR *ctx, const char *argc, long argl)
7783
{
7784
#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
7785
    WOLFSSL_BY_DIR_entry *entry;
7786
    size_t pathLen;
7787
    int i, num;
7788
    const char* c;
7789
#ifdef WOLFSSL_SMALL_STACK
7790
    char *buf;
7791
#else
7792
    char  buf[MAX_FILENAME_SZ];
7793
#endif
7794
7795
    WOLFSSL_ENTER("x509AddCertDir");
7796
7797
    pathLen = 0;
7798
    c = argc;
7799
    /* sanity check, zero length */
7800
    if (ctx == NULL || c == NULL || *c == '\0')
7801
        return WOLFSSL_FAILURE;
7802
7803
#ifdef WOLFSSL_SMALL_STACK
7804
    buf = (char*)XMALLOC(MAX_FILENAME_SZ, NULL, DYNAMIC_TYPE_OPENSSL);
7805
    if (buf == NULL) {
7806
        WOLFSSL_LEAVE("x509AddCertDir", MEMORY_E);
7807
        return MEMORY_E;
7808
    }
7809
#endif
7810
7811
    XMEMSET(buf, 0, MAX_FILENAME_SZ);
7812
7813
    do {
7814
        if (*c == SEPARATOR_CHAR || *c == '\0') {
7815
7816
            num = wolfSSL_sk_BY_DIR_entry_num(ctx->dir_entry);
7817
7818
            for (i=0; i<num; i++) {
7819
7820
                entry = wolfSSL_sk_BY_DIR_entry_value(ctx->dir_entry, i);
7821
7822
                if (XSTRLEN(entry->dir_name) == pathLen &&
7823
                    XSTRNCMP(entry->dir_name, buf, pathLen) == 0) {
7824
                    WOLFSSL_MSG("dir entry found");
7825
                    break;
7826
                }
7827
            }
7828
7829
            if (num == -1 || i == num) {
7830
                WOLFSSL_MSG("no entry found");
7831
7832
                if (ctx->dir_entry == NULL) {
7833
                    ctx->dir_entry = wolfSSL_sk_BY_DIR_entry_new_null();
7834
7835
                    if (ctx->dir_entry == NULL) {
7836
                        WOLFSSL_MSG("failed to allocate dir_entry");
7837
                        #ifdef WOLFSSL_SMALL_STACK
7838
                            XFREE(buf, 0, DYNAMIC_TYPE_OPENSSL);
7839
                        #endif
7840
                        return 0;
7841
                    }
7842
                }
7843
7844
                entry = wolfSSL_BY_DIR_entry_new();
7845
                if (entry == NULL) {
7846
                    WOLFSSL_MSG("failed to allocate dir entry");
7847
                    #ifdef WOLFSSL_SMALL_STACK
7848
                        XFREE(buf, 0, DYNAMIC_TYPE_OPENSSL);
7849
                    #endif
7850
                    return 0;
7851
                }
7852
                entry->dir_type = (int)argl;
7853
                entry->dir_name = (char*)XMALLOC(pathLen + 1/* \0 termination*/
7854
                                                , NULL, DYNAMIC_TYPE_OPENSSL);
7855
                entry->hashes = wolfSSL_sk_BY_DIR_HASH_new_null();
7856
                if (entry->dir_name == NULL || entry->hashes == NULL) {
7857
                    WOLFSSL_MSG("failed to allocate dir name");
7858
                    wolfSSL_BY_DIR_entry_free(entry);
7859
                    #ifdef WOLFSSL_SMALL_STACK
7860
                        XFREE(buf, 0, DYNAMIC_TYPE_OPENSSL);
7861
                    #endif
7862
                    return 0;
7863
                }
7864
7865
                XSTRNCPY(entry->dir_name, buf, pathLen);
7866
                entry->dir_name[pathLen] = '\0';
7867
7868
                if (wolfSSL_sk_BY_DIR_entry_push(ctx->dir_entry, entry) <= 0) {
7869
                    wolfSSL_BY_DIR_entry_free(entry);
7870
                    #ifdef WOLFSSL_SMALL_STACK
7871
                        XFREE(buf, 0, DYNAMIC_TYPE_OPENSSL);
7872
                    #endif
7873
                    return 0;
7874
                }
7875
            }
7876
            /* skip separator */
7877
            if (*c == SEPARATOR_CHAR) c++;
7878
7879
            pathLen = 0;
7880
            XMEMSET(buf, 0, MAX_FILENAME_SZ);
7881
        }
7882
        buf[pathLen++] = *c;
7883
7884
    } while(*c++ != '\0');
7885
7886
#ifdef WOLFSSL_SMALL_STACK
7887
    XFREE(buf, 0, DYNAMIC_TYPE_OPENSSL);
7888
#endif
7889
7890
    return WOLFSSL_SUCCESS;
7891
#else
7892
    (void)ctx;
7893
    (void)argc;
7894
    (void)argl;
7895
    return WOLFSSL_NOT_IMPLEMENTED;
7896
#endif
7897
}
7898
7899
/* set additional data to X509_LOOKUP                                   */
7900
/* @param ctx    a pointer to X509_LOOKUP structure                     */
7901
/* @param cmd    control command :                                      */
7902
/*               X509_L_FILE_LOAD, X509_L_ADD_DIR X509_L_ADD_STORE or   */
7903
/*               X509_L_LOAD_STORE                                      */
7904
/* @param argc   arguments for the control command                      */
7905
/* @param argl   arguments for the control command                      */
7906
/* @param **ret  return value of the control command                    */
7907
/* @return WOLFSSL_SUCCESS on successful, otherwise WOLFSSL_FAILURE     */
7908
/* note: WOLFSSL_X509_L_ADD_STORE and WOLFSSL_X509_L_LOAD_STORE have not*/
7909
/*       yet implemented. It returns WOLFSSL_NOT_IMPLEMENTED            */
7910
/*       when those control commands are passed.                        */
7911
int wolfSSL_X509_LOOKUP_ctrl(WOLFSSL_X509_LOOKUP *ctx, int cmd,
7912
        const char *argc, long argl, char **ret)
7913
{
7914
    int lret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
7915
7916
    WOLFSSL_ENTER("wolfSSL_X509_LOOKUP_ctrl");
7917
#if !defined(NO_FILESYSTEM)
7918
    if (ctx != NULL) {
7919
        switch (cmd) {
7920
        case WOLFSSL_X509_L_FILE_LOAD:
7921
            /* expects to return a number of processed cert or crl file */
7922
            lret = wolfSSL_X509_load_cert_crl_file(ctx, argc, (int)argl) > 0 ?
7923
                            WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
7924
            break;
7925
        case WOLFSSL_X509_L_ADD_DIR:
7926
            /* store directory location to use it later */
7927
#if !defined(NO_WOLFSSL_DIR)
7928
            lret = x509AddCertDir(ctx->dirs, argc, argl);
7929
#else
7930
            (void)x509AddCertDir;
7931
            lret = WOLFSSL_NOT_IMPLEMENTED;
7932
#endif
7933
            break;
7934
        case WOLFSSL_X509_L_ADD_STORE:
7935
        case WOLFSSL_X509_L_LOAD_STORE:
7936
            return WOLFSSL_NOT_IMPLEMENTED;
7937
7938
        default:
7939
            break;
7940
        }
7941
    }
7942
    (void)ret;
7943
#else
7944
    (void)ctx;
7945
    (void)argc;
7946
    (void)argl;
7947
    (void)ret;
7948
    (void)cmd;
7949
    (void)x509AddCertDir;
7950
    lret = WOLFSSL_NOT_IMPLEMENTED;
7951
#endif
7952
    return lret;
7953
}
7954
7955
7956
#if defined(WOLFSSL_CERT_GEN)
7957
static int wolfssl_x509_make_der(WOLFSSL_X509* x509, int req,
7958
        unsigned char* der, int* derSz, int includeSig);
7959
#endif
7960
7961
#ifdef WOLFSSL_CERT_GEN
7962
#ifndef NO_BIO
7963
/* Converts the X509 to DER format and outputs it into bio.
7964
 *
7965
 * bio  is the structure to hold output DER
7966
 * x509 certificate to create DER from
7967
 * req  if set then a CSR is generated
7968
 *
7969
 * returns WOLFSSL_SUCCESS on success
7970
 */
7971
static int loadX509orX509REQFromBio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
7972
    int req)
7973
{
7974
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
7975
    /* Get large buffer to hold cert der */
7976
    int derSz = X509_BUFFER_SZ;
7977
#ifdef WOLFSSL_SMALL_STACK
7978
    byte* der;
7979
#else
7980
    byte der[X509_BUFFER_SZ];
7981
#endif
7982
    WOLFSSL_ENTER("wolfSSL_i2d_X509_bio");
7983
7984
    if (bio == NULL || x509 == NULL) {
7985
        return WOLFSSL_FAILURE;
7986
    }
7987
7988
#ifdef WOLFSSL_SMALL_STACK
7989
    der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7990
    if (!der) {
7991
        WOLFSSL_MSG("malloc failed");
7992
        return WOLFSSL_FAILURE;
7993
    }
7994
#endif
7995
7996
    if (wolfssl_x509_make_der(x509, req, der, &derSz, 1) != WOLFSSL_SUCCESS) {
7997
        goto cleanup;
7998
    }
7999
8000
    if (wolfSSL_BIO_write(bio, der, derSz) != derSz) {
8001
        goto cleanup;
8002
    }
8003
8004
    ret = WOLFSSL_SUCCESS;
8005
cleanup:
8006
    #ifdef WOLFSSL_SMALL_STACK
8007
    XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8008
    #endif
8009
8010
    return ret;
8011
}
8012
8013
/* Converts the X509 to DER format and outputs it into bio.
8014
 *
8015
 * bio  is the structure to hold output DER
8016
 * x509 certificate to create DER from
8017
 *
8018
 * returns WOLFSSL_SUCCESS on success
8019
 */
8020
int wolfSSL_i2d_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
8021
{
8022
    return loadX509orX509REQFromBio(bio, x509, 0);
8023
}
8024
8025
#ifdef WOLFSSL_CERT_REQ
8026
int wolfSSL_i2d_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
8027
{
8028
    return loadX509orX509REQFromBio(bio, x509, 1);
8029
}
8030
#endif /* WOLFSSL_CERT_REQ */
8031
#endif /* !NO_BIO */
8032
#endif /* WOLFSSL_CERT_GEN */
8033
8034
/* Converts an internal structure to a DER buffer
8035
 *
8036
 * x509 structure to get DER buffer from
8037
 * out  buffer to hold result. If NULL then *out is NULL then a new buffer is
8038
 *      created.
8039
 *
8040
 * returns the size of the DER result on success
8041
 */
8042
int wolfSSL_i2d_X509(WOLFSSL_X509* x509, unsigned char** out)
8043
{
8044
    const unsigned char* der;
8045
    int derSz = 0;
8046
    int advance = 1;
8047
8048
    WOLFSSL_ENTER("wolfSSL_i2d_X509");
8049
8050
    if (x509 == NULL) {
8051
        WOLFSSL_LEAVE("wolfSSL_i2d_X509", BAD_FUNC_ARG);
8052
        return BAD_FUNC_ARG;
8053
    }
8054
8055
    der = wolfSSL_X509_get_der(x509, &derSz);
8056
    if (der == NULL) {
8057
        WOLFSSL_LEAVE("wolfSSL_i2d_X509", MEMORY_E);
8058
        return MEMORY_E;
8059
    }
8060
8061
    if (out != NULL && *out == NULL) {
8062
        *out = (unsigned char*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL);
8063
        if (*out == NULL) {
8064
            WOLFSSL_LEAVE("wolfSSL_i2d_X509", MEMORY_E);
8065
            return MEMORY_E;
8066
        }
8067
        advance = 0;
8068
    }
8069
8070
    if (out != NULL) {
8071
        XMEMCPY(*out, der, derSz);
8072
        if (advance)
8073
            *out += derSz;
8074
    }
8075
8076
    WOLFSSL_LEAVE("wolfSSL_i2d_X509", derSz);
8077
    return derSz;
8078
}
8079
8080
#ifdef WOLFSSL_DUAL_ALG_CERTS
8081
/* Generate a der preTBS from a decoded cert, and write
8082
 * to buffer.
8083
 *
8084
 * @param [in]  cert  The decoded cert to parse.
8085
 * @param [out] der   The der buffer to write in.
8086
 * @param [in]  derSz The der buffer size.
8087
 *
8088
 * @return  preTBS der size on success.
8089
 * */
8090
int wc_GeneratePreTBS(DecodedCert* cert, byte *der, int derSz) {
8091
    int ret = 0;
8092
    WOLFSSL_X509 *x = NULL;
8093
    byte certIsCSR = 0;
8094
8095
    WOLFSSL_ENTER("wc_GeneratePreTBS");
8096
8097
    if ((cert == NULL) || (der == NULL) || (derSz <= 0)) {
8098
        return BAD_FUNC_ARG;
8099
    }
8100
8101
#ifdef WOLFSSL_CERT_REQ
8102
    certIsCSR = cert->isCSR;
8103
#endif
8104
8105
    x = wolfSSL_X509_new();
8106
    if (x == NULL) {
8107
        ret = MEMORY_E;
8108
    }
8109
    else {
8110
        ret = CopyDecodedToX509(x, cert);
8111
    }
8112
8113
    if (ret == 0) {
8114
        /* Remove the altsigval extension. */
8115
        XFREE(x->altSigValDer, x->heap, DYNAMIC_TYPE_X509_EXT);
8116
        x->altSigValDer = NULL;
8117
        x->altSigValLen = 0;
8118
        /* Remove sigOID so it won't be encoded. */
8119
        x->sigOID = 0;
8120
        /* We now have a PreTBS. Encode it. */
8121
        ret = wolfssl_x509_make_der(x, certIsCSR, der, &derSz, 0);
8122
        if (ret == WOLFSSL_SUCCESS) {
8123
            ret = derSz;
8124
        }
8125
    }
8126
8127
    if (x != NULL) {
8128
        wolfSSL_X509_free(x);
8129
        x = NULL;
8130
    }
8131
8132
    return ret;
8133
}
8134
#endif /* WOLFSSL_DUAL_ALG_CERTS */
8135
8136
#ifndef NO_BIO
8137
/**
8138
 * Converts the DER from bio and creates a WOLFSSL_X509 structure from it.
8139
 * @param bio  is the structure holding DER
8140
 * @param x509 certificate to create from DER. Can be NULL
8141
 * @param req  1 for a CSR and 0 for a x509 cert
8142
 * @return pointer to WOLFSSL_X509 structure on success and NULL on fail
8143
 */
8144
static WOLFSSL_X509* d2i_X509orX509REQ_bio(WOLFSSL_BIO* bio,
8145
                                            WOLFSSL_X509** x509, int req)
8146
{
8147
    WOLFSSL_X509* localX509 = NULL;
8148
    byte* mem  = NULL;
8149
    int    size;
8150
8151
    WOLFSSL_ENTER("wolfSSL_d2i_X509_bio");
8152
8153
    if (bio == NULL) {
8154
        WOLFSSL_MSG("Bad Function Argument bio is NULL");
8155
        return NULL;
8156
    }
8157
8158
    size = wolfSSL_BIO_get_len(bio);
8159
    if (size <= 0) {
8160
        WOLFSSL_MSG("wolfSSL_BIO_get_len error. Possibly no pending data.");
8161
        WOLFSSL_ERROR(WOLFSSL_ASN1_R_HEADER_TOO_LONG_E);
8162
        return NULL;
8163
    }
8164
8165
    if (!(mem = (byte*)XMALLOC(size, NULL, DYNAMIC_TYPE_OPENSSL))) {
8166
        WOLFSSL_MSG("malloc error");
8167
        return NULL;
8168
    }
8169
8170
    if ((size = wolfSSL_BIO_read(bio, mem, size)) == 0) {
8171
        WOLFSSL_MSG("wolfSSL_BIO_read error");
8172
        XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL);
8173
        return NULL;
8174
    }
8175
8176
    if (req) {
8177
#ifdef WOLFSSL_CERT_REQ
8178
        localX509 = wolfSSL_X509_REQ_d2i(NULL, mem, size);
8179
#else
8180
        WOLFSSL_MSG("CSR not compiled in");
8181
#endif
8182
    }
8183
    else {
8184
        localX509 = wolfSSL_X509_d2i_ex(NULL, mem, size, bio->heap);
8185
    }
8186
    if (localX509 == NULL) {
8187
        WOLFSSL_MSG("wolfSSL_X509_d2i error");
8188
        XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL);
8189
        return NULL;
8190
    }
8191
8192
    if (x509 != NULL) {
8193
        *x509 = localX509;
8194
    }
8195
8196
    XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL);
8197
    return localX509;
8198
}
8199
8200
WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509)
8201
{
8202
    return d2i_X509orX509REQ_bio(bio, x509, 0);
8203
}
8204
8205
#ifdef WOLFSSL_CERT_REQ
8206
WOLFSSL_X509* wolfSSL_d2i_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509)
8207
{
8208
    return d2i_X509orX509REQ_bio(bio, x509, 1);
8209
}
8210
#endif
8211
#endif /* !NO_BIO */
8212
8213
#endif /* OPENSSL_EXTRA */
8214
8215
#ifdef OPENSSL_EXTRA
8216
/* Use the public key to verify the signature. Note: this only verifies
8217
 * the certificate signature.
8218
 * returns WOLFSSL_SUCCESS on successful signature verification */
8219
static int verifyX509orX509REQ(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey,
8220
    int req)
8221
{
8222
    int ret;
8223
    const byte* der;
8224
    int derSz = 0;
8225
    int type;
8226
8227
    (void)req;
8228
8229
    if (x509 == NULL || pkey == NULL) {
8230
        return WOLFSSL_FATAL_ERROR;
8231
    }
8232
8233
    der = wolfSSL_X509_get_der(x509, &derSz);
8234
    if (der == NULL) {
8235
        WOLFSSL_MSG("Error getting WOLFSSL_X509 DER");
8236
        return WOLFSSL_FATAL_ERROR;
8237
    }
8238
8239
    switch (pkey->type) {
8240
        case WC_EVP_PKEY_RSA:
8241
            type = RSAk;
8242
            break;
8243
8244
        case WC_EVP_PKEY_EC:
8245
            type = ECDSAk;
8246
            break;
8247
8248
        case WC_EVP_PKEY_DSA:
8249
            type = DSAk;
8250
            break;
8251
8252
        default:
8253
            WOLFSSL_MSG("Unknown pkey key type");
8254
            return WOLFSSL_FATAL_ERROR;
8255
    }
8256
8257
#ifdef WOLFSSL_CERT_REQ
8258
    if (req)
8259
        ret = CheckCSRSignaturePubKey(der, (word32)derSz, x509->heap,
8260
                (unsigned char*)pkey->pkey.ptr, pkey->pkey_sz, type);
8261
    else
8262
#endif
8263
        ret = CheckCertSignaturePubKey(der, (word32)derSz, x509->heap,
8264
                (unsigned char*)pkey->pkey.ptr, pkey->pkey_sz, type);
8265
    if (ret == 0) {
8266
        return WOLFSSL_SUCCESS;
8267
    }
8268
    return WOLFSSL_FAILURE;
8269
}
8270
8271
int wolfSSL_X509_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey)
8272
{
8273
    return verifyX509orX509REQ(x509, pkey, 0);
8274
}
8275
8276
#ifdef WOLFSSL_CERT_REQ
8277
int wolfSSL_X509_REQ_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey)
8278
{
8279
    return verifyX509orX509REQ(x509, pkey, 1);
8280
}
8281
#endif /* WOLFSSL_CERT_REQ */
8282
8283
#if !defined(NO_FILESYSTEM)
8284
static void *wolfSSL_d2i_X509_fp_ex(XFILE file, void **x509, int type)
8285
{
8286
    void *newx509 = NULL;
8287
    byte *fileBuffer = NULL;
8288
    long sz = 0;
8289
8290
    /* init variable */
8291
    if (x509)
8292
        *x509 = NULL;
8293
8294
    /* argument check */
8295
    if (file == XBADFILE) {
8296
        return NULL;
8297
    }
8298
8299
    /* determine file size */
8300
    if (XFSEEK(file, 0, XSEEK_END) != 0) {
8301
        return NULL;
8302
    }
8303
    sz = XFTELL(file);
8304
    if (XFSEEK(file, 0, XSEEK_SET) != 0) {
8305
        return NULL;
8306
    }
8307
8308
    if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
8309
        WOLFSSL_MSG("d2i_X509_fp_ex file size error");
8310
        return NULL;
8311
    }
8312
8313
    fileBuffer = (byte *)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
8314
    if (fileBuffer != NULL) {
8315
        if ((long)XFREAD(fileBuffer, 1, (size_t)sz, file) != sz) {
8316
            WOLFSSL_MSG("File read failed");
8317
            goto err_exit;
8318
        }
8319
        if (type == CERT_TYPE) {
8320
            newx509 = (void *)wolfSSL_X509_d2i(NULL, fileBuffer, (int)sz);
8321
        }
8322
    #ifdef HAVE_CRL
8323
        else if (type == CRL_TYPE) {
8324
            newx509 = (void *)wolfSSL_d2i_X509_CRL(NULL, fileBuffer, (int)sz);
8325
        }
8326
    #endif
8327
    #ifdef WOLFSSL_CERT_REQ
8328
        else if (type == CERTREQ_TYPE) {
8329
             newx509 = (void *)wolfSSL_X509_REQ_d2i(NULL, fileBuffer, (int)sz);
8330
        }
8331
    #endif
8332
    #if !defined(NO_ASN) && !defined(NO_PWDBASED) && defined(HAVE_PKCS12)
8333
        else if (type == PKCS12_TYPE) {
8334
            if ((newx509 = wc_PKCS12_new()) == NULL) {
8335
                goto err_exit;
8336
            }
8337
            if (wc_d2i_PKCS12(fileBuffer, (word32)sz,
8338
                                                     (WC_PKCS12*)newx509) < 0) {
8339
                goto err_exit;
8340
            }
8341
        }
8342
    #endif
8343
        else {
8344
            goto err_exit;
8345
        }
8346
        if (newx509 == NULL) {
8347
            WOLFSSL_MSG("X509 failed");
8348
            goto err_exit;
8349
        }
8350
    }
8351
8352
    if (x509)
8353
        *x509 = newx509;
8354
8355
    goto _exit;
8356
8357
err_exit:
8358
#if !defined(NO_ASN) && !defined(NO_PWDBASED) && defined(HAVE_PKCS12)
8359
    if ((newx509 != NULL) && (type == PKCS12_TYPE)) {
8360
        wc_PKCS12_free((WC_PKCS12*)newx509);
8361
        newx509 = NULL;
8362
    }
8363
#endif
8364
_exit:
8365
    XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
8366
8367
    return newx509;
8368
}
8369
8370
#ifdef WOLFSSL_CERT_REQ
8371
WOLFSSL_X509* wolfSSL_d2i_X509_REQ_fp(XFILE fp, WOLFSSL_X509 **req)
8372
{
8373
    return (WOLFSSL_X509 *)wolfSSL_d2i_X509_fp_ex(fp, (void **)req,
8374
                                                  CERTREQ_TYPE);
8375
}
8376
#endif /* WOLFSSL_CERT_REQ */
8377
8378
WOLFSSL_X509 *wolfSSL_d2i_X509_fp(XFILE fp, WOLFSSL_X509 **x509)
8379
{
8380
    WOLFSSL_ENTER("wolfSSL_d2i_X509_fp");
8381
    return (WOLFSSL_X509 *)wolfSSL_d2i_X509_fp_ex(fp, (void **)x509, CERT_TYPE);
8382
}
8383
8384
/* load certificate or CRL file, and add it to the STORE           */
8385
/* @param ctx    a pointer to X509_LOOKUP structure                */
8386
/* @param file   file name to load                                 */
8387
/* @param type   WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1     */
8388
/* @return a number of loading CRL or certificate, otherwise zero  */
8389
WOLFSSL_API int wolfSSL_X509_load_cert_crl_file(WOLFSSL_X509_LOOKUP *ctx,
8390
    const char *file, int type)
8391
{
8392
    WOLFSSL_X509 *x509 = NULL;
8393
8394
    int cnt = 0;
8395
8396
    WOLFSSL_ENTER("wolfSSL_X509_load_cert_crl_file");
8397
8398
    /* stanity check */
8399
    if (ctx == NULL || file == NULL) {
8400
        WOLFSSL_MSG("bad arguments");
8401
        return 0;
8402
    }
8403
8404
    if (type != WOLFSSL_FILETYPE_PEM) {
8405
        x509 = wolfSSL_X509_load_certificate_file(file, type);
8406
        if (x509 != NULL) {
8407
            if (wolfSSL_X509_STORE_add_cert(ctx->store, x509)
8408
                                    == WOLFSSL_SUCCESS) {
8409
                cnt++;
8410
            }
8411
            else {
8412
                WOLFSSL_MSG("wolfSSL_X509_STORE_add_cert error");
8413
            }
8414
            wolfSSL_X509_free(x509);
8415
            x509 = NULL;
8416
        }
8417
        else {
8418
            WOLFSSL_MSG("wolfSSL_X509_load_certificate_file error");
8419
        }
8420
8421
    }
8422
    else {
8423
#if defined(OPENSSL_ALL)
8424
    #if !defined(NO_BIO)
8425
        STACK_OF(WOLFSSL_X509_INFO) *info;
8426
        WOLFSSL_X509_INFO *info_tmp;
8427
        int i;
8428
        int num = 0;
8429
        WOLFSSL_BIO *bio = wolfSSL_BIO_new_file(file, "rb");
8430
        if (!bio) {
8431
            WOLFSSL_MSG("wolfSSL_BIO_new error");
8432
            return cnt;
8433
        }
8434
8435
        info = wolfSSL_PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
8436
8437
        wolfSSL_BIO_free(bio);
8438
8439
        if (!info) {
8440
            WOLFSSL_MSG("wolfSSL_PEM_X509_INFO_read_bio error");
8441
            return cnt;
8442
        }
8443
        num = wolfSSL_sk_X509_INFO_num(info);
8444
        for (i=0; i < num; i++) {
8445
            info_tmp = wolfSSL_sk_X509_INFO_value(info, i);
8446
8447
            if (info_tmp->x509) {
8448
                if (wolfSSL_X509_STORE_add_cert(ctx->store, info_tmp->x509) ==
8449
                    WOLFSSL_SUCCESS) {
8450
                    cnt ++;
8451
                }
8452
                else {
8453
                    WOLFSSL_MSG("wolfSSL_X509_STORE_add_cert failed");
8454
                }
8455
            }
8456
#ifdef HAVE_CRL
8457
            if (info_tmp->crl) {
8458
                if (wolfSSL_X509_STORE_add_crl(ctx->store, info_tmp->crl) ==
8459
                    WOLFSSL_SUCCESS) {
8460
                    cnt ++;
8461
                }
8462
                else {
8463
                    WOLFSSL_MSG("wolfSSL_X509_STORE_add_crl failed");
8464
                }
8465
            }
8466
#endif
8467
        }
8468
        wolfSSL_sk_X509_INFO_pop_free(info, wolfSSL_X509_INFO_free);
8469
    #elif defined(HAVE_CRL)
8470
        /* Only supports one certificate or CRL in the file. */
8471
        WOLFSSL_X509_CRL* crl = NULL;
8472
        XFILE fp = XFOPEN(file, "rb");
8473
        if (fp == XBADFILE) {
8474
            WOLFSSL_MSG("XFOPEN error");
8475
            return cnt;
8476
        }
8477
8478
        x509 = wolfSSL_PEM_read_X509(fp, NULL, NULL, NULL);
8479
        if (x509 != NULL) {
8480
            if (wolfSSL_X509_STORE_add_cert(ctx->store, x509) ==
8481
                WOLFSSL_SUCCESS) {
8482
                cnt++;
8483
            }
8484
            else {
8485
                WOLFSSL_MSG("wolfSSL_X509_STORE_add_cert failed");
8486
            }
8487
        }
8488
        else {
8489
            if (XFSEEK(fp, 0, XSEEK_SET) != 0) {
8490
                WOLFSSL_MSG("XFSEEK error");
8491
                return cnt;
8492
            }
8493
            crl = wolfSSL_PEM_read_X509_CRL(fp, NULL, NULL, NULL);
8494
            if (crl != NULL) {
8495
                if (wolfSSL_X509_STORE_add_crl(ctx->store, crl) ==
8496
                    WOLFSSL_SUCCESS) {
8497
                    cnt++;
8498
                }
8499
                else {
8500
                    WOLFSSL_MSG("wolfSSL_X509_STORE_add_crl failed");
8501
                }
8502
            }
8503
            else {
8504
                WOLFSSL_MSG("Certificate and CRL not recognized");
8505
                return cnt;
8506
            }
8507
        }
8508
8509
        wolfSSL_X509_free(x509);
8510
        wolfSSL_X509_CRL_free(crl);
8511
    #endif
8512
#else
8513
    (void)cnt;
8514
#endif /* OPENSSL_ALL && !NO_BIO */
8515
    }
8516
8517
    WOLFSSL_LEAVE("wolfSSL_X509_load_ceretificate_crl_file", cnt);
8518
    return cnt;
8519
}
8520
#endif /* !NO_FILESYSTEM */
8521
8522
8523
#ifdef HAVE_CRL
8524
8525
#ifndef NO_BIO
8526
WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL_bio(WOLFSSL_BIO *bp,
8527
                                                    WOLFSSL_X509_CRL **x)
8528
{
8529
    int derSz;
8530
    byte* der = NULL;
8531
    WOLFSSL_X509_CRL* crl = NULL;
8532
8533
    if (bp == NULL)
8534
        return NULL;
8535
8536
    if ((derSz = wolfSSL_BIO_get_len(bp)) > 0) {
8537
        der = (byte*)XMALLOC(derSz, 0, DYNAMIC_TYPE_DER);
8538
        if (der != NULL) {
8539
            if (wolfSSL_BIO_read(bp, der, derSz) == derSz) {
8540
                crl = wolfSSL_d2i_X509_CRL(x, der, derSz);
8541
            }
8542
        }
8543
    }
8544
8545
    XFREE(der, 0, DYNAMIC_TYPE_DER);
8546
8547
    return crl;
8548
}
8549
#endif
8550
8551
#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
8552
WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL_fp(XFILE fp, WOLFSSL_X509_CRL **crl)
8553
{
8554
    WOLFSSL_ENTER("wolfSSL_d2i_X509_CRL_fp");
8555
    return (WOLFSSL_X509_CRL *)wolfSSL_d2i_X509_fp_ex(fp, (void **)crl,
8556
        CRL_TYPE);
8557
}
8558
8559
/* Read CRL file, and add it to store and corresponding cert manager     */
8560
/* @param ctx   a pointer of X509_LOOKUP back to the X509_STORE          */
8561
/* @param file  a file to read                                           */
8562
/* @param type  WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1            */
8563
/* @return WOLFSSL_SUCCESS(1) on successful, otherwise WOLFSSL_FAILURE(0)*/
8564
WOLFSSL_API int wolfSSL_X509_load_crl_file(WOLFSSL_X509_LOOKUP *ctx,
8565
                                             const char *file, int type)
8566
{
8567
#ifndef NO_BIO
8568
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
8569
    int count = 0;
8570
    WOLFSSL_BIO *bio = NULL;
8571
    WOLFSSL_X509_CRL *crl = NULL;
8572
8573
    WOLFSSL_ENTER("wolfSSL_X509_load_crl_file");
8574
8575
    if (ctx == NULL || file == NULL)
8576
        return ret;
8577
8578
    if ((bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file())) == NULL)
8579
        return ret;
8580
8581
    if (wolfSSL_BIO_read_filename(bio, file) <= 0) {
8582
        wolfSSL_BIO_free(bio);
8583
        return ret;
8584
    }
8585
8586
    if (wolfSSL_BIO_read_filename(bio, file) <= 0) {
8587
        wolfSSL_BIO_free(bio);
8588
        return ret;
8589
    }
8590
8591
    if (type == WOLFSSL_FILETYPE_PEM) {
8592
        do {
8593
            crl = wolfSSL_PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL);
8594
            if (crl == NULL) {
8595
                if (count <= 0) {
8596
                    WOLFSSL_MSG("Load crl failed");
8597
                }
8598
                break;
8599
            }
8600
8601
            ret = wolfSSL_X509_STORE_add_crl(ctx->store, crl);
8602
            if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
8603
                WOLFSSL_MSG("Adding crl failed");
8604
                break;
8605
            }
8606
            count++;
8607
            wolfSSL_X509_CRL_free(crl);
8608
            crl = NULL;
8609
        }   while(crl == NULL);
8610
8611
        ret = count;
8612
    }
8613
    else if (type == WOLFSSL_FILETYPE_ASN1) {
8614
        crl = wolfSSL_d2i_X509_CRL_bio(bio, NULL);
8615
        if (crl == NULL) {
8616
            WOLFSSL_MSG("Load crl failed");
8617
        }
8618
        else {
8619
            ret = wolfSSL_X509_STORE_add_crl(ctx->store, crl);
8620
            if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
8621
                WOLFSSL_MSG("Adding crl failed");
8622
            }
8623
            else {
8624
                ret = 1;/* handled a file */
8625
            }
8626
        }
8627
    }
8628
    else {
8629
        WOLFSSL_MSG("Invalid file type");
8630
    }
8631
8632
    wolfSSL_X509_CRL_free(crl);
8633
    wolfSSL_BIO_free(bio);
8634
8635
    WOLFSSL_LEAVE("wolfSSL_X509_load_crl_file", ret);
8636
    return ret;
8637
#else
8638
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
8639
    int count = 0;
8640
    XFILE fp;
8641
    WOLFSSL_X509_CRL *crl = NULL;
8642
8643
    WOLFSSL_ENTER("wolfSSL_X509_load_crl_file");
8644
8645
    if (ctx == NULL || file == NULL)
8646
        return ret;
8647
8648
    if ((fp = XFOPEN(file, "rb")) == XBADFILE)
8649
        return ret;
8650
8651
    if (type == WOLFSSL_FILETYPE_PEM) {
8652
        do {
8653
            crl = wolfSSL_PEM_read_X509_CRL(fp, NULL, NULL, NULL);
8654
            if (crl == NULL) {
8655
                if (count <= 0) {
8656
                    WOLFSSL_MSG("Load crl failed");
8657
                }
8658
                break;
8659
            }
8660
8661
            ret = wolfSSL_X509_STORE_add_crl(ctx->store, crl);
8662
            if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
8663
                WOLFSSL_MSG("Adding crl failed");
8664
                break;
8665
            }
8666
            count++;
8667
            wolfSSL_X509_CRL_free(crl);
8668
            crl = NULL;
8669
        }
8670
        while(crl == NULL);
8671
8672
        ret = count;
8673
    }
8674
    else if (type == WOLFSSL_FILETYPE_ASN1) {
8675
        crl = wolfSSL_d2i_X509_CRL_fp(fp, NULL);
8676
        if (crl == NULL) {
8677
            WOLFSSL_MSG("Load crl failed");
8678
        }
8679
        else {
8680
            ret = wolfSSL_X509_STORE_add_crl(ctx->store, crl);
8681
            if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
8682
                WOLFSSL_MSG("Adding crl failed");
8683
            }
8684
            else {
8685
                ret = 1;/* handled a file */
8686
            }
8687
        }
8688
    }
8689
    else {
8690
        WOLFSSL_MSG("Invalid file type");
8691
    }
8692
8693
    wolfSSL_X509_CRL_free(crl);
8694
    XFCLOSE(fp);
8695
8696
    WOLFSSL_LEAVE("wolfSSL_X509_load_crl_file", ret);
8697
    return ret;
8698
#endif /* !NO_BIO */
8699
}
8700
#endif /* !NO_FILESYSTEM */
8701
8702
8703
WOLFSSL_X509_CRL* wolfSSL_d2i_X509_CRL(WOLFSSL_X509_CRL** crl,
8704
        const unsigned char* in, int len)
8705
{
8706
    WOLFSSL_X509_CRL *newcrl = NULL;
8707
    int ret = WOLFSSL_SUCCESS;
8708
8709
    WOLFSSL_ENTER("wolfSSL_d2i_X509_CRL");
8710
8711
    if (in == NULL) {
8712
        WOLFSSL_MSG("Bad argument value");
8713
    }
8714
    else {
8715
        newcrl =(WOLFSSL_X509_CRL*)XMALLOC(sizeof(WOLFSSL_X509_CRL), NULL,
8716
                DYNAMIC_TYPE_CRL);
8717
        if (newcrl == NULL) {
8718
            WOLFSSL_MSG("New CRL allocation failed");
8719
        }
8720
        else {
8721
            ret = InitCRL(newcrl, NULL);
8722
            if (ret < 0) {
8723
                WOLFSSL_MSG("Init tmp CRL failed");
8724
            }
8725
            else {
8726
                ret = BufferLoadCRL(newcrl, in, len, WOLFSSL_FILETYPE_ASN1,
8727
                    NO_VERIFY);
8728
                if (ret != WOLFSSL_SUCCESS) {
8729
                    WOLFSSL_MSG("Buffer Load CRL failed");
8730
                }
8731
                else {
8732
                    if (crl) {
8733
                        *crl = newcrl;
8734
                    }
8735
                }
8736
            }
8737
        }
8738
    }
8739
8740
    if ((ret != WOLFSSL_SUCCESS) && (newcrl != NULL)) {
8741
        wolfSSL_X509_CRL_free(newcrl);
8742
        newcrl = NULL;
8743
    }
8744
8745
    return newcrl;
8746
}
8747
8748
/* Retrieve issuer X509_NAME from CRL
8749
 * return X509_NAME*  on success
8750
 * return NULL on failure
8751
 */
8752
WOLFSSL_X509_NAME* wolfSSL_X509_CRL_get_issuer_name(WOLFSSL_X509_CRL* crl)
8753
{
8754
    if (crl == NULL || crl->crlList == NULL)
8755
        return NULL;
8756
8757
    return crl->crlList->issuer;
8758
}
8759
8760
/* Retrieve version from CRL
8761
 * return version on success
8762
 * return 0 on failure
8763
 */
8764
int wolfSSL_X509_CRL_version(WOLFSSL_X509_CRL* crl)
8765
{
8766
    if (crl == NULL || crl->crlList == NULL)
8767
        return 0;
8768
8769
    return crl->crlList->version;
8770
}
8771
8772
/* Retrieve sig OID from CRL
8773
 * return OID on success
8774
 * return 0 on failure
8775
 */
8776
int wolfSSL_X509_CRL_get_signature_type(WOLFSSL_X509_CRL* crl)
8777
{
8778
    if (crl == NULL || crl->crlList == NULL)
8779
        return 0;
8780
8781
    return crl->crlList->signatureOID;
8782
}
8783
8784
/* Retrieve sig NID from CRL
8785
 * return NID on success
8786
 * return 0 on failure
8787
 */
8788
int wolfSSL_X509_CRL_get_signature_nid(const WOLFSSL_X509_CRL* crl)
8789
{
8790
    if (crl == NULL || crl->crlList == NULL)
8791
        return 0;
8792
8793
    return oid2nid(crl->crlList->signatureOID, oidSigType);
8794
}
8795
8796
/* Retrieve signature from CRL
8797
 * return WOLFSSL_SUCCESS on success and negative values on failure
8798
 */
8799
int wolfSSL_X509_CRL_get_signature(WOLFSSL_X509_CRL* crl,
8800
    unsigned char* buf, int* bufSz)
8801
{
8802
    WOLFSSL_ENTER("wolfSSL_X509_CRL_get_signature");
8803
8804
    if (crl == NULL || crl->crlList == NULL ||
8805
        crl->crlList->signature == NULL || bufSz == NULL)
8806
        return BAD_FUNC_ARG;
8807
8808
    if (buf != NULL) {
8809
        if (*bufSz < (int)crl->crlList->signatureSz) {
8810
            WOLFSSL_MSG("Signature buffer too small");
8811
            return BUFFER_E;
8812
        }
8813
        else {
8814
            XMEMCPY(buf, crl->crlList->signature, crl->crlList->signatureSz);
8815
        }
8816
    }
8817
    *bufSz = (int)crl->crlList->signatureSz;
8818
8819
    return WOLFSSL_SUCCESS;
8820
}
8821
8822
/* Retrieve serial number from RevokedCert
8823
 * return WOLFSSL_SUCCESS on success and negative values on failure
8824
 */
8825
int wolfSSL_X509_REVOKED_get_serial_number(RevokedCert* rev,
8826
    byte* in, int* inOutSz)
8827
{
8828
    WOLFSSL_ENTER("wolfSSL_X509_REVOKED_get_serial_number");
8829
    if (rev == NULL || inOutSz == NULL) {
8830
        return BAD_FUNC_ARG;
8831
    }
8832
8833
    if (in != NULL) {
8834
        if (*inOutSz < rev->serialSz) {
8835
            WOLFSSL_MSG("Serial buffer too small");
8836
            return BUFFER_E;
8837
        }
8838
        XMEMCPY(in, rev->serialNumber, rev->serialSz);
8839
    }
8840
    *inOutSz = rev->serialSz;
8841
8842
    return WOLFSSL_SUCCESS;
8843
}
8844
8845
const WOLFSSL_ASN1_INTEGER* wolfSSL_X509_REVOKED_get0_serial_number(const
8846
                                                      WOLFSSL_X509_REVOKED *rev)
8847
{
8848
    WOLFSSL_ENTER("wolfSSL_X509_REVOKED_get0_serial_number");
8849
8850
    if (rev != NULL) {
8851
        return rev->serialNumber;
8852
    }
8853
    else
8854
        return NULL;
8855
}
8856
8857
#ifndef NO_WOLFSSL_STUB
8858
const WOLFSSL_ASN1_TIME* wolfSSL_X509_REVOKED_get0_revocation_date(const
8859
                                                      WOLFSSL_X509_REVOKED *rev)
8860
{
8861
    WOLFSSL_STUB("wolfSSL_X509_REVOKED_get0_revocation_date");
8862
8863
    (void) rev;
8864
    return NULL;
8865
}
8866
#endif
8867
8868
8869
#ifndef NO_BIO
8870
/* print serial number out
8871
*  return WOLFSSL_SUCCESS on success
8872
*/
8873
static int X509RevokedPrintSerial(WOLFSSL_BIO* bio, RevokedCert* rev,
8874
    int indent)
8875
{
8876
    unsigned char serial[32];
8877
    int  sz = sizeof(serial);
8878
8879
    XMEMSET(serial, 0, sz);
8880
    if (wolfSSL_X509_REVOKED_get_serial_number(rev, serial, &sz)
8881
            == WOLFSSL_SUCCESS) {
8882
        X509PrintSerial_ex(bio, serial, sz, 0, indent);
8883
    }
8884
    return WOLFSSL_SUCCESS;
8885
}
8886
8887
8888
/* print out the signature in human readable format for use with
8889
* wolfSSL_X509_CRL_print()
8890
 * return WOLFSSL_SUCCESS on success
8891
 */
8892
static int X509CRLPrintSignature(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl,
8893
        int algOnly, int indent)
8894
{
8895
    int sigSz = 0;
8896
8897
    if (wolfSSL_X509_CRL_get_signature(crl, NULL, &sigSz) <= 0) {
8898
        return WOLFSSL_FAILURE;
8899
    }
8900
8901
    if (sigSz > 0) {
8902
        unsigned char* sig;
8903
        int sigNid = wolfSSL_X509_CRL_get_signature_nid(crl);
8904
8905
        sig = (unsigned char*)XMALLOC(sigSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8906
        if (sig == NULL) {
8907
            return WOLFSSL_FAILURE;
8908
        }
8909
8910
        if (wolfSSL_X509_CRL_get_signature(crl, sig, &sigSz) <= 0) {
8911
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8912
            return WOLFSSL_FAILURE;
8913
        }
8914
8915
        if (X509PrintSignature_ex(bio, sig, sigSz, sigNid, algOnly, indent)
8916
                != WOLFSSL_SUCCESS) {
8917
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8918
            return WOLFSSL_FAILURE;
8919
        }
8920
8921
        XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8922
8923
    }
8924
8925
    return WOLFSSL_SUCCESS;
8926
}
8927
#endif /* !NO_BIO */
8928
8929
#if !defined(NO_BIO) && defined(XSNPRINTF)
8930
/* print out the extensions in human readable format for use with
8931
 * wolfSSL_X509_CRL_print()
8932
 * return WOLFSSL_SUCCESS on success
8933
 */
8934
static int X509CRLPrintExtensions(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl,
8935
        int indent)
8936
{
8937
    char tmp[MAX_WIDTH]; /* buffer for XSNPRINTF */
8938
    int  ret = 0;
8939
8940
    if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s\n", indent, "",
8941
                "CRL extensions:") >= MAX_WIDTH) {
8942
        ret = WOLFSSL_FAILURE;
8943
    }
8944
8945
    if (ret == 0 && wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
8946
        ret = WOLFSSL_FAILURE;
8947
    }
8948
8949
    if (ret == 0 && crl->crlList->crlNumberSet) {
8950
        char dec_string[49]; /* 20 octets can express numbers up to approx
8951
                                49 decimal digits */
8952
        int freeMp = 0;
8953
    #ifdef WOLFSSL_SMALL_STACK
8954
        mp_int* dec_num = (mp_int*)XMALLOC(sizeof(*dec_num), NULL,
8955
                            DYNAMIC_TYPE_BIGINT);
8956
        if (dec_num == NULL) {
8957
            ret = MEMORY_E;
8958
        }
8959
    #else
8960
        mp_int dec_num[1];
8961
    #endif
8962
8963
        if (ret == 0 && (mp_init(dec_num) != MP_OKAY)) {
8964
             ret = MP_INIT_E;
8965
        }
8966
        else if (ret == 0) {
8967
            freeMp = 1;
8968
        }
8969
8970
        if (ret == 0 && mp_read_radix(dec_num, (char *)crl->crlList->crlNumber,
8971
                    MP_RADIX_HEX) != MP_OKAY) {
8972
            ret = WOLFSSL_FAILURE;
8973
        }
8974
8975
        if (ret == 0 && mp_toradix(dec_num, dec_string, MP_RADIX_DEC)
8976
                    != MP_OKAY) {
8977
            ret = WOLFSSL_FAILURE;
8978
        }
8979
8980
        if (ret == 0 && XSNPRINTF(tmp, MAX_WIDTH, "%*s%s\n", indent + 4, "",
8981
                    "X509v3 CRL Number:") >= MAX_WIDTH) {
8982
            ret = WOLFSSL_FAILURE;
8983
        }
8984
8985
        if (ret == 0 && wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
8986
            ret = WOLFSSL_FAILURE;
8987
        }
8988
8989
        if (ret == 0 && XSNPRINTF(tmp, MAX_WIDTH, "%*s%s\n", indent + 8, "",
8990
            dec_string) >= MAX_WIDTH) {
8991
            ret = WOLFSSL_FAILURE;
8992
        }
8993
8994
        if (ret == 0 && wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
8995
            ret = WOLFSSL_FAILURE;
8996
        }
8997
8998
        XMEMSET(tmp, 0, sizeof(tmp));
8999
9000
        if (freeMp) {
9001
            mp_free(dec_num);
9002
        }
9003
9004
    #ifdef WOLFSSL_SMALL_STACK
9005
        XFREE(dec_num, NULL, DYNAMIC_TYPE_BIGINT);
9006
    #endif
9007
    }
9008
9009
#if !defined(NO_SKID)
9010
    if (ret == 0 && crl->crlList->extAuthKeyIdSet &&
9011
            crl->crlList->extAuthKeyId[0] != 0) {
9012
        word32 i;
9013
        char val[5];
9014
        int valSz = 5;
9015
9016
        if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s", indent + 4, "",
9017
                    "X509v3 Authority Key Identifier:") >= MAX_WIDTH) {
9018
            ret = WOLFSSL_FAILURE;
9019
        }
9020
9021
        if (ret == 0) {
9022
            XSTRNCAT(tmp, "\n", MAX_WIDTH - XSTRLEN(tmp) - 1);
9023
        }
9024
9025
        if (ret == 0 && wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
9026
            ret = WOLFSSL_FAILURE;
9027
        }
9028
        XMEMSET(tmp, 0, MAX_WIDTH);
9029
9030
        if (ret == 0 && XSNPRINTF(tmp, MAX_WIDTH - 1, "%*s%s",
9031
                    indent + 8, "", "keyid") >= MAX_WIDTH) {
9032
            ret = WOLFSSL_FAILURE;
9033
        }
9034
9035
9036
        for (i = 0; i < XSTRLEN((char*)crl->crlList->extAuthKeyId); i++) {
9037
            /* check if buffer is almost full */
9038
            if (ret == 0 && XSTRLEN(tmp) >= sizeof(tmp) - valSz) {
9039
                if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
9040
                    ret = WOLFSSL_FAILURE;
9041
                }
9042
                tmp[0] = '\0';
9043
            }
9044
            if (ret == 0 && XSNPRINTF(val, (size_t)valSz, ":%02X",
9045
                    crl->crlList->extAuthKeyId[i]) >= valSz) {
9046
                WOLFSSL_MSG("buffer overrun");
9047
                ret = WOLFSSL_FAILURE;
9048
            }
9049
            if (ret == 0) {
9050
                XSTRNCAT(tmp, val, valSz);
9051
            }
9052
        }
9053
        if (ret == 0) {
9054
            XSTRNCAT(tmp, "\n", XSTRLEN("\n") + 1);
9055
        }
9056
        if (ret == 0 && wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
9057
            ret = WOLFSSL_FAILURE;
9058
        }
9059
    }
9060
#endif
9061
9062
    if (ret == 0) {
9063
        ret = WOLFSSL_SUCCESS;
9064
    }
9065
9066
    return ret;
9067
}
9068
9069
/* iterate through a CRL's Revoked Certs and print out in human
9070
 * readable format for use with wolfSSL_X509_CRL_print()
9071
 * return WOLFSSL_SUCCESS on success
9072
 */
9073
static int X509CRLPrintRevoked(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl,
9074
        int indent)
9075
{
9076
    char tmp[MAX_WIDTH]; /* buffer for XSNPRINTF */
9077
    int i;
9078
9079
    if (crl->crlList->totalCerts > 0) {
9080
        RevokedCert* revoked = crl->crlList->certs;
9081
9082
        if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s\n", indent, "",
9083
                    "Revoked Certificates:") >= MAX_WIDTH) {
9084
            return WOLFSSL_FAILURE;
9085
        }
9086
9087
        if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
9088
            return WOLFSSL_FAILURE;
9089
        }
9090
        XMEMSET(tmp, 0, MAX_WIDTH);
9091
9092
        for (i = 0; i < crl->crlList->totalCerts; i++) {
9093
            if (revoked->serialSz > 0) {
9094
                if (X509RevokedPrintSerial(bio, revoked, indent + 4)
9095
                        != WOLFSSL_SUCCESS) {
9096
                    return WOLFSSL_FAILURE;
9097
                }
9098
            }
9099
        #ifndef NO_ASN_TIME
9100
             if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s", indent + 8, "",
9101
                         "Revocation Date: ") >= MAX_WIDTH) {
9102
                return WOLFSSL_FAILURE;
9103
            }
9104
9105
            if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
9106
                return WOLFSSL_FAILURE;
9107
            }
9108
9109
            if (revoked->revDate[0] != 0) {
9110
                if (GetTimeString(revoked->revDate, ASN_UTC_TIME,
9111
                    tmp, MAX_WIDTH) != WOLFSSL_SUCCESS) {
9112
                    if (GetTimeString(revoked->revDate, ASN_GENERALIZED_TIME,
9113
                    tmp, MAX_WIDTH) != WOLFSSL_SUCCESS) {
9114
                        WOLFSSL_MSG("Error getting revocation date");
9115
                        return WOLFSSL_FAILURE;
9116
                    }
9117
                }
9118
            }
9119
            else {
9120
                XSTRNCPY(tmp, "Not Set", MAX_WIDTH-1);
9121
            }
9122
            tmp[MAX_WIDTH - 1] = '\0'; /* make sure null terminated */
9123
            if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
9124
                return WOLFSSL_FAILURE;
9125
            }
9126
9127
            if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) {
9128
                return WOLFSSL_FAILURE;
9129
            }
9130
        #endif
9131
            revoked = revoked->next;
9132
        }
9133
    }
9134
    else {
9135
        if (wolfSSL_BIO_write(bio, "No Revoked Certificates.\n",
9136
                       (int)XSTRLEN("No Revoked Certificates.\n")) <= 0) {
9137
            return WOLFSSL_FAILURE;
9138
        }
9139
    }
9140
9141
    return WOLFSSL_SUCCESS;
9142
}
9143
9144
#ifndef NO_ASN_TIME
9145
/* print out the last/next update times in human readable
9146
 * format for use with wolfSSL_X509_CRL_print()
9147
 * return WOLFSSL_SUCCESS on success
9148
 */
9149
static int X509CRLPrintDates(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl,
9150
        int indent)
9151
{
9152
    char tmp[MAX_WIDTH]; /* buffer for XSNPRINTF */
9153
9154
    if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s", indent, "",
9155
                "Last Update: ") >= MAX_WIDTH) {
9156
        return WOLFSSL_FAILURE;
9157
    }
9158
9159
    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
9160
        return WOLFSSL_FAILURE;
9161
    }
9162
9163
    if (crl->crlList->lastDate[0] != 0) {
9164
        if (GetTimeString(crl->crlList->lastDate, ASN_UTC_TIME,
9165
            tmp, MAX_WIDTH) != WOLFSSL_SUCCESS) {
9166
            if (GetTimeString(crl->crlList->lastDate, ASN_GENERALIZED_TIME,
9167
            tmp, MAX_WIDTH) != WOLFSSL_SUCCESS) {
9168
                WOLFSSL_MSG("Error getting last update date");
9169
                return WOLFSSL_FAILURE;
9170
            }
9171
        }
9172
    }
9173
    else {
9174
        XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
9175
    }
9176
    tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
9177
    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
9178
        return WOLFSSL_FAILURE;
9179
    }
9180
9181
    if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) {
9182
        return WOLFSSL_FAILURE;
9183
    }
9184
9185
    if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s", indent, "",
9186
                "Next Update: ") >= MAX_WIDTH) {
9187
        return WOLFSSL_FAILURE;
9188
    }
9189
9190
    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
9191
        return WOLFSSL_FAILURE;
9192
    }
9193
9194
    if (crl->crlList->nextDate[0] != 0) {
9195
        if (GetTimeString(crl->crlList->nextDate, ASN_UTC_TIME,
9196
            tmp, MAX_WIDTH) != WOLFSSL_SUCCESS) {
9197
            if (GetTimeString(crl->crlList->nextDate, ASN_GENERALIZED_TIME,
9198
            tmp, MAX_WIDTH) != WOLFSSL_SUCCESS) {
9199
                WOLFSSL_MSG("Error getting next update date");
9200
                return WOLFSSL_FAILURE;
9201
            }
9202
        }
9203
    }
9204
    else {
9205
        XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
9206
    }
9207
    tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
9208
    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
9209
        return WOLFSSL_FAILURE;
9210
    }
9211
9212
    if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) {
9213
        return WOLFSSL_FAILURE;
9214
    }
9215
9216
    return WOLFSSL_SUCCESS;
9217
}
9218
#endif
9219
9220
/* Writes the human readable form of x509 to bio.
9221
 *
9222
 * bio  WOLFSSL_BIO to write to.
9223
 * crl Certificate revocation list to write.
9224
 *
9225
 * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
9226
 */
9227
int wolfSSL_X509_CRL_print(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl)
9228
{
9229
    char issuType[] = "Issuer: ";
9230
9231
    if (bio == NULL || crl == NULL || crl->crlList == NULL) {
9232
        return WOLFSSL_FAILURE;
9233
    }
9234
9235
    if (wolfSSL_BIO_write(bio, "Certificate Revocation List (CRL):\n",
9236
                  (int)XSTRLEN("Certificate Revocation List (CRL):\n")) <= 0) {
9237
            return WOLFSSL_FAILURE;
9238
    }
9239
9240
    /* print version */
9241
    if (X509PrintVersion(bio, wolfSSL_X509_CRL_version(crl), 8)
9242
            != WOLFSSL_SUCCESS) {
9243
        return WOLFSSL_FAILURE;
9244
    }
9245
9246
    /* print signature algo */
9247
    if (X509CRLPrintSignature(bio, crl, 1, 8) != WOLFSSL_SUCCESS) {
9248
        return WOLFSSL_FAILURE;
9249
    }
9250
9251
    /* print issuer name */
9252
    if (X509PrintName(bio, wolfSSL_X509_CRL_get_issuer_name(crl), issuType, 8)
9253
            != WOLFSSL_SUCCESS) {
9254
        return WOLFSSL_FAILURE;
9255
    }
9256
9257
#ifndef NO_ASN_TIME
9258
    /* print last and next update times */
9259
    if (X509CRLPrintDates(bio, crl, 8) != WOLFSSL_SUCCESS) {
9260
        return WOLFSSL_FAILURE;
9261
    }
9262
#endif
9263
9264
    /* print CRL extensions */
9265
    if (X509CRLPrintExtensions(bio, crl, 8) != WOLFSSL_SUCCESS) {
9266
        return WOLFSSL_FAILURE;
9267
    }
9268
9269
    /* print CRL Revoked Certs */
9270
    if (X509CRLPrintRevoked(bio, crl, 0) != WOLFSSL_SUCCESS) {
9271
        return WOLFSSL_FAILURE;
9272
    }
9273
9274
    if (X509CRLPrintSignature(bio, crl, 0, 4) != WOLFSSL_SUCCESS) {
9275
        return WOLFSSL_FAILURE;
9276
    }
9277
9278
    if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
9279
        return WOLFSSL_FAILURE;
9280
    }
9281
9282
    return WOLFSSL_SUCCESS;
9283
}
9284
#endif /* !NO_BIO && XSNPRINTF */
9285
#endif /* HAVE_CRL */
9286
#endif /* OPENSSL_EXTRA */
9287
9288
#if defined(HAVE_CRL) && (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL))
9289
void wolfSSL_X509_CRL_free(WOLFSSL_X509_CRL *crl)
9290
{
9291
    WOLFSSL_ENTER("wolfSSL_X509_CRL_free");
9292
9293
    if (crl)
9294
        FreeCRL(crl, 1);
9295
}
9296
#endif /* HAVE_CRL && (OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL) */
9297
9298
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA)
9299
WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_lastUpdate(WOLFSSL_X509_CRL* crl)
9300
{
9301
    if ((crl != NULL) && (crl->crlList != NULL) &&
9302
        (crl->crlList->lastDateAsn1.data[0] != 0)) {
9303
        return &crl->crlList->lastDateAsn1;
9304
    }
9305
    else
9306
        return NULL;
9307
}
9308
9309
WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_nextUpdate(WOLFSSL_X509_CRL* crl)
9310
{
9311
    if ((crl != NULL) && (crl->crlList != NULL) &&
9312
        (crl->crlList->nextDateAsn1.data[0] != 0)) {
9313
        return &crl->crlList->nextDateAsn1;
9314
    }
9315
    else
9316
        return NULL;
9317
}
9318
9319
#ifndef NO_WOLFSSL_STUB
9320
int wolfSSL_X509_CRL_verify(WOLFSSL_X509_CRL* crl, WOLFSSL_EVP_PKEY* key)
9321
{
9322
    (void)crl;
9323
    (void)key;
9324
    WOLFSSL_STUB("X509_CRL_verify");
9325
    return 0;
9326
}
9327
#endif
9328
#endif /* HAVE_CRL && OPENSSL_EXTRA */
9329
9330
#ifdef OPENSSL_EXTRA
9331
9332
9333
WOLFSSL_X509_VERIFY_PARAM* wolfSSL_X509_VERIFY_PARAM_new(void)
9334
{
9335
    WOLFSSL_X509_VERIFY_PARAM *param = NULL;
9336
    param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC(
9337
            sizeof(WOLFSSL_X509_VERIFY_PARAM), NULL, DYNAMIC_TYPE_OPENSSL);
9338
    if (param != NULL)
9339
        XMEMSET(param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM ));
9340
9341
    return(param);
9342
}
9343
9344
9345
void wolfSSL_X509_VERIFY_PARAM_free(WOLFSSL_X509_VERIFY_PARAM *param)
9346
{
9347
    XFREE(param, NULL, DYNAMIC_TYPE_OPENSSL);
9348
}
9349
9350
9351
/* Sets flags by OR'ing with existing value. */
9352
int wolfSSL_X509_VERIFY_PARAM_set_flags(WOLFSSL_X509_VERIFY_PARAM *param,
9353
        unsigned long flags)
9354
{
9355
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
9356
9357
    if (param != NULL) {
9358
        param->flags |= flags;
9359
        ret = WOLFSSL_SUCCESS;
9360
    }
9361
9362
    return ret;
9363
}
9364
9365
9366
int wolfSSL_X509_VERIFY_PARAM_get_flags(WOLFSSL_X509_VERIFY_PARAM *param)
9367
{
9368
    int ret = 0;
9369
9370
    if (param != NULL) {
9371
        ret = (int)param->flags;
9372
    }
9373
9374
    return ret;
9375
}
9376
9377
9378
int wolfSSL_X509_VERIFY_PARAM_clear_flags(WOLFSSL_X509_VERIFY_PARAM *param,
9379
        unsigned long flags)
9380
{
9381
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
9382
9383
    if (param != NULL) {
9384
        param->flags &= ~flags;
9385
        ret = WOLFSSL_SUCCESS;
9386
    }
9387
9388
    return ret;
9389
}
9390
9391
/* note WOLFSSL_X509_VERIFY_PARAM does not record purpose, trust, depth, or
9392
 * auth_level.
9393
 */
9394
static const WOLFSSL_X509_VERIFY_PARAM x509_verify_param_builtins[] = {
9395
    {
9396
     "ssl_client",              /* name */
9397
     0,                         /* check_time */
9398
     0,                         /* inherit_flags */
9399
     0,                         /* flags */
9400
     "",                        /* hostname */
9401
     0,                         /* hostFlags */
9402
     ""                         /* ipasc */
9403
    },
9404
    {
9405
     "ssl_server",              /* name */
9406
     0,                         /* check_time */
9407
     0,                         /* inherit_flags */
9408
     0,                         /* flags */
9409
     "",                        /* hostname */
9410
     0,                         /* hostFlags */
9411
     ""                         /* ipasc */
9412
    }
9413
};
9414
9415
const WOLFSSL_X509_VERIFY_PARAM *wolfSSL_X509_VERIFY_PARAM_lookup(
9416
    const char *name)
9417
{
9418
    const WOLFSSL_X509_VERIFY_PARAM *param = &x509_verify_param_builtins[0],
9419
        *param_end = &x509_verify_param_builtins[
9420
                                         XELEM_CNT(x509_verify_param_builtins)];
9421
9422
    if (name == NULL) {
9423
        return NULL;
9424
    }
9425
    while (param < param_end) {
9426
        if (XSTRCMP(name, param->name) == 0)
9427
            return param;
9428
        ++param;
9429
    }
9430
    return NULL;
9431
}
9432
9433
/* inherits properties of param "to" to param "from"
9434
*
9435
* WOLFSSL_VPARAM_DEFAULT          any values in "src" is copied
9436
*                                 if "src" value is new for "to".
9437
* WOLFSSL_VPARAM_OVERWRITE        all values of "form" are copied to "to"
9438
* WOLFSSL_VPARAM_RESET_FLAGS      the flag values are copied, not Ored
9439
* WOLFSSL_VPARAM_LOCKED           don't copy any values
9440
* WOLFSSL_VPARAM_ONCE             the current inherit_flags is zerroed
9441
*/
9442
int wolfSSL_X509_VERIFY_PARAM_inherit(WOLFSSL_X509_VERIFY_PARAM *to,
9443
                                         const WOLFSSL_X509_VERIFY_PARAM *from)
9444
{
9445
    int ret = WOLFSSL_SUCCESS;
9446
    int isOverWrite = 0;
9447
    int isDefault = 0;
9448
    unsigned int flags;
9449
9450
    /* sanity check */
9451
    if (!to || !from) {
9452
        /* be compatible to openssl return value */
9453
        return WOLFSSL_SUCCESS;
9454
    }
9455
    flags = to->inherit_flags | from->inherit_flags;
9456
9457
    if (flags & WOLFSSL_VPARAM_LOCKED) {
9458
        return WOLFSSL_SUCCESS;
9459
    }
9460
9461
    if (flags & WOLFSSL_VPARAM_ONCE) {
9462
        to->inherit_flags = 0;
9463
    }
9464
9465
    isOverWrite = (flags & WOLFSSL_VPARAM_OVERWRITE);
9466
    isDefault = (flags & WOLFSSL_VPARAM_DEFAULT);
9467
9468
    /* copy check_time if check time is not set */
9469
    if ((to->flags & WOLFSSL_USE_CHECK_TIME) == 0 || isOverWrite) {
9470
           to->check_time = from->check_time;
9471
           to->flags &= ~WOLFSSL_USE_CHECK_TIME;
9472
    }
9473
    /* host name */
9474
    if (isOverWrite ||
9475
        (from->hostName[0] != 0 && (to->hostName[0] == 0 || isDefault))) {
9476
            if (!(ret = wolfSSL_X509_VERIFY_PARAM_set1_host(to, from->hostName,
9477
                (unsigned int)XSTRLEN(from->hostName))))
9478
                return ret;
9479
        to->hostFlags = from->hostFlags;
9480
    }
9481
    /* ip ascii */
9482
    if (isOverWrite ||
9483
        (from->ipasc[0] != 0 && (to->ipasc[0] == 0 || isDefault))) {
9484
9485
            if (!(ret = wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(to, from->ipasc)))
9486
                return ret;
9487
    }
9488
9489
    if (flags & WOLFSSL_VPARAM_RESET_FLAGS)
9490
        to->flags = 0;
9491
9492
    to->flags |= from->flags;
9493
9494
    return ret;
9495
}
9496
9497
/******************************************************************************
9498
* wolfSSL_X509_VERIFY_PARAM_set1_host - sets the DNS hostname to name
9499
* hostnames is cleared if name is NULL or empty.
9500
*
9501
* RETURNS:
9502
*
9503
*/
9504
int wolfSSL_X509_VERIFY_PARAM_set1_host(WOLFSSL_X509_VERIFY_PARAM* pParam,
9505
                                         const char* name,
9506
                                         unsigned int nameSz)
9507
{
9508
    WOLFSSL_ENTER("wolfSSL_X509_VERIFY_PARAM_set1_host");
9509
9510
    if (pParam == NULL)
9511
        return WOLFSSL_FAILURE;
9512
9513
    /* If name is NULL, clear hostname. */
9514
    if (name == NULL) {
9515
        XMEMSET(pParam->hostName, 0, WOLFSSL_HOST_NAME_MAX);
9516
        return WOLFSSL_SUCCESS;
9517
    }
9518
9519
    /* If name is NULL-terminated, namelen can be set to zero. */
9520
    if (nameSz == 0) {
9521
        nameSz = (unsigned int)XSTRLEN(name);
9522
    }
9523
9524
    if (nameSz > 0 && name[nameSz - 1] == '\0')
9525
        nameSz--;
9526
9527
    if (nameSz > WOLFSSL_HOST_NAME_MAX-1) {
9528
        WOLFSSL_MSG("Truncating name");
9529
        nameSz = WOLFSSL_HOST_NAME_MAX-1;
9530
    }
9531
9532
    if (nameSz > 0) {
9533
        XMEMCPY(pParam->hostName, name, nameSz);
9534
        XMEMSET(pParam->hostName + nameSz, 0,
9535
                WOLFSSL_HOST_NAME_MAX - nameSz);
9536
    }
9537
9538
    pParam->hostName[nameSz] = '\0';
9539
9540
    return WOLFSSL_SUCCESS;
9541
}
9542
9543
/* Set VERIFY PARAM from "from" pointer to "to" pointer */
9544
int wolfSSL_X509_VERIFY_PARAM_set1(WOLFSSL_X509_VERIFY_PARAM *to,
9545
                                   const WOLFSSL_X509_VERIFY_PARAM *from)
9546
{
9547
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
9548
    unsigned int _inherit_flags;
9549
9550
    if (!to) {
9551
        return ret;
9552
    }
9553
    /* keeps the inherit flags for save */
9554
    _inherit_flags = to->inherit_flags;
9555
9556
    /* Ored DEFAULT inherit flag property to copy "from" contents to "to"
9557
    *  contents
9558
    */
9559
    to->inherit_flags |= WOLFSSL_VPARAM_DEFAULT;
9560
9561
    ret = wolfSSL_X509_VERIFY_PARAM_inherit(to, from);
9562
9563
    /* restore inherit flag */
9564
    to->inherit_flags = _inherit_flags;
9565
9566
    return ret;
9567
}
9568
9569
/* Set the host flag in the X509_VERIFY_PARAM structure */
9570
void wolfSSL_X509_VERIFY_PARAM_set_hostflags(WOLFSSL_X509_VERIFY_PARAM* param,
9571
                                             unsigned int flags)
9572
{
9573
    if (param != NULL) {
9574
        param->hostFlags = flags;
9575
    }
9576
}
9577
9578
/* Sets the expected IP address to ipasc.
9579
 *
9580
 * param is a pointer to the X509_VERIFY_PARAM structure
9581
 * ipasc is a NULL-terminated string with N.N.N.N for IPv4 and
9582
 *       HH:HH ... HH:HH for IPv6. There is no validation performed on the
9583
 *       parameter, and it must be an exact match with the IP in the cert.
9584
 *
9585
 * return 1 for success and 0 for failure*/
9586
int wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(WOLFSSL_X509_VERIFY_PARAM *param,
9587
        const char *ipasc)
9588
{
9589
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
9590
9591
    if (param != NULL) {
9592
        if (ipasc == NULL) {
9593
            param->ipasc[0] = '\0';
9594
        }
9595
        else {
9596
            XSTRLCPY(param->ipasc, ipasc, WOLFSSL_MAX_IPSTR);
9597
            param->ipasc[WOLFSSL_MAX_IPSTR-1] = '\0';
9598
        }
9599
        ret = WOLFSSL_SUCCESS;
9600
    }
9601
9602
    return ret;
9603
}
9604
/* Sets the expected IP address to ip(asc)
9605
 *          by re-constructing IP address in ascii
9606
 * @param  param is a pointer to the X509_VERIFY_PARAM structure
9607
 * @param  ip    in binary format of ip address
9608
 * @param  iplen size of ip, 4 for ipv4, 16 for ipv6
9609
 * @return 1 for success and 0 for failure
9610
 */
9611
int wolfSSL_X509_VERIFY_PARAM_set1_ip(WOLFSSL_X509_VERIFY_PARAM* param,
9612
    const unsigned char* ip, size_t iplen)
9613
{
9614
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
9615
#ifndef NO_FILESYSTEM
9616
    char* buf = NULL;
9617
    char* p = NULL;
9618
    word32 val = 0;
9619
    int i;
9620
    const size_t max_ipv6_len = 40;
9621
    byte write_zero = 0;
9622
#endif
9623
9624
    /* sanity check */
9625
    if (param == NULL || (iplen != 0 && iplen != 4 && iplen != 16)) {
9626
        WOLFSSL_MSG("bad function arg");
9627
        return ret;
9628
    }
9629
    if (ip == NULL && iplen != 0) {
9630
        WOLFSSL_MSG("bad function arg");
9631
        return ret;
9632
    }
9633
#ifndef NO_FILESYSTEM
9634
    if (iplen == 4) {
9635
        /* ipv4 www.xxx.yyy.zzz max 15 length + Null termination */
9636
        buf = (char*)XMALLOC(16, NULL, DYNAMIC_TYPE_TMP_BUFFER);
9637
        if (!buf) {
9638
            WOLFSSL_MSG("failed malloc");
9639
            return ret;
9640
        }
9641
9642
        (void)XSNPRINTF(buf, 16, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
9643
        buf[15] = '\0'; /* null terminate */
9644
    }
9645
    else if (iplen == 16) {
9646
        /* ipv6 normal address scheme
9647
        *   y1:y2:y3:y4:y5:y6:y7:y8, len(yx):4, len(y1-y8):32. len(":"):7
9648
        *   Max len is 32 + 7 + 1(Termination) = 40 bytes
9649
        *
9650
        *   ipv6 dual address
9651
        *   Or y1:y2:y3:y4:y:y6:x.x.x.x yx is 4, y1-y6 is 24, ":" is 6
9652
        *   x.x.x.x is 15.
9653
        *   Max len is 24 + 6 + 15 + 1(Termination) = 46 bytes
9654
        *
9655
        *   Expect data in ip[16]
9656
        *   e.g (aaaa):(bbbb):(cccc):....(hhhh)
9657
        *   (aaaa) = (ip[0<<8)|ip[1]
9658
        *   ......
9659
        *   (hhhh) = (ip[14]<<8)|(ip[15])
9660
        *
9661
        *   e.g ::(gggg):(hhhh)
9662
        *   ip[0]-[11] = 0
9663
        *   (gggg) = (ip[12]<<8) |(ip[13])
9664
        *   (hhhh) = (ip[14]<<8) |(ip[15])
9665
        *
9666
        *   Because it is not able to know which ivp6 scheme uses from data to
9667
        *   reconstruct IP address, this function assumes
9668
        *   ivp6 normal address scheme, not dual address scheme,
9669
        *   to re-construct IP address in ascii.
9670
        */
9671
        buf = (char*)XMALLOC(max_ipv6_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
9672
        if (!buf) {
9673
            WOLFSSL_MSG("failed malloc");
9674
            return ret;
9675
        }
9676
        p = buf;
9677
        for (i = 0; i < 16; i += 2) {
9678
            val = (((word32)(ip[i]<<8)) | (ip[i+1])) & 0xFFFF;
9679
            if (val == 0) {
9680
                if (!write_zero) {
9681
                    *p = ':';
9682
                }
9683
                p++;
9684
                *p = '\0';
9685
                write_zero = 1;
9686
            }
9687
            else {
9688
                if (i != 0) {
9689
                    *p++ = ':';
9690
                }
9691
                (void)XSNPRINTF(p, max_ipv6_len - (size_t)(p - buf), "%x", val);
9692
            }
9693
            /* sanity check */
9694
            if (XSTRLEN(buf) > max_ipv6_len) {
9695
                WOLFSSL_MSG("The target ip address exceeds buffer length(40)");
9696
                XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
9697
                buf = NULL;
9698
                break;
9699
            }
9700
            /* move the pointer to the last */
9701
            /* XSTRLEN includes NULL because of XSPRINTF use */
9702
            p = buf + (XSTRLEN(buf));
9703
        }
9704
        /* termination */
9705
        if (i == 16 && buf) {
9706
            p--;
9707
            if ((*p) == ':') {
9708
                /* when the last character is :, the following segments are zero
9709
                 * Therefore, adding : and null termination */
9710
                p++;
9711
                *p++ = ':';
9712
                *p = '\0';
9713
            }
9714
        }
9715
    }
9716
    else {
9717
        WOLFSSL_MSG("iplen is zero, do nothing");
9718
        return WOLFSSL_SUCCESS;
9719
    }
9720
9721
    if (buf) {
9722
        /* set address to ip asc */
9723
        ret = wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(param, buf);
9724
        XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
9725
    }
9726
#else
9727
    (void)param;
9728
    (void)ip;
9729
    (void)iplen;
9730
#endif
9731
9732
    return ret;
9733
}
9734
9735
#ifndef NO_WOLFSSL_STUB
9736
void wolfSSL_X509_OBJECT_free_contents(WOLFSSL_X509_OBJECT* obj)
9737
{
9738
    (void)obj;
9739
    WOLFSSL_STUB("X509_OBJECT_free_contents");
9740
}
9741
#endif
9742
9743
#ifndef NO_ASN_TIME
9744
int wolfSSL_X509_cmp_current_time(const WOLFSSL_ASN1_TIME* asnTime)
9745
{
9746
    return wolfSSL_X509_cmp_time(asnTime, NULL);
9747
}
9748
9749
/* return WOLFSSL_FATAL_ERROR if asnTime is earlier than or equal to cmpTime,
9750
 * and 1 otherwise
9751
 * return 0 on error
9752
 */
9753
int wolfSSL_X509_cmp_time(const WOLFSSL_ASN1_TIME* asnTime, time_t* cmpTime)
9754
{
9755
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
9756
    time_t tmpTime, *pTime = &tmpTime;
9757
    struct tm ts, *tmpTs, *ct;
9758
#if defined(NEED_TMP_TIME)
9759
    /* for use with gmtime_r */
9760
    struct tm tmpTimeStorage;
9761
9762
    tmpTs = &tmpTimeStorage;
9763
#else
9764
    tmpTs = NULL;
9765
#endif
9766
    (void)tmpTs;
9767
9768
    if (asnTime == NULL) {
9769
        return WOLFSSL_FAILURE;
9770
    }
9771
9772
    if (cmpTime == NULL) {
9773
        /* Use current time */
9774
        *pTime = wc_Time(0);
9775
    }
9776
    else {
9777
        pTime = cmpTime;
9778
    }
9779
9780
    if (wolfSSL_ASN1_TIME_to_tm((WOLFSSL_ASN1_TIME*)asnTime, &ts) !=
9781
                                                              WOLFSSL_SUCCESS) {
9782
        WOLFSSL_MSG("Failed to convert WOLFSSL_ASN1_TIME to struct tm.");
9783
        return WOLFSSL_FAILURE;
9784
    }
9785
9786
    /* Convert to time struct*/
9787
    ct = XGMTIME(pTime, tmpTs);
9788
9789
    if (ct == NULL)
9790
        return GETTIME_ERROR;
9791
9792
    /* DateGreaterThan returns 1 for >; 0 for <= */
9793
    ret = DateGreaterThan(&ts, ct) ? 1 : -1;
9794
9795
    return ret;
9796
}
9797
#endif /* !NO_ASN_TIME */
9798
9799
#if (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)) && \
9800
    !defined(NO_ASN_TIME) && !defined(USER_TIME) && !defined(TIME_OVERRIDES)
9801
WOLFSSL_ASN1_TIME *wolfSSL_X509_time_adj_ex(WOLFSSL_ASN1_TIME *asnTime,
9802
    int offset_day, long offset_sec, time_t *in_tm)
9803
{
9804
    /* get current time if in_tm is null */
9805
    time_t t = in_tm ? *in_tm : wc_Time(0);
9806
    return wolfSSL_ASN1_TIME_adj(asnTime, t, offset_day, offset_sec);
9807
}
9808
9809
WOLFSSL_ASN1_TIME *wolfSSL_X509_time_adj(WOLFSSL_ASN1_TIME *asnTime,
9810
    long offset_sec, time_t *in_tm)
9811
{
9812
    return wolfSSL_X509_time_adj_ex(asnTime, 0, offset_sec, in_tm);
9813
}
9814
9815
WOLFSSL_ASN1_TIME* wolfSSL_X509_gmtime_adj(WOLFSSL_ASN1_TIME *s, long adj)
9816
{
9817
    return wolfSSL_X509_time_adj(s, adj, NULL);
9818
}
9819
#endif
9820
9821
#ifndef NO_WOLFSSL_STUB
9822
int wolfSSL_sk_X509_REVOKED_num(WOLFSSL_X509_REVOKED* revoked)
9823
{
9824
    (void)revoked;
9825
    WOLFSSL_STUB("sk_X509_REVOKED_num");
9826
    return 0;
9827
}
9828
#endif
9829
9830
#ifndef NO_WOLFSSL_STUB
9831
WOLFSSL_X509_REVOKED* wolfSSL_X509_CRL_get_REVOKED(WOLFSSL_X509_CRL* crl)
9832
{
9833
    (void)crl;
9834
    WOLFSSL_STUB("X509_CRL_get_REVOKED");
9835
    return NULL;
9836
}
9837
#endif
9838
9839
#ifndef NO_WOLFSSL_STUB
9840
WOLFSSL_X509_REVOKED* wolfSSL_sk_X509_REVOKED_value(
9841
                                    WOLFSSL_X509_REVOKED* revoked, int value)
9842
{
9843
    (void)revoked;
9844
    (void)value;
9845
    WOLFSSL_STUB("sk_X509_REVOKED_value");
9846
    return NULL;
9847
}
9848
#endif
9849
9850
#endif /* OPENSSL_EXTRA */
9851
9852
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
9853
9854
WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509* x509)
9855
{
9856
    WOLFSSL_ASN1_INTEGER* a;
9857
    int i = 0;
9858
9859
    WOLFSSL_ENTER("wolfSSL_X509_get_serialNumber");
9860
9861
    if (x509 == NULL) {
9862
        WOLFSSL_MSG("NULL function argument");
9863
        return NULL;
9864
    }
9865
9866
    if (x509->serialNumber != NULL)
9867
       return x509->serialNumber;
9868
9869
    a = wolfSSL_ASN1_INTEGER_new();
9870
    if (a == NULL)
9871
        return NULL;
9872
9873
    /* Make sure there is space for the data, ASN.1 type and length. */
9874
    if (x509->serialSz > (WOLFSSL_ASN1_INTEGER_MAX - 2)) {
9875
        /* dynamically create data buffer, +2 for type and length */
9876
        a->data = (unsigned char*)XMALLOC(x509->serialSz + 2, NULL,
9877
                DYNAMIC_TYPE_OPENSSL);
9878
        if (a->data == NULL) {
9879
            wolfSSL_ASN1_INTEGER_free(a);
9880
            return NULL;
9881
        }
9882
        a->dataMax   = (unsigned int)x509->serialSz + 2;
9883
        a->isDynamic = 1;
9884
    }
9885
    else {
9886
        /* Use array instead of dynamic memory */
9887
        a->data    = a->intData;
9888
        a->dataMax = WOLFSSL_ASN1_INTEGER_MAX;
9889
    }
9890
9891
    #if defined(WOLFSSL_QT) || defined(WOLFSSL_HAPROXY)
9892
        XMEMCPY(&a->data[i], x509->serial, x509->serialSz);
9893
        a->length = x509->serialSz;
9894
    #else
9895
        a->data[i++] = ASN_INTEGER;
9896
        i += SetLength(x509->serialSz, a->data + i);
9897
        XMEMCPY(&a->data[i], x509->serial, x509->serialSz);
9898
        a->length = x509->serialSz + 2;
9899
    #endif
9900
9901
    x509->serialNumber = a;
9902
9903
    return a;
9904
}
9905
9906
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
9907
9908
#ifdef OPENSSL_EXTRA
9909
9910
#if defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD) \
9911
    || defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_WPAS)
9912
WOLFSSL_X509_ALGOR* wolfSSL_X509_ALGOR_new(void)
9913
{
9914
    WOLFSSL_X509_ALGOR* ret;
9915
    ret = (WOLFSSL_X509_ALGOR*)XMALLOC(sizeof(WOLFSSL_X509_ALGOR), NULL,
9916
                                       DYNAMIC_TYPE_OPENSSL);
9917
    if (ret) {
9918
        XMEMSET(ret, 0, sizeof(WOLFSSL_X509_ALGOR));
9919
    }
9920
    return ret;
9921
}
9922
9923
void wolfSSL_X509_ALGOR_free(WOLFSSL_X509_ALGOR *alg)
9924
{
9925
    if (alg) {
9926
        wolfSSL_ASN1_OBJECT_free(alg->algorithm);
9927
        wolfSSL_ASN1_TYPE_free(alg->parameter);
9928
        XFREE(alg, NULL, DYNAMIC_TYPE_OPENSSL);
9929
    }
9930
}
9931
9932
/* Returns X509_ALGOR struct with signature algorithm */
9933
const WOLFSSL_X509_ALGOR* wolfSSL_X509_get0_tbs_sigalg(const WOLFSSL_X509 *x509)
9934
{
9935
    WOLFSSL_ENTER("wolfSSL_X509_get0_tbs_sigalg");
9936
9937
    if (x509 == NULL) {
9938
        WOLFSSL_MSG("x509 struct NULL error");
9939
        return NULL;
9940
    }
9941
9942
    return &x509->algor;
9943
}
9944
9945
/* Sets paobj pointer to X509_ALGOR signature algorithm */
9946
void wolfSSL_X509_ALGOR_get0(const WOLFSSL_ASN1_OBJECT **paobj, int *pptype,
9947
                            const void **ppval, const WOLFSSL_X509_ALGOR *algor)
9948
{
9949
    WOLFSSL_ENTER("wolfSSL_X509_ALGOR_get0");
9950
9951
    if (!algor) {
9952
        WOLFSSL_MSG("algor object is NULL");
9953
        return;
9954
    }
9955
9956
    if (paobj)
9957
        *paobj = algor->algorithm;
9958
    if (ppval && algor->parameter)
9959
        *ppval = algor->parameter->value.ptr;
9960
    if (pptype) {
9961
        if (algor->parameter) {
9962
            *pptype = algor->parameter->type;
9963
        }
9964
        else {
9965
            /* Default to WOLFSSL_V_ASN1_OBJECT */
9966
            *pptype = WOLFSSL_V_ASN1_OBJECT;
9967
        }
9968
    }
9969
}
9970
9971
/**
9972
 * Populate algor members.
9973
 *
9974
 * @param algor The object to be set
9975
 * @param aobj The value to be set in algor->algorithm
9976
 * @param ptype The type of algor->parameter
9977
 * @param pval The value of algor->parameter
9978
 * @return WOLFSSL_SUCCESS on success
9979
 *         WOLFSSL_FAILURE on missing parameters or bad malloc
9980
 */
9981
int wolfSSL_X509_ALGOR_set0(WOLFSSL_X509_ALGOR *algor,
9982
                            WOLFSSL_ASN1_OBJECT *aobj, int ptype, void *pval)
9983
{
9984
    if (!algor) {
9985
        return WOLFSSL_FAILURE;
9986
    }
9987
9988
    if (!algor->parameter) {
9989
        algor->parameter = wolfSSL_ASN1_TYPE_new();
9990
        if (!algor->parameter) {
9991
            return WOLFSSL_FAILURE;
9992
        }
9993
    }
9994
9995
    if (aobj) {
9996
        algor->algorithm = aobj;
9997
    }
9998
    wolfSSL_ASN1_TYPE_set(algor->parameter, ptype, pval);
9999
10000
    return WOLFSSL_SUCCESS;
10001
}
10002
10003
/**
10004
 * Serialize object to DER encoding
10005
 *
10006
 * @param alg Object to serialize
10007
 * @param pp  Output
10008
 * @return Length on success
10009
 *         Negative number on failure
10010
 */
10011
int wolfSSL_i2d_X509_ALGOR(const WOLFSSL_X509_ALGOR* alg,
10012
        unsigned char** pp)
10013
{
10014
    int len;
10015
    word32 oid = 0;
10016
    word32 idx = 0;
10017
    unsigned char* buf = NULL;
10018
10019
    if (alg == NULL || alg->algorithm == 0) {
10020
        WOLFSSL_MSG("alg is NULL or algorithm not set");
10021
        return WOLFSSL_FATAL_ERROR;
10022
    }
10023
10024
    if (GetObjectId(alg->algorithm->obj, &idx, &oid,
10025
            (word32)alg->algorithm->grp, alg->algorithm->objSz) < 0) {
10026
        WOLFSSL_MSG("Issue getting OID of object");
10027
        return WOLFSSL_FATAL_ERROR;
10028
    }
10029
10030
    len = (int)SetAlgoID((int)oid, NULL, alg->algorithm->grp, 0);
10031
    if (len == 0) {
10032
        WOLFSSL_MSG("SetAlgoID error");
10033
        return WOLFSSL_FATAL_ERROR;
10034
    }
10035
10036
    if (pp != NULL) {
10037
        if (*pp != NULL)
10038
            buf = *pp;
10039
        else {
10040
            buf = (byte*)XMALLOC((size_t)len, NULL, DYNAMIC_TYPE_ASN1);
10041
            if (buf == NULL)
10042
                return WOLFSSL_FATAL_ERROR;
10043
        }
10044
10045
        len = (int)SetAlgoID((int)oid, buf, alg->algorithm->grp, 0);
10046
        if (len == 0) {
10047
            WOLFSSL_MSG("SetAlgoID error");
10048
            if (*pp == NULL)
10049
                XFREE(buf, NULL, DYNAMIC_TYPE_ASN1);
10050
            return WOLFSSL_FATAL_ERROR;
10051
        }
10052
10053
        if (*pp != NULL)
10054
            *pp += len;
10055
        else
10056
            *pp = buf;
10057
    }
10058
10059
    return len;
10060
}
10061
10062
WOLFSSL_X509_ALGOR* wolfSSL_d2i_X509_ALGOR(WOLFSSL_X509_ALGOR** out,
10063
        const byte** src, long len)
10064
{
10065
    WOLFSSL_X509_ALGOR* ret = NULL;
10066
    word32 idx = 0;
10067
    word32 oid = 0;
10068
    int grp;
10069
10070
    WOLFSSL_ENTER("wolfSSL_d2i_X509_ALGOR");
10071
10072
    if (src == NULL || *src == NULL || len == 0)
10073
        return NULL;
10074
10075
    if (GetAlgoId(*src, &idx, &oid, oidIgnoreType, (word32)len) != 0)
10076
        return NULL;
10077
10078
    /* Try to guess the type */
10079
    for (grp = 0; grp < oidIgnoreType; grp++) {
10080
        word32 oidSz;
10081
        if (OidFromId(oid, (word32)grp, &oidSz) != NULL)
10082
            break;
10083
    }
10084
    if (grp == oidIgnoreType)
10085
        return NULL;
10086
10087
    ret = wolfSSL_X509_ALGOR_new();
10088
    if (ret == NULL)
10089
        return NULL;
10090
10091
    ret->algorithm = wolfSSL_OBJ_nid2obj(oid2nid(oid, grp));
10092
    if (ret->algorithm == NULL) {
10093
        wolfSSL_X509_ALGOR_free(ret);
10094
        return NULL;
10095
    }
10096
    *src += idx;
10097
10098
    if (out != NULL) {
10099
        if (*out != NULL)
10100
            wolfSSL_X509_ALGOR_free(*out);
10101
        *out = ret;
10102
    }
10103
10104
    return ret;
10105
}
10106
10107
/**
10108
 * Allocate a new WOLFSSL_X509_PUBKEY object.
10109
 *
10110
 * @return New zero'ed WOLFSSL_X509_PUBKEY object
10111
 */
10112
WOLFSSL_X509_PUBKEY *wolfSSL_X509_PUBKEY_new(void)
10113
{
10114
    WOLFSSL_X509_PUBKEY *ret;
10115
    ret = (WOLFSSL_X509_PUBKEY*)XMALLOC(sizeof(WOLFSSL_X509_PUBKEY), NULL,
10116
                                        DYNAMIC_TYPE_OPENSSL);
10117
    if (!ret) {
10118
        return NULL;
10119
    }
10120
    XMEMSET(ret, 0, sizeof(WOLFSSL_X509_PUBKEY));
10121
    ret->algor = wolfSSL_X509_ALGOR_new();
10122
    if (!ret->algor) {
10123
        wolfSSL_X509_PUBKEY_free(ret);
10124
        return NULL;
10125
    }
10126
    return ret;
10127
}
10128
10129
/**
10130
 * Free WOLFSSL_X509_PUBKEY and all its members.
10131
 *
10132
 * @param at Object to free
10133
 */
10134
void wolfSSL_X509_PUBKEY_free(WOLFSSL_X509_PUBKEY *x)
10135
{
10136
    if (x) {
10137
        if (x->algor) {
10138
            wolfSSL_X509_ALGOR_free(x->algor);
10139
        }
10140
        if (x->pkey) {
10141
            wolfSSL_EVP_PKEY_free(x->pkey);
10142
        }
10143
        XFREE(x, NULL, DYNAMIC_TYPE_OPENSSL);
10144
    }
10145
}
10146
10147
/* Returns X509_PUBKEY structure containing X509_ALGOR and EVP_PKEY */
10148
WOLFSSL_X509_PUBKEY* wolfSSL_X509_get_X509_PUBKEY(const WOLFSSL_X509* x509)
10149
{
10150
    WOLFSSL_ENTER("wolfSSL_X509_get_X509_PUBKEY");
10151
10152
    if (x509 == NULL) {
10153
        WOLFSSL_MSG("x509 struct NULL error");
10154
        return NULL;
10155
    }
10156
10157
    return (WOLFSSL_X509_PUBKEY*)&x509->key;
10158
}
10159
10160
/* Sets ppkalg pointer to X509_PUBKEY algorithm. Returns WOLFSSL_SUCCESS on
10161
    success or WOLFSSL_FAILURE on error. */
10162
int wolfSSL_X509_PUBKEY_get0_param(WOLFSSL_ASN1_OBJECT **ppkalg,
10163
     const unsigned char **pk, int *ppklen, WOLFSSL_X509_ALGOR **pa,
10164
     WOLFSSL_X509_PUBKEY *pub)
10165
{
10166
    WOLFSSL_ENTER("wolfSSL_X509_PUBKEY_get0_param");
10167
10168
    if (!pub || !pub->pubKeyOID) {
10169
        WOLFSSL_MSG("X509_PUBKEY struct not populated");
10170
        return WOLFSSL_FAILURE;
10171
    }
10172
10173
    if (!pub->algor) {
10174
        if (!(pub->algor = wolfSSL_X509_ALGOR_new())) {
10175
            return WOLFSSL_FAILURE;
10176
        }
10177
        pub->algor->algorithm = wolfSSL_OBJ_nid2obj(pub->pubKeyOID);
10178
        if (pub->algor->algorithm == NULL) {
10179
            WOLFSSL_MSG("Failed to create object from NID");
10180
            return WOLFSSL_FAILURE;
10181
        }
10182
    }
10183
10184
    if (pa)
10185
        *pa = pub->algor;
10186
    if (ppkalg)
10187
        *ppkalg = pub->algor->algorithm;
10188
    if (pk)
10189
        *pk = (unsigned char*)pub->pkey->pkey.ptr;
10190
    if (ppklen)
10191
        *ppklen = pub->pkey->pkey_sz;
10192
10193
    return WOLFSSL_SUCCESS;
10194
}
10195
10196
/* Returns a pointer to the pkey when passed a key */
10197
WOLFSSL_EVP_PKEY* wolfSSL_X509_PUBKEY_get(WOLFSSL_X509_PUBKEY* key)
10198
{
10199
    WOLFSSL_ENTER("wolfSSL_X509_PUBKEY_get");
10200
    if (key == NULL || key->pkey == NULL) {
10201
        WOLFSSL_LEAVE("wolfSSL_X509_PUBKEY_get", BAD_FUNC_ARG);
10202
        return NULL;
10203
    }
10204
    if (wolfSSL_EVP_PKEY_up_ref(key->pkey) != WOLFSSL_SUCCESS) {
10205
        WOLFSSL_LEAVE("wolfSSL_X509_PUBKEY_get", BAD_MUTEX_E);
10206
        return NULL;
10207
    }
10208
    WOLFSSL_LEAVE("wolfSSL_X509_PUBKEY_get", WOLFSSL_SUCCESS);
10209
    return key->pkey;
10210
}
10211
10212
int wolfSSL_X509_PUBKEY_set(WOLFSSL_X509_PUBKEY **x, WOLFSSL_EVP_PKEY *key)
10213
{
10214
    WOLFSSL_X509_PUBKEY *pk = NULL;
10215
    int ptype;
10216
    void *pval;
10217
#ifndef NO_DSA
10218
    WOLFSSL_ASN1_STRING *str;
10219
#endif
10220
#ifdef HAVE_ECC
10221
    int nid;
10222
    const WOLFSSL_EC_GROUP *group;
10223
#endif
10224
    WOLFSSL_ASN1_OBJECT *keyTypeObj;
10225
10226
    WOLFSSL_ENTER("wolfSSL_X509_PUBKEY_set");
10227
10228
    if (!x || !key) {
10229
        return WOLFSSL_FAILURE;
10230
    }
10231
10232
    if (!(pk = wolfSSL_X509_PUBKEY_new())) {
10233
        return WOLFSSL_FAILURE;
10234
    }
10235
10236
    switch (key->type) {
10237
#ifndef NO_RSA
10238
    case WC_EVP_PKEY_RSA:
10239
        pval = NULL;
10240
        ptype = WOLFSSL_V_ASN1_NULL;
10241
        pk->pubKeyOID = RSAk;
10242
        break;
10243
#endif
10244
#ifndef NO_DSA
10245
    case WC_EVP_PKEY_DSA:
10246
        if (!key->dsa->p || !key->dsa->q || !key->dsa->g)
10247
            goto error;
10248
10249
        str = wolfSSL_ASN1_STRING_new();
10250
        if (str == NULL)
10251
            goto error;
10252
10253
        str->length = wolfSSL_i2d_DSAparams(key->dsa,
10254
             (unsigned char **)&str->data);
10255
        if (str->length <= 0) {
10256
            wolfSSL_ASN1_STRING_free(str);
10257
            goto error;
10258
        }
10259
        str->isDynamic = 1;
10260
10261
        pval = str;
10262
        ptype = WOLFSSL_V_ASN1_SEQUENCE;
10263
        pk->pubKeyOID = DSAk;
10264
        break;
10265
#endif
10266
#ifdef HAVE_ECC
10267
    case WC_EVP_PKEY_EC:
10268
        group = wolfSSL_EC_KEY_get0_group(key->ecc);
10269
        if (!group)
10270
            goto error;
10271
10272
        nid = wolfSSL_EC_GROUP_get_curve_name(group);
10273
        if (nid <= 0) {
10274
            /* TODO: Add support for no nid case */
10275
            WOLFSSL_MSG("nid not found");
10276
            goto error;
10277
        }
10278
10279
        pval = wolfSSL_OBJ_nid2obj(nid);
10280
        if (!pval)
10281
            goto error;
10282
10283
        ptype = WOLFSSL_V_ASN1_OBJECT;
10284
        pk->pubKeyOID = ECDSAk;
10285
        break;
10286
#endif
10287
    default:
10288
        WOLFSSL_MSG("Unknown key type");
10289
        goto error;
10290
    }
10291
10292
    keyTypeObj = wolfSSL_OBJ_nid2obj(key->type);
10293
    if (keyTypeObj == NULL) {
10294
        if (ptype == WOLFSSL_V_ASN1_OBJECT)
10295
            ASN1_OBJECT_free((WOLFSSL_ASN1_OBJECT *)pval);
10296
        else
10297
            ASN1_STRING_free((WOLFSSL_ASN1_STRING *)pval);
10298
        goto error;
10299
    }
10300
    if (!wolfSSL_X509_ALGOR_set0(pk->algor, keyTypeObj, ptype, pval)) {
10301
        WOLFSSL_MSG("Failed to create algorithm object");
10302
        ASN1_OBJECT_free(keyTypeObj);
10303
        if (ptype == WOLFSSL_V_ASN1_OBJECT)
10304
            ASN1_OBJECT_free((WOLFSSL_ASN1_OBJECT *)pval);
10305
        else
10306
            ASN1_STRING_free((WOLFSSL_ASN1_STRING *)pval);
10307
        goto error;
10308
    }
10309
10310
    if (!wolfSSL_EVP_PKEY_up_ref(key)) {
10311
        WOLFSSL_MSG("Failed to up key reference");
10312
        goto error;
10313
    }
10314
    pk->pkey = key;
10315
10316
    wolfSSL_X509_PUBKEY_free(*x);
10317
    *x = pk;
10318
    return WOLFSSL_SUCCESS;
10319
error:
10320
    if (pk) {
10321
        wolfSSL_X509_PUBKEY_free(pk);
10322
    }
10323
    return WOLFSSL_FAILURE;
10324
}
10325
10326
#endif /* OPENSSL_ALL || WOLFSSL_APACHE_HTTPD || WOLFSSL_HAPROXY ||
10327
        * WOLFSSL_WPAS */
10328
10329
#if !defined(NO_CERTS) && !defined(NO_ASN) && !defined(NO_PWDBASED)
10330
10331
int wolfSSL_i2d_X509_PUBKEY(WOLFSSL_X509_PUBKEY* x509_PubKey,
10332
    unsigned char** der)
10333
{
10334
    if (x509_PubKey == NULL)
10335
        return WOLFSSL_FATAL_ERROR;
10336
    return wolfSSL_i2d_PublicKey(x509_PubKey->pkey, der);
10337
}
10338
10339
#endif /* !NO_CERTS && !NO_ASN && !NO_PWDBASED */
10340
10341
#endif /* OPENSSL_EXTRA */
10342
10343
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
10344
WOLFSSL_BASIC_CONSTRAINTS* wolfSSL_BASIC_CONSTRAINTS_new(void)
10345
{
10346
    WOLFSSL_BASIC_CONSTRAINTS* bc;
10347
    bc = (WOLFSSL_BASIC_CONSTRAINTS*)
10348
          XMALLOC(sizeof(WOLFSSL_BASIC_CONSTRAINTS), NULL,
10349
          DYNAMIC_TYPE_X509_EXT);
10350
    if (bc == NULL) {
10351
        WOLFSSL_MSG("Failed to malloc basic constraints");
10352
        return NULL;
10353
    }
10354
    XMEMSET(bc, 0, sizeof(WOLFSSL_BASIC_CONSTRAINTS));
10355
    return bc;
10356
}
10357
10358
/* frees the wolfSSL_BASIC_CONSTRAINTS object */
10359
void wolfSSL_BASIC_CONSTRAINTS_free(WOLFSSL_BASIC_CONSTRAINTS *bc)
10360
{
10361
    WOLFSSL_ENTER("wolfSSL_BASIC_CONSTRAINTS_free");
10362
    if (bc == NULL) {
10363
        WOLFSSL_MSG("Argument is NULL");
10364
        return;
10365
    }
10366
    if (bc->pathlen) {
10367
        wolfSSL_ASN1_INTEGER_free(bc->pathlen);
10368
    }
10369
    XFREE(bc, NULL, DYNAMIC_TYPE_OPENSSL);
10370
}
10371
10372
WOLFSSL_AUTHORITY_KEYID* wolfSSL_AUTHORITY_KEYID_new(void)
10373
{
10374
    WOLFSSL_AUTHORITY_KEYID* akey = (WOLFSSL_AUTHORITY_KEYID*)XMALLOC(
10375
          sizeof(WOLFSSL_AUTHORITY_KEYID), NULL, DYNAMIC_TYPE_OPENSSL);
10376
    if (!akey) {
10377
        WOLFSSL_MSG("Issue creating WOLFSSL_AUTHORITY_KEYID struct");
10378
        return NULL;
10379
    }
10380
    XMEMSET(akey, 0, sizeof(WOLFSSL_AUTHORITY_KEYID));
10381
    return akey;
10382
}
10383
10384
/* frees the wolfSSL_AUTHORITY_KEYID object */
10385
void wolfSSL_AUTHORITY_KEYID_free(WOLFSSL_AUTHORITY_KEYID *id)
10386
{
10387
    WOLFSSL_ENTER("wolfSSL_AUTHORITY_KEYID_free");
10388
    if (id == NULL) {
10389
        WOLFSSL_MSG("Argument is NULL");
10390
        return;
10391
    }
10392
    if (id->keyid) {
10393
        wolfSSL_ASN1_STRING_free(id->keyid);
10394
    }
10395
    if (id->issuer) {
10396
        wolfSSL_ASN1_OBJECT_free(id->issuer);
10397
    }
10398
    if (id->serial) {
10399
        wolfSSL_ASN1_INTEGER_free(id->serial);
10400
    }
10401
    XFREE(id, NULL, DYNAMIC_TYPE_OPENSSL);
10402
}
10403
10404
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
10405
10406
#ifdef KEEP_PEER_CERT
10407
char*  wolfSSL_X509_get_subjectCN(WOLFSSL_X509* x509)
10408
{
10409
    if (x509 == NULL)
10410
        return NULL;
10411
10412
    return x509->subjectCN;
10413
}
10414
#endif /* KEEP_PEER_CERT */
10415
10416
#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA)
10417
/* increments ref count of WOLFSSL_X509. Return 1 on success, 0 on error */
10418
int wolfSSL_X509_up_ref(WOLFSSL_X509* x509)
10419
{
10420
    if (x509) {
10421
        int ret;
10422
        wolfSSL_RefInc(&x509->ref, &ret);
10423
        if (ret != 0) {
10424
            WOLFSSL_MSG("Failed to lock x509 mutex");
10425
            return WOLFSSL_FAILURE;
10426
        }
10427
10428
        return WOLFSSL_SUCCESS;
10429
    }
10430
10431
    return WOLFSSL_FAILURE;
10432
}
10433
#endif /* OPENSSL_EXTRA_X509_SMALL || OPENSSL_EXTRA */
10434
10435
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
10436
WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_chain_up_ref(
10437
        WOLF_STACK_OF(WOLFSSL_X509)* chain)
10438
{
10439
    /* wolfSSL_sk_dup takes care of doing a deep copy */
10440
    return wolfSSL_sk_dup(chain);
10441
}
10442
#endif
10443
10444
#if defined(OPENSSL_EXTRA)
10445
10446
WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* wolfSSL_sk_X509_OBJECT_deep_copy(
10447
    const WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk,
10448
    WOLFSSL_X509_OBJECT* (*c)(const WOLFSSL_X509_OBJECT*),
10449
    void (*f)(WOLFSSL_X509_OBJECT*))
10450
{
10451
    (void)f; /* free function */
10452
    (void)c; /* copy function */
10453
    return wolfSSL_sk_dup((WOLFSSL_STACK*)sk);
10454
}
10455
#endif
10456
10457
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
10458
    void wolfSSL_X509_NAME_free(WOLFSSL_X509_NAME *name)
10459
    {
10460
        WOLFSSL_ENTER("wolfSSL_X509_NAME_free");
10461
        FreeX509Name(name);
10462
        if (name != NULL) {
10463
            XFREE(name, name->heap, DYNAMIC_TYPE_X509);
10464
        }
10465
    }
10466
10467
10468
    /* Malloc's a new WOLFSSL_X509_NAME structure
10469
     *
10470
     * returns NULL on failure, otherwise returns a new structure.
10471
     */
10472
    WOLFSSL_X509_NAME* wolfSSL_X509_NAME_new_ex(void *heap)
10473
    {
10474
        WOLFSSL_X509_NAME* name;
10475
10476
        WOLFSSL_ENTER("wolfSSL_X509_NAME_new_ex");
10477
10478
        name = (WOLFSSL_X509_NAME*)XMALLOC(sizeof(WOLFSSL_X509_NAME), heap,
10479
                DYNAMIC_TYPE_X509);
10480
        if (name != NULL) {
10481
            InitX509Name(name, 1, heap);
10482
        }
10483
        return name;
10484
    }
10485
10486
    WOLFSSL_X509_NAME* wolfSSL_X509_NAME_new(void) {
10487
        return wolfSSL_X509_NAME_new_ex(NULL);
10488
    }
10489
10490
    /* Creates a duplicate of a WOLFSSL_X509_NAME structure.
10491
       Returns a new WOLFSSL_X509_NAME structure or NULL on failure */
10492
    WOLFSSL_X509_NAME* wolfSSL_X509_NAME_dup(WOLFSSL_X509_NAME *name)
10493
    {
10494
        WOLFSSL_X509_NAME* copy = NULL;
10495
10496
        WOLFSSL_ENTER("wolfSSL_X509_NAME_dup");
10497
10498
        if (name == NULL) {
10499
            WOLFSSL_MSG("NULL parameter");
10500
            return NULL;
10501
        }
10502
10503
        if (!(copy = wolfSSL_X509_NAME_new_ex(name->heap))) {
10504
            return NULL;
10505
        }
10506
10507
        /* copy contents */
10508
        InitX509Name(copy, 1, name->heap);
10509
        if (wolfSSL_X509_NAME_copy(name, copy) != WOLFSSL_SUCCESS) {
10510
            wolfSSL_X509_NAME_free(copy);
10511
            return NULL;
10512
        }
10513
10514
        return copy;
10515
    }
10516
10517
#ifdef WOLFSSL_CERT_GEN
10518
10519
#if defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT) || \
10520
    defined(OPENSSL_EXTRA)
10521
    /* Helper function to copy cert name from a WOLFSSL_X509_NAME structure to
10522
    * a Cert structure.
10523
    *
10524
    * returns length of DER on success and a negative error value on failure
10525
    */
10526
    static int CopyX509NameToCert(WOLFSSL_X509_NAME* n, byte* out)
10527
    {
10528
        unsigned char* der = NULL;
10529
        int length = WC_NO_ERR_TRACE(BAD_FUNC_ARG), ret;
10530
        word32 idx = 0;
10531
10532
        ret = wolfSSL_i2d_X509_NAME(n, &der);
10533
        if (ret > (int)sizeof(CertName) || ret < 0) {
10534
            WOLFSSL_MSG("Name conversion error");
10535
            ret = MEMORY_E;
10536
        }
10537
10538
        if (ret > 0) {
10539
            /* strip off sequence, this gets added on certificate creation */
10540
            ret = GetSequence(der, &idx, &length, (word32)ret);
10541
        }
10542
10543
        if (ret > 0) {
10544
            XMEMCPY(out, der + idx, length);
10545
        }
10546
10547
        XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
10548
10549
        return length;
10550
    }
10551
#endif
10552
10553
#ifdef WOLFSSL_CERT_REQ
10554
    static int ReqCertFromX509(Cert* cert, WOLFSSL_X509* req)
10555
    {
10556
        int ret;
10557
10558
        if (wc_InitCert(cert) != 0)
10559
            return WOLFSSL_FAILURE;
10560
10561
10562
        ret = CopyX509NameToCert(&req->subject, cert->sbjRaw);
10563
        if (ret < 0) {
10564
            WOLFSSL_MSG("REQ subject conversion error");
10565
            ret = MEMORY_E;
10566
        }
10567
        else {
10568
            ret = WOLFSSL_SUCCESS;
10569
        }
10570
10571
        if (ret == WOLFSSL_SUCCESS) {
10572
        #if defined(OPENSSL_ALL)
10573
            int idx;
10574
        #endif
10575
10576
            cert->version = req->version;
10577
            cert->isCA = req->isCa;
10578
            cert->basicConstSet = req->basicConstSet;
10579
    #ifdef WOLFSSL_CERT_EXT
10580
            if (req->subjKeyIdSz != 0) {
10581
                XMEMCPY(cert->skid, req->subjKeyId, req->subjKeyIdSz);
10582
                cert->skidSz = (int)req->subjKeyIdSz;
10583
            }
10584
            if (req->keyUsageSet)
10585
                cert->keyUsage = req->keyUsage;
10586
10587
            cert->extKeyUsage = req->extKeyUsage;
10588
    #endif
10589
10590
            XMEMCPY(cert->challengePw, req->challengePw, CTC_NAME_SIZE);
10591
            cert->challengePwPrintableString = req->challengePw[0] != 0;
10592
10593
        #if defined(OPENSSL_ALL)
10594
            idx = wolfSSL_X509_REQ_get_attr_by_NID(req,
10595
                    WC_NID_pkcs9_unstructuredName, -1);
10596
            if (idx != WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) {
10597
                WOLFSSL_X509_ATTRIBUTE *attr;
10598
                attr = wolfSSL_X509_REQ_get_attr(req, idx);
10599
                if (attr != NULL) {
10600
                    const unsigned char *attrData;
10601
                    int attrDataSz;
10602
10603
                    attrData = wolfSSL_ASN1_STRING_get0_data(
10604
                            attr->value->value.asn1_string);
10605
                    attrDataSz = wolfSSL_ASN1_STRING_length(
10606
                            attr->value->value.asn1_string);
10607
10608
                    /* +1 to make sure is terminated string */
10609
                    if (attrDataSz + 1 > CTC_NAME_SIZE) {
10610
                        WOLFSSL_MSG("attribute size was too large to copy");
10611
                        ret = REQ_ATTRIBUTE_E;
10612
                    }
10613
                    else {
10614
                        XMEMCPY(cert->unstructuredName, attrData, attrDataSz);
10615
                        cert->unstructuredName[attrDataSz] = '\0';
10616
                    }
10617
                }
10618
            }
10619
10620
        #ifdef WOLFSSL_CUSTOM_OID
10621
            if (ret == WOLFSSL_SUCCESS) {
10622
                if ((req->customExtCount < 0) ||
10623
                    (req->customExtCount >= NUM_CUSTOM_EXT)) {
10624
                    WOLFSSL_MSG("Bad value for customExtCount.");
10625
                    ret = WOLFSSL_FAILURE;
10626
                }
10627
10628
                if (ret == WOLFSSL_SUCCESS) {
10629
                    for (idx = 0; idx < req->customExtCount; idx++) {
10630
                        /* Note that ownership is NOT transferred.
10631
                         * req->custom_exts buffers still need to be cleaned
10632
                         * up. */
10633
                        cert->customCertExt[idx] = req->custom_exts[idx];
10634
                    }
10635
                    cert->customCertExtCount = req->customExtCount;
10636
                }
10637
            }
10638
        #endif /* WOLFSSL_CUSTOM_OID */
10639
        #endif /* OPENSSL_ALL */
10640
10641
    #ifdef WOLFSSL_ALT_NAMES
10642
            if (ret == WOLFSSL_SUCCESS) {
10643
                cert->altNamesSz = FlattenAltNames(cert->altNames,
10644
                        sizeof(cert->altNames), req->altNames);
10645
            }
10646
    #endif /* WOLFSSL_ALT_NAMES */
10647
        }
10648
10649
        return ret;
10650
    }
10651
#endif /* WOLFSSL_CERT_REQ */
10652
10653
/* converts WOLFSSL_AN1_TIME to Cert form, returns positive size on
10654
 * success */
10655
static int CertDateFromX509(byte* out, int outSz, WOLFSSL_ASN1_TIME* t)
10656
{
10657
    int sz, i;
10658
10659
    if (t->length + 1 >= outSz) {
10660
        return BUFFER_E;
10661
    }
10662
10663
    out[0] = (byte) t->type;
10664
    sz = (int)SetLength((word32)t->length, out + 1) + 1;  /* gen tag */
10665
    for (i = 0; i < t->length; i++) {
10666
        out[sz + i] = t->data[i];
10667
    }
10668
    return t->length + sz;
10669
}
10670
10671
/* convert a WOLFSSL_X509 to a Cert structure for writing out */
10672
static int CertFromX509(Cert* cert, WOLFSSL_X509* x509)
10673
{
10674
    int ret;
10675
#ifdef WOLFSSL_CERT_EXT
10676
    int i;
10677
#endif
10678
10679
    WOLFSSL_ENTER("wolfSSL_X509_to_Cert");
10680
10681
    if (x509 == NULL || cert == NULL) {
10682
        return BAD_FUNC_ARG;
10683
    }
10684
10685
    wc_InitCert(cert);
10686
10687
    cert->version = (int)wolfSSL_X509_get_version(x509);
10688
10689
    if (x509->notBefore.length > 0) {
10690
        cert->beforeDateSz = CertDateFromX509(cert->beforeDate,
10691
                    CTC_DATE_SIZE, &x509->notBefore);
10692
        if (cert->beforeDateSz <= 0) {
10693
            WOLFSSL_MSG("Error converting WOLFSSL_X509 not before date");
10694
            return WOLFSSL_FAILURE;
10695
        }
10696
    }
10697
    else {
10698
        cert->beforeDateSz = 0;
10699
    }
10700
10701
    if (x509->notAfter.length > 0) {
10702
        cert->afterDateSz = CertDateFromX509(cert->afterDate,
10703
                    CTC_DATE_SIZE, &x509->notAfter);
10704
        if (cert->afterDateSz <= 0) {
10705
            WOLFSSL_MSG("Error converting WOLFSSL_X509 not after date");
10706
            return WOLFSSL_FAILURE;
10707
        }
10708
    }
10709
    else {
10710
        cert->afterDateSz = 0;
10711
    }
10712
10713
#ifdef WOLFSSL_ALT_NAMES
10714
    cert->altNamesSz = FlattenAltNames(cert->altNames,
10715
            sizeof(cert->altNames), x509->altNames);
10716
#endif /* WOLFSSL_ALT_NAMES */
10717
10718
    cert->sigType = wolfSSL_X509_get_signature_type(x509);
10719
    cert->keyType = x509->pubKeyOID;
10720
    cert->isCA    = wolfSSL_X509_get_isCA(x509);
10721
    cert->basicConstCrit = x509->basicConstCrit;
10722
    cert->basicConstSet = x509->basicConstSet;
10723
    cert->pathLen = x509->pathLength;
10724
    cert->pathLenSet = x509->pathLengthSet;
10725
10726
#ifdef WOLFSSL_CERT_EXT
10727
    if (x509->subjKeyIdSz <= CTC_MAX_SKID_SIZE) {
10728
        if (x509->subjKeyId) {
10729
            XMEMCPY(cert->skid, x509->subjKeyId, x509->subjKeyIdSz);
10730
        }
10731
        cert->skidSz = (int)x509->subjKeyIdSz;
10732
    }
10733
    else {
10734
        WOLFSSL_MSG("Subject Key ID too large");
10735
        WOLFSSL_ERROR_VERBOSE(BUFFER_E);
10736
        return WOLFSSL_FAILURE;
10737
    }
10738
10739
    if (x509->authKeyIdSz < sizeof(cert->akid)) {
10740
    #ifdef WOLFSSL_AKID_NAME
10741
        cert->rawAkid = 0;
10742
        if (x509->authKeyIdSrc) {
10743
            XMEMCPY(cert->akid, x509->authKeyIdSrc, x509->authKeyIdSrcSz);
10744
            cert->akidSz = (int)x509->authKeyIdSrcSz;
10745
            cert->rawAkid = 1;
10746
        }
10747
        else
10748
    #endif
10749
        if (x509->authKeyId) {
10750
            XMEMCPY(cert->akid, x509->authKeyId, x509->authKeyIdSz);
10751
            cert->akidSz = (int)x509->authKeyIdSz;
10752
        }
10753
    }
10754
    else {
10755
        WOLFSSL_MSG("Auth Key ID too large");
10756
        WOLFSSL_ERROR_VERBOSE(BUFFER_E);
10757
        return WOLFSSL_FAILURE;
10758
    }
10759
10760
    for (i = 0; i < x509->certPoliciesNb; i++) {
10761
        /* copy the smaller of MAX macros, by default they are currently equal*/
10762
        if ((int)CTC_MAX_CERTPOL_SZ <= (int)MAX_CERTPOL_SZ) {
10763
            XMEMCPY(cert->certPolicies[i], x509->certPolicies[i],
10764
                    CTC_MAX_CERTPOL_SZ);
10765
        }
10766
        else {
10767
            XMEMCPY(cert->certPolicies[i], x509->certPolicies[i],
10768
                    MAX_CERTPOL_SZ);
10769
        }
10770
    }
10771
    cert->certPoliciesNb = (word16)x509->certPoliciesNb;
10772
10773
    cert->keyUsage = x509->keyUsage;
10774
    cert->extKeyUsage = x509->extKeyUsage;
10775
    cert->nsCertType = x509->nsCertType;
10776
10777
    if (x509->rawCRLInfo != NULL) {
10778
        if (x509->rawCRLInfoSz > CTC_MAX_CRLINFO_SZ) {
10779
            WOLFSSL_MSG("CRL Info too large");
10780
            WOLFSSL_ERROR_VERBOSE(BUFFER_E);
10781
            return WOLFSSL_FAILURE;
10782
        }
10783
        XMEMCPY(cert->crlInfo, x509->rawCRLInfo, x509->rawCRLInfoSz);
10784
        cert->crlInfoSz = x509->rawCRLInfoSz;
10785
    }
10786
10787
#ifdef WOLFSSL_DUAL_ALG_CERTS
10788
    /* We point to instance in x509 so DON'T need to be free'd. */
10789
    cert->sapkiDer = x509->sapkiDer;
10790
    cert->sapkiLen = x509->sapkiLen;
10791
    cert->sapkiCrit = x509->sapkiCrit;
10792
    cert->altSigAlgDer = x509->altSigAlgDer;
10793
    cert->altSigAlgLen  = x509->altSigAlgLen;
10794
    cert->altSigAlgCrit = x509->altSigAlgCrit;
10795
    cert->altSigValDer = x509->altSigValDer;
10796
    cert->altSigValLen = x509->altSigValLen;
10797
    cert->altSigValCrit = x509->altSigValCrit;
10798
#endif /* WOLFSSL_DUAL_ALG_CERTS */
10799
10800
#if defined(WOLFSSL_ASN_TEMPLATE) && defined(WOLFSSL_CUSTOM_OID) && \
10801
    defined(HAVE_OID_ENCODING)
10802
10803
    if ((x509->customExtCount < 0) ||
10804
            (x509->customExtCount >= NUM_CUSTOM_EXT)) {
10805
        WOLFSSL_MSG("Bad value for customExtCount.");
10806
        return WOLFSSL_FAILURE;
10807
    }
10808
10809
    for (i = 0; i < x509->customExtCount; i++) {
10810
        if (wc_SetCustomExtension(cert, x509->custom_exts[i].crit,
10811
                x509->custom_exts[i].oid, x509->custom_exts[i].val,
10812
                x509->custom_exts[i].valSz))
10813
        {
10814
            return WOLFSSL_FAILURE;
10815
        }
10816
    }
10817
#endif /* WOLFSSL_ASN_TEMPLATE && WOLFSSL_CUSTOM_OID && HAVE_OID_ENCODING */
10818
10819
#endif /* WOLFSSL_CERT_EXT */
10820
10821
#ifdef WOLFSSL_CERT_REQ
10822
    /* copy over challenge password for REQ certs */
10823
    XMEMCPY(cert->challengePw, x509->challengePw, CTC_NAME_SIZE);
10824
#endif
10825
10826
    /* Only makes sense to do this for OPENSSL_EXTRA because without
10827
     * this define the function will error out below */
10828
    #ifdef OPENSSL_EXTRA
10829
    if (x509->serialSz == 0 && x509->serialNumber != NULL &&
10830
            /* Check if the buffer contains more than just the
10831
             * ASN tag and length */
10832
            x509->serialNumber->length > 2) {
10833
        if (wolfSSL_X509_set_serialNumber(x509, x509->serialNumber)
10834
                != WOLFSSL_SUCCESS) {
10835
            WOLFSSL_MSG("Failed to set serial number");
10836
            return WOLFSSL_FAILURE;
10837
        }
10838
    }
10839
    #endif
10840
10841
    /* set serial number */
10842
    if (x509->serialSz > 0) {
10843
    #if defined(OPENSSL_EXTRA)
10844
        byte serial[EXTERNAL_SERIAL_SIZE];
10845
        int  serialSz = EXTERNAL_SERIAL_SIZE;
10846
10847
        ret = wolfSSL_X509_get_serial_number(x509, serial, &serialSz);
10848
        if (ret != WOLFSSL_SUCCESS) {
10849
            WOLFSSL_MSG("Serial size error");
10850
            return WOLFSSL_FAILURE;
10851
        }
10852
10853
        if (serialSz > EXTERNAL_SERIAL_SIZE ||
10854
                serialSz > CTC_SERIAL_SIZE) {
10855
            WOLFSSL_MSG("Serial size too large error");
10856
            WOLFSSL_ERROR_VERBOSE(BUFFER_E);
10857
            return WOLFSSL_FAILURE;
10858
        }
10859
        XMEMCPY(cert->serial, serial, serialSz);
10860
        cert->serialSz = serialSz;
10861
    #else
10862
        WOLFSSL_MSG("Getting X509 serial number not supported");
10863
        return WOLFSSL_FAILURE;
10864
    #endif
10865
    }
10866
10867
    /* copy over Name structures */
10868
    if (x509->issuerSet)
10869
        cert->selfSigned = 0;
10870
10871
#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
10872
    ret = CopyX509NameToCert(&x509->subject, cert->sbjRaw);
10873
    if (ret < 0) {
10874
        WOLFSSL_MSG("Subject conversion error");
10875
        return MEMORY_E;
10876
    }
10877
    if (cert->selfSigned) {
10878
        XMEMCPY(cert->issRaw, cert->sbjRaw, sizeof(CertName));
10879
    }
10880
    else {
10881
        ret = CopyX509NameToCert(&x509->issuer, cert->issRaw);
10882
        if (ret < 0) {
10883
            WOLFSSL_MSG("Issuer conversion error");
10884
            return MEMORY_E;
10885
        }
10886
    }
10887
#endif
10888
10889
    cert->heap = x509->heap;
10890
10891
    (void)ret;
10892
    return WOLFSSL_SUCCESS;
10893
}
10894
10895
10896
    /* returns the sig type to use on success i.e CTC_SHAwRSA and WOLFSSL_FALURE
10897
     * on fail case */
10898
    static int wolfSSL_sigTypeFromPKEY(WOLFSSL_EVP_MD* md,
10899
            WOLFSSL_EVP_PKEY* pkey)
10900
    {
10901
    #if !defined(NO_PWDBASED) && defined(OPENSSL_EXTRA)
10902
        int hashType;
10903
        int sigType = WOLFSSL_FAILURE;
10904
10905
        /* Convert key type and hash algorithm to a signature algorithm */
10906
        if (wolfSSL_EVP_get_hashinfo(md, &hashType, NULL)
10907
            == WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
10908
        {
10909
            return WOLFSSL_FAILURE;
10910
        }
10911
10912
        if (pkey->type == WC_EVP_PKEY_RSA) {
10913
            switch (hashType) {
10914
                case WC_HASH_TYPE_SHA:
10915
                    sigType = CTC_SHAwRSA;
10916
                    break;
10917
                case WC_HASH_TYPE_SHA224:
10918
                    sigType = CTC_SHA224wRSA;
10919
                    break;
10920
                case WC_HASH_TYPE_SHA256:
10921
                    sigType = CTC_SHA256wRSA;
10922
                    break;
10923
                case WC_HASH_TYPE_SHA384:
10924
                    sigType = CTC_SHA384wRSA;
10925
                    break;
10926
                case WC_HASH_TYPE_SHA512:
10927
                    sigType = CTC_SHA512wRSA;
10928
                    break;
10929
            #ifdef WOLFSSL_SHA3
10930
                case WC_HASH_TYPE_SHA3_224:
10931
                    sigType = CTC_SHA3_224wRSA;
10932
                    break;
10933
                case WC_HASH_TYPE_SHA3_256:
10934
                    sigType = CTC_SHA3_256wRSA;
10935
                    break;
10936
                case WC_HASH_TYPE_SHA3_384:
10937
                    sigType = CTC_SHA3_384wRSA;
10938
                    break;
10939
                case WC_HASH_TYPE_SHA3_512:
10940
                    sigType = CTC_SHA3_512wRSA;
10941
                    break;
10942
            #endif
10943
                default:
10944
                    return WOLFSSL_FAILURE;
10945
            }
10946
        }
10947
        else if (pkey->type == WC_EVP_PKEY_EC) {
10948
            switch (hashType) {
10949
                case WC_HASH_TYPE_SHA:
10950
                    sigType = CTC_SHAwECDSA;
10951
                    break;
10952
                case WC_HASH_TYPE_SHA224:
10953
                    sigType = CTC_SHA224wECDSA;
10954
                    break;
10955
                case WC_HASH_TYPE_SHA256:
10956
                    sigType = CTC_SHA256wECDSA;
10957
                    break;
10958
                case WC_HASH_TYPE_SHA384:
10959
                    sigType = CTC_SHA384wECDSA;
10960
                    break;
10961
                case WC_HASH_TYPE_SHA512:
10962
                    sigType = CTC_SHA512wECDSA;
10963
                    break;
10964
            #ifdef WOLFSSL_SHA3
10965
                case WC_HASH_TYPE_SHA3_224:
10966
                    sigType = CTC_SHA3_224wECDSA;
10967
                    break;
10968
                case WC_HASH_TYPE_SHA3_256:
10969
                    sigType = CTC_SHA3_256wECDSA;
10970
                    break;
10971
                case WC_HASH_TYPE_SHA3_384:
10972
                    sigType = CTC_SHA3_384wECDSA;
10973
                    break;
10974
                case WC_HASH_TYPE_SHA3_512:
10975
                    sigType = CTC_SHA3_512wECDSA;
10976
                    break;
10977
            #endif
10978
                default:
10979
                    return WOLFSSL_FAILURE;
10980
            }
10981
        }
10982
        else
10983
            return WOLFSSL_FAILURE;
10984
        return sigType;
10985
#else
10986
        (void)md;
10987
        (void)pkey;
10988
        WOLFSSL_MSG("Cannot get hashinfo when NO_PWDBASED is defined");
10989
        return WOLFSSL_FAILURE;
10990
#endif /* !NO_PWDBASED && OPENSSL_EXTRA */
10991
    }
10992
10993
10994
    /* generates DER buffer from WOLFSSL_X509
10995
     * If req == 1 then creates a request DER buffer
10996
     *
10997
     * updates derSz with certificate body size on success
10998
     * return WOLFSSL_SUCCESS on success
10999
     */
11000
    static int wolfssl_x509_make_der(WOLFSSL_X509* x509, int req,
11001
            unsigned char* der, int* derSz, int includeSig)
11002
    {
11003
        int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
11004
        int totalLen;
11005
        Cert* cert = NULL;
11006
        void* key = NULL;
11007
        int type = -1;
11008
    #ifndef NO_RSA
11009
        RsaKey* rsa = NULL;
11010
    #endif
11011
    #ifdef HAVE_ECC
11012
        ecc_key* ecc = NULL;
11013
    #endif
11014
    #ifndef NO_DSA
11015
        DsaKey* dsa = NULL;
11016
    #endif
11017
    #if defined(HAVE_FALCON)
11018
        falcon_key* falcon = NULL;
11019
    #endif
11020
    #if defined(HAVE_DILITHIUM)
11021
        dilithium_key* dilithium = NULL;
11022
    #endif
11023
    #if defined(HAVE_SPHINCS)
11024
        sphincs_key* sphincs = NULL;
11025
    #endif
11026
        WC_RNG rng;
11027
        word32 idx = 0;
11028
11029
        if (x509 == NULL || der == NULL || derSz == NULL)
11030
            return BAD_FUNC_ARG;
11031
11032
    #ifndef WOLFSSL_CERT_REQ
11033
        if (req) {
11034
            WOLFSSL_MSG("WOLFSSL_CERT_REQ needed for certificate request");
11035
            return WOLFSSL_FAILURE;
11036
        }
11037
    #endif
11038
11039
        /* allocate Cert struct on heap since it is large */
11040
        cert = (Cert*)XMALLOC(sizeof(Cert), NULL, DYNAMIC_TYPE_CERT);
11041
        if (cert == NULL) {
11042
            WOLFSSL_MSG("Failed to allocate memory for Cert struct");
11043
            return WOLFSSL_FAILURE;
11044
        }
11045
        XMEMSET(cert, 0, sizeof(Cert));
11046
11047
    #ifdef WOLFSSL_CERT_REQ
11048
        if (req) {
11049
            if (ReqCertFromX509(cert, x509) != WOLFSSL_SUCCESS) {
11050
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
11051
                return WOLFSSL_FAILURE;
11052
            }
11053
        }
11054
        else
11055
    #endif
11056
        {
11057
            /* Create a Cert that has the certificate fields. */
11058
            if (CertFromX509(cert, x509) != WOLFSSL_SUCCESS) {
11059
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
11060
                return WOLFSSL_FAILURE;
11061
            }
11062
        }
11063
11064
        /* Create a public key object from requests public key. */
11065
    #ifndef NO_RSA
11066
        if (x509->pubKeyOID == RSAk) {
11067
11068
            rsa = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
11069
            if (rsa == NULL) {
11070
                WOLFSSL_MSG("Failed to allocate memory for RsaKey");
11071
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
11072
                return WOLFSSL_FAILURE;
11073
            }
11074
11075
            type = RSA_TYPE;
11076
            ret = wc_InitRsaKey(rsa, x509->heap);
11077
            if (ret != 0) {
11078
                XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
11079
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
11080
                return ret;
11081
            }
11082
            ret = wc_RsaPublicKeyDecode(x509->pubKey.buffer, &idx, rsa,
11083
                                                           x509->pubKey.length);
11084
            if (ret != 0) {
11085
                WOLFSSL_ERROR_VERBOSE(ret);
11086
                wc_FreeRsaKey(rsa);
11087
                XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
11088
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
11089
                return ret;
11090
            }
11091
            key = (void*)rsa;
11092
        }
11093
    #endif
11094
    #ifdef HAVE_ECC
11095
        if (x509->pubKeyOID == ECDSAk) {
11096
11097
            ecc = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
11098
            if (ecc == NULL) {
11099
                WOLFSSL_MSG("Failed to allocate memory for ecc_key");
11100
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
11101
                return WOLFSSL_FAILURE;
11102
            }
11103
11104
            type = ECC_TYPE;
11105
            ret = wc_ecc_init(ecc);
11106
            if (ret != 0) {
11107
                XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
11108
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
11109
                return ret;
11110
            }
11111
            ret = wc_EccPublicKeyDecode(x509->pubKey.buffer, &idx, ecc,
11112
                                                           x509->pubKey.length);
11113
            if (ret != 0) {
11114
                WOLFSSL_ERROR_VERBOSE(ret);
11115
                wc_ecc_free(ecc);
11116
                XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
11117
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
11118
                return ret;
11119
            }
11120
            key = (void*)ecc;
11121
        }
11122
    #endif
11123
    #ifndef NO_DSA
11124
        if (x509->pubKeyOID == DSAk) {
11125
11126
            dsa = (DsaKey*)XMALLOC(sizeof(DsaKey), NULL, DYNAMIC_TYPE_DSA);
11127
            if (dsa == NULL) {
11128
                WOLFSSL_MSG("Failed to allocate memory for DsaKey");
11129
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
11130
                return WOLFSSL_FAILURE;
11131
            }
11132
11133
            type = DSA_TYPE;
11134
            ret = wc_InitDsaKey(dsa);
11135
            if (ret != 0) {
11136
                XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
11137
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
11138
                return ret;
11139
            }
11140
            ret = wc_DsaPublicKeyDecode(x509->pubKey.buffer, &idx, dsa,
11141
                                                           x509->pubKey.length);
11142
            if (ret != 0) {
11143
                WOLFSSL_ERROR_VERBOSE(ret);
11144
                wc_FreeDsaKey(dsa);
11145
                XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
11146
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
11147
                return ret;
11148
            }
11149
            key = (void*)dsa;
11150
        }
11151
    #endif
11152
    #if defined(HAVE_FALCON)
11153
        if ((x509->pubKeyOID == FALCON_LEVEL1k) ||
11154
            (x509->pubKeyOID == FALCON_LEVEL5k)) {
11155
            falcon = (falcon_key*)XMALLOC(sizeof(falcon_key), NULL,
11156
                                          DYNAMIC_TYPE_FALCON);
11157
            if (falcon == NULL) {
11158
                WOLFSSL_MSG("Failed to allocate memory for falcon_key");
11159
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
11160
                return WOLFSSL_FAILURE;
11161
            }
11162
11163
            ret = wc_falcon_init(falcon);
11164
            if (ret != 0) {
11165
                XFREE(falcon, NULL, DYNAMIC_TYPE_FALCON);
11166
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
11167
                return ret;
11168
            }
11169
11170
            if (x509->pubKeyOID == FALCON_LEVEL1k) {
11171
                type = FALCON_LEVEL1_TYPE;
11172
                wc_falcon_set_level(falcon, 1);
11173
            }
11174
            else if (x509->pubKeyOID == FALCON_LEVEL5k) {
11175
                type = FALCON_LEVEL5_TYPE;
11176
                wc_falcon_set_level(falcon, 5);
11177
            }
11178
11179
            ret = wc_Falcon_PublicKeyDecode(x509->pubKey.buffer, &idx, falcon,
11180
                                            x509->pubKey.length);
11181
            if (ret != 0) {
11182
                WOLFSSL_ERROR_VERBOSE(ret);
11183
                wc_falcon_free(falcon);
11184
                XFREE(falcon, NULL, DYNAMIC_TYPE_FALCON);
11185
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
11186
                return ret;
11187
            }
11188
            key = (void*)falcon;
11189
        }
11190
    #endif
11191
    #if defined(HAVE_DILITHIUM)
11192
        if ((x509->pubKeyOID == ML_DSA_LEVEL2k) ||
11193
            (x509->pubKeyOID == ML_DSA_LEVEL3k) ||
11194
            (x509->pubKeyOID == ML_DSA_LEVEL5k)
11195
            #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
11196
         || (x509->pubKeyOID == DILITHIUM_LEVEL2k)
11197
         || (x509->pubKeyOID == DILITHIUM_LEVEL3k)
11198
         || (x509->pubKeyOID == DILITHIUM_LEVEL5k)
11199
            #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */
11200
            ) {
11201
            dilithium = (dilithium_key*)XMALLOC(sizeof(dilithium_key), NULL,
11202
                                          DYNAMIC_TYPE_DILITHIUM);
11203
            if (dilithium == NULL) {
11204
                WOLFSSL_MSG("Failed to allocate memory for dilithium_key");
11205
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
11206
                return WOLFSSL_FAILURE;
11207
            }
11208
11209
            ret = wc_dilithium_init(dilithium);
11210
            if (ret != 0) {
11211
                XFREE(dilithium, NULL, DYNAMIC_TYPE_DILITHIUM);
11212
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
11213
                return ret;
11214
            }
11215
11216
            if (x509->pubKeyOID == ML_DSA_LEVEL2k) {
11217
                type = ML_DSA_LEVEL2_TYPE;
11218
                wc_dilithium_set_level(dilithium, WC_ML_DSA_44);
11219
            }
11220
            else if (x509->pubKeyOID == ML_DSA_LEVEL3k) {
11221
                type = ML_DSA_LEVEL3_TYPE;
11222
                wc_dilithium_set_level(dilithium, WC_ML_DSA_65);
11223
            }
11224
            else if (x509->pubKeyOID == ML_DSA_LEVEL5k) {
11225
                type = ML_DSA_LEVEL5_TYPE;
11226
                wc_dilithium_set_level(dilithium, WC_ML_DSA_87);
11227
            }
11228
            #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
11229
            else if (x509->pubKeyOID == DILITHIUM_LEVEL2k) {
11230
                type = DILITHIUM_LEVEL2_TYPE;
11231
                wc_dilithium_set_level(dilithium, WC_ML_DSA_44_DRAFT);
11232
            }
11233
            else if (x509->pubKeyOID == DILITHIUM_LEVEL3k) {
11234
                type = DILITHIUM_LEVEL3_TYPE;
11235
                wc_dilithium_set_level(dilithium, WC_ML_DSA_65_DRAFT);
11236
            }
11237
            else if (x509->pubKeyOID == DILITHIUM_LEVEL5k) {
11238
                type = DILITHIUM_LEVEL5_TYPE;
11239
                wc_dilithium_set_level(dilithium, WC_ML_DSA_87_DRAFT);
11240
            }
11241
            #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */
11242
11243
            ret = wc_Dilithium_PublicKeyDecode(x509->pubKey.buffer, &idx,
11244
                                    dilithium, x509->pubKey.length);
11245
            if (ret != 0) {
11246
                WOLFSSL_ERROR_VERBOSE(ret);
11247
                wc_dilithium_free(dilithium);
11248
                XFREE(dilithium, NULL, DYNAMIC_TYPE_DILITHIUM);
11249
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
11250
                return ret;
11251
            }
11252
            key = (void*)dilithium;
11253
        }
11254
    #endif
11255
    #if defined(HAVE_SPHINCS)
11256
        if ((x509->pubKeyOID == SPHINCS_FAST_LEVEL1k) ||
11257
            (x509->pubKeyOID == SPHINCS_FAST_LEVEL3k) ||
11258
            (x509->pubKeyOID == SPHINCS_FAST_LEVEL5k) ||
11259
            (x509->pubKeyOID == SPHINCS_SMALL_LEVEL1k) ||
11260
            (x509->pubKeyOID == SPHINCS_SMALL_LEVEL3k) ||
11261
            (x509->pubKeyOID == SPHINCS_SMALL_LEVEL5k)) {
11262
            sphincs = (sphincs_key*)XMALLOC(sizeof(sphincs_key), NULL,
11263
                                          DYNAMIC_TYPE_SPHINCS);
11264
            if (sphincs == NULL) {
11265
                WOLFSSL_MSG("Failed to allocate memory for sphincs_key");
11266
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
11267
                return WOLFSSL_FAILURE;
11268
            }
11269
11270
            ret = wc_sphincs_init(sphincs);
11271
            if (ret != 0) {
11272
                XFREE(sphincs, NULL, DYNAMIC_TYPE_SPHINCS);
11273
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
11274
                return ret;
11275
            }
11276
11277
            if (x509->pubKeyOID == SPHINCS_FAST_LEVEL1k) {
11278
                type = SPHINCS_FAST_LEVEL1_TYPE;
11279
                wc_sphincs_set_level_and_optim(sphincs, 1, FAST_VARIANT);
11280
            }
11281
            else if (x509->pubKeyOID == SPHINCS_FAST_LEVEL3k) {
11282
                type = SPHINCS_FAST_LEVEL3_TYPE;
11283
                wc_sphincs_set_level_and_optim(sphincs, 3, FAST_VARIANT);
11284
            }
11285
            else if (x509->pubKeyOID == SPHINCS_FAST_LEVEL3k) {
11286
                type = SPHINCS_FAST_LEVEL5_TYPE;
11287
                wc_sphincs_set_level_and_optim(sphincs, 5, FAST_VARIANT);
11288
            }
11289
            else if (x509->pubKeyOID == SPHINCS_SMALL_LEVEL1k) {
11290
                type = SPHINCS_SMALL_LEVEL1_TYPE;
11291
                wc_sphincs_set_level_and_optim(sphincs, 1, SMALL_VARIANT);
11292
            }
11293
            else if (x509->pubKeyOID == SPHINCS_SMALL_LEVEL3k) {
11294
                type = SPHINCS_SMALL_LEVEL3_TYPE;
11295
                wc_sphincs_set_level_and_optim(sphincs, 3, SMALL_VARIANT);
11296
            }
11297
            else if (x509->pubKeyOID == SPHINCS_SMALL_LEVEL3k) {
11298
                type = SPHINCS_SMALL_LEVEL5_TYPE;
11299
                wc_sphincs_set_level_and_optim(sphincs, 5, SMALL_VARIANT);
11300
            }
11301
11302
            ret = wc_Sphincs_PublicKeyDecode(x509->pubKey.buffer, &idx, sphincs,
11303
                                             x509->pubKey.length);
11304
            if (ret != 0) {
11305
                WOLFSSL_ERROR_VERBOSE(ret);
11306
                wc_sphincs_free(sphincs);
11307
                XFREE(sphincs, NULL, DYNAMIC_TYPE_SPHINCS);
11308
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
11309
                return ret;
11310
            }
11311
            key = (void*)sphincs;
11312
        }
11313
    #endif
11314
        if (key == NULL) {
11315
            WOLFSSL_MSG("No public key found for certificate");
11316
            XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
11317
            return WOLFSSL_FAILURE;
11318
        }
11319
11320
        /* Make the body of the certificate request. */
11321
    #ifdef WOLFSSL_CERT_REQ
11322
        if (req) {
11323
            ret = wc_MakeCertReq_ex(cert, der, *derSz, type, key);
11324
        }
11325
        else
11326
    #endif
11327
        {
11328
            ret = wc_InitRng(&rng);
11329
            if (ret != 0) {
11330
                ret = WOLFSSL_FAILURE;
11331
                goto cleanup;
11332
            }
11333
11334
            ret = wc_MakeCert_ex(cert, der, *derSz, type, key, &rng);
11335
            wc_FreeRng(&rng);
11336
        }
11337
        if (ret <= 0) {
11338
            WOLFSSL_ERROR_VERBOSE(ret);
11339
            ret = WOLFSSL_FAILURE;
11340
            goto cleanup;
11341
        }
11342
11343
        if ((x509->serialSz == 0) &&
11344
                (cert->serialSz <= EXTERNAL_SERIAL_SIZE) &&
11345
                (cert->serialSz > 0)) {
11346
        #if defined(OPENSSL_EXTRA)
11347
            WOLFSSL_ASN1_INTEGER *i = wolfSSL_ASN1_INTEGER_new();
11348
11349
            if (i == NULL) {
11350
                WOLFSSL_MSG("wolfSSL_ASN1_INTEGER_new error");
11351
                ret = WOLFSSL_FAILURE;
11352
                goto cleanup;
11353
            }
11354
            else {
11355
                i->length = cert->serialSz + 2;
11356
                i->data[0] = ASN_INTEGER;
11357
                i->data[1] = (unsigned char)cert->serialSz;
11358
                XMEMCPY(i->data + 2, cert->serial, cert->serialSz);
11359
                if (wolfSSL_X509_set_serialNumber(x509, i) != WOLFSSL_SUCCESS) {
11360
                    WOLFSSL_MSG("Issue setting generated serial number");
11361
                    wolfSSL_ASN1_INTEGER_free(i);
11362
                    ret = WOLFSSL_FAILURE;
11363
                    goto cleanup;
11364
                }
11365
                wolfSSL_ASN1_INTEGER_free(i);
11366
            }
11367
        #else
11368
            WOLFSSL_MSG("ASN1_INTEGER API not in build");
11369
11370
            ret = WOLFSSL_FAILURE;
11371
            goto cleanup;
11372
        #endif /* OPENSSL_EXTRA */
11373
        }
11374
11375
        if (includeSig) {
11376
            if (!x509->sig.buffer) {
11377
                WOLFSSL_MSG("No signature buffer");
11378
                ret = WOLFSSL_FAILURE;
11379
                goto cleanup;
11380
            }
11381
            totalLen = AddSignature(NULL, ret, NULL, x509->sig.length,
11382
                                  x509->sigOID);
11383
            if (totalLen > *derSz) {
11384
                WOLFSSL_MSG("Output der buffer too short");
11385
                ret = WOLFSSL_FAILURE;
11386
                goto cleanup;
11387
            }
11388
            ret = AddSignature(der, ret, x509->sig.buffer,
11389
                               x509->sig.length, x509->sigOID);
11390
        }
11391
11392
        *derSz = ret;
11393
        ret = WOLFSSL_SUCCESS;
11394
cleanup:
11395
        /* Dispose of the public key object. */
11396
    #ifndef NO_RSA
11397
        if (x509->pubKeyOID == RSAk) {
11398
            wc_FreeRsaKey(rsa);
11399
            XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
11400
        }
11401
    #endif
11402
    #ifdef HAVE_ECC
11403
        if (x509->pubKeyOID == ECDSAk) {
11404
            wc_ecc_free(ecc);
11405
            XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
11406
        }
11407
    #endif
11408
    #ifndef NO_DSA
11409
        if (x509->pubKeyOID == DSAk) {
11410
            wc_FreeDsaKey(dsa);
11411
            XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
11412
        }
11413
    #endif
11414
    #if defined(HAVE_FALCON)
11415
        if ((x509->pubKeyOID == FALCON_LEVEL1k) ||
11416
            (x509->pubKeyOID == FALCON_LEVEL5k)) {
11417
            wc_falcon_free(falcon);
11418
            XFREE(falcon, NULL, DYNAMIC_TYPE_FALCON);
11419
        }
11420
    #endif
11421
    #if defined(HAVE_DILITHIUM)
11422
        if ((x509->pubKeyOID == ML_DSA_LEVEL2k) ||
11423
            (x509->pubKeyOID == ML_DSA_LEVEL3k) ||
11424
            (x509->pubKeyOID == ML_DSA_LEVEL5k)
11425
        #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
11426
         || (x509->pubKeyOID == DILITHIUM_LEVEL2k)
11427
         || (x509->pubKeyOID == DILITHIUM_LEVEL3k)
11428
         || (x509->pubKeyOID == DILITHIUM_LEVEL5k)
11429
        #endif
11430
        ) {
11431
            wc_dilithium_free(dilithium);
11432
            XFREE(dilithium, NULL, DYNAMIC_TYPE_DILITHIUM);
11433
        }
11434
    #endif
11435
    #if defined(HAVE_SPHINCS)
11436
        if ((x509->pubKeyOID == SPHINCS_FAST_LEVEL1k) ||
11437
            (x509->pubKeyOID == SPHINCS_FAST_LEVEL3k) ||
11438
            (x509->pubKeyOID == SPHINCS_FAST_LEVEL5k) ||
11439
            (x509->pubKeyOID == SPHINCS_SMALL_LEVEL1k) ||
11440
            (x509->pubKeyOID == SPHINCS_SMALL_LEVEL3k) ||
11441
            (x509->pubKeyOID == SPHINCS_SMALL_LEVEL5k)) {
11442
            wc_sphincs_free(sphincs);
11443
            XFREE(sphincs, NULL, DYNAMIC_TYPE_SPHINCS);
11444
        }
11445
    #endif
11446
        XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
11447
11448
        return ret;
11449
    }
11450
11451
11452
    /* signs a der buffer for the WOLFSSL_X509 structure using the PKEY and MD
11453
     * hash passed in
11454
     *
11455
     * WARNING: this free's and replaces the existing DER buffer in the
11456
     *          WOLFSSL_X509 with the newly signed buffer.
11457
     * returns size of signed buffer on success and negative values on fail
11458
     */
11459
    static int wolfSSL_X509_resign_cert(WOLFSSL_X509* x509, int req,
11460
            unsigned char* der, int derSz, int certBodySz, WOLFSSL_EVP_MD* md,
11461
            WOLFSSL_EVP_PKEY* pkey)
11462
    {
11463
        int ret;
11464
        void* key = NULL;
11465
        int type = -1;
11466
        int sigType;
11467
        WC_RNG rng;
11468
11469
        (void)req;
11470
        WOLFSSL_ENTER("wolfSSL_X509_resign_cert");
11471
11472
        sigType = wolfSSL_sigTypeFromPKEY(md, pkey);
11473
        if (sigType == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
11474
            WOLFSSL_MSG("Error getting signature type from pkey");
11475
            return WOLFSSL_FATAL_ERROR;
11476
        }
11477
11478
11479
        /* Get the private key object and type from pkey. */
11480
    #ifndef NO_RSA
11481
        if (pkey->type == WC_EVP_PKEY_RSA) {
11482
            type = RSA_TYPE;
11483
            key = pkey->rsa->internal;
11484
        }
11485
    #endif
11486
    #ifdef HAVE_ECC
11487
        if (pkey->type == WC_EVP_PKEY_EC) {
11488
            type = ECC_TYPE;
11489
            key = pkey->ecc->internal;
11490
        }
11491
    #endif
11492
11493
        /* Sign the certificate (request) body. */
11494
        ret = wc_InitRng(&rng);
11495
        if (ret != 0)
11496
            return ret;
11497
        ret = wc_SignCert_ex(certBodySz, sigType, der, (word32)derSz, type, key,
11498
            &rng);
11499
        wc_FreeRng(&rng);
11500
        if (ret < 0) {
11501
            WOLFSSL_LEAVE("wolfSSL_X509_resign_cert", ret);
11502
            return ret;
11503
        }
11504
        derSz = ret;
11505
11506
        /* Extract signature from buffer */
11507
        {
11508
            word32 idx = 0;
11509
            int    len = 0;
11510
11511
            /* Read top level sequence */
11512
            if (GetSequence(der, &idx, &len, (word32)derSz) < 0) {
11513
                WOLFSSL_MSG("GetSequence error");
11514
                return WOLFSSL_FATAL_ERROR;
11515
            }
11516
            /* Move idx to signature */
11517
            idx += certBodySz;
11518
            /* Read signature algo sequence */
11519
            if (GetSequence(der, &idx, &len, (word32)derSz) < 0) {
11520
                WOLFSSL_MSG("GetSequence error");
11521
                return WOLFSSL_FATAL_ERROR;
11522
            }
11523
            idx += len;
11524
            /* Read signature bit string */
11525
            if (CheckBitString(der, &idx, &len, (word32)derSz, 0, NULL) != 0) {
11526
                WOLFSSL_MSG("CheckBitString error");
11527
                return WOLFSSL_FATAL_ERROR;
11528
            }
11529
            /* Sanity check */
11530
            if (idx + len != (word32)derSz) {
11531
                WOLFSSL_MSG("unexpected asn1 structure");
11532
                return WOLFSSL_FATAL_ERROR;
11533
            }
11534
            x509->sig.length = 0;
11535
            if (x509->sig.buffer)
11536
                XFREE(x509->sig.buffer, x509->heap, DYNAMIC_TYPE_SIGNATURE);
11537
            x509->sig.buffer = (byte*)XMALLOC(len, x509->heap,
11538
                                              DYNAMIC_TYPE_SIGNATURE);
11539
            if (!x509->sig.buffer) {
11540
                WOLFSSL_MSG("malloc error");
11541
                return WOLFSSL_FATAL_ERROR;
11542
            }
11543
            XMEMCPY(x509->sig.buffer, der + idx, len);
11544
            x509->sig.length = (unsigned int)len;
11545
        }
11546
11547
        /* Put in the new certificate encoding into the x509 object. */
11548
        FreeDer(&x509->derCert);
11549
        type = CERT_TYPE;
11550
    #ifdef WOLFSSL_CERT_REQ
11551
        if (req) {
11552
            type = CERTREQ_TYPE;
11553
        }
11554
    #endif
11555
        if (AllocDer(&x509->derCert, (word32)derSz, type, NULL) != 0)
11556
            return WOLFSSL_FATAL_ERROR;
11557
        XMEMCPY(x509->derCert->buffer, der, derSz);
11558
        x509->derCert->length = (word32)derSz;
11559
11560
        return ret;
11561
    }
11562
11563
11564
#ifndef WC_MAX_X509_GEN
11565
    /* able to override max size until dynamic buffer created */
11566
    #define WC_MAX_X509_GEN 4096
11567
#endif
11568
11569
/* returns the size of signature on success */
11570
int wolfSSL_X509_sign(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey,
11571
        const WOLFSSL_EVP_MD* md)
11572
{
11573
    int  ret;
11574
    /* @TODO dynamic set based on expected cert size */
11575
    byte *der = (byte *)XMALLOC(WC_MAX_X509_GEN, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11576
    int  derSz = WC_MAX_X509_GEN;
11577
11578
    WOLFSSL_ENTER("wolfSSL_X509_sign");
11579
11580
    if (x509 == NULL || pkey == NULL || md == NULL) {
11581
        ret = WOLFSSL_FAILURE;
11582
        goto out;
11583
    }
11584
11585
    x509->sigOID = wolfSSL_sigTypeFromPKEY((WOLFSSL_EVP_MD*)md, pkey);
11586
    if ((ret = wolfssl_x509_make_der(x509, 0, der, &derSz, 0)) !=
11587
            WOLFSSL_SUCCESS) {
11588
        WOLFSSL_MSG("Unable to make DER for X509");
11589
        WOLFSSL_LEAVE("wolfSSL_X509_sign", ret);
11590
        (void)ret;
11591
        ret = WOLFSSL_FAILURE;
11592
        goto out;
11593
    }
11594
11595
    ret = wolfSSL_X509_resign_cert(x509, 0, der, WC_MAX_X509_GEN, derSz,
11596
            (WOLFSSL_EVP_MD*)md, pkey);
11597
    if (ret <= 0) {
11598
        WOLFSSL_LEAVE("wolfSSL_X509_sign", ret);
11599
        ret = WOLFSSL_FAILURE;
11600
        goto out;
11601
    }
11602
11603
out:
11604
    XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11605
11606
    return ret;
11607
}
11608
11609
#if defined(OPENSSL_EXTRA)
11610
int wolfSSL_X509_sign_ctx(WOLFSSL_X509 *x509, WOLFSSL_EVP_MD_CTX *ctx)
11611
{
11612
    WOLFSSL_ENTER("wolfSSL_X509_sign_ctx");
11613
11614
    if (!x509 || !ctx || !ctx->pctx || !ctx->pctx->pkey) {
11615
        WOLFSSL_MSG("Bad parameter");
11616
        return WOLFSSL_FAILURE;
11617
    }
11618
11619
    return wolfSSL_X509_sign(x509, ctx->pctx->pkey,
11620
        wolfSSL_EVP_MD_CTX_md(ctx));
11621
}
11622
#endif /* OPENSSL_EXTRA */
11623
#endif /* WOLFSSL_CERT_GEN */
11624
11625
11626
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
11627
    defined(OPENSSL_EXTRA_X509_SMALL) || defined(WOLFSSL_WPAS_SMALL)
11628
/* Converts from WC_NID_* value to wolfSSL value if needed.
11629
 *
11630
 * @param [in] nid  Numeric Id of a domain name component.
11631
 * @return  Domain name tag values - wolfSSL internal values.
11632
 * @return  -1 when nid isn't known.
11633
 */
11634
static int ConvertNIDToWolfSSL(int nid)
11635
{
11636
    switch (nid) {
11637
        case WC_NID_commonName : return ASN_COMMON_NAME;
11638
    #ifdef WOLFSSL_CERT_NAME_ALL
11639
        case WC_NID_name :       return ASN_NAME;
11640
        case WC_NID_givenName:   return ASN_GIVEN_NAME;
11641
        case WC_NID_dnQualifier :   return ASN_DNQUALIFIER;
11642
        case WC_NID_initials:   return ASN_INITIALS;
11643
    #endif /* WOLFSSL_CERT_NAME_ALL */
11644
        case WC_NID_surname :    return ASN_SUR_NAME;
11645
        case WC_NID_countryName: return ASN_COUNTRY_NAME;
11646
        case WC_NID_localityName: return ASN_LOCALITY_NAME;
11647
        case WC_NID_stateOrProvinceName: return ASN_STATE_NAME;
11648
        case WC_NID_streetAddress: return ASN_STREET_ADDR;
11649
        case WC_NID_organizationName: return ASN_ORG_NAME;
11650
        case WC_NID_organizationalUnitName: return ASN_ORGUNIT_NAME;
11651
        case WC_NID_emailAddress: return ASN_EMAIL_NAME;
11652
        case WC_NID_pkcs9_contentType: return ASN_CONTENT_TYPE;
11653
        case WC_NID_serialNumber: return ASN_SERIAL_NUMBER;
11654
        case WC_NID_userId: return ASN_USER_ID;
11655
        case WC_NID_businessCategory: return ASN_BUS_CAT;
11656
        case WC_NID_domainComponent: return ASN_DOMAIN_COMPONENT;
11657
        case WC_NID_postalCode: return ASN_POSTAL_CODE;
11658
        case WC_NID_rfc822Mailbox: return ASN_RFC822_MAILBOX;
11659
        case WC_NID_favouriteDrink: return ASN_FAVOURITE_DRINK;
11660
        default:
11661
            WOLFSSL_MSG("Attribute NID not found");
11662
            return WOLFSSL_FATAL_ERROR;
11663
    }
11664
}
11665
#endif /* OPENSSL_ALL || OPENSSL_EXTRA ||
11666
          OPENSSL_EXTRA_X509_SMALL || WOLFSSL_WPAS_SMALL*/
11667
11668
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
11669
    defined(OPENSSL_EXTRA_X509_SMALL)
11670
/* This is to convert the x509 name structure into canonical DER format     */
11671
/*  , which has the following rules:                                        */
11672
/*   convert to UTF8                                                        */
11673
/*   convert to lower case                                                  */
11674
/*   multi-spaces collapsed                                                 */
11675
/*   leading SEQUENCE header is skipped                                     */
11676
/* @param  name a pointer to X509_NAME that is to be converted              */
11677
/* @param  out  a pointer to converted data                                 */
11678
/* @return a number of converted bytes, otherwise <=0 error code            */
11679
int wolfSSL_i2d_X509_NAME_canon(WOLFSSL_X509_NAME* name, unsigned char** out)
11680
{
11681
    int  totalBytes = 0, i, idx;
11682
    byte *output, *local = NULL;
11683
#ifdef WOLFSSL_SMALL_STACK
11684
    EncodedName* names = NULL;
11685
#else
11686
    EncodedName  names[MAX_NAME_ENTRIES];
11687
#endif
11688
11689
    if (name == NULL)
11690
        return BAD_FUNC_ARG;
11691
11692
#ifdef WOLFSSL_SMALL_STACK
11693
    names = (EncodedName*)XMALLOC(sizeof(EncodedName) * MAX_NAME_ENTRIES, NULL,
11694
                                                       DYNAMIC_TYPE_TMP_BUFFER);
11695
    if (names == NULL)
11696
        return MEMORY_E;
11697
#endif
11698
11699
    XMEMSET(names, 0, sizeof(EncodedName) * MAX_NAME_ENTRIES);
11700
11701
    for (i = 0; i < MAX_NAME_ENTRIES; i++) {
11702
        WOLFSSL_X509_NAME_ENTRY* entry;
11703
        int ret;
11704
11705
        entry = wolfSSL_X509_NAME_get_entry(name, i);
11706
        if (entry != NULL && entry->set >= 1) {
11707
            const char* nameStr;
11708
            WOLFSSL_ASN1_STRING* data;
11709
            WOLFSSL_ASN1_STRING* cano_data;
11710
11711
            cano_data = wolfSSL_ASN1_STRING_new();
11712
            if (cano_data == NULL) {
11713
                #ifdef WOLFSSL_SMALL_STACK
11714
                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11715
                #endif
11716
                return MEMORY_E;
11717
            }
11718
11719
            data = wolfSSL_X509_NAME_ENTRY_get_data(entry);
11720
            if (data == NULL) {
11721
            #ifdef WOLFSSL_SMALL_STACK
11722
                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11723
            #endif
11724
                wolfSSL_ASN1_STRING_free(cano_data);
11725
                WOLFSSL_MSG("Error getting entry data");
11726
                return WOLFSSL_FATAL_ERROR;
11727
            }
11728
            if (wolfSSL_ASN1_STRING_canon(cano_data, data) != WOLFSSL_SUCCESS) {
11729
            #ifdef WOLFSSL_SMALL_STACK
11730
                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11731
            #endif
11732
                wolfSSL_ASN1_STRING_free(cano_data);
11733
                return WOLFSSL_FAILURE;
11734
            }
11735
            nameStr = (const char*)wolfSSL_ASN1_STRING_data(cano_data);
11736
11737
            ret = wc_EncodeNameCanonical(&names[i], nameStr, CTC_UTF8,
11738
                (byte)ConvertNIDToWolfSSL(entry->nid));
11739
            if (ret < 0) {
11740
            #ifdef WOLFSSL_SMALL_STACK
11741
                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11742
            #endif
11743
                wolfSSL_ASN1_STRING_free(cano_data);
11744
                WOLFSSL_MSG("EncodeName failed");
11745
                return WOLFSSL_FATAL_ERROR;
11746
            }
11747
            totalBytes += ret;
11748
            wolfSSL_ASN1_STRING_free(cano_data);
11749
        }
11750
    }
11751
11752
    if (out == NULL) {
11753
        /* If out is NULL, caller just wants length. */
11754
#ifdef WOLFSSL_SMALL_STACK
11755
        XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11756
#endif
11757
        return totalBytes;
11758
    }
11759
11760
    /* skip header */
11761
    /* check if using buffer passed in */
11762
    if (*out == NULL) {
11763
        *out = local = (unsigned char*)XMALLOC(totalBytes, NULL,
11764
                DYNAMIC_TYPE_OPENSSL);
11765
        if (*out == NULL) {
11766
            return MEMORY_E;
11767
        }
11768
    }
11769
    output = *out;
11770
    idx = 0;
11771
11772
    for (i = 0; i < MAX_NAME_ENTRIES; i++) {
11773
        if (names[i].used) {
11774
            XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
11775
            idx += names[i].totalLen;
11776
        }
11777
    }
11778
11779
#ifdef WOLFSSL_SMALL_STACK
11780
    XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11781
#endif
11782
11783
    /* used existing buffer passed in, so increment pointer */
11784
    if (local == NULL) {
11785
        *out += totalBytes;
11786
    }
11787
    return totalBytes;
11788
}
11789
#endif /* OPENSSL_ALL || OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
11790
11791
#ifdef WOLFSSL_CERT_GEN
11792
/* Guarded by either
11793
 * A) WOLFSSL_WPAS_SMALL is on or
11794
 * B) (OPENSSL_EXTRA or OPENSSL_EXTRA_X509_SMALL) + WOLFSSL_CERT_GEN +
11795
 *    (WOLFSSL_CERT_REQ or WOLFSSL_CERT_EXT or OPENSSL_EXTRA) has been
11796
 *    defined
11797
 */
11798
#if defined(WOLFSSL_WPAS_SMALL) || \
11799
    (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
11800
    defined(WOLFSSL_CERT_GEN) && \
11801
    (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT) || \
11802
     defined(OPENSSL_EXTRA))
11803
11804
/* Converts the x509 name structure into DER format.
11805
 *
11806
 * out  pointer to either a pre setup buffer or a pointer to null for
11807
 *      creating a dynamic buffer. In the case that a pre-existing buffer is
11808
 *      used out will be incremented the size of the DER buffer on success. If
11809
 *      out is NULL, the function returns the necessary output buffer length.
11810
 *
11811
 * returns the size of the buffer on success, or negative value with failure
11812
 */
11813
int wolfSSL_i2d_X509_NAME(WOLFSSL_X509_NAME* name, unsigned char** out)
11814
{
11815
    int  totalBytes = 0, i, idx;
11816
    byte temp[MAX_SEQ_SZ];
11817
    byte *output, *local = NULL;
11818
#ifdef WOLFSSL_SMALL_STACK
11819
    EncodedName* names = NULL;
11820
#else
11821
    EncodedName  names[MAX_NAME_ENTRIES];
11822
#endif
11823
11824
    if (name == NULL)
11825
        return BAD_FUNC_ARG;
11826
11827
#ifdef WOLFSSL_SMALL_STACK
11828
    names = (EncodedName*)XMALLOC(sizeof(EncodedName) * MAX_NAME_ENTRIES, NULL,
11829
                                                       DYNAMIC_TYPE_TMP_BUFFER);
11830
    if (names == NULL)
11831
        return MEMORY_E;
11832
#endif
11833
11834
    XMEMSET(names, 0, sizeof(EncodedName) * MAX_NAME_ENTRIES);
11835
11836
    for (i = 0; i < MAX_NAME_ENTRIES; i++) {
11837
        WOLFSSL_X509_NAME_ENTRY* entry;
11838
        int ret;
11839
11840
        entry = wolfSSL_X509_NAME_get_entry(name, i);
11841
        if (entry != NULL && entry->set >= 1) {
11842
            const char* nameStr;
11843
            int type;
11844
            WOLFSSL_ASN1_STRING* data;
11845
11846
            data = wolfSSL_X509_NAME_ENTRY_get_data(entry);
11847
            if (data == NULL) {
11848
            #ifdef WOLFSSL_SMALL_STACK
11849
                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11850
            #endif
11851
                WOLFSSL_MSG("Error getting entry data");
11852
                return WOLFSSL_FATAL_ERROR;
11853
            }
11854
11855
            nameStr = (const char*)wolfSSL_ASN1_STRING_data(data);
11856
            type    = wolfSSL_ASN1_STRING_type(data);
11857
11858
            switch (type) {
11859
                case WOLFSSL_MBSTRING_UTF8:
11860
                    type = CTC_UTF8;
11861
                    break;
11862
                case WOLFSSL_MBSTRING_ASC:
11863
                case WOLFSSL_V_ASN1_PRINTABLESTRING:
11864
                    type = CTC_PRINTABLE;
11865
                    break;
11866
                default:
11867
                    WOLFSSL_MSG(
11868
                        "Unknown encoding type conversion UTF8 by default");
11869
                    type = CTC_UTF8;
11870
            }
11871
            ret = wc_EncodeName(&names[i], nameStr, (char)type,
11872
                (byte)ConvertNIDToWolfSSL(entry->nid));
11873
            if (ret < 0) {
11874
            #ifdef WOLFSSL_SMALL_STACK
11875
                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11876
            #endif
11877
                WOLFSSL_MSG("EncodeName failed");
11878
                return WOLFSSL_FATAL_ERROR;
11879
            }
11880
            totalBytes += ret;
11881
        }
11882
    }
11883
11884
    /* header */
11885
    idx = (int)SetSequence((word32)totalBytes, temp);
11886
    if (totalBytes + idx > ASN_NAME_MAX) {
11887
#ifdef WOLFSSL_SMALL_STACK
11888
        XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11889
#endif
11890
        WOLFSSL_MSG("Total Bytes is greater than ASN_NAME_MAX");
11891
        return BUFFER_E;
11892
    }
11893
11894
    if (out == NULL) {
11895
        /* If out is NULL, caller just wants length. */
11896
        totalBytes += idx;
11897
#ifdef WOLFSSL_SMALL_STACK
11898
        XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11899
#endif
11900
        return totalBytes;
11901
    }
11902
11903
    /* check if using buffer passed in */
11904
    if (*out == NULL) {
11905
        *out = local = (unsigned char*)XMALLOC(totalBytes + idx, name->heap,
11906
                DYNAMIC_TYPE_OPENSSL);
11907
        if (*out == NULL) {
11908
            return MEMORY_E;
11909
        }
11910
    }
11911
    output = *out;
11912
11913
    idx = (int)SetSequence((word32)totalBytes, output);
11914
    totalBytes += idx;
11915
    for (i = 0; i < MAX_NAME_ENTRIES; i++) {
11916
        if (names[i].used) {
11917
            XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
11918
            idx += names[i].totalLen;
11919
        }
11920
    }
11921
11922
#ifdef WOLFSSL_SMALL_STACK
11923
    XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11924
#endif
11925
11926
    /* used existing buffer passed in, so increment pointer */
11927
    if (local == NULL) {
11928
        *out += totalBytes;
11929
    }
11930
    return totalBytes;
11931
}
11932
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
11933
#endif /* WOLFSSL_CERT_GEN */
11934
11935
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) || \
11936
    defined (WOLFSSL_WPAS_SMALL)
11937
11938
    WOLFSSL_X509_NAME *wolfSSL_d2i_X509_NAME(WOLFSSL_X509_NAME **name,
11939
                                             unsigned char **in, long length)
11940
    {
11941
        WOLFSSL_X509_NAME* tmp = NULL;
11942
    #ifdef WOLFSSL_SMALL_STACK
11943
        DecodedCert* cert = NULL;
11944
    #else
11945
        DecodedCert cert[1];
11946
    #endif
11947
11948
        WOLFSSL_ENTER("wolfSSL_d2i_X509_NAME");
11949
11950
        if (!in || !*in || length <= 0) {
11951
            WOLFSSL_MSG("Bad argument");
11952
            return NULL;
11953
        }
11954
11955
    #ifdef WOLFSSL_SMALL_STACK
11956
        cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
11957
                                     DYNAMIC_TYPE_DCERT);
11958
        if (cert == NULL) {
11959
            return NULL;
11960
        }
11961
    #endif
11962
11963
        /* Set the X509_NAME buffer as the input data for cert.
11964
         * in is NOT a full certificate. Just the name. */
11965
        InitDecodedCert(cert, *in, (word32)length, NULL);
11966
11967
        /* Parse the X509 subject name */
11968
        if (GetName(cert, ASN_SUBJECT, (int)length) != 0) {
11969
            WOLFSSL_MSG("WOLFSSL_X509_NAME parse error");
11970
            goto cleanup;
11971
        }
11972
11973
        if (!(tmp = wolfSSL_X509_NAME_new_ex(cert->heap))) {
11974
            WOLFSSL_MSG("wolfSSL_X509_NAME_new_ex error");
11975
            goto cleanup;
11976
        }
11977
11978
        if (wolfSSL_X509_NAME_copy((WOLFSSL_X509_NAME*)cert->subjectName,
11979
                    tmp) != WOLFSSL_SUCCESS) {
11980
            wolfSSL_X509_NAME_free(tmp);
11981
            tmp = NULL;
11982
            goto cleanup;
11983
        }
11984
11985
        if (name)
11986
            *name = tmp;
11987
cleanup:
11988
        FreeDecodedCert(cert);
11989
    #ifdef WOLFSSL_SMALL_STACK
11990
        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
11991
    #endif
11992
        return tmp;
11993
    }
11994
#endif /* OPENSSL_EXTRA || OPENSSL_ALL || WOLFSSL_WPAS_SMALL */
11995
11996
11997
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
11998
11999
    /* Compares the two X509 names. If the size of x is larger then y then a
12000
     * positive value is returned if x is smaller a negative value is returned.
12001
     * In the case that the sizes are equal a the value of strcmp between the
12002
     * two names is returned.
12003
     *
12004
     * x First name for comparison
12005
     * y Second name to compare with x
12006
     */
12007
    int wolfSSL_X509_NAME_cmp(const WOLFSSL_X509_NAME* x,
12008
            const WOLFSSL_X509_NAME* y)
12009
    {
12010
        const char* _x;
12011
        const char* _y;
12012
        WOLFSSL_ENTER("wolfSSL_X509_NAME_cmp");
12013
12014
        if (x == NULL || y == NULL) {
12015
            WOLFSSL_MSG("Bad argument passed in");
12016
            return -2;
12017
        }
12018
12019
        if (x == y) {
12020
            return 0; /* match */
12021
        }
12022
12023
        if (x->sz != y->sz) {
12024
            return x->sz - y->sz;
12025
        }
12026
12027
        /*
12028
         * If the name member is not set or is immediately null terminated then
12029
         * compare the staticName member
12030
         */
12031
        _x = (x->name && *x->name) ? x->name : x->staticName;
12032
        _y = (y->name && *y->name) ? y->name : y->staticName;
12033
12034
        return XSTRNCASECMP(_x, _y, x->sz); /* y sz is the same */
12035
    }
12036
12037
#ifndef NO_BIO
12038
12039
static WOLFSSL_X509 *loadX509orX509REQFromPemBio(WOLFSSL_BIO *bp,
12040
        WOLFSSL_X509 **x, wc_pem_password_cb *cb, void *u, int type)
12041
{
12042
    WOLFSSL_X509* x509 = NULL;
12043
#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
12044
    unsigned char* pem = NULL;
12045
    int pemSz;
12046
    long  i = 0, l, footerSz;
12047
    const char* footer = NULL;
12048
12049
    WOLFSSL_ENTER("loadX509orX509REQFromPemBio");
12050
12051
    if (bp == NULL || (type != CERT_TYPE && type != CERTREQ_TYPE)) {
12052
        WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_X509", BAD_FUNC_ARG);
12053
        return NULL;
12054
    }
12055
12056
    if ((l = wolfSSL_BIO_get_len(bp)) <= 0) {
12057
        /* No certificate in buffer */
12058
#if defined (WOLFSSL_HAPROXY)
12059
        WOLFSSL_ERROR(PEM_R_NO_START_LINE);
12060
#else
12061
        WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
12062
#endif
12063
        return NULL;
12064
    }
12065
12066
    pemSz = (int)l;
12067
    pem   = (unsigned char*)XMALLOC(pemSz, 0, DYNAMIC_TYPE_PEM);
12068
    if (pem == NULL)
12069
        return NULL;
12070
    XMEMSET(pem, 0, pemSz);
12071
12072
    i = 0;
12073
    if (wc_PemGetHeaderFooter(type, NULL, &footer) != 0) {
12074
        XFREE(pem, 0, DYNAMIC_TYPE_PEM);
12075
        return NULL;
12076
    }
12077
    footerSz = (long)XSTRLEN(footer);
12078
12079
    /* TODO: Inefficient
12080
     * reading in one byte at a time until see the footer
12081
     */
12082
    while ((l = wolfSSL_BIO_read(bp, (char *)&pem[i], 1)) == 1) {
12083
        i++;
12084
        if (i > footerSz && XMEMCMP((char *)&pem[i-footerSz], footer,
12085
                footerSz) == 0) {
12086
            if (wolfSSL_BIO_read(bp, (char *)&pem[i], 1) == 1) {
12087
                /* attempt to read newline following footer */
12088
                i++;
12089
                if (pem[i-1] == '\r') {
12090
                    /* found \r , Windows line ending is \r\n so try to read one
12091
                     * more byte for \n, ignoring return value */
12092
                    (void)wolfSSL_BIO_read(bp, (char *)&pem[i++], 1);
12093
                }
12094
            }
12095
            break;
12096
        }
12097
    }
12098
    if (l == 0)
12099
        WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
12100
    if (i > pemSz) {
12101
        WOLFSSL_MSG("Error parsing PEM");
12102
    }
12103
    else {
12104
        pemSz = (int)i;
12105
    #ifdef WOLFSSL_CERT_REQ
12106
        if (type == CERTREQ_TYPE)
12107
            x509 = loadX509orX509REQFromBuffer(pem, pemSz, WOLFSSL_FILETYPE_PEM,
12108
                CERTREQ_TYPE, cb, u);
12109
        else
12110
    #endif
12111
            x509 = loadX509orX509REQFromBuffer(pem, pemSz, WOLFSSL_FILETYPE_PEM,
12112
                CERT_TYPE, cb, u);
12113
    }
12114
12115
    if (x != NULL) {
12116
        *x = x509;
12117
    }
12118
12119
    XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
12120
12121
#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
12122
    (void)bp;
12123
    (void)x;
12124
    (void)cb;
12125
    (void)u;
12126
12127
    return x509;
12128
}
12129
12130
12131
#if defined(WOLFSSL_ACERT)
12132
    WOLFSSL_X509_ACERT *wolfSSL_PEM_read_bio_X509_ACERT(WOLFSSL_BIO *bp,
12133
                                                        WOLFSSL_X509_ACERT **x,
12134
                                                        wc_pem_password_cb *cb,
12135
                                                        void *u)
12136
    {
12137
        WOLFSSL_X509_ACERT* x509 = NULL;
12138
#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
12139
        unsigned char * pem = NULL;
12140
        int             pemSz;
12141
12142
        WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509_ACERT");
12143
12144
        if (bp == NULL) {
12145
            WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_X509_ACERT", BAD_FUNC_ARG);
12146
            return NULL;
12147
        }
12148
12149
        if ((pemSz = wolfSSL_BIO_get_len(bp)) <= 0) {
12150
            /* No certificate in buffer */
12151
            WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
12152
            return NULL;
12153
        }
12154
12155
        pem   = (unsigned char*)XMALLOC(pemSz, 0, DYNAMIC_TYPE_PEM);
12156
12157
        if (pem == NULL) {
12158
            return NULL;
12159
        }
12160
12161
        XMEMSET(pem, 0, pemSz);
12162
12163
        if (wolfSSL_BIO_read(bp, pem, pemSz) != pemSz) {
12164
            XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
12165
            return NULL;
12166
        }
12167
12168
        x509 = wolfSSL_X509_ACERT_load_certificate_buffer(pem, pemSz,
12169
                                                          WOLFSSL_FILETYPE_PEM);
12170
12171
        if (x != NULL) {
12172
            *x = x509;
12173
        }
12174
12175
        XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
12176
12177
#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
12178
        (void)bp;
12179
        (void)x;
12180
        (void)cb;
12181
        (void)u;
12182
12183
        return x509;
12184
12185
    }
12186
#endif /* WOLFSSL_ACERT */
12187
12188
    WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x,
12189
                                            wc_pem_password_cb *cb, void *u)
12190
    {
12191
        return loadX509orX509REQFromPemBio(bp, x, cb, u, CERT_TYPE);
12192
    }
12193
12194
    /*
12195
     * bp : bio to read X509 from
12196
     * x  : x509 to write to
12197
     * cb : password call back for reading PEM
12198
     * u  : password
12199
     * _AUX is for working with a trusted X509 certificate
12200
     */
12201
    WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_AUX(WOLFSSL_BIO *bp,
12202
                               WOLFSSL_X509 **x, wc_pem_password_cb *cb,
12203
                               void *u)
12204
    {
12205
        WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509");
12206
12207
        /* AUX info is; trusted/rejected uses, friendly name, private key id,
12208
         * and potentially a stack of "other" info. wolfSSL does not store
12209
         * friendly name or private key id yet in WOLFSSL_X509 for human
12210
         * readability and does not support extra trusted/rejected uses for
12211
         * root CA. */
12212
        return wolfSSL_PEM_read_bio_X509(bp, x, cb, u);
12213
    }
12214
12215
#ifdef WOLFSSL_CERT_REQ
12216
WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_REQ(WOLFSSL_BIO *bp, WOLFSSL_X509 **x,
12217
                                                wc_pem_password_cb *cb, void *u)
12218
{
12219
    return loadX509orX509REQFromPemBio(bp, x, cb, u, CERTREQ_TYPE);
12220
}
12221
12222
#ifndef NO_FILESYSTEM
12223
    WOLFSSL_X509* wolfSSL_PEM_read_X509_REQ(XFILE fp, WOLFSSL_X509** x,
12224
                                            wc_pem_password_cb* cb, void* u)
12225
    {
12226
        int err = 0;
12227
        WOLFSSL_X509* ret = NULL;
12228
        WOLFSSL_BIO* bio = NULL;
12229
12230
        WOLFSSL_ENTER("wolfSSL_PEM_read_X509_REQ");
12231
12232
        if (fp == XBADFILE) {
12233
            WOLFSSL_MSG("Invalid file.");
12234
            err = 1;
12235
        }
12236
12237
        if (err == 0) {
12238
            bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
12239
            if (bio == NULL) {
12240
                WOLFSSL_MSG("Failed to create new BIO with input file.");
12241
                err = 1;
12242
            }
12243
        }
12244
        if (err == 0 && wolfSSL_BIO_set_fp(bio, fp, WOLFSSL_BIO_CLOSE)
12245
                != WOLFSSL_SUCCESS) {
12246
            WOLFSSL_MSG("Failed to set BIO file pointer.");
12247
            err = 1;
12248
        }
12249
        if (err == 0) {
12250
            ret = wolfSSL_PEM_read_bio_X509_REQ(bio, x, cb, u);
12251
        }
12252
12253
        wolfSSL_BIO_free(bio);
12254
12255
        return ret;
12256
    }
12257
#endif /* !NO_FILESYSTEM */
12258
#endif /* WOLFSSL_CERT_REQ */
12259
12260
    WOLFSSL_X509_CRL *wolfSSL_PEM_read_bio_X509_CRL(WOLFSSL_BIO *bp,
12261
            WOLFSSL_X509_CRL **x, wc_pem_password_cb *cb, void *u)
12262
    {
12263
#if defined(WOLFSSL_PEM_TO_DER) && defined(HAVE_CRL)
12264
        unsigned char* pem = NULL;
12265
        int pemSz;
12266
        int derSz;
12267
        DerBuffer* der = NULL;
12268
        WOLFSSL_X509_CRL* crl = NULL;
12269
12270
        if ((pemSz = wolfSSL_BIO_get_len(bp)) <= 0) {
12271
            goto err;
12272
        }
12273
12274
        pem = (unsigned char*)XMALLOC(pemSz, 0, DYNAMIC_TYPE_PEM);
12275
        if (pem == NULL) {
12276
            goto err;
12277
        }
12278
12279
        if (wolfSSL_BIO_read(bp, pem, pemSz) != pemSz) {
12280
            goto err;
12281
        }
12282
12283
        if ((PemToDer(pem, pemSz, CRL_TYPE, &der, NULL, NULL, NULL)) < 0) {
12284
            goto err;
12285
        }
12286
        derSz = (int)der->length;
12287
        if ((crl = wolfSSL_d2i_X509_CRL(x, der->buffer, derSz)) == NULL) {
12288
            goto err;
12289
        }
12290
12291
err:
12292
        XFREE(pem, 0, DYNAMIC_TYPE_PEM);
12293
        if (der != NULL) {
12294
            FreeDer(&der);
12295
        }
12296
12297
        (void)cb;
12298
        (void)u;
12299
12300
        return crl;
12301
#else
12302
        (void)bp;
12303
        (void)x;
12304
        (void)cb;
12305
        (void)u;
12306
12307
        return NULL;
12308
#endif
12309
    }
12310
12311
#endif /* !NO_BIO */
12312
12313
#if !defined(NO_FILESYSTEM)
12314
static void* wolfSSL_PEM_read_X509_ex(XFILE fp, void **x,
12315
    wc_pem_password_cb *cb, void *u, int type)
12316
{
12317
    unsigned char* pem = NULL;
12318
    int pemSz;
12319
    long i = 0, l;
12320
    void *newx509;
12321
    int derSz;
12322
    DerBuffer* der = NULL;
12323
12324
    WOLFSSL_ENTER("wolfSSL_PEM_read_X509");
12325
12326
    if (fp == XBADFILE) {
12327
        WOLFSSL_LEAVE("wolfSSL_PEM_read_X509", BAD_FUNC_ARG);
12328
        return NULL;
12329
    }
12330
    /* Read cert from file */
12331
    i = XFTELL(fp);
12332
    if (i < 0) {
12333
        WOLFSSL_LEAVE("wolfSSL_PEM_read_X509", BAD_FUNC_ARG);
12334
        return NULL;
12335
    }
12336
12337
    if (XFSEEK(fp, 0, XSEEK_END) != 0)
12338
        return NULL;
12339
    l = XFTELL(fp);
12340
    if (l < 0)
12341
        return NULL;
12342
    if (XFSEEK(fp, i, SEEK_SET) != 0)
12343
        return NULL;
12344
    pemSz = (int)(l - i);
12345
12346
    /* check calculated length */
12347
    if (pemSz > MAX_WOLFSSL_FILE_SIZE || pemSz <= 0) {
12348
        WOLFSSL_MSG("PEM_read_X509_ex file size error");
12349
        return NULL;
12350
    }
12351
12352
    /* allocate pem buffer */
12353
    pem = (unsigned char*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_PEM);
12354
    if (pem == NULL)
12355
        return NULL;
12356
12357
    if ((int)XFREAD((char *)pem, 1, (size_t)pemSz, fp) != pemSz)
12358
        goto err_exit;
12359
12360
    switch (type) {
12361
        case CERT_TYPE:
12362
            newx509 = (void *)wolfSSL_X509_load_certificate_buffer(pem,
12363
                pemSz, WOLFSSL_FILETYPE_PEM);
12364
            break;
12365
12366
    #ifdef HAVE_CRL
12367
        case CRL_TYPE:
12368
            if ((PemToDer(pem, pemSz, CRL_TYPE, &der, NULL, NULL, NULL)) < 0)
12369
                goto err_exit;
12370
            derSz = (int)der->length;
12371
            newx509 = (void*)wolfSSL_d2i_X509_CRL((WOLFSSL_X509_CRL **)x,
12372
                (const unsigned char *)der->buffer, derSz);
12373
            if (newx509 == NULL)
12374
                goto err_exit;
12375
            FreeDer(&der);
12376
            break;
12377
    #endif
12378
12379
        default:
12380
            goto err_exit;
12381
    }
12382
    if (x != NULL) {
12383
        *x = newx509;
12384
    }
12385
    XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
12386
    return newx509;
12387
12388
err_exit:
12389
    XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
12390
    if (der != NULL)
12391
        FreeDer(&der);
12392
12393
    /* unused */
12394
    (void)cb;
12395
    (void)u;
12396
    (void)derSz;
12397
12398
    return NULL;
12399
}
12400
12401
WOLFSSL_API WOLFSSL_X509* wolfSSL_PEM_read_X509(XFILE fp, WOLFSSL_X509 **x,
12402
                                                wc_pem_password_cb *cb, void *u)
12403
{
12404
    return (WOLFSSL_X509* )wolfSSL_PEM_read_X509_ex(fp, (void **)x, cb, u,
12405
         CERT_TYPE);
12406
}
12407
12408
#if defined(HAVE_CRL)
12409
WOLFSSL_API WOLFSSL_X509_CRL* wolfSSL_PEM_read_X509_CRL(XFILE fp,
12410
                        WOLFSSL_X509_CRL **crl, wc_pem_password_cb *cb, void *u)
12411
{
12412
    return (WOLFSSL_X509_CRL* )wolfSSL_PEM_read_X509_ex(fp, (void **)crl, cb, u,
12413
         CRL_TYPE);
12414
}
12415
#endif
12416
12417
#ifdef WOLFSSL_CERT_GEN
12418
#ifndef NO_BIO
12419
    int wolfSSL_PEM_write_X509(XFILE fp, WOLFSSL_X509* x)
12420
    {
12421
        int ret;
12422
        WOLFSSL_BIO* bio;
12423
12424
        if (x == NULL || fp == XBADFILE)
12425
            return 0;
12426
12427
        bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
12428
        if (bio == NULL)
12429
            return 0;
12430
12431
        if (wolfSSL_BIO_set_fp(bio, fp, WOLFSSL_BIO_NOCLOSE) != WOLFSSL_SUCCESS) {
12432
            wolfSSL_BIO_free(bio);
12433
            bio = NULL;
12434
        }
12435
12436
        ret = wolfSSL_PEM_write_bio_X509(bio, x);
12437
12438
        if (bio != NULL)
12439
            wolfSSL_BIO_free(bio);
12440
12441
        return ret;
12442
    }
12443
#endif /* !NO_BIO */
12444
#endif /* WOLFSSL_CERT_GEN */
12445
#endif /* !NO_FILESYSTEM */
12446
12447
#endif /* OPENSSL_EXTRA || OPENSSL_ALL */
12448
#ifdef OPENSSL_ALL
12449
12450
#ifndef NO_BIO
12451
    /* create and return a new WOLFSSL_X509_PKEY structure or NULL on failure */
12452
    static WOLFSSL_X509_PKEY* wolfSSL_X509_PKEY_new(void* heap)
12453
    {
12454
        WOLFSSL_X509_PKEY* ret;
12455
12456
        ret = (WOLFSSL_X509_PKEY*)XMALLOC(sizeof(WOLFSSL_X509_PKEY), heap,
12457
            DYNAMIC_TYPE_KEY);
12458
        if (ret != NULL) {
12459
            XMEMSET(ret, 0, sizeof(WOLFSSL_X509_PKEY));
12460
            ret->heap = heap;
12461
        }
12462
        return ret;
12463
    }
12464
#endif /* !NO_BIO */
12465
12466
12467
    /* free up all memory used by "xPkey" passed in */
12468
    static void wolfSSL_X509_PKEY_free(WOLFSSL_X509_PKEY* xPkey)
12469
    {
12470
        if (xPkey != NULL) {
12471
            wolfSSL_EVP_PKEY_free(xPkey->dec_pkey);
12472
            XFREE(xPkey, xPkey->heap, DYNAMIC_TYPE_KEY);
12473
        }
12474
    }
12475
12476
12477
#ifndef NO_BIO
12478
12479
#define PEM_COMPARE_HEADER(start, end, header) \
12480
        ((end) - (start) == XSTR_SIZEOF(header) && XMEMCMP(start, header, \
12481
                XSTR_SIZEOF(header)) == 0)
12482
12483
    /**
12484
     * This read one structure from bio and returns the read structure
12485
     * in the appropriate output parameter (x509, crl, x_pkey). The
12486
     * output parameters must be set to NULL.
12487
     * @param bio    Input for reading structures
12488
     * @param cb     Password callback
12489
     * @param x509   Output
12490
     * @param crl    Output
12491
     * @param x_pkey Output
12492
     * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE otherwise
12493
     */
12494
    static int wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio(
12495
            WOLFSSL_BIO* bio, wc_pem_password_cb* cb, WOLFSSL_X509** x509,
12496
            WOLFSSL_X509_CRL** crl, WOLFSSL_X509_PKEY** x_pkey)
12497
    {
12498
12499
#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
12500
        char* pem = NULL;
12501
        long  i = pem_struct_min_sz, l;
12502
        const char* header = NULL;
12503
        const char* headerEnd = NULL;
12504
        const char* footer = NULL;
12505
        const char* footerEnd = NULL;
12506
    #ifdef HAVE_CRL
12507
        DerBuffer* der = NULL;
12508
    #endif
12509
        WOLFSSL_BIO* pemBio = NULL;
12510
12511
        if (!bio || !x509 || *x509 || !crl || *crl || !x_pkey || *x_pkey) {
12512
            WOLFSSL_MSG("Bad input parameter or output parameters "
12513
                        "not set to a NULL value.");
12514
            return WOLFSSL_FAILURE;
12515
        }
12516
12517
        if ((l = wolfSSL_BIO_get_len(bio)) <= 0) {
12518
            /* No certificate in buffer */
12519
            WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
12520
            return WOLFSSL_FAILURE;
12521
        }
12522
12523
        pem = (char*)XMALLOC(l, 0, DYNAMIC_TYPE_PEM);
12524
        if (pem == NULL)
12525
            return WOLFSSL_FAILURE;
12526
12527
        if (wolfSSL_BIO_read(bio, &pem[0], pem_struct_min_sz) !=
12528
                pem_struct_min_sz) {
12529
            WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
12530
            goto err;
12531
        }
12532
12533
        /* Read the header and footer */
12534
        while (i < l && wolfSSL_BIO_read(bio, &pem[i], 1) == 1) {
12535
            i++;
12536
            if (!header) {
12537
                header = XSTRNSTR(pem, "-----BEGIN ", (unsigned int)i);
12538
            }
12539
            else if (!headerEnd) {
12540
                headerEnd = XSTRNSTR(header + XSTR_SIZEOF("-----BEGIN "),
12541
                        "-----",
12542
                        (unsigned int)
12543
                        (i - (header + XSTR_SIZEOF("-----BEGIN ") - pem)));
12544
                if (headerEnd) {
12545
                    headerEnd += XSTR_SIZEOF("-----");
12546
                    /* Read in the newline */
12547
                    if (wolfSSL_BIO_read(bio, &pem[i], 1) != 1) {
12548
                        WOLFSSL_MSG("wolfSSL_BIO_read error");
12549
                        goto err;
12550
                    }
12551
                    i++;
12552
                    if (*headerEnd != '\n' && *headerEnd != '\r') {
12553
                        WOLFSSL_MSG("Missing newline after header");
12554
                        goto err;
12555
                    }
12556
                }
12557
            }
12558
            else if (!footer) {
12559
                footer = XSTRNSTR(headerEnd, "-----END ",
12560
                        (unsigned int)(i - (headerEnd - pem)));
12561
            }
12562
            else if (!footerEnd) {
12563
                footerEnd = XSTRNSTR(footer + XSTR_SIZEOF("-----"),
12564
                        "-----", (unsigned int)(i -
12565
                            (footer + XSTR_SIZEOF("-----") - pem)));
12566
                if (footerEnd) {
12567
                    footerEnd += XSTR_SIZEOF("-----");
12568
                    /* Now check that footer matches header */
12569
                    if ((headerEnd - (header + XSTR_SIZEOF("-----BEGIN "))) ==
12570
                        (footerEnd - (footer + XSTR_SIZEOF("-----END "))) &&
12571
                        XMEMCMP(header + XSTR_SIZEOF("-----BEGIN "),
12572
                                footer + XSTR_SIZEOF("-----END "),
12573
                        headerEnd - (header + XSTR_SIZEOF("-----BEGIN ")))
12574
                            != 0) {
12575
                        WOLFSSL_MSG("Header and footer don't match");
12576
                        goto err;
12577
                    }
12578
                    /* header and footer match */
12579
                    break;
12580
                }
12581
            }
12582
        }
12583
        if (!footerEnd) {
12584
            /* Only check footerEnd since it is set last */
12585
            WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
12586
            goto err;
12587
        }
12588
        else {
12589
            if (PEM_COMPARE_HEADER(header, headerEnd,
12590
                    "-----BEGIN CERTIFICATE-----")) {
12591
                /* We have a certificate */
12592
                WOLFSSL_MSG("Parsing x509 cert");
12593
                *x509 = wolfSSL_X509_load_certificate_buffer(
12594
                        (const unsigned char*) header,
12595
                        (int)(footerEnd - header), WOLFSSL_FILETYPE_PEM);
12596
                if (!*x509) {
12597
                    WOLFSSL_MSG("wolfSSL_X509_load_certificate_buffer error");
12598
                    goto err;
12599
                }
12600
            }
12601
    #ifdef HAVE_CRL
12602
            else if (PEM_COMPARE_HEADER(header, headerEnd,
12603
                        "-----BEGIN X509 CRL-----")) {
12604
                /* We have a crl */
12605
                WOLFSSL_MSG("Parsing crl");
12606
                if ((PemToDer((const unsigned char*) header,
12607
                        (long)(footerEnd - header), CRL_TYPE, &der, NULL, NULL,
12608
                        NULL)) < 0) {
12609
                    WOLFSSL_MSG("PemToDer error");
12610
                    goto err;
12611
                }
12612
                *crl = wolfSSL_d2i_X509_CRL(NULL, der->buffer, der->length);
12613
                if (!*crl) {
12614
                    WOLFSSL_MSG("wolfSSL_d2i_X509_CRL error");
12615
                    goto err;
12616
                }
12617
            }
12618
    #endif
12619
            else {
12620
                WOLFSSL_MSG("Parsing x509 key");
12621
12622
                if (!(*x_pkey = wolfSSL_X509_PKEY_new(NULL))) {
12623
                    WOLFSSL_MSG("wolfSSL_X509_PKEY_new error");
12624
                    goto err;
12625
                }
12626
12627
                if (!(pemBio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()))) {
12628
                    WOLFSSL_MSG("wolfSSL_BIO_new error");
12629
                    goto err;
12630
                }
12631
12632
                if (wolfSSL_BIO_write(pemBio, header,
12633
                        (int)(footerEnd - header)) != footerEnd - header) {
12634
                    WOLFSSL_MSG("wolfSSL_BIO_new error");
12635
                    goto err;
12636
                }
12637
12638
                if (wolfSSL_PEM_read_bio_PrivateKey(pemBio,
12639
                        &(*x_pkey)->dec_pkey, cb, NULL) == NULL) {
12640
                    WOLFSSL_MSG("wolfSSL_PEM_read_bio_PrivateKey error");
12641
                    goto err;
12642
                }
12643
12644
                wolfSSL_BIO_free(pemBio);
12645
            }
12646
        }
12647
12648
        XFREE(pem, 0, DYNAMIC_TYPE_PEM);
12649
    #ifdef HAVE_CRL
12650
        if (der)
12651
            FreeDer(&der);
12652
    #endif
12653
        return WOLFSSL_SUCCESS;
12654
err:
12655
        XFREE(pem, 0, DYNAMIC_TYPE_PEM);
12656
    #ifdef HAVE_CRL
12657
        if (der)
12658
            FreeDer(&der);
12659
    #endif
12660
        if (*x_pkey) {
12661
            wolfSSL_X509_PKEY_free(*x_pkey);
12662
            *x_pkey = NULL;
12663
        }
12664
        if (pemBio)
12665
            wolfSSL_BIO_free(pemBio);
12666
        return WOLFSSL_FAILURE;
12667
#else /* ! (WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM) */
12668
        return WOLFSSL_FAILURE;
12669
#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
12670
    }
12671
12672
#ifndef NO_FILESYSTEM
12673
    WOLF_STACK_OF(WOLFSSL_X509_INFO)* wolfSSL_PEM_X509_INFO_read(
12674
            XFILE fp, WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
12675
            pem_password_cb* cb, void* u)
12676
    {
12677
        WOLFSSL_BIO* fileBio = wolfSSL_BIO_new_fp(fp, WOLFSSL_BIO_NOCLOSE);
12678
        WOLF_STACK_OF(WOLFSSL_X509_INFO)* ret = NULL;
12679
12680
        WOLFSSL_ENTER("wolfSSL_PEM_X509_INFO_read");
12681
        if (fileBio != NULL) {
12682
            ret = wolfSSL_PEM_X509_INFO_read_bio(fileBio, sk, cb, u);
12683
            wolfSSL_BIO_free(fileBio);
12684
        }
12685
        return ret;
12686
    }
12687
#endif /* !NO_FILESYSTEM */
12688
12689
    /*
12690
     * bio WOLFSSL_BIO to read certificates from
12691
     * sk  possible stack to push more X509_INFO structs to. Can be NULL
12692
     * cb  callback password for encrypted PEM certificates
12693
     * u   user input such as password
12694
     *
12695
     * returns stack on success and NULL or default stack passed in on fail
12696
     */
12697
    WOLF_STACK_OF(WOLFSSL_X509_INFO)* wolfSSL_PEM_X509_INFO_read_bio(
12698
        WOLFSSL_BIO* bio, WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
12699
        wc_pem_password_cb* cb, void* u)
12700
    {
12701
        WOLF_STACK_OF(WOLFSSL_X509_INFO)* localSk = NULL;
12702
        int ret = WOLFSSL_SUCCESS;
12703
        WOLFSSL_X509_INFO* current = NULL;
12704
        WOLFSSL_X509*      x509 = NULL;
12705
        WOLFSSL_X509_CRL*  crl  = NULL;
12706
        WOLFSSL_X509_PKEY* x_pkey = NULL;
12707
12708
        (void)u;
12709
12710
        WOLFSSL_ENTER("wolfSSL_PEM_X509_INFO_read_bio");
12711
12712
        /* attempt to use passed in stack or create a new one */
12713
        if (sk != NULL) {
12714
            localSk = sk;
12715
        }
12716
        else {
12717
            localSk = wolfSSL_sk_X509_INFO_new_null();
12718
        }
12719
        if (localSk == NULL) {
12720
            WOLFSSL_LEAVE("wolfSSL_PEM_X509_INFO_read_bio",
12721
                    MEMORY_E);
12722
            return NULL;
12723
        }
12724
12725
        /* parse through BIO and push new info's found onto stack */
12726
        while (1) {
12727
            x509 = NULL;
12728
            crl  = NULL;
12729
            x_pkey = NULL;
12730
12731
            if (wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio(bio, cb,
12732
                    &x509, &crl, &x_pkey) == WOLFSSL_SUCCESS) {
12733
                if (current == NULL ||
12734
                        (x509 && current->x509) ||
12735
                        (crl && current->crl) ||
12736
                        (x_pkey && current->x_pkey)) {
12737
                    /* Need to create new current since existing one already
12738
                     * has the member filled or this is the first successful
12739
                     * read. */
12740
                    current = wolfSSL_X509_INFO_new();
12741
                    if (current == NULL) {
12742
                        ret = MEMORY_E;
12743
                        break;
12744
                    }
12745
                    if (wolfSSL_sk_X509_INFO_push(localSk, current) <= 0) {
12746
                        wolfSSL_X509_INFO_free(current);
12747
                        current = NULL;
12748
                        ret = WOLFSSL_FAILURE;
12749
                        break;
12750
                    }
12751
                }
12752
12753
                if (x509) {
12754
                    current->x509 = x509;
12755
                }
12756
                else if (crl) {
12757
                    current->crl = crl;
12758
                }
12759
                else if (x_pkey) {
12760
                    current->x_pkey = x_pkey;
12761
                }
12762
                else {
12763
                    WOLFSSL_MSG("No output parameters set");
12764
                    ret = WOLFSSL_FAILURE;
12765
                    break;
12766
                }
12767
            }
12768
            else {
12769
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
12770
                unsigned long err;
12771
                CLEAR_ASN_NO_PEM_HEADER_ERROR(err);
12772
                if (ERR_GET_LIB(err) != ERR_LIB_PEM ||
12773
                    ERR_GET_REASON(err) != PEM_R_NO_START_LINE) {
12774
                    ret = WOLFSSL_FAILURE;
12775
                }
12776
#else
12777
                if (wolfSSL_sk_X509_INFO_num(localSk) > 0) {
12778
                    WOLFSSL_MSG("At least one X509_INFO object on stack."
12779
                                "Assuming error means EOF or no more PEM"
12780
                                "headers found.");
12781
                }
12782
                else {
12783
                    ret = WOLFSSL_FAILURE;
12784
                }
12785
#endif
12786
                break;
12787
            }
12788
        }
12789
        if (ret != WOLFSSL_SUCCESS ||
12790
                wolfSSL_sk_X509_INFO_num(localSk) == 0) {
12791
            /* current should always be pushed onto the localsk stack at this
12792
             * point. The only case when it isn't is when
12793
             * wolfSSL_sk_X509_INFO_push fails but in that case the current
12794
             * free is handled inside the loop. */
12795
            if (localSk != sk) {
12796
                wolfSSL_sk_pop_free(localSk, NULL);
12797
            }
12798
            wolfSSL_X509_free(x509);
12799
#ifdef HAVE_CRL
12800
            wolfSSL_X509_CRL_free(crl);
12801
#endif
12802
            wolfSSL_X509_PKEY_free(x_pkey);
12803
            localSk = NULL;
12804
        }
12805
        WOLFSSL_LEAVE("wolfSSL_PEM_X509_INFO_read_bio", ret);
12806
        return localSk;
12807
    }
12808
#endif /* !NO_BIO */
12809
#endif /* OPENSSL_ALL */
12810
12811
    void wolfSSL_X509_NAME_ENTRY_free(WOLFSSL_X509_NAME_ENTRY* ne)
12812
    {
12813
        WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_free");
12814
        if (ne != NULL) {
12815
            wolfSSL_ASN1_OBJECT_free(ne->object);
12816
            if (ne->value != NULL) {
12817
                wolfSSL_ASN1_STRING_free(ne->value);
12818
            }
12819
            XFREE(ne, NULL, DYNAMIC_TYPE_NAME_ENTRY);
12820
        }
12821
    }
12822
12823
12824
    WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_new(void)
12825
    {
12826
        WOLFSSL_X509_NAME_ENTRY* ne;
12827
12828
        ne = (WOLFSSL_X509_NAME_ENTRY*)XMALLOC(sizeof(WOLFSSL_X509_NAME_ENTRY),
12829
                NULL, DYNAMIC_TYPE_NAME_ENTRY);
12830
        if (ne != NULL) {
12831
            XMEMSET(ne, 0, sizeof(WOLFSSL_X509_NAME_ENTRY));
12832
        }
12833
12834
        return ne;
12835
    }
12836
12837
12838
    static void wolfssl_x509_name_entry_set(WOLFSSL_X509_NAME_ENTRY* ne,
12839
        int nid, int type, const unsigned char *data, int dataSz)
12840
    {
12841
        ne->nid = nid;
12842
        /* Reuse the object if already available. */
12843
        ne->object = wolfSSL_OBJ_nid2obj_ex(nid, ne->object);
12844
        if (ne->value == NULL) {
12845
            ne->value = wolfSSL_ASN1_STRING_type_new(type);
12846
        }
12847
        if (ne->value != NULL) {
12848
            if (wolfSSL_ASN1_STRING_set(ne->value, (const void*)data,
12849
                                            dataSz) == WOLFSSL_SUCCESS) {
12850
                ne->set = 1;
12851
            }
12852
            else {
12853
                /* Free the ASN1_STRING if it is not set. */
12854
                wolfSSL_ASN1_STRING_free(ne->value);
12855
                ne->value = NULL;
12856
            }
12857
        }
12858
    }
12859
12860
    /* Create a new WOLFSSL_X509_NAME_ENTRY structure based on the text passed
12861
     * in. Returns NULL on failure */
12862
    WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_create_by_txt(
12863
            WOLFSSL_X509_NAME_ENTRY **neIn, const char *txt, int type,
12864
            const unsigned char *data, int dataSz)
12865
    {
12866
        int nid = -1;
12867
        WOLFSSL_X509_NAME_ENTRY* ne = NULL;
12868
12869
        WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_create_by_txt");
12870
12871
        if (txt == NULL) {
12872
            return NULL;
12873
        }
12874
12875
        if (neIn != NULL) {
12876
            ne = *neIn;
12877
        }
12878
12879
        nid = wolfSSL_OBJ_txt2nid(txt);
12880
        if (nid == WC_NID_undef) {
12881
            WOLFSSL_MSG("Unable to find text");
12882
            ne = NULL;
12883
        }
12884
        else {
12885
            if (ne == NULL) {
12886
                ne = wolfSSL_X509_NAME_ENTRY_new();
12887
                if (ne == NULL) {
12888
                    return NULL;
12889
                }
12890
            }
12891
12892
            wolfssl_x509_name_entry_set(ne, nid, type, data, dataSz);
12893
        }
12894
12895
        return ne;
12896
    }
12897
12898
12899
    /* Creates a new entry given the NID, type, and data
12900
     * "dataSz" is number of bytes in data, if set to -1 then XSTRLEN is used
12901
     * "out" can be used to store the new entry data in an existing structure
12902
     *       if NULL then a new WOLFSSL_X509_NAME_ENTRY structure is created
12903
     * returns a pointer to WOLFSSL_X509_NAME_ENTRY on success and NULL on fail
12904
     */
12905
    WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_create_by_NID(
12906
            WOLFSSL_X509_NAME_ENTRY** out, int nid, int type,
12907
            const unsigned char* data, int dataSz)
12908
    {
12909
        WOLFSSL_X509_NAME_ENTRY* ne;
12910
12911
#ifdef WOLFSSL_DEBUG_OPENSSL
12912
        WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_create_by_NID");
12913
#endif
12914
12915
        if (!data) {
12916
            WOLFSSL_MSG("Bad parameter");
12917
            return NULL;
12918
        }
12919
12920
        if (out == NULL || *out == NULL) {
12921
            ne = wolfSSL_X509_NAME_ENTRY_new();
12922
            if (ne == NULL) {
12923
                return NULL;
12924
            }
12925
            if (out != NULL) {
12926
                *out = ne;
12927
            }
12928
        }
12929
        else {
12930
            ne = *out;
12931
        }
12932
12933
        wolfssl_x509_name_entry_set(ne, nid, type, data, dataSz);
12934
12935
        return ne;
12936
    }
12937
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
12938
12939
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
12940
    defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
12941
    defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
12942
    defined(HAVE_POCO_LIB) || defined(WOLFSSL_HAPROXY)
12943
WOLFSSL_ASN1_OBJECT* wolfSSL_X509_NAME_ENTRY_get_object(
12944
    WOLFSSL_X509_NAME_ENTRY *ne)
12945
{
12946
    WOLFSSL_ASN1_OBJECT* object = NULL;
12947
12948
#ifdef WOLFSSL_DEBUG_OPENSSL
12949
    WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_get_object");
12950
#endif
12951
12952
    if (ne != NULL) {
12953
        /* Create object from nid - reuse existing object if possible. */
12954
        object = wolfSSL_OBJ_nid2obj_ex(ne->nid, ne->object);
12955
        if (object != NULL) {
12956
            /* Set the object when no error. */
12957
            ne->object = object;
12958
        }
12959
    }
12960
12961
    return object;
12962
}
12963
#endif /* OPENSSL_ALL || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE ||
12964
        * HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_POCO_LIB || WOLFSSL_HAPROXY */
12965
12966
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
12967
    /* add all entry of type "nid" to the buffer "fullName" and advance "idx"
12968
     * since number of entries is small, a brute force search is used here
12969
     * returns the number of entries added
12970
     */
12971
    static int AddAllEntry(WOLFSSL_X509_NAME* name, char* fullName,
12972
            int fullNameSz, int* idx)
12973
    {
12974
        int i;
12975
        int ret = 0;
12976
12977
        for (i = 0; i < MAX_NAME_ENTRIES; i++) {
12978
            if (name->entry[i].set) {
12979
                WOLFSSL_X509_NAME_ENTRY* e;
12980
                WOLFSSL_ASN1_OBJECT* obj;
12981
12982
                int sz;
12983
                unsigned char* data;
12984
12985
                e = &name->entry[i];
12986
                obj = wolfSSL_X509_NAME_ENTRY_get_object(e);
12987
                if (obj == NULL) {
12988
                    return BAD_FUNC_ARG;
12989
                }
12990
12991
                XMEMCPY(fullName + *idx, "/", 1); *idx = *idx + 1;
12992
                sz = (int)XSTRLEN(obj->sName);
12993
                XMEMCPY(fullName + *idx, obj->sName, sz);
12994
                *idx += sz;
12995
                XMEMCPY(fullName + *idx, "=", 1); *idx = *idx + 1;
12996
12997
                data = wolfSSL_ASN1_STRING_data(e->value);
12998
                if (data != NULL) {
12999
                    sz = (int)XSTRLEN((const char*)data);
13000
                    XMEMCPY(fullName + *idx, data, sz);
13001
                    *idx += sz;
13002
                }
13003
13004
                ret++;
13005
            }
13006
        }
13007
        (void)fullNameSz;
13008
        return ret;
13009
    }
13010
13011
13012
    /* Converts a list of entries in WOLFSSL_X509_NAME struct into a string
13013
     * returns 0 on success */
13014
    static int RebuildFullName(WOLFSSL_X509_NAME* name)
13015
    {
13016
        int totalLen = 0, i, idx, entryCount = 0;
13017
13018
        if (name == NULL)
13019
            return BAD_FUNC_ARG;
13020
13021
        for (i = 0; i < MAX_NAME_ENTRIES; i++) {
13022
            if (name->entry[i].set) {
13023
                WOLFSSL_X509_NAME_ENTRY* e;
13024
                WOLFSSL_ASN1_OBJECT* obj;
13025
13026
                e = &name->entry[i];
13027
                obj = wolfSSL_X509_NAME_ENTRY_get_object(e);
13028
                if (obj == NULL)
13029
                    return BAD_FUNC_ARG;
13030
13031
                totalLen += (int)XSTRLEN(obj->sName) + 2;/*+2 for '/' and '=' */
13032
                totalLen += wolfSSL_ASN1_STRING_length(e->value);
13033
            }
13034
        }
13035
13036
        if (name->dynamicName) {
13037
            XFREE(name->name, name->heap, DYNAMIC_TYPE_X509);
13038
            name->name = name->staticName;
13039
            name->dynamicName = 0;
13040
        }
13041
13042
        if (totalLen >= ASN_NAME_MAX) {
13043
            name->name = (char*)XMALLOC(totalLen + 1, name->heap,
13044
                    DYNAMIC_TYPE_X509);
13045
            if (name->name == NULL)
13046
                return MEMORY_E;
13047
            name->dynamicName = 1;
13048
        }
13049
13050
        idx = 0;
13051
        entryCount = AddAllEntry(name, name->name, totalLen, &idx);
13052
        if (entryCount < 0)
13053
            return entryCount;
13054
13055
        name->name[idx] = '\0';
13056
        name->sz = idx + 1; /* size includes null terminator */
13057
        name->entrySz = entryCount;
13058
13059
        return 0;
13060
    }
13061
13062
    /* Copies entry into name. With it being copied freeing entry becomes the
13063
     * callers responsibility.
13064
     * returns 1 for success and 0 for error */
13065
    int wolfSSL_X509_NAME_add_entry(WOLFSSL_X509_NAME* name,
13066
            WOLFSSL_X509_NAME_ENTRY* entry, int idx, int set)
13067
    {
13068
        WOLFSSL_X509_NAME_ENTRY* current = NULL;
13069
        int ret, i;
13070
13071
#ifdef WOLFSSL_DEBUG_OPENSSL
13072
        WOLFSSL_ENTER("wolfSSL_X509_NAME_add_entry");
13073
#endif
13074
13075
        if (name == NULL || entry == NULL || entry->value == NULL) {
13076
            WOLFSSL_MSG("NULL argument passed in");
13077
            return WOLFSSL_FAILURE;
13078
        }
13079
13080
        if (idx >= 0) {
13081
            /* place in specific index */
13082
13083
            if (idx >= MAX_NAME_ENTRIES) {
13084
                WOLFSSL_MSG("Error index to insert entry is larger than array");
13085
                return WOLFSSL_FAILURE;
13086
            }
13087
            i = idx;
13088
        }
13089
        else {
13090
            /* iterate through and find first open spot */
13091
            for (i = 0; i < MAX_NAME_ENTRIES; i++) {
13092
                if (name->entry[i].set != 1) { /* not set so overwritten */
13093
                    WOLFSSL_MSG("Found place for name entry");
13094
                    break;
13095
                }
13096
            }
13097
13098
            if (i == MAX_NAME_ENTRIES) {
13099
                WOLFSSL_MSG("No spot found for name entry");
13100
                return WOLFSSL_FAILURE;
13101
            }
13102
        }
13103
13104
        current = &name->entry[i];
13105
        if (current->set == 0)
13106
            name->entrySz++;
13107
13108
        if (wolfSSL_X509_NAME_ENTRY_create_by_NID(&current,
13109
                            entry->nid,
13110
                            wolfSSL_ASN1_STRING_type(entry->value),
13111
                            wolfSSL_ASN1_STRING_data(entry->value),
13112
                            wolfSSL_ASN1_STRING_length(entry->value)) != NULL)
13113
        {
13114
            ret = WOLFSSL_SUCCESS;
13115
        #ifdef OPENSSL_ALL
13116
            if (name->entries == NULL) {
13117
                name->entries = wolfSSL_sk_X509_NAME_new(NULL);
13118
            }
13119
            if (wolfSSL_sk_X509_NAME_ENTRY_push(name->entries, current) <= 0) {
13120
                ret = WOLFSSL_FAILURE;
13121
            }
13122
        #endif
13123
        }
13124
        else {
13125
            ret = WOLFSSL_FAILURE;
13126
        }
13127
13128
        if (ret != WOLFSSL_SUCCESS) {
13129
            WOLFSSL_MSG("Error adding the name entry");
13130
            if (current->set == 0)
13131
                name->entrySz--;
13132
            return WOLFSSL_FAILURE;
13133
        }
13134
13135
        if (RebuildFullName(name) != 0)
13136
            return WOLFSSL_FAILURE;
13137
13138
        (void)set;
13139
        return WOLFSSL_SUCCESS;
13140
    }
13141
13142
    int wolfSSL_X509_NAME_add_entry_by_txt(WOLFSSL_X509_NAME *name,
13143
                                           const char *field, int type,
13144
                                           const unsigned char *bytes, int len,
13145
                                           int loc, int set)
13146
    {
13147
        int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
13148
        int nid;
13149
        WOLFSSL_X509_NAME_ENTRY* entry;
13150
13151
        (void)type;
13152
        WOLFSSL_ENTER("wolfSSL_X509_NAME_add_entry_by_txt");
13153
13154
        if (name == NULL || field == NULL)
13155
            return WOLFSSL_FAILURE;
13156
13157
        if ((nid = wolfSSL_OBJ_txt2nid(field)) == WC_NID_undef) {
13158
            WOLFSSL_MSG("Unable convert text to NID");
13159
            return WOLFSSL_FAILURE;
13160
        }
13161
13162
        entry = wolfSSL_X509_NAME_ENTRY_create_by_NID(NULL,
13163
                  nid, type, (unsigned char*)bytes, len);
13164
        if (entry == NULL)
13165
            return WOLFSSL_FAILURE;
13166
13167
        ret = wolfSSL_X509_NAME_add_entry(name, entry, loc, set);
13168
        wolfSSL_X509_NAME_ENTRY_free(entry);
13169
13170
        return ret;
13171
    }
13172
13173
    int wolfSSL_X509_NAME_add_entry_by_NID(WOLFSSL_X509_NAME *name, int nid,
13174
                                           int type, const unsigned char *bytes,
13175
                                           int len, int loc, int set)
13176
    {
13177
        int ret;
13178
        WOLFSSL_X509_NAME_ENTRY* entry;
13179
        WOLFSSL_ENTER("wolfSSL_X509_NAME_add_entry_by_NID");
13180
        entry = wolfSSL_X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes,
13181
                len);
13182
        if (entry == NULL)
13183
            return WOLFSSL_FAILURE;
13184
        ret = wolfSSL_X509_NAME_add_entry(name, entry, loc, set);
13185
        wolfSSL_X509_NAME_ENTRY_free(entry);
13186
        return ret;
13187
    }
13188
13189
    WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_delete_entry(
13190
            WOLFSSL_X509_NAME *name, int loc)
13191
    {
13192
        WOLFSSL_X509_NAME_ENTRY* ret;
13193
        WOLFSSL_ENTER("wolfSSL_X509_NAME_delete_entry");
13194
13195
        if (!name) {
13196
            WOLFSSL_MSG("Bad parameter");
13197
            return NULL;
13198
        }
13199
13200
        ret = wolfSSL_X509_NAME_get_entry(name, loc);
13201
        if (!ret) {
13202
            WOLFSSL_MSG("loc entry not found");
13203
            return NULL;
13204
        }
13205
        name->entry[loc].set = 0;
13206
        return ret;
13207
    }
13208
13209
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
13210
13211
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN)
13212
    int wolfSSL_X509_NAME_get_index_by_OBJ(WOLFSSL_X509_NAME *name,
13213
                                           const WOLFSSL_ASN1_OBJECT *obj,
13214
                                           int idx) {
13215
        if (!name || idx >= MAX_NAME_ENTRIES ||
13216
                !obj || !obj->obj) {
13217
            return WOLFSSL_FATAL_ERROR;
13218
        }
13219
13220
        if (idx < 0) {
13221
            idx = -1;
13222
        }
13223
13224
        for (idx++; idx < MAX_NAME_ENTRIES; idx++) {
13225
            /* Find index of desired name */
13226
            if (name->entry[idx].set) {
13227
                if (XSTRLEN(obj->sName) ==
13228
                        XSTRLEN(name->entry[idx].object->sName) &&
13229
                    XSTRNCMP((const char*) obj->sName,
13230
                        name->entry[idx].object->sName, obj->objSz - 1) == 0) {
13231
                    return idx;
13232
                }
13233
            }
13234
        }
13235
        return WOLFSSL_FATAL_ERROR;
13236
    }
13237
#endif
13238
13239
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
13240
    defined(OPENSSL_EXTRA_X509_SMALL)
13241
13242
#ifdef OPENSSL_EXTRA
13243
    int wolfSSL_X509_NAME_ENTRY_set(const WOLFSSL_X509_NAME_ENTRY *ne)
13244
    {
13245
        if (ne != NULL) {
13246
            return ne->set;
13247
        }
13248
        return 0;
13249
    }
13250
#endif
13251
13252
13253
    /* returns a pointer to the internal entry at location 'loc' on success,
13254
     * a null pointer is returned in fail cases */
13255
    WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_get_entry(
13256
                                             WOLFSSL_X509_NAME *name, int loc)
13257
    {
13258
#ifdef WOLFSSL_DEBUG_OPENSSL
13259
        WOLFSSL_ENTER("wolfSSL_X509_NAME_get_entry");
13260
#endif
13261
13262
        if (name == NULL) {
13263
            return NULL;
13264
        }
13265
13266
        if (loc < 0 || loc >= MAX_NAME_ENTRIES) {
13267
            WOLFSSL_MSG("Bad argument");
13268
            return NULL;
13269
        }
13270
13271
        if (name->entry[loc].set) {
13272
#ifdef WOLFSSL_PYTHON
13273
            /* "set" is not only flag use, but also stack index position use in
13274
            *  OpenSSL. Python makes tuple based on this number. Therefore,
13275
            *  updating "set" by position + 1. "plus 1" means to avoid "not set"
13276
            *  zero.
13277
            */
13278
            name->entry[loc].set = loc + 1;
13279
#endif
13280
            return &name->entry[loc];
13281
        }
13282
        else {
13283
            return NULL;
13284
        }
13285
    }
13286
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
13287
13288
#ifdef OPENSSL_EXTRA
13289
13290
int wolfSSL_X509_check_private_key(WOLFSSL_X509 *x509, WOLFSSL_EVP_PKEY *key)
13291
{
13292
    WOLFSSL_ENTER("wolfSSL_X509_check_private_key");
13293
13294
    if (!x509 || !key) {
13295
        WOLFSSL_MSG("Bad parameter");
13296
        return WOLFSSL_FAILURE;
13297
    }
13298
13299
#ifndef NO_CHECK_PRIVATE_KEY
13300
    return wc_CheckPrivateKey((byte*)key->pkey.ptr, key->pkey_sz,
13301
            x509->pubKey.buffer, x509->pubKey.length,
13302
            (enum Key_Sum)x509->pubKeyOID, key->heap) == 1 ?
13303
                    WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
13304
#else
13305
    /* not compiled in */
13306
    return WOLFSSL_SUCCESS;
13307
#endif
13308
}
13309
13310
#endif /* OPENSSL_EXTRA */
13311
13312
#if defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL) \
13313
    || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA)
13314
#ifndef NO_BIO
13315
13316
#ifdef WOLFSSL_CERT_GEN
13317
13318
#ifdef WOLFSSL_CERT_REQ
13319
/* writes the x509 from x to the WOLFSSL_BIO bp
13320
 *
13321
 * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on fail
13322
 */
13323
int wolfSSL_PEM_write_bio_X509_REQ(WOLFSSL_BIO *bp, WOLFSSL_X509 *x)
13324
{
13325
    byte* pem;
13326
    int   pemSz = 0;
13327
    const unsigned char* der;
13328
    int derSz;
13329
    int ret;
13330
13331
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509_REQ");
13332
13333
    if (x == NULL || bp == NULL) {
13334
        return WOLFSSL_FAILURE;
13335
    }
13336
13337
    der = wolfSSL_X509_get_der(x, &derSz);
13338
    if (der == NULL) {
13339
        return WOLFSSL_FAILURE;
13340
    }
13341
13342
    /* get PEM size */
13343
    pemSz = wc_DerToPemEx(der, (word32)derSz, NULL, 0, NULL, CERTREQ_TYPE);
13344
    if (pemSz < 0) {
13345
        return WOLFSSL_FAILURE;
13346
    }
13347
13348
    /* create PEM buffer and convert from DER */
13349
    pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13350
    if (pem == NULL) {
13351
        return WOLFSSL_FAILURE;
13352
    }
13353
    if (wc_DerToPemEx(der, (word32)derSz, pem, pemSz, NULL, CERTREQ_TYPE) < 0) {
13354
        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13355
        return WOLFSSL_FAILURE;
13356
    }
13357
13358
    /* write the PEM to BIO */
13359
    ret = wolfSSL_BIO_write(bp, pem, pemSz);
13360
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13361
13362
    if (ret <= 0) return WOLFSSL_FAILURE;
13363
    return WOLFSSL_SUCCESS;
13364
}
13365
#endif /* WOLFSSL_CERT_REQ */
13366
13367
13368
/* writes the x509 from x to the WOLFSSL_BIO bp
13369
 *
13370
 * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on fail
13371
 */
13372
int wolfSSL_PEM_write_bio_X509_AUX(WOLFSSL_BIO *bp, WOLFSSL_X509 *x)
13373
{
13374
    byte* pem;
13375
    int   pemSz = 0;
13376
    const unsigned char* der;
13377
    int derSz;
13378
    int ret;
13379
13380
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509_AUX");
13381
13382
    if (bp == NULL || x == NULL) {
13383
        WOLFSSL_MSG("NULL argument passed in");
13384
        return WOLFSSL_FAILURE;
13385
    }
13386
13387
    der = wolfSSL_X509_get_der(x, &derSz);
13388
    if (der == NULL) {
13389
        return WOLFSSL_FAILURE;
13390
    }
13391
13392
    /* get PEM size */
13393
    pemSz = wc_DerToPemEx(der, (word32)derSz, NULL, 0, NULL, CERT_TYPE);
13394
    if (pemSz < 0) {
13395
        return WOLFSSL_FAILURE;
13396
    }
13397
13398
    /* create PEM buffer and convert from DER */
13399
    pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13400
    if (pem == NULL) {
13401
        return WOLFSSL_FAILURE;
13402
    }
13403
    if (wc_DerToPemEx(der, (word32)derSz, pem, pemSz, NULL, CERT_TYPE) < 0) {
13404
        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13405
        return WOLFSSL_FAILURE;
13406
    }
13407
13408
    /* write the PEM to BIO */
13409
    ret = wolfSSL_BIO_write(bp, pem, pemSz);
13410
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13411
13412
    if (ret <= 0) return WOLFSSL_FAILURE;
13413
    return WOLFSSL_SUCCESS;
13414
}
13415
13416
int wolfSSL_PEM_write_bio_X509(WOLFSSL_BIO *bio, WOLFSSL_X509 *cert)
13417
{
13418
    byte* pem = NULL;
13419
    int   pemSz = 0;
13420
    /* Get large buffer to hold cert der */
13421
    const byte* der = NULL;
13422
    int derSz = X509_BUFFER_SZ;
13423
    int ret;
13424
13425
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509");
13426
13427
    if (bio == NULL || cert == NULL) {
13428
        WOLFSSL_MSG("NULL argument passed in");
13429
        return WOLFSSL_FAILURE;
13430
    }
13431
13432
    /* Do not call wolfssl_x509_make_der() here. If we did, then need to re-sign
13433
     * because we don't know the original order of the extensions and so we must
13434
     * assume our extensions are in a different order, thus need to re-sign. */
13435
    der = wolfSSL_X509_get_der(cert, &derSz);
13436
    if (der == NULL) {
13437
        goto error;
13438
    }
13439
13440
    /* get PEM size */
13441
    pemSz = wc_DerToPemEx(der, (word32)derSz, NULL, 0, NULL, CERT_TYPE);
13442
    if (pemSz < 0) {
13443
        goto error;
13444
    }
13445
13446
    /* create PEM buffer and convert from DER */
13447
    pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13448
    if (pem == NULL) {
13449
        goto error;
13450
    }
13451
    if (wc_DerToPemEx(der, (word32)derSz, pem, pemSz, NULL, CERT_TYPE) < 0) {
13452
        goto error;
13453
    }
13454
13455
    /* write the PEM to BIO */
13456
    ret = wolfSSL_BIO_write(bio, pem, pemSz);
13457
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13458
13459
    if (ret <= 0) return WOLFSSL_FAILURE;
13460
    return WOLFSSL_SUCCESS;
13461
13462
error:
13463
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13464
    return WOLFSSL_FAILURE;
13465
}
13466
#endif /* WOLFSSL_CERT_GEN */
13467
13468
#endif /* !NO_BIO */
13469
#endif /* HAVE_LIGHTY || HAVE_STUNNEL || WOLFSSL_MYSQL_COMPATIBLE */
13470
13471
#if defined(OPENSSL_EXTRA) || defined(HAVE_STUNNEL) || \
13472
        defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY) || \
13473
        defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_OPENSSH) || \
13474
        defined(HAVE_SBLIM_SFCB)
13475
13476
WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_sk_X509_NAME_new(
13477
        WOLF_SK_COMPARE_CB(WOLFSSL_X509_NAME, cb))
13478
{
13479
    WOLFSSL_STACK* sk;
13480
    (void)cb;
13481
13482
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_new");
13483
13484
    sk = wolfSSL_sk_new_node(NULL);
13485
    if (sk != NULL) {
13486
        sk->type = STACK_TYPE_X509_NAME;
13487
    }
13488
13489
    return sk;
13490
}
13491
13492
int wolfSSL_sk_X509_NAME_num(const WOLF_STACK_OF(WOLFSSL_X509_NAME) *sk)
13493
{
13494
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_num");
13495
13496
    if (sk == NULL)
13497
        return BAD_FUNC_ARG;
13498
13499
    return (int)sk->num;
13500
}
13501
13502
/* Getter function for WOLFSSL_X509_NAME pointer
13503
 *
13504
 * sk is the stack to retrieve pointer from
13505
 * i  is the index value in stack
13506
 *
13507
 * returns a pointer to a WOLFSSL_X509_NAME structure on success and NULL on
13508
 *         fail
13509
 */
13510
WOLFSSL_X509_NAME* wolfSSL_sk_X509_NAME_value(
13511
    const WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, int i)
13512
{
13513
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_value");
13514
    return (WOLFSSL_X509_NAME*)wolfSSL_sk_value(sk, i);
13515
}
13516
13517
WOLFSSL_X509_NAME* wolfSSL_sk_X509_NAME_pop(
13518
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk)
13519
{
13520
    return (WOLFSSL_X509_NAME*)wolfSSL_sk_pop(sk);
13521
}
13522
13523
void wolfSSL_sk_X509_NAME_pop_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk,
13524
    void (*f) (WOLFSSL_X509_NAME*))
13525
{
13526
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_pop_free");
13527
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
13528
}
13529
13530
/* Free only the sk structure, NOT X509_NAME members */
13531
void wolfSSL_sk_X509_NAME_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk)
13532
{
13533
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_free");
13534
    wolfSSL_sk_free(sk);
13535
}
13536
13537
int wolfSSL_sk_X509_NAME_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk,
13538
    WOLFSSL_X509_NAME* name)
13539
{
13540
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_push");
13541
13542
    return wolfSSL_sk_push(sk, name);
13543
}
13544
13545
/* return index of found, or negative to indicate not found */
13546
int wolfSSL_sk_X509_NAME_find(const WOLF_STACK_OF(WOLFSSL_X509_NAME) *sk,
13547
    WOLFSSL_X509_NAME *name)
13548
{
13549
    int i;
13550
13551
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_find");
13552
13553
    if (sk == NULL)
13554
        return BAD_FUNC_ARG;
13555
13556
    for (i = 0; sk; i++, sk = sk->next) {
13557
        if (wolfSSL_X509_NAME_cmp(sk->data.name, name) == 0) {
13558
            return i;
13559
        }
13560
    }
13561
    return WOLFSSL_FATAL_ERROR;
13562
}
13563
13564
/* Name Entry */
13565
WOLF_STACK_OF(WOLFSSL_X509_NAME_ENTRY)* wolfSSL_sk_X509_NAME_ENTRY_new(
13566
    WOLF_SK_COMPARE_CB(WOLFSSL_X509_NAME_ENTRY, cb))
13567
{
13568
    WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL);
13569
    if (sk != NULL) {
13570
        sk->type = STACK_TYPE_X509_NAME_ENTRY;
13571
        (void)cb;
13572
    }
13573
    return sk;
13574
}
13575
13576
int wolfSSL_sk_X509_NAME_ENTRY_push(WOLF_STACK_OF(WOLFSSL_X509_NAME_ENTRY)* sk,
13577
    WOLFSSL_X509_NAME_ENTRY* name_entry)
13578
{
13579
    return wolfSSL_sk_push(sk, name_entry);
13580
}
13581
13582
WOLFSSL_X509_NAME_ENTRY* wolfSSL_sk_X509_NAME_ENTRY_value(
13583
    const WOLF_STACK_OF(WOLFSSL_X509_NAME_ENTRY)* sk, int i)
13584
{
13585
    return (WOLFSSL_X509_NAME_ENTRY*)wolfSSL_sk_value(sk, i);
13586
}
13587
13588
int wolfSSL_sk_X509_NAME_ENTRY_num(
13589
    const WOLF_STACK_OF(WOLFSSL_X509_NAME_ENTRY)* sk)
13590
{
13591
    if (sk == NULL)
13592
        return BAD_FUNC_ARG;
13593
    return (int)sk->num;
13594
}
13595
13596
void wolfSSL_sk_X509_NAME_ENTRY_free(WOLF_STACK_OF(WOLFSSL_X509_NAME_ENTRY)* sk)
13597
{
13598
    wolfSSL_sk_free(sk);
13599
}
13600
13601
#endif /* OPENSSL_EXTRA || HAVE_STUNNEL || WOLFSSL_NGINX ||
13602
            HAVE_LIGHTY || WOLFSSL_HAPROXY ||
13603
            WOLFSSL_OPENSSH || HAVE_SBLIM_SFCB */
13604
13605
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
13606
    (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
13607
    defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
13608
    defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB))
13609
13610
#if defined(OPENSSL_ALL)
13611
WOLFSSL_X509_INFO* wolfSSL_X509_INFO_new(void)
13612
{
13613
    WOLFSSL_X509_INFO* info;
13614
    info = (WOLFSSL_X509_INFO*)XMALLOC(sizeof(WOLFSSL_X509_INFO), NULL,
13615
        DYNAMIC_TYPE_X509);
13616
    if (info) {
13617
        XMEMSET(info, 0, sizeof(*info));
13618
    }
13619
    return info;
13620
}
13621
13622
void wolfSSL_X509_INFO_free(WOLFSSL_X509_INFO* info)
13623
{
13624
    if (info == NULL)
13625
        return;
13626
13627
    if (info->x509) {
13628
        wolfSSL_X509_free(info->x509);
13629
        info->x509 = NULL;
13630
    }
13631
#ifdef HAVE_CRL
13632
    if (info->crl) {
13633
        wolfSSL_X509_CRL_free(info->crl);
13634
        info->crl = NULL;
13635
    }
13636
#endif
13637
    wolfSSL_X509_PKEY_free(info->x_pkey);
13638
    info->x_pkey = NULL;
13639
13640
    XFREE(info, NULL, DYNAMIC_TYPE_X509);
13641
}
13642
#endif
13643
13644
WOLFSSL_STACK* wolfSSL_sk_X509_INFO_new_null(void)
13645
{
13646
    WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL);
13647
    if (sk) {
13648
        sk->type = STACK_TYPE_X509_INFO;
13649
    }
13650
    return sk;
13651
}
13652
13653
int wolfSSL_sk_X509_INFO_num(const WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk)
13654
{
13655
    WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_num");
13656
13657
    return wolfSSL_sk_num(sk);
13658
}
13659
13660
WOLFSSL_X509_INFO* wolfSSL_sk_X509_INFO_value(
13661
        const WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk, int i)
13662
{
13663
    WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_value");
13664
13665
    return (WOLFSSL_X509_INFO *)wolfSSL_sk_value(sk, i);
13666
}
13667
13668
WOLFSSL_X509_INFO* wolfSSL_sk_X509_INFO_pop(
13669
        WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk)
13670
{
13671
    return (WOLFSSL_X509_INFO*)wolfSSL_sk_pop(sk);
13672
}
13673
13674
#if defined(OPENSSL_ALL)
13675
void wolfSSL_sk_X509_INFO_pop_free(WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
13676
    void (*f) (WOLFSSL_X509_INFO*))
13677
{
13678
    WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_pop_free");
13679
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
13680
}
13681
13682
void wolfSSL_sk_X509_INFO_free(WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk)
13683
{
13684
    WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_free");
13685
    wolfSSL_sk_free(sk);
13686
}
13687
13688
/* Adds the WOLFSSL_X509_INFO to the stack "sk". "sk" takes control of "in" and
13689
 * tries to free it when the stack is free'd.
13690
 *
13691
 * return number of elements on success 0 on fail
13692
 */
13693
int wolfSSL_sk_X509_INFO_push(WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
13694
                                                      WOLFSSL_X509_INFO* in)
13695
{
13696
    return wolfSSL_sk_push(sk, in);
13697
}
13698
13699
/* Creates a duplicate of WOLF_STACK_OF(WOLFSSL_X509_NAME).
13700
 * Returns a new WOLF_STACK_OF(WOLFSSL_X509_NAME) or NULL on failure */
13701
WOLF_STACK_OF(WOLFSSL_X509_NAME) *wolfSSL_dup_CA_list(
13702
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk)
13703
{
13704
    int i;
13705
    const int num = wolfSSL_sk_X509_NAME_num(sk);
13706
    WOLF_STACK_OF(WOLFSSL_X509_NAME) *copy;
13707
    WOLFSSL_X509_NAME *name;
13708
13709
    WOLFSSL_ENTER("wolfSSL_dup_CA_list");
13710
13711
    copy = wolfSSL_sk_X509_NAME_new(NULL);
13712
    if (copy == NULL) {
13713
        WOLFSSL_MSG("Memory error");
13714
        return NULL;
13715
    }
13716
13717
    for (i = 0; i < num; i++) {
13718
        name = wolfSSL_X509_NAME_dup(wolfSSL_sk_X509_NAME_value(sk, i));
13719
        if (name == NULL || wolfSSL_sk_X509_NAME_push(copy, name) <= 0) {
13720
            WOLFSSL_MSG("Memory error");
13721
            wolfSSL_sk_X509_NAME_pop_free(copy, wolfSSL_X509_NAME_free);
13722
            wolfSSL_X509_NAME_free(name);
13723
            return NULL;
13724
        }
13725
    }
13726
13727
    return copy;
13728
}
13729
13730
void* wolfSSL_sk_X509_OBJECT_value(WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk,
13731
    int i)
13732
{
13733
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_value");
13734
    for (; sk != NULL && i > 0; i--)
13735
        sk = sk->next;
13736
13737
    if (i != 0 || sk == NULL)
13738
        return NULL;
13739
    return sk->data.x509_obj;
13740
}
13741
13742
int wolfSSL_sk_X509_OBJECT_num(const WOLF_STACK_OF(WOLFSSL_X509_OBJECT) *s)
13743
{
13744
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_num");
13745
    if (s) {
13746
        return (int)s->num;
13747
    }
13748
    else {
13749
        return 0;
13750
    }
13751
}
13752
13753
int wolfSSL_sk_X509_NAME_set_cmp_func(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk,
13754
    WOLF_SK_COMPARE_CB(WOLFSSL_X509_NAME, cb))
13755
{
13756
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_set_cmp_func");
13757
13758
    if (sk == NULL)
13759
        return BAD_FUNC_ARG;
13760
13761
    WOLFSSL_MSG("Stack comparison not used in wolfSSL");
13762
    (void)cb;
13763
    return 0;
13764
}
13765
#endif /* OPENSSL_ALL */
13766
13767
#ifndef NO_BIO
13768
13769
/* Helper function for X509_NAME_print_ex. Sets *buf to string for domain
13770
   name attribute based on NID. Returns size of buf */
13771
static int get_dn_attr_by_nid(int n, const char** buf)
13772
{
13773
    int len = 0;
13774
    const char *str;
13775
13776
    switch(n)
13777
    {
13778
        case WC_NID_commonName :
13779
            str = "CN";
13780
            len = 2;
13781
            break;
13782
        case WC_NID_countryName:
13783
            str = "C";
13784
            len = 1;
13785
            break;
13786
        case WC_NID_localityName:
13787
            str = "L";
13788
            len = 1;
13789
            break;
13790
        case WC_NID_stateOrProvinceName:
13791
            str = "ST";
13792
            len = 2;
13793
            break;
13794
        case WC_NID_streetAddress:
13795
            str = "street";
13796
            len = 6;
13797
            break;
13798
        case WC_NID_organizationName:
13799
            str = "O";
13800
            len = 1;
13801
            break;
13802
        case WC_NID_organizationalUnitName:
13803
            str = "OU";
13804
            len = 2;
13805
            break;
13806
        case WC_NID_postalCode:
13807
            str = "postalCode";
13808
            len = 10;
13809
            break;
13810
        case WC_NID_emailAddress:
13811
            str = "emailAddress";
13812
            len = 12;
13813
            break;
13814
        case WC_NID_surname:
13815
            str = "SN";
13816
            len = 2;
13817
            break;
13818
        case WC_NID_givenName:
13819
            str = "GN";
13820
            len = 2;
13821
            break;
13822
        case WC_NID_dnQualifier:
13823
            str = "dnQualifier";
13824
            len = 11;
13825
            break;
13826
        case WC_NID_name:
13827
            str = "name";
13828
            len = 4;
13829
            break;
13830
        case WC_NID_initials:
13831
            str = "initials";
13832
            len = 8;
13833
            break;
13834
        case WC_NID_domainComponent:
13835
            str = "DC";
13836
            len = 2;
13837
            break;
13838
        case WC_NID_pkcs9_contentType:
13839
            str = "contentType";
13840
            len = 11;
13841
            break;
13842
        case WC_NID_userId:
13843
            str = "UID";
13844
            len = 3;
13845
            break;
13846
        case WC_NID_serialNumber:
13847
            str = "serialNumber";
13848
            len = 12;
13849
            break;
13850
        case WC_NID_title:
13851
            str = "title";
13852
            len = 5;
13853
            break;
13854
        case WC_NID_rfc822Mailbox:
13855
            str = "mail";
13856
            len = 4;
13857
            break;
13858
        default:
13859
            WOLFSSL_MSG("Attribute type not found");
13860
            str = NULL;
13861
13862
    }
13863
    if (buf != NULL)
13864
        *buf = str;
13865
    return len;
13866
}
13867
13868
/**
13869
 * Escape input string for RFC2253 requirements. The following characters
13870
 * are escaped with a backslash (\):
13871
 *
13872
 *     1. A space or '#' at the beginning of the string
13873
 *     2. A space at the end of the string
13874
 *     3. One of: ",", "+", """, "\", "<", ">", ";"
13875
 *
13876
 * in    - input string to escape
13877
 * inSz  - length of in, not including the null terminator
13878
 * out   - buffer for output string to be written, will be null terminated
13879
 * outSz - size of out
13880
 *
13881
 * Returns size of output string (not counting NULL terminator) on success,
13882
 * negative on error.
13883
 */
13884
static int wolfSSL_EscapeString_RFC2253(char* in, word32 inSz,
13885
                                        char* out, word32 outSz)
13886
{
13887
    word32 inIdx = 0;
13888
    word32 outIdx = 0;
13889
13890
    if (in == NULL || out == NULL || inSz == 0 || outSz == 0) {
13891
        return BAD_FUNC_ARG;
13892
    }
13893
13894
    for (inIdx = 0; inIdx < inSz; inIdx++) {
13895
13896
        char c = in[inIdx];
13897
13898
        if (((inIdx == 0) && (c == ' ' || c == '#')) ||
13899
            ((inIdx == (inSz-1)) && (c == ' ')) ||
13900
            c == ',' || c == '+' || c == '"' || c == '\\' ||
13901
            c == '<' || c == '>' || c == ';') {
13902
13903
            if (outIdx > (outSz - 1)) {
13904
                return BUFFER_E;
13905
            }
13906
            out[outIdx] = '\\';
13907
            outIdx++;
13908
        }
13909
        if (outIdx > (outSz - 1)) {
13910
            return BUFFER_E;
13911
        }
13912
        out[outIdx] = c;
13913
        outIdx++;
13914
    }
13915
13916
    /* null terminate out */
13917
    if (outIdx > (outSz -1)) {
13918
        return BUFFER_E;
13919
    }
13920
    out[outIdx] = '\0';
13921
13922
    return (int)outIdx;
13923
}
13924
13925
/*
13926
 * Print human readable version of X509_NAME to provided BIO.
13927
 *
13928
 * bio    - output BIO to place name string. Does not include null terminator.
13929
 * name   - input name to convert to string
13930
 * indent - number of indent spaces to prepend to name string
13931
 * flags  - flags to control function behavior. Not all flags are currently
13932
 *          supported/implemented. Currently supported are:
13933
 *              XN_FLAG_RFC2253 - only the backslash escape requirements from
13934
 *                                RFC22523 currently implemented.
13935
 *              XN_FLAG_DN_REV  - print name reversed. Automatically done by
13936
 *                                XN_FLAG_RFC2253.
13937
 *              XN_FLAG_SPC_EQ  - spaces before and after '=' character
13938
 *
13939
 * Returns WOLFSSL_SUCCESS (1) on success, WOLFSSL_FAILURE (0) on failure.
13940
 */
13941
int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name,
13942
                int indent, unsigned long flags)
13943
{
13944
    int i, count = 0, nameStrSz = 0, escapeSz = 0;
13945
    int eqSpace  = 0;
13946
    char eqStr[4];
13947
    char* tmp = NULL;
13948
    char* nameStr = NULL;
13949
    const char *buf = NULL;
13950
    WOLFSSL_X509_NAME_ENTRY* ne;
13951
    WOLFSSL_ASN1_STRING* str;
13952
    char escaped[ASN_NAME_MAX];
13953
13954
    WOLFSSL_ENTER("wolfSSL_X509_NAME_print_ex");
13955
13956
    if ((name == NULL) || (bio == NULL))
13957
        return WOLFSSL_FAILURE;
13958
13959
    XMEMSET(eqStr, 0, sizeof(eqStr));
13960
    if (flags & WOLFSSL_XN_FLAG_SPC_EQ) {
13961
        eqSpace = 2;
13962
        XSTRNCPY(eqStr, " = ", 4);
13963
    }
13964
    else {
13965
        XSTRNCPY(eqStr, "=", 4);
13966
    }
13967
13968
    for (i = 0; i < indent; i++) {
13969
        if (wolfSSL_BIO_write(bio, " ", 1) != 1)
13970
            return WOLFSSL_FAILURE;
13971
    }
13972
13973
    count = wolfSSL_X509_NAME_entry_count(name);
13974
13975
    for (i = 0; i < count; i++) {
13976
        int len;
13977
        int tmpSz;
13978
13979
        /* reverse name order for RFC2253 and DN_REV */
13980
        if ((flags & WOLFSSL_XN_FLAG_RFC2253) ||
13981
            (flags & WOLFSSL_XN_FLAG_DN_REV)) {
13982
            ne = wolfSSL_X509_NAME_get_entry(name, count - i - 1);
13983
        }
13984
        else {
13985
            ne = wolfSSL_X509_NAME_get_entry(name, i);
13986
        }
13987
        if (ne == NULL)
13988
            return WOLFSSL_FAILURE;
13989
13990
        str = wolfSSL_X509_NAME_ENTRY_get_data(ne);
13991
        if (str == NULL)
13992
            return WOLFSSL_FAILURE;
13993
13994
        if (flags & WOLFSSL_XN_FLAG_RFC2253) {
13995
            /* escape string for RFC 2253, ret sz not counting null term */
13996
            escapeSz = wolfSSL_EscapeString_RFC2253(str->data,
13997
                            str->length, escaped, sizeof(escaped));
13998
            if (escapeSz < 0)
13999
                return WOLFSSL_FAILURE;
14000
14001
            nameStr = escaped;
14002
            nameStrSz = escapeSz;
14003
        }
14004
        else {
14005
            nameStr = str->data;
14006
            nameStrSz = str->length;
14007
        }
14008
14009
        /* len is without null terminator */
14010
        len = get_dn_attr_by_nid(ne->nid, &buf);
14011
        if (len == 0 || buf == NULL)
14012
            return WOLFSSL_FAILURE;
14013
14014
        /* + 4 for '=', comma space and '\0'*/
14015
        tmpSz = nameStrSz + len + 4 + eqSpace;
14016
        tmp = (char*)XMALLOC(tmpSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14017
        if (tmp == NULL) {
14018
            return WOLFSSL_FAILURE;
14019
        }
14020
14021
        if (i < count - 1) {
14022
            if (XSNPRINTF(tmp, (size_t)tmpSz, "%s%s%s, ", buf, eqStr, nameStr)
14023
                >= tmpSz)
14024
            {
14025
                WOLFSSL_MSG("buffer overrun");
14026
                XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14027
                return WOLFSSL_FAILURE;
14028
            }
14029
14030
            tmpSz = len + nameStrSz + 3 + eqSpace; /* 3 for '=', comma space */
14031
        }
14032
        else {
14033
            if (XSNPRINTF(tmp, (size_t)tmpSz, "%s%s%s", buf, eqStr, nameStr)
14034
                >= tmpSz)
14035
            {
14036
                WOLFSSL_MSG("buffer overrun");
14037
                XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14038
                return WOLFSSL_FAILURE;
14039
            }
14040
            tmpSz = len + nameStrSz + 1 + eqSpace; /* 1 for '=' */
14041
            if (bio->type != WOLFSSL_BIO_FILE &&
14042
                                              bio->type != WOLFSSL_BIO_MEMORY) {
14043
                ++tmpSz; /* include the terminating null when not writing to a
14044
                          * file.
14045
                          */
14046
            }
14047
        }
14048
14049
        if (wolfSSL_BIO_write(bio, tmp, tmpSz) != tmpSz) {
14050
            XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14051
            return WOLFSSL_FAILURE;
14052
        }
14053
14054
        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14055
    }
14056
14057
    return WOLFSSL_SUCCESS;
14058
}
14059
14060
#ifndef NO_FILESYSTEM
14061
int wolfSSL_X509_NAME_print_ex_fp(XFILE file, WOLFSSL_X509_NAME* name,
14062
        int indent, unsigned long flags)
14063
{
14064
    WOLFSSL_BIO* bio;
14065
    int ret;
14066
14067
    WOLFSSL_ENTER("wolfSSL_X509_NAME_print_ex_fp");
14068
14069
    if (!(bio = wolfSSL_BIO_new_fp(file, WOLFSSL_BIO_NOCLOSE))) {
14070
        WOLFSSL_MSG("wolfSSL_BIO_new_fp error");
14071
        return WOLFSSL_FAILURE;
14072
    }
14073
14074
    ret = wolfSSL_X509_NAME_print_ex(bio, name, indent, flags);
14075
14076
    wolfSSL_BIO_free(bio);
14077
14078
    return ret;
14079
}
14080
#endif /* NO_FILESYSTEM */
14081
#endif /* !NO_BIO */
14082
14083
#ifndef NO_WOLFSSL_STUB
14084
WOLFSSL_ASN1_BIT_STRING* wolfSSL_X509_get0_pubkey_bitstr(const WOLFSSL_X509* x)
14085
{
14086
    (void)x;
14087
    WOLFSSL_ENTER("wolfSSL_X509_get0_pubkey_bitstr");
14088
    WOLFSSL_STUB("X509_get0_pubkey_bitstr");
14089
14090
    return NULL;
14091
}
14092
#endif
14093
14094
#ifdef OPENSSL_ALL
14095
WOLFSSL_X509_LOOKUP_TYPE wolfSSL_X509_OBJECT_get_type(
14096
        const WOLFSSL_X509_OBJECT* obj)
14097
{
14098
    if (obj == NULL)
14099
        return WOLFSSL_X509_LU_NONE;
14100
    return obj->type;
14101
}
14102
14103
WOLFSSL_X509_OBJECT* wolfSSL_X509_OBJECT_new(void)
14104
{
14105
    WOLFSSL_X509_OBJECT* ret = (WOLFSSL_X509_OBJECT*)
14106
            XMALLOC(sizeof(WOLFSSL_X509_OBJECT), NULL, DYNAMIC_TYPE_OPENSSL);
14107
    if (ret != NULL)
14108
        XMEMSET(ret, 0, sizeof(WOLFSSL_X509_OBJECT));
14109
    return ret;
14110
}
14111
14112
void wolfSSL_X509_OBJECT_free(WOLFSSL_X509_OBJECT *obj)
14113
{
14114
    WOLFSSL_ENTER("wolfSSL_X509_OBJECT_free");
14115
    if (obj != NULL) {
14116
        if (obj->type == WOLFSSL_X509_LU_X509) {
14117
            wolfSSL_X509_free(obj->data.x509);
14118
        }
14119
    #ifdef HAVE_CRL
14120
        else if (obj->type == WOLFSSL_X509_LU_CRL) {
14121
            wolfSSL_X509_CRL_free(obj->data.crl);
14122
        }
14123
    #endif
14124
        else {
14125
            /* We don't free as this will point to
14126
             * store->cm->crl which we don't own */
14127
            WOLFSSL_MSG("Not free'ing CRL in WOLFSSL_X509_OBJECT");
14128
        }
14129
        XFREE(obj, NULL, DYNAMIC_TYPE_OPENSSL);
14130
    }
14131
}
14132
14133
WOLFSSL_X509_OBJECT *wolfSSL_X509_OBJECT_retrieve_by_subject(
14134
        WOLF_STACK_OF(WOLFSSL_X509_OBJECT) *sk,
14135
        WOLFSSL_X509_LOOKUP_TYPE type,
14136
        WOLFSSL_X509_NAME *name)
14137
{
14138
    int i;
14139
14140
    WOLFSSL_ENTER("wolfSSL_X509_OBJECT_retrieve_by_subject");
14141
14142
    if (sk == NULL || name == NULL)
14143
        return NULL;
14144
14145
    for (i = 0; i < wolfSSL_sk_X509_OBJECT_num(sk); i++) {
14146
        WOLFSSL_X509_OBJECT* obj = (WOLFSSL_X509_OBJECT *)
14147
            wolfSSL_sk_X509_OBJECT_value(sk, i);
14148
        if (obj != NULL && obj->type == type &&
14149
            wolfSSL_X509_NAME_cmp(
14150
                wolfSSL_X509_get_subject_name(obj->data.x509), name) == 0)
14151
            return obj;
14152
    }
14153
    return NULL;
14154
}
14155
#endif /* OPENSSL_ALL */
14156
14157
#ifndef NO_WOLFSSL_STUB
14158
WOLFSSL_X509_OBJECT* wolfSSL_sk_X509_OBJECT_delete(
14159
    WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk, int i)
14160
{
14161
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_delete");
14162
    WOLFSSL_STUB("wolfSSL_sk_X509_OBJECT_delete");
14163
    (void)sk;
14164
    (void)i;
14165
    return NULL;
14166
}
14167
#endif
14168
14169
WOLFSSL_X509 *wolfSSL_X509_OBJECT_get0_X509(const WOLFSSL_X509_OBJECT *obj)
14170
{
14171
    if (obj != NULL && obj->type == WOLFSSL_X509_LU_X509)
14172
        return obj->data.x509;
14173
    return NULL;
14174
}
14175
14176
WOLFSSL_X509_CRL *wolfSSL_X509_OBJECT_get0_X509_CRL(WOLFSSL_X509_OBJECT *obj)
14177
{
14178
    if (obj != NULL && obj->type == WOLFSSL_X509_LU_CRL)
14179
        return obj->data.crl;
14180
    return NULL;
14181
}
14182
14183
#endif /* OPENSSL_ALL || (OPENSSL_EXTRA && (HAVE_STUNNEL || WOLFSSL_NGINX ||
14184
        * HAVE_LIGHTY || WOLFSSL_HAPROXY || WOLFSSL_OPENSSH ||
14185
        * HAVE_SBLIM_SFCB)) */
14186
14187
14188
#if defined(OPENSSL_EXTRA)
14189
14190
int wolfSSL_sk_X509_num(const WOLF_STACK_OF(WOLFSSL_X509) *s)
14191
{
14192
    WOLFSSL_ENTER("wolfSSL_sk_X509_num");
14193
14194
    if (s == NULL)
14195
        return WOLFSSL_FATAL_ERROR;
14196
    return (int)s->num;
14197
}
14198
14199
#endif /* OPENSSL_EXTRA */
14200
14201
#ifdef HAVE_EX_DATA_CRYPTO
14202
int wolfSSL_X509_get_ex_new_index(int idx, void *arg,
14203
                                  WOLFSSL_CRYPTO_EX_new* new_func,
14204
                                  WOLFSSL_CRYPTO_EX_dup* dup_func,
14205
                                  WOLFSSL_CRYPTO_EX_free* free_func)
14206
{
14207
    WOLFSSL_ENTER("wolfSSL_X509_get_ex_new_index");
14208
14209
    return wolfssl_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_X509, idx, arg,
14210
                                    new_func, dup_func, free_func);
14211
}
14212
#endif
14213
14214
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
14215
void *wolfSSL_X509_get_ex_data(WOLFSSL_X509 *x509, int idx)
14216
{
14217
    WOLFSSL_ENTER("wolfSSL_X509_get_ex_data");
14218
#ifdef HAVE_EX_DATA
14219
    if (x509 != NULL) {
14220
        return wolfSSL_CRYPTO_get_ex_data(&x509->ex_data, idx);
14221
    }
14222
#else
14223
    (void)x509;
14224
    (void)idx;
14225
#endif
14226
    return NULL;
14227
}
14228
14229
int wolfSSL_X509_set_ex_data(WOLFSSL_X509 *x509, int idx, void *data)
14230
{
14231
    WOLFSSL_ENTER("wolfSSL_X509_set_ex_data");
14232
#ifdef HAVE_EX_DATA
14233
    if (x509 != NULL) {
14234
        return wolfSSL_CRYPTO_set_ex_data(&x509->ex_data, idx, data);
14235
    }
14236
#else
14237
    (void)x509;
14238
    (void)idx;
14239
    (void)data;
14240
#endif
14241
    return WOLFSSL_FAILURE;
14242
}
14243
14244
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
14245
int wolfSSL_X509_set_ex_data_with_cleanup(
14246
    WOLFSSL_X509 *x509,
14247
    int idx,
14248
    void *data,
14249
    wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
14250
{
14251
    WOLFSSL_ENTER("wolfSSL_X509_set_ex_data_with_cleanup");
14252
    if (x509 != NULL)
14253
    {
14254
        return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&x509->ex_data, idx,
14255
                                                       data, cleanup_routine);
14256
    }
14257
    return WOLFSSL_FAILURE;
14258
}
14259
#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
14260
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
14261
14262
14263
#ifndef NO_ASN
14264
int wolfSSL_X509_check_host(WOLFSSL_X509 *x, const char *chk, size_t chklen,
14265
                    unsigned int flags, char **peername)
14266
0
{
14267
0
    int         ret;
14268
0
    size_t      i;
14269
#ifdef WOLFSSL_SMALL_STACK
14270
    DecodedCert *dCert;
14271
#else
14272
0
    DecodedCert dCert[1];
14273
0
#endif
14274
14275
0
    WOLFSSL_ENTER("wolfSSL_X509_check_host");
14276
14277
    /* flags and peername not needed for Nginx. */
14278
0
    (void)peername;
14279
14280
0
    if ((x == NULL) || (chk == NULL)) {
14281
0
        WOLFSSL_MSG("Invalid parameter");
14282
0
        return WOLFSSL_FAILURE;
14283
0
    }
14284
14285
0
    if (flags & WOLFSSL_NO_WILDCARDS) {
14286
0
        WOLFSSL_MSG("X509_CHECK_FLAG_NO_WILDCARDS not yet implemented");
14287
0
        return WOLFSSL_FAILURE;
14288
0
    }
14289
0
    if (flags & WOLFSSL_NO_PARTIAL_WILDCARDS) {
14290
0
        WOLFSSL_MSG("X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS not yet implemented");
14291
0
        return WOLFSSL_FAILURE;
14292
0
    }
14293
0
    if (flags & WOLFSSL_MULTI_LABEL_WILDCARDS) {
14294
0
        WOLFSSL_MSG("X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS not yet implemented");
14295
0
        return WOLFSSL_FAILURE;
14296
0
    }
14297
14298
#ifdef WOLFSSL_SMALL_STACK
14299
    dCert = (DecodedCert *)XMALLOC(sizeof(*dCert), x->heap,
14300
                                   DYNAMIC_TYPE_DCERT);
14301
    if (dCert == NULL) {
14302
        WOLFSSL_MSG("\tout of memory");
14303
        return WOLFSSL_FATAL_ERROR;
14304
    }
14305
#endif
14306
14307
0
    InitDecodedCert(dCert, x->derCert->buffer, x->derCert->length, NULL);
14308
0
    ret = ParseCertRelative(dCert, CERT_TYPE, 0, NULL, NULL);
14309
0
    if (ret != 0) {
14310
0
        goto out;
14311
0
    }
14312
14313
    /* Replicate openssl behavior for checklen */
14314
0
    if (chklen == 0) {
14315
0
        chklen = (size_t)(XSTRLEN(chk));
14316
0
    }
14317
0
    else {
14318
0
        for (i = 0; i < (chklen > 1 ? chklen - 1 : chklen); i++) {
14319
0
            if (chk[i] == '\0') {
14320
0
                ret = WOLFSSL_FATAL_ERROR;
14321
0
                goto out;
14322
0
            }
14323
0
        }
14324
0
    }
14325
0
    if (chklen > 1 && (chk[chklen - 1] == '\0')) {
14326
0
        chklen--;
14327
0
    }
14328
14329
0
    ret = CheckHostName(dCert, (char *)chk, chklen, flags);
14330
14331
0
out:
14332
14333
0
    FreeDecodedCert(dCert);
14334
#ifdef WOLFSSL_SMALL_STACK
14335
    XFREE(dCert, x->heap, DYNAMIC_TYPE_DCERT);
14336
#endif
14337
14338
0
    if (ret != 0)
14339
0
        return WOLFSSL_FAILURE;
14340
0
    return WOLFSSL_SUCCESS;
14341
0
}
14342
14343
14344
int wolfSSL_X509_check_ip_asc(WOLFSSL_X509 *x, const char *ipasc,
14345
        unsigned int flags)
14346
0
{
14347
0
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
14348
#ifdef WOLFSSL_SMALL_STACK
14349
    DecodedCert *dCert = NULL;
14350
#else
14351
0
    DecodedCert dCert[1];
14352
0
#endif
14353
14354
0
    WOLFSSL_ENTER("wolfSSL_X509_check_ip_asc");
14355
14356
    /* flags not yet implemented */
14357
0
    (void)flags;
14358
14359
0
    if ((x == NULL) || (x->derCert == NULL) || (ipasc == NULL)) {
14360
0
        WOLFSSL_MSG("Invalid parameter");
14361
0
    }
14362
0
    else {
14363
0
        ret = WOLFSSL_SUCCESS;
14364
0
    }
14365
14366
#ifdef WOLFSSL_SMALL_STACK
14367
    if (ret == WOLFSSL_SUCCESS) {
14368
        dCert = (DecodedCert *)XMALLOC(sizeof(*dCert), x->heap,
14369
                                       DYNAMIC_TYPE_DCERT);
14370
        if (dCert == NULL) {
14371
            WOLFSSL_MSG("\tout of memory");
14372
            ret = WOLFSSL_FAILURE;
14373
        }
14374
    }
14375
#endif
14376
14377
0
    if (ret == WOLFSSL_SUCCESS) {
14378
0
        InitDecodedCert(dCert, x->derCert->buffer, x->derCert->length, NULL);
14379
0
        ret = ParseCertRelative(dCert, CERT_TYPE, 0, NULL, NULL);
14380
0
        if (ret != 0) {
14381
0
            ret = WOLFSSL_FAILURE;
14382
0
        }
14383
0
        else {
14384
0
            ret = CheckIPAddr(dCert, ipasc);
14385
0
            if (ret != 0) {
14386
0
                ret = WOLFSSL_FAILURE;
14387
0
            }
14388
0
            else {
14389
0
                ret = WOLFSSL_SUCCESS;
14390
0
            }
14391
0
        }
14392
0
        FreeDecodedCert(dCert);
14393
0
    }
14394
14395
#ifdef WOLFSSL_SMALL_STACK
14396
    if (x != NULL) {
14397
        XFREE(dCert, x->heap, DYNAMIC_TYPE_DCERT);
14398
    }
14399
#endif
14400
14401
0
    return ret;
14402
0
}
14403
#endif
14404
14405
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN)
14406
int wolfSSL_X509_check_email(WOLFSSL_X509 *x, const char *chk, size_t chkLen,
14407
                             unsigned int flags)
14408
{
14409
    WOLFSSL_X509_NAME *subjName;
14410
    int emailLen;
14411
    char *emailBuf;
14412
14413
    (void)flags;
14414
14415
    WOLFSSL_ENTER("wolfSSL_X509_check_email");
14416
14417
    if ((x == NULL) || (chk == NULL)) {
14418
        WOLFSSL_MSG("Invalid parameter");
14419
        return WOLFSSL_FAILURE;
14420
    }
14421
14422
    subjName = wolfSSL_X509_get_subject_name(x);
14423
    if (subjName == NULL)
14424
        return WOLFSSL_FAILURE;
14425
14426
    /* Call with NULL buffer to get required length. */
14427
    emailLen = wolfSSL_X509_NAME_get_text_by_NID(subjName, WC_NID_emailAddress,
14428
                                                 NULL, 0);
14429
    if (emailLen < 0)
14430
        return WOLFSSL_FAILURE;
14431
14432
    ++emailLen; /* Add 1 for the NUL. */
14433
14434
    emailBuf = (char*)XMALLOC(emailLen, x->heap, DYNAMIC_TYPE_OPENSSL);
14435
    if (emailBuf == NULL)
14436
        return WOLFSSL_FAILURE;
14437
14438
    emailLen = wolfSSL_X509_NAME_get_text_by_NID(subjName, WC_NID_emailAddress,
14439
                                                 emailBuf, emailLen);
14440
    if (emailLen < 0) {
14441
        XFREE(emailBuf, x->heap, DYNAMIC_TYPE_OPENSSL);
14442
        return WOLFSSL_FAILURE;
14443
    }
14444
14445
    if (chkLen == 0)
14446
        chkLen = XSTRLEN(chk);
14447
14448
    if (chkLen != (size_t)emailLen
14449
     || XSTRNCMP(chk, emailBuf, chkLen)) {
14450
        XFREE(emailBuf, x->heap, DYNAMIC_TYPE_OPENSSL);
14451
        return WOLFSSL_FAILURE;
14452
    }
14453
14454
    XFREE(emailBuf, x->heap, DYNAMIC_TYPE_OPENSSL);
14455
    return WOLFSSL_SUCCESS;
14456
}
14457
#endif /* OPENSSL_EXTRA && WOLFSSL_CERT_GEN */
14458
14459
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \
14460
    || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY)
14461
14462
int wolfSSL_X509_NAME_digest(const WOLFSSL_X509_NAME *name,
14463
        const WOLFSSL_EVP_MD *type, unsigned char *md, unsigned int *len)
14464
{
14465
    WOLFSSL_ENTER("wolfSSL_X509_NAME_digest");
14466
14467
    if (name == NULL || type == NULL)
14468
        return WOLFSSL_FAILURE;
14469
14470
#if !defined(NO_FILESYSTEM) && !defined(NO_PWDBASED)
14471
    return wolfSSL_EVP_Digest((unsigned char*)name->name,
14472
                              name->sz, md, len, type, NULL);
14473
#else
14474
    (void)md;
14475
    (void)len;
14476
    return NOT_COMPILED_IN;
14477
#endif
14478
}
14479
14480
#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY ||
14481
    OPENSSL_EXTRA || HAVE_LIGHTY */
14482
14483
#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
14484
    defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
14485
14486
void wolfSSL_X509_email_free(WOLF_STACK_OF(WOLFSSL_STRING) *sk)
14487
{
14488
    WOLFSSL_STACK *curr;
14489
14490
    while (sk != NULL) {
14491
        curr = sk;
14492
        sk = sk->next;
14493
14494
        XFREE(curr, NULL, DYNAMIC_TYPE_OPENSSL);
14495
    }
14496
}
14497
14498
WOLF_STACK_OF(WOLFSSL_STRING) *wolfSSL_X509_get1_ocsp(WOLFSSL_X509 *x)
14499
{
14500
    WOLFSSL_STACK* list = NULL;
14501
    char*          url;
14502
14503
    if (x == NULL || x->authInfoSz == 0)
14504
        return NULL;
14505
14506
    list = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK) + x->authInfoSz + 1,
14507
                                   NULL, DYNAMIC_TYPE_OPENSSL);
14508
    if (list == NULL)
14509
        return NULL;
14510
14511
    url = (char*)list;
14512
    url += sizeof(WOLFSSL_STACK);
14513
    XMEMCPY(url, x->authInfo, x->authInfoSz);
14514
    url[x->authInfoSz] = '\0';
14515
14516
    list->data.string = url;
14517
    list->next = NULL;
14518
    list->num = 1;
14519
14520
    return list;
14521
}
14522
14523
int wolfSSL_X509_check_issued(WOLFSSL_X509 *issuer, WOLFSSL_X509 *subject)
14524
{
14525
    WOLFSSL_X509_NAME *issuerName = wolfSSL_X509_get_issuer_name(subject);
14526
    WOLFSSL_X509_NAME *subjectName = wolfSSL_X509_get_subject_name(issuer);
14527
14528
    if (issuerName == NULL || subjectName == NULL)
14529
        return WOLFSSL_X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
14530
14531
    /* Literal matching of encoded names and key ids. */
14532
    if (issuerName->sz != subjectName->sz ||
14533
           XMEMCMP(issuerName->name, subjectName->name, subjectName->sz) != 0) {
14534
        return WOLFSSL_X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
14535
    }
14536
14537
    if (subject->authKeyId != NULL && issuer->subjKeyId != NULL) {
14538
        if (subject->authKeyIdSz != issuer->subjKeyIdSz ||
14539
                XMEMCMP(subject->authKeyId, issuer->subjKeyId,
14540
                        issuer->subjKeyIdSz) != 0) {
14541
            return WOLFSSL_X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
14542
        }
14543
    }
14544
14545
    return WOLFSSL_X509_V_OK;
14546
}
14547
14548
#endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */
14549
14550
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
14551
    defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
14552
WOLFSSL_X509* wolfSSL_X509_dup(WOLFSSL_X509 *x)
14553
{
14554
    WOLFSSL_ENTER("wolfSSL_X509_dup");
14555
14556
    if (x == NULL) {
14557
        WOLFSSL_MSG("Error: NULL input");
14558
        return NULL;
14559
    }
14560
14561
    if (x->derCert == NULL) {
14562
        WOLFSSL_MSG("Error: NULL derCert parameter");
14563
        return NULL;
14564
    }
14565
14566
    return wolfSSL_X509_d2i_ex(NULL, x->derCert->buffer, x->derCert->length,
14567
        x->heap);
14568
}
14569
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || KEEP_PEER_CERT || \
14570
          SESSION_CERTS */
14571
14572
#if defined(OPENSSL_EXTRA)
14573
int wolfSSL_X509_check_ca(WOLFSSL_X509 *x509)
14574
{
14575
    WOLFSSL_ENTER("wolfSSL_X509_check_ca");
14576
14577
    if (x509 == NULL)
14578
        return WOLFSSL_FAILURE;
14579
    if (x509->isCa)
14580
        return 1;
14581
    if (x509->extKeyUsageCrit)
14582
        return 4;
14583
14584
    return 0;
14585
}
14586
#endif /* OPENSSL_EXTRA */
14587
14588
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
14589
long wolfSSL_X509_get_version(const WOLFSSL_X509 *x509)
14590
{
14591
    int version = 0;
14592
14593
    WOLFSSL_ENTER("wolfSSL_X509_get_version");
14594
14595
    if (x509 == NULL) {
14596
        WOLFSSL_MSG("invalid parameter");
14597
        return 0L;
14598
    }
14599
    version = x509->version;
14600
    if (version != 0)
14601
        return (long)version - 1L;
14602
14603
    return 0L;
14604
}
14605
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
14606
14607
#if defined(OPENSSL_EXTRA)
14608
int wolfSSL_X509_get_signature_nid(const WOLFSSL_X509 *x)
14609
{
14610
    if (x == NULL)
14611
        return 0;
14612
14613
    return oid2nid((word32)x->sigOID, oidSigType);
14614
}
14615
#endif  /* OPENSSL_EXTRA */
14616
14617
#if defined(OPENSSL_EXTRA)
14618
WOLFSSL_STACK* wolfSSL_sk_X509_new(WOLF_SK_COMPARE_CB(WOLFSSL_X509, cb))
14619
{
14620
    (void)cb;
14621
    return wolfSSL_sk_X509_new_null();
14622
}
14623
14624
WOLFSSL_STACK* wolfSSL_sk_X509_new_null(void)
14625
{
14626
    WOLFSSL_STACK* s = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
14627
            DYNAMIC_TYPE_OPENSSL);
14628
    if (s != NULL) {
14629
        XMEMSET(s, 0, sizeof(*s));
14630
        s->type = STACK_TYPE_X509;
14631
    }
14632
14633
    return s;
14634
}
14635
#endif  /* OPENSSL_EXTRA */
14636
14637
#ifdef OPENSSL_ALL
14638
14639
WOLFSSL_STACK* wolfSSL_sk_X509_OBJECT_new(void)
14640
{
14641
    WOLFSSL_STACK* s = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
14642
            DYNAMIC_TYPE_OPENSSL);
14643
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_new");
14644
    if (s != NULL) {
14645
        XMEMSET(s, 0, sizeof(*s));
14646
        s->type = STACK_TYPE_X509_OBJ;
14647
    }
14648
    return s;
14649
}
14650
14651
void wolfSSL_sk_X509_OBJECT_free(WOLFSSL_STACK* s)
14652
{
14653
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_free");
14654
    wolfSSL_sk_free(s);
14655
}
14656
14657
void wolfSSL_sk_X509_OBJECT_pop_free(WOLFSSL_STACK* s,
14658
        void (*f) (WOLFSSL_X509_OBJECT*))
14659
{
14660
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_pop_free");
14661
    wolfSSL_sk_pop_free(s, (wolfSSL_sk_freefunc)f);
14662
}
14663
14664
int wolfSSL_sk_X509_OBJECT_push(WOLFSSL_STACK* sk, WOLFSSL_X509_OBJECT* obj)
14665
{
14666
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_push");
14667
14668
    if (sk == NULL || obj == NULL) {
14669
        return WOLFSSL_FAILURE;
14670
    }
14671
14672
    return wolfSSL_sk_push(sk, obj);
14673
}
14674
14675
#endif /* OPENSSL_ALL */
14676
14677
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
14678
/* unlike wolfSSL_X509_NAME_dup this does not malloc a duplicate, only deep
14679
 * copy. "to" is expected to be a fresh blank name, if not pointers could be
14680
 * lost */
14681
int wolfSSL_X509_NAME_copy(WOLFSSL_X509_NAME* from, WOLFSSL_X509_NAME* to)
14682
{
14683
    int i;
14684
14685
    WOLFSSL_ENTER("wolfSSL_X509_NAME_copy");
14686
14687
    if (from == NULL || to == NULL) {
14688
        WOLFSSL_MSG("NULL parameter");
14689
        return BAD_FUNC_ARG;
14690
    }
14691
14692
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY)
14693
    if (from->rawLen > 0) {
14694
        if (from->rawLen > ASN_NAME_MAX) {
14695
            WOLFSSL_MSG("Bad raw size");
14696
            return BAD_FUNC_ARG;
14697
        }
14698
        XMEMCPY(to->raw, from->raw, from->rawLen);
14699
        to->rawLen = from->rawLen;
14700
    }
14701
#endif
14702
14703
    if (from->dynamicName) {
14704
        to->name = (char*)XMALLOC(from->sz, to->heap, DYNAMIC_TYPE_SUBJECT_CN);
14705
        if (to->name == NULL)
14706
            return WOLFSSL_FAILURE;
14707
        to->dynamicName = 1;
14708
    }
14709
    XMEMCPY(to->name, from->name, from->sz);
14710
    to->sz = from->sz;
14711
14712
    for (i = 0; i < MAX_NAME_ENTRIES; i++) {
14713
        WOLFSSL_X509_NAME_ENTRY* ne = wolfSSL_X509_NAME_get_entry(from, i);
14714
        if (ne != NULL) {
14715
            if (wolfSSL_X509_NAME_add_entry(to, ne, i, 1) != WOLFSSL_SUCCESS) {
14716
                return WOLFSSL_FAILURE;
14717
            }
14718
        }
14719
    }
14720
    to->entrySz = from->entrySz;
14721
    return WOLFSSL_SUCCESS;
14722
}
14723
14724
14725
/* copies over information from "name" to the "cert" subject name
14726
 * returns WOLFSSL_SUCCESS on success */
14727
int wolfSSL_X509_set_subject_name(WOLFSSL_X509 *cert, WOLFSSL_X509_NAME *name)
14728
{
14729
    WOLFSSL_ENTER("wolfSSL_X509_set_subject_name");
14730
    if (cert == NULL || name == NULL)
14731
        return WOLFSSL_FAILURE;
14732
14733
    FreeX509Name(&cert->subject);
14734
    InitX509Name(&cert->subject, 0, cert->heap);
14735
14736
    if (wolfSSL_X509_NAME_copy(name, &cert->subject) != WOLFSSL_SUCCESS) {
14737
        FreeX509Name(&cert->subject);
14738
        return WOLFSSL_FAILURE;
14739
    }
14740
14741
    cert->subject.x509 = cert;
14742
    return WOLFSSL_SUCCESS;
14743
}
14744
14745
14746
/* copies over information from "name" to the "cert" issuer name
14747
 * returns WOLFSSL_SUCCESS on success */
14748
int wolfSSL_X509_set_issuer_name(WOLFSSL_X509 *cert, WOLFSSL_X509_NAME *name)
14749
{
14750
    WOLFSSL_ENTER("wolfSSL_X509_set_issuer_name");
14751
    if (cert == NULL || name == NULL)
14752
        return WOLFSSL_FAILURE;
14753
14754
    FreeX509Name(&cert->issuer);
14755
    InitX509Name(&cert->issuer, 0, cert->heap);
14756
14757
    if (wolfSSL_X509_NAME_copy(name, &cert->issuer) != WOLFSSL_SUCCESS) {
14758
        FreeX509Name(&cert->issuer);
14759
        return WOLFSSL_FAILURE;
14760
    }
14761
14762
    cert->issuer.x509 = cert;
14763
    cert->issuerSet = 1;
14764
14765
    return WOLFSSL_SUCCESS;
14766
}
14767
14768
14769
int wolfSSL_X509_set_notAfter(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME* t)
14770
{
14771
    if (x509 == NULL || t == NULL) {
14772
        return WOLFSSL_FAILURE;
14773
    }
14774
14775
    x509->notAfter.type = t->type;
14776
    x509->notAfter.length = t->length;
14777
14778
    XMEMCPY(x509->notAfter.data, t->data, CTC_DATE_SIZE);
14779
14780
    return WOLFSSL_SUCCESS;
14781
}
14782
14783
int wolfSSL_X509_set_notBefore(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME* t)
14784
{
14785
    if (x509 == NULL || t == NULL) {
14786
        return WOLFSSL_FAILURE;
14787
    }
14788
14789
    x509->notBefore.type = t->type;
14790
    x509->notBefore.length = t->length;
14791
14792
    XMEMCPY(x509->notBefore.data, t->data, CTC_DATE_SIZE);
14793
14794
    return WOLFSSL_SUCCESS;
14795
}
14796
14797
int wolfSSL_X509_set1_notAfter(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME *t)
14798
{
14799
    return wolfSSL_X509_set_notAfter(x509, t);
14800
}
14801
14802
int wolfSSL_X509_set1_notBefore(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME *t)
14803
{
14804
    return wolfSSL_X509_set_notBefore(x509, t);
14805
}
14806
14807
int wolfSSL_X509_set_serialNumber(WOLFSSL_X509* x509, WOLFSSL_ASN1_INTEGER* s)
14808
{
14809
    WOLFSSL_ENTER("wolfSSL_X509_set_serialNumber");
14810
    if (x509 == NULL || s == NULL || s->length >= EXTERNAL_SERIAL_SIZE)
14811
        return WOLFSSL_FAILURE;
14812
14813
    /* WOLFSSL_ASN1_INTEGER has type | size | data
14814
     * Sanity check that the data is actually in ASN format */
14815
    if (s->length < 3 && s->data[0] != ASN_INTEGER &&
14816
            s->data[1] != s->length - 2) {
14817
        return WOLFSSL_FAILURE;
14818
    }
14819
    XMEMCPY(x509->serial, s->data + 2, s->length - 2);
14820
    x509->serialSz = s->length - 2;
14821
    x509->serial[s->length] = 0;
14822
14823
    return WOLFSSL_SUCCESS;
14824
}
14825
14826
14827
int wolfSSL_X509_set_pubkey(WOLFSSL_X509 *cert, WOLFSSL_EVP_PKEY *pkey)
14828
{
14829
    byte* p = NULL;
14830
    int derSz = 0;
14831
    WOLFSSL_ENTER("wolfSSL_X509_set_pubkey");
14832
14833
    if (cert == NULL || pkey == NULL)
14834
        return WOLFSSL_FAILURE;
14835
14836
    /* Regenerate since pkey->pkey.ptr may contain private key */
14837
    switch (pkey->type) {
14838
#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(NO_RSA)
14839
    case WC_EVP_PKEY_RSA:
14840
        {
14841
            RsaKey* rsa;
14842
14843
            if (pkey->rsa == NULL || pkey->rsa->internal == NULL)
14844
                return WOLFSSL_FAILURE;
14845
14846
            rsa = (RsaKey*)pkey->rsa->internal;
14847
            derSz = wc_RsaPublicKeyDerSize(rsa, 1);
14848
            if (derSz <= 0)
14849
                return WOLFSSL_FAILURE;
14850
14851
            p = (byte*)XMALLOC(derSz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
14852
            if (p == NULL)
14853
                return WOLFSSL_FAILURE;
14854
14855
            if ((derSz = wc_RsaKeyToPublicDer(rsa, p, (word32)derSz)) <= 0) {
14856
                XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
14857
                return WOLFSSL_FAILURE;
14858
            }
14859
            cert->pubKeyOID = RSAk;
14860
        }
14861
        break;
14862
#endif /* (WOLFSSL_KEY_GEN || OPENSSL_EXTRA) && !NO_RSA */
14863
#if !defined(HAVE_SELFTEST) && (defined(WOLFSSL_KEY_GEN) || \
14864
        defined(WOLFSSL_CERT_GEN)) && !defined(NO_DSA)
14865
    case WC_EVP_PKEY_DSA:
14866
        {
14867
            DsaKey* dsa;
14868
14869
            if (pkey->dsa == NULL || pkey->dsa->internal == NULL)
14870
                return WOLFSSL_FAILURE;
14871
14872
            dsa = (DsaKey*)pkey->dsa->internal;
14873
            /* size of pub, priv, p, q, g + ASN.1 additional information */
14874
            derSz = 5 * mp_unsigned_bin_size(&dsa->g) + MAX_ALGO_SZ;
14875
            p = (byte*)XMALLOC(derSz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
14876
            if (p == NULL)
14877
                return WOLFSSL_FAILURE;
14878
14879
            if ((derSz = wc_DsaKeyToPublicDer(dsa, p, (word32)derSz)) <= 0) {
14880
                XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
14881
                return WOLFSSL_FAILURE;
14882
            }
14883
            cert->pubKeyOID = DSAk;
14884
        }
14885
        break;
14886
#endif /* !HAVE_SELFTEST && (WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN) && !NO_DSA */
14887
#ifdef HAVE_ECC
14888
    case WC_EVP_PKEY_EC:
14889
        {
14890
            ecc_key* ecc;
14891
14892
            if (pkey->ecc == NULL || pkey->ecc->internal == NULL)
14893
                return WOLFSSL_FAILURE;
14894
14895
            ecc = (ecc_key*)pkey->ecc->internal;
14896
            derSz = wc_EccPublicKeyDerSize(ecc, 1);
14897
            if (derSz <= 0)
14898
                return WOLFSSL_FAILURE;
14899
14900
            p = (byte*)XMALLOC(derSz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
14901
            if (p == NULL)
14902
                return WOLFSSL_FAILURE;
14903
14904
            if ((derSz = wc_EccPublicKeyToDer(ecc, p, (word32)derSz, 1)) <= 0) {
14905
                XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
14906
                return WOLFSSL_FAILURE;
14907
            }
14908
            cert->pubKeyOID = ECDSAk;
14909
        }
14910
        break;
14911
#endif
14912
    default:
14913
        return WOLFSSL_FAILURE;
14914
    }
14915
    XFREE(cert->pubKey.buffer, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
14916
    cert->pubKey.buffer = p;
14917
    cert->pubKey.length = (unsigned int)derSz;
14918
14919
    return WOLFSSL_SUCCESS;
14920
}
14921
14922
int wolfSSL_X509_set_version(WOLFSSL_X509* x509, long v)
14923
{
14924
    WOLFSSL_ENTER("wolfSSL_X509_set_version");
14925
    if ((x509 == NULL) || (v < 0) || (v >= INT_MAX)) {
14926
        return WOLFSSL_FAILURE;
14927
    }
14928
    x509->version = (int) v + 1;
14929
14930
    return WOLFSSL_SUCCESS;
14931
}
14932
14933
#endif /* (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) && WOLFSSL_CERT_GEN */
14934
14935
#if (defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)) &&           \
14936
    defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ)
14937
14938
void wolfSSL_X509V3_set_ctx(WOLFSSL_X509V3_CTX* ctx, WOLFSSL_X509* issuer,
14939
        WOLFSSL_X509* subject, WOLFSSL_X509* req, WOLFSSL_X509_CRL* crl,
14940
        int flag)
14941
{
14942
    int ret = WOLFSSL_SUCCESS;
14943
    WOLFSSL_ENTER("wolfSSL_X509V3_set_ctx");
14944
    if (!ctx) {
14945
        ret = WOLFSSL_FAILURE;
14946
        WOLFSSL_MSG("wolfSSL_X509V3_set_ctx() called with null ctx.");
14947
    }
14948
14949
    if (ret == WOLFSSL_SUCCESS && (ctx->x509 != NULL)) {
14950
        ret = WOLFSSL_FAILURE;
14951
        WOLFSSL_MSG("wolfSSL_X509V3_set_ctx() called "
14952
                    "with ctx->x509 already allocated.");
14953
    }
14954
14955
    if (ret == WOLFSSL_SUCCESS) {
14956
        ctx->x509 = wolfSSL_X509_new_ex(
14957
            (issuer && issuer->heap) ? issuer->heap :
14958
            (subject && subject->heap) ? subject->heap :
14959
            (req && req->heap) ? req->heap :
14960
            NULL);
14961
        if (!ctx->x509) {
14962
            ret = WOLFSSL_FAILURE;
14963
            WOLFSSL_MSG("wolfSSL_X509_new_ex() failed "
14964
                        "in wolfSSL_X509V3_set_ctx().");
14965
        }
14966
    }
14967
14968
    /* Set parameters in ctx as long as ret == WOLFSSL_SUCCESS */
14969
    if (ret == WOLFSSL_SUCCESS && issuer)
14970
        ret = wolfSSL_X509_set_issuer_name(ctx->x509, &issuer->issuer);
14971
14972
    if (ret == WOLFSSL_SUCCESS && subject)
14973
        ret = wolfSSL_X509_set_subject_name(ctx->x509, &subject->subject);
14974
14975
    if (ret == WOLFSSL_SUCCESS && req) {
14976
        WOLFSSL_MSG("req not implemented.");
14977
    }
14978
14979
    if (ret == WOLFSSL_SUCCESS && crl) {
14980
        WOLFSSL_MSG("crl not implemented.");
14981
    }
14982
14983
    if (ret == WOLFSSL_SUCCESS && flag) {
14984
        WOLFSSL_MSG("flag not implemented.");
14985
    }
14986
14987
    if (ret != WOLFSSL_SUCCESS) {
14988
        WOLFSSL_MSG("Error setting WOLFSSL_X509V3_CTX parameters.");
14989
    }
14990
}
14991
14992
#ifndef NO_BIO
14993
int wolfSSL_i2d_X509_REQ(WOLFSSL_X509* req, unsigned char** out)
14994
{
14995
    int derSz = 0;
14996
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
14997
    WOLFSSL_BIO* bio = NULL;
14998
    WOLFSSL_ENTER("wolfSSL_i2d_X509_REQ");
14999
15000
    if (req == NULL || out == NULL) {
15001
        return BAD_FUNC_ARG;
15002
    }
15003
15004
    if (!(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()))) {
15005
        return WOLFSSL_FAILURE;
15006
    }
15007
15008
    if (wolfSSL_i2d_X509_REQ_bio(bio, req) != WOLFSSL_SUCCESS) {
15009
        WOLFSSL_MSG("wolfSSL_i2d_X509_REQ_bio error");
15010
        goto cleanup;
15011
    }
15012
15013
    derSz = wolfSSL_BIO_get_len(bio);
15014
15015
    if (*out == NULL) {
15016
        *out = (unsigned char*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL);
15017
        if (!*out) {
15018
            WOLFSSL_MSG("malloc error");
15019
            ret = MEMORY_E;
15020
            goto cleanup;
15021
        }
15022
    }
15023
15024
    if (wolfSSL_BIO_read(bio, *out, derSz) != derSz) {
15025
        WOLFSSL_MSG("wolfSSL_BIO_read error");
15026
        goto cleanup;
15027
    }
15028
15029
    ret = derSz;
15030
cleanup:
15031
    wolfSSL_BIO_free(bio);
15032
15033
    return ret;
15034
}
15035
#endif /* !NO_BIO */
15036
15037
WOLFSSL_X509* wolfSSL_X509_REQ_new(void)
15038
{
15039
    return wolfSSL_X509_new();
15040
}
15041
15042
void wolfSSL_X509_REQ_free(WOLFSSL_X509* req)
15043
{
15044
    wolfSSL_X509_free(req);
15045
}
15046
15047
int wolfSSL_X509_REQ_set_version(WOLFSSL_X509 *x, long version)
15048
{
15049
    WOLFSSL_ENTER("wolfSSL_X509_REQ_set_version");
15050
    if ((x == NULL) || (version < 0) || (version >= INT_MAX)) {
15051
        return WOLFSSL_FAILURE;
15052
    }
15053
    x->version = (int)version;
15054
    return WOLFSSL_SUCCESS;
15055
}
15056
15057
long wolfSSL_X509_REQ_get_version(const WOLFSSL_X509 *req)
15058
{
15059
    WOLFSSL_ENTER("wolfSSL_X509_REQ_get_version");
15060
    if (req == NULL) {
15061
        return 0; /* invalid arg */
15062
    }
15063
    return (long)req->version;
15064
}
15065
15066
int wolfSSL_X509_REQ_sign(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey,
15067
                          const WOLFSSL_EVP_MD *md)
15068
{
15069
    int ret;
15070
#ifdef WOLFSSL_SMALL_STACK
15071
    byte* der = NULL;
15072
#else
15073
    byte der[2048];
15074
#endif
15075
    int derSz = 2048;
15076
15077
    if (req == NULL || pkey == NULL || md == NULL) {
15078
        WOLFSSL_LEAVE("wolfSSL_X509_REQ_sign", BAD_FUNC_ARG);
15079
        return WOLFSSL_FAILURE;
15080
    }
15081
15082
#ifdef WOLFSSL_SMALL_STACK
15083
    der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15084
    if (der == NULL) {
15085
        return WOLFSSL_FAILURE;
15086
    }
15087
#endif
15088
15089
    /* Create a Cert that has the certificate request fields. */
15090
    req->sigOID = wolfSSL_sigTypeFromPKEY((WOLFSSL_EVP_MD*)md, pkey);
15091
    ret = wolfssl_x509_make_der(req, 1, der, &derSz, 0);
15092
    if (ret != WOLFSSL_SUCCESS) {
15093
#ifdef WOLFSSL_SMALL_STACK
15094
        XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15095
#endif
15096
        WOLFSSL_MSG("Unable to make DER for X509");
15097
        WOLFSSL_LEAVE("wolfSSL_X509_REQ_sign", ret);
15098
        return WOLFSSL_FAILURE;
15099
    }
15100
15101
    if (wolfSSL_X509_resign_cert(req, 1, der, 2048, derSz,
15102
            (WOLFSSL_EVP_MD*)md, pkey) <= 0) {
15103
#ifdef WOLFSSL_SMALL_STACK
15104
        XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15105
#endif
15106
        return WOLFSSL_FAILURE;
15107
    }
15108
#ifdef WOLFSSL_SMALL_STACK
15109
    XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15110
#endif
15111
    return WOLFSSL_SUCCESS;
15112
}
15113
15114
int wolfSSL_X509_REQ_sign_ctx(WOLFSSL_X509 *req,
15115
                              WOLFSSL_EVP_MD_CTX* md_ctx)
15116
{
15117
    if (md_ctx && md_ctx->pctx)
15118
        return wolfSSL_X509_REQ_sign(req, md_ctx->pctx->pkey,
15119
                wolfSSL_EVP_MD_CTX_md(md_ctx));
15120
    else
15121
        return WOLFSSL_FAILURE;
15122
}
15123
15124
static int regenX509REQDerBuffer(WOLFSSL_X509* x509)
15125
{
15126
    int derSz = X509_BUFFER_SZ;
15127
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
15128
#ifndef WOLFSSL_SMALL_STACK
15129
    byte der[X509_BUFFER_SZ];
15130
#else
15131
    byte* der;
15132
15133
    der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15134
    if (!der) {
15135
        WOLFSSL_MSG("malloc failed");
15136
        return WOLFSSL_FAILURE;
15137
    }
15138
#endif
15139
15140
    if (wolfssl_x509_make_der(x509, 1, der, &derSz, 0) == WOLFSSL_SUCCESS) {
15141
        FreeDer(&x509->derCert);
15142
        if (AllocDer(&x509->derCert, (word32)derSz, CERT_TYPE,
15143
                                                             x509->heap) == 0) {
15144
            XMEMCPY(x509->derCert->buffer, der, derSz);
15145
            ret = WOLFSSL_SUCCESS;
15146
        }
15147
        else {
15148
            WOLFSSL_MSG("Failed to allocate DER buffer for X509");
15149
        }
15150
    }
15151
    else {
15152
        WOLFSSL_MSG("Unable to make DER for X509 REQ");
15153
    }
15154
#ifdef WOLFSSL_SMALL_STACK
15155
    XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
15156
#endif
15157
    return ret;
15158
}
15159
15160
int wolfSSL_X509_REQ_add_extensions(WOLFSSL_X509* req,
15161
        WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* ext_sk)
15162
{
15163
    WOLFSSL_X509_EXTENSION* ext = NULL;
15164
15165
    if (!req || !ext_sk) {
15166
        WOLFSSL_MSG("Bad parameter");
15167
        return WOLFSSL_FAILURE;
15168
    }
15169
15170
    /* It is not an error if the stack is empty. */
15171
    ext = ext_sk->data.ext;
15172
    if (ext == NULL) {
15173
        return WOLFSSL_SUCCESS;
15174
    }
15175
15176
    while (ext_sk) {
15177
        ext = ext_sk->data.ext;
15178
15179
        if (wolfSSL_X509_add_ext(req, ext, -1) != WOLFSSL_SUCCESS) {
15180
            WOLFSSL_MSG("wolfSSL_X509_add_ext error");
15181
            return WOLFSSL_FAILURE;
15182
        }
15183
15184
        ext_sk = ext_sk->next;
15185
    }
15186
15187
    return regenX509REQDerBuffer(req);
15188
}
15189
15190
int wolfSSL_X509_REQ_add1_attr_by_txt(WOLFSSL_X509 *req,
15191
                              const char *attrname, int type,
15192
                              const unsigned char *bytes, int len)
15193
{
15194
    WOLFSSL_ENTER("wolfSSL_X509_REQ_add1_attr_by_txt");
15195
15196
#ifdef HAVE_LIBEST
15197
    if (!req || !attrname || !bytes || type != MBSTRING_ASC) {
15198
        WOLFSSL_MSG("Bad parameter");
15199
        return WOLFSSL_FAILURE;
15200
    }
15201
15202
    if (len < 0) {
15203
        len = (int)XSTRLEN((char*)bytes);
15204
    }
15205
15206
    /* For now just pretend that we support this for libest testing */
15207
    if (len == XSTR_SIZEOF("1.3.6.1.1.1.1.22") &&
15208
            XMEMCMP("1.3.6.1.1.1.1.22", bytes, len) == 0) {
15209
        /* MAC Address */
15210
    }
15211
    else if (len == XSTR_SIZEOF("1.2.840.10045.2.1") &&
15212
            XMEMCMP("1.2.840.10045.2.1", bytes, len) == 0) {
15213
        /* ecPublicKey */
15214
    }
15215
    else if (len == XSTR_SIZEOF("1.2.840.10045.4.3.3") &&
15216
            XMEMCMP("1.2.840.10045.4.3.3", bytes, len) == 0) {
15217
        /* ecdsa-with-SHA384 */
15218
    }
15219
    else {
15220
        return WOLFSSL_FAILURE;
15221
    }
15222
15223
    /* return error if not built for libest */
15224
    return WOLFSSL_SUCCESS;
15225
#else
15226
    (void)req;
15227
    (void)attrname;
15228
    (void)type;
15229
    (void)bytes;
15230
    (void)len;
15231
    return WOLFSSL_FAILURE;
15232
#endif
15233
}
15234
15235
15236
static int wolfSSL_X509_ATTRIBUTE_set(WOLFSSL_X509_ATTRIBUTE* attr,
15237
        const char* data, int dataSz, int type, int nid)
15238
{
15239
    if (attr) {
15240
        attr->value->value.asn1_string = wolfSSL_ASN1_STRING_new();
15241
        if (wolfSSL_ASN1_STRING_set(attr->value->value.asn1_string,
15242
                data, dataSz) != WOLFSSL_SUCCESS) {
15243
            wolfSSL_ASN1_STRING_free(attr->value->value.asn1_string);
15244
            WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
15245
            return WOLFSSL_FAILURE;
15246
        }
15247
        attr->value->type = type;
15248
        attr->object->nid = nid;
15249
    }
15250
    else {
15251
        WOLFSSL_MSG("wolfSSL_X509_ATTRIBUTE_new error");
15252
        return WOLFSSL_FAILURE;
15253
    }
15254
15255
    return WOLFSSL_SUCCESS;
15256
}
15257
15258
15259
int wolfSSL_X509_REQ_add1_attr_by_NID(WOLFSSL_X509 *req,
15260
                                      int nid, int type,
15261
                                      const unsigned char *bytes,
15262
                                      int len)
15263
{
15264
    int ret;
15265
    WOLFSSL_X509_ATTRIBUTE* attr;
15266
15267
    WOLFSSL_ENTER("wolfSSL_X509_REQ_add1_attr_by_NID");
15268
15269
    if (!req || !bytes || type != WOLFSSL_MBSTRING_ASC) {
15270
        WOLFSSL_MSG("Bad parameter");
15271
        return WOLFSSL_FAILURE;
15272
    }
15273
15274
    switch (nid) {
15275
    case WC_NID_pkcs9_challengePassword:
15276
        if (len < 0)
15277
            len = (int)XSTRLEN((char*)bytes);
15278
        if (len < CTC_NAME_SIZE) {
15279
            XMEMCPY(req->challengePw, bytes, len);
15280
            req->challengePw[len] = '\0';
15281
        }
15282
        else {
15283
            WOLFSSL_MSG("Challenge password too long");
15284
            WOLFSSL_ERROR_VERBOSE(BUFFER_E);
15285
            return WOLFSSL_FAILURE;
15286
        }
15287
        break;
15288
    case WC_NID_serialNumber:
15289
        if (len < 0)
15290
            len = (int)XSTRLEN((char*)bytes);
15291
        if (len + 1 > EXTERNAL_SERIAL_SIZE) {
15292
            WOLFSSL_MSG("SerialNumber too long");
15293
            WOLFSSL_ERROR_VERBOSE(BUFFER_E);
15294
            return WOLFSSL_FAILURE;
15295
        }
15296
        XMEMCPY(req->serial, bytes, len);
15297
        req->serialSz = len;
15298
        break;
15299
15300
    case WC_NID_pkcs9_unstructuredName:
15301
    case WC_NID_pkcs9_contentType:
15302
    case WC_NID_surname:
15303
    case WC_NID_initials:
15304
    case WC_NID_givenName:
15305
    case WC_NID_dnQualifier:
15306
        break;
15307
15308
    default:
15309
        WOLFSSL_MSG("Unsupported attribute");
15310
        return WOLFSSL_FAILURE;
15311
    }
15312
15313
    attr = wolfSSL_X509_ATTRIBUTE_new();
15314
    ret = wolfSSL_X509_ATTRIBUTE_set(attr, (const char*)bytes, len,
15315
            WOLFSSL_V_ASN1_PRINTABLESTRING, nid);
15316
    if (ret != WOLFSSL_SUCCESS) {
15317
        wolfSSL_X509_ATTRIBUTE_free(attr);
15318
    }
15319
    else {
15320
        if (req->reqAttributes == NULL) {
15321
            req->reqAttributes = wolfSSL_sk_new_node(req->heap);
15322
            if (req->reqAttributes != NULL) {
15323
                req->reqAttributes->type = STACK_TYPE_X509_REQ_ATTR;
15324
            }
15325
        }
15326
        if ((req->reqAttributes != NULL) &&
15327
                (req->reqAttributes->type == STACK_TYPE_X509_REQ_ATTR)) {
15328
            /* Using wolfSSL_sk_insert to maintain backwards compatibility with
15329
             * earlier versions of _push API that pushed items to the start of
15330
             * the list instead of the end. */
15331
            ret = wolfSSL_sk_insert(req->reqAttributes, attr, 0) > 0
15332
                    ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
15333
        }
15334
        else {
15335
            ret = WOLFSSL_FAILURE;
15336
        }
15337
        if (ret != WOLFSSL_SUCCESS)
15338
            wolfSSL_X509_ATTRIBUTE_free(attr);
15339
    }
15340
15341
    return ret;
15342
}
15343
15344
WOLFSSL_X509 *wolfSSL_X509_to_X509_REQ(WOLFSSL_X509 *x,
15345
        WOLFSSL_EVP_PKEY *pkey, const WOLFSSL_EVP_MD *md)
15346
{
15347
    WOLFSSL_ENTER("wolfSSL_X509_to_X509_REQ");
15348
    (void)pkey;
15349
    (void)md;
15350
    return wolfSSL_X509_dup(x);
15351
}
15352
15353
int wolfSSL_X509_REQ_set_subject_name(WOLFSSL_X509 *req,
15354
                                      WOLFSSL_X509_NAME *name)
15355
{
15356
    return wolfSSL_X509_set_subject_name(req, name);
15357
}
15358
15359
int wolfSSL_X509_REQ_set_pubkey(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey)
15360
{
15361
    return wolfSSL_X509_set_pubkey(req, pkey);
15362
}
15363
#endif /* OPENSSL_ALL && WOLFSSL_CERT_GEN && WOLFSSL_CERT_REQ */
15364
15365
#if (defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)) && \
15366
    (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_REQ))
15367
15368
WOLFSSL_ASN1_TYPE *wolfSSL_X509_ATTRIBUTE_get0_type(
15369
        WOLFSSL_X509_ATTRIBUTE *attr, int idx)
15370
{
15371
    WOLFSSL_ENTER("wolfSSL_X509_ATTRIBUTE_get0_type");
15372
15373
    if (!attr || idx != 0) {
15374
        WOLFSSL_MSG("Bad parameter");
15375
        return NULL;
15376
    }
15377
15378
    return attr->value;
15379
}
15380
15381
15382
/**
15383
 * @param req X509_REQ containing attribute
15384
 * @return the number of attributes
15385
 */
15386
int wolfSSL_X509_REQ_get_attr_count(const WOLFSSL_X509 *req)
15387
{
15388
    if (req == NULL || req->reqAttributes == NULL)
15389
        return 0;
15390
15391
    return wolfSSL_sk_num(req->reqAttributes);
15392
}
15393
15394
15395
/**
15396
 * @param req X509_REQ containing attribute
15397
 * @param loc NID of the attribute to return
15398
 */
15399
WOLFSSL_X509_ATTRIBUTE *wolfSSL_X509_REQ_get_attr(
15400
        const WOLFSSL_X509 *req, int loc)
15401
{
15402
    WOLFSSL_ENTER("wolfSSL_X509_REQ_get_attr");
15403
15404
    if (!req || req->reqAttributes == NULL) {
15405
        WOLFSSL_MSG("Bad parameter");
15406
        return NULL;
15407
    }
15408
15409
    return (WOLFSSL_X509_ATTRIBUTE*)wolfSSL_sk_value(req->reqAttributes, loc);
15410
}
15411
15412
/* Return NID as the attr index */
15413
int wolfSSL_X509_REQ_get_attr_by_NID(const WOLFSSL_X509 *req,
15414
        int nid, int lastpos)
15415
{
15416
    int idx;
15417
15418
    WOLFSSL_ENTER("wolfSSL_X509_REQ_get_attr_by_NID");
15419
15420
    if (!req) {
15421
        WOLFSSL_MSG("Bad parameter");
15422
        return WOLFSSL_FATAL_ERROR;
15423
    }
15424
15425
    /* search through stack for first matching nid */
15426
    for (idx = lastpos + 1; idx < wolfSSL_sk_num(req->reqAttributes); idx++) {
15427
        WOLFSSL_X509_ATTRIBUTE* attr =
15428
             (WOLFSSL_X509_ATTRIBUTE*)wolfSSL_sk_value(req->reqAttributes, idx);
15429
        if (attr != NULL && attr->object != NULL && attr->object->nid == nid)
15430
            return idx;
15431
    }
15432
15433
    return WOLFSSL_FATAL_ERROR;
15434
}
15435
15436
WOLFSSL_X509_ATTRIBUTE* wolfSSL_X509_ATTRIBUTE_new(void)
15437
{
15438
    WOLFSSL_X509_ATTRIBUTE* ret;
15439
    WOLFSSL_ENTER("wolfSSL_X509_ATTRIBUTE_new");
15440
    ret = (WOLFSSL_X509_ATTRIBUTE*)XMALLOC(sizeof(WOLFSSL_X509_ATTRIBUTE),
15441
            NULL, DYNAMIC_TYPE_OPENSSL);
15442
    if (!ret) {
15443
        WOLFSSL_MSG("malloc error");
15444
        return NULL;
15445
    }
15446
    XMEMSET(ret, 0, sizeof(WOLFSSL_X509_ATTRIBUTE));
15447
    ret->object = wolfSSL_ASN1_OBJECT_new();
15448
    ret->value = wolfSSL_ASN1_TYPE_new();
15449
    /* Don't allocate ret->set since WOLFSSL_ASN1_TYPE
15450
     * is not supported as a stack type */
15451
    if (!ret->object || !ret->value) {
15452
        WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new or wolfSSL_ASN1_TYPE_new error");
15453
        wolfSSL_X509_ATTRIBUTE_free(ret);
15454
        return NULL;
15455
    }
15456
    return ret;
15457
}
15458
15459
void wolfSSL_X509_ATTRIBUTE_free(WOLFSSL_X509_ATTRIBUTE* attr)
15460
{
15461
    WOLFSSL_ENTER("wolfSSL_X509_ATTRIBUTE_free");
15462
    if (attr) {
15463
        if (attr->object) {
15464
            wolfSSL_ASN1_OBJECT_free(attr->object);
15465
        }
15466
        if (attr->value) {
15467
            wolfSSL_ASN1_TYPE_free(attr->value);
15468
        }
15469
        if (attr->set) {
15470
            wolfSSL_sk_pop_free(attr->set, NULL);
15471
        }
15472
        XFREE(attr, NULL, DYNAMIC_TYPE_OPENSSL);
15473
    }
15474
}
15475
#endif /* (OPENSSL_ALL || OPENSSL_EXTRA) &&
15476
          (WOLFSSL_CERT_GEN || WOLFSSL_CERT_REQ) */
15477
15478
#if defined(WOLFSSL_ACERT) && \
15479
   (defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA))
15480
15481
/* Allocate and return a new WOLFSSL_X509_ACERT struct pointer.
15482
 *
15483
 * @param [in]      heap        heap hint
15484
 *
15485
 * @return  pointer  on success
15486
 * @return  NULL     on error
15487
 * */
15488
WOLFSSL_X509_ACERT * wolfSSL_X509_ACERT_new_ex(void* heap)
15489
{
15490
    WOLFSSL_X509_ACERT * x509 = NULL;
15491
15492
    WOLFSSL_ENTER("wolfSSL_X509_ACERT_new");
15493
15494
    x509 = (WOLFSSL_X509_ACERT*) XMALLOC(sizeof(WOLFSSL_X509_ACERT), heap,
15495
                                         DYNAMIC_TYPE_X509_ACERT);
15496
15497
    if (x509 != NULL) {
15498
        wolfSSL_X509_ACERT_init(x509, 1, heap);
15499
    }
15500
15501
    return x509;
15502
}
15503
15504
WOLFSSL_X509_ACERT * wolfSSL_X509_ACERT_new(void)
15505
{
15506
    return wolfSSL_X509_ACERT_new_ex(NULL);
15507
}
15508
15509
/* Initialize a WOLFSSL_X509_ACERT struct.
15510
 *
15511
 * If dynamic == 1, then the x509 pointer will be freed
15512
 * in wolfSSL_X509_ACERT_free.
15513
 *
15514
 * @param [in]      x509        x509 acert pointer
15515
 * @param [in]      dynamic     dynamic mem flag
15516
 * @param [in]      heap        heap hint
15517
 *
15518
 * @return  void
15519
 * */
15520
void wolfSSL_X509_ACERT_init(WOLFSSL_X509_ACERT * x509, int dynamic, void* heap)
15521
{
15522
    WOLFSSL_ENTER("wolfSSL_X509_ACERT_init");
15523
15524
    if (x509 == NULL) {
15525
        WOLFSSL_MSG("error: InitX509Acert: null parameter");
15526
        return;
15527
    }
15528
15529
    XMEMSET(x509, 0, sizeof(*x509));
15530
15531
    x509->heap = heap;
15532
    x509->dynamic = dynamic;
15533
}
15534
15535
/* Free a WOLFSSL_X509_ACERT struct and its sub-fields.
15536
 *
15537
 * If this ACERT was initialized with dynamic == 1, then
15538
 * the x509 pointer itself will be freed as well.
15539
 *
15540
 * @param [in]      x509        x509 acert pointer
15541
 *
15542
 * @return  void
15543
 * */
15544
void wolfSSL_X509_ACERT_free(WOLFSSL_X509_ACERT * x509)
15545
{
15546
    int    dynamic = 0;
15547
    void * heap = NULL;
15548
15549
    WOLFSSL_ENTER("wolfSSL_X509_ACERT_free");
15550
15551
    if (x509 == NULL) {
15552
        WOLFSSL_MSG("error: wolfSSL_X509_ACERT_free: null parameter");
15553
        return;
15554
    }
15555
15556
    dynamic = x509->dynamic;
15557
    heap = x509->heap;
15558
15559
    /* Free holder and att cert issuer structures. */
15560
    if (x509->holderIssuerName) {
15561
        FreeAltNames(x509->holderIssuerName, heap);
15562
        x509->holderIssuerName = NULL;
15563
    }
15564
15565
    if (x509->holderEntityName) {
15566
        FreeAltNames(x509->holderEntityName, heap);
15567
        x509->holderEntityName = NULL;
15568
    }
15569
15570
    if (x509->AttCertIssuerName) {
15571
        FreeAltNames(x509->AttCertIssuerName, heap);
15572
        x509->AttCertIssuerName = NULL;
15573
    }
15574
15575
    if (x509->rawAttr != NULL) {
15576
        XFREE(x509->rawAttr, heap, DYNAMIC_TYPE_X509_EXT);
15577
        x509->rawAttr = NULL;
15578
        x509->rawAttrLen = 0;
15579
    }
15580
15581
    /* Free derCert source and signature buffer. */
15582
    FreeDer(&x509->derCert);
15583
15584
    if (x509->sig.buffer != NULL) {
15585
        XFREE(x509->sig.buffer, heap, DYNAMIC_TYPE_SIGNATURE);
15586
        x509->sig.buffer = NULL;
15587
    }
15588
15589
    /* Finally memset and free x509 acert structure. */
15590
    XMEMSET(x509, 0, sizeof(*x509));
15591
15592
    if (dynamic == 1) {
15593
        XFREE(x509, heap, DYNAMIC_TYPE_X509_ACERT);
15594
    }
15595
15596
    return;
15597
}
15598
15599
#if defined(OPENSSL_EXTRA)
15600
long wolfSSL_X509_ACERT_get_version(const WOLFSSL_X509_ACERT* x509)
15601
{
15602
    int version = 0;
15603
15604
    if (x509 == NULL) {
15605
        return 0L;
15606
    }
15607
15608
    version = x509->version;
15609
15610
    return version != 0 ? (long)version - 1L : 0L;
15611
}
15612
#endif /* OPENSSL_EXTRA */
15613
15614
int wolfSSL_X509_ACERT_version(WOLFSSL_X509_ACERT* x509)
15615
{
15616
    if (x509 == NULL) {
15617
        return 0;
15618
    }
15619
15620
    return x509->version;
15621
}
15622
15623
/* Retrieve the serial number from an ACERT.
15624
 *
15625
 * @param [in]       x509    the x509 attribute certificate
15626
 * @param [in, out]  buf     the serial number buffer pointer
15627
 * @param [in, out]  bufSz   the serial number buffer size pointer
15628
 *
15629
 * buf may be null, but bufSz is required. On success, sets
15630
 * bufSz pointer to signature length, and copies signature
15631
 * to buf if provided.
15632
 *
15633
 * Returns  WWOLFSSL_FATAL_ERROR if bufSz is null or too small.
15634
 * Returns  WOLFSSL_SUCCESS on success.
15635
 */
15636
int wolfSSL_X509_ACERT_get_serial_number(WOLFSSL_X509_ACERT* x509,
15637
                                         byte* buf, int* bufSz)
15638
{
15639
    WOLFSSL_ENTER("wolfSSL_X509_ACERT_get_serial_number");
15640
15641
    if (x509 == NULL || bufSz == NULL) {
15642
        WOLFSSL_MSG("error: null argument passed in");
15643
        return BAD_FUNC_ARG;
15644
    }
15645
15646
    if (buf != NULL) {
15647
        if (*bufSz < x509->serialSz) {
15648
            WOLFSSL_MSG("error: serial buffer too small");
15649
            return BUFFER_E;
15650
        }
15651
15652
        XMEMCPY(buf, x509->serial, x509->serialSz);
15653
    }
15654
15655
    *bufSz = x509->serialSz;
15656
15657
    return WOLFSSL_SUCCESS;
15658
}
15659
15660
/* Sets buf pointer and len to raw Attribute buffer and buffer len
15661
 * in X509 struct.
15662
 *
15663
 * Returns WOLFSSL_SUCCESS on success.
15664
 * Returns BAD_FUNC_ARG if input pointers are null.
15665
 * */
15666
WOLFSSL_API int wolfSSL_X509_ACERT_get_attr_buf(const WOLFSSL_X509_ACERT* x509,
15667
                                                const byte ** rawAttr,
15668
                                                word32 * rawAttrLen)
15669
{
15670
    if (x509 == NULL || rawAttr == NULL || rawAttrLen == NULL) {
15671
        return BAD_FUNC_ARG;
15672
    }
15673
15674
    *rawAttr = x509->rawAttr;
15675
    *rawAttrLen = x509->rawAttrLen;
15676
15677
    return WOLFSSL_SUCCESS;
15678
}
15679
15680
#ifndef NO_WOLFSSL_STUB
15681
WOLFSSL_API int wolfSSL_X509_ACERT_sign(WOLFSSL_X509_ACERT * x509,
15682
                                        WOLFSSL_EVP_PKEY * pkey,
15683
                                        const WOLFSSL_EVP_MD * md)
15684
{
15685
    WOLFSSL_STUB("X509_ACERT_sign");
15686
    (void) x509;
15687
    (void) pkey;
15688
    (void) md;
15689
    return WOLFSSL_NOT_IMPLEMENTED;
15690
}
15691
#endif /* NO_WOLFSSL_STUB */
15692
15693
/* Helper function for ACERT_verify.
15694
 *
15695
 * @param [in]       x509    the x509 attribute certificate
15696
 * @param [in, out]  outSz   the x509 der length
15697
 *
15698
 * @return  der buffer on success
15699
 * @return  NULL on error
15700
 * */
15701
static const byte* acert_get_der(WOLFSSL_X509_ACERT * x509, int* outSz)
15702
{
15703
    if (x509 == NULL || x509->derCert == NULL || outSz == NULL) {
15704
        return NULL;
15705
    }
15706
15707
    *outSz = (int)x509->derCert->length;
15708
    return x509->derCert->buffer;
15709
}
15710
15711
/* Given an X509_ACERT and EVP_PKEY, verify the acert's signature.
15712
 *
15713
 * @param [in]    x509    the x509 attribute certificate
15714
 * @param [in]    pkey    the evp_pkey
15715
 *
15716
 * @return  WOLFSSL_SUCCESS on verify success
15717
 * @return  < 0 on error
15718
 * */
15719
int wolfSSL_X509_ACERT_verify(WOLFSSL_X509_ACERT* x509, WOLFSSL_EVP_PKEY* pkey)
15720
{
15721
    int          ret = 0;
15722
    const byte * der = NULL;
15723
    int          derSz = 0;
15724
    int          pkey_type;
15725
15726
    if (x509 == NULL || pkey == NULL) {
15727
        WOLFSSL_MSG("error: wolfSSL_X509_ACERT_verify: bad arg");
15728
        return WOLFSSL_FATAL_ERROR;
15729
    }
15730
15731
    WOLFSSL_ENTER("wolfSSL_X509_ACERT_verify");
15732
15733
    der = acert_get_der(x509, &derSz);
15734
15735
    if (der == NULL || derSz <= 0) {
15736
        WOLFSSL_MSG("error: wolfSSL_X509_ACERT_verify: get der failed");
15737
        return WOLFSSL_FATAL_ERROR;
15738
    }
15739
15740
    switch (pkey->type) {
15741
    case WC_EVP_PKEY_RSA:
15742
        pkey_type = RSAk;
15743
        break;
15744
15745
    case WC_EVP_PKEY_EC:
15746
        pkey_type = ECDSAk;
15747
        break;
15748
15749
    case WC_EVP_PKEY_DSA:
15750
        pkey_type = DSAk;
15751
        break;
15752
15753
    default:
15754
        WOLFSSL_MSG("error: wolfSSL_X509_ACERT_verify: unknown pkey type");
15755
        return WOLFSSL_FATAL_ERROR;
15756
    }
15757
15758
15759
    ret = VerifyX509Acert(der, (word32)derSz,
15760
                          (const byte *)pkey->pkey.ptr, pkey->pkey_sz,
15761
                          pkey_type, x509->heap);
15762
15763
    return ret == 0 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
15764
}
15765
15766
/* Loads an x509 attribute certificate from buffer, and returns
15767
 * pointer to new WOLFSSL_X509_ACERT struct on success.
15768
 *
15769
 * @param [in]  buf    The acert buffer to load.
15770
 * @param [in]  sz     The size of the buffer.
15771
 * @param [in]  format The format of the buffer data.
15772
 * @param [in]  heap   Dynamic memory allocation hint.
15773
 *
15774
 * @return  pointer to WOLFSSL_X509_ACERT on success.
15775
 * @return  NULL on error.
15776
 * */
15777
WOLFSSL_X509_ACERT * wolfSSL_X509_ACERT_load_certificate_buffer_ex(
15778
    const unsigned char* buf, int sz, int format, void * heap)
15779
{
15780
    int                  ret = 0;
15781
    WOLFSSL_X509_ACERT * x509 = NULL;
15782
    DerBuffer *          der = NULL;
15783
    #ifdef WOLFSSL_SMALL_STACK
15784
    DecodedAcert *       acert = NULL;
15785
    #else
15786
    DecodedAcert         acert[1];
15787
    #endif
15788
15789
    WOLFSSL_ENTER("wolfSSL_X509_ACERT_load_certificate_buffer");
15790
15791
    if (format == WOLFSSL_FILETYPE_PEM) {
15792
    #ifdef WOLFSSL_PEM_TO_DER
15793
        ret = PemToDer(buf, sz, ACERT_TYPE, &der, heap, NULL, NULL);
15794
15795
        if (ret != 0 || der == NULL || der->buffer == NULL) {
15796
            WOLFSSL_ERROR(ret);
15797
15798
            if (der != NULL) {
15799
                FreeDer(&der);
15800
            }
15801
15802
            return NULL;
15803
        }
15804
    #else
15805
        WOLFSSL_ERROR(NOT_COMPILED_IN);
15806
        return NULL;
15807
    #endif
15808
    }
15809
    else {
15810
        ret = AllocDer(&der, (word32)sz, ACERT_TYPE, heap);
15811
15812
        if (ret != 0 || der == NULL || der->buffer == NULL) {
15813
            WOLFSSL_ERROR(ret);
15814
            return NULL;
15815
        }
15816
15817
        XMEMCPY(der->buffer, buf, sz);
15818
    }
15819
15820
    #ifdef WOLFSSL_SMALL_STACK
15821
    acert = (DecodedAcert*)XMALLOC(sizeof(DecodedAcert), heap,
15822
                                   DYNAMIC_TYPE_DCERT);
15823
    if (acert == NULL) {
15824
        WOLFSSL_ERROR(MEMORY_ERROR);
15825
        FreeDer(&der);
15826
        return NULL;
15827
    }
15828
    #endif
15829
15830
    InitDecodedAcert(acert, der->buffer, der->length, heap);
15831
15832
    ret = ParseX509Acert(acert, VERIFY_SKIP_DATE);
15833
15834
    if (ret == 0) {
15835
        x509 = wolfSSL_X509_ACERT_new_ex(heap);
15836
15837
        if (x509 != NULL) {
15838
            ret = CopyDecodedAcertToX509(x509, acert);
15839
15840
            if (ret != 0) {
15841
                wolfSSL_X509_ACERT_free(x509);
15842
                x509 = NULL;
15843
            }
15844
        }
15845
        else {
15846
            ret = MEMORY_ERROR;
15847
        }
15848
    }
15849
15850
    FreeDecodedAcert(acert);
15851
15852
    #ifdef WOLFSSL_SMALL_STACK
15853
    XFREE(acert, heap, DYNAMIC_TYPE_DCERT);
15854
    #endif
15855
15856
    FreeDer(&der);
15857
15858
    if (ret != 0) {
15859
        WOLFSSL_ERROR(ret);
15860
    }
15861
15862
    return x509;
15863
}
15864
15865
WOLFSSL_X509_ACERT * wolfSSL_X509_ACERT_load_certificate_buffer(
15866
    const unsigned char* buf, int sz, int format)
15867
{
15868
    return wolfSSL_X509_ACERT_load_certificate_buffer_ex(buf, sz, format, NULL);
15869
}
15870
15871
/* Retrieve the signature from an ACERT.
15872
 *
15873
 * @param [in]       x509    the x509 attribute certificate
15874
 * @param [in, out]  buf     the signature buffer pointer
15875
 * @param [in, out]  bufSz   the signature buffer size pointer
15876
 *
15877
 * buf may be null, but bufSz is required. On success, sets
15878
 * bufSz pointer to signature length, and copies signature
15879
 * to buf if provided.
15880
 *
15881
 * Returns  WWOLFSSL_FATAL_ERROR if bufSz is null or too small.
15882
 * Returns  WOLFSSL_SUCCESS on success.
15883
 */
15884
int wolfSSL_X509_ACERT_get_signature(WOLFSSL_X509_ACERT* x509,
15885
                                     unsigned char* buf, int* bufSz)
15886
{
15887
    WOLFSSL_ENTER("wolfSSL_X509_ACERT_get_signature");
15888
15889
    if (x509 == NULL || bufSz == NULL) {
15890
        return WOLFSSL_FATAL_ERROR;
15891
    }
15892
15893
    /* If buf array is provided, it must be long enough. */
15894
    if (buf != NULL && *bufSz < (int)x509->sig.length) {
15895
        return WOLFSSL_FATAL_ERROR;
15896
    }
15897
15898
    if (buf != NULL) {
15899
        /* Copy in buffer if provided. */
15900
        XMEMCPY(buf, x509->sig.buffer, x509->sig.length);
15901
    }
15902
15903
    *bufSz = (int)x509->sig.length;
15904
15905
    return WOLFSSL_SUCCESS;
15906
}
15907
#endif /* WOLFSSL_ACERT && (OPENSSL_EXTRA_X509_SMALL || OPENSSL_EXTRA) */
15908
15909
#endif /* !NO_CERTS */
15910
15911
#endif /* !WOLFCRYPT_ONLY */
15912
15913
#endif /* WOLFSSL_X509_INCLUDED */