Coverage Report

Created: 2024-06-28 06:19

/src/wolfssl/src/x509.c
Line
Count
Source (jump to first uncovered line)
1
/* x509.c
2
 *
3
 * Copyright (C) 2006-2023 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 2 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
23
#ifdef HAVE_CONFIG_H
24
    #include <config.h>
25
#endif
26
27
#include <wolfssl/wolfcrypt/settings.h>
28
29
#if !defined(WOLFSSL_X509_INCLUDED)
30
    #ifndef WOLFSSL_IGNORE_FILE_WARN
31
        #warning x509.c does not need to be compiled separately from ssl.c
32
    #endif
33
#else
34
35
#ifndef WOLFCRYPT_ONLY
36
37
#ifndef NO_CERTS
38
39
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
40
    #include <wolfssl/openssl/x509v3.h>
41
#endif
42
43
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
44
unsigned int wolfSSL_X509_get_extension_flags(WOLFSSL_X509* x509)
45
{
46
    unsigned int flags = 0;
47
48
    WOLFSSL_ENTER("wolfSSL_X509_get_extension_flags");
49
50
    if (x509 != NULL) {
51
        if (x509->keyUsageSet) {
52
            flags |= EXFLAG_KUSAGE;
53
        }
54
        if (x509->extKeyUsageSrc != NULL) {
55
            flags |= EXFLAG_XKUSAGE;
56
        }
57
    }
58
59
    WOLFSSL_LEAVE("wolfSSL_X509_get_extension_flags", flags);
60
61
    return flags;
62
}
63
64
unsigned int wolfSSL_X509_get_key_usage(WOLFSSL_X509* x509)
65
{
66
    unsigned int ret = 0;
67
68
    WOLFSSL_ENTER("wolfSSL_X509_get_key_usage");
69
70
    if (x509 == NULL) {
71
        WOLFSSL_MSG("x509 is NULL");
72
    }
73
    else {
74
        if (x509->keyUsageSet) {
75
            ret = wolfSSL_X509_get_keyUsage(x509);
76
        }
77
        else {
78
            ret = (unsigned int)-1;
79
        }
80
    }
81
82
    WOLFSSL_LEAVE("wolfSSL_X509_get_key_usage", ret);
83
84
    return ret;
85
}
86
87
unsigned int wolfSSL_X509_get_extended_key_usage(WOLFSSL_X509* x509)
88
{
89
    int ret = 0;
90
91
    WOLFSSL_ENTER("wolfSSL_X509_get_extended_key_usage");
92
93
    if (x509 != NULL) {
94
        if (x509->extKeyUsage & EXTKEYUSE_OCSP_SIGN)
95
            ret |= XKU_OCSP_SIGN;
96
        if (x509->extKeyUsage & EXTKEYUSE_TIMESTAMP)
97
            ret |= XKU_TIMESTAMP;
98
        if (x509->extKeyUsage & EXTKEYUSE_EMAILPROT)
99
            ret |= XKU_SMIME;
100
        if (x509->extKeyUsage & EXTKEYUSE_CODESIGN)
101
            ret |= XKU_CODE_SIGN;
102
        if (x509->extKeyUsage & EXTKEYUSE_CLIENT_AUTH)
103
            ret |= XKU_SSL_CLIENT;
104
        if (x509->extKeyUsage & EXTKEYUSE_SERVER_AUTH)
105
            ret |= XKU_SSL_SERVER;
106
        if (x509->extKeyUsage & EXTKEYUSE_ANY)
107
            ret |= XKU_ANYEKU;
108
    }
109
110
    WOLFSSL_LEAVE("wolfSSL_X509_get_extended_key_usage", ret);
111
112
    return (unsigned int)ret;
113
}
114
115
/* Returns the number of X509V3 extensions in X509 object, or 0 on failure */
116
int wolfSSL_X509_get_ext_count(const WOLFSSL_X509* passedCert)
117
{
118
    int extCount = 0;
119
    int length = 0;
120
    int outSz = 0;
121
    const byte* rawCert;
122
    int sz = 0;
123
    word32 idx = 0;
124
    const byte* input;
125
#ifdef WOLFSSL_SMALL_STACK
126
    DecodedCert *cert;
127
#else
128
    DecodedCert cert[1];
129
#endif
130
131
    WOLFSSL_ENTER("wolfSSL_X509_get_ext_count");
132
    if (passedCert == NULL) {
133
        WOLFSSL_MSG("\tNot passed a certificate");
134
        return WOLFSSL_FAILURE;
135
    }
136
137
    rawCert = wolfSSL_X509_get_der((WOLFSSL_X509*)passedCert, &outSz);
138
    if (rawCert == NULL) {
139
        WOLFSSL_MSG("\tpassedCert has no internal DerBuffer set.");
140
        return WOLFSSL_FAILURE;
141
    }
142
143
#ifdef WOLFSSL_SMALL_STACK
144
    cert = (DecodedCert *)XMALLOC(sizeof(*cert), NULL, DYNAMIC_TYPE_DCERT);
145
    if (cert == NULL) {
146
        WOLFSSL_MSG("out of memory");
147
        return WOLFSSL_FAILURE;
148
    }
149
#endif
150
151
    InitDecodedCert(cert, rawCert, (word32)outSz, 0);
152
153
    if (ParseCert(cert,
154
#ifdef WOLFSSL_CERT_REQ
155
            passedCert->isCSR ? CERTREQ_TYPE :
156
#endif
157
                    CA_TYPE,
158
            NO_VERIFY, NULL) < 0) {
159
        WOLFSSL_MSG("\tCertificate parsing failed");
160
        goto out;
161
    }
162
163
    input = cert->extensions;
164
    sz = cert->extensionsSz;
165
166
    if (input == NULL || sz == 0) {
167
        WOLFSSL_MSG("\tsz or input NULL error");
168
        goto out;
169
    }
170
171
#ifdef WOLFSSL_CERT_REQ
172
    if (!passedCert->isCSR)
173
#endif
174
    {
175
        if (input[idx++] != ASN_EXTENSIONS) {
176
            WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
177
            goto out;
178
        }
179
180
        if (GetLength(input, &idx, &length, sz) < 0) {
181
            WOLFSSL_MSG("\tfail: invalid length");
182
            goto out;
183
        }
184
    }
185
186
    if (GetSequence(input, &idx, &length, sz) < 0) {
187
        WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
188
        goto out;
189
    }
190
191
    while (idx < (word32)sz) {
192
        if (GetSequence(input, &idx, &length, sz) < 0) {
193
            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
194
            FreeDecodedCert(cert);
195
            return WOLFSSL_FAILURE;
196
        }
197
        idx += length;
198
        extCount++;
199
    }
200
201
out:
202
203
    FreeDecodedCert(cert);
204
#ifdef WOLFSSL_SMALL_STACK
205
    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
206
#endif
207
    return extCount;
208
}
209
210
/* Creates and returns pointer to a new X509_EXTENSION object in memory */
211
WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_new(void)
212
{
213
    WOLFSSL_X509_EXTENSION* newExt;
214
215
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_new");
216
217
    newExt = (WOLFSSL_X509_EXTENSION*)XMALLOC(sizeof(WOLFSSL_X509_EXTENSION),
218
              NULL, DYNAMIC_TYPE_X509_EXT);
219
    if (newExt == NULL)
220
        return NULL;
221
    XMEMSET(newExt, 0, sizeof(WOLFSSL_X509_EXTENSION));
222
223
    return newExt;
224
}
225
226
227
/* Clear out and free internal pointers of ASN.1 STRING object.
228
 *
229
 * @param [in] asn1  ASN.1 STRING object.
230
 */
231
static void wolfSSL_ASN1_STRING_clear(WOLFSSL_ASN1_STRING* asn1)
232
{
233
    /* Check we have an object to free. */
234
    if (asn1 != NULL) {
235
        /* Dispose of dynamic data. */
236
        if ((asn1->length > 0) && asn1->isDynamic) {
237
            XFREE(asn1->data, NULL, DYNAMIC_TYPE_OPENSSL);
238
        }
239
        XMEMSET(asn1, 0, sizeof(WOLFSSL_ASN1_STRING));
240
    }
241
}
242
243
244
void wolfSSL_X509_EXTENSION_free(WOLFSSL_X509_EXTENSION* x)
245
{
246
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_free");
247
    if (x == NULL)
248
        return;
249
250
    if (x->obj != NULL) {
251
        wolfSSL_ASN1_OBJECT_free(x->obj);
252
    }
253
254
    wolfSSL_ASN1_STRING_clear(&x->value);
255
    wolfSSL_sk_pop_free(x->ext_sk, NULL);
256
257
    XFREE(x, NULL, DYNAMIC_TYPE_X509_EXT);
258
}
259
260
WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_dup(WOLFSSL_X509_EXTENSION* src)
261
{
262
    WOLFSSL_X509_EXTENSION* ret = NULL;
263
    int err = 0;
264
265
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_dup");
266
267
    if (src == NULL) {
268
        err = 1;
269
    }
270
271
    if (err == 0) {
272
        ret = wolfSSL_X509_EXTENSION_new();
273
        if (ret == NULL) {
274
            err = 1;
275
        }
276
    }
277
    if (err == 0 && src->obj != NULL) {
278
        ret->obj = wolfSSL_ASN1_OBJECT_dup(src->obj);
279
        if (ret->obj == NULL) {
280
            err = 1;
281
        }
282
    }
283
    if (err == 0) {
284
        ret->crit = src->crit;
285
        if (wolfSSL_ASN1_STRING_copy(&ret->value, &src->value) !=
286
                WOLFSSL_SUCCESS) {
287
            err = 1;
288
        }
289
    }
290
291
    if (err == 1 && ret != NULL) {
292
        wolfSSL_X509_EXTENSION_free(ret);
293
        ret = NULL;
294
    }
295
296
    return ret;
297
}
298
299
WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_create_by_OBJ(
300
    WOLFSSL_X509_EXTENSION* ex, WOLFSSL_ASN1_OBJECT *obj, int crit,
301
    WOLFSSL_ASN1_STRING *data)
302
{
303
    int err = 0;
304
    WOLFSSL_X509_EXTENSION *ret = ex;
305
306
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_create_by_OBJ");
307
308
    if ((obj == NULL) || (data == NULL)) {
309
       return NULL;
310
    }
311
312
    if (ret == NULL) {
313
        ret = wolfSSL_X509_EXTENSION_new();
314
        if (ret == NULL) {
315
            err = 1;
316
        }
317
    } else {
318
        /* Prevent potential memory leaks and dangling pointers. */
319
        wolfSSL_ASN1_OBJECT_free(ret->obj);
320
        ret->obj = NULL;
321
        wolfSSL_ASN1_STRING_clear(&ret->value);
322
    }
323
324
    if (err == 0) {
325
        ret->crit = crit;
326
        ret->obj = wolfSSL_ASN1_OBJECT_dup(obj);
327
        if (ret->obj == NULL) {
328
            err = 1;
329
        }
330
    }
331
332
    if (err == 0) {
333
        if (wolfSSL_ASN1_STRING_copy(&ret->value, data) != WOLFSSL_SUCCESS) {
334
            err = 1;
335
        }
336
    }
337
338
    if (err == 1) {
339
        if (ret != ex) {
340
            wolfSSL_X509_EXTENSION_free(ret);
341
        }
342
        ret = NULL;
343
    }
344
    return ret;
345
}
346
347
/* Creates and returns a new WOLFSSL_X509_EXTENSION stack. */
348
WOLFSSL_STACK* wolfSSL_sk_new_x509_ext(void)
349
{
350
    WOLFSSL_STACK* sk;
351
    WOLFSSL_ENTER("wolfSSL_sk_new_x509_ext");
352
353
    sk = wolfSSL_sk_new_null();
354
    if (sk) {
355
        sk->type = STACK_TYPE_X509_EXT;
356
    }
357
    return sk;
358
}
359
360
/* This function does NOT return 1 on success. It returns 0 on fail, and the
361
 * number of items in the stack upon success. This is for compatibility with
362
 * OpenSSL. */
363
int wolfSSL_sk_X509_EXTENSION_push(WOLFSSL_STACK* sk,WOLFSSL_X509_EXTENSION* ext)
364
{
365
    WOLFSSL_STACK* node;
366
367
    WOLFSSL_ENTER("wolfSSL_sk_X509_EXTENSION_push");
368
369
    if (sk == NULL || ext == NULL) {
370
        return WOLFSSL_FAILURE;
371
    }
372
373
    /* no previous values in stack */
374
    if (sk->data.ext == NULL) {
375
        sk->data.ext = ext;
376
        sk->num += 1;
377
        return (int)sk->num;
378
    }
379
380
    /* stack already has value(s) create a new node and add more */
381
    node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
382
                                                             DYNAMIC_TYPE_X509);
383
    if (node == NULL) {
384
        WOLFSSL_MSG("Memory error");
385
        return WOLFSSL_FAILURE;
386
    }
387
    XMEMSET(node, 0, sizeof(WOLFSSL_STACK));
388
389
    /* push new obj onto head of stack */
390
    node->data.ext  = sk->data.ext;
391
    node->next      = sk->next;
392
    node->type      = sk->type;
393
    sk->next        = node;
394
    sk->data.ext    = ext;
395
    sk->num        += 1;
396
397
    return (int)sk->num;
398
}
399
400
/* Free the structure for X509_EXTENSION stack
401
 *
402
 * sk  stack to free nodes in
403
 */
404
void wolfSSL_sk_X509_EXTENSION_free(WOLFSSL_STACK* sk)
405
{
406
    WOLFSSL_STACK* node;
407
408
    WOLFSSL_ENTER("wolfSSL_sk_X509_EXTENSION_free");
409
410
    if (sk == NULL) {
411
        return;
412
    }
413
414
    /* parse through stack freeing each node */
415
    node = sk->next;
416
    while ((node != NULL) && (sk->num > 1)) {
417
        WOLFSSL_STACK* tmp = node;
418
        node = node->next;
419
420
        wolfSSL_X509_EXTENSION_free(tmp->data.ext);
421
        XFREE(tmp, NULL, DYNAMIC_TYPE_X509);
422
        sk->num -= 1;
423
    }
424
425
    /* free head of stack */
426
    if (sk->num == 1) {
427
        wolfSSL_X509_EXTENSION_free(sk->data.ext);
428
    }
429
    XFREE(sk, NULL, DYNAMIC_TYPE_X509);
430
}
431
432
static WOLFSSL_STACK* generateExtStack(const WOLFSSL_X509 *x)
433
{
434
    int numOfExt, i;
435
    WOLFSSL_X509 *x509 = (WOLFSSL_X509*)x;
436
    WOLFSSL_STACK* ret;
437
    WOLFSSL_STACK* tmp;
438
439
    if (!x509) {
440
        WOLFSSL_MSG("Bad parameter");
441
        return NULL;
442
    }
443
444
    /* Save x509->ext_sk */
445
    tmp = x509->ext_sk;
446
    x509->ext_sk = NULL;
447
    numOfExt = wolfSSL_X509_get_ext_count(x509);
448
449
    for (i = 0; i < numOfExt; i++) {
450
        /* Build the extension stack */
451
        (void)wolfSSL_X509_set_ext(x509, i);
452
    }
453
454
    /* Restore */
455
    ret = x509->ext_sk;
456
    x509->ext_sk = tmp;
457
    return ret;
458
}
459
460
/**
461
 * @param x Certificate to extract extensions from
462
 * @return STACK_OF(X509_EXTENSION)*
463
 */
464
const WOLFSSL_STACK *wolfSSL_X509_get0_extensions(const WOLFSSL_X509 *x)
465
{
466
    int numOfExt;
467
    WOLFSSL_X509 *x509 = (WOLFSSL_X509*)x;
468
    WOLFSSL_ENTER("wolfSSL_X509_get0_extensions");
469
470
    if (!x509) {
471
        WOLFSSL_MSG("Bad parameter");
472
        return NULL;
473
    }
474
475
    numOfExt = wolfSSL_X509_get_ext_count(x509);
476
477
    if (numOfExt != wolfSSL_sk_num(x509->ext_sk_full)) {
478
        wolfSSL_sk_pop_free(x509->ext_sk_full, NULL);
479
        x509->ext_sk_full = generateExtStack(x);
480
    }
481
482
    return x509->ext_sk_full;
483
}
484
485
/**
486
 * Caller is responsible for freeing the returned stack.
487
 */
488
const WOLFSSL_STACK *wolfSSL_X509_REQ_get_extensions(const WOLFSSL_X509 *x)
489
{
490
    return generateExtStack(x);
491
}
492
493
/* Gets the X509_EXTENSION* ext based on it's location in WOLFSSL_X509* x509.
494
 *
495
 * x509   : The X509 structure to look for the extension.
496
 * loc    : Location of the extension. If the extension is found at the given
497
 * location, a new X509_EXTENSION structure is populated with extension-specific
498
 * data based on the extension type.
499
500
 * Returns NULL on error or pointer to X509_EXTENSION structure containing the
501
 * extension. The returned X509_EXTENSION should not be free'd by caller.
502
 * The returned X509_EXTENSION is pushed onto a stack inside the x509 argument.
503
 * This is later free'd when x509 is free'd.
504
 *
505
 * NOTE: for unknown extension NIDs, a X509_EXTENSION is populated with the
506
 * extension oid as the ASN1_OBJECT (QT compatibility)
507
 */
508
WOLFSSL_X509_EXTENSION* wolfSSL_X509_get_ext(const WOLFSSL_X509* x509, int loc)
509
{
510
    WOLFSSL_X509_EXTENSION* ext = NULL;
511
    WOLFSSL_ENTER("wolfSSL_X509_get_ext");
512
    if (x509 == NULL)
513
        return NULL;
514
515
   ext = wolfSSL_X509_set_ext((WOLFSSL_X509*) x509, loc);
516
   return ext;
517
}
518
519
int wolfSSL_X509_get_ext_by_OBJ(const WOLFSSL_X509 *x,
520
        const WOLFSSL_ASN1_OBJECT *obj, int lastpos)
521
{
522
    const WOLF_STACK_OF(WOLFSSL_X509_EXTENSION) *sk;
523
524
    if (!x || !obj) {
525
        WOLFSSL_MSG("Bad parameter");
526
        return -1;
527
    }
528
529
    sk = wolfSSL_X509_get0_extensions(x);
530
    if (!sk) {
531
        WOLFSSL_MSG("No extensions");
532
        return -1;
533
    }
534
    lastpos++;
535
    if (lastpos < 0)
536
        lastpos = 0;
537
    for (; lastpos < wolfSSL_sk_num(sk); lastpos++)
538
        if (wolfSSL_OBJ_cmp((WOLFSSL_ASN1_OBJECT*)wolfSSL_sk_value(sk,
539
                        lastpos), obj) == 0)
540
            return lastpos;
541
    return -1;
542
}
543
544
#endif /* OPENSSL_ALL || OPENSSL_EXTRA */
545
546
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
547
    defined(WOLFSSL_WPAS_SMALL)
548
/* Set a general name from the DNS entry data.
549
 *
550
 * @param [in]      dns  DNS entry.
551
 * @param [in, out] gn   General name to place data in.
552
 * @return  1 on success.
553
 * @return  0 on failure.
554
 */
555
static int wolfssl_dns_entry_othername_to_gn(DNS_entry* dns,
556
    WOLFSSL_GENERAL_NAME* gn)
557
{
558
    int ret = 0;
559
    WOLFSSL_ASN1_OBJECT* obj;
560
    WOLFSSL_ASN1_TYPE* type;
561
    WOLFSSL_ASN1_STRING* str;
562
    byte tag;
563
    unsigned char* p = (unsigned char *)dns->name;
564
    long len = dns->len;
565
566
#ifdef WOLFSSL_FPKI
567
    if (dns->oidSum != 0) {
568
        /* UPN OID: 1.3.6.1.4.1.311.20.2.3 */
569
        static const unsigned char upn_oid[] = {
570
            0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x03
571
        };
572
        /* FASCN OID: 2.16.840.1.101.3.6.6 */
573
        static const unsigned char fascn_oid[] = {
574
            0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x06, 0x06
575
        };
576
        const unsigned char* oid;
577
        word32 oidSz;
578
579
        if ((oid = OidFromId(dns->oidSum, oidCertAltNameType, &oidSz)) ==
580
                NULL) {
581
            if (dns->oidSum == UPN_OID) {
582
                oid = upn_oid;
583
                oidSz = (word32)sizeof(upn_oid);
584
            }
585
            else if (dns->oidSum == FASCN_OID) {
586
                oid = fascn_oid;
587
                oidSz = (word32)sizeof(fascn_oid);
588
            }
589
            else {
590
                goto err;
591
            }
592
        }
593
        if ((obj = wolfSSL_c2i_ASN1_OBJECT(NULL, &oid, oidSz)) == NULL) {
594
            goto err;
595
        }
596
597
        tag = ASN_UTF8STRING;
598
    }
599
    else
600
#endif
601
    {
602
        word32 idx = 0;
603
        int nameLen;
604
605
        /* Create an object id for general name from DER encoding. */
606
        obj = wolfSSL_d2i_ASN1_OBJECT(NULL, (const unsigned char**)&p, len);
607
        if (obj == NULL) {
608
            goto err;
609
        }
610
        /* Pointer moved on and now update length of remaining data. */
611
        len -= (long)((size_t)p - (size_t)dns->name);
612
613
        /* Next is: [0]. Check tag and length. */
614
        if (GetASNTag(p, &idx, &tag, (word32)len) < 0) {
615
            wolfSSL_ASN1_OBJECT_free(obj);
616
            goto err;
617
        }
618
        if (tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {
619
            wolfSSL_ASN1_OBJECT_free(obj);
620
            goto err;
621
        }
622
        if (GetLength(p, &idx, &nameLen, (word32)len) <= 1) {
623
            wolfSSL_ASN1_OBJECT_free(obj);
624
            goto err;
625
        }
626
627
        /* Next is a string of some type. */
628
        if (GetASNTag(p, &idx, &tag, (word32)len) < 0) {
629
            wolfSSL_ASN1_OBJECT_free(obj);
630
            goto err;
631
        }
632
        if (GetLength(p, &idx, &nameLen, (word32)len) <= 0) {
633
            wolfSSL_ASN1_OBJECT_free(obj);
634
            goto err;
635
        }
636
        p += idx;
637
        len -= idx;
638
    }
639
640
    /* Create a WOLFSSL_ASN1_STRING from the DER. */
641
    str = wolfSSL_ASN1_STRING_type_new(tag);
642
    if (str == NULL) {
643
        wolfSSL_ASN1_OBJECT_free(obj);
644
        goto err;
645
    }
646
    wolfSSL_ASN1_STRING_set(str, p, (word32)len);
647
648
    /* Wrap string in a WOLFSSL_ASN1_TYPE. */
649
    type = wolfSSL_ASN1_TYPE_new();
650
    if (type == NULL) {
651
        wolfSSL_ASN1_OBJECT_free(obj);
652
        wolfSSL_ASN1_STRING_free(str);
653
        goto err;
654
    }
655
    wolfSSL_ASN1_TYPE_set(type, tag, str);
656
657
    /* Store the object and string in general name. */
658
    gn->d.otherName->type_id = obj;
659
    gn->d.otherName->value = type;
660
661
    ret = 1;
662
err:
663
    return ret;
664
}
665
#endif /* OPENSSL_ALL || WOLFSSL_WPAS_SMALL */
666
667
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
668
static int wolfssl_x509_alt_names_to_gn(WOLFSSL_X509* x509,
669
    WOLFSSL_X509_EXTENSION* ext)
670
{
671
    int ret = 0;
672
    WOLFSSL_GENERAL_NAME* gn = NULL;
673
    DNS_entry* dns = NULL;
674
    WOLFSSL_STACK* sk;
675
676
#ifdef OPENSSL_ALL
677
    ret = wolfSSL_ASN1_STRING_set(&ext->value, x509->subjAltNameSrc,
678
              x509->subjAltNameSz);
679
    if (ret != WOLFSSL_SUCCESS) {
680
        WOLFSSL_MSG("ASN1_STRING_set() failed");
681
        goto err;
682
    }
683
#endif
684
685
    sk = (WOLFSSL_GENERAL_NAMES*)XMALLOC(sizeof(WOLFSSL_GENERAL_NAMES), NULL,
686
        DYNAMIC_TYPE_ASN1);
687
    if (sk == NULL) {
688
        goto err;
689
    }
690
    XMEMSET(sk, 0, sizeof(WOLFSSL_GENERAL_NAMES));
691
    sk->type = STACK_TYPE_GEN_NAME;
692
693
    if (x509->subjAltNameSet && x509->altNames != NULL) {
694
        /* alt names are DNS_entry structs */
695
        dns = x509->altNames;
696
        /* Currently only support GEN_DNS type */
697
        while (dns != NULL) {
698
            gn = wolfSSL_GENERAL_NAME_new();
699
            if (gn == NULL) {
700
                WOLFSSL_MSG("Error creating GENERAL_NAME");
701
                wolfSSL_sk_pop_free(sk, NULL);
702
                goto err;
703
            }
704
705
            gn->type = dns->type;
706
            if (gn->type == GEN_OTHERNAME) {
707
                if (!wolfssl_dns_entry_othername_to_gn(dns, gn)) {
708
                    WOLFSSL_MSG("OTHERNAME set failed");
709
                    wolfSSL_GENERAL_NAME_free(gn);
710
                    wolfSSL_sk_pop_free(sk, NULL);
711
                    goto err;
712
                }
713
            }
714
            else {
715
                gn->d.ia5->length = dns->len;
716
                if (wolfSSL_ASN1_STRING_set(gn->d.ia5, dns->name,
717
                        gn->d.ia5->length) != WOLFSSL_SUCCESS) {
718
                    WOLFSSL_MSG("ASN1_STRING_set failed");
719
                    wolfSSL_GENERAL_NAME_free(gn);
720
                    wolfSSL_sk_pop_free(sk, NULL);
721
                    goto err;
722
                }
723
            }
724
725
            if (wolfSSL_sk_GENERAL_NAME_push(sk, gn) != WOLFSSL_SUCCESS) {
726
                WOLFSSL_MSG("Error pushing onto stack");
727
                wolfSSL_GENERAL_NAME_free(gn);
728
                wolfSSL_sk_pop_free(sk, NULL);
729
                goto err;
730
            }
731
732
            dns = dns->next;
733
        }
734
    }
735
    ext->ext_sk = sk;
736
    ext->crit = x509->subjAltNameCrit;
737
738
    ret = 1;
739
err:
740
    return ret;
741
}
742
743
/* Pushes a new X509_EXTENSION* ext onto the stack inside WOLFSSL_X509* x509.
744
 * This is currently a helper function for wolfSSL_X509_get_ext
745
 * Caller does not free the returned WOLFSSL_X509_EXTENSION*
746
 */
747
WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc)
748
{
749
    int extCount = 0, length = 0, outSz = 0, sz = 0, ret = 0;
750
    int objSz = 0, isSet = 0;
751
    const byte* rawCert;
752
    const byte* input;
753
    byte* oidBuf;
754
    word32 oid, idx = 0, tmpIdx = 0, nid;
755
    WOLFSSL_X509_EXTENSION* ext = NULL;
756
    WOLFSSL_ASN1_INTEGER* a;
757
    WOLFSSL_STACK* sk;
758
#ifdef WOLFSSL_SMALL_STACK
759
    DecodedCert* cert = NULL;
760
#else
761
    DecodedCert cert[1];
762
#endif
763
764
    WOLFSSL_ENTER("wolfSSL_X509_set_ext");
765
766
    if(x509 == NULL){
767
        WOLFSSL_MSG("\tNot passed a certificate");
768
        return NULL;
769
    }
770
771
    if(loc <0 || (loc > wolfSSL_X509_get_ext_count(x509))){
772
        WOLFSSL_MSG("\tBad location argument");
773
        return NULL;
774
    }
775
776
    ext = wolfSSL_X509_EXTENSION_new();
777
    if (ext == NULL) {
778
        WOLFSSL_MSG("\tX509_EXTENSION_new() failed");
779
        return NULL;
780
    }
781
782
    rawCert = wolfSSL_X509_get_der((WOLFSSL_X509*)x509, &outSz);
783
    if (rawCert == NULL) {
784
        WOLFSSL_MSG("\tX509_get_der() failed");
785
        wolfSSL_X509_EXTENSION_free(ext);
786
        return NULL;
787
    }
788
789
#ifdef WOLFSSL_SMALL_STACK
790
    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT);
791
    if (cert == NULL) {
792
        WOLFSSL_MSG("Failed to allocate memory for DecodedCert");
793
        wolfSSL_X509_EXTENSION_free(ext);
794
        return NULL;
795
    }
796
#endif
797
798
    InitDecodedCert(cert, rawCert, (word32)outSz, 0);
799
800
    if (ParseCert(cert,
801
#ifdef WOLFSSL_CERT_REQ
802
            x509->isCSR ? CERTREQ_TYPE :
803
#endif
804
                    CA_TYPE,
805
            NO_VERIFY, NULL) < 0) {
806
        WOLFSSL_MSG("\tCertificate parsing failed");
807
        wolfSSL_X509_EXTENSION_free(ext);
808
        FreeDecodedCert(cert);
809
    #ifdef WOLFSSL_SMALL_STACK
810
        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
811
    #endif
812
        return NULL;
813
    }
814
815
    input = cert->extensions;
816
    sz = cert->extensionsSz;
817
818
    if (input == NULL || sz == 0) {
819
        WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
820
        wolfSSL_X509_EXTENSION_free(ext);
821
        FreeDecodedCert(cert);
822
#ifdef WOLFSSL_SMALL_STACK
823
        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
824
#endif
825
        return NULL;
826
    }
827
828
#ifdef WOLFSSL_CERT_REQ
829
    if (!x509->isCSR)
830
#endif
831
    {
832
        if (input[idx++] != ASN_EXTENSIONS) {
833
            WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
834
            wolfSSL_X509_EXTENSION_free(ext);
835
            FreeDecodedCert(cert);
836
    #ifdef WOLFSSL_SMALL_STACK
837
            XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
838
    #endif
839
            return NULL;
840
        }
841
842
        if (GetLength(input, &idx, &length, sz) < 0) {
843
            WOLFSSL_MSG("\tfail: invalid length");
844
            wolfSSL_X509_EXTENSION_free(ext);
845
            FreeDecodedCert(cert);
846
    #ifdef WOLFSSL_SMALL_STACK
847
            XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
848
    #endif
849
            return NULL;
850
        }
851
    }
852
853
    if (GetSequence(input, &idx, &length, sz) < 0) {
854
        WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
855
        wolfSSL_X509_EXTENSION_free(ext);
856
        FreeDecodedCert(cert);
857
#ifdef WOLFSSL_SMALL_STACK
858
        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
859
#endif
860
        return NULL;
861
    }
862
863
    while (idx < (word32)sz) {
864
        oid = 0;
865
866
        if (GetSequence(input, &idx, &length, sz) < 0) {
867
            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
868
            wolfSSL_X509_EXTENSION_free(ext);
869
            FreeDecodedCert(cert);
870
    #ifdef WOLFSSL_SMALL_STACK
871
            XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
872
    #endif
873
            return NULL;
874
        }
875
876
        tmpIdx = idx;
877
        ret = GetObjectId(input, &idx, &oid, oidCertExtType, sz);
878
        if (ret < 0) {
879
            WOLFSSL_MSG("\tfail: OBJECT ID");
880
            wolfSSL_X509_EXTENSION_free(ext);
881
            FreeDecodedCert(cert);
882
        #ifdef WOLFSSL_SMALL_STACK
883
            XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
884
        #endif
885
            return NULL;
886
        }
887
        idx = tmpIdx;
888
        nid = (word32)oid2nid(oid, oidCertExtType);
889
890
        /* Continue while loop until extCount == loc or idx > sz */
891
        if (extCount != loc) {
892
            idx += length;
893
            extCount++;
894
            continue;
895
        }
896
        /* extCount == loc. Now get the extension. */
897
        /* Check if extension has been set */
898
        isSet = wolfSSL_X509_ext_isSet_by_NID((WOLFSSL_X509*)x509, nid);
899
900
        if (wolfSSL_OBJ_nid2ln(nid) != NULL) {
901
            /* This is NOT an unknown OID. */
902
            ext->obj = wolfSSL_OBJ_nid2obj(nid);
903
            if (ext->obj == NULL) {
904
                WOLFSSL_MSG("\tfail: Invalid OBJECT");
905
                wolfSSL_X509_EXTENSION_free(ext);
906
                FreeDecodedCert(cert);
907
            #ifdef WOLFSSL_SMALL_STACK
908
                XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
909
            #endif
910
                return NULL;
911
            }
912
        }
913
914
        if (ext->obj) {
915
            ext->obj->nid = nid;
916
        }
917
918
        switch (oid) {
919
            case BASIC_CA_OID:
920
                if (!isSet)
921
                    break;
922
                /* Set pathlength */
923
                a = wolfSSL_ASN1_INTEGER_new();
924
                if (a == NULL) {
925
                    wolfSSL_X509_EXTENSION_free(ext);
926
                    FreeDecodedCert(cert);
927
                #ifdef WOLFSSL_SMALL_STACK
928
                    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
929
                #endif
930
                    return NULL;
931
                }
932
                a->length = x509->pathLength;
933
934
                /* Save ASN1_INTEGER in x509 extension */
935
                ext->obj->pathlen = a;
936
937
                ext->obj->ca = x509->isCa;
938
                ext->crit = x509->basicConstCrit;
939
                break;
940
941
            case AUTH_INFO_OID:
942
                if (!isSet)
943
                    break;
944
945
                /* Create a stack to hold both the caIssuer and ocsp objects
946
                    in X509_EXTENSION structure */
947
                sk = wolfSSL_sk_new_asn1_obj();
948
                if (sk == NULL) {
949
                    WOLFSSL_MSG("Failed to malloc stack");
950
                    wolfSSL_X509_EXTENSION_free(ext);
951
                    FreeDecodedCert(cert);
952
                #ifdef WOLFSSL_SMALL_STACK
953
                    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
954
                #endif
955
                    return NULL;
956
                }
957
958
                /* Add CaIssuers object to stack */
959
                if (x509->authInfoCaIssuer != NULL &&
960
                    x509->authInfoCaIssuerSz > 0)
961
                {
962
                    WOLFSSL_ASN1_OBJECT* obj;
963
                    obj = wolfSSL_ASN1_OBJECT_new();
964
                    if (obj == NULL) {
965
                        WOLFSSL_MSG("Error creating ASN1 object");
966
                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
967
                        wolfSSL_X509_EXTENSION_free(ext);
968
                        FreeDecodedCert(cert);
969
                    #ifdef WOLFSSL_SMALL_STACK
970
                        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
971
                    #endif
972
                        return NULL;
973
                    }
974
                    obj->obj = (byte*)x509->authInfoCaIssuer;
975
                    obj->objSz = x509->authInfoCaIssuerSz;
976
                    obj->grp = oidCertAuthInfoType;
977
                    obj->nid = NID_ad_ca_issuers;
978
979
                    ret = wolfSSL_sk_ASN1_OBJECT_push(sk, obj);
980
                    if (ret != WOLFSSL_SUCCESS) {
981
                        WOLFSSL_MSG("Error pushing ASN1 object onto stack");
982
                        wolfSSL_ASN1_OBJECT_free(obj);
983
                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
984
                        wolfSSL_X509_EXTENSION_free(ext);
985
                        FreeDecodedCert(cert);
986
                    #ifdef WOLFSSL_SMALL_STACK
987
                        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
988
                    #endif
989
                        return NULL;
990
                    }
991
                }
992
993
                /* Add OCSP object to stack */
994
                if (x509->authInfo != NULL &&
995
                    x509->authInfoSz > 0)
996
                {
997
                    WOLFSSL_ASN1_OBJECT* obj;
998
                    obj = wolfSSL_ASN1_OBJECT_new();
999
                    if (obj == NULL) {
1000
                        WOLFSSL_MSG("Error creating ASN1 object");
1001
                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
1002
                        wolfSSL_X509_EXTENSION_free(ext);
1003
                        FreeDecodedCert(cert);
1004
                    #ifdef WOLFSSL_SMALL_STACK
1005
                        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1006
                    #endif
1007
                        return NULL;
1008
                    }
1009
                    obj->obj = x509->authInfo;
1010
                    obj->objSz = x509->authInfoSz;
1011
                    obj->grp = oidCertAuthInfoType;
1012
                    obj->nid = NID_ad_OCSP;
1013
1014
                    ret = wolfSSL_sk_ASN1_OBJECT_push(sk, obj);
1015
                    if (ret != WOLFSSL_SUCCESS) {
1016
                        WOLFSSL_MSG("Error pushing ASN1 object onto stack");
1017
                        wolfSSL_ASN1_OBJECT_free(obj);
1018
                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
1019
                        wolfSSL_X509_EXTENSION_free(ext);
1020
                        FreeDecodedCert(cert);
1021
                    #ifdef WOLFSSL_SMALL_STACK
1022
                        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1023
                    #endif
1024
                        return NULL;
1025
                    }
1026
                }
1027
                ext->ext_sk = sk;
1028
                ext->crit = x509->authInfoCrit;
1029
                break;
1030
1031
            case AUTH_KEY_OID:
1032
                if (!isSet)
1033
                    break;
1034
1035
                ret = wolfSSL_ASN1_STRING_set(&ext->value, x509->authKeyId,
1036
                                        x509->authKeyIdSz);
1037
                if (ret != WOLFSSL_SUCCESS) {
1038
                    WOLFSSL_MSG("ASN1_STRING_set() failed");
1039
                    wolfSSL_X509_EXTENSION_free(ext);
1040
                    FreeDecodedCert(cert);
1041
                #ifdef WOLFSSL_SMALL_STACK
1042
                    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1043
                #endif
1044
                    return NULL;
1045
                }
1046
                ext->crit = x509->authKeyIdCrit;
1047
                break;
1048
1049
            case SUBJ_KEY_OID:
1050
                if (!isSet)
1051
                    break;
1052
1053
                ret = wolfSSL_ASN1_STRING_set(&ext->value, x509->subjKeyId,
1054
                                        x509->subjKeyIdSz);
1055
                if (ret != WOLFSSL_SUCCESS) {
1056
                    WOLFSSL_MSG("ASN1_STRING_set() failed");
1057
                    wolfSSL_X509_EXTENSION_free(ext);
1058
                    FreeDecodedCert(cert);
1059
                #ifdef WOLFSSL_SMALL_STACK
1060
                    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1061
                #endif
1062
                    return NULL;
1063
                }
1064
                ext->crit = x509->subjKeyIdCrit;
1065
                break;
1066
1067
            case CERT_POLICY_OID:
1068
                if (!isSet)
1069
                    break;
1070
                ext->crit = x509->certPolicyCrit;
1071
                break;
1072
1073
            case KEY_USAGE_OID:
1074
                if (!isSet)
1075
                    break;
1076
1077
                ret = wolfSSL_ASN1_STRING_set(&ext->value,
1078
                                  (byte*)&(x509->keyUsage), sizeof(word16));
1079
                if (ret != WOLFSSL_SUCCESS) {
1080
                    WOLFSSL_MSG("ASN1_STRING_set() failed");
1081
                    wolfSSL_X509_EXTENSION_free(ext);
1082
                    FreeDecodedCert(cert);
1083
                #ifdef WOLFSSL_SMALL_STACK
1084
                    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1085
                #endif
1086
                    return NULL;
1087
                }
1088
                ext->crit = x509->keyUsageCrit;
1089
                break;
1090
1091
            case EXT_KEY_USAGE_OID:
1092
                if (!isSet)
1093
                    break;
1094
1095
                ret = wolfSSL_ASN1_STRING_set(&ext->value, x509->extKeyUsageSrc,
1096
                                              x509->extKeyUsageSz);
1097
                if (ret != WOLFSSL_SUCCESS) {
1098
                    WOLFSSL_MSG("ASN1_STRING_set() failed");
1099
                    wolfSSL_X509_EXTENSION_free(ext);
1100
                    FreeDecodedCert(cert);
1101
                #ifdef WOLFSSL_SMALL_STACK
1102
                    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1103
                #endif
1104
                    return NULL;
1105
                }
1106
                ext->crit = x509->extKeyUsageCrit;
1107
                break;
1108
1109
            case CRL_DIST_OID:
1110
                if (!isSet)
1111
                    break;
1112
                ext->crit = x509->CRLdistCrit;
1113
                break;
1114
1115
            case ALT_NAMES_OID:
1116
                if (!isSet)
1117
                    break;
1118
                if (!wolfssl_x509_alt_names_to_gn(x509, ext)) {
1119
                    wolfSSL_X509_EXTENSION_free(ext);
1120
                    FreeDecodedCert(cert);
1121
                #ifdef WOLFSSL_SMALL_STACK
1122
                    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1123
                #endif
1124
                    return NULL;
1125
                }
1126
                break;
1127
1128
            default:
1129
                WOLFSSL_MSG("Unknown extension type found, parsing OID");
1130
                /* If the extension type is not recognized/supported,
1131
                 *  set the ASN1_OBJECT in the extension with the
1132
                 *  parsed oid for access in later function calls */
1133
1134
                /* Get OID from input */
1135
                if (GetASNObjectId(input, &idx, &length, sz) != 0) {
1136
                    WOLFSSL_MSG("Failed to Get ASN Object Id");
1137
                    wolfSSL_X509_EXTENSION_free(ext);
1138
                    FreeDecodedCert(cert);
1139
                #ifdef WOLFSSL_SMALL_STACK
1140
                    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1141
                #endif
1142
                    return NULL;
1143
                }
1144
                oidBuf = (byte*)XMALLOC(length+1+MAX_LENGTH_SZ, NULL,
1145
                                    DYNAMIC_TYPE_TMP_BUFFER);
1146
                if (oidBuf == NULL) {
1147
                    WOLFSSL_MSG("Failed to malloc tmp buffer");
1148
                    wolfSSL_X509_EXTENSION_free(ext);
1149
                    FreeDecodedCert(cert);
1150
                #ifdef WOLFSSL_SMALL_STACK
1151
                    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1152
                #endif
1153
                    return NULL;
1154
                }
1155
                oidBuf[0] = ASN_OBJECT_ID;
1156
                objSz++;
1157
                objSz += SetLength(length, oidBuf + 1);
1158
                objSz += length;
1159
1160
                /* Set object size and reallocate space in object buffer */
1161
                if (ext->obj == NULL) {
1162
                    ext->obj = wolfSSL_ASN1_OBJECT_new();
1163
                    if (ext->obj == NULL) {
1164
                        XFREE(oidBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1165
                        wolfSSL_X509_EXTENSION_free(ext);
1166
                        FreeDecodedCert(cert);
1167
                #ifdef WOLFSSL_SMALL_STACK
1168
                        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1169
                #endif
1170
                        return NULL;
1171
                    }
1172
                }
1173
1174
                ext->obj->objSz = objSz;
1175
                if(((ext->obj->dynamic & WOLFSSL_ASN1_DYNAMIC_DATA) != 0) ||
1176
                   (ext->obj->obj == NULL)) {
1177
                        ext->obj->obj =(byte*)XREALLOC((byte*)ext->obj->obj,
1178
                                             ext->obj->objSz,
1179
                                             NULL,DYNAMIC_TYPE_ASN1);
1180
                    if (ext->obj->obj == NULL) {
1181
                        wolfSSL_X509_EXTENSION_free(ext);
1182
                        FreeDecodedCert(cert);
1183
                        XFREE(oidBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1184
                    #ifdef WOLFSSL_SMALL_STACK
1185
                        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1186
                    #endif
1187
                        return NULL;
1188
                    }
1189
                    ext->obj->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA;
1190
                } else {
1191
                    ext->obj->dynamic &= ~WOLFSSL_ASN1_DYNAMIC_DATA;
1192
                }
1193
                /* Get OID from input and copy to ASN1_OBJECT buffer */
1194
                XMEMCPY(oidBuf+2, input+idx, length);
1195
                XMEMCPY((byte*)ext->obj->obj, oidBuf, ext->obj->objSz);
1196
                XFREE(oidBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1197
                oidBuf = NULL;
1198
                ext->obj->grp = oidCertExtType;
1199
                ext->crit = 0;
1200
1201
                /* Get extension data and copy as ASN1_STRING */
1202
                tmpIdx = idx + length;
1203
                if ((tmpIdx >= (word32)sz) ||
1204
                    (input[tmpIdx] != ASN_OCTET_STRING))
1205
                {
1206
                    WOLFSSL_MSG("Error decoding unknown extension data");
1207
                    wolfSSL_ASN1_OBJECT_free(ext->obj);
1208
                    wolfSSL_X509_EXTENSION_free(ext);
1209
                    FreeDecodedCert(cert);
1210
                #ifdef WOLFSSL_SMALL_STACK
1211
                    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1212
                #endif
1213
                    return NULL;
1214
                }
1215
1216
                tmpIdx++;
1217
1218
                if (GetLength(input, &tmpIdx, &length, sz) <= 0) {
1219
                    WOLFSSL_MSG("Error: Invalid Input Length.");
1220
                    wolfSSL_ASN1_OBJECT_free(ext->obj);
1221
                    wolfSSL_X509_EXTENSION_free(ext);
1222
                    FreeDecodedCert(cert);
1223
                #ifdef WOLFSSL_SMALL_STACK
1224
                    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1225
                #endif
1226
                    return NULL;
1227
                }
1228
                ext->value.data = (char*)XMALLOC(length, NULL, DYNAMIC_TYPE_ASN1);
1229
                ext->value.isDynamic = 1;
1230
                if (ext->value.data == NULL) {
1231
                    WOLFSSL_MSG("Failed to malloc ASN1_STRING data");
1232
                    wolfSSL_X509_EXTENSION_free(ext);
1233
                    FreeDecodedCert(cert);
1234
                #ifdef WOLFSSL_SMALL_STACK
1235
                    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1236
                #endif
1237
                    return NULL;
1238
                }
1239
                XMEMCPY(ext->value.data,input+tmpIdx,length);
1240
                ext->value.length = length;
1241
        } /* switch(oid) */
1242
1243
        break; /* Got the Extension. Now exit while loop. */
1244
1245
    } /* while(idx < sz) */
1246
1247
    /* Store the new extension in a stack inside x509
1248
     * The extensions on the stack are free'd internally when FreeX509 is called
1249
     */
1250
    if (x509->ext_sk == NULL)
1251
        x509->ext_sk = wolfSSL_sk_new_x509_ext();
1252
    if (wolfSSL_sk_X509_EXTENSION_push(x509->ext_sk, ext) == WOLFSSL_FAILURE) {
1253
        wolfSSL_X509_EXTENSION_free(ext);
1254
        ext = NULL;
1255
    }
1256
1257
    FreeDecodedCert(cert);
1258
#ifdef WOLFSSL_SMALL_STACK
1259
    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
1260
#endif
1261
    return ext;
1262
}
1263
1264
/**
1265
 * @param str String to copy
1266
 * @param buf Output buffer. If this contains a pointer then it is free'd
1267
 *            with the DYNAMIC_TYPE_X509_EXT hint.
1268
 * @param len Output length
1269
 * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on error
1270
 */
1271
static int asn1_string_copy_to_buffer(WOLFSSL_ASN1_STRING* str, byte** buf,
1272
        word32* len, void* heap) {
1273
    if (!str || !buf || !len) {
1274
        return WOLFSSL_FAILURE;
1275
    }
1276
    if (str->data && str->length > 0) {
1277
        if (*buf)
1278
            XFREE(*buf, heap, DYNAMIC_TYPE_X509_EXT);
1279
        *len = 0;
1280
        *buf = (byte*)XMALLOC(str->length, heap,
1281
                DYNAMIC_TYPE_X509_EXT);
1282
        if (!*buf) {
1283
            WOLFSSL_MSG("malloc error");
1284
            return WOLFSSL_FAILURE;
1285
        }
1286
        *len = str->length;
1287
        XMEMCPY(*buf, str->data, str->length);
1288
    }
1289
1290
    (void)heap;
1291
    return WOLFSSL_SUCCESS;
1292
}
1293
1294
int wolfSSL_X509_add_ext(WOLFSSL_X509 *x509, WOLFSSL_X509_EXTENSION *ext, int loc)
1295
{
1296
    int nid;
1297
1298
    WOLFSSL_ENTER("wolfSSL_X509_add_ext");
1299
1300
    if (!x509 || !ext || loc >= 0) {
1301
        WOLFSSL_MSG("Bad parameter");
1302
        return WOLFSSL_FAILURE;
1303
    }
1304
    nid = (ext->obj != NULL) ? ext->obj->type : ext->value.nid;
1305
1306
    switch (nid) {
1307
    case NID_authority_key_identifier:
1308
        if (x509->authKeyIdSrc != NULL) {
1309
            /* If authKeyId points into authKeyIdSrc then free it and
1310
             * revert to old functionality */
1311
            XFREE(x509->authKeyIdSrc, x509->heap, DYNAMIC_TYPE_X509_EXT);
1312
            x509->authKeyIdSrc = NULL;
1313
            x509->authKeyId = NULL;
1314
        }
1315
        if (asn1_string_copy_to_buffer(&ext->value, &x509->authKeyId,
1316
                &x509->authKeyIdSz, x509->heap) != WOLFSSL_SUCCESS) {
1317
            WOLFSSL_MSG("asn1_string_copy_to_buffer error");
1318
            return WOLFSSL_FAILURE;
1319
        }
1320
        x509->authKeyIdCrit = (byte)ext->crit;
1321
        break;
1322
    case NID_subject_key_identifier:
1323
        if (asn1_string_copy_to_buffer(&ext->value, &x509->subjKeyId,
1324
                &x509->subjKeyIdSz, x509->heap) != WOLFSSL_SUCCESS) {
1325
            WOLFSSL_MSG("asn1_string_copy_to_buffer error");
1326
            return WOLFSSL_FAILURE;
1327
        }
1328
        x509->subjKeyIdCrit = (byte)ext->crit;
1329
        break;
1330
    case NID_subject_alt_name:
1331
    {
1332
        WOLFSSL_GENERAL_NAMES* gns = ext->ext_sk;
1333
        while (gns) {
1334
            WOLFSSL_GENERAL_NAME* gn = gns->data.gn;
1335
            if ((gn != NULL) && (gn->type == ASN_OTHER_TYPE)) {
1336
                char *buf = NULL;
1337
                int ret = 0;
1338
                word32 len = 0;
1339
1340
                len = SetOthername(gn->d.otherName, NULL);
1341
                if (len == WOLFSSL_FAILURE) {
1342
                    return WOLFSSL_FAILURE;
1343
                }
1344
1345
                buf = (char*)XMALLOC(len, x509->heap, DYNAMIC_TYPE_X509_EXT);
1346
                if (buf == NULL) {
1347
                    WOLFSSL_MSG("Couldn't allocate memory for othername");
1348
                    return WOLFSSL_FAILURE;
1349
                }
1350
1351
                /* SetOthername() cannot fail; already passed above. */
1352
                SetOthername(gn->d.otherName, (byte*)buf);
1353
1354
                ret = wolfSSL_X509_add_altname_ex(x509, buf, len,
1355
                                                  ASN_OTHER_TYPE);
1356
                XFREE(buf, x509->heap, DYNAMIC_TYPE_X509_EXT);
1357
                if (ret == WOLFSSL_FAILURE) {
1358
                     WOLFSSL_MSG("wolfSSL_X509_add_altname_ex() failed");
1359
                     return WOLFSSL_FAILURE;
1360
                }
1361
            }
1362
            else if (!gn || !gn->d.ia5 ||
1363
                wolfSSL_X509_add_altname_ex(x509, gn->d.ia5->data,
1364
                    gn->d.ia5->length, gn->type) != WOLFSSL_SUCCESS) {
1365
                WOLFSSL_MSG("Subject alternative name missing extension");
1366
                return WOLFSSL_FAILURE;
1367
            }
1368
            gns = gns->next;
1369
        }
1370
        x509->subjAltNameSet = 1;
1371
        x509->subjAltNameCrit = (byte)ext->crit;
1372
        break;
1373
    }
1374
    case NID_key_usage:
1375
        if (ext && ext->value.data) {
1376
            if (ext->value.length == sizeof(word16)) {
1377
                /* if ext->value is already word16, set directly */
1378
                x509->keyUsage = *(word16*)ext->value.data;
1379
                x509->keyUsageCrit = (byte)ext->crit;
1380
                x509->keyUsageSet = 1;
1381
            }
1382
            else if (ext->value.length > 0) {
1383
                /* ext->value is comma-delimited string, convert to word16 */
1384
                if (ParseKeyUsageStr(ext->value.data, &x509->keyUsage,
1385
                                     x509->heap) != 0) {
1386
                    return WOLFSSL_FAILURE;
1387
                }
1388
                x509->keyUsageCrit = (byte)ext->crit;
1389
                x509->keyUsageSet = 1;
1390
            }
1391
            else {
1392
                return WOLFSSL_FAILURE;
1393
            }
1394
        }
1395
        break;
1396
    case NID_ext_key_usage:
1397
        if (ext && ext->value.data) {
1398
            if (ext->value.length == sizeof(byte)) {
1399
                /* if ext->value is already word16, set directly */
1400
                x509->extKeyUsage = *(byte*)ext->value.data;
1401
                x509->extKeyUsageCrit = (byte)ext->crit;
1402
            }
1403
            else if (ext->value.length > 0) {
1404
                /* ext->value is comma-delimited string, convert to word16 */
1405
                if (ParseExtKeyUsageStr(ext->value.data, &x509->extKeyUsage,
1406
                                        x509->heap) != 0) {
1407
                    return WOLFSSL_FAILURE;
1408
                }
1409
                x509->extKeyUsageCrit = (byte)ext->crit;
1410
            }
1411
            else {
1412
                return WOLFSSL_FAILURE;
1413
            }
1414
        }
1415
        break;
1416
    case NID_basic_constraints:
1417
        if (ext->obj) {
1418
            x509->isCa = (byte)ext->obj->ca;
1419
            x509->basicConstCrit = (byte)ext->crit;
1420
            if (ext->obj->pathlen)
1421
                x509->pathLength = ext->obj->pathlen->length;
1422
            x509->basicConstSet = 1;
1423
        }
1424
        break;
1425
    default:
1426
#ifdef WOLFSSL_CUSTOM_OID
1427
        if ((ext->obj == NULL) || (ext->value.length == 0)) {
1428
            WOLFSSL_MSG("Extension has insufficient information.");
1429
            return WOLFSSL_FAILURE;
1430
        }
1431
1432
        if ((x509->customExtCount < 0) ||
1433
            (x509->customExtCount >= NUM_CUSTOM_EXT)) {
1434
            WOLFSSL_MSG("Bad value for customExtCount.");
1435
            return WOLFSSL_FAILURE;
1436
        }
1437
1438
        /* This is a viable custom extension. */
1439
        char *oid = XMALLOC(MAX_OID_STRING_SZ, x509->heap,
1440
                            DYNAMIC_TYPE_X509_EXT);
1441
        byte *val = XMALLOC(ext->value.length, x509->heap,
1442
                            DYNAMIC_TYPE_X509_EXT);
1443
        int err = 0;
1444
1445
        if ((oid == NULL) || (val == NULL)) {
1446
            WOLFSSL_MSG("Memory allocation failure.\n");
1447
            err = 1;
1448
        }
1449
1450
        if (err == 0) {
1451
            XMEMCPY(val, ext->value.data, ext->value.length);
1452
            if (wolfSSL_OBJ_obj2txt(oid, MAX_OID_STRING_SZ, ext->obj, 1) < 0) {
1453
                err = 1;
1454
            }
1455
        }
1456
1457
        if (err == 1) {
1458
            XFREE(val, x509->heap, DYNAMIC_TYPE_X509_EXT);
1459
            XFREE(oid, x509->heap, DYNAMIC_TYPE_X509_EXT);
1460
            return WOLFSSL_FAILURE;
1461
        }
1462
1463
        /* x509->custom_exts now owns the buffers and they must be managed. */
1464
        x509->custom_exts[x509->customExtCount].oid = oid;
1465
        x509->custom_exts[x509->customExtCount].crit = ext->crit;
1466
        x509->custom_exts[x509->customExtCount].val = val;
1467
        x509->custom_exts[x509->customExtCount].valSz = ext->value.length;
1468
        x509->customExtCount++;
1469
#else
1470
        WOLFSSL_MSG("Unsupported extension to add");
1471
        return WOLFSSL_FAILURE;
1472
#endif /* WOLFSSL_CUSTOM_OID */
1473
        break;
1474
    }
1475
1476
    return WOLFSSL_SUCCESS;
1477
}
1478
1479
#ifndef NO_BIO
1480
/* Return 0 on success and 1 on failure. Copies ext data to bio, using indent
1481
 *  to pad the output. flag is ignored. */
1482
int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, WOLFSSL_X509_EXTENSION *ext,
1483
        unsigned long flag, int indent)
1484
{
1485
    ASN1_OBJECT* obj;
1486
    ASN1_STRING* str;
1487
    int nid;
1488
    int rc = WOLFSSL_FAILURE;
1489
    char tmp[CTC_NAME_SIZE*2 + 1];
1490
    const int tmpSz = sizeof(tmp);
1491
    int tmpLen = 0;
1492
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_print");
1493
1494
    if ((out == NULL) || (ext == NULL)) {
1495
        WOLFSSL_MSG("NULL parameter error");
1496
        return rc;
1497
    }
1498
1499
    obj = wolfSSL_X509_EXTENSION_get_object(ext);
1500
    if (obj == NULL) {
1501
        WOLFSSL_MSG("Error getting ASN1_OBJECT from X509_EXTENSION");
1502
        return rc;
1503
    }
1504
1505
    str = wolfSSL_X509_EXTENSION_get_data(ext);
1506
    if (str == NULL) {
1507
        WOLFSSL_MSG("Error getting ASN1_STRING from X509_EXTENSION");
1508
        return rc;
1509
    }
1510
1511
    /* Print extension based on the type */
1512
    nid = wolfSSL_OBJ_obj2nid(obj);
1513
    switch (nid) {
1514
        case BASIC_CA_OID:
1515
        {
1516
            char isCa[] = "TRUE";
1517
            char notCa[] = "FALSE";
1518
            if ((tmpLen = XSNPRINTF(tmp, tmpSz, "%*sCA:%s", indent, "",
1519
                                     obj->ca ? isCa : notCa))
1520
                >= tmpSz)
1521
                return rc;
1522
            break;
1523
        }
1524
        case ALT_NAMES_OID:
1525
        {
1526
            WOLFSSL_STACK* sk;
1527
            char* val;
1528
            int valLen;
1529
            int len;
1530
1531
            sk = ext->ext_sk;
1532
            while (sk != NULL) {
1533
                if (sk->type == STACK_TYPE_GEN_NAME && sk->data.gn) {
1534
                    /* str is GENERAL_NAME for subject alternative name ext */
1535
                    str = sk->data.gn->d.ia5;
1536
                    len = str->length + 2; /* + 2 for NULL char and "," */
1537
                    if (len > tmpSz) {
1538
                        WOLFSSL_MSG("len greater than buffer size");
1539
                        return rc;
1540
                    }
1541
1542
                    val = (char*)XMALLOC(len + indent, NULL,
1543
                                                       DYNAMIC_TYPE_TMP_BUFFER);
1544
                    if (val == NULL) {
1545
                        WOLFSSL_MSG("Memory error");
1546
                        return rc;
1547
                    }
1548
                    if (sk->next) {
1549
                        if ((valLen = XSNPRINTF(val, len, "%*s%s,",
1550
                                      indent, "", str->strData))
1551
                            >= len) {
1552
                            XFREE(val, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1553
                            return rc;
1554
                        }
1555
                    } else {
1556
                        if ((valLen = XSNPRINTF(val, len, "%*s%s",
1557
                                      indent, "", str->strData))
1558
                            >= len) {
1559
                            XFREE(val, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1560
                            return rc;
1561
                        }
1562
                    }
1563
                    if ((tmpLen + valLen) >= tmpSz) {
1564
                        XFREE(val, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1565
                        return rc;
1566
                    }
1567
                    XMEMCPY(tmp + tmpLen, val, valLen);
1568
                    tmpLen += valLen;
1569
                    XFREE(val, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1570
                }
1571
                sk = sk->next;
1572
            }
1573
            break;
1574
        }
1575
        case AUTH_KEY_OID:
1576
        case SUBJ_KEY_OID:
1577
        {
1578
            char* asn1str;
1579
            asn1str = wolfSSL_i2s_ASN1_STRING(NULL, str);
1580
            tmpLen = XSNPRINTF(tmp, tmpSz, "%*s%s", indent, "", asn1str);
1581
            XFREE(asn1str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1582
            if (tmpLen >= tmpSz) return rc;
1583
            break;
1584
        }
1585
        case AUTH_INFO_OID:
1586
        case CERT_POLICY_OID:
1587
        case CRL_DIST_OID:
1588
        case KEY_USAGE_OID:
1589
            WOLFSSL_MSG("X509V3_EXT_print not yet implemented for ext type");
1590
            break;
1591
1592
        default:
1593
            if ((tmpLen = XSNPRINTF(
1594
                     tmp, tmpSz, "%*s%s", indent, "", str->strData))
1595
                >= tmpSz)
1596
                return rc;
1597
    }
1598
1599
    if (wolfSSL_BIO_write(out, tmp, tmpLen) == tmpLen) {
1600
        rc = WOLFSSL_SUCCESS;
1601
    }
1602
    (void) flag;
1603
1604
    return rc;
1605
}
1606
#endif /* !NO_BIO */
1607
1608
#ifndef NO_WOLFSSL_STUB
1609
int wolfSSL_X509V3_EXT_add_nconf(WOLFSSL_CONF *conf, WOLFSSL_X509V3_CTX *ctx,
1610
        const char *section, WOLFSSL_X509 *cert)
1611
{
1612
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_add_nconf");
1613
    WOLFSSL_STUB("wolfSSL_X509V3_EXT_add_nconf");
1614
    (void)conf;
1615
    (void)ctx;
1616
    (void)section;
1617
    (void)cert;
1618
    return WOLFSSL_SUCCESS;
1619
}
1620
#endif
1621
1622
/* Returns crit flag in X509_EXTENSION object */
1623
int wolfSSL_X509_EXTENSION_get_critical(const WOLFSSL_X509_EXTENSION* ex)
1624
{
1625
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_get_critical");
1626
    if (ex == NULL)
1627
        return BAD_FUNC_ARG;
1628
    return ex->crit;
1629
}
1630
1631
/* Sets if the extension is critical
1632
 * returns WOLFSSL_SUCCESS on success
1633
 */
1634
int wolfSSL_X509_EXTENSION_set_critical(WOLFSSL_X509_EXTENSION* ex, int crit)
1635
{
1636
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_set_critical");
1637
    if (ex == NULL)
1638
        return WOLFSSL_FAILURE;
1639
    ex->crit = crit;
1640
    return WOLFSSL_SUCCESS;
1641
}
1642
1643
/* Creates v3_ext_method for a given X509v3 extension
1644
 *
1645
 * ex   : The X509_EXTENSION used to create v3_ext_method. If the extension is
1646
 * not NULL, get the NID of the extension object and populate the
1647
 * extension type-specific X509V3_EXT_* function(s) in v3_ext_method.
1648
 *
1649
 * Returns NULL on error or pointer to the v3_ext_method populated with extension
1650
 * type-specific X509V3_EXT_* function(s).
1651
 *
1652
 * NOTE: NID_subject_key_identifier is currently the only extension implementing
1653
 * the X509V3_EXT_* functions, as it is the only type called directly by QT. The
1654
 * other extension types return a pointer to a v3_ext_method struct that contains
1655
 * only the NID.
1656
 */
1657
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
1658
const WOLFSSL_v3_ext_method* wolfSSL_X509V3_EXT_get(WOLFSSL_X509_EXTENSION* ex)
1659
#else
1660
WOLFSSL_v3_ext_method* wolfSSL_X509V3_EXT_get(WOLFSSL_X509_EXTENSION* ex)
1661
#endif
1662
{
1663
    int nid;
1664
    WOLFSSL_v3_ext_method method;
1665
1666
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_get");
1667
    if ((ex == NULL) || (ex->obj == NULL)) {
1668
        WOLFSSL_MSG("Passed an invalid X509_EXTENSION*");
1669
        return NULL;
1670
    }
1671
    /* Initialize method to 0 */
1672
    XMEMSET(&method, 0, sizeof(struct WOLFSSL_v3_ext_method));
1673
1674
    nid = ex->obj->nid;
1675
    if (nid <= 0) {
1676
        WOLFSSL_MSG("Failed to get nid from passed extension object");
1677
        return NULL;
1678
    }
1679
    XMEMSET(&method, 0, sizeof(WOLFSSL_v3_ext_method));
1680
    switch (nid) {
1681
        case NID_basic_constraints:
1682
            break;
1683
        case NID_subject_key_identifier:
1684
            method.i2s = (X509V3_EXT_I2S)wolfSSL_i2s_ASN1_STRING;
1685
            break;
1686
        case NID_subject_alt_name:
1687
            WOLFSSL_MSG("i2v function not yet implemented for Subject Alternative Name");
1688
            break;
1689
        case NID_key_usage:
1690
            WOLFSSL_MSG("i2v function not yet implemented for Key Usage");
1691
            break;
1692
        case NID_authority_key_identifier:
1693
            WOLFSSL_MSG("i2v function not yet implemented for Auth Key Id");
1694
            break;
1695
        case NID_info_access:
1696
            WOLFSSL_MSG("i2v function not yet implemented for Info Access");
1697
            break;
1698
        case NID_ext_key_usage:
1699
            WOLFSSL_MSG("i2v function not yet implemented for Ext Key Usage");
1700
            break;
1701
        case NID_certificate_policies:
1702
            WOLFSSL_MSG("r2i function not yet implemented for Cert Policies");
1703
            break;
1704
        case NID_crl_distribution_points:
1705
            WOLFSSL_MSG("r2i function not yet implemented for CRL Dist Points");
1706
            break;
1707
        default:
1708
            /* If extension type is unknown, return NULL -- QT makes call to
1709
                X509_EXTENSION_get_data() if there is no v3_ext_method */
1710
            WOLFSSL_MSG("X509V3_EXT_get(): Unknown extension type found");
1711
            return NULL;
1712
    }
1713
1714
    method.ext_nid = nid;
1715
    ex->ext_method = method;
1716
1717
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
1718
    return (const WOLFSSL_v3_ext_method*)&ex->ext_method;
1719
#else
1720
    return (WOLFSSL_v3_ext_method*)&ex->ext_method;
1721
#endif
1722
}
1723
1724
/* Create an Authority Info Access (AIA) from the contents of the extension.
1725
 *
1726
 * AIA is a stack of Access Descriptions.
1727
 *
1728
 * RFC 5280: 4.2.2.1
1729
 *
1730
 * @param [in] ext  X509v3 extension.
1731
 * @return  Stack of Access Descriptions as an AIA on success.
1732
 * @return  NULL on error.
1733
 */
1734
static WOLFSSL_AUTHORITY_INFO_ACCESS* wolfssl_x509v3_ext_aia_d2i(
1735
    WOLFSSL_X509_EXTENSION* ext)
1736
{
1737
    int err = 0;
1738
    int ret;
1739
    WOLFSSL_AUTHORITY_INFO_ACCESS* aia = NULL;
1740
    WOLFSSL_STACK* sk;
1741
    WOLFSSL_ACCESS_DESCRIPTION* ad = NULL;
1742
1743
    /* Get the type specific data of this extension. */
1744
    sk = ext->ext_sk;
1745
    if (sk == NULL) {
1746
        WOLFSSL_MSG("ACCESS_DESCRIPTION stack NULL");
1747
        err = 1;
1748
    }
1749
1750
    if (!err) {
1751
        /* AUTHORITY_INFO_ACCESS is a stack of ACCESS_DESCRIPTION entries. */
1752
        aia = wolfSSL_sk_new_null();
1753
        if (aia == NULL) {
1754
            WOLFSSL_MSG("Failed to malloc AUTHORITY_INFO_ACCESS");
1755
            err = 1;
1756
        }
1757
    }
1758
    if (!err) {
1759
        /* AIA is a stack of Access Descriptions. */
1760
        aia->type = STACK_TYPE_ACCESS_DESCRIPTION;
1761
    }
1762
1763
    while ((!err) && (sk != NULL)) {
1764
        WOLFSSL_ASN1_OBJECT* aiaEntry;
1765
1766
        /* Looking for objects in extension's data. */
1767
        if (sk->type != STACK_TYPE_OBJ) {
1768
            sk = sk->next;
1769
            continue;
1770
        }
1771
1772
        /* Get ASN.1 Object from the stack entry's data. */
1773
        aiaEntry = sk->data.obj;
1774
1775
        /* ACCESS_DESCRIPTION has two members: method and location.
1776
         *  method: ASN1_OBJECT as either AIA_OCSP_OID or AIA_CA_ISSUER_OID
1777
         *  location: GENERAL_NAME structure containing the URI.
1778
         */
1779
1780
        /* Allocate a new Access Description. */
1781
        ad = (WOLFSSL_ACCESS_DESCRIPTION*)XMALLOC(
1782
            sizeof(WOLFSSL_ACCESS_DESCRIPTION), NULL, DYNAMIC_TYPE_X509_EXT);
1783
        if (ad == NULL) {
1784
            WOLFSSL_MSG("Failed to malloc ACCESS_DESCRIPTION");
1785
            err = 1;
1786
            break;
1787
        }
1788
        XMEMSET(ad, 0, sizeof(WOLFSSL_ACCESS_DESCRIPTION));
1789
1790
        /* Create new ASN1_OBJECT from NID. */
1791
        ad->method = wolfSSL_OBJ_nid2obj(aiaEntry->nid);
1792
        if (ad->method == NULL) {
1793
            WOLFSSL_MSG("OBJ_nid2obj() failed");
1794
            err = 1;
1795
            break;
1796
        }
1797
1798
        /* Allocate memory for GENERAL NAME. */
1799
        ad->location = wolfSSL_GENERAL_NAME_new();
1800
        if (ad->location == NULL) {
1801
            WOLFSSL_MSG("Failed to malloc GENERAL_NAME");
1802
            err = 1;
1803
            break;
1804
        }
1805
1806
        /* Set the type of general name to URI (only type supported). */
1807
        ret = wolfSSL_GENERAL_NAME_set_type(ad->location, GEN_URI);
1808
        if (ret != WOLFSSL_SUCCESS) {
1809
            err = 1;
1810
            break;
1811
        }
1812
1813
        /* Set the URI into GENERAL_NAME. */
1814
        ret = wolfSSL_ASN1_STRING_set(ad->location->d.uniformResourceIdentifier,
1815
            aiaEntry->obj, aiaEntry->objSz);
1816
        if (ret != WOLFSSL_SUCCESS) {
1817
            WOLFSSL_MSG("ASN1_STRING_set() failed");
1818
            err = 1;
1819
            break;
1820
        }
1821
        /* Push onto AUTHORITY_INFO_ACCESS stack. */
1822
        ret = wolfSSL_sk_ACCESS_DESCRIPTION_push(aia, ad);
1823
        if (ret != WOLFSSL_SUCCESS) {
1824
            WOLFSSL_MSG("Error pushing ASN1 AD onto stack");
1825
            err = 1;
1826
            break;
1827
        }
1828
        /* Set to NULL so that it doesn't get freed now it is in AIA stack. */
1829
        ad = NULL;
1830
1831
        sk = sk->next;
1832
    }
1833
1834
    if (err) {
1835
        /* Dispose of Access Description if not put in stack. */
1836
        if (ad != NULL) {
1837
            wolfSSL_ASN1_OBJECT_free(ad->method);
1838
            wolfSSL_GENERAL_NAME_free(ad->location);
1839
            XFREE(ad, NULL, DYNAMIC_TYPE_X509_EXT);
1840
        }
1841
        /* Dispose of incomplete Access Description stack. */
1842
        wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(aia, NULL);
1843
        aia = NULL;
1844
    }
1845
    return aia;
1846
}
1847
1848
/* Parses and returns an x509v3 extension internal structure.
1849
 *
1850
 * ext   : The X509_EXTENSION for parsing internal structure. If extension is
1851
 * not NULL, get the NID of the extension object and create a new
1852
 * extension-specific internal structure based on the extension type.
1853
 *
1854
 * Returns NULL on error or if NID is not found, otherwise returns a pointer to
1855
 * the extension type-specific X509_EXTENSION internal structure.
1856
 * Return is expected to be free'd by caller.
1857
 */
1858
void* wolfSSL_X509V3_EXT_d2i(WOLFSSL_X509_EXTENSION* ext)
1859
{
1860
    const WOLFSSL_v3_ext_method* method;
1861
    int ret;
1862
    WOLFSSL_ASN1_OBJECT* object;
1863
    WOLFSSL_BASIC_CONSTRAINTS* bc;
1864
    WOLFSSL_AUTHORITY_KEYID* akey;
1865
    WOLFSSL_ASN1_STRING* asn1String, *newString;
1866
    WOLFSSL_STACK* sk;
1867
1868
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_d2i");
1869
1870
    if(ext == NULL) {
1871
        WOLFSSL_MSG("Bad function Argument");
1872
        return NULL;
1873
    }
1874
1875
    /* extract extension info */
1876
    method = wolfSSL_X509V3_EXT_get(ext);
1877
    if (method == NULL) {
1878
        WOLFSSL_MSG("wolfSSL_X509V3_EXT_get error");
1879
        return NULL;
1880
    }
1881
    object = wolfSSL_X509_EXTENSION_get_object(ext);
1882
    if (object == NULL) {
1883
        WOLFSSL_MSG("X509_EXTENSION_get_object failed");
1884
        return NULL;
1885
    }
1886
1887
    /* Return pointer to proper internal structure based on NID */
1888
    switch (object->type) {
1889
        /* basicConstraints */
1890
        case (NID_basic_constraints):
1891
            WOLFSSL_MSG("basicConstraints");
1892
            /* Allocate new BASIC_CONSTRAINTS structure */
1893
            bc = wolfSSL_BASIC_CONSTRAINTS_new();
1894
            if (bc == NULL) {
1895
                WOLFSSL_MSG("Failed to malloc basic constraints");
1896
                return NULL;
1897
            }
1898
            /* Copy pathlen and CA into BASIC_CONSTRAINTS from object */
1899
            bc->ca = object->ca;
1900
            if (object->pathlen->length > 0) {
1901
                bc->pathlen = wolfSSL_ASN1_INTEGER_dup(object->pathlen);
1902
                if (bc->pathlen == NULL) {
1903
                    WOLFSSL_MSG("Failed to duplicate ASN1_INTEGER");
1904
                    wolfSSL_BASIC_CONSTRAINTS_free(bc);
1905
                    return NULL;
1906
                }
1907
            }
1908
            else
1909
                bc->pathlen = NULL;
1910
            return bc;
1911
1912
        /* subjectKeyIdentifier */
1913
        case (NID_subject_key_identifier):
1914
            WOLFSSL_MSG("subjectKeyIdentifier");
1915
            asn1String = wolfSSL_X509_EXTENSION_get_data(ext);
1916
            if (asn1String == NULL) {
1917
                WOLFSSL_MSG("X509_EXTENSION_get_data() failed");
1918
                return NULL;
1919
            }
1920
            newString = wolfSSL_ASN1_STRING_new();
1921
            if (newString == NULL) {
1922
                WOLFSSL_MSG("Failed to malloc ASN1_STRING");
1923
                return NULL;
1924
            }
1925
            ret = wolfSSL_ASN1_STRING_set(newString, asn1String->data,
1926
                                                            asn1String->length);
1927
            if (ret != WOLFSSL_SUCCESS) {
1928
                WOLFSSL_MSG("ASN1_STRING_set() failed");
1929
                wolfSSL_ASN1_STRING_free(newString);
1930
                return NULL;
1931
            };
1932
            newString->type = asn1String->type;
1933
            return newString;
1934
1935
        /* authorityKeyIdentifier */
1936
        case (NID_authority_key_identifier):
1937
            WOLFSSL_MSG("AuthorityKeyIdentifier");
1938
1939
            akey = (WOLFSSL_AUTHORITY_KEYID*)
1940
                    XMALLOC(sizeof(WOLFSSL_AUTHORITY_KEYID), NULL,
1941
                    DYNAMIC_TYPE_X509_EXT);
1942
            if (akey == NULL) {
1943
                WOLFSSL_MSG("Failed to malloc authority key id");
1944
                return NULL;
1945
            }
1946
1947
            XMEMSET(akey, 0, sizeof(WOLFSSL_AUTHORITY_KEYID));
1948
1949
            akey->keyid = wolfSSL_ASN1_STRING_new();
1950
            if (akey->keyid == NULL) {
1951
                WOLFSSL_MSG("ASN1_STRING_new() failed");
1952
                wolfSSL_AUTHORITY_KEYID_free(akey);
1953
                return NULL;
1954
            }
1955
1956
            asn1String = wolfSSL_X509_EXTENSION_get_data(ext);
1957
            if (asn1String == NULL) {
1958
                WOLFSSL_MSG("X509_EXTENSION_get_data() failed");
1959
                wolfSSL_AUTHORITY_KEYID_free(akey);
1960
                return NULL;
1961
            }
1962
1963
            ret = wolfSSL_ASN1_STRING_set(akey->keyid, asn1String->data,
1964
                                                            asn1String->length);
1965
            if (ret != WOLFSSL_SUCCESS) {
1966
                WOLFSSL_MSG("ASN1_STRING_set() failed");
1967
                wolfSSL_AUTHORITY_KEYID_free(akey);
1968
                return NULL;
1969
            };
1970
            akey->keyid->type   = asn1String->type;
1971
1972
            /* For now, set issuer and serial to NULL. This may need to be
1973
                updated for future use */
1974
            akey->issuer = NULL;
1975
            akey->serial = NULL;
1976
            return akey;
1977
1978
        /* keyUsage */
1979
        case (NID_key_usage):
1980
            WOLFSSL_MSG("keyUsage");
1981
            /* This may need to be updated for future use. The i2v method for
1982
                keyUsage is not currently set. For now, return the ASN1_STRING
1983
                representation of KeyUsage bit string */
1984
            asn1String = wolfSSL_X509_EXTENSION_get_data(ext);
1985
            if (asn1String == NULL) {
1986
                WOLFSSL_MSG("X509_EXTENSION_get_data() failed");
1987
                return NULL;
1988
            }
1989
            newString = wolfSSL_ASN1_STRING_new();
1990
            if (newString == NULL) {
1991
                WOLFSSL_MSG("Failed to malloc ASN1_STRING");
1992
                return NULL;
1993
            }
1994
            ret = wolfSSL_ASN1_STRING_set(newString, asn1String->data,
1995
                                                            asn1String->length);
1996
            if (ret != WOLFSSL_SUCCESS) {
1997
                WOLFSSL_MSG("ASN1_STRING_set() failed");
1998
                wolfSSL_ASN1_STRING_free(newString);
1999
                return NULL;
2000
            };
2001
            newString->type = asn1String->type;
2002
            return newString;
2003
2004
        /* extKeyUsage */
2005
        case (NID_ext_key_usage):
2006
            WOLFSSL_MSG("extKeyUsage not supported yet");
2007
            return NULL;
2008
2009
        /* certificatePolicies */
2010
        case (NID_certificate_policies):
2011
            WOLFSSL_MSG("certificatePolicies not supported yet");
2012
            return NULL;
2013
2014
        /* cRLDistributionPoints */
2015
        case (NID_crl_distribution_points):
2016
            WOLFSSL_MSG("cRLDistributionPoints not supported yet");
2017
            return NULL;
2018
2019
        case NID_subject_alt_name:
2020
            if (ext->ext_sk == NULL) {
2021
                WOLFSSL_MSG("Subject alt name stack NULL");
2022
                return NULL;
2023
            }
2024
            sk = wolfSSL_sk_dup(ext->ext_sk);
2025
            if (sk == NULL) {
2026
                WOLFSSL_MSG("Failed to duplicate subject alt names stack.");
2027
                return NULL;
2028
            }
2029
            return sk;
2030
2031
        /* authorityInfoAccess */
2032
        case NID_info_access:
2033
            WOLFSSL_MSG("AuthorityInfoAccess");
2034
            return wolfssl_x509v3_ext_aia_d2i(ext);
2035
2036
        default:
2037
            WOLFSSL_MSG("Extension NID not in table, returning NULL");
2038
            break;
2039
    }
2040
    return NULL;
2041
}
2042
2043
/* Looks for the extension matching the passed in nid
2044
 *
2045
 * x509 : certificate to get parse through for extension.
2046
 * nid : Extension OID to be found.
2047
 * lastPos : Start search from extension after lastPos.
2048
 *           Set to -1 to search from index 0.
2049
 * return >= 0 If successful the extension index is returned.
2050
 * return -1 If extension is not found or error is encountered.
2051
 */
2052
int wolfSSL_X509_get_ext_by_NID(const WOLFSSL_X509* x509, int nid, int lastPos)
2053
{
2054
    int extCount = 0, length = 0, outSz = 0, sz = 0, ret = 0;
2055
    int isSet = 0, found = 0, loc;
2056
    const byte* rawCert;
2057
    const byte* input;
2058
    word32 oid, idx = 0, tmpIdx = 0, foundNID;
2059
#ifdef WOLFSSL_SMALL_STACK
2060
    DecodedCert *cert;
2061
#else
2062
    DecodedCert cert[1];
2063
#endif
2064
2065
    WOLFSSL_ENTER("wolfSSL_X509_get_ext_by_NID");
2066
2067
    if(x509 == NULL){
2068
        WOLFSSL_MSG("\tNot passed a certificate");
2069
        return WOLFSSL_FATAL_ERROR;
2070
    }
2071
2072
    if(lastPos < -1 || (lastPos > (wolfSSL_X509_get_ext_count(x509) - 1))){
2073
        WOLFSSL_MSG("\tBad location argument");
2074
        return WOLFSSL_FATAL_ERROR;
2075
    }
2076
2077
    loc = lastPos + 1;
2078
2079
    rawCert = wolfSSL_X509_get_der((WOLFSSL_X509*)x509, &outSz);
2080
    if (rawCert == NULL) {
2081
        WOLFSSL_MSG("\tX509_get_der() failed");
2082
        return WOLFSSL_FATAL_ERROR;
2083
    }
2084
2085
#ifdef WOLFSSL_SMALL_STACK
2086
    cert = (DecodedCert *)XMALLOC(sizeof(*cert), x509->heap,
2087
                                  DYNAMIC_TYPE_DCERT);
2088
    if (cert == NULL) {
2089
        WOLFSSL_MSG("\tout of memory");
2090
        return WOLFSSL_FATAL_ERROR;
2091
    }
2092
#endif
2093
2094
    InitDecodedCert( cert, rawCert, (word32)outSz, 0);
2095
2096
    if (ParseCert(cert,
2097
#ifdef WOLFSSL_CERT_REQ
2098
            x509->isCSR ? CERTREQ_TYPE :
2099
#endif
2100
            CA_TYPE,
2101
            NO_VERIFY, NULL) < 0) {
2102
        WOLFSSL_MSG("\tCertificate parsing failed");
2103
        goto out;
2104
    }
2105
2106
    input = cert->extensions;
2107
    sz = cert->extensionsSz;
2108
2109
    if (input == NULL || sz == 0) {
2110
        WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
2111
        goto out;
2112
    }
2113
2114
#ifdef WOLFSSL_CERT_REQ
2115
    if (!x509->isCSR)
2116
#endif
2117
    {
2118
        if (input[idx++] != ASN_EXTENSIONS) {
2119
            WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
2120
            goto out;
2121
        }
2122
2123
        if (GetLength(input, &idx, &length, sz) < 0) {
2124
            WOLFSSL_MSG("\tfail: invalid length");
2125
            goto out;
2126
        }
2127
    }
2128
2129
    if (GetSequence(input, &idx, &length, sz) < 0) {
2130
        WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
2131
        goto out;
2132
    }
2133
2134
    while (idx < (word32)sz) {
2135
        oid = 0;
2136
2137
        if (GetSequence(input, &idx, &length, sz) < 0) {
2138
            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
2139
            goto out;
2140
        }
2141
2142
        tmpIdx = idx;
2143
        ret = GetObjectId(input, &idx, &oid, oidCertExtType, sz);
2144
        if (ret < 0) {
2145
            WOLFSSL_MSG("\tfail: OBJECT ID");
2146
            goto out;
2147
        }
2148
        idx = tmpIdx;
2149
        foundNID = (word32)oid2nid(oid, oidCertExtType);
2150
2151
        if (extCount >= loc) {
2152
            /* extCount >= loc. Now check if extension has been set */
2153
            isSet = wolfSSL_X509_ext_isSet_by_NID((WOLFSSL_X509*)x509, foundNID);
2154
2155
            if (isSet && ((word32)nid == foundNID)) {
2156
                found = 1;
2157
                break;
2158
            }
2159
        }
2160
2161
        idx += length;
2162
        extCount++;
2163
    } /* while(idx < sz) */
2164
2165
out:
2166
2167
    FreeDecodedCert(cert);
2168
#ifdef WOLFSSL_SMALL_STACK
2169
    XFREE(cert, x509->heap, DYNAMIC_TYPE_DCERT);
2170
#endif
2171
2172
    return found ? extCount : WOLFSSL_FATAL_ERROR;
2173
}
2174
2175
#endif /* OPENSSL_ALL || OPENSSL_EXTRA */
2176
2177
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
2178
/* Looks for the extension matching the passed in nid
2179
 *
2180
 * c   : if not null then is set to status value -2 if multiple occurrences
2181
 *       of the extension are found, -1 if not found, 0 if found and not
2182
 *       critical, and 1 if found and critical.
2183
 * nid : Extension OID to be found.
2184
 * idx : if NULL return first extension found match, otherwise start search at
2185
 *       idx location and set idx to the location of extension returned.
2186
 * returns NULL or a pointer to an WOLFSSL_ASN1_BIT_STRING (for KEY_USAGE_OID)
2187
 * or WOLFSSL_STACK (for other)
2188
 * holding extension structure
2189
 *
2190
 * NOTE code for decoding extensions is in asn.c DecodeCertExtensions --
2191
 * use already decoded extension in this function to avoid decoding twice.
2192
 * Currently we do not make use of idx since getting pre decoded extensions.
2193
 */
2194
void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c,
2195
    int* idx)
2196
{
2197
    void* ret = NULL;
2198
    WOLFSSL_STACK* sk = NULL;
2199
    WOLFSSL_ASN1_OBJECT* obj = NULL;
2200
    WOLFSSL_GENERAL_NAME* gn = NULL;
2201
#ifdef OPENSSL_EXTRA
2202
    WOLFSSL_DIST_POINT* dp = NULL;
2203
#endif
2204
    WOLFSSL_BASIC_CONSTRAINTS* bc = NULL;
2205
2206
    WOLFSSL_ENTER("wolfSSL_X509_get_ext_d2i");
2207
2208
    if (x509 == NULL) {
2209
        return NULL;
2210
    }
2211
2212
    if (c != NULL) {
2213
        *c = -1; /* default to not found */
2214
    }
2215
2216
    switch (nid) {
2217
        case BASIC_CA_OID:
2218
            if (x509->basicConstSet) {
2219
                WOLFSSL_ASN1_INTEGER* a;
2220
2221
                bc = wolfSSL_BASIC_CONSTRAINTS_new();
2222
                if (!bc) {
2223
                    WOLFSSL_MSG("wolfSSL_BASIC_CONSTRAINTS_new error");
2224
                    return NULL;
2225
                }
2226
2227
                a = wolfSSL_ASN1_INTEGER_new();
2228
                if (!a) {
2229
                    WOLFSSL_MSG("wolfSSL_ASN1_INTEGER_new error");
2230
                    wolfSSL_BASIC_CONSTRAINTS_free(bc);
2231
                    return NULL;
2232
                }
2233
                a->length = x509->pathLength;
2234
2235
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) || \
2236
        defined(WOLFSSL_APACHE_HTTPD)
2237
                bc->ca = x509->isCa;
2238
#endif
2239
                bc->pathlen = a;
2240
                if (c != NULL) {
2241
                    *c = x509->basicConstCrit;
2242
                }
2243
            }
2244
            else {
2245
                WOLFSSL_MSG("No Basic Constraint set");
2246
            }
2247
            return bc;
2248
2249
        case ALT_NAMES_OID:
2250
        {
2251
            DNS_entry* dns = NULL;
2252
2253
            if (x509->subjAltNameSet && x509->altNames != NULL) {
2254
                /* Malloc GENERAL_NAME stack */
2255
                sk = wolfSSL_sk_new_null();
2256
                if (sk == NULL)
2257
                    return NULL;
2258
                sk->type = STACK_TYPE_GEN_NAME;
2259
2260
                /* alt names are DNS_entry structs */
2261
                if (c != NULL) {
2262
                    if (x509->altNames->next != NULL) {
2263
                        *c = -2; /* more then one found */
2264
                    }
2265
                    else {
2266
                        *c = x509->subjAltNameCrit;
2267
                    }
2268
                }
2269
2270
                dns = x509->altNames;
2271
                /* Currently only support GEN_DNS type */
2272
                while (dns != NULL) {
2273
                    gn = wolfSSL_GENERAL_NAME_new();
2274
                    if (gn == NULL) {
2275
                        WOLFSSL_MSG("Error creating GENERAL_NAME");
2276
                        goto err;
2277
                    }
2278
2279
                    gn->type = dns->type;
2280
                    switch (gn->type) {
2281
                        case ASN_DIR_TYPE:
2282
                            {
2283
                                int localIdx = 0;
2284
                                unsigned char* n = (unsigned char*)XMALLOC(
2285
                                        dns->len + MAX_SEQ_SZ, x509->heap,
2286
                                        DYNAMIC_TYPE_TMP_BUFFER);
2287
                                if (n == NULL) {
2288
                                    goto err;
2289
                                }
2290
2291
                                localIdx += SetSequence(dns->len, n);
2292
                                XMEMCPY(n + localIdx, dns->name, dns->len);
2293
                                gn->d.dirn =  wolfSSL_d2i_X509_NAME(NULL, &n,
2294
                                        dns->len + localIdx);
2295
                                XFREE(n, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
2296
                                if (gn->d.dirn == NULL) {
2297
                                    WOLFSSL_MSG("Convert altDirName to X509 "
2298
                                            "NAME failed");
2299
                                    goto err;
2300
                                }
2301
                            }
2302
                            break;
2303
2304
                        case ASN_OTHER_TYPE:
2305
                            if (!wolfssl_dns_entry_othername_to_gn(dns, gn)) {
2306
                                goto err;
2307
                            }
2308
                            break;
2309
2310
                        default:
2311
                            if (wolfSSL_ASN1_STRING_set(gn->d.dNSName,
2312
                                    dns->name, dns->len) != WOLFSSL_SUCCESS) {
2313
                                WOLFSSL_MSG("ASN1_STRING_set failed");
2314
                                goto err;
2315
                            }
2316
                            gn->d.dNSName->type = V_ASN1_IA5STRING;
2317
                    }
2318
2319
                    dns = dns->next;
2320
                    if (wolfSSL_sk_GENERAL_NAME_push(sk, gn) !=
2321
                                                      WOLFSSL_SUCCESS) {
2322
                        WOLFSSL_MSG("Error pushing ASN1 object onto stack");
2323
                        goto err;
2324
                    }
2325
                    /* null so that it doesn't get pushed again after switch */
2326
                    gn = NULL;
2327
                }
2328
            }
2329
            else {
2330
                WOLFSSL_MSG("No Alt Names set");
2331
            }
2332
2333
            break;
2334
        }
2335
2336
        case CRL_DIST_OID:
2337
    #if defined(OPENSSL_EXTRA)
2338
            if (x509->CRLdistSet && x509->CRLInfo != NULL) {
2339
                if (c != NULL) {
2340
                    *c = x509->CRLdistCrit;
2341
                }
2342
2343
                sk = wolfSSL_sk_new_null();
2344
                if (sk == NULL) {
2345
                    return NULL;
2346
                }
2347
                sk->type = STACK_TYPE_DIST_POINT;
2348
2349
                gn = wolfSSL_GENERAL_NAME_new();
2350
                if (gn == NULL) {
2351
                    WOLFSSL_MSG("Error creating GENERAL_NAME");
2352
                    goto err;
2353
                }
2354
2355
                if (wolfSSL_GENERAL_NAME_set_type(gn, GEN_URI) !=
2356
                        WOLFSSL_SUCCESS) {
2357
                    WOLFSSL_MSG("Error setting GENERAL_NAME type");
2358
                    goto err;
2359
                }
2360
2361
                if (wolfSSL_ASN1_STRING_set(gn->d.uniformResourceIdentifier,
2362
                        x509->CRLInfo, x509->CRLInfoSz) != WOLFSSL_SUCCESS) {
2363
                    WOLFSSL_MSG("ASN1_STRING_set failed");
2364
                    goto err;
2365
                }
2366
2367
                /* wolfSSL only decodes one dist point */
2368
                dp = wolfSSL_DIST_POINT_new();
2369
                if (dp == NULL) {
2370
                    WOLFSSL_MSG("Error creating DIST_POINT");
2371
                    goto err;
2372
                }
2373
2374
                /* push GENERAL_NAME onto fullname stack */
2375
                if (wolfSSL_sk_GENERAL_NAME_push(dp->distpoint->name.fullname,
2376
                                                 gn) != WOLFSSL_SUCCESS) {
2377
                    WOLFSSL_MSG("wolfSSL_sk_GENERAL_NAME_push error");
2378
                    goto err;
2379
                }
2380
2381
                /* push DIST_POINT onto stack */
2382
                if (wolfSSL_sk_DIST_POINT_push(sk, dp) != WOLFSSL_SUCCESS) {
2383
                    WOLFSSL_MSG("Error pushing DIST_POINT onto stack");
2384
                    goto err;
2385
                }
2386
2387
                gn = NULL;
2388
                dp = NULL;
2389
2390
            }
2391
            else {
2392
                WOLFSSL_MSG("No CRL dist set");
2393
            }
2394
    #endif /* OPENSSL_EXTRA */
2395
            break;
2396
2397
        case AUTH_INFO_OID:
2398
            if (x509->authInfoSet && x509->authInfo != NULL) {
2399
                if (c != NULL) {
2400
                    *c = x509->authInfoCrit;
2401
                }
2402
                obj = wolfSSL_ASN1_OBJECT_new();
2403
                if (obj == NULL) {
2404
                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
2405
                    return NULL;
2406
                }
2407
                obj->type  = AUTH_INFO_OID;
2408
                obj->grp   = oidCertExtType;
2409
                obj->obj   = x509->authInfo;
2410
                obj->objSz = x509->authInfoSz;
2411
            }
2412
            else {
2413
                WOLFSSL_MSG("No Auth Info set");
2414
            }
2415
            break;
2416
2417
        case AUTH_KEY_OID:
2418
            if (x509->authKeyIdSet) {
2419
                WOLFSSL_AUTHORITY_KEYID* akey = wolfSSL_AUTHORITY_KEYID_new();
2420
                if (!akey) {
2421
                    WOLFSSL_MSG("Issue creating WOLFSSL_AUTHORITY_KEYID struct");
2422
                    return NULL;
2423
                }
2424
2425
                if (c != NULL) {
2426
                    *c = x509->authKeyIdCrit;
2427
                }
2428
                obj = wolfSSL_ASN1_OBJECT_new();
2429
                if (obj == NULL) {
2430
                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
2431
                    wolfSSL_AUTHORITY_KEYID_free(akey);
2432
                    return NULL;
2433
                }
2434
                obj->type  = AUTH_KEY_OID;
2435
                obj->grp   = oidCertExtType;
2436
                obj->obj   = x509->authKeyId;
2437
                obj->objSz = x509->authKeyIdSz;
2438
                akey->issuer = obj;
2439
                return akey;
2440
            }
2441
            else {
2442
                WOLFSSL_MSG("No Auth Key set");
2443
            }
2444
            break;
2445
2446
        case SUBJ_KEY_OID:
2447
            if (x509->subjKeyIdSet) {
2448
                if (c != NULL) {
2449
                    *c = x509->subjKeyIdCrit;
2450
                }
2451
                obj = wolfSSL_ASN1_OBJECT_new();
2452
                if (obj == NULL) {
2453
                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
2454
                    return NULL;
2455
                }
2456
                obj->type  = SUBJ_KEY_OID;
2457
                obj->grp   = oidCertExtType;
2458
                obj->obj   = x509->subjKeyId;
2459
                obj->objSz = x509->subjKeyIdSz;
2460
            }
2461
            else {
2462
                WOLFSSL_MSG("No Subject Key set");
2463
            }
2464
            break;
2465
2466
        case CERT_POLICY_OID:
2467
        {
2468
        #ifdef WOLFSSL_CERT_EXT
2469
            int i;
2470
2471
            if (x509->certPoliciesNb > 0) {
2472
                if (c != NULL) {
2473
                    if (x509->certPoliciesNb > 1) {
2474
                        *c = -2;
2475
                    }
2476
                    else {
2477
                        *c = 0;
2478
                    }
2479
                }
2480
2481
                sk = wolfSSL_sk_new_asn1_obj();
2482
                if (sk == NULL) {
2483
                    return NULL;
2484
                }
2485
2486
                for (i = 0; i < x509->certPoliciesNb - 1; i++) {
2487
                    obj = wolfSSL_ASN1_OBJECT_new();
2488
                    if (obj == NULL) {
2489
                        WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
2490
                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
2491
                        return NULL;
2492
                    }
2493
                    obj->type  = CERT_POLICY_OID;
2494
                    obj->grp   = oidCertExtType;
2495
                    obj->obj   = (byte*)(x509->certPolicies[i]);
2496
                    obj->objSz = MAX_CERTPOL_SZ;
2497
                    if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj)
2498
                                                           != WOLFSSL_SUCCESS) {
2499
                        WOLFSSL_MSG("Error pushing ASN1 object onto stack");
2500
                        wolfSSL_ASN1_OBJECT_free(obj);
2501
                        wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
2502
                        sk = NULL;
2503
                    }
2504
                }
2505
                obj = wolfSSL_ASN1_OBJECT_new();
2506
                if (obj == NULL) {
2507
                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
2508
                    wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL);
2509
                    return NULL;
2510
                }
2511
                obj->type  = CERT_POLICY_OID;
2512
                obj->grp   = oidCertExtType;
2513
                obj->obj   = (byte*)(x509->certPolicies[i]);
2514
                obj->objSz = MAX_CERTPOL_SZ;
2515
            }
2516
            else {
2517
                WOLFSSL_MSG("No Cert Policy set");
2518
            }
2519
        #elif defined(WOLFSSL_SEP)
2520
            if (x509->certPolicySet) {
2521
                if (c != NULL) {
2522
                    *c = x509->certPolicyCrit;
2523
                }
2524
                obj = wolfSSL_ASN1_OBJECT_new();
2525
                if (obj == NULL) {
2526
                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
2527
                    return NULL;
2528
                }
2529
                obj->type  = CERT_POLICY_OID;
2530
                obj->grp   = oidCertExtType;
2531
            }
2532
            else {
2533
                WOLFSSL_MSG("No Cert Policy set");
2534
            }
2535
        #else
2536
            WOLFSSL_MSG("wolfSSL not built with WOLFSSL_SEP or WOLFSSL_CERT_EXT");
2537
        #endif
2538
            break;
2539
        }
2540
        case KEY_USAGE_OID:
2541
        {
2542
            WOLFSSL_ASN1_STRING* asn1str = NULL;
2543
            if (x509->keyUsageSet) {
2544
                if (c != NULL) {
2545
                    *c = x509->keyUsageCrit;
2546
                }
2547
2548
                asn1str = wolfSSL_ASN1_STRING_new();
2549
                if (asn1str == NULL) {
2550
                    WOLFSSL_MSG("Failed to malloc ASN1_STRING");
2551
                    return NULL;
2552
                }
2553
2554
                if (wolfSSL_ASN1_STRING_set(asn1str, &x509->keyUsage,
2555
                        sizeof(word16)) != WOLFSSL_SUCCESS) {
2556
                    WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
2557
                    wolfSSL_ASN1_STRING_free(asn1str);
2558
                    return NULL;
2559
                }
2560
2561
                asn1str->type = KEY_USAGE_OID;
2562
            }
2563
            else {
2564
                WOLFSSL_MSG("No Key Usage set");
2565
            }
2566
            /* don't add stack of and return bit string directly */
2567
            return asn1str;
2568
        }
2569
        case INHIBIT_ANY_OID:
2570
            WOLFSSL_MSG("INHIBIT ANY extension not supported");
2571
            break;
2572
2573
        case EXT_KEY_USAGE_OID:
2574
            if (x509->extKeyUsageSrc != NULL) {
2575
                if (c != NULL) {
2576
                    if (x509->extKeyUsageCount > 1) {
2577
                        *c = -2;
2578
                    }
2579
                    else {
2580
                        *c = x509->extKeyUsageCrit;
2581
                    }
2582
                }
2583
                obj = wolfSSL_ASN1_OBJECT_new();
2584
                if (obj == NULL) {
2585
                    WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
2586
                    return NULL;
2587
                }
2588
                obj->type  = EXT_KEY_USAGE_OID;
2589
                obj->grp   = oidCertExtType;
2590
                obj->obj   = x509->extKeyUsageSrc;
2591
                obj->objSz = x509->extKeyUsageSz;
2592
            }
2593
            else {
2594
                WOLFSSL_MSG("No Extended Key Usage set");
2595
            }
2596
            break;
2597
2598
        case NAME_CONS_OID:
2599
            WOLFSSL_MSG("Name Constraint OID extension not supported");
2600
            break;
2601
2602
        case PRIV_KEY_USAGE_PERIOD_OID:
2603
            WOLFSSL_MSG("Private Key Usage Period extension not supported");
2604
            break;
2605
2606
        case SUBJ_INFO_ACC_OID:
2607
            WOLFSSL_MSG("Subject Info Access extension not supported");
2608
            break;
2609
2610
        case POLICY_MAP_OID:
2611
            WOLFSSL_MSG("Policy Map extension not supported");
2612
            break;
2613
2614
        case POLICY_CONST_OID:
2615
            WOLFSSL_MSG("Policy Constraint extension not supported");
2616
            break;
2617
2618
        case ISSUE_ALT_NAMES_OID:
2619
            WOLFSSL_MSG("Issue Alt Names extension not supported");
2620
            break;
2621
2622
        case TLS_FEATURE_OID:
2623
            WOLFSSL_MSG("TLS Feature extension not supported");
2624
            break;
2625
2626
        default:
2627
            WOLFSSL_MSG("Unsupported/Unknown extension OID");
2628
    }
2629
2630
    /* make sure stack of is allocated */
2631
    if ((obj || gn) && sk == NULL) {
2632
        sk = wolfSSL_sk_new_asn1_obj();
2633
        if (sk == NULL) {
2634
            goto err;
2635
        }
2636
    }
2637
    if (obj) {
2638
        if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) != WOLFSSL_SUCCESS) {
2639
            WOLFSSL_MSG("Error pushing ASN1_OBJECT object onto "
2640
                        "stack.");
2641
            goto err;
2642
        }
2643
    }
2644
2645
    ret = sk;
2646
2647
    (void)idx;
2648
2649
    return ret;
2650
2651
err:
2652
    if (obj) {
2653
        wolfSSL_ASN1_OBJECT_free(obj);
2654
    }
2655
    if (gn) {
2656
        wolfSSL_GENERAL_NAME_free(gn);
2657
    }
2658
    #ifdef OPENSSL_EXTRA
2659
    if (dp) {
2660
        wolfSSL_DIST_POINT_free(dp);
2661
    }
2662
    #endif
2663
    if (sk) {
2664
        wolfSSL_sk_pop_free(sk, NULL);
2665
    }
2666
    return NULL;
2667
}
2668
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
2669
2670
#ifdef OPENSSL_EXTRA
2671
int wolfSSL_X509_add_altname_ex(WOLFSSL_X509* x509, const char* name,
2672
        word32 nameSz, int type)
2673
{
2674
    DNS_entry* newAltName = NULL;
2675
    char* nameCopy = NULL;
2676
2677
    if (x509 == NULL)
2678
        return WOLFSSL_FAILURE;
2679
2680
    if ((name == NULL) || (nameSz == 0))
2681
        return WOLFSSL_SUCCESS;
2682
2683
    newAltName = AltNameNew(x509->heap);
2684
    if (newAltName == NULL)
2685
        return WOLFSSL_FAILURE;
2686
2687
    nameCopy = (char*)XMALLOC(nameSz + 1, x509->heap, DYNAMIC_TYPE_ALTNAME);
2688
    if (nameCopy == NULL) {
2689
        XFREE(newAltName, x509->heap, DYNAMIC_TYPE_ALTNAME);
2690
        return WOLFSSL_FAILURE;
2691
    }
2692
2693
    XMEMCPY(nameCopy, name, nameSz);
2694
2695
    nameCopy[nameSz] = '\0';
2696
2697
    newAltName->next = x509->altNames;
2698
    newAltName->type = type;
2699
    newAltName->len = nameSz;
2700
    newAltName->name = nameCopy;
2701
    x509->altNames = newAltName;
2702
2703
    return WOLFSSL_SUCCESS;
2704
}
2705
2706
int wolfSSL_X509_add_altname(WOLFSSL_X509* x509, const char* name, int type)
2707
{
2708
    word32 nameSz;
2709
2710
    if (name == NULL)
2711
        return WOLFSSL_SUCCESS;
2712
2713
    nameSz = (word32)XSTRLEN(name);
2714
    if (nameSz == 0)
2715
        return WOLFSSL_SUCCESS;
2716
2717
    if (type == ASN_IP_TYPE) {
2718
        WOLFSSL_MSG("Type not supported, use wolfSSL_X509_add_altname_ex");
2719
        return WOLFSSL_FAILURE;
2720
    }
2721
2722
    return wolfSSL_X509_add_altname_ex(x509, name, nameSz, type);
2723
}
2724
2725
#ifndef NO_WOLFSSL_STUB
2726
WOLFSSL_X509_EXTENSION *wolfSSL_X509_delete_ext(WOLFSSL_X509 *x509, int loc)
2727
{
2728
    WOLFSSL_STUB("wolfSSL_X509_delete_ext");
2729
    (void)x509;
2730
    (void)loc;
2731
    return NULL;
2732
}
2733
2734
/* currently LHASH is not implemented (and not needed for Apache port) */
2735
WOLFSSL_X509_EXTENSION* wolfSSL_X509V3_EXT_conf_nid(
2736
        WOLF_LHASH_OF(CONF_VALUE)* conf, WOLFSSL_X509V3_CTX* ctx, int nid,
2737
        char* value)
2738
{
2739
    WOLFSSL_STUB("wolfSSL_X509V3_EXT_conf_nid");
2740
2741
    if (conf != NULL) {
2742
        WOLFSSL_MSG("Handling LHASH not implemented yet");
2743
        return NULL;
2744
    }
2745
2746
    (void)conf;
2747
    (void)ctx;
2748
    (void)nid;
2749
    (void)value;
2750
    return NULL;
2751
}
2752
2753
void wolfSSL_X509V3_set_ctx_nodb(WOLFSSL_X509V3_CTX* ctx)
2754
{
2755
    WOLFSSL_STUB("wolfSSL_X509V3_set_ctx_nodb");
2756
    (void)ctx;
2757
}
2758
#endif /* !NO_WOLFSSL_STUB */
2759
2760
#ifdef OPENSSL_EXTRA
2761
static WOLFSSL_X509_EXTENSION* createExtFromStr(int nid, const char *value)
2762
{
2763
    WOLFSSL_X509_EXTENSION* ext;
2764
2765
    if (value == NULL)
2766
        return NULL;
2767
2768
    ext = wolfSSL_X509_EXTENSION_new();
2769
    if (ext == NULL) {
2770
        WOLFSSL_MSG("memory error");
2771
        return NULL;
2772
    }
2773
    ext->value.nid = nid;
2774
2775
    switch (nid) {
2776
        case NID_subject_key_identifier:
2777
        case NID_authority_key_identifier:
2778
            if (wolfSSL_ASN1_STRING_set(&ext->value, value, -1)
2779
                    != WOLFSSL_SUCCESS) {
2780
                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
2781
                goto err_cleanup;
2782
            }
2783
            ext->value.type = CTC_UTF8;
2784
            break;
2785
        case NID_subject_alt_name:
2786
        {
2787
            WOLFSSL_GENERAL_NAMES* gns;
2788
            WOLFSSL_GENERAL_NAME* gn;
2789
2790
            if (wolfSSL_ASN1_STRING_set(&ext->value, value, -1)
2791
                    != WOLFSSL_SUCCESS) {
2792
                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
2793
                goto err_cleanup;
2794
            }
2795
            ext->value.type = ASN_DNS_TYPE;
2796
2797
            /* add stack of general names */
2798
            gns = wolfSSL_sk_new_null();
2799
            if (gns == NULL) {
2800
                WOLFSSL_MSG("wolfSSL_sk_new_null error");
2801
                goto err_cleanup;
2802
            }
2803
            ext->ext_sk = gns; /* wolfSSL_X509_EXTENSION_free will handle
2804
                                * free'ing gns */
2805
            gns->type = STACK_TYPE_GEN_NAME;
2806
            gn = wolfSSL_GENERAL_NAME_new();
2807
            if (gn == NULL) {
2808
                WOLFSSL_MSG("wolfSSL_GENERAL_NAME_new error");
2809
                goto err_cleanup;
2810
            }
2811
            if (wolfSSL_sk_GENERAL_NAME_push(gns, gn) != WOLFSSL_SUCCESS) {
2812
                WOLFSSL_MSG("wolfSSL_sk_GENERAL_NAME_push error");
2813
                wolfSSL_GENERAL_NAME_free(gn);
2814
                goto err_cleanup;
2815
            }
2816
            if (wolfSSL_ASN1_STRING_set(gn->d.ia5, value, -1)
2817
                    != WOLFSSL_SUCCESS) {
2818
                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set failed");
2819
                goto err_cleanup;
2820
            }
2821
            gn->type = ASN_DNS_TYPE;
2822
            break;
2823
        }
2824
        case NID_key_usage:
2825
            if (wolfSSL_ASN1_STRING_set(&ext->value, value, -1)
2826
                    != WOLFSSL_SUCCESS) {
2827
                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
2828
                goto err_cleanup;
2829
            }
2830
            ext->value.type = KEY_USAGE_OID;
2831
            break;
2832
        case NID_ext_key_usage:
2833
            if (wolfSSL_ASN1_STRING_set(&ext->value, value, -1)
2834
                    != WOLFSSL_SUCCESS) {
2835
                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
2836
                goto err_cleanup;
2837
            }
2838
            ext->value.type = EXT_KEY_USAGE_OID;
2839
            break;
2840
        default:
2841
            WOLFSSL_MSG("invalid or unsupported NID");
2842
            goto err_cleanup;
2843
    }
2844
    return ext;
2845
err_cleanup:
2846
    wolfSSL_X509_EXTENSION_free(ext);
2847
    return NULL;
2848
}
2849
2850
/**
2851
 * Create a WOLFSSL_X509_EXTENSION from the input arguments.
2852
 * @param conf  Not used
2853
 * @param ctx   Not used
2854
 * @param nid   Interprets the value parameter as the x509 extension that
2855
 *              corresponds to this NID.
2856
 * @param value A NULL terminated string that is taken as the value of the
2857
 *              newly created extension object.
2858
 * @return WOLFSSL_X509_EXTENSION* on success or NULL on failure.
2859
 */
2860
WOLFSSL_X509_EXTENSION* wolfSSL_X509V3_EXT_nconf_nid(WOLFSSL_CONF* conf,
2861
        WOLFSSL_X509V3_CTX *ctx, int nid, const char *value)
2862
{
2863
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_nconf_nid");
2864
2865
    if (value == NULL) {
2866
        WOLFSSL_MSG("value NULL parameter");
2867
        return NULL;
2868
    }
2869
2870
    if (conf != NULL || ctx != NULL) {
2871
        WOLFSSL_MSG("wolfSSL_X509V3_EXT_nconf_nid does not handle either "
2872
                    "conf or ctx parameters");
2873
    }
2874
2875
    return createExtFromStr(nid, value);
2876
}
2877
2878
/**
2879
 * Create a WOLFSSL_X509_EXTENSION from the input arguments.
2880
 * @param conf  Not used
2881
 * @param ctx   Not used
2882
 * @param sName The textual representation of the NID that the value parameter
2883
 *              should be interpreted as.
2884
 * @param value A NULL terminated string that is taken as the value of the
2885
 *              newly created extension object.
2886
 * @return WOLFSSL_X509_EXTENSION* on success or NULL on failure.
2887
 */
2888
WOLFSSL_X509_EXTENSION* wolfSSL_X509V3_EXT_nconf(WOLFSSL_CONF *conf,
2889
        WOLFSSL_X509V3_CTX *ctx, const char *sName, const char *value)
2890
{
2891
    const WOLFSSL_ObjectInfo* info = wolfssl_object_info;
2892
    size_t i;
2893
2894
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_nconf");
2895
2896
    if (value == NULL) {
2897
        WOLFSSL_MSG("value NULL parameter");
2898
        return NULL;
2899
    }
2900
2901
    if (conf != NULL || ctx != NULL) {
2902
        WOLFSSL_MSG("wolfSSL_X509V3_EXT_nconf does not handle either "
2903
                    "conf or ctx parameters");
2904
    }
2905
2906
    for (i = 0; i < wolfssl_object_info_sz; i++, info++) {
2907
        if (XSTRCMP(info->sName, sName) == 0)
2908
            return createExtFromStr(info->nid, value);
2909
    }
2910
2911
    WOLFSSL_MSG("value didn't match any known NID");
2912
    return NULL;
2913
}
2914
2915
static void wolfSSL_X509V3_EXT_METHOD_populate(WOLFSSL_v3_ext_method *method,
2916
                                               int nid)
2917
{
2918
    if (!method)
2919
        return;
2920
2921
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_METHOD_populate");
2922
    switch (nid) {
2923
    case NID_subject_key_identifier:
2924
        method->i2s = (X509V3_EXT_I2S)wolfSSL_i2s_ASN1_STRING;
2925
        FALL_THROUGH;
2926
    case NID_authority_key_identifier:
2927
    case NID_key_usage:
2928
    case NID_certificate_policies:
2929
    case NID_policy_mappings:
2930
    case NID_subject_alt_name:
2931
    case NID_issuer_alt_name:
2932
    case NID_basic_constraints:
2933
    case NID_name_constraints:
2934
    case NID_policy_constraints:
2935
    case NID_ext_key_usage:
2936
    case NID_crl_distribution_points:
2937
    case NID_inhibit_any_policy:
2938
    case NID_info_access:
2939
        WOLFSSL_MSG("Nothing to populate for current NID");
2940
        break;
2941
    default:
2942
        WOLFSSL_MSG("Unknown or unsupported NID");
2943
        break;
2944
    }
2945
2946
    return;
2947
}
2948
2949
/**
2950
 * @param nid One of the NID_* constants defined in asn.h
2951
 * @param crit
2952
 * @param data This data is copied to the returned extension.
2953
 * @return
2954
 */
2955
WOLFSSL_X509_EXTENSION *wolfSSL_X509V3_EXT_i2d(int nid, int crit,
2956
                                               void *data)
2957
{
2958
    WOLFSSL_X509_EXTENSION *ext = NULL;
2959
    WOLFSSL_ASN1_STRING* asn1str = NULL;
2960
2961
    WOLFSSL_ENTER("wolfSSL_X509V3_EXT_i2d");
2962
2963
    if (!data) {
2964
        return NULL;
2965
    }
2966
2967
    if (!(ext = wolfSSL_X509_EXTENSION_new())) {
2968
        return NULL;
2969
    }
2970
2971
    wolfSSL_X509V3_EXT_METHOD_populate(&ext->ext_method, nid);
2972
2973
    switch (nid) {
2974
    case NID_subject_key_identifier:
2975
        /* WOLFSSL_ASN1_STRING */
2976
    case NID_key_usage:
2977
        /* WOLFSSL_ASN1_STRING */
2978
    {
2979
        asn1str = (WOLFSSL_ASN1_STRING*)data;
2980
        ext->value = *asn1str;
2981
        if (asn1str->isDynamic) {
2982
            ext->value.data = (char*)XMALLOC(asn1str->length, NULL,
2983
                                             DYNAMIC_TYPE_OPENSSL);
2984
            if (!ext->value.data) {
2985
                WOLFSSL_MSG("malloc failed");
2986
                /* Zero so that no existing memory is freed */
2987
                XMEMSET(&ext->value, 0, sizeof(WOLFSSL_ASN1_STRING));
2988
                goto err_cleanup;
2989
            }
2990
            XMEMCPY(ext->value.data, asn1str->data, asn1str->length);
2991
        }
2992
        else {
2993
            ext->value.data = ext->value.strData;
2994
        }
2995
2996
        if (!(ext->obj = wolfSSL_OBJ_nid2obj(nid))) {
2997
            WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new failed");
2998
            goto err_cleanup;
2999
        }
3000
3001
        break;
3002
    }
3003
    case NID_subject_alt_name:
3004
        /* typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES */
3005
    case NID_issuer_alt_name:
3006
        /* typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES */
3007
    case NID_ext_key_usage:
3008
        /* typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE */
3009
    case NID_info_access:
3010
        /* typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS */
3011
    {
3012
        WOLFSSL_STACK* sk = (WOLFSSL_STACK*)data;
3013
3014
        if (ext->ext_sk) {
3015
            wolfSSL_sk_pop_free(ext->ext_sk, NULL);
3016
        }
3017
3018
        if (!(ext->ext_sk = wolfSSL_sk_dup(sk))) {
3019
            WOLFSSL_MSG("wolfSSL_sk_dup failed");
3020
            goto err_cleanup;
3021
        }
3022
3023
        if (!(ext->obj = wolfSSL_OBJ_nid2obj(nid))) {
3024
            WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new failed");
3025
            goto err_cleanup;
3026
        }
3027
3028
        break;
3029
    }
3030
    case NID_basic_constraints:
3031
    {
3032
        /* WOLFSSL_BASIC_CONSTRAINTS */
3033
        WOLFSSL_BASIC_CONSTRAINTS* bc = (WOLFSSL_BASIC_CONSTRAINTS*)data;
3034
3035
        if (!(ext->obj = wolfSSL_ASN1_OBJECT_new())) {
3036
            WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new failed");
3037
            goto err_cleanup;
3038
        }
3039
3040
        ext->obj->ca = bc->ca;
3041
        if (bc->pathlen) {
3042
            ext->obj->pathlen = wolfSSL_ASN1_INTEGER_dup(bc->pathlen);
3043
            if (!ext->obj->pathlen) {
3044
                WOLFSSL_MSG("wolfSSL_ASN1_INTEGER_dup failed");
3045
                goto err_cleanup;
3046
            }
3047
        }
3048
        break;
3049
    }
3050
    case NID_authority_key_identifier:
3051
    {
3052
        /* AUTHORITY_KEYID */
3053
        WOLFSSL_AUTHORITY_KEYID* akey = (WOLFSSL_AUTHORITY_KEYID*)data;
3054
3055
        if (akey->keyid) {
3056
            if (wolfSSL_ASN1_STRING_set(&ext->value, akey->keyid->data,
3057
                                    akey->keyid->length) != WOLFSSL_SUCCESS) {
3058
                WOLFSSL_MSG("wolfSSL_ASN1_STRING_set failed");
3059
                goto err_cleanup;
3060
            }
3061
            ext->value.type = akey->keyid->type;
3062
3063
            if (!(ext->obj = wolfSSL_OBJ_nid2obj(nid))) {
3064
                WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new failed");
3065
                goto err_cleanup;
3066
            }
3067
3068
        }
3069
        else if (akey->issuer) {
3070
            ext->obj = wolfSSL_ASN1_OBJECT_dup(akey->issuer);
3071
            if (!ext->obj) {
3072
                WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_dup failed");
3073
                goto err_cleanup;
3074
            }
3075
        }
3076
        else {
3077
            WOLFSSL_MSG("NID_authority_key_identifier empty data");
3078
            goto err_cleanup;
3079
        }
3080
        break;
3081
    }
3082
    case NID_inhibit_any_policy:
3083
        /* ASN1_INTEGER */
3084
    case NID_certificate_policies:
3085
        /* STACK_OF(POLICYINFO) */
3086
    case NID_policy_mappings:
3087
        /* STACK_OF(POLICY_MAPPING) */
3088
    case NID_name_constraints:
3089
        /* NAME_CONSTRAINTS */
3090
    case NID_policy_constraints:
3091
        /* POLICY_CONSTRAINTS */
3092
    case NID_crl_distribution_points:
3093
        /* typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS */
3094
    default:
3095
        WOLFSSL_MSG("Unknown or unsupported NID");
3096
        break;
3097
    }
3098
3099
    ext->crit = crit;
3100
3101
    return ext;
3102
err_cleanup:
3103
    if (ext) {
3104
        wolfSSL_X509_EXTENSION_free(ext);
3105
    }
3106
    return NULL;
3107
}
3108
3109
/* Returns pointer to ASN1_OBJECT from an X509_EXTENSION object */
3110
WOLFSSL_ASN1_OBJECT* wolfSSL_X509_EXTENSION_get_object \
3111
    (WOLFSSL_X509_EXTENSION* ext)
3112
{
3113
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_get_object");
3114
    if(ext == NULL)
3115
        return NULL;
3116
    return ext->obj;
3117
}
3118
3119
3120
/**
3121
 * duplicates the 'obj' input and sets it into the 'ext' structure
3122
 * returns WOLFSSL_SUCCESS on success
3123
 */
3124
int wolfSSL_X509_EXTENSION_set_object(WOLFSSL_X509_EXTENSION* ext,
3125
        const WOLFSSL_ASN1_OBJECT* obj)
3126
{
3127
    WOLFSSL_ASN1_OBJECT *current;
3128
3129
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_set_object");
3130
    if (ext == NULL)
3131
        return WOLFSSL_FAILURE;
3132
3133
    current = wolfSSL_X509_EXTENSION_get_object(ext);
3134
    if (current != NULL) {
3135
        wolfSSL_ASN1_OBJECT_free(current);
3136
    }
3137
    ext->obj = wolfSSL_ASN1_OBJECT_dup((WOLFSSL_ASN1_OBJECT*)obj);
3138
    return WOLFSSL_SUCCESS;
3139
}
3140
#endif /* OPENSSL_ALL */
3141
3142
/* Returns pointer to ASN1_STRING in X509_EXTENSION object */
3143
WOLFSSL_ASN1_STRING* wolfSSL_X509_EXTENSION_get_data(WOLFSSL_X509_EXTENSION* ext)
3144
{
3145
    WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_get_data");
3146
    if (ext == NULL)
3147
        return NULL;
3148
    return &ext->value;
3149
}
3150
3151
3152
/**
3153
 * Creates a duplicate of input 'data' and sets it into 'ext' structure
3154
 * returns WOLFSSL_SUCCESS on success
3155
 */
3156
int wolfSSL_X509_EXTENSION_set_data(WOLFSSL_X509_EXTENSION* ext,
3157
        WOLFSSL_ASN1_STRING* data)
3158
{
3159
    WOLFSSL_ASN1_STRING* current;
3160
3161
    if (ext == NULL || data == NULL)
3162
        return WOLFSSL_FAILURE;
3163
3164
    current = wolfSSL_X509_EXTENSION_get_data(ext);
3165
    if (current->length > 0 && current->data != NULL && current->isDynamic) {
3166
        XFREE(current->data, NULL, DYNAMIC_TYPE_OPENSSL);
3167
    }
3168
3169
    return wolfSSL_ASN1_STRING_copy(&ext->value, data);
3170
}
3171
3172
#if !defined(NO_PWDBASED)
3173
int wolfSSL_X509_digest(const WOLFSSL_X509* x509, const WOLFSSL_EVP_MD* digest,
3174
        unsigned char* buf, unsigned int* len)
3175
{
3176
    int ret;
3177
3178
    WOLFSSL_ENTER("wolfSSL_X509_digest");
3179
3180
    if (x509 == NULL || digest == NULL) {
3181
        WOLFSSL_MSG("Null argument found");
3182
        return WOLFSSL_FAILURE;
3183
    }
3184
3185
    if (x509->derCert == NULL) {
3186
        WOLFSSL_MSG("No DER certificate stored in X509");
3187
        return WOLFSSL_FAILURE;
3188
    }
3189
3190
    ret = wolfSSL_EVP_Digest(x509->derCert->buffer, x509->derCert->length, buf,
3191
                              len, digest, NULL);
3192
    WOLFSSL_LEAVE("wolfSSL_X509_digest", ret);
3193
    return ret;
3194
}
3195
3196
int wolfSSL_X509_pubkey_digest(const WOLFSSL_X509 *x509,
3197
        const WOLFSSL_EVP_MD *digest, unsigned char* buf, unsigned int* len)
3198
{
3199
    int ret;
3200
3201
    WOLFSSL_ENTER("wolfSSL_X509_pubkey_digest");
3202
3203
    if (x509 == NULL || digest == NULL) {
3204
        WOLFSSL_MSG("Null argument found");
3205
        return WOLFSSL_FAILURE;
3206
    }
3207
3208
    if (x509->pubKey.buffer == NULL || x509->pubKey.length == 0) {
3209
        WOLFSSL_MSG("No DER public key stored in X509");
3210
        return WOLFSSL_FAILURE;
3211
    }
3212
3213
    ret = wolfSSL_EVP_Digest(x509->pubKey.buffer, x509->pubKey.length, buf,
3214
                              len, digest, NULL);
3215
    WOLFSSL_LEAVE("wolfSSL_X509_pubkey_digest", ret);
3216
    return ret;
3217
}
3218
#endif
3219
3220
#endif /* OPENSSL_EXTRA */
3221
3222
#ifdef OPENSSL_EXTRA
3223
3224
    #ifndef NO_WOLFSSL_STUB
3225
    const char* wolfSSL_X509_get_default_cert_file_env(void)
3226
    {
3227
        WOLFSSL_STUB("X509_get_default_cert_file_env");
3228
        return NULL;
3229
    }
3230
3231
    const char* wolfSSL_X509_get_default_cert_file(void)
3232
    {
3233
        WOLFSSL_STUB("X509_get_default_cert_file");
3234
        return NULL;
3235
    }
3236
3237
    const char* wolfSSL_X509_get_default_cert_dir_env(void)
3238
    {
3239
        WOLFSSL_STUB("X509_get_default_cert_dir_env");
3240
        return NULL;
3241
    }
3242
3243
    const char* wolfSSL_X509_get_default_cert_dir(void)
3244
    {
3245
        WOLFSSL_STUB("X509_get_default_cert_dir");
3246
        return NULL;
3247
    }
3248
    #endif
3249
3250
#endif /* OPENSSL_EXTRA */
3251
3252
#if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS) || \
3253
    defined(OPENSSL_EXTRA)  || defined(OPENSSL_EXTRA_X509_SMALL)
3254
3255
/* user externally called free X509, if dynamic go ahead with free, otherwise
3256
 * don't */
3257
static void ExternalFreeX509(WOLFSSL_X509* x509)
3258
{
3259
#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA)
3260
    int doFree = 0;
3261
#endif
3262
3263
    WOLFSSL_ENTER("ExternalFreeX509");
3264
    if (x509) {
3265
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
3266
        wolfSSL_CRYPTO_cleanup_ex_data(&x509->ex_data);
3267
#endif
3268
        if (x509->dynamicMemory) {
3269
        #if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA)
3270
            int ret;
3271
            wolfSSL_RefDec(&x509->ref, &doFree, &ret);
3272
            if (ret != 0) {
3273
                WOLFSSL_MSG("Couldn't lock x509 mutex");
3274
            }
3275
        #endif /* OPENSSL_EXTRA_X509_SMALL || OPENSSL_EXTRA */
3276
3277
        #if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA)
3278
            if (doFree)
3279
        #endif /* OPENSSL_EXTRA_X509_SMALL || OPENSSL_EXTRA */
3280
            {
3281
                FreeX509(x509);
3282
                XFREE(x509, x509->heap, DYNAMIC_TYPE_X509);
3283
            }
3284
        } else {
3285
            WOLFSSL_MSG("free called on non dynamic object, not freeing");
3286
        }
3287
    }
3288
}
3289
3290
/* Frees an external WOLFSSL_X509 structure */
3291
WOLFSSL_ABI
3292
void wolfSSL_X509_free(WOLFSSL_X509* x509)
3293
{
3294
    WOLFSSL_ENTER("wolfSSL_FreeX509");
3295
    ExternalFreeX509(x509);
3296
}
3297
3298
3299
/* copy name into in buffer, at most sz bytes, if buffer is null will
3300
   malloc buffer, call responsible for freeing                     */
3301
WOLFSSL_ABI
3302
char* wolfSSL_X509_NAME_oneline(WOLFSSL_X509_NAME* name, char* in, int sz)
3303
{
3304
    int copySz;
3305
3306
    if (name == NULL) {
3307
        WOLFSSL_MSG("WOLFSSL_X509_NAME pointer was NULL");
3308
        return NULL;
3309
    }
3310
3311
    copySz = min(sz, name->sz);
3312
3313
    WOLFSSL_ENTER("wolfSSL_X509_NAME_oneline");
3314
    if (!name->sz) return in;
3315
3316
    if (!in) {
3317
    #ifdef WOLFSSL_STATIC_MEMORY
3318
        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
3319
        return NULL;
3320
    #else
3321
        in = (char*)XMALLOC(name->sz, NULL, DYNAMIC_TYPE_OPENSSL);
3322
        if (!in ) return in;
3323
        copySz = name->sz;
3324
    #endif
3325
    }
3326
3327
    if (copySz <= 0)
3328
        return in;
3329
3330
    XMEMCPY(in, name->name, copySz - 1);
3331
    in[copySz - 1] = 0;
3332
3333
    return in;
3334
}
3335
3336
#ifdef OPENSSL_EXTRA
3337
/* Given an X509_NAME, convert it to canonical form and then hash
3338
 * with the provided hash type. Returns the first 4 bytes of the hash
3339
 * as unsigned long on success, and 0 otherwise. */
3340
static unsigned long X509NameHash(WOLFSSL_X509_NAME* name,
3341
    enum wc_HashType hashType)
3342
{
3343
    unsigned long  hash = 0;
3344
    unsigned char* canonName = NULL;
3345
    byte           digest[WC_MAX_DIGEST_SIZE];
3346
    int            size = 0;
3347
    int            rc;
3348
3349
    WOLFSSL_ENTER("X509NameHash");
3350
3351
    if (name == NULL) {
3352
        WOLFSSL_ERROR_MSG("WOLFSSL_X509_NAME pointer was NULL");
3353
        return 0;
3354
    }
3355
3356
    if (name->sz == 0) {
3357
        WOLFSSL_ERROR_MSG("Nothing to hash in WOLFSSL_X509_NAME");
3358
        return 0;
3359
    }
3360
3361
    size = wolfSSL_i2d_X509_NAME_canon(name, &canonName);
3362
3363
    if (size <= 0 || canonName == NULL) {
3364
        WOLFSSL_ERROR_MSG("wolfSSL_i2d_X509_NAME_canon error");
3365
        return 0;
3366
    }
3367
3368
    rc = wc_Hash(hashType, (const byte*)canonName,(word32)size, digest,
3369
        sizeof(digest));
3370
3371
    if (rc == 0) {
3372
        hash = (((unsigned long)digest[3] << 24) |
3373
                ((unsigned long)digest[2] << 16) |
3374
                ((unsigned long)digest[1] <<  8) |
3375
                ((unsigned long)digest[0]));
3376
    }
3377
    else if (rc == HASH_TYPE_E) {
3378
        WOLFSSL_ERROR_MSG("Hash function not compiled in");
3379
    }
3380
    else {
3381
        WOLFSSL_ERROR_MSG("Error hashing name");
3382
    }
3383
3384
    XFREE(canonName, NULL, DYNAMIC_TYPE_OPENSSL);
3385
    return hash;
3386
}
3387
3388
unsigned long wolfSSL_X509_NAME_hash(WOLFSSL_X509_NAME* name)
3389
{
3390
    return X509NameHash(name, WC_HASH_TYPE_SHA);
3391
}
3392
3393
/******************************************************************************
3394
* wolfSSL_X509_subject_name_hash
3395
* wolfSSL_X509_issuer_name_hash
3396
* Compute the hash digest of the subject / issuer name.
3397
* These functions prefer SHA-1 (if available) for compatibility. Otherwise
3398
* they use SHA-256.
3399
*
3400
* RETURNS:
3401
* The first 4 bytes of SHA-1 (or SHA-256) hash in little endian order as
3402
* unsigned long.
3403
* Otherwise, returns zero.
3404
*
3405
* Note:
3406
* Returns the same hash value as OpenSSL's X509_X_name_hash() API
3407
* if SHA-1 support is compiled in. SHA-256 will be used if SHA-1 is
3408
* not available.
3409
*/
3410
unsigned long wolfSSL_X509_subject_name_hash(const WOLFSSL_X509* x509)
3411
{
3412
    if (x509 == NULL) {
3413
        WOLFSSL_ERROR_MSG("WOLFSSL_X509 pointer was NULL");
3414
        return 0;
3415
    }
3416
3417
    #ifndef NO_SHA
3418
    return X509NameHash((WOLFSSL_X509_NAME*) &x509->subject, WC_HASH_TYPE_SHA);
3419
    #elif !defined(NO_SHA256)
3420
    return X509NameHash((WOLFSSL_X509_NAME*) &x509->subject,
3421
                        WC_HASH_TYPE_SHA256);
3422
    #else
3423
    WOLFSSL_ERROR_MSG("Hash function not compiled in");
3424
    return 0;
3425
    #endif
3426
}
3427
3428
unsigned long wolfSSL_X509_issuer_name_hash(const WOLFSSL_X509* x509)
3429
{
3430
    if (x509 == NULL) {
3431
        WOLFSSL_ERROR_MSG("WOLFSSL_X509 pointer was NULL");
3432
        return 0;
3433
    }
3434
3435
    #ifndef NO_SHA
3436
    return X509NameHash((WOLFSSL_X509_NAME*) &x509->issuer, WC_HASH_TYPE_SHA);
3437
    #elif !defined(NO_SHA256)
3438
    return X509NameHash((WOLFSSL_X509_NAME*) &x509->issuer,
3439
                        WC_HASH_TYPE_SHA256);
3440
    #else
3441
    WOLFSSL_ERROR_MSG("Hash function not compiled in");
3442
    return 0;
3443
    #endif
3444
}
3445
#endif /* OPENSSL_EXTRA */
3446
3447
#if defined(OPENSSL_EXTRA) && defined(XSNPRINTF)
3448
/* Copies X509 subject name into a buffer, with comma-separated name entries
3449
 *   (matching OpenSSL v1.0.0 format)
3450
 * Example Output for Issuer:
3451
 *
3452
 * C=US, ST=Montana, L=Bozeman, O=Sawtooth, OU=Consulting,
3453
 *  CN=www.wolfssl.com, emailAddress=info@wolfssl.com
3454
 */
3455
char* wolfSSL_X509_get_name_oneline(WOLFSSL_X509_NAME* name, char* in, int sz)
3456
{
3457
    int count, i;
3458
    int totalLen = 0;
3459
    char tmpBuf[256];
3460
    WOLFSSL_ENTER("wolfSSL_X509_get_name_oneline");
3461
3462
    if (name == NULL) {
3463
        WOLFSSL_MSG("wolfSSL_X509_get_name_oneline failed");
3464
        return NULL;
3465
    }
3466
    #ifdef WOLFSSL_STATIC_MEMORY
3467
    if (!in) {
3468
        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
3469
        return NULL;
3470
    }
3471
    #endif
3472
3473
    /* Loop through X509 name entries and copy new format to buffer */
3474
    count = wolfSSL_X509_NAME_entry_count(name);
3475
    for (i = 0; i < count; i++) {
3476
        WOLFSSL_X509_NAME_ENTRY* entry;
3477
        int nameSz;
3478
        int strSz;
3479
        int strLen;
3480
        char *str;
3481
        const int tmpBufSz = sizeof(tmpBuf);
3482
        char buf[80];
3483
        const char* sn;
3484
3485
        /* Get name entry and size */
3486
        entry = wolfSSL_X509_NAME_get_entry(name, i);
3487
        if (entry == NULL) {
3488
            WOLFSSL_MSG("wolfSSL_X509_NAME_get_entry failed");
3489
            return NULL;
3490
        }
3491
        nameSz = wolfSSL_X509_NAME_get_text_by_NID(name, entry->nid, buf,
3492
                                                                   sizeof(buf));
3493
        if (nameSz < 0) {
3494
            WOLFSSL_MSG("wolfSSL_X509_NAME_get_text_by_NID failed");
3495
            return NULL;
3496
        }
3497
3498
        /* Get short name */
3499
        sn = wolfSSL_OBJ_nid2sn(entry->nid);
3500
        if (sn == NULL) {
3501
            WOLFSSL_MSG("OBJ_nid2sn failed");
3502
            return NULL;
3503
        }
3504
3505
        /* Copy sn and name text to buffer
3506
         * Add extra strSz for '=', ',', ' ' and '\0' characters in XSNPRINTF.
3507
         */
3508
        if (i != count - 1) {
3509
            strSz = (int)XSTRLEN(sn) + nameSz + 4;
3510
            str = (char*)XMALLOC(strSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3511
            if (str == NULL) {
3512
                WOLFSSL_MSG("Memory error");
3513
                return NULL;
3514
            }
3515
            if ((strLen = XSNPRINTF(str, strSz, "%s=%s, ", sn, buf))
3516
                >= strSz)
3517
            {
3518
                WOLFSSL_MSG("buffer overrun");
3519
                XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3520
                return NULL;
3521
            }
3522
        }
3523
        else {
3524
            /* Copy last name entry
3525
            * Add extra strSz for '=' and '\0' characters in XSNPRINTF.
3526
            */
3527
            strSz = (int)XSTRLEN(sn) + nameSz + 2;
3528
            str = (char*)XMALLOC(strSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3529
            if (str == NULL) {
3530
                WOLFSSL_MSG("Memory error");
3531
                return NULL;
3532
            }
3533
            if ((strLen = XSNPRINTF(str, strSz, "%s=%s", sn, buf)) >= strSz) {
3534
                WOLFSSL_MSG("buffer overrun");
3535
                XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3536
                return NULL;
3537
            }
3538
        }
3539
        /* Copy string to tmpBuf */
3540
        if (totalLen + strLen > tmpBufSz) {
3541
            WOLFSSL_MSG("buffer overrun");
3542
            XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3543
            return NULL;
3544
        }
3545
        XMEMCPY(tmpBuf + totalLen, str, strLen);
3546
        totalLen += strLen;
3547
        XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3548
    }
3549
3550
    /* Allocate space based on total string size if no buffer was provided */
3551
    if (!in) {
3552
        in = (char*)XMALLOC(totalLen+1, NULL, DYNAMIC_TYPE_OPENSSL);
3553
        if (in == NULL) {
3554
            WOLFSSL_MSG("Memory error");
3555
            return in;
3556
        }
3557
    }
3558
    else {
3559
        if (totalLen + 1 > sz) {
3560
            WOLFSSL_MSG("buffer overrun");
3561
            return NULL;
3562
        }
3563
    }
3564
3565
    XMEMCPY(in, tmpBuf, totalLen);
3566
    in[totalLen] = '\0';
3567
3568
    return in;
3569
}
3570
#endif
3571
3572
3573
/* Wraps wolfSSL_X509_d2i
3574
 *
3575
 * returns a WOLFSSL_X509 structure pointer on success and NULL on fail
3576
 */
3577
WOLFSSL_X509* wolfSSL_d2i_X509(WOLFSSL_X509** x509, const unsigned char** in,
3578
        int len)
3579
{
3580
    WOLFSSL_X509* newX509 = NULL;
3581
    WOLFSSL_ENTER("wolfSSL_d2i_X509");
3582
3583
    if (in == NULL) {
3584
        WOLFSSL_MSG("NULL input for wolfSSL_d2i_X509");
3585
        return NULL;
3586
    }
3587
3588
    newX509 = wolfSSL_X509_d2i(x509, *in, len);
3589
    if (newX509 != NULL) {
3590
        *in += newX509->derCert->length;
3591
    }
3592
    return newX509;
3593
}
3594
3595
static WOLFSSL_X509* d2i_X509orX509REQ(WOLFSSL_X509** x509,
3596
                                        const byte* in, int len, int req)
3597
{
3598
    WOLFSSL_X509 *newX509 = NULL;
3599
    int type = req ? CERTREQ_TYPE : CERT_TYPE;
3600
3601
    WOLFSSL_ENTER("wolfSSL_X509_d2i");
3602
3603
    if (in != NULL && len != 0
3604
    #ifndef WOLFSSL_CERT_REQ
3605
            && req == 0
3606
    #else
3607
            && (req == 0 || req == 1)
3608
    #endif
3609
            ) {
3610
    #ifdef WOLFSSL_SMALL_STACK
3611
        DecodedCert* cert;
3612
    #else
3613
        DecodedCert  cert[1];
3614
    #endif
3615
3616
    #ifdef WOLFSSL_SMALL_STACK
3617
        cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
3618
                                     DYNAMIC_TYPE_DCERT);
3619
        if (cert == NULL)
3620
            return NULL;
3621
    #endif
3622
3623
        InitDecodedCert(cert, (byte*)in, len, NULL);
3624
    #ifdef WOLFSSL_CERT_REQ
3625
        cert->isCSR = (byte)req;
3626
    #endif
3627
        if (ParseCertRelative(cert, type, 0, NULL) == 0) {
3628
            newX509 = wolfSSL_X509_new();
3629
            if (newX509 != NULL) {
3630
                if (CopyDecodedToX509(newX509, cert) != 0) {
3631
                    wolfSSL_X509_free(newX509);
3632
                    newX509 = NULL;
3633
                }
3634
            }
3635
        }
3636
        FreeDecodedCert(cert);
3637
    #ifdef WOLFSSL_SMALL_STACK
3638
        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
3639
    #endif
3640
    }
3641
3642
    if (x509 != NULL)
3643
        *x509 = newX509;
3644
3645
    return newX509;
3646
}
3647
3648
int wolfSSL_X509_get_isCA(WOLFSSL_X509* x509)
3649
{
3650
    int isCA = 0;
3651
3652
    WOLFSSL_ENTER("wolfSSL_X509_get_isCA");
3653
3654
    if (x509 != NULL)
3655
        isCA = x509->isCa;
3656
3657
    WOLFSSL_LEAVE("wolfSSL_X509_get_isCA", isCA);
3658
3659
    return isCA;
3660
}
3661
3662
WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len)
3663
{
3664
    return d2i_X509orX509REQ(x509, in, len, 0);
3665
}
3666
3667
#ifdef WOLFSSL_CERT_REQ
3668
WOLFSSL_X509* wolfSSL_X509_REQ_d2i(WOLFSSL_X509** x509,
3669
        const unsigned char* in, int len)
3670
{
3671
    return d2i_X509orX509REQ(x509, in, len, 1);
3672
}
3673
#endif
3674
3675
#endif /* KEEP_PEER_CERT || SESSION_CERTS || OPENSSL_EXTRA ||
3676
          OPENSSL_EXTRA_X509_SMALL */
3677
3678
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
3679
/* returns the number of entries in the WOLFSSL_X509_NAME */
3680
int wolfSSL_X509_NAME_entry_count(WOLFSSL_X509_NAME* name)
3681
{
3682
    int count = 0;
3683
3684
    WOLFSSL_ENTER("wolfSSL_X509_NAME_entry_count");
3685
3686
    if (name != NULL)
3687
        count = name->entrySz;
3688
3689
    WOLFSSL_LEAVE("wolfSSL_X509_NAME_entry_count", count);
3690
    return count;
3691
}
3692
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
3693
3694
#if defined(OPENSSL_EXTRA) || \
3695
    defined(KEEP_OUR_CERT) || defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
3696
3697
/* return the next, if any, altname from the peer cert */
3698
WOLFSSL_ABI
3699
char* wolfSSL_X509_get_next_altname(WOLFSSL_X509* cert)
3700
{
3701
    char* ret = NULL;
3702
    WOLFSSL_ENTER("wolfSSL_X509_get_next_altname");
3703
3704
    /* don't have any to work with */
3705
    if (cert == NULL || cert->altNames == NULL)
3706
        return NULL;
3707
3708
    /* already went through them */
3709
    if (cert->altNamesNext == NULL) {
3710
#ifdef WOLFSSL_MULTICIRCULATE_ALTNAMELIST
3711
        /* Reset altNames List to head
3712
         * so that caller can circulate the list again
3713
         */
3714
        cert->altNamesNext = cert->altNames;
3715
#endif
3716
        return NULL;
3717
    }
3718
3719
    ret = cert->altNamesNext->name;
3720
#if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
3721
    /* return the IP address as a string */
3722
    if (cert->altNamesNext->type == ASN_IP_TYPE) {
3723
        ret = cert->altNamesNext->ipString;
3724
    }
3725
#endif
3726
    cert->altNamesNext = cert->altNamesNext->next;
3727
3728
    return ret;
3729
}
3730
3731
int wolfSSL_X509_get_signature(WOLFSSL_X509* x509,
3732
                                                unsigned char* buf, int* bufSz)
3733
{
3734
    WOLFSSL_ENTER("wolfSSL_X509_get_signature");
3735
    if (x509 == NULL || bufSz == NULL || (*bufSz < (int)x509->sig.length &&
3736
                buf != NULL))
3737
        return WOLFSSL_FATAL_ERROR;
3738
3739
    if (buf != NULL)
3740
        XMEMCPY(buf, x509->sig.buffer, x509->sig.length);
3741
    *bufSz = x509->sig.length;
3742
3743
    return WOLFSSL_SUCCESS;
3744
}
3745
3746
3747
/* Getter function that copies over the DER public key buffer to "buf" and
3748
    * sets the size in bufSz. If "buf" is NULL then just bufSz is set to needed
3749
    * buffer size. "bufSz" passed in should initially be set by the user to be
3750
    * the size of "buf". This gets checked to make sure the buffer is large
3751
    * enough to hold the public key.
3752
    *
3753
    * Note: this is the X.509 form of key with "header" info.
3754
    * return WOLFSSL_SUCCESS on success
3755
    */
3756
int wolfSSL_X509_get_pubkey_buffer(WOLFSSL_X509* x509,
3757
                                            unsigned char* buf, int* bufSz)
3758
{
3759
#ifdef WOLFSSL_SMALL_STACK
3760
    DecodedCert* cert;
3761
#else
3762
    DecodedCert cert[1];
3763
#endif
3764
    const byte*  der;
3765
    int length = 0;
3766
    int    ret = 0, derSz = 0;
3767
    int badDate = 0;
3768
    const byte* pubKeyX509 = NULL;
3769
    int   pubKeyX509Sz = 0;
3770
3771
    WOLFSSL_ENTER("wolfSSL_X509_get_pubkey_buffer");
3772
    if (x509 == NULL || bufSz == NULL) {
3773
        WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", BAD_FUNC_ARG);
3774
        return WOLFSSL_FATAL_ERROR;
3775
    }
3776
3777
3778
#ifdef WOLFSSL_SMALL_STACK
3779
    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert),
3780
                                    x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
3781
    if (cert == NULL) {
3782
        WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", MEMORY_E);
3783
        return WOLFSSL_FATAL_ERROR;
3784
    }
3785
#endif
3786
3787
    der = wolfSSL_X509_get_der(x509, &derSz);
3788
    if (der != NULL) {
3789
        InitDecodedCert(cert, der, derSz, NULL);
3790
        ret = wc_GetPubX509(cert, 0, &badDate);
3791
        if (ret >= 0) {
3792
            word32 idx = cert->srcIdx;
3793
            pubKeyX509 = cert->source + cert->srcIdx;
3794
            ret = GetSequence(cert->source, &cert->srcIdx, &length,
3795
                    cert->maxIdx);
3796
            pubKeyX509Sz = length + (cert->srcIdx - idx);
3797
        }
3798
        FreeDecodedCert(cert);
3799
    }
3800
#ifdef WOLFSSL_SMALL_STACK
3801
    XFREE(cert, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
3802
#endif
3803
3804
    if (ret < 0) {
3805
        WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", ret);
3806
        return WOLFSSL_FATAL_ERROR;
3807
    }
3808
3809
    if (buf != NULL && pubKeyX509 != NULL) {
3810
        if (pubKeyX509Sz > *bufSz) {
3811
            WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", BUFFER_E);
3812
            return WOLFSSL_FATAL_ERROR;
3813
        }
3814
        XMEMCPY(buf, pubKeyX509, pubKeyX509Sz);
3815
    }
3816
    *bufSz = pubKeyX509Sz;
3817
3818
    return WOLFSSL_SUCCESS;
3819
}
3820
3821
3822
/* Getter function for the public key OID value
3823
    * return public key OID stored in WOLFSSL_X509 structure */
3824
int wolfSSL_X509_get_pubkey_type(WOLFSSL_X509* x509)
3825
{
3826
    if (x509 == NULL)
3827
        return WOLFSSL_FAILURE;
3828
    return x509->pubKeyOID;
3829
}
3830
3831
#endif /* OPENSSL_EXTRA || KEEP_OUR_CERT || KEEP_PEER_CERT || SESSION_CERTS */
3832
3833
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
3834
    defined(KEEP_OUR_CERT) || defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
3835
3836
/* write X509 serial number in unsigned binary to buffer
3837
    buffer needs to be at least EXTERNAL_SERIAL_SIZE (32) for all cases
3838
    return WOLFSSL_SUCCESS on success */
3839
int wolfSSL_X509_get_serial_number(WOLFSSL_X509* x509,
3840
                                    byte* in, int* inOutSz)
3841
{
3842
    WOLFSSL_ENTER("wolfSSL_X509_get_serial_number");
3843
    if (x509 == NULL || inOutSz == NULL) {
3844
        WOLFSSL_MSG("Null argument passed in");
3845
        return BAD_FUNC_ARG;
3846
    }
3847
3848
    if (in != NULL) {
3849
        if (*inOutSz < x509->serialSz) {
3850
            WOLFSSL_MSG("Serial buffer too small");
3851
            return BUFFER_E;
3852
        }
3853
        XMEMCPY(in, x509->serial, x509->serialSz);
3854
    }
3855
    *inOutSz = x509->serialSz;
3856
3857
    return WOLFSSL_SUCCESS;
3858
}
3859
3860
/* not an openssl compatibility function - getting for derCert */
3861
const byte* wolfSSL_X509_get_der(WOLFSSL_X509* x509, int* outSz)
3862
{
3863
    WOLFSSL_ENTER("wolfSSL_X509_get_der");
3864
3865
    if (x509 == NULL || x509->derCert == NULL || outSz == NULL)
3866
        return NULL;
3867
3868
    *outSz = (int)x509->derCert->length;
3869
    return x509->derCert->buffer;
3870
}
3871
3872
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || KEEP_OUR_CERT || KEEP_PEER_CERT || SESSION_CERTS */
3873
3874
#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) || \
3875
    defined(OPENSSL_ALL) || defined(KEEP_OUR_CERT) || \
3876
    defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
3877
3878
/* used by JSSE (not a standard compatibility function) */
3879
WOLFSSL_ABI
3880
const byte* wolfSSL_X509_notBefore(WOLFSSL_X509* x509)
3881
{
3882
    WOLFSSL_ENTER("wolfSSL_X509_notBefore");
3883
3884
    if (x509 == NULL)
3885
        return NULL;
3886
3887
    XMEMSET(x509->notBeforeData, 0, sizeof(x509->notBeforeData));
3888
    x509->notBeforeData[0] = (byte)x509->notBefore.type;
3889
    x509->notBeforeData[1] = (byte)x509->notBefore.length;
3890
    XMEMCPY(&x509->notBeforeData[2], x509->notBefore.data, x509->notBefore.length);
3891
3892
    return x509->notBeforeData;
3893
}
3894
3895
/* used by JSSE (not a standard compatibility function) */
3896
WOLFSSL_ABI
3897
const byte* wolfSSL_X509_notAfter(WOLFSSL_X509* x509)
3898
{
3899
    WOLFSSL_ENTER("wolfSSL_X509_notAfter");
3900
3901
    if (x509 == NULL)
3902
        return NULL;
3903
3904
    XMEMSET(x509->notAfterData, 0, sizeof(x509->notAfterData));
3905
    x509->notAfterData[0] = (byte)x509->notAfter.type;
3906
    x509->notAfterData[1] = (byte)x509->notAfter.length;
3907
    XMEMCPY(&x509->notAfterData[2], x509->notAfter.data, x509->notAfter.length);
3908
3909
    return x509->notAfterData;
3910
}
3911
3912
int wolfSSL_X509_version(WOLFSSL_X509* x509)
3913
{
3914
    WOLFSSL_ENTER("wolfSSL_X509_version");
3915
3916
    if (x509 == NULL)
3917
        return 0;
3918
3919
    return x509->version;
3920
}
3921
#endif
3922
3923
#ifdef OPENSSL_EXTRA
3924
3925
/* get the buffer to be signed (tbs) from the WOLFSSL_X509 certificate
3926
    *
3927
    * outSz : gets set to the size of the buffer
3928
    * returns a pointer to the internal buffer at the location of TBS on
3929
    *         on success and NULL on failure.
3930
    */
3931
const unsigned char* wolfSSL_X509_get_tbs(WOLFSSL_X509* x509, int* outSz)
3932
{
3933
    int sz = 0, len;
3934
    unsigned int idx = 0, tmpIdx;
3935
    const unsigned char* der = NULL;
3936
    const unsigned char* tbs = NULL;
3937
3938
    if (x509 == NULL || outSz == NULL) {
3939
        return NULL;
3940
    }
3941
3942
    der = wolfSSL_X509_get_der(x509, &sz);
3943
    if (der == NULL) {
3944
        return NULL;
3945
    }
3946
3947
    if (GetSequence(der, &idx, &len, sz) < 0) {
3948
        return NULL;
3949
    }
3950
    tbs = der + idx;
3951
    tmpIdx = idx;
3952
    if (GetSequence(der, &idx, &len, sz) < 0) {
3953
        return NULL;
3954
    }
3955
    *outSz = len + (idx - tmpIdx);
3956
    return tbs;
3957
}
3958
3959
#ifdef WOLFSSL_SEP
3960
3961
/* copy oid into in buffer, at most *inOutSz bytes, if buffer is null will
3962
   malloc buffer, call responsible for freeing. Actual size returned in
3963
   *inOutSz. Requires inOutSz be non-null */
3964
byte* wolfSSL_X509_get_device_type(WOLFSSL_X509* x509, byte* in, int *inOutSz)
3965
{
3966
    int copySz;
3967
3968
    WOLFSSL_ENTER("wolfSSL_X509_get_dev_type");
3969
    if (inOutSz == NULL) return NULL;
3970
    if (!x509->deviceTypeSz) return in;
3971
3972
    copySz = min(*inOutSz, x509->deviceTypeSz);
3973
3974
    if (!in) {
3975
    #ifdef WOLFSSL_STATIC_MEMORY
3976
        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
3977
        return NULL;
3978
    #else
3979
        in = (byte*)XMALLOC(x509->deviceTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
3980
        if (!in) return in;
3981
        copySz = x509->deviceTypeSz;
3982
    #endif
3983
    }
3984
3985
    XMEMCPY(in, x509->deviceType, copySz);
3986
    *inOutSz = copySz;
3987
3988
    return in;
3989
}
3990
3991
3992
byte* wolfSSL_X509_get_hw_type(WOLFSSL_X509* x509, byte* in, int* inOutSz)
3993
{
3994
    int copySz;
3995
3996
    WOLFSSL_ENTER("wolfSSL_X509_get_hw_type");
3997
    if (inOutSz == NULL) return NULL;
3998
    if (!x509->hwTypeSz) return in;
3999
4000
    copySz = min(*inOutSz, x509->hwTypeSz);
4001
4002
    if (!in) {
4003
    #ifdef WOLFSSL_STATIC_MEMORY
4004
        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
4005
        return NULL;
4006
    #else
4007
        in = (byte*)XMALLOC(x509->hwTypeSz, 0, DYNAMIC_TYPE_OPENSSL);
4008
        if (!in) return in;
4009
        copySz = x509->hwTypeSz;
4010
    #endif
4011
    }
4012
4013
    XMEMCPY(in, x509->hwType, copySz);
4014
    *inOutSz = copySz;
4015
4016
    return in;
4017
}
4018
4019
4020
byte* wolfSSL_X509_get_hw_serial_number(WOLFSSL_X509* x509,byte* in,
4021
                                        int* inOutSz)
4022
{
4023
    int copySz;
4024
4025
    WOLFSSL_ENTER("wolfSSL_X509_get_hw_serial_number");
4026
    if (inOutSz == NULL) return NULL;
4027
    if (!x509->hwTypeSz) return in;
4028
4029
    copySz = min(*inOutSz, x509->hwSerialNumSz);
4030
4031
    if (!in) {
4032
    #ifdef WOLFSSL_STATIC_MEMORY
4033
        WOLFSSL_MSG("Using static memory -- please pass in a buffer");
4034
        return NULL;
4035
    #else
4036
        in = (byte*)XMALLOC(x509->hwSerialNumSz, 0, DYNAMIC_TYPE_OPENSSL);
4037
        if (!in) return in;
4038
        copySz = x509->hwSerialNumSz;
4039
    #endif
4040
    }
4041
4042
    XMEMCPY(in, x509->hwSerialNum, copySz);
4043
    *inOutSz = copySz;
4044
4045
    return in;
4046
}
4047
4048
#endif /* WOLFSSL_SEP */
4049
#endif /* OPENSSL_EXTRA */
4050
4051
/* require OPENSSL_EXTRA since wolfSSL_X509_free is wrapped by OPENSSL_EXTRA */
4052
#if defined(OPENSSL_EXTRA)
4053
4054
WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notBefore(const WOLFSSL_X509* x509)
4055
{
4056
    WOLFSSL_ENTER("wolfSSL_X509_get_notBefore");
4057
4058
    if (x509 == NULL)
4059
        return NULL;
4060
4061
    return (WOLFSSL_ASN1_TIME*)&x509->notBefore;
4062
}
4063
4064
4065
WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notAfter(const WOLFSSL_X509* x509)
4066
{
4067
    WOLFSSL_ENTER("wolfSSL_X509_get_notAfter");
4068
4069
    if (x509 == NULL)
4070
        return NULL;
4071
4072
    return (WOLFSSL_ASN1_TIME*)&x509->notAfter;
4073
}
4074
4075
4076
/* return 1 on success 0 on fail */
4077
int wolfSSL_sk_X509_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, WOLFSSL_X509* x509)
4078
{
4079
    WOLFSSL_ENTER("wolfSSL_sk_X509_push");
4080
4081
    if (sk == NULL || x509 == NULL) {
4082
        return WOLFSSL_FAILURE;
4083
    }
4084
4085
    return wolfSSL_sk_push(sk, x509);
4086
}
4087
4088
4089
/* Return and remove the last x509 pushed on stack */
4090
WOLFSSL_X509* wolfSSL_sk_X509_pop(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk)
4091
{
4092
    WOLFSSL_STACK* node;
4093
    WOLFSSL_X509*  x509;
4094
4095
    if (sk == NULL) {
4096
        return NULL;
4097
    }
4098
4099
    node = sk->next;
4100
    x509 = sk->data.x509;
4101
4102
    if (node != NULL) { /* update sk and remove node from stack */
4103
        sk->data.x509 = node->data.x509;
4104
        sk->next = node->next;
4105
        XFREE(node, NULL, DYNAMIC_TYPE_X509);
4106
    }
4107
    else { /* last x509 in stack */
4108
        sk->data.x509 = NULL;
4109
    }
4110
4111
    if (sk->num > 0) {
4112
        sk->num -= 1;
4113
    }
4114
4115
    return x509;
4116
}
4117
4118
/* Getter function for WOLFSSL_X509 pointer
4119
 *
4120
 * sk is the stack to retrieve pointer from
4121
 * i  is the index value in stack
4122
 *
4123
 * returns a pointer to a WOLFSSL_X509 structure on success and NULL on
4124
 *         fail
4125
 */
4126
WOLFSSL_X509* wolfSSL_sk_X509_value(STACK_OF(WOLFSSL_X509)* sk, int i)
4127
{
4128
    WOLFSSL_ENTER("wolfSSL_sk_X509_value");
4129
4130
    for (; sk != NULL && i > 0; i--)
4131
        sk = sk->next;
4132
4133
    if (i != 0 || sk == NULL)
4134
        return NULL;
4135
    return sk->data.x509;
4136
}
4137
4138
4139
/* Return and remove the first x509 pushed on stack */
4140
WOLFSSL_X509* wolfSSL_sk_X509_shift(WOLF_STACK_OF(WOLFSSL_X509)* sk)
4141
{
4142
    WOLFSSL_STACK* node;
4143
    WOLFSSL_X509*  x509;
4144
4145
    if (sk == NULL) {
4146
        return NULL;
4147
    }
4148
4149
    node = sk->next;
4150
    x509 = sk->data.x509;
4151
4152
    if (node != NULL) {
4153
        /* walk to end of stack to first node pushed, and remove it */
4154
        WOLFSSL_STACK* prevNode = sk;
4155
4156
        while (node->next != NULL) {
4157
            prevNode = node;
4158
            node = node->next;
4159
        }
4160
4161
        x509 = node->data.x509;
4162
        prevNode->next = NULL;
4163
        XFREE(node, NULL, DYNAMIC_TYPE_X509);
4164
    }
4165
    else { /* only one x509 in stack */
4166
        sk->data.x509 = NULL;
4167
    }
4168
4169
    if (sk->num > 0) {
4170
        sk->num -= 1;
4171
    }
4172
4173
    return x509;
4174
}
4175
4176
#endif /* OPENSSL_EXTRA */
4177
4178
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
4179
/* Free's all nodes in X509 stack. This is different then wolfSSL_sk_X509_free
4180
 * in that it free's the underlying objects pushed to the stack.
4181
 *
4182
 * sk  stack to free nodes in
4183
 * f   X509 free function
4184
 */
4185
void wolfSSL_sk_X509_pop_free(STACK_OF(WOLFSSL_X509)* sk,
4186
    void (*f) (WOLFSSL_X509*))
4187
{
4188
    WOLFSSL_ENTER("wolfSSL_sk_X509_pop_free");
4189
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
4190
}
4191
4192
4193
/* free just the stack structure */
4194
void wolfSSL_sk_X509_free(WOLF_STACK_OF(WOLFSSL_X509)* sk)
4195
{
4196
    wolfSSL_sk_free(sk);
4197
}
4198
4199
#ifdef HAVE_CRL
4200
WOLFSSL_STACK* wolfSSL_sk_X509_CRL_new(void)
4201
{
4202
    WOLFSSL_STACK* s = wolfSSL_sk_new_node(NULL);
4203
    if (s != NULL)
4204
        s->type = STACK_TYPE_X509_CRL;
4205
    return s;
4206
}
4207
4208
void wolfSSL_sk_X509_CRL_pop_free(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk,
4209
    void (*f) (WOLFSSL_X509_CRL*))
4210
{
4211
    WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_pop_free");
4212
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
4213
}
4214
4215
void wolfSSL_sk_X509_CRL_free(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk)
4216
{
4217
    wolfSSL_sk_X509_CRL_pop_free(sk, NULL);
4218
}
4219
4220
/* return 1 on success 0 on fail */
4221
int wolfSSL_sk_X509_CRL_push(WOLF_STACK_OF(WOLFSSL_X509_CRL)* sk, WOLFSSL_X509_CRL* crl)
4222
{
4223
    WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_push");
4224
4225
    if (sk == NULL || crl == NULL) {
4226
        return WOLFSSL_FAILURE;
4227
    }
4228
4229
    return wolfSSL_sk_push(sk, crl);
4230
}
4231
4232
WOLFSSL_X509_CRL* wolfSSL_sk_X509_CRL_value(WOLF_STACK_OF(WOLFSSL_X509)* sk,
4233
                                            int i)
4234
{
4235
    WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_value");
4236
    if (sk)
4237
        return (WOLFSSL_X509_CRL*)wolfSSL_sk_value(sk, i);
4238
    return NULL;
4239
}
4240
4241
int wolfSSL_sk_X509_CRL_num(WOLF_STACK_OF(WOLFSSL_X509)* sk)
4242
{
4243
    WOLFSSL_ENTER("wolfSSL_sk_X509_CRL_num");
4244
    if (sk)
4245
        return wolfSSL_sk_num(sk);
4246
    return 0;
4247
}
4248
#endif /* HAVE_CRL */
4249
4250
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
4251
4252
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_QT)
4253
/* return 1 on success 0 on fail */
4254
int wolfSSL_sk_ACCESS_DESCRIPTION_push(WOLF_STACK_OF(ACCESS_DESCRIPTION)* sk,
4255
                                              WOLFSSL_ACCESS_DESCRIPTION* a)
4256
{
4257
    WOLFSSL_ENTER("wolfSSL_sk_ACCESS_DESCRIPTION_push");
4258
4259
    return wolfSSL_sk_push(sk, a);
4260
}
4261
4262
/* Frees all nodes in ACCESS_DESCRIPTION stack
4263
*
4264
* sk stack of nodes to free
4265
* f  free function to use
4266
*/
4267
void wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(WOLFSSL_STACK* sk,
4268
    void (*f) (WOLFSSL_ACCESS_DESCRIPTION*))
4269
{
4270
   WOLFSSL_ENTER("wolfSSL_sk_ACCESS_DESCRIPTION_pop_free");
4271
   wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
4272
}
4273
4274
void wolfSSL_sk_ACCESS_DESCRIPTION_free(WOLFSSL_STACK* sk)
4275
{
4276
    wolfSSL_sk_free(sk);
4277
}
4278
4279
4280
/* AUTHORITY_INFO_ACCESS object is a stack of ACCESS_DESCRIPTION objects,
4281
 * to free the stack the WOLFSSL_ACCESS_DESCRIPTION stack free function is
4282
 * used */
4283
void wolfSSL_AUTHORITY_INFO_ACCESS_free(
4284
        WOLF_STACK_OF(WOLFSSL_ACCESS_DESCRIPTION)* sk)
4285
{
4286
    WOLFSSL_ENTER("wolfSSL_AUTHORITY_INFO_ACCESS_free");
4287
    wolfSSL_sk_ACCESS_DESCRIPTION_free(sk);
4288
}
4289
4290
void wolfSSL_AUTHORITY_INFO_ACCESS_pop_free(
4291
        WOLF_STACK_OF(WOLFSSL_ACCESS_DESCRIPTION)* sk,
4292
        void (*f) (WOLFSSL_ACCESS_DESCRIPTION*))
4293
{
4294
    WOLFSSL_ENTER("wolfSSL_AUTHORITY_INFO_ACCESS_free");
4295
    wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(sk, f);
4296
}
4297
4298
4299
void wolfSSL_ACCESS_DESCRIPTION_free(WOLFSSL_ACCESS_DESCRIPTION* a)
4300
{
4301
    WOLFSSL_ENTER("wolfSSL_ACCESS_DESCRIPTION_free");
4302
    if (a == NULL)
4303
        return;
4304
4305
    if (a->method)
4306
        wolfSSL_ASN1_OBJECT_free(a->method);
4307
    if (a->location)
4308
        wolfSSL_GENERAL_NAME_free(a->location);
4309
    XFREE(a, NULL, DYNAMIC_TYPE_X509_EXT);
4310
4311
    /* a = NULL, don't try to a or double free it */
4312
}
4313
#endif /* OPENSSL_EXTRA || WOLFSSL_QT */
4314
4315
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
4316
4317
/* Creates and returns new GENERAL_NAME structure */
4318
WOLFSSL_GENERAL_NAME* wolfSSL_GENERAL_NAME_new(void)
4319
{
4320
    WOLFSSL_GENERAL_NAME* gn;
4321
    WOLFSSL_ENTER("GENERAL_NAME_new");
4322
4323
    gn = (WOLFSSL_GENERAL_NAME*)XMALLOC(sizeof(WOLFSSL_GENERAL_NAME), NULL,
4324
                                                             DYNAMIC_TYPE_ASN1);
4325
    if (gn == NULL) {
4326
        return NULL;
4327
    }
4328
    XMEMSET(gn, 0, sizeof(WOLFSSL_GENERAL_NAME));
4329
4330
    gn->d.ia5 = wolfSSL_ASN1_STRING_new();
4331
    if (gn->d.ia5 == NULL) {
4332
        WOLFSSL_MSG("Issue creating ASN1_STRING struct");
4333
        wolfSSL_GENERAL_NAME_free(gn);
4334
        return NULL;
4335
    }
4336
    gn->type = GEN_IA5;
4337
    return gn;
4338
}
4339
4340
WOLFSSL_GENERAL_NAME* wolfSSL_GENERAL_NAME_dup(WOLFSSL_GENERAL_NAME* gn)
4341
{
4342
    WOLFSSL_GENERAL_NAME* dupl = NULL;
4343
4344
    WOLFSSL_ENTER("wolfSSL_GENERAL_NAME_dup");
4345
4346
    if (!gn) {
4347
        WOLFSSL_MSG("Bad parameter");
4348
        return NULL;
4349
    }
4350
4351
    if (!(dupl = wolfSSL_GENERAL_NAME_new())) {
4352
        WOLFSSL_MSG("wolfSSL_GENERAL_NAME_new error");
4353
        return NULL;
4354
    }
4355
4356
    wolfSSL_ASN1_STRING_free(dupl->d.ia5);
4357
    dupl->d.ia5 = NULL;
4358
    switch (gn->type) {
4359
    /* WOLFSSL_ASN1_STRING types */
4360
    case GEN_DNS:
4361
        if (!(dupl->d.dNSName = wolfSSL_ASN1_STRING_dup(gn->d.dNSName))) {
4362
            WOLFSSL_MSG("wolfSSL_ASN1_STRING_dup error");
4363
            goto error;
4364
        }
4365
        break;
4366
    case GEN_IPADD:
4367
        if (!(dupl->d.iPAddress = wolfSSL_ASN1_STRING_dup(gn->d.iPAddress))) {
4368
            WOLFSSL_MSG("wolfSSL_ASN1_STRING_dup error");
4369
            goto error;
4370
        }
4371
        break;
4372
    case GEN_EMAIL:
4373
        if (!(dupl->d.rfc822Name = wolfSSL_ASN1_STRING_dup(gn->d.rfc822Name))) {
4374
            WOLFSSL_MSG("wolfSSL_ASN1_STRING_dup error");
4375
            goto error;
4376
        }
4377
        break;
4378
    case GEN_URI:
4379
        if (!(dupl->d.uniformResourceIdentifier =
4380
                wolfSSL_ASN1_STRING_dup(gn->d.uniformResourceIdentifier))) {
4381
            WOLFSSL_MSG("wolfSSL_ASN1_STRING_dup error");
4382
            goto error;
4383
        }
4384
        break;
4385
    case GEN_OTHERNAME:
4386
        if (gn->d.otherName->value->type != V_ASN1_UTF8STRING) {
4387
            WOLFSSL_MSG("Unsupported othername value type");
4388
            goto error;
4389
        }
4390
        dupl->d.otherName = (WOLFSSL_ASN1_OTHERNAME*)XMALLOC(
4391
            sizeof(WOLFSSL_ASN1_OTHERNAME), NULL, DYNAMIC_TYPE_ASN1);
4392
        if (dupl->d.otherName == NULL) {
4393
            WOLFSSL_MSG("XMALLOC error");
4394
            goto error;
4395
        }
4396
        dupl->d.otherName->type_id = wolfSSL_ASN1_OBJECT_dup(
4397
            gn->d.otherName->type_id);
4398
        dupl->d.otherName->value = (WOLFSSL_ASN1_TYPE*)XMALLOC(
4399
            sizeof(WOLFSSL_ASN1_TYPE), NULL, DYNAMIC_TYPE_ASN1);
4400
        if (dupl->d.otherName->value != NULL) {
4401
            dupl->d.otherName->value->type = gn->d.otherName->value->type;
4402
            dupl->d.otherName->value->value.utf8string =
4403
                wolfSSL_ASN1_STRING_dup(
4404
                                      gn->d.otherName->value->value.utf8string);
4405
        }
4406
        if ((dupl->d.otherName->type_id == NULL) ||
4407
            (dupl->d.otherName->value == NULL) ||
4408
            (dupl->d.otherName->value->value.utf8string == NULL)) {
4409
            wolfSSL_ASN1_OBJECT_free(dupl->d.otherName->type_id);
4410
            wolfSSL_ASN1_TYPE_free(dupl->d.otherName->value);
4411
            XFREE(dupl->d.otherName, NULL, DYNAMIC_TYPE_ASN1);
4412
            dupl->d.otherName = NULL;
4413
            WOLFSSL_MSG("error duping othername");
4414
            goto error;
4415
        }
4416
        break;
4417
    case GEN_X400:
4418
    case GEN_DIRNAME:
4419
    case GEN_EDIPARTY:
4420
    case GEN_RID:
4421
    default:
4422
        WOLFSSL_MSG("Unrecognized or unsupported GENERAL_NAME type");
4423
        goto error;
4424
    }
4425
    dupl->type = gn->type;
4426
4427
    return dupl;
4428
error:
4429
    if (dupl) {
4430
        wolfSSL_GENERAL_NAME_free(dupl);
4431
    }
4432
    return NULL;
4433
}
4434
4435
/* Set an Othername in a general name.
4436
 *
4437
 * @param [out] gen     Pointer to the GENERAL_NAME where the othername is set.
4438
 * @param [in]  oid     Object ID (ie UPN).
4439
 * @param [in]  name    The actual name.
4440
 * @return  WOLFSSL_FAILURE on invalid parameter or memory error,
4441
 *          WOLFSSL_SUCCESS otherwise.
4442
 */
4443
int wolfSSL_GENERAL_NAME_set0_othername(WOLFSSL_GENERAL_NAME* gen,
4444
                                        ASN1_OBJECT* oid, ASN1_TYPE* value)
4445
{
4446
    WOLFSSL_ASN1_OBJECT *x = NULL;
4447
4448
    if ((gen == NULL) || (oid == NULL) || (value == NULL)) {
4449
        return WOLFSSL_FAILURE;
4450
    }
4451
4452
    x = wolfSSL_ASN1_OBJECT_dup(oid);
4453
    if (x == NULL) {
4454
        WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_dup() failed");
4455
        return WOLFSSL_FAILURE;
4456
    }
4457
4458
    gen->type = GEN_OTHERNAME;
4459
    gen->d.otherName->type_id = x;
4460
    gen->d.otherName->value = value;
4461
    return WOLFSSL_SUCCESS;
4462
}
4463
4464
/* return 1 on success 0 on fail */
4465
int wolfSSL_sk_GENERAL_NAME_push(WOLFSSL_GENERAL_NAMES* sk,
4466
                                 WOLFSSL_GENERAL_NAME* gn)
4467
{
4468
    WOLFSSL_STACK* node;
4469
    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_push");
4470
4471
    if (sk == NULL || gn == NULL) {
4472
        return WOLFSSL_FAILURE;
4473
    }
4474
4475
    /* no previous values in stack */
4476
    if (sk->data.gn == NULL) {
4477
        sk->data.gn = gn;
4478
        sk->num += 1;
4479
4480
        return WOLFSSL_SUCCESS;
4481
    }
4482
4483
    /* stack already has value(s) create a new node and add more */
4484
    node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
4485
                                                             DYNAMIC_TYPE_ASN1);
4486
    if (node == NULL) {
4487
        WOLFSSL_MSG("Memory error");
4488
        return WOLFSSL_FAILURE;
4489
    }
4490
    XMEMSET(node, 0, sizeof(WOLFSSL_STACK));
4491
4492
    /* push new obj onto head of stack */
4493
    node->type    = STACK_TYPE_GEN_NAME;
4494
    node->data.gn = sk->data.gn;
4495
    node->next    = sk->next;
4496
    sk->next      = node;
4497
    sk->data.gn   = gn;
4498
    sk->num      += 1;
4499
4500
    return WOLFSSL_SUCCESS;
4501
}
4502
4503
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
4504
4505
#ifdef OPENSSL_EXTRA
4506
4507
/* Returns the general name at index i from the stack
4508
 *
4509
 * sk  stack to get general name from
4510
 * idx index to get
4511
 *
4512
 * return a pointer to the internal node of the stack
4513
 */
4514
WOLFSSL_GENERAL_NAME* wolfSSL_sk_GENERAL_NAME_value(WOLFSSL_STACK* sk, int idx)
4515
{
4516
    WOLFSSL_STACK* ret;
4517
4518
    if (sk == NULL) {
4519
        return NULL;
4520
    }
4521
4522
    ret = wolfSSL_sk_get_node(sk, idx);
4523
    if (ret != NULL) {
4524
        return ret->data.gn;
4525
    }
4526
    return NULL;
4527
}
4528
4529
/* Gets the number of nodes in the stack
4530
 *
4531
 * sk  stack to get the number of nodes from
4532
 *
4533
 * returns the number of nodes, -1 if no nodes
4534
 */
4535
int wolfSSL_sk_GENERAL_NAME_num(WOLFSSL_STACK* sk)
4536
{
4537
    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_num");
4538
4539
    if (sk == NULL) {
4540
        return -1;
4541
    }
4542
4543
    return (int)sk->num;
4544
}
4545
4546
/* Allocates an empty GENERAL NAME stack */
4547
WOLFSSL_STACK* wolfSSL_sk_GENERAL_NAME_new(void *cmpFunc) {
4548
    WOLFSSL_STACK* sk = NULL;
4549
    (void)cmpFunc;
4550
    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_new");
4551
4552
    sk = wolfSSL_sk_new_null();
4553
    if (sk != NULL) {
4554
        sk->type = STACK_TYPE_GEN_NAME;
4555
    }
4556
4557
    return sk;
4558
}
4559
#endif /* OPENSSL_EXTRA */
4560
4561
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
4562
4563
/* Frees all nodes in a GENERAL NAME stack
4564
 *
4565
 * sk stack of nodes to free
4566
 * f  free function to use, not called with wolfSSL
4567
 */
4568
void wolfSSL_sk_GENERAL_NAME_pop_free(WOLFSSL_STACK* sk,
4569
        void (*f) (WOLFSSL_GENERAL_NAME*))
4570
{
4571
    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_pop_free");
4572
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
4573
}
4574
4575
void wolfSSL_sk_GENERAL_NAME_free(WOLFSSL_STACK* sk)
4576
{
4577
    WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_free");
4578
    wolfSSL_sk_X509_pop_free(sk, NULL);
4579
}
4580
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
4581
4582
#ifdef OPENSSL_EXTRA
4583
static void wolfSSL_DIST_POINT_NAME_free(WOLFSSL_DIST_POINT_NAME* dpn)
4584
{
4585
    if (dpn != NULL) {
4586
        if (dpn->name.fullname != NULL) {
4587
            wolfSSL_sk_X509_pop_free(dpn->name.fullname, NULL);
4588
        }
4589
        XFREE(dpn, NULL, DYNAMIC_TYPE_OPENSSL);
4590
    }
4591
}
4592
4593
4594
/* returns new pointer on success and NULL on fail */
4595
static WOLFSSL_DIST_POINT_NAME* wolfSSL_DIST_POINT_NAME_new(void)
4596
{
4597
    WOLFSSL_DIST_POINT_NAME* dpn = NULL;
4598
    WOLFSSL_GENERAL_NAMES* gns = NULL;
4599
4600
    dpn = (WOLFSSL_DIST_POINT_NAME*)XMALLOC(sizeof(WOLFSSL_DIST_POINT_NAME),
4601
                                            NULL, DYNAMIC_TYPE_OPENSSL);
4602
    if (dpn == NULL) {
4603
        return NULL;
4604
    }
4605
    XMEMSET(dpn, 0, sizeof(WOLFSSL_DIST_POINT_NAME));
4606
4607
    gns = wolfSSL_sk_new_null();
4608
    if (gns == NULL) {
4609
        WOLFSSL_MSG("wolfSSL_sk_new_null error");
4610
        XFREE(dpn, NULL, DYNAMIC_TYPE_OPENSSL);
4611
        return NULL;
4612
    }
4613
    gns->type = STACK_TYPE_GEN_NAME;
4614
4615
    /* DIST_POINT_NAME type may be 0 or 1, indicating whether fullname or
4616
     * relativename is used. See: RFC 5280 section 4.2.1.13 */
4617
    dpn->name.fullname = gns;
4618
    dpn->type = 0;
4619
4620
    return dpn;
4621
}
4622
4623
4624
/* Creates and returns new DIST_POINT structure */
4625
WOLFSSL_DIST_POINT* wolfSSL_DIST_POINT_new(void)
4626
{
4627
    WOLFSSL_DIST_POINT* dp = NULL;
4628
    WOLFSSL_DIST_POINT_NAME* dpn = NULL;
4629
4630
    WOLFSSL_ENTER("wolfSSL_DIST_POINT_new");
4631
4632
    dp = (WOLFSSL_DIST_POINT*)XMALLOC(sizeof(WOLFSSL_DIST_POINT), NULL,
4633
                                      DYNAMIC_TYPE_OPENSSL);
4634
    if (dp == NULL) {
4635
        return NULL;
4636
    }
4637
    XMEMSET(dp, 0, sizeof(WOLFSSL_DIST_POINT));
4638
4639
    dpn = wolfSSL_DIST_POINT_NAME_new();
4640
    if (dpn == NULL) {
4641
        XFREE(dp, NULL, DYNAMIC_TYPE_OPENSSL);
4642
        return NULL;
4643
    }
4644
    dp->distpoint = dpn;
4645
4646
    return dp;
4647
}
4648
4649
4650
/* Frees DIST_POINT objects.
4651
*/
4652
void wolfSSL_DIST_POINT_free(WOLFSSL_DIST_POINT* dp)
4653
{
4654
    WOLFSSL_ENTER("wolfSSL_DIST_POINT_free");
4655
    if (dp != NULL) {
4656
        wolfSSL_DIST_POINT_NAME_free(dp->distpoint);
4657
        XFREE(dp, NULL, DYNAMIC_TYPE_OPENSSL);
4658
    }
4659
}
4660
4661
void wolfSSL_DIST_POINTS_free(WOLFSSL_DIST_POINTS *dps)
4662
{
4663
    WOLFSSL_ENTER("wolfSSL_DIST_POINTS_free");
4664
4665
    if (dps == NULL) {
4666
        return;
4667
    }
4668
4669
    wolfSSL_sk_free(dps);
4670
}
4671
4672
/* return 1 on success 0 on fail */
4673
int wolfSSL_sk_DIST_POINT_push(WOLFSSL_DIST_POINTS* sk, WOLFSSL_DIST_POINT* dp)
4674
{
4675
    WOLFSSL_ENTER("wolfSSL_sk_DIST_POINT_push");
4676
4677
    if (sk == NULL || dp == NULL) {
4678
        return WOLFSSL_FAILURE;
4679
    }
4680
4681
    return wolfSSL_sk_push(sk, dp);
4682
}
4683
4684
/* Returns the CRL dist point at index i from the stack
4685
 *
4686
 * sk  stack to get general name from
4687
 * idx index to get
4688
 *
4689
 * return a pointer to the internal node of the stack
4690
 */
4691
WOLFSSL_DIST_POINT* wolfSSL_sk_DIST_POINT_value(WOLFSSL_STACK* sk, int idx)
4692
{
4693
    if (sk == NULL) {
4694
        return NULL;
4695
    }
4696
4697
    return (WOLFSSL_DIST_POINT*)wolfSSL_sk_value(sk, idx);
4698
}
4699
4700
/* Gets the number of nodes in the stack
4701
 *
4702
 * sk  stack to get the number of nodes from
4703
 *
4704
 * returns the number of nodes, -1 if no nodes
4705
 */
4706
int wolfSSL_sk_DIST_POINT_num(WOLFSSL_STACK* sk)
4707
{
4708
    WOLFSSL_ENTER("wolfSSL_sk_DIST_POINT_num");
4709
4710
    if (sk == NULL) {
4711
        return -1;
4712
    }
4713
4714
    return wolfSSL_sk_num(sk);
4715
}
4716
4717
/* Frees all nodes in a DIST_POINT stack
4718
 *
4719
 * sk stack of nodes to free
4720
 * f  free function to use
4721
 */
4722
void wolfSSL_sk_DIST_POINT_pop_free(WOLFSSL_STACK* sk,
4723
        void (*f) (WOLFSSL_DIST_POINT*))
4724
{
4725
    WOLFSSL_ENTER("wolfSSL_sk_DIST_POINT_pop_free");
4726
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
4727
}
4728
4729
void wolfSSL_sk_DIST_POINT_free(WOLFSSL_STACK* sk)
4730
{
4731
    WOLFSSL_ENTER("wolfSSL_sk_DIST_POINT_free");
4732
    wolfSSL_sk_free(sk);
4733
}
4734
4735
/* returns the number of nodes in stack on success and WOLFSSL_FATAL_ERROR
4736
 * on fail */
4737
int wolfSSL_sk_ACCESS_DESCRIPTION_num(WOLFSSL_STACK* sk)
4738
{
4739
    if (sk == NULL) {
4740
        return WOLFSSL_FATAL_ERROR;
4741
    }
4742
4743
    return (int)sk->num;
4744
}
4745
4746
/* returns NULL on fail and pointer to internal data on success */
4747
WOLFSSL_ACCESS_DESCRIPTION* wolfSSL_sk_ACCESS_DESCRIPTION_value(
4748
        WOLFSSL_STACK* sk, int idx)
4749
{
4750
    WOLFSSL_STACK* ret;
4751
4752
    if (sk == NULL) {
4753
        return NULL;
4754
    }
4755
4756
    ret = wolfSSL_sk_get_node(sk, idx);
4757
    if (ret != NULL) {
4758
        return ret->data.access;
4759
    }
4760
    return NULL;
4761
}
4762
#endif /* OPENSSL_EXTRA */
4763
4764
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
4765
/* free's the internal type for the general name */
4766
static void wolfSSL_GENERAL_NAME_type_free(WOLFSSL_GENERAL_NAME* name)
4767
{
4768
    if (name != NULL) {
4769
        switch (name->type) {
4770
        case GEN_IA5:
4771
            wolfSSL_ASN1_STRING_free(name->d.ia5);
4772
            name->d.ia5 = NULL;
4773
            break;
4774
        case GEN_EMAIL:
4775
            wolfSSL_ASN1_STRING_free(name->d.rfc822Name);
4776
            name->d.rfc822Name = NULL;
4777
            break;
4778
        case GEN_DNS:
4779
            wolfSSL_ASN1_STRING_free(name->d.dNSName);
4780
            name->d.dNSName = NULL;
4781
            break;
4782
        case GEN_DIRNAME:
4783
            wolfSSL_X509_NAME_free(name->d.dirn);
4784
            name->d.dirn = NULL;
4785
            break;
4786
        case GEN_URI:
4787
            wolfSSL_ASN1_STRING_free(name->d.uniformResourceIdentifier);
4788
            name->d.uniformResourceIdentifier = NULL;
4789
            break;
4790
        case GEN_IPADD:
4791
            wolfSSL_ASN1_STRING_free(name->d.iPAddress);
4792
            name->d.iPAddress = NULL;
4793
            break;
4794
        case GEN_RID:
4795
            wolfSSL_ASN1_OBJECT_free(name->d.registeredID);
4796
            name->d.registeredID = NULL;
4797
            break;
4798
        case GEN_OTHERNAME:
4799
            if (name->d.otherName != NULL) {
4800
                wolfSSL_ASN1_OBJECT_free(name->d.otherName->type_id);
4801
                wolfSSL_ASN1_TYPE_free(name->d.otherName->value);
4802
                XFREE(name->d.otherName, NULL, DYNAMIC_TYPE_ASN1);
4803
                name->d.otherName = NULL;
4804
            }
4805
            break;
4806
        case GEN_X400:
4807
            /* Unsupported: fall through */
4808
        case GEN_EDIPARTY:
4809
            /* Unsupported: fall through */
4810
        default:
4811
            WOLFSSL_MSG("wolfSSL_GENERAL_NAME_type_free: possible leak");
4812
            break;
4813
        }
4814
    }
4815
}
4816
4817
/* sets the general name type and free's the existing one
4818
 * can fail with a memory error if malloc fails or bad arg error
4819
 * otherwise return WOLFSSL_SUCCESS */
4820
int wolfSSL_GENERAL_NAME_set_type(WOLFSSL_GENERAL_NAME* name, int typ)
4821
{
4822
    int ret = WOLFSSL_SUCCESS;
4823
4824
    if (name != NULL) {
4825
        wolfSSL_GENERAL_NAME_type_free(name);
4826
        name->type = typ;
4827
4828
        switch (typ) {
4829
            case GEN_URI:
4830
                name->d.uniformResourceIdentifier = wolfSSL_ASN1_STRING_new();
4831
                if (name->d.uniformResourceIdentifier == NULL)
4832
                    ret = MEMORY_E;
4833
                break;
4834
            default:
4835
                name->type = GEN_IA5;
4836
                name->d.ia5 = wolfSSL_ASN1_STRING_new();
4837
                if (name->d.ia5 == NULL)
4838
                    ret = MEMORY_E;
4839
        }
4840
    }
4841
    else {
4842
        ret = BAD_FUNC_ARG;
4843
    }
4844
4845
    return ret;
4846
}
4847
4848
/* Set the value in a general name. This is a compat layer API.
4849
 *
4850
 * @param [out] a       Pointer to the GENERAL_NAME where the othername is set.
4851
 * @param [in]  type    The type of this general name.
4852
 * @param [in]  value   The ASN.1 string that is the value.
4853
 * @return none
4854
 * @note the set0 indicates we take ownership so the user does NOT free value.
4855
 */
4856
void wolfSSL_GENERAL_NAME_set0_value(WOLFSSL_GENERAL_NAME *a, int type,
4857
                                     void *value)
4858
{
4859
    WOLFSSL_ASN1_STRING *val = (WOLFSSL_ASN1_STRING *)value;
4860
    if (a == NULL) {
4861
        WOLFSSL_MSG("a is NULL");
4862
        return;
4863
    }
4864
4865
    if (val == NULL) {
4866
        WOLFSSL_MSG("value is NULL");
4867
        return;
4868
    }
4869
4870
    if (type != GEN_DNS) {
4871
        WOLFSSL_MSG("Only GEN_DNS is supported");
4872
        return;
4873
    }
4874
4875
    wolfSSL_GENERAL_NAME_type_free(a);
4876
    a->type = type;
4877
    if (type == GEN_DNS) {
4878
        a->d.dNSName = val;
4879
    }
4880
}
4881
4882
/* Frees GENERAL_NAME objects.
4883
*/
4884
void wolfSSL_GENERAL_NAME_free(WOLFSSL_GENERAL_NAME* name)
4885
{
4886
    WOLFSSL_ENTER("wolfSSL_GENERAL_NAME_Free");
4887
    if (name != NULL) {
4888
        wolfSSL_GENERAL_NAME_type_free(name);
4889
        XFREE(name, NULL, DYNAMIC_TYPE_OPENSSL);
4890
    }
4891
}
4892
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL*/
4893
4894
#ifdef OPENSSL_EXTRA
4895
void wolfSSL_GENERAL_NAMES_free(WOLFSSL_GENERAL_NAMES *gens)
4896
{
4897
    WOLFSSL_ENTER("wolfSSL_GENERAL_NAMES_free");
4898
4899
    if (gens == NULL) {
4900
        return;
4901
    }
4902
4903
    wolfSSL_sk_GENERAL_NAME_free(gens);
4904
}
4905
4906
void wolfSSL_EXTENDED_KEY_USAGE_free(WOLFSSL_STACK * sk)
4907
{
4908
    WOLFSSL_ENTER("wolfSSL_EXTENDED_KEY_USAGE_free");
4909
4910
    if (sk == NULL) {
4911
        return;
4912
    }
4913
4914
    wolfSSL_sk_X509_pop_free(sk, NULL);
4915
}
4916
4917
#if defined(OPENSSL_ALL) && !defined(NO_BIO)
4918
/* Outputs name string of the given WOLFSSL_GENERAL_NAME_OBJECT to WOLFSSL_BIO.
4919
 * Can handle following GENERAL_NAME_OBJECT types:
4920
 *  - GEN_OTHERNAME #
4921
 *  - GEN_EMAIL
4922
 *  - GEN_DNS
4923
 *  - GEN_X400  #
4924
 *  - GEN_DIRNAME
4925
 *  - GEN_EDIPARTY #
4926
 *  - GEN_URI
4927
 *  - GEN_RID
4928
 * The each name string to be output has "typename:namestring" format.
4929
 * For instance, email name string will be output as "email:info@wolfssl.com".
4930
 * However,some types above marked with "#" will be output with
4931
 * "typename:<unsupported>".
4932
 *
4933
 * Parameters:
4934
 *  - out: WOLFSSL_BIO object which is the output destination
4935
 *  - gen: WOLFSSL_GENERAL_NAME object to be output its name
4936
 *
4937
 * Returns WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure.
4938
 */
4939
int wolfSSL_GENERAL_NAME_print(WOLFSSL_BIO* out, WOLFSSL_GENERAL_NAME* gen)
4940
{
4941
    int ret, i;
4942
    unsigned int wd;
4943
    unsigned char* p;
4944
    (void)wd;
4945
    (void)p;
4946
    (void)i;
4947
    WOLFSSL_ENTER("wolfSSL_GENERAL_NAME_print");
4948
4949
    if (out == NULL || gen == NULL)
4950
        return WOLFSSL_FAILURE;
4951
4952
    ret = WOLFSSL_FAILURE;
4953
    switch (gen->type)
4954
    {
4955
    case GEN_OTHERNAME:
4956
        ret = wolfSSL_BIO_printf(out, "othername:<unsupported>");
4957
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
4958
        break;
4959
4960
    case GEN_EMAIL:
4961
        ret = wolfSSL_BIO_printf(out, "email:");
4962
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
4963
        if (ret == WOLFSSL_SUCCESS)
4964
        {
4965
            ret = wolfSSL_ASN1_STRING_print(out, gen->d.rfc822Name);
4966
        }
4967
        break;
4968
4969
    case GEN_DNS:
4970
        ret = wolfSSL_BIO_printf(out, "DNS:");
4971
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
4972
        if (ret == WOLFSSL_SUCCESS) {
4973
            ret = wolfSSL_BIO_printf(out, "%s", gen->d.dNSName->strData);
4974
            ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
4975
        }
4976
        break;
4977
4978
    case GEN_X400:
4979
        ret = wolfSSL_BIO_printf(out, "X400Name:<unsupported>");
4980
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
4981
        break;
4982
4983
    case GEN_DIRNAME:
4984
        ret = wolfSSL_BIO_printf(out, "DirName:");
4985
        if (ret == WOLFSSL_SUCCESS) {
4986
            ret = wolfSSL_X509_NAME_print_ex(out, gen->d.directoryName, 0,
4987
                                                         XN_FLAG_ONELINE);
4988
        }
4989
        break;
4990
4991
    case GEN_EDIPARTY:
4992
        ret = wolfSSL_BIO_printf(out, "EdiPartyName:<unsupported>");
4993
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
4994
        break;
4995
4996
    case GEN_URI:
4997
        ret = wolfSSL_BIO_printf(out, "URI:");
4998
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
4999
        if (ret == WOLFSSL_SUCCESS) {
5000
            ret = wolfSSL_ASN1_STRING_print(out,
5001
                                    gen->d.uniformResourceIdentifier);
5002
        }
5003
        break;
5004
5005
    case GEN_IPADD:
5006
        ret = wolfSSL_BIO_printf(out, "IP Address");
5007
        ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
5008
        if (ret == WOLFSSL_SUCCESS) {
5009
5010
            if (!gen->d.iPAddress->length) {
5011
                ret = WOLFSSL_FAILURE;
5012
                break;
5013
            }
5014
            p = (unsigned char*)gen->d.iPAddress->strData;
5015
5016
            if (gen->d.iPAddress->length == 4) {
5017
                ret = wolfSSL_BIO_printf(out, ":%d.%d.%d.%d",
5018
                                  p[0],p[1],p[2],p[3]);
5019
            }
5020
            else if (gen->d.iPAddress->length == 16) {
5021
5022
                for (i = 0; i < 16 && ret == WOLFSSL_SUCCESS;) {
5023
                    wd = p[i] << 8 | p[i+1];
5024
5025
                    i += 2;
5026
                    ret = wolfSSL_BIO_printf(out, ":%X", wd);
5027
                    ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
5028
                }
5029
            }
5030
            else {
5031
                ret = wolfSSL_BIO_printf(out, "<unsupported>");
5032
            }
5033
            ret = (ret > 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
5034
        }
5035
        break;
5036
5037
    case GEN_RID:
5038
        ret = wolfSSL_BIO_printf(out, "Registered ID:");
5039
        if (ret == WOLFSSL_SUCCESS) {
5040
            ret = wolfSSL_i2a_ASN1_OBJECT(out, gen->d.registeredID);
5041
        }
5042
        break;
5043
5044
    default:
5045
        /* unsupported type */
5046
        break;
5047
    }
5048
5049
    if (ret == WOLFSSL_FAILURE)
5050
        return WOLFSSL_FAILURE;
5051
    else
5052
        return WOLFSSL_SUCCESS;
5053
}
5054
#endif /* OPENSSL_ALL */
5055
5056
WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* wolfSSL_sk_X509_EXTENSION_new_null(void)
5057
{
5058
    WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL);
5059
    if (sk) {
5060
        sk->type = STACK_TYPE_X509_EXT;
5061
    }
5062
5063
    return (WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)*)sk;;
5064
}
5065
5066
/* returns the number of nodes on the stack */
5067
int wolfSSL_sk_X509_EXTENSION_num(WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk)
5068
{
5069
    if (sk != NULL) {
5070
        return (int)sk->num;
5071
    }
5072
    return WOLFSSL_FATAL_ERROR;
5073
}
5074
5075
5076
/* returns null on failure and pointer to internal value on success */
5077
WOLFSSL_X509_EXTENSION* wolfSSL_sk_X509_EXTENSION_value(
5078
        WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk, int idx)
5079
{
5080
    WOLFSSL_STACK* ret;
5081
5082
    if (sk == NULL) {
5083
        return NULL;
5084
    }
5085
5086
    ret = wolfSSL_sk_get_node(sk, idx);
5087
    if (ret != NULL) {
5088
        return ret->data.ext;
5089
    }
5090
    return NULL;
5091
}
5092
5093
/* frees all of the nodes and the values in stack */
5094
void wolfSSL_sk_X509_EXTENSION_pop_free(
5095
        WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk,
5096
        void (*f) (WOLFSSL_X509_EXTENSION*))
5097
{
5098
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
5099
}
5100
5101
#endif /* OPENSSL_EXTRA */
5102
5103
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
5104
5105
WOLFSSL_X509* wolfSSL_X509_d2i_fp(WOLFSSL_X509** x509, XFILE file)
5106
{
5107
    WOLFSSL_X509* newX509 = NULL;
5108
5109
    WOLFSSL_ENTER("wolfSSL_X509_d2i_fp");
5110
5111
    if (file != XBADFILE) {
5112
        byte* fileBuffer = NULL;
5113
        long sz = 0;
5114
5115
        if (XFSEEK(file, 0, XSEEK_END) != 0)
5116
            return NULL;
5117
        sz = XFTELL(file);
5118
        if (XFSEEK(file, 0, XSEEK_SET) != 0)
5119
            return NULL;
5120
5121
        if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
5122
            WOLFSSL_MSG("X509_d2i file size error");
5123
            return NULL;
5124
        }
5125
5126
        fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
5127
        if (fileBuffer != NULL) {
5128
            int ret = (int)XFREAD(fileBuffer, 1, sz, file);
5129
            if (ret == sz) {
5130
                newX509 = wolfSSL_X509_d2i(NULL, fileBuffer, (int)sz);
5131
            }
5132
            XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
5133
        }
5134
    }
5135
5136
    if (x509 != NULL)
5137
        *x509 = newX509;
5138
5139
    return newX509;
5140
}
5141
5142
#endif /* OPENSSL_EXTRA && !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM */
5143
5144
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
5145
    defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
5146
5147
#ifndef NO_FILESYSTEM
5148
WOLFSSL_ABI
5149
WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format)
5150
{
5151
#ifdef WOLFSSL_SMALL_STACK
5152
    byte  staticBuffer[1]; /* force heap usage */
5153
#else
5154
    byte  staticBuffer[FILE_BUFFER_SIZE];
5155
#endif
5156
    byte* fileBuffer = staticBuffer;
5157
    int   dynamic = 0;
5158
    int   ret;
5159
    long  sz = 0;
5160
    XFILE file;
5161
5162
    WOLFSSL_X509* x509 = NULL;
5163
5164
    /* Check the inputs */
5165
    if ((fname == NULL) ||
5166
        (format != WOLFSSL_FILETYPE_ASN1 && format != WOLFSSL_FILETYPE_PEM))
5167
        return NULL;
5168
5169
    file = XFOPEN(fname, "rb");
5170
    if (file == XBADFILE)
5171
        return NULL;
5172
5173
    if (XFSEEK(file, 0, XSEEK_END) != 0){
5174
        XFCLOSE(file);
5175
        return NULL;
5176
    }
5177
    sz = XFTELL(file);
5178
    if (XFSEEK(file, 0, XSEEK_SET) != 0){
5179
        XFCLOSE(file);
5180
        return NULL;
5181
    }
5182
5183
    if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
5184
        WOLFSSL_MSG("X509_load_certificate_file size error");
5185
        XFCLOSE(file);
5186
        return NULL;
5187
    }
5188
5189
    if (sz > (long)sizeof(staticBuffer)) {
5190
        fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
5191
        if (fileBuffer == NULL) {
5192
            XFCLOSE(file);
5193
            return NULL;
5194
        }
5195
        dynamic = 1;
5196
    }
5197
5198
    ret = (int)XFREAD(fileBuffer, 1, sz, file);
5199
    if (ret != sz) {
5200
        XFCLOSE(file);
5201
        if (dynamic)
5202
            XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
5203
        return NULL;
5204
    }
5205
5206
    XFCLOSE(file);
5207
5208
    x509 = wolfSSL_X509_load_certificate_buffer(fileBuffer, (int)sz, format);
5209
5210
    if (dynamic)
5211
        XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
5212
5213
    return x509;
5214
}
5215
#endif /* !NO_FILESYSTEM */
5216
5217
static WOLFSSL_X509* loadX509orX509REQFromBuffer(
5218
    const unsigned char* buf, int sz, int format, int type)
5219
{
5220
5221
    int ret = 0;
5222
    WOLFSSL_X509* x509 = NULL;
5223
    DerBuffer* der = NULL;
5224
5225
    WOLFSSL_ENTER("wolfSSL_X509_load_certificate_ex");
5226
5227
    if (format == WOLFSSL_FILETYPE_PEM) {
5228
    #ifdef WOLFSSL_PEM_TO_DER
5229
        ret = PemToDer(buf, sz, type, &der, NULL, NULL, NULL);
5230
        if (ret != 0) {
5231
            FreeDer(&der);
5232
        }
5233
    #else
5234
        ret = NOT_COMPILED_IN;
5235
    #endif
5236
    }
5237
    else {
5238
        ret = AllocDer(&der, (word32)sz, type, NULL);
5239
        if (ret == 0) {
5240
            XMEMCPY(der->buffer, buf, sz);
5241
        }
5242
    }
5243
5244
    /* At this point we want `der` to have the certificate in DER format */
5245
    /* ready to be decoded. */
5246
    if (der != NULL && der->buffer != NULL) {
5247
    #ifdef WOLFSSL_SMALL_STACK
5248
        DecodedCert* cert;
5249
    #else
5250
        DecodedCert  cert[1];
5251
    #endif
5252
5253
    #ifdef WOLFSSL_SMALL_STACK
5254
        cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
5255
                                     DYNAMIC_TYPE_DCERT);
5256
        if (cert == NULL) {
5257
            ret = MEMORY_ERROR;
5258
        }
5259
        else
5260
    #endif
5261
        {
5262
            InitDecodedCert(cert, der->buffer, der->length, NULL);
5263
            ret = ParseCertRelative(cert, type, 0, NULL);
5264
            if (ret == 0) {
5265
                x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
5266
                                                             DYNAMIC_TYPE_X509);
5267
                if (x509 != NULL) {
5268
                    InitX509(x509, 1, NULL);
5269
                    ret = CopyDecodedToX509(x509, cert);
5270
                    if (ret != 0) {
5271
                        wolfSSL_X509_free(x509);
5272
                        x509 = NULL;
5273
                    }
5274
                }
5275
                else {
5276
                    ret = MEMORY_ERROR;
5277
                }
5278
            }
5279
5280
            FreeDecodedCert(cert);
5281
        #ifdef WOLFSSL_SMALL_STACK
5282
            XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
5283
        #endif
5284
        }
5285
5286
        FreeDer(&der);
5287
    }
5288
5289
    if (ret != 0) {
5290
        WOLFSSL_ERROR(ret);
5291
    }
5292
5293
    return x509;
5294
}
5295
5296
WOLFSSL_X509* wolfSSL_X509_load_certificate_buffer(
5297
    const unsigned char* buf, int sz, int format)
5298
{
5299
    return loadX509orX509REQFromBuffer(buf, sz,
5300
            format, CERT_TYPE);
5301
}
5302
5303
#ifdef WOLFSSL_CERT_REQ
5304
WOLFSSL_X509* wolfSSL_X509_REQ_load_certificate_buffer(
5305
    const unsigned char* buf, int sz, int format)
5306
{
5307
    return loadX509orX509REQFromBuffer(buf, sz,
5308
            format, CERTREQ_TYPE);
5309
}
5310
#endif
5311
5312
#endif /* KEEP_PEER_CERT || SESSION_CERTS */
5313
5314
#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(KEEP_PEER_CERT) || \
5315
    defined(SESSION_CERTS)
5316
/* Smaller subset of X509 compatibility functions. Avoid increasing the size of
5317
 * this subset and its memory usage */
5318
5319
/* returns a pointer to a new WOLFSSL_X509 structure on success and NULL on
5320
 * fail
5321
 */
5322
WOLFSSL_X509* wolfSSL_X509_new(void)
5323
{
5324
    WOLFSSL_X509* x509;
5325
5326
    x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
5327
            DYNAMIC_TYPE_X509);
5328
    if (x509 != NULL) {
5329
        InitX509(x509, 1, NULL);
5330
    }
5331
5332
    return x509;
5333
}
5334
5335
WOLFSSL_ABI
5336
WOLFSSL_X509_NAME* wolfSSL_X509_get_subject_name(WOLFSSL_X509* cert)
5337
{
5338
    WOLFSSL_ENTER("wolfSSL_X509_get_subject_name");
5339
    if (cert)
5340
        return &cert->subject;
5341
    return NULL;
5342
}
5343
5344
WOLFSSL_ABI
5345
WOLFSSL_X509_NAME* wolfSSL_X509_get_issuer_name(WOLFSSL_X509* cert)
5346
{
5347
    WOLFSSL_ENTER("wolfSSL_X509_get_issuer_name");
5348
    if (cert)
5349
        return &cert->issuer;
5350
    return NULL;
5351
}
5352
5353
5354
int wolfSSL_X509_get_signature_type(WOLFSSL_X509* x509)
5355
{
5356
    int type = 0;
5357
5358
    WOLFSSL_ENTER("wolfSSL_X509_get_signature_type");
5359
5360
    if (x509 != NULL)
5361
        type = x509->sigOID;
5362
5363
    return type;
5364
}
5365
5366
#if defined(OPENSSL_EXTRA_X509_SMALL)
5367
5368
int wolfSSL_X509_NAME_get_sz(WOLFSSL_X509_NAME* name)
5369
{
5370
    WOLFSSL_ENTER("wolfSSL_X509_NAME_get_sz");
5371
    if (!name)
5372
        return -1;
5373
    return name->sz;
5374
}
5375
5376
/* Searches for the first ENTRY of type NID
5377
 * idx is the location to start searching from, the value at when the entry was
5378
 *     found is stored into idx
5379
 * returns a pointer to the entry on success and null on fail */
5380
static WOLFSSL_X509_NAME_ENTRY* GetEntryByNID(WOLFSSL_X509_NAME* name, int nid,
5381
        int* idx)
5382
{
5383
    int i;
5384
    WOLFSSL_X509_NAME_ENTRY* ret = NULL;
5385
5386
    /* and index of less than 0 is assumed to be starting from 0 */
5387
    if (*idx < 0) {
5388
        *idx = 0;
5389
    }
5390
5391
    for (i = *idx; i < MAX_NAME_ENTRIES; i++) {
5392
        if (name->entry[i].nid == nid) {
5393
            ret = &name->entry[i];
5394
            *idx = i;
5395
            break;
5396
        }
5397
    }
5398
    return ret;
5399
}
5400
5401
5402
/* Used to get a string from the WOLFSSL_X509_NAME structure that
5403
 * corresponds with the NID value passed in. This finds the first entry with
5404
 * matching NID value, if searching for the case where there is multiple
5405
 * entries with the same NID value than other functions should be used
5406
 * (i.e. wolfSSL_X509_NAME_get_index_by_NID, wolfSSL_X509_NAME_get_entry)
5407
 *
5408
 * name structure to get string from
5409
 * nid  NID value to search for
5410
 * buf  [out] buffer to hold results. If NULL then the buffer size minus the
5411
 *      null char is returned.
5412
 * len  size of "buf" passed in
5413
 *
5414
 * returns the length of string found, not including the NULL terminator.
5415
 *         It's possible the function could return a negative value in the
5416
 *         case that len is less than or equal to 0. A negative value is
5417
 *         considered an error case.
5418
 */
5419
int wolfSSL_X509_NAME_get_text_by_NID(WOLFSSL_X509_NAME* name,
5420
                                      int nid, char* buf, int len)
5421
{
5422
    WOLFSSL_X509_NAME_ENTRY* e;
5423
    unsigned char *text = NULL;
5424
    int textSz = 0;
5425
    int idx    = 0;
5426
5427
    WOLFSSL_ENTER("wolfSSL_X509_NAME_get_text_by_NID");
5428
5429
    if (name == NULL) {
5430
        WOLFSSL_MSG("NULL argument passed in");
5431
        return WOLFSSL_FATAL_ERROR;
5432
    }
5433
5434
    e = GetEntryByNID(name, nid, &idx);
5435
    if (e == NULL) {
5436
        WOLFSSL_MSG("Entry type not found");
5437
        return WOLFSSL_FATAL_ERROR;
5438
    }
5439
    text   = wolfSSL_ASN1_STRING_data(e->value);
5440
    textSz = wolfSSL_ASN1_STRING_length(e->value);
5441
5442
    if (text == NULL) {
5443
        WOLFSSL_MSG("Unable to get entry text");
5444
        return WOLFSSL_FATAL_ERROR;
5445
    }
5446
5447
    /* if buf is NULL return size of buffer needed (minus null char) */
5448
    if (buf == NULL) {
5449
        WOLFSSL_MSG("Buffer is NULL, returning buffer size only");
5450
        return textSz;
5451
    }
5452
5453
    /* buf is not NULL from above */
5454
    if (text != NULL) {
5455
        textSz = min(textSz + 1, len); /* + 1 to account for null char */
5456
        if (textSz > 0) {
5457
            XMEMCPY(buf, text, textSz - 1);
5458
            buf[textSz - 1] = '\0';
5459
        }
5460
    }
5461
5462
    WOLFSSL_LEAVE("wolfSSL_X509_NAME_get_text_by_NID", textSz);
5463
    return (textSz - 1); /* do not include null character in size */
5464
}
5465
5466
/* Creates a new WOLFSSL_EVP_PKEY structure that has the public key from x509
5467
 *
5468
 * returns a pointer to the created WOLFSSL_EVP_PKEY on success and NULL on fail
5469
 */
5470
WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
5471
{
5472
    WOLFSSL_EVP_PKEY* key = NULL;
5473
    int ret;
5474
5475
    (void)ret;
5476
5477
    WOLFSSL_ENTER("wolfSSL_X509_get_pubkey");
5478
    if (x509 != NULL) {
5479
        key = wolfSSL_EVP_PKEY_new_ex(x509->heap);
5480
        if (key != NULL) {
5481
            if (x509->pubKeyOID == RSAk) {
5482
                key->type = EVP_PKEY_RSA;
5483
            }
5484
            else if (x509->pubKeyOID == DSAk) {
5485
                key->type = EVP_PKEY_DSA;
5486
            }
5487
            else {
5488
                key->type = EVP_PKEY_EC;
5489
            }
5490
            key->save_type = 0;
5491
            key->pkey.ptr = (char*)XMALLOC(
5492
                        x509->pubKey.length, x509->heap,
5493
                                                       DYNAMIC_TYPE_PUBLIC_KEY);
5494
            if (key->pkey.ptr == NULL) {
5495
                wolfSSL_EVP_PKEY_free(key);
5496
                return NULL;
5497
            }
5498
            XMEMCPY(key->pkey.ptr, x509->pubKey.buffer, x509->pubKey.length);
5499
            key->pkey_sz = x509->pubKey.length;
5500
5501
            #ifdef HAVE_ECC
5502
                key->pkey_curve = (int)x509->pkCurveOID;
5503
            #endif /* HAVE_ECC */
5504
5505
            /* decode RSA key */
5506
            #ifndef NO_RSA
5507
            if (key->type == EVP_PKEY_RSA) {
5508
                key->ownRsa = 1;
5509
                key->rsa = wolfSSL_RSA_new();
5510
                if (key->rsa == NULL) {
5511
                    wolfSSL_EVP_PKEY_free(key);
5512
                    return NULL;
5513
                }
5514
5515
                if (wolfSSL_RSA_LoadDer_ex(key->rsa,
5516
                            (const unsigned char*)key->pkey.ptr, key->pkey_sz,
5517
                            WOLFSSL_RSA_LOAD_PUBLIC) != WOLFSSL_SUCCESS) {
5518
                    wolfSSL_EVP_PKEY_free(key);
5519
                    return NULL;
5520
                }
5521
            }
5522
            #endif /* NO_RSA */
5523
5524
            /* decode ECC key */
5525
            #if defined(HAVE_ECC) && defined(OPENSSL_EXTRA)
5526
            if (key->type == EVP_PKEY_EC) {
5527
                word32 idx = 0;
5528
5529
                key->ownEcc = 1;
5530
                key->ecc = wolfSSL_EC_KEY_new();
5531
                if (key->ecc == NULL || key->ecc->internal == NULL) {
5532
                    wolfSSL_EVP_PKEY_free(key);
5533
                    return NULL;
5534
                }
5535
5536
                /* not using wolfSSL_EC_KEY_LoadDer because public key in x509
5537
                 * is in the format of x963 (no sequence at start of buffer) */
5538
                ret = wc_EccPublicKeyDecode((const unsigned char*)key->pkey.ptr,
5539
                                            &idx, (ecc_key*)key->ecc->internal,
5540
                                            key->pkey_sz);
5541
                if (ret < 0) {
5542
                    WOLFSSL_ERROR_VERBOSE(ret);
5543
                    WOLFSSL_MSG("wc_EccPublicKeyDecode failed");
5544
                    wolfSSL_EVP_PKEY_free(key);
5545
                    return NULL;
5546
                }
5547
5548
                if (SetECKeyExternal(key->ecc) != WOLFSSL_SUCCESS) {
5549
                    WOLFSSL_MSG("SetECKeyExternal failed");
5550
                    wolfSSL_EVP_PKEY_free(key);
5551
                    return NULL;
5552
                }
5553
5554
                key->ecc->inSet = 1;
5555
            }
5556
            #endif /* HAVE_ECC && OPENSSL_EXTRA */
5557
5558
            #ifndef NO_DSA
5559
            if (key->type == EVP_PKEY_DSA) {
5560
                key->ownDsa = 1;
5561
                key->dsa = wolfSSL_DSA_new();
5562
                if (key->dsa == NULL) {
5563
                    wolfSSL_EVP_PKEY_free(key);
5564
                    return NULL;
5565
                }
5566
5567
                if (wolfSSL_DSA_LoadDer_ex(key->dsa,
5568
                            (const unsigned char*)key->pkey.ptr, key->pkey_sz, \
5569
                            WOLFSSL_DSA_LOAD_PUBLIC) != WOLFSSL_SUCCESS) {
5570
                    wolfSSL_DSA_free(key->dsa);
5571
                    key->dsa = NULL;
5572
                    wolfSSL_EVP_PKEY_free(key);
5573
                    return NULL;
5574
                }
5575
            }
5576
            #endif /* NO_DSA */
5577
        }
5578
    }
5579
    return key;
5580
}
5581
#endif /* OPENSSL_EXTRA_X509_SMALL */
5582
5583
/* End of smaller subset of X509 compatibility functions. Avoid increasing the
5584
 * size of this subset and its memory usage */
5585
#endif /* OPENSSL_EXTRA_X509_SMALL || KEEP_PEER_CERT || SESSION_CERTS */
5586
5587
#if defined(OPENSSL_ALL)
5588
/*
5589
 * Converts a and b to DER and then does an XMEMCMP to check if they match.
5590
 * Returns 0 when certificates match and WOLFSSL_FATAL_ERROR when they don't.
5591
 */
5592
int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b)
5593
{
5594
        const byte* derA;
5595
        const byte* derB;
5596
        int outSzA = 0;
5597
        int outSzB = 0;
5598
5599
        if (a == NULL || b == NULL){
5600
            return BAD_FUNC_ARG;
5601
        }
5602
5603
        derA = wolfSSL_X509_get_der((WOLFSSL_X509*)a, &outSzA);
5604
        if (derA == NULL){
5605
            WOLFSSL_MSG("wolfSSL_X509_get_der - certificate A has failed");
5606
            return WOLFSSL_FATAL_ERROR;
5607
        }
5608
        derB = wolfSSL_X509_get_der((WOLFSSL_X509*)b, &outSzB);
5609
        if (derB == NULL){
5610
            WOLFSSL_MSG("wolfSSL_X509_get_der - certificate B has failed");
5611
            return WOLFSSL_FATAL_ERROR;
5612
        }
5613
5614
        if (outSzA != outSzB || XMEMCMP(derA, derB, outSzA) != 0) {
5615
            WOLFSSL_LEAVE("wolfSSL_X509_cmp", WOLFSSL_FATAL_ERROR);
5616
            return WOLFSSL_FATAL_ERROR;
5617
        }
5618
5619
        WOLFSSL_LEAVE("wolfSSL_X509_cmp", 0);
5620
5621
        return 0;
5622
    }
5623
#endif /* OPENSSL_ALL */
5624
5625
#if defined(OPENSSL_EXTRA)
5626
    int wolfSSL_X509_ext_isSet_by_NID(WOLFSSL_X509* x509, int nid)
5627
    {
5628
        int isSet = 0;
5629
5630
        WOLFSSL_ENTER("wolfSSL_X509_ext_isSet_by_NID");
5631
5632
        if (x509 != NULL) {
5633
            switch (nid) {
5634
                case NID_basic_constraints: isSet = x509->basicConstSet; break;
5635
                case NID_subject_alt_name: isSet = x509->subjAltNameSet; break;
5636
                case NID_authority_key_identifier: isSet = x509->authKeyIdSet; break;
5637
                case NID_subject_key_identifier: isSet = x509->subjKeyIdSet; break;
5638
                case NID_key_usage: isSet = x509->keyUsageSet; break;
5639
                case NID_crl_distribution_points: isSet = x509->CRLdistSet; break;
5640
                case NID_ext_key_usage: isSet = ((x509->extKeyUsageSrc) ? 1 : 0);
5641
                    break;
5642
                case NID_info_access: isSet = x509->authInfoSet; break;
5643
                #if defined(WOLFSSL_SEP) || defined(WOLFSSL_QT)
5644
                    case NID_certificate_policies: isSet = x509->certPolicySet; break;
5645
                #endif /* WOLFSSL_SEP || WOLFSSL_QT */
5646
                default:
5647
                    WOLFSSL_MSG("NID not in table");
5648
            }
5649
        }
5650
5651
        WOLFSSL_LEAVE("wolfSSL_X509_ext_isSet_by_NID", isSet);
5652
5653
        return isSet;
5654
    }
5655
5656
5657
    int wolfSSL_X509_ext_get_critical_by_NID(WOLFSSL_X509* x509, int nid)
5658
    {
5659
        int crit = 0;
5660
5661
        WOLFSSL_ENTER("wolfSSL_X509_ext_get_critical_by_NID");
5662
5663
        if (x509 != NULL) {
5664
            switch (nid) {
5665
                case NID_basic_constraints: crit = x509->basicConstCrit; break;
5666
                case NID_subject_alt_name: crit = x509->subjAltNameCrit; break;
5667
                case NID_authority_key_identifier: crit = x509->authKeyIdCrit; break;
5668
                case NID_subject_key_identifier: crit = x509->subjKeyIdCrit; break;
5669
                case NID_key_usage: crit = x509->keyUsageCrit; break;
5670
                case NID_crl_distribution_points: crit= x509->CRLdistCrit; break;
5671
                case NID_ext_key_usage: crit= x509->extKeyUsageCrit; break;
5672
                #if defined(WOLFSSL_SEP) || defined(WOLFSSL_QT)
5673
                    case NID_certificate_policies: crit = x509->certPolicyCrit; break;
5674
                #endif /* WOLFSSL_SEP || WOLFSSL_QT */
5675
            }
5676
        }
5677
5678
        WOLFSSL_LEAVE("wolfSSL_X509_ext_get_critical_by_NID", crit);
5679
5680
        return crit;
5681
    }
5682
5683
5684
    int wolfSSL_X509_get_isSet_pathLength(WOLFSSL_X509* x509)
5685
    {
5686
        int isSet = 0;
5687
5688
        WOLFSSL_ENTER("wolfSSL_X509_get_isSet_pathLength");
5689
5690
        if (x509 != NULL)
5691
            isSet = x509->basicConstPlSet;
5692
5693
        WOLFSSL_LEAVE("wolfSSL_X509_get_isSet_pathLength", isSet);
5694
5695
        return isSet;
5696
    }
5697
5698
5699
    word32 wolfSSL_X509_get_pathLength(WOLFSSL_X509* x509)
5700
    {
5701
        word32 pathLength = 0;
5702
5703
        WOLFSSL_ENTER("wolfSSL_X509_get_pathLength");
5704
5705
        if (x509 != NULL)
5706
            pathLength = x509->pathLength;
5707
5708
        WOLFSSL_LEAVE("wolfSSL_X509_get_pathLength", pathLength);
5709
5710
        return pathLength;
5711
    }
5712
5713
5714
    unsigned int wolfSSL_X509_get_keyUsage(WOLFSSL_X509* x509)
5715
    {
5716
        word16 usage = 0;
5717
5718
        WOLFSSL_ENTER("wolfSSL_X509_get_keyUsage");
5719
5720
        if (x509 != NULL)
5721
            usage = x509->keyUsage;
5722
5723
        WOLFSSL_LEAVE("wolfSSL_X509_get_keyUsage", usage);
5724
5725
        return usage;
5726
    }
5727
5728
5729
    byte* wolfSSL_X509_get_authorityKeyID(WOLFSSL_X509* x509,
5730
                                          byte* dst, int* dstLen)
5731
    {
5732
        byte *id = NULL;
5733
        int copySz = 0;
5734
5735
        WOLFSSL_ENTER("wolfSSL_X509_get_authorityKeyID");
5736
5737
        if (x509 != NULL) {
5738
            if (x509->authKeyIdSet) {
5739
                copySz = min(dstLen != NULL ? *dstLen : 0,
5740
                             (int)x509->authKeyIdSz);
5741
                id = x509->authKeyId;
5742
            }
5743
5744
            if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
5745
                XMEMCPY(dst, id, copySz);
5746
                id = dst;
5747
                *dstLen = copySz;
5748
            }
5749
        }
5750
5751
        WOLFSSL_LEAVE("wolfSSL_X509_get_authorityKeyID", copySz);
5752
5753
        return id;
5754
    }
5755
5756
    byte* wolfSSL_X509_get_subjectKeyID(WOLFSSL_X509* x509,
5757
                                        byte* dst, int* dstLen)
5758
    {
5759
        byte *id = NULL;
5760
        int copySz = 0;
5761
5762
        WOLFSSL_ENTER("wolfSSL_X509_get_subjectKeyID");
5763
5764
        if (x509 != NULL) {
5765
            if (x509->subjKeyIdSet) {
5766
                copySz = min(dstLen != NULL ? *dstLen : 0,
5767
                                                        (int)x509->subjKeyIdSz);
5768
                id = x509->subjKeyId;
5769
            }
5770
5771
            if (dst != NULL && dstLen != NULL && id != NULL && copySz > 0) {
5772
                XMEMCPY(dst, id, copySz);
5773
                id = dst;
5774
                *dstLen = copySz;
5775
            }
5776
        }
5777
5778
        WOLFSSL_LEAVE("wolfSSL_X509_get_subjectKeyID", copySz);
5779
5780
        return id;
5781
    }
5782
#endif /* OPENSSL_EXTRA */
5783
5784
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
5785
    defined(OPENSSL_EXTRA_X509_SMALL)
5786
5787
    /* Looks up the index of the first entry encountered with matching NID
5788
     * The search starts from index 'pos'
5789
     * returns a negative value on failure and positive index value on success*/
5790
    int wolfSSL_X509_NAME_get_index_by_NID(WOLFSSL_X509_NAME* name,
5791
                                          int nid, int pos)
5792
    {
5793
        int value = nid, i;
5794
5795
        WOLFSSL_ENTER("wolfSSL_X509_NAME_get_index_by_NID");
5796
5797
        if (name == NULL) {
5798
            return BAD_FUNC_ARG;
5799
        }
5800
5801
        i = pos + 1; /* start search after index passed in */
5802
        if (i < 0) {
5803
            i = 0;
5804
        }
5805
5806
        for (;i < name->entrySz && i < MAX_NAME_ENTRIES; i++) {
5807
            if (name->entry[i].nid == value) {
5808
                return i;
5809
            }
5810
        }
5811
        return WOLFSSL_FATAL_ERROR;
5812
    }
5813
5814
5815
    WOLFSSL_ASN1_STRING*  wolfSSL_X509_NAME_ENTRY_get_data(
5816
                                                    WOLFSSL_X509_NAME_ENTRY* in)
5817
    {
5818
        WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_get_data");
5819
        if (in == NULL)
5820
            return NULL;
5821
5822
        return in->value;
5823
    }
5824
5825
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
5826
5827
#ifdef OPENSSL_EXTRA
5828
#ifndef NO_BIO
5829
5830
#ifndef MAX_WIDTH
5831
    #define MAX_WIDTH 80
5832
#endif
5833
5834
static int X509PrintSubjAltName(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
5835
        int indent)
5836
{
5837
    int ret = WOLFSSL_SUCCESS;
5838
    DNS_entry* entry;
5839
5840
    if (bio == NULL || x509 == NULL) {
5841
        ret = WOLFSSL_FAILURE;
5842
    }
5843
5844
    if (ret == WOLFSSL_SUCCESS && x509->subjAltNameSet &&
5845
            x509->altNames != NULL) {
5846
        char scratch[MAX_WIDTH];
5847
        int len;
5848
5849
        len = XSNPRINTF(scratch, MAX_WIDTH, "%*s", indent, "");
5850
        if (len >= MAX_WIDTH)
5851
            ret = WOLFSSL_FAILURE;
5852
        if (ret == WOLFSSL_SUCCESS) {
5853
            if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) {
5854
                ret = WOLFSSL_FAILURE;
5855
            }
5856
        }
5857
        if (ret == WOLFSSL_SUCCESS) {
5858
            int nameCount = 0;
5859
5860
            entry = x509->altNames;
5861
            while (entry != NULL) {
5862
                ++nameCount;
5863
                if (nameCount > 1) {
5864
                    if (wolfSSL_BIO_write(bio, ", ", 2) <= 0) {
5865
                        ret = WOLFSSL_FAILURE;
5866
                        break;
5867
                    }
5868
                }
5869
5870
                if (entry->type == ASN_DNS_TYPE) {
5871
                    len = XSNPRINTF(scratch, MAX_WIDTH, "DNS:%s", entry->name);
5872
                    if (len >= MAX_WIDTH) {
5873
                        ret = WOLFSSL_FAILURE;
5874
                        break;
5875
                    }
5876
                }
5877
            #if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
5878
                else if (entry->type == ASN_IP_TYPE) {
5879
                    len = XSNPRINTF(scratch, MAX_WIDTH, "IP Address:%s",
5880
                            entry->ipString);
5881
                    if (len >= MAX_WIDTH) {
5882
                        ret = WOLFSSL_FAILURE;
5883
                        break;
5884
                    }
5885
                }
5886
            #endif /* OPENSSL_ALL || WOLFSSL_IP_ALT_NAME */
5887
                else if (entry->type == ASN_RFC822_TYPE) {
5888
                    len = XSNPRINTF(scratch, MAX_WIDTH, "email:%s",
5889
                            entry->name);
5890
                    if (len >= MAX_WIDTH) {
5891
                        ret = WOLFSSL_FAILURE;
5892
                        break;
5893
                    }
5894
                }
5895
                else if (entry->type == ASN_DIR_TYPE) {
5896
                    /* @TODO entry->name in ASN1 syntax */
5897
                    len = XSNPRINTF(scratch, MAX_WIDTH,
5898
                        "DirName:<print out not supported yet>");
5899
                    if (len >= MAX_WIDTH) {
5900
                        ret = WOLFSSL_FAILURE;
5901
                        break;
5902
                    }
5903
                }
5904
                else if (entry->type == ASN_URI_TYPE) {
5905
                    len = XSNPRINTF(scratch, MAX_WIDTH, "URI:%s",
5906
                        entry->name);
5907
                     if (len >= MAX_WIDTH) {
5908
                        ret = WOLFSSL_FAILURE;
5909
                        break;
5910
                    }
5911
                }
5912
            #if defined(OPENSSL_ALL)
5913
                else if (entry->type == ASN_RID_TYPE) {
5914
                    len = XSNPRINTF(scratch, MAX_WIDTH, "Registered ID:%s",
5915
                        entry->ridString);
5916
                    if (len >= MAX_WIDTH) {
5917
                        ret = WOLFSSL_FAILURE;
5918
                        break;
5919
                    }
5920
                }
5921
            #endif
5922
                else if (entry->type == ASN_OTHER_TYPE) {
5923
                    len = XSNPRINTF(scratch, MAX_WIDTH,
5924
                        "othername <unsupported>");
5925
                    if (len >= MAX_WIDTH) {
5926
                        ret = WOLFSSL_FAILURE;
5927
                        break;
5928
                    }
5929
                }
5930
                else {
5931
                    WOLFSSL_MSG("Bad alt name type.");
5932
                    ret = WOLFSSL_FAILURE;
5933
                    break;
5934
                }
5935
5936
                if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch))
5937
                        <= 0) {
5938
                    ret = WOLFSSL_FAILURE;
5939
                    break;
5940
                }
5941
5942
                entry = entry->next;
5943
            }
5944
        }
5945
5946
        if (ret == WOLFSSL_SUCCESS && wolfSSL_BIO_write(bio, "\n", 1) <= 0) {
5947
            ret = WOLFSSL_FAILURE;
5948
        }
5949
    }
5950
5951
    return ret;
5952
}
5953
5954
#ifdef XSNPRINTF
5955
static int X509PrintKeyUsage(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
5956
{
5957
    int ret = WOLFSSL_SUCCESS;
5958
    const int usages[] = {
5959
        KEYUSE_DIGITAL_SIG,
5960
        KEYUSE_CONTENT_COMMIT,
5961
        KEYUSE_KEY_ENCIPHER,
5962
        KEYUSE_DATA_ENCIPHER,
5963
        KEYUSE_KEY_AGREE,
5964
        KEYUSE_KEY_CERT_SIGN,
5965
        KEYUSE_CRL_SIGN,
5966
        KEYUSE_ENCIPHER_ONLY,
5967
        KEYUSE_DECIPHER_ONLY
5968
    };
5969
    const char* usageStrs[] = {
5970
        "Digital Signature",
5971
        "Non Repudiation",
5972
        "Key Encipherment",
5973
        "Data Encipherment",
5974
        "Key Agreement",
5975
        "Certificate Sign",
5976
        "CRL Sign",
5977
        "Encipher Only",
5978
        "Decipher Only"
5979
    };
5980
5981
    if (bio == NULL || x509 == NULL) {
5982
        ret = WOLFSSL_FAILURE;
5983
    }
5984
5985
    if (ret == WOLFSSL_SUCCESS && x509->keyUsageSet && x509->keyUsage != 0) {
5986
        char scratch[MAX_WIDTH];
5987
        int len;
5988
        word32 i = 0;
5989
        int usageCount = 0;
5990
5991
        len = XSNPRINTF(scratch, MAX_WIDTH, "%*s", indent, "");
5992
        if (len >= MAX_WIDTH)
5993
            ret = WOLFSSL_FAILURE;
5994
        if (ret == WOLFSSL_SUCCESS) {
5995
            if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) {
5996
                ret = WOLFSSL_FAILURE;
5997
            }
5998
        }
5999
        for (; ret == WOLFSSL_SUCCESS && i < sizeof(usages) / sizeof(usages[i]);
6000
             i++) {
6001
            if (x509->keyUsage & usages[i]) {
6002
                ++usageCount;
6003
                if (usageCount > 1 && wolfSSL_BIO_write(bio, ", ", 2) <= 0) {
6004
                    ret = WOLFSSL_FAILURE;
6005
                    break;
6006
                }
6007
                if (wolfSSL_BIO_write(bio, usageStrs[i],
6008
                                      (int)XSTRLEN(usageStrs[i])) <= 0) {
6009
                    ret = WOLFSSL_FAILURE;
6010
                    break;
6011
                }
6012
            }
6013
        }
6014
        if (ret == WOLFSSL_SUCCESS && wolfSSL_BIO_write(bio, "\n", 1) <= 0) {
6015
            ret = WOLFSSL_FAILURE;
6016
        }
6017
    }
6018
6019
    return ret;
6020
}
6021
6022
static int X509PrintExtendedKeyUsage(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
6023
        int indent)
6024
{
6025
    int ret = WOLFSSL_SUCCESS;
6026
    const int usages[] = {
6027
        EXTKEYUSE_OCSP_SIGN,
6028
        EXTKEYUSE_TIMESTAMP,
6029
        EXTKEYUSE_EMAILPROT,
6030
        EXTKEYUSE_CODESIGN,
6031
        EXTKEYUSE_CLIENT_AUTH,
6032
        EXTKEYUSE_SERVER_AUTH
6033
    };
6034
    const char* usageStrs[] = {
6035
        "OCSP Signing",
6036
        "Time Stamping",
6037
        "E-mail Protection",
6038
        "Code Signing",
6039
        "TLS Web Client Authentication",
6040
        "TLS Web Server Authentication"
6041
    };
6042
6043
    if (bio == NULL || x509 == NULL) {
6044
        ret = WOLFSSL_FAILURE;
6045
    }
6046
6047
    if (ret == WOLFSSL_SUCCESS && x509->extKeyUsageCount > 0
6048
            && x509->extKeyUsage != 0) {
6049
        char scratch[MAX_WIDTH];
6050
        int len;
6051
        word32 i = 0;
6052
        int usageCount = 0;
6053
6054
        len = XSNPRINTF(scratch, MAX_WIDTH, "%*s", indent, "");
6055
        if (len >= MAX_WIDTH)
6056
            ret = WOLFSSL_FAILURE;
6057
        if (ret == WOLFSSL_SUCCESS) {
6058
            if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) {
6059
                ret = WOLFSSL_FAILURE;
6060
            }
6061
        }
6062
        for (; ret == WOLFSSL_SUCCESS && i < sizeof(usages) / sizeof(usages[i]);
6063
             i++) {
6064
            if (x509->extKeyUsage & usages[i]) {
6065
                ++usageCount;
6066
                if (usageCount > 1 && wolfSSL_BIO_write(bio, ", ", 2) <= 0) {
6067
                    ret = WOLFSSL_FAILURE;
6068
                    break;
6069
                }
6070
                if (wolfSSL_BIO_write(bio, usageStrs[i],
6071
                                      (int)XSTRLEN(usageStrs[i])) <= 0) {
6072
                    ret = WOLFSSL_FAILURE;
6073
                    break;
6074
                }
6075
            }
6076
        }
6077
        if (ret == WOLFSSL_SUCCESS && wolfSSL_BIO_write(bio, "\n", 1) <= 0) {
6078
            ret = WOLFSSL_FAILURE;
6079
        }
6080
    }
6081
6082
    return ret;
6083
}
6084
6085
6086
/* print serial number out
6087
 * return WOLFSSL_SUCCESS on success
6088
 */
6089
static int X509PrintSerial_ex(WOLFSSL_BIO* bio, byte* serial, int sz,
6090
        int delimiter, int indent)
6091
{
6092
    char scratch[MAX_WIDTH];
6093
    const int scratchSz = sizeof(scratch);
6094
    int scratchLen;
6095
6096
    if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*sSerial Number:",
6097
                                 indent, "")) >= MAX_WIDTH) {
6098
        WOLFSSL_MSG("buffer overrun");
6099
        return WOLFSSL_FAILURE;
6100
    }
6101
    if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
6102
        return WOLFSSL_FAILURE;
6103
    }
6104
6105
    if (sz > (int)sizeof(byte)) {
6106
        int i;
6107
6108
        /* serial is larger than int size so print off hex values */
6109
        if ((scratchLen = XSNPRINTF(
6110
                 scratch, MAX_WIDTH, "\n%*s", indent + 4, ""))
6111
                >= MAX_WIDTH) {
6112
            WOLFSSL_MSG("buffer overrun");
6113
            return WOLFSSL_FAILURE;
6114
        }
6115
        for (i = 0; i < sz; i++) {
6116
            int valLen;
6117
6118
            if ((valLen = XSNPRINTF(
6119
                     scratch + scratchLen, scratchSz - scratchLen,
6120
                     "%02x%s", serial[i], (i < sz - 1) ?
6121
                     (delimiter ? ":" : "") : "\n"))
6122
                >= scratchSz - scratchLen)
6123
            {
6124
                WOLFSSL_MSG("buffer overrun");
6125
                return WOLFSSL_FAILURE;
6126
            }
6127
            scratchLen += valLen;
6128
        }
6129
        if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
6130
            return WOLFSSL_FAILURE;
6131
        }
6132
    }
6133
6134
    /* if serial can fit into byte then print on the same line */
6135
    else  {
6136
        if ((scratchLen = XSNPRINTF(
6137
                 scratch, MAX_WIDTH, " %d (0x%x)\n", serial[0], serial[0]))
6138
            >= MAX_WIDTH)
6139
        {
6140
            WOLFSSL_MSG("buffer overrun");
6141
            return WOLFSSL_FAILURE;
6142
        }
6143
        if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
6144
            return WOLFSSL_FAILURE;
6145
        }
6146
    }
6147
    return WOLFSSL_SUCCESS;
6148
}
6149
6150
static int X509PrintSerial(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
6151
{
6152
    unsigned char serial[32];
6153
    int  sz = sizeof(serial);
6154
6155
    XMEMSET(serial, 0, sz);
6156
    if (wolfSSL_X509_get_serial_number(x509, serial, &sz) == WOLFSSL_SUCCESS) {
6157
        X509PrintSerial_ex(bio, serial, sz, 1, indent);
6158
    }
6159
    return WOLFSSL_SUCCESS;
6160
}
6161
6162
/* iterate through certificate extensions printing them out in human readable
6163
 * form
6164
 * return WOLFSSL_SUCCESS on success
6165
 */
6166
static int X509PrintExtensions(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
6167
{
6168
    int  ret = WOLFSSL_SUCCESS;
6169
    char scratch[MAX_WIDTH];
6170
    const int scratchSz = sizeof(scratch);
6171
    int scratchLen;
6172
    int  count, i;
6173
    char* buf = NULL;
6174
6175
    count = wolfSSL_X509_get_ext_count(x509);
6176
    if (count <= 0)
6177
        return WOLFSSL_SUCCESS;
6178
6179
#ifdef WOLFSSL_CERT_REQ
6180
    if (x509->isCSR) {
6181
        if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*s%s\n", indent, "",
6182
                      "Requested extensions:")) >= MAX_WIDTH) {
6183
            return WOLFSSL_FAILURE;
6184
        }
6185
    }
6186
    else
6187
#endif
6188
    {
6189
        if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*s%s\n", indent, "",
6190
                                     "X509v3 extensions:")) >= MAX_WIDTH) {
6191
            return WOLFSSL_FAILURE;
6192
        }
6193
    }
6194
    if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
6195
        return WOLFSSL_FAILURE;
6196
    }
6197
6198
    buf = (char*)XMALLOC(MAX_WIDTH-4-indent, x509->heap,
6199
                         DYNAMIC_TYPE_TMP_BUFFER);
6200
    if (buf == NULL) {
6201
        return WOLFSSL_FAILURE;
6202
    }
6203
6204
    for (i = 0; (i < count) && (ret != WOLFSSL_FAILURE); i++) {
6205
        WOLFSSL_X509_EXTENSION* ext;
6206
6207
        ext = wolfSSL_X509_get_ext(x509, i);
6208
        if (ext != NULL) {
6209
            WOLFSSL_ASN1_OBJECT* obj;
6210
            int nid;
6211
            char val[6];
6212
            int valLen;
6213
            word32 j;
6214
6215
            obj = wolfSSL_X509_EXTENSION_get_object(ext);
6216
            if (obj == NULL) {
6217
                ret = WOLFSSL_FAILURE;
6218
                break;
6219
            }
6220
            if (wolfSSL_OBJ_obj2txt(buf, MAX_WIDTH, obj, 0)
6221
                == WOLFSSL_FAILURE)
6222
            {
6223
                ret = WOLFSSL_FAILURE;
6224
                break;
6225
            }
6226
            if ((scratchLen = XSNPRINTF(
6227
                     scratch, MAX_WIDTH, "%*s%s%s\n", indent + 4, "",
6228
                     buf,
6229
                     (wolfSSL_X509_EXTENSION_get_critical(ext)
6230
                      ? ": critical"
6231
                      : ": ")))
6232
                >= MAX_WIDTH)
6233
            {
6234
                ret = WOLFSSL_FAILURE;
6235
                break;
6236
            }
6237
6238
            if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
6239
                ret = WOLFSSL_FAILURE;
6240
                break;
6241
            }
6242
            nid = wolfSSL_OBJ_obj2nid(obj);
6243
            switch (nid) {
6244
            case NID_subject_alt_name:
6245
                ret = X509PrintSubjAltName(bio, x509, indent + 8);
6246
                break;
6247
6248
            case NID_subject_key_identifier:
6249
                if (!x509->subjKeyIdSet || x509->subjKeyId == NULL ||
6250
                    x509->subjKeyIdSz == 0)
6251
                {
6252
                    ret = WOLFSSL_FAILURE;
6253
                    break;
6254
                }
6255
6256
                if ((scratchLen = XSNPRINTF(
6257
                         scratch, scratchSz,
6258
                         "%*s", indent + 8, "")) >= scratchSz)
6259
                {
6260
                    ret = WOLFSSL_FAILURE;
6261
                    break;
6262
                }
6263
                for (j = 0; j < x509->subjKeyIdSz; j++) {
6264
                    if ((valLen = XSNPRINTF(
6265
                             val, sizeof(val), "%02X%s",
6266
                             x509->subjKeyId[j],
6267
                             (j < x509->subjKeyIdSz - 1) ? ":" : "\n"))
6268
                        >= (int)sizeof(val))
6269
                    {
6270
                        ret = WOLFSSL_FAILURE;
6271
                        break;
6272
                    }
6273
                    if (scratchLen + valLen >= scratchSz) {
6274
                        if (wolfSSL_BIO_write(bio, scratch,
6275
                                              scratchLen) <= 0) {
6276
                            ret = WOLFSSL_FAILURE;
6277
                            break;
6278
                        }
6279
                        scratchLen = 0;
6280
                    }
6281
                    XMEMCPY(scratch + scratchLen, val, valLen);
6282
                    scratchLen += valLen;
6283
                }
6284
                if (ret == WOLFSSL_FAILURE)
6285
                    break;
6286
                if (wolfSSL_BIO_write(bio, scratch,
6287
                                      scratchLen) <= 0) {
6288
                    ret = WOLFSSL_FAILURE;
6289
                    break;
6290
                }
6291
                break;
6292
6293
            case NID_authority_key_identifier:
6294
                if (!x509->authKeyIdSet || x509->authKeyId == NULL ||
6295
                    x509->authKeyIdSz == 0) {
6296
                    ret = WOLFSSL_FAILURE;
6297
                    break;
6298
                }
6299
6300
                if ((scratchLen = XSNPRINTF(
6301
                         scratch, scratchSz, "%*s%s",
6302
                         indent + 8, "", "keyid:")) >= scratchSz)
6303
                {
6304
                    ret = WOLFSSL_FAILURE;
6305
                    break;
6306
                }
6307
                for (j = 0; j < x509->authKeyIdSz; j++) {
6308
                    if ((valLen = XSNPRINTF(
6309
                             val, sizeof(val), "%02X%s",
6310
                             x509->authKeyId[j],
6311
                             (j < x509->authKeyIdSz - 1) ? ":" : "\n\n"))
6312
                        >= (int)sizeof(val))
6313
                    {
6314
                        ret = WOLFSSL_FAILURE;
6315
                        break;
6316
                    }
6317
                    if (scratchLen >= scratchSz - valLen) {
6318
                        if (wolfSSL_BIO_write(bio, scratch,
6319
                                              scratchLen) <= 0)
6320
                        {
6321
                            ret = WOLFSSL_FAILURE;
6322
                            break;
6323
                        }
6324
                        scratchLen = 0;
6325
                    }
6326
                    if (scratchLen + valLen >= scratchSz) {
6327
                        ret = WOLFSSL_FAILURE;
6328
                        break;
6329
                    }
6330
                    XMEMCPY(scratch + scratchLen, val, valLen);
6331
                    scratchLen += valLen;
6332
                }
6333
                if (ret == WOLFSSL_FAILURE)
6334
                    break;
6335
                if (wolfSSL_BIO_write(bio, scratch,
6336
                                      scratchLen) <= 0) {
6337
                    ret = WOLFSSL_FAILURE;
6338
                    break;
6339
                }
6340
                break;
6341
6342
            case NID_basic_constraints:
6343
                if (!x509->basicConstSet) {
6344
                    ret = WOLFSSL_FAILURE;
6345
                    break;
6346
                }
6347
                if ((scratchLen = XSNPRINTF(
6348
                         scratch, scratchSz,
6349
                         "%*sCA:%s\n",
6350
                         indent + 8, "", (x509->isCa)? "TRUE": "FALSE"))
6351
                    >= scratchSz)
6352
                {
6353
                    ret = WOLFSSL_FAILURE;
6354
                    break;
6355
                }
6356
                if (wolfSSL_BIO_write(bio, scratch,
6357
                                      scratchLen) <= 0) {
6358
                    ret = WOLFSSL_FAILURE;
6359
                    break;
6360
                }
6361
                break;
6362
6363
            case NID_key_usage:
6364
                ret = X509PrintKeyUsage(bio, x509, indent + 8);
6365
                break;
6366
6367
            case NID_ext_key_usage:
6368
                ret = X509PrintExtendedKeyUsage(bio, x509, indent + 8);
6369
                break;
6370
6371
            default:
6372
                /* extension nid not yet supported */
6373
                if ((scratchLen = XSNPRINTF(
6374
                         scratch, MAX_WIDTH,
6375
                         "%*sNID %d print not yet supported\n",
6376
                         indent + 8, "", nid)) >= MAX_WIDTH)
6377
                {
6378
                    ret = WOLFSSL_FAILURE;
6379
                    break;
6380
                }
6381
6382
                if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
6383
                    ret = WOLFSSL_FAILURE;
6384
                    break;
6385
                }
6386
            }
6387
        }
6388
    }
6389
6390
    if (buf != NULL) {
6391
        XFREE(buf, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
6392
    }
6393
6394
    return ret;
6395
}
6396
6397
6398
/* print out the signature in human readable format for use with
6399
 * wolfSSL_X509_print()
6400
 * return WOLFSSL_SUCCESS on success
6401
 */
6402
static int X509PrintSignature_ex(WOLFSSL_BIO* bio, byte* sig,
6403
        int sigSz, int sigNid, int algOnly, int indent)
6404
{
6405
    char scratch[MAX_WIDTH];
6406
    int scratchLen;
6407
    WOLFSSL_ASN1_OBJECT* obj = NULL;
6408
    int ret = WOLFSSL_SUCCESS;
6409
    char tmp[100];
6410
    int tmpLen = 0;
6411
6412
    if (sigSz <= 0) {
6413
        return WOLFSSL_SUCCESS;
6414
    }
6415
6416
    if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*s%s", indent, "",
6417
                                "Signature Algorithm: ")) >= MAX_WIDTH) {
6418
        ret = WOLFSSL_FAILURE;
6419
    }
6420
6421
    if (ret == WOLFSSL_SUCCESS) {
6422
        if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0)
6423
            ret = WOLFSSL_FAILURE;
6424
    }
6425
6426
    if (ret == WOLFSSL_SUCCESS) {
6427
        obj = wolfSSL_OBJ_nid2obj(sigNid);
6428
        if (obj == NULL)
6429
            ret = WOLFSSL_FAILURE;
6430
    }
6431
    if (ret == WOLFSSL_SUCCESS) {
6432
        if (wolfSSL_OBJ_obj2txt(scratch, MAX_WIDTH, obj, 0)
6433
            == WOLFSSL_FAILURE)
6434
        {
6435
            ret = WOLFSSL_FAILURE;
6436
        }
6437
    }
6438
6439
    if (ret == WOLFSSL_SUCCESS) {
6440
        if ((tmpLen = XSNPRINTF(tmp, sizeof(tmp),"%s\n", scratch))
6441
            >= (int)sizeof(tmp))
6442
        {
6443
            ret = WOLFSSL_FAILURE;
6444
        }
6445
    }
6446
    if (ret == WOLFSSL_SUCCESS) {
6447
        if (wolfSSL_BIO_write(bio, tmp, tmpLen) <= 0)
6448
            ret = WOLFSSL_FAILURE;
6449
    }
6450
6451
    /* Leave function if the desired content to print
6452
     * is only the signature algorithm */
6453
    if (algOnly) {
6454
        if (obj != NULL)
6455
            wolfSSL_ASN1_OBJECT_free(obj);
6456
6457
        return ret;
6458
    }
6459
6460
    if (ret == WOLFSSL_SUCCESS) {
6461
        if ((tmpLen = XSNPRINTF(tmp, sizeof(tmp), "%*s", indent + 5, ""))
6462
            >= (int)sizeof(tmp))
6463
        {
6464
            ret = WOLFSSL_FAILURE;
6465
        }
6466
    }
6467
6468
    if (ret == WOLFSSL_SUCCESS) {
6469
        int i;
6470
6471
        for (i = 0; i < sigSz; i++) {
6472
            char val[6];
6473
            int valLen;
6474
6475
            if (i == 0) {
6476
                if ((valLen = XSNPRINTF(val, sizeof(val), "%02x", sig[i]))
6477
                    >= (int)sizeof(val))
6478
                {
6479
                    ret = WOLFSSL_FAILURE;
6480
                    break;
6481
                }
6482
            }
6483
            else if (((i % 18) == 0)) {
6484
                if (wolfSSL_BIO_write(bio, tmp, tmpLen)
6485
                    <= 0) {
6486
                    ret = WOLFSSL_FAILURE;
6487
                    break;
6488
                }
6489
                if ((tmpLen = XSNPRINTF(tmp, sizeof(tmp), ":\n%*s",
6490
                                        indent + 5, ""))
6491
                    >= (int)sizeof(tmp))
6492
                {
6493
                    ret = WOLFSSL_FAILURE;
6494
                    break;
6495
                }
6496
                if ((valLen = XSNPRINTF(val, sizeof(val), "%02x", sig[i]))
6497
                    >= (int)sizeof(val))
6498
                {
6499
                    ret = WOLFSSL_FAILURE;
6500
                    break;
6501
                }
6502
            }
6503
            else {
6504
                if ((valLen = XSNPRINTF(val, sizeof(val), ":%02x", sig[i]))
6505
                    >= (int)sizeof(val))
6506
                {
6507
                    ret = WOLFSSL_FAILURE;
6508
                    break;
6509
                }
6510
            }
6511
            if ((tmpLen < 0) || (valLen < 0) ||
6512
                    (valLen >= ((int)sizeof(tmp) - tmpLen - 1))) {
6513
                ret = WOLFSSL_FAILURE;
6514
                break;
6515
            }
6516
            XMEMCPY(tmp + tmpLen, val, valLen);
6517
            tmpLen += valLen;
6518
            tmp[tmpLen] = 0;
6519
        }
6520
    }
6521
6522
    /* print out remaining sig values */
6523
    if (ret == WOLFSSL_SUCCESS) {
6524
        if (tmpLen > 0) {
6525
            if (wolfSSL_BIO_write(bio, tmp, tmpLen)
6526
                <= 0)
6527
            {
6528
                ret = WOLFSSL_FAILURE;
6529
            }
6530
        }
6531
    }
6532
6533
    if (obj != NULL)
6534
        wolfSSL_ASN1_OBJECT_free(obj);
6535
6536
    return ret;
6537
}
6538
6539
static int X509PrintSignature(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
6540
        int algOnly, int indent)
6541
{
6542
    int sigSz = 0;
6543
    if (wolfSSL_X509_get_signature(x509, NULL, &sigSz) <= 0) {
6544
        return WOLFSSL_FAILURE;
6545
    }
6546
6547
    if (sigSz > 0) {
6548
        unsigned char* sig;
6549
        int sigNid;
6550
6551
        sigNid = wolfSSL_X509_get_signature_nid(x509);
6552
        if (sigNid <= 0) {
6553
            return WOLFSSL_FAILURE;
6554
        }
6555
6556
        sig = (unsigned char*)XMALLOC(sigSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6557
        if (sig == NULL) {
6558
            return WOLFSSL_FAILURE;
6559
        }
6560
6561
        if (wolfSSL_X509_get_signature(x509, sig, &sigSz) <= 0) {
6562
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6563
            return WOLFSSL_FAILURE;
6564
        }
6565
6566
        if (X509PrintSignature_ex(bio, sig, sigSz, sigNid, algOnly, indent)
6567
                != WOLFSSL_SUCCESS) {
6568
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6569
            return WOLFSSL_FAILURE;
6570
        }
6571
6572
        if (sig != NULL) {
6573
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6574
        }
6575
6576
    }
6577
6578
    return WOLFSSL_SUCCESS;
6579
}
6580
6581
6582
/* print out the public key in human readable format for use with
6583
 * wolfSSL_X509_print()
6584
 * return WOLFSSL_SUCCESS on success
6585
 */
6586
static int X509PrintPubKey(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
6587
{
6588
    char scratch[MAX_WIDTH];
6589
    WOLFSSL_EVP_PKEY* pubKey;
6590
    int len;
6591
    int ret = WOLFSSL_SUCCESS;
6592
6593
    if (bio == NULL || x509 == NULL)
6594
        return BAD_FUNC_ARG;
6595
6596
    len = XSNPRINTF(scratch, MAX_WIDTH, "%*sSubject Public Key Info:\n", indent, "");
6597
    if (len >= MAX_WIDTH)
6598
        return WOLFSSL_FAILURE;
6599
    if (wolfSSL_BIO_write(bio, scratch, len) <= 0)
6600
        return WOLFSSL_FAILURE;
6601
6602
    switch (x509->pubKeyOID) {
6603
    #ifndef NO_RSA
6604
        case RSAk:
6605
            len = XSNPRINTF(scratch, MAX_WIDTH,
6606
                    "%*sPublic Key Algorithm: rsaEncryption\n", indent + 4, "");
6607
            if (len >= MAX_WIDTH)
6608
                return WOLFSSL_FAILURE;
6609
            if (wolfSSL_BIO_write(bio, scratch, len) <= 0)
6610
                return WOLFSSL_FAILURE;
6611
            break;
6612
    #endif
6613
    #ifdef HAVE_ECC
6614
        case ECDSAk:
6615
            len = XSNPRINTF(scratch, MAX_WIDTH,
6616
                    "%*sPublic Key Algorithm: EC\n", indent + 4, "");
6617
            if (len >= MAX_WIDTH)
6618
                return WOLFSSL_FAILURE;
6619
            if (wolfSSL_BIO_write(bio, scratch, len) <= 0)
6620
                return WOLFSSL_FAILURE;
6621
            break;
6622
    #endif
6623
        default:
6624
                WOLFSSL_MSG("Unknown key type");
6625
                return WOLFSSL_FAILURE;
6626
    }
6627
6628
    pubKey = wolfSSL_X509_get_pubkey(x509);
6629
    if (pubKey == NULL)
6630
        return WOLFSSL_FAILURE;
6631
6632
    ret = wolfSSL_EVP_PKEY_print_public(bio, pubKey, indent + 8, NULL);
6633
6634
    wolfSSL_EVP_PKEY_free(pubKey);
6635
6636
    return ret;
6637
}
6638
6639
6640
/* human readable print out of x509 name formatted for use with
6641
 * wolfSSL_X509_print()
6642
 * return WOLFSSL_SUCCESS on success
6643
 */
6644
static int X509PrintName(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name,
6645
        char* type, int indent)
6646
{
6647
    if (name != NULL) {
6648
        char scratch[MAX_WIDTH];
6649
        int scratchLen;
6650
6651
        if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH,
6652
                                     "%*s%s", indent, "", type))
6653
            >= MAX_WIDTH)
6654
        {
6655
            return WOLFSSL_FAILURE;
6656
        }
6657
        if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
6658
            return WOLFSSL_FAILURE;
6659
        }
6660
        if (wolfSSL_X509_NAME_print_ex(bio, name, 1, 0) <= 0) {
6661
            return WOLFSSL_FAILURE;
6662
        }
6663
        if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) {
6664
            return WOLFSSL_FAILURE;
6665
        }
6666
    }
6667
    return WOLFSSL_SUCCESS;
6668
}
6669
6670
6671
/* human readable print out of x509 version
6672
 * return WOLFSSL_SUCCESS on success
6673
 */
6674
static int X509PrintVersion(WOLFSSL_BIO* bio, int version, int indent)
6675
{
6676
    char scratch[MAX_WIDTH];
6677
    int scratchLen;
6678
6679
    if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH,
6680
                                 "%*s%s", indent, "", "Version:"))
6681
        >= MAX_WIDTH)
6682
    {
6683
        return WOLFSSL_FAILURE;
6684
    }
6685
    if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
6686
        return WOLFSSL_FAILURE;
6687
    }
6688
6689
    if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH,
6690
                                 " %d (0x%x)\n", version, (byte)version-1))
6691
        >= MAX_WIDTH)
6692
    {
6693
        return WOLFSSL_FAILURE;
6694
    }
6695
    if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
6696
        return WOLFSSL_FAILURE;
6697
    }
6698
    return WOLFSSL_SUCCESS;
6699
}
6700
6701
#ifdef WOLFSSL_CERT_REQ
6702
/* Print out of REQ attributes
6703
 * return WOLFSSL_SUCCESS on success
6704
 */
6705
static int X509PrintReqAttributes(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
6706
        int indent)
6707
{
6708
    WOLFSSL_X509_ATTRIBUTE* attr;
6709
    char scratch[MAX_WIDTH];
6710
    int scratchLen;
6711
    int i = 0;
6712
6713
    if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH,
6714
                                 "%*s%s", indent, "", "Attributes: \n"))
6715
        >= MAX_WIDTH)
6716
    {
6717
        return WOLFSSL_FAILURE;
6718
    }
6719
    if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
6720
        return WOLFSSL_FAILURE;
6721
    }
6722
    do {
6723
        attr = wolfSSL_X509_REQ_get_attr(x509, i);
6724
        if (attr != NULL) {
6725
            char lName[NAME_SZ/4]; /* NAME_SZ default is 80 */
6726
            int lNameSz = NAME_SZ/4;
6727
            const byte* data;
6728
6729
            if (wolfSSL_OBJ_obj2txt(lName, lNameSz, attr->object, 0)
6730
                == WOLFSSL_FAILURE)
6731
            {
6732
                return WOLFSSL_FAILURE;
6733
            }
6734
            lNameSz = (int)XSTRLEN(lName);
6735
            data = wolfSSL_ASN1_STRING_get0_data(
6736
                    attr->value->value.asn1_string);
6737
            if (data == NULL) {
6738
                WOLFSSL_MSG("No REQ attribute found when expected");
6739
                return WOLFSSL_FAILURE;
6740
            }
6741
            if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH,
6742
                          "%*s%s%*s:%s\n", indent+4, "",
6743
                          lName, (NAME_SZ/4)-lNameSz, "", data))
6744
                >= MAX_WIDTH)
6745
            {
6746
                return WOLFSSL_FAILURE;
6747
            }
6748
            if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) {
6749
                WOLFSSL_MSG("Error writing REQ attribute");
6750
                return WOLFSSL_FAILURE;
6751
            }
6752
        }
6753
        i++;
6754
    } while (attr != NULL);
6755
6756
    return WOLFSSL_SUCCESS;
6757
}
6758
6759
6760
/*
6761
 * return WOLFSSL_SUCCESS on success
6762
 */
6763
int wolfSSL_X509_REQ_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
6764
{
6765
    char subjType[] = "Subject: ";
6766
6767
    if (bio == NULL || x509 == NULL) {
6768
        return WOLFSSL_FAILURE;
6769
    }
6770
6771
    if (wolfSSL_BIO_write(bio, "Certificate Request:\n",
6772
                  (int)XSTRLEN("Certificate Request:\n")) <= 0) {
6773
            return WOLFSSL_FAILURE;
6774
    }
6775
6776
    if (wolfSSL_BIO_write(bio, "    Data:\n",
6777
                  (int)XSTRLEN("    Data:\n")) <= 0) {
6778
            return WOLFSSL_FAILURE;
6779
    }
6780
6781
    /* print version of cert */
6782
    if (X509PrintVersion(bio, wolfSSL_X509_version(x509), 8)
6783
            != WOLFSSL_SUCCESS) {
6784
        return WOLFSSL_FAILURE;
6785
    }
6786
6787
    if (X509PrintSerial(bio, x509, 8) != WOLFSSL_SUCCESS) {
6788
        return WOLFSSL_FAILURE;
6789
    }
6790
6791
    /* print subject */
6792
    if (X509PrintName(bio, wolfSSL_X509_get_subject_name(x509), subjType, 8)
6793
            != WOLFSSL_SUCCESS) {
6794
        return WOLFSSL_FAILURE;
6795
    }
6796
6797
    /* get and print public key */
6798
    if (X509PrintPubKey(bio, x509, 8) != WOLFSSL_SUCCESS) {
6799
        return WOLFSSL_FAILURE;
6800
    }
6801
6802
    /* print out extensions */
6803
    if (X509PrintExtensions(bio, x509, 4) != WOLFSSL_SUCCESS) {
6804
        return WOLFSSL_FAILURE;
6805
    }
6806
6807
    /* print out req attributes */
6808
    if (X509PrintReqAttributes(bio, x509, 4) != WOLFSSL_SUCCESS) {
6809
        return WOLFSSL_FAILURE;
6810
    }
6811
6812
    /* print out signature */
6813
    if (X509PrintSignature(bio, x509, 0, 4) != WOLFSSL_SUCCESS) {
6814
        return WOLFSSL_FAILURE;
6815
    }
6816
6817
    /* done with print out */
6818
    if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
6819
        return WOLFSSL_FAILURE;
6820
    }
6821
6822
    return WOLFSSL_SUCCESS;
6823
}
6824
#endif /* WOLFSSL_CERT_REQ */
6825
6826
6827
/* Writes the human readable form of x509 to bio.
6828
 *
6829
 * bio  WOLFSSL_BIO to write to.
6830
 * x509 Certificate to write.
6831
 *
6832
 * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
6833
 */
6834
int wolfSSL_X509_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
6835
    unsigned long nmflags, unsigned long cflag)
6836
{
6837
    char issuType[] = "Issuer:";
6838
    char subjType[] = "Subject:";
6839
6840
    WOLFSSL_ENTER("wolfSSL_X509_print_ex");
6841
6842
    /* flags currently not supported */
6843
    (void)nmflags;
6844
    (void)cflag;
6845
6846
    if (bio == NULL || x509 == NULL) {
6847
        return WOLFSSL_FAILURE;
6848
    }
6849
6850
    if (wolfSSL_BIO_write(bio, "Certificate:\n",
6851
                  (int)XSTRLEN("Certificate:\n")) <= 0) {
6852
            return WOLFSSL_FAILURE;
6853
    }
6854
6855
    if (wolfSSL_BIO_write(bio, "    Data:\n",
6856
                  (int)XSTRLEN("    Data:\n")) <= 0) {
6857
            return WOLFSSL_FAILURE;
6858
    }
6859
6860
    /* print version of cert */
6861
    if (X509PrintVersion(bio, wolfSSL_X509_version(x509), 8)
6862
            != WOLFSSL_SUCCESS) {
6863
        return WOLFSSL_FAILURE;
6864
    }
6865
6866
    /* print serial number out */
6867
    if (X509PrintSerial(bio, x509, 8) != WOLFSSL_SUCCESS) {
6868
        return WOLFSSL_FAILURE;
6869
    }
6870
6871
    /* print out signature algo*/
6872
    if (X509PrintSignature(bio, x509, 1, 8) != WOLFSSL_SUCCESS) {
6873
        return WOLFSSL_FAILURE;
6874
    }
6875
6876
    /* print issuer */
6877
    if (X509PrintName(bio, wolfSSL_X509_get_issuer_name(x509), issuType, 8)
6878
            != WOLFSSL_SUCCESS) {
6879
        return WOLFSSL_FAILURE;
6880
    }
6881
6882
#ifndef NO_ASN_TIME
6883
    /* print validity */
6884
    {
6885
        char tmp[80];
6886
6887
        if (wolfSSL_BIO_write(bio, "        Validity\n",
6888
                      (int)XSTRLEN("        Validity\n")) <= 0) {
6889
            return WOLFSSL_FAILURE;
6890
        }
6891
6892
        if (wolfSSL_BIO_write(bio, "            Not Before: ",
6893
                      (int)XSTRLEN("            Not Before: ")) <= 0) {
6894
            return WOLFSSL_FAILURE;
6895
        }
6896
        if (x509->notBefore.length > 0) {
6897
            if (GetTimeString(x509->notBefore.data, ASN_UTC_TIME,
6898
                tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
6899
                if (GetTimeString(x509->notBefore.data, ASN_GENERALIZED_TIME,
6900
                tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
6901
                    WOLFSSL_MSG("Error getting not before date");
6902
                    return WOLFSSL_FAILURE;
6903
                }
6904
            }
6905
        }
6906
        else {
6907
            XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
6908
        }
6909
        tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
6910
        if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
6911
            return WOLFSSL_FAILURE;
6912
        }
6913
6914
        if (wolfSSL_BIO_write(bio, "\n            Not After : ",
6915
                      (int)XSTRLEN("\n            Not After : ")) <= 0) {
6916
            return WOLFSSL_FAILURE;
6917
        }
6918
        if (x509->notAfter.length > 0) {
6919
            if (GetTimeString(x509->notAfter.data, ASN_UTC_TIME,
6920
                tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
6921
                if (GetTimeString(x509->notAfter.data, ASN_GENERALIZED_TIME,
6922
                    tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
6923
                    WOLFSSL_MSG("Error getting not after date");
6924
                    return WOLFSSL_FAILURE;
6925
                }
6926
            }
6927
        }
6928
        else {
6929
            XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
6930
        }
6931
        tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
6932
        if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
6933
            return WOLFSSL_FAILURE;
6934
        }
6935
6936
        if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
6937
            return WOLFSSL_FAILURE;
6938
        }
6939
    }
6940
    #endif
6941
6942
    /* print subject */
6943
    if (X509PrintName(bio, wolfSSL_X509_get_subject_name(x509), subjType, 8)
6944
            != WOLFSSL_SUCCESS) {
6945
        return WOLFSSL_FAILURE;
6946
    }
6947
6948
    /* get and print public key */
6949
    if (X509PrintPubKey(bio, x509, 8) != WOLFSSL_SUCCESS) {
6950
        return WOLFSSL_FAILURE;
6951
    }
6952
6953
    /* print out extensions */
6954
    if (X509PrintExtensions(bio, x509, 8) != WOLFSSL_SUCCESS) {
6955
        return WOLFSSL_FAILURE;
6956
    }
6957
6958
    /* print out signature */
6959
    if (X509PrintSignature(bio, x509, 0, 4) != WOLFSSL_SUCCESS) {
6960
        return WOLFSSL_FAILURE;
6961
    }
6962
6963
    /* done with print out */
6964
    if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
6965
        return WOLFSSL_FAILURE;
6966
    }
6967
6968
    return WOLFSSL_SUCCESS;
6969
}
6970
int wolfSSL_X509_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
6971
{
6972
    return wolfSSL_X509_print_ex(bio, x509, 0, 0);
6973
}
6974
6975
#ifndef NO_FILESYSTEM
6976
int wolfSSL_X509_print_fp(XFILE fp, WOLFSSL_X509 *x509)
6977
{
6978
    WOLFSSL_BIO* bio;
6979
    int ret;
6980
6981
    WOLFSSL_ENTER("wolfSSL_X509_print_fp");
6982
6983
    if (!fp || !x509) {
6984
        WOLFSSL_MSG("Bad parameter");
6985
        return WOLFSSL_FAILURE;
6986
    }
6987
6988
    if (!(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file()))) {
6989
        WOLFSSL_MSG("wolfSSL_BIO_new wolfSSL_BIO_s_file error");
6990
        return WOLFSSL_FAILURE;
6991
    }
6992
6993
    if (wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS) {
6994
        WOLFSSL_MSG("wolfSSL_BIO_set_fp error");
6995
        wolfSSL_BIO_free(bio);
6996
        return WOLFSSL_FAILURE;
6997
    }
6998
6999
    ret = wolfSSL_X509_print(bio, x509);
7000
7001
    wolfSSL_BIO_free(bio);
7002
7003
    return ret;
7004
}
7005
#endif /* NO_FILESYSTEM */
7006
7007
#endif /* XSNPRINTF */
7008
7009
int wolfSSL_X509_signature_print(WOLFSSL_BIO *bp,
7010
        const WOLFSSL_X509_ALGOR *sigalg, const WOLFSSL_ASN1_STRING *sig)
7011
{
7012
    int length = 0;
7013
    word32 idx = 0;
7014
    int i;
7015
7016
    (void)sig;
7017
7018
    WOLFSSL_ENTER("wolfSSL_X509_signature_print");
7019
7020
    if (!bp || !sigalg) {
7021
        WOLFSSL_MSG("Bad parameter");
7022
        return WOLFSSL_FAILURE;
7023
    }
7024
7025
    if ((sigalg->algorithm->obj == NULL) ||
7026
        (sigalg->algorithm->obj[idx] != ASN_OBJECT_ID)) {
7027
        WOLFSSL_MSG("Bad ASN1 Object");
7028
        return WOLFSSL_FAILURE;
7029
    }
7030
    idx++; /* skip object id */
7031
7032
    if (GetLength((const byte*)sigalg->algorithm->obj, &idx, &length,
7033
                  sigalg->algorithm->objSz) < 0 || length < 0) {
7034
        return WOLFSSL_FAILURE;
7035
    }
7036
7037
    if (wolfSSL_BIO_puts(bp, "    Raw Signature Algorithm:") <= 0) {
7038
        WOLFSSL_MSG("wolfSSL_BIO_puts error");
7039
        return WOLFSSL_FAILURE;
7040
    }
7041
7042
    for (i = 0; i < length; ++i) {
7043
        char hex_digits[4];
7044
#ifdef XSNPRINTF
7045
        if (XSNPRINTF(hex_digits, sizeof(hex_digits), "%c%02X", i>0 ? ':' : ' ',
7046
                  (unsigned int)sigalg->algorithm->obj[idx+i])
7047
            >= (int)sizeof(hex_digits))
7048
        {
7049
            WOLFSSL_MSG("buffer overrun");
7050
            return WOLFSSL_FAILURE;
7051
        }
7052
#else
7053
        XSPRINTF(hex_digits, "%c%02X", i>0 ? ':' : ' ',
7054
                 (unsigned int)sigalg->algorithm->obj[idx+i]);
7055
#endif
7056
        if (wolfSSL_BIO_puts(bp, hex_digits) <= 0)
7057
            return WOLFSSL_FAILURE;
7058
    }
7059
7060
    if (wolfSSL_BIO_puts(bp, "\n") <= 0)
7061
        return WOLFSSL_FAILURE;
7062
7063
    return WOLFSSL_SUCCESS;
7064
}
7065
#endif /* !NO_BIO */
7066
7067
#ifndef NO_WOLFSSL_STUB
7068
void wolfSSL_X509_get0_signature(const WOLFSSL_ASN1_BIT_STRING **psig,
7069
        const WOLFSSL_X509_ALGOR **palg, const WOLFSSL_X509 *x509)
7070
{
7071
    (void)psig;
7072
    (void)palg;
7073
    (void)x509;
7074
    WOLFSSL_STUB("wolfSSL_X509_get0_signature");
7075
}
7076
#endif
7077
7078
#endif /* OPENSSL_EXTRA */
7079
7080
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
7081
const char* wolfSSL_X509_verify_cert_error_string(long err)
7082
{
7083
    return wolfSSL_ERR_reason_error_string(err);
7084
}
7085
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
7086
7087
#ifdef OPENSSL_EXTRA
7088
7089
/* Add directory path that will be used for loading certs and CRLs
7090
 * which have the <hash>.rn name format.
7091
 * type may be WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1.
7092
 * returns WOLFSSL_SUCCESS on successful, otherwise negative or zero. */
7093
int wolfSSL_X509_LOOKUP_add_dir(WOLFSSL_X509_LOOKUP* lookup, const char* dir,
7094
                               long type)
7095
{
7096
    return wolfSSL_X509_LOOKUP_ctrl(lookup, WOLFSSL_X509_L_ADD_DIR, dir, type,
7097
                                    NULL);
7098
}
7099
7100
int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP* lookup,
7101
                                 const char* file, long type)
7102
{
7103
#if !defined(NO_FILESYSTEM) && \
7104
    (defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM))
7105
    int           ret = WOLFSSL_FAILURE;
7106
    XFILE         fp;
7107
    long          sz;
7108
    byte*         pem = NULL;
7109
    byte*         curr = NULL;
7110
    byte*         prev = NULL;
7111
    WOLFSSL_X509* x509;
7112
    const char* header = NULL;
7113
    const char* footer = NULL;
7114
7115
    if (type != WOLFSSL_FILETYPE_PEM)
7116
        return WS_RETURN_CODE(BAD_FUNC_ARG, (int)WOLFSSL_FAILURE);
7117
7118
    fp = XFOPEN(file, "rb");
7119
    if (fp == XBADFILE)
7120
        return WS_RETURN_CODE(BAD_FUNC_ARG, (int)WOLFSSL_FAILURE);
7121
7122
    if(XFSEEK(fp, 0, XSEEK_END) != 0) {
7123
        XFCLOSE(fp);
7124
        return WS_RETURN_CODE(WOLFSSL_BAD_FILE,WOLFSSL_FAILURE);
7125
    }
7126
    sz = XFTELL(fp);
7127
    if(XFSEEK(fp, 0, XSEEK_SET) != 0) {
7128
        XFCLOSE(fp);
7129
        return WS_RETURN_CODE(WOLFSSL_BAD_FILE,WOLFSSL_FAILURE);
7130
    }
7131
7132
    if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
7133
        WOLFSSL_MSG("X509_LOOKUP_load_file size error");
7134
        goto end;
7135
    }
7136
7137
    pem = (byte*)XMALLOC(sz, 0, DYNAMIC_TYPE_PEM);
7138
    if (pem == NULL) {
7139
        ret = MEMORY_ERROR;
7140
        goto end;
7141
    }
7142
7143
    /* Read in file which may be CRLs or certificates. */
7144
    if (XFREAD(pem, (size_t)sz, 1, fp) != 1)
7145
        goto end;
7146
7147
    prev = curr = pem;
7148
    do {
7149
        /* get PEM header and footer based on type */
7150
        if (wc_PemGetHeaderFooter(CRL_TYPE, &header, &footer) == 0 &&
7151
                XSTRNSTR((char*)curr, header, (unsigned int)sz) != NULL) {
7152
#ifdef HAVE_CRL
7153
            WOLFSSL_CERT_MANAGER* cm = lookup->store->cm;
7154
7155
            if (cm->crl == NULL) {
7156
                if (wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECK)
7157
                    != WOLFSSL_SUCCESS) {
7158
                    WOLFSSL_MSG("Enable CRL failed");
7159
                    goto end;
7160
                }
7161
            }
7162
7163
            ret = BufferLoadCRL(cm->crl, curr, sz, WOLFSSL_FILETYPE_PEM,
7164
                NO_VERIFY);
7165
            if (ret != WOLFSSL_SUCCESS)
7166
                goto end;
7167
#endif
7168
            curr = (byte*)XSTRNSTR((char*)curr, footer, (unsigned int)sz);
7169
        }
7170
        else if (wc_PemGetHeaderFooter(CERT_TYPE, &header, &footer) == 0 &&
7171
                XSTRNSTR((char*)curr, header, (unsigned int)sz) != NULL) {
7172
            x509 = wolfSSL_X509_load_certificate_buffer(curr, (int)sz,
7173
                                                        WOLFSSL_FILETYPE_PEM);
7174
            if (x509 == NULL)
7175
                 goto end;
7176
            ret = wolfSSL_X509_STORE_add_cert(lookup->store, x509);
7177
            wolfSSL_X509_free(x509);
7178
            if (ret != WOLFSSL_SUCCESS)
7179
                goto end;
7180
            curr = (byte*)XSTRNSTR((char*)curr, footer, (unsigned int)sz);
7181
        }
7182
        else
7183
            goto end;
7184
7185
        if (curr == NULL)
7186
            goto end;
7187
7188
        curr++;
7189
        sz -= (long)(curr - prev);
7190
        prev = curr;
7191
    }
7192
    while (ret == WOLFSSL_SUCCESS);
7193
7194
end:
7195
    if (pem != NULL)
7196
        XFREE(pem, 0, DYNAMIC_TYPE_PEM);
7197
    XFCLOSE(fp);
7198
    return WS_RETURN_CODE(ret, (int)WOLFSSL_FAILURE);
7199
#else
7200
    (void)lookup;
7201
    (void)file;
7202
    (void)type;
7203
    return WS_RETURN_CODE(WOLFSSL_FAILURE,WOLFSSL_FAILURE);
7204
#endif
7205
}
7206
7207
WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_hash_dir(void)
7208
{
7209
    /* Method implementation in functions. */
7210
    static WOLFSSL_X509_LOOKUP_METHOD meth = { 1 };
7211
    return &meth;
7212
}
7213
7214
WOLFSSL_X509_LOOKUP_METHOD* wolfSSL_X509_LOOKUP_file(void)
7215
{
7216
    /* Method implementation in functions. */
7217
    static WOLFSSL_X509_LOOKUP_METHOD meth = { 0 };
7218
    return &meth;
7219
}
7220
7221
/* set directory path to load certificate or CRL which have the hash.N form */
7222
/* for late use                                                             */
7223
/* @param ctx    a pointer to WOLFSSL_BY_DIR structure                      */
7224
/* @param argc   directory path                                             */
7225
/* @param argl   file type, either WOLFSSL_FILETYPE_PEM or                  */
7226
/*                                          WOLFSSL_FILETYPE_ASN1           */
7227
/* @return WOLFSSL_SUCCESS on successful, otherwise negative or zero        */
7228
static int x509AddCertDir(WOLFSSL_BY_DIR *ctx, const char *argc, long argl)
7229
{
7230
#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
7231
    WOLFSSL_BY_DIR_entry *entry;
7232
    size_t pathLen;
7233
    int i, num;
7234
    const char* c;
7235
#ifdef WOLFSSL_SMALL_STACK
7236
    char *buf;
7237
#else
7238
    char  buf[MAX_FILENAME_SZ];
7239
#endif
7240
7241
    WOLFSSL_ENTER("x509AddCertDir");
7242
7243
    pathLen = 0;
7244
    c = argc;
7245
    /* sanity check, zero length */
7246
    if (ctx == NULL || c == NULL || *c == '\0')
7247
        return WOLFSSL_FAILURE;
7248
7249
#ifdef WOLFSSL_SMALL_STACK
7250
    buf = (char*)XMALLOC(MAX_FILENAME_SZ, NULL, DYNAMIC_TYPE_OPENSSL);
7251
    if (buf == NULL) {
7252
        WOLFSSL_LEAVE("x509AddCertDir", MEMORY_E);
7253
        return MEMORY_E;
7254
    }
7255
#endif
7256
7257
    XMEMSET(buf, 0, MAX_FILENAME_SZ);
7258
7259
    do {
7260
        if (*c == SEPARATOR_CHAR || *c == '\0') {
7261
7262
            num = wolfSSL_sk_BY_DIR_entry_num(ctx->dir_entry);
7263
7264
            for (i=0; i<num; i++) {
7265
7266
                entry = wolfSSL_sk_BY_DIR_entry_value(ctx->dir_entry, i);
7267
7268
                if (XSTRLEN(entry->dir_name) == pathLen &&
7269
                    XSTRNCMP(entry->dir_name, buf, pathLen) == 0) {
7270
                    WOLFSSL_MSG("dir entry found");
7271
                    break;
7272
                }
7273
            }
7274
7275
            if (num == -1 || i == num) {
7276
                WOLFSSL_MSG("no entry found");
7277
7278
                if (ctx->dir_entry == NULL) {
7279
                    ctx->dir_entry = wolfSSL_sk_BY_DIR_entry_new_null();
7280
7281
                    if (ctx->dir_entry == NULL) {
7282
                        WOLFSSL_MSG("failed to allocate dir_entry");
7283
                        #ifdef WOLFSSL_SMALL_STACK
7284
                            XFREE(buf, 0, DYNAMIC_TYPE_OPENSSL);
7285
                        #endif
7286
                        return 0;
7287
                    }
7288
                }
7289
7290
                entry = wolfSSL_BY_DIR_entry_new();
7291
                if (entry == NULL) {
7292
                    WOLFSSL_MSG("failed to allocate dir entry");
7293
                    #ifdef WOLFSSL_SMALL_STACK
7294
                        XFREE(buf, 0, DYNAMIC_TYPE_OPENSSL);
7295
                    #endif
7296
                    return 0;
7297
                }
7298
                entry->dir_type = (int)argl;
7299
                entry->dir_name = (char*)XMALLOC(pathLen + 1/* \0 termination*/
7300
                                                , NULL, DYNAMIC_TYPE_OPENSSL);
7301
                entry->hashes = wolfSSL_sk_BY_DIR_HASH_new_null();
7302
                if (entry->dir_name == NULL || entry->hashes == NULL) {
7303
                    WOLFSSL_MSG("failed to allocate dir name");
7304
                    wolfSSL_BY_DIR_entry_free(entry);
7305
                    #ifdef WOLFSSL_SMALL_STACK
7306
                        XFREE(buf, 0, DYNAMIC_TYPE_OPENSSL);
7307
                    #endif
7308
                    return 0;
7309
                }
7310
7311
                XSTRNCPY(entry->dir_name, buf, pathLen);
7312
                entry->dir_name[pathLen] = '\0';
7313
7314
                if (wolfSSL_sk_BY_DIR_entry_push(ctx->dir_entry, entry)
7315
                                                    != WOLFSSL_SUCCESS) {
7316
                    wolfSSL_BY_DIR_entry_free(entry);
7317
                    #ifdef WOLFSSL_SMALL_STACK
7318
                        XFREE(buf, 0, DYNAMIC_TYPE_OPENSSL);
7319
                    #endif
7320
                    return 0;
7321
                }
7322
            }
7323
            /* skip separator */
7324
            if (*c == SEPARATOR_CHAR) c++;
7325
7326
            pathLen = 0;
7327
            XMEMSET(buf, 0, MAX_FILENAME_SZ);
7328
        }
7329
        buf[pathLen++] = *c;
7330
7331
    } while(*c++ != '\0');
7332
7333
#ifdef WOLFSSL_SMALL_STACK
7334
    XFREE(buf, 0, DYNAMIC_TYPE_OPENSSL);
7335
#endif
7336
7337
    return WOLFSSL_SUCCESS;
7338
#else
7339
    (void)ctx;
7340
    (void)argc;
7341
    (void)argl;
7342
    return WOLFSSL_NOT_IMPLEMENTED;
7343
#endif
7344
}
7345
7346
/* set additional data to X509_LOOKUP                                   */
7347
/* @param ctx    a pointer to X509_LOOKUP structure                     */
7348
/* @param cmd    control command :                                      */
7349
/*               X509_L_FILE_LOAD, X509_L_ADD_DIR X509_L_ADD_STORE or   */
7350
/*               X509_L_LOAD_STORE                                      */
7351
/* @param argc   arguments for the control command                      */
7352
/* @param argl   arguments for the control command                      */
7353
/* @param **ret  return value of the control command                    */
7354
/* @return WOLFSSL_SUCCESS on successful, otherwise WOLFSSL_FAILURE     */
7355
/* note: WOLFSSL_X509_L_ADD_STORE and WOLFSSL_X509_L_LOAD_STORE have not*/
7356
/*       yet implemented. It returns WOLFSSL_NOT_IMPLEMENTED            */
7357
/*       when those control commands are passed.                        */
7358
int wolfSSL_X509_LOOKUP_ctrl(WOLFSSL_X509_LOOKUP *ctx, int cmd,
7359
        const char *argc, long argl, char **ret)
7360
{
7361
    int lret = WOLFSSL_FAILURE;
7362
7363
    WOLFSSL_ENTER("wolfSSL_X509_LOOKUP_ctrl");
7364
#if !defined(NO_FILESYSTEM)
7365
    if (ctx != NULL) {
7366
        switch (cmd) {
7367
        case WOLFSSL_X509_L_FILE_LOAD:
7368
            /* expects to return a number of processed cert or crl file */
7369
            lret = wolfSSL_X509_load_cert_crl_file(ctx, argc, (int)argl) > 0 ?
7370
                            WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
7371
            break;
7372
        case WOLFSSL_X509_L_ADD_DIR:
7373
            /* store directory location to use it later */
7374
#if !defined(NO_WOLFSSL_DIR)
7375
            lret = x509AddCertDir(ctx->dirs, argc, argl);
7376
#else
7377
            (void)x509AddCertDir;
7378
            lret = WOLFSSL_NOT_IMPLEMENTED;
7379
#endif
7380
            break;
7381
        case WOLFSSL_X509_L_ADD_STORE:
7382
        case WOLFSSL_X509_L_LOAD_STORE:
7383
            return WOLFSSL_NOT_IMPLEMENTED;
7384
7385
        default:
7386
            break;
7387
        }
7388
    }
7389
    (void)ret;
7390
#else
7391
    (void)ctx;
7392
    (void)argc;
7393
    (void)argl;
7394
    (void)ret;
7395
    (void)cmd;
7396
    (void)x509AddCertDir;
7397
    lret = WOLFSSL_NOT_IMPLEMENTED;
7398
#endif
7399
    return lret;
7400
}
7401
7402
7403
#if defined(WOLFSSL_CERT_GEN)
7404
static int wolfssl_x509_make_der(WOLFSSL_X509* x509, int req,
7405
        unsigned char* der, int* derSz, int includeSig);
7406
#endif
7407
7408
#ifdef WOLFSSL_CERT_GEN
7409
#ifndef NO_BIO
7410
/* Converts the X509 to DER format and outputs it into bio.
7411
 *
7412
 * bio  is the structure to hold output DER
7413
 * x509 certificate to create DER from
7414
 * req  if set then a CSR is generated
7415
 *
7416
 * returns WOLFSSL_SUCCESS on success
7417
 */
7418
static int loadX509orX509REQFromBio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int req)
7419
{
7420
    int ret = WOLFSSL_FAILURE;
7421
    /* Get large buffer to hold cert der */
7422
    int derSz = X509_BUFFER_SZ;
7423
#ifdef WOLFSSL_SMALL_STACK
7424
    byte* der;
7425
#else
7426
    byte der[X509_BUFFER_SZ];
7427
#endif
7428
    WOLFSSL_ENTER("wolfSSL_i2d_X509_bio");
7429
7430
    if (bio == NULL || x509 == NULL) {
7431
        return WOLFSSL_FAILURE;
7432
    }
7433
7434
#ifdef WOLFSSL_SMALL_STACK
7435
    der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7436
    if (!der) {
7437
        WOLFSSL_MSG("malloc failed");
7438
        return WOLFSSL_FAILURE;
7439
    }
7440
#endif
7441
7442
    if (wolfssl_x509_make_der(x509, req, der, &derSz, 1) != WOLFSSL_SUCCESS) {
7443
        goto cleanup;
7444
    }
7445
7446
    if (wolfSSL_BIO_write(bio, der, derSz) != derSz) {
7447
        goto cleanup;
7448
    }
7449
7450
    ret = WOLFSSL_SUCCESS;
7451
cleanup:
7452
    #ifdef WOLFSSL_SMALL_STACK
7453
    XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7454
    #endif
7455
7456
    return ret;
7457
}
7458
7459
/* Converts the X509 to DER format and outputs it into bio.
7460
 *
7461
 * bio  is the structure to hold output DER
7462
 * x509 certificate to create DER from
7463
 *
7464
 * returns WOLFSSL_SUCCESS on success
7465
 */
7466
int wolfSSL_i2d_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
7467
{
7468
    return loadX509orX509REQFromBio(bio, x509, 0);
7469
}
7470
7471
#ifdef WOLFSSL_CERT_REQ
7472
int wolfSSL_i2d_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
7473
{
7474
    return loadX509orX509REQFromBio(bio, x509, 1);
7475
}
7476
#endif /* WOLFSSL_CERT_REQ */
7477
#endif /* !NO_BIO */
7478
#endif /* WOLFSSL_CERT_GEN */
7479
7480
/* Converts an internal structure to a DER buffer
7481
 *
7482
 * x509 structure to get DER buffer from
7483
 * out  buffer to hold result. If NULL then *out is NULL then a new buffer is
7484
 *      created.
7485
 *
7486
 * returns the size of the DER result on success
7487
 */
7488
int wolfSSL_i2d_X509(WOLFSSL_X509* x509, unsigned char** out)
7489
{
7490
    const unsigned char* der;
7491
    int derSz = 0;
7492
    int advance = 1;
7493
7494
    WOLFSSL_ENTER("wolfSSL_i2d_X509");
7495
7496
    if (x509 == NULL) {
7497
        WOLFSSL_LEAVE("wolfSSL_i2d_X509", BAD_FUNC_ARG);
7498
        return BAD_FUNC_ARG;
7499
    }
7500
7501
    der = wolfSSL_X509_get_der(x509, &derSz);
7502
    if (der == NULL) {
7503
        WOLFSSL_LEAVE("wolfSSL_i2d_X509", MEMORY_E);
7504
        return MEMORY_E;
7505
    }
7506
7507
    if (out != NULL && *out == NULL) {
7508
        *out = (unsigned char*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL);
7509
        if (*out == NULL) {
7510
            WOLFSSL_LEAVE("wolfSSL_i2d_X509", MEMORY_E);
7511
            return MEMORY_E;
7512
        }
7513
        advance = 0;
7514
    }
7515
7516
    if (out != NULL) {
7517
        XMEMCPY(*out, der, derSz);
7518
        if (advance)
7519
            *out += derSz;
7520
    }
7521
7522
    WOLFSSL_LEAVE("wolfSSL_i2d_X509", derSz);
7523
    return derSz;
7524
}
7525
7526
#ifndef NO_BIO
7527
/**
7528
 * Converts the DER from bio and creates a WOLFSSL_X509 structure from it.
7529
 * @param bio  is the structure holding DER
7530
 * @param x509 certificate to create from DER. Can be NULL
7531
 * @param req  1 for a CSR and 0 for a x509 cert
7532
 * @return pointer to WOLFSSL_X509 structure on success and NULL on fail
7533
 */
7534
static WOLFSSL_X509* d2i_X509orX509REQ_bio(WOLFSSL_BIO* bio,
7535
                                            WOLFSSL_X509** x509, int req)
7536
{
7537
    WOLFSSL_X509* localX509 = NULL;
7538
    byte* mem  = NULL;
7539
    int    size;
7540
7541
    WOLFSSL_ENTER("wolfSSL_d2i_X509_bio");
7542
7543
    if (bio == NULL) {
7544
        WOLFSSL_MSG("Bad Function Argument bio is NULL");
7545
        return NULL;
7546
    }
7547
7548
    size = wolfSSL_BIO_get_len(bio);
7549
    if (size <= 0) {
7550
        WOLFSSL_MSG("wolfSSL_BIO_get_len error. Possibly no pending data.");
7551
        WOLFSSL_ERROR(ASN1_R_HEADER_TOO_LONG);
7552
        return NULL;
7553
    }
7554
7555
    if (!(mem = (byte*)XMALLOC(size, NULL, DYNAMIC_TYPE_OPENSSL))) {
7556
        WOLFSSL_MSG("malloc error");
7557
        return NULL;
7558
    }
7559
7560
    if ((size = wolfSSL_BIO_read(bio, mem, size)) == 0) {
7561
        WOLFSSL_MSG("wolfSSL_BIO_read error");
7562
        XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL);
7563
        return NULL;
7564
    }
7565
7566
    if (req) {
7567
#ifdef WOLFSSL_CERT_REQ
7568
        localX509 = wolfSSL_X509_REQ_d2i(NULL, mem, size);
7569
#else
7570
        WOLFSSL_MSG("CSR not compiled in");
7571
#endif
7572
    }
7573
    else {
7574
        localX509 = wolfSSL_X509_d2i(NULL, mem, size);
7575
    }
7576
    if (localX509 == NULL) {
7577
        WOLFSSL_MSG("wolfSSL_X509_d2i error");
7578
        XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL);
7579
        return NULL;
7580
    }
7581
7582
    if (x509 != NULL) {
7583
        *x509 = localX509;
7584
    }
7585
7586
    XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL);
7587
    return localX509;
7588
}
7589
7590
WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509)
7591
{
7592
    return d2i_X509orX509REQ_bio(bio, x509, 0);
7593
}
7594
7595
#ifdef WOLFSSL_CERT_REQ
7596
WOLFSSL_X509* wolfSSL_d2i_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509)
7597
{
7598
    return d2i_X509orX509REQ_bio(bio, x509, 1);
7599
}
7600
#endif
7601
#endif /* !NO_BIO */
7602
7603
#endif /* OPENSSL_EXTRA */
7604
7605
#ifdef OPENSSL_EXTRA
7606
/* Use the public key to verify the signature. Note: this only verifies
7607
 * the certificate signature.
7608
 * returns WOLFSSL_SUCCESS on successful signature verification */
7609
static int verifyX509orX509REQ(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey, int req)
7610
{
7611
    int ret;
7612
    const byte* der;
7613
    int derSz = 0;
7614
    int type;
7615
7616
    (void)req;
7617
7618
    if (x509 == NULL || pkey == NULL) {
7619
        return WOLFSSL_FATAL_ERROR;
7620
    }
7621
7622
    der = wolfSSL_X509_get_der(x509, &derSz);
7623
    if (der == NULL) {
7624
        WOLFSSL_MSG("Error getting WOLFSSL_X509 DER");
7625
        return WOLFSSL_FATAL_ERROR;
7626
    }
7627
7628
    switch (pkey->type) {
7629
        case EVP_PKEY_RSA:
7630
            type = RSAk;
7631
            break;
7632
7633
        case EVP_PKEY_EC:
7634
            type = ECDSAk;
7635
            break;
7636
7637
        case EVP_PKEY_DSA:
7638
            type = DSAk;
7639
            break;
7640
7641
        default:
7642
            WOLFSSL_MSG("Unknown pkey key type");
7643
            return WOLFSSL_FATAL_ERROR;
7644
    }
7645
7646
#ifdef WOLFSSL_CERT_REQ
7647
    if (req)
7648
        ret = CheckCSRSignaturePubKey(der, derSz, x509->heap,
7649
                (unsigned char*)pkey->pkey.ptr, pkey->pkey_sz, type);
7650
    else
7651
#endif
7652
        ret = CheckCertSignaturePubKey(der, derSz, x509->heap,
7653
                (unsigned char*)pkey->pkey.ptr, pkey->pkey_sz, type);
7654
    if (ret == 0) {
7655
        return WOLFSSL_SUCCESS;
7656
    }
7657
    return WOLFSSL_FAILURE;
7658
}
7659
7660
int wolfSSL_X509_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey)
7661
{
7662
    return verifyX509orX509REQ(x509, pkey, 0);
7663
}
7664
7665
#ifdef WOLFSSL_CERT_REQ
7666
int wolfSSL_X509_REQ_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey)
7667
{
7668
    return verifyX509orX509REQ(x509, pkey, 1);
7669
}
7670
#endif /* WOLFSSL_CERT_REQ */
7671
7672
#if !defined(NO_FILESYSTEM)
7673
static void *wolfSSL_d2i_X509_fp_ex(XFILE file, void **x509, int type)
7674
{
7675
    void *newx509 = NULL;
7676
    byte *fileBuffer = NULL;
7677
    long sz = 0;
7678
7679
    /* init variable */
7680
    if (x509)
7681
        *x509 = NULL;
7682
7683
    /* argument check */
7684
    if (file == XBADFILE) {
7685
        return NULL;
7686
    }
7687
7688
    /* determine file size */
7689
    if (XFSEEK(file, 0, XSEEK_END) != 0) {
7690
        return NULL;
7691
    }
7692
    sz = XFTELL(file);
7693
    if (XFSEEK(file, 0, XSEEK_SET) != 0) {
7694
        return NULL;
7695
    }
7696
7697
    if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
7698
        WOLFSSL_MSG("d2i_X509_fp_ex file size error");
7699
        return NULL;
7700
    }
7701
7702
    fileBuffer = (byte *)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
7703
    if (fileBuffer != NULL) {
7704
        if ((long)XFREAD(fileBuffer, 1, sz, file) != sz) {
7705
            WOLFSSL_MSG("File read failed");
7706
            goto err_exit;
7707
        }
7708
        if (type == CERT_TYPE) {
7709
            newx509 = (void *)wolfSSL_X509_d2i(NULL, fileBuffer, (int)sz);
7710
        }
7711
    #ifdef HAVE_CRL
7712
        else if (type == CRL_TYPE) {
7713
            newx509 = (void *)wolfSSL_d2i_X509_CRL(NULL, fileBuffer, (int)sz);
7714
        }
7715
    #endif
7716
    #ifdef WOLFSSL_CERT_REQ
7717
        else if (type == CERTREQ_TYPE) {
7718
             newx509 = (void *)wolfSSL_X509_REQ_d2i(NULL, fileBuffer, (int)sz);
7719
        }
7720
    #endif
7721
    #if !defined(NO_ASN) && !defined(NO_PWDBASED) && defined(HAVE_PKCS12)
7722
        else if (type == PKCS12_TYPE) {
7723
            if ((newx509 = wc_PKCS12_new()) == NULL) {
7724
                goto err_exit;
7725
            }
7726
            if (wc_d2i_PKCS12(fileBuffer, (int)sz, (WC_PKCS12*)newx509) < 0) {
7727
                goto err_exit;
7728
            }
7729
        }
7730
    #endif
7731
        else {
7732
            goto err_exit;
7733
        }
7734
        if (newx509 == NULL) {
7735
            WOLFSSL_MSG("X509 failed");
7736
            goto err_exit;
7737
        }
7738
    }
7739
7740
    if (x509)
7741
        *x509 = newx509;
7742
7743
    goto _exit;
7744
7745
err_exit:
7746
#if !defined(NO_ASN) && !defined(NO_PWDBASED) && defined(HAVE_PKCS12)
7747
    if ((newx509 != NULL) && (type == PKCS12_TYPE)) {
7748
        wc_PKCS12_free((WC_PKCS12*)newx509);
7749
        newx509 = NULL;
7750
    }
7751
#endif
7752
_exit:
7753
    if (fileBuffer != NULL)
7754
        XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
7755
7756
    return newx509;
7757
}
7758
7759
#ifdef WOLFSSL_CERT_REQ
7760
WOLFSSL_X509* wolfSSL_d2i_X509_REQ_fp(XFILE fp, WOLFSSL_X509 **req)
7761
{
7762
    return (WOLFSSL_X509 *)wolfSSL_d2i_X509_fp_ex(fp, (void **)req,
7763
                                                  CERTREQ_TYPE);
7764
}
7765
#endif /* WOLFSSL_CERT_REQ */
7766
7767
WOLFSSL_X509 *wolfSSL_d2i_X509_fp(XFILE fp, WOLFSSL_X509 **x509)
7768
{
7769
    WOLFSSL_ENTER("wolfSSL_d2i_X509_fp");
7770
    return (WOLFSSL_X509 *)wolfSSL_d2i_X509_fp_ex(fp, (void **)x509, CERT_TYPE);
7771
}
7772
7773
/* load certificate or CRL file, and add it to the STORE           */
7774
/* @param ctx    a pointer to X509_LOOKUP structure                */
7775
/* @param file   file name to load                                 */
7776
/* @param type   WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1     */
7777
/* @return a number of loading CRL or certificate, otherwise zero  */
7778
WOLFSSL_API int wolfSSL_X509_load_cert_crl_file(WOLFSSL_X509_LOOKUP *ctx,
7779
    const char *file, int type)
7780
{
7781
    WOLFSSL_X509 *x509 = NULL;
7782
7783
    int cnt = 0;
7784
7785
    WOLFSSL_ENTER("wolfSSL_X509_load_cert_crl_file");
7786
7787
    /* stanity check */
7788
    if (ctx == NULL || file == NULL) {
7789
        WOLFSSL_MSG("bad arguments");
7790
        return 0;
7791
    }
7792
7793
    if (type != WOLFSSL_FILETYPE_PEM) {
7794
        x509 = wolfSSL_X509_load_certificate_file(file, type);
7795
        if (x509 != NULL) {
7796
            if (wolfSSL_X509_STORE_add_cert(ctx->store, x509)
7797
                                    == WOLFSSL_SUCCESS) {
7798
                cnt++;
7799
            } else {
7800
                WOLFSSL_MSG("wolfSSL_X509_STORE_add_cert error");
7801
            }
7802
            wolfSSL_X509_free(x509);
7803
            x509 = NULL;
7804
        } else {
7805
            WOLFSSL_MSG("wolfSSL_X509_load_certificate_file error");
7806
        }
7807
7808
    } else {
7809
#if defined(OPENSSL_ALL)
7810
    #if !defined(NO_BIO)
7811
        STACK_OF(WOLFSSL_X509_INFO) *info;
7812
        WOLFSSL_X509_INFO *info_tmp;
7813
        int i;
7814
        int num = 0;
7815
        WOLFSSL_BIO *bio = wolfSSL_BIO_new_file(file, "rb");
7816
        if(!bio) {
7817
            WOLFSSL_MSG("wolfSSL_BIO_new error");
7818
            return cnt;
7819
        }
7820
7821
        info = wolfSSL_PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
7822
7823
        wolfSSL_BIO_free(bio);
7824
7825
        if (!info) {
7826
            WOLFSSL_MSG("wolfSSL_PEM_X509_INFO_read_bio error");
7827
            return cnt;
7828
        }
7829
        num = wolfSSL_sk_X509_INFO_num(info);
7830
        for (i=0; i < num; i++) {
7831
            info_tmp = wolfSSL_sk_X509_INFO_value(info, i);
7832
7833
            if (info_tmp->x509) {
7834
                if(wolfSSL_X509_STORE_add_cert(ctx->store, info_tmp->x509) ==
7835
                    WOLFSSL_SUCCESS) {
7836
                    cnt ++;
7837
                } else {
7838
                    WOLFSSL_MSG("wolfSSL_X509_STORE_add_cert failed");
7839
                }
7840
            }
7841
#ifdef HAVE_CRL
7842
            if (info_tmp->crl) {
7843
                if(wolfSSL_X509_STORE_add_crl(ctx->store, info_tmp->crl) ==
7844
                    WOLFSSL_SUCCESS) {
7845
                    cnt ++;
7846
                } else {
7847
                    WOLFSSL_MSG("wolfSSL_X509_STORE_add_crl failed");
7848
                }
7849
            }
7850
#endif
7851
        }
7852
        wolfSSL_sk_X509_INFO_pop_free(info, wolfSSL_X509_INFO_free);
7853
    #elif defined(HAVE_CRL)
7854
        /* Only supports one certificate or CRL in the file. */
7855
        WOLFSSL_X509_CRL* crl = NULL;
7856
        XFILE fp = XFOPEN(file, "rb");
7857
        if (fp == XBADFILE) {
7858
            WOLFSSL_MSG("XFOPEN error");
7859
            return cnt;
7860
        }
7861
7862
        x509 = wolfSSL_PEM_read_X509(fp, NULL, NULL, NULL);
7863
        if (x509 != NULL) {
7864
            if (wolfSSL_X509_STORE_add_cert(ctx->store, x509) ==
7865
                WOLFSSL_SUCCESS) {
7866
                cnt++;
7867
            }
7868
            else {
7869
                WOLFSSL_MSG("wolfSSL_X509_STORE_add_cert failed");
7870
            }
7871
        }
7872
        else {
7873
            if (XFSEEK(fp, 0, XSEEK_SET) != 0) {
7874
                WOLFSSL_MSG("XFSEEK error");
7875
                return cnt;
7876
            }
7877
            crl = wolfSSL_PEM_read_X509_CRL(fp, NULL, NULL, NULL);
7878
            if (crl != NULL) {
7879
                if (wolfSSL_X509_STORE_add_crl(ctx->store, crl) ==
7880
                    WOLFSSL_SUCCESS) {
7881
                    cnt++;
7882
                }
7883
                else {
7884
                    WOLFSSL_MSG("wolfSSL_X509_STORE_add_crl failed");
7885
                }
7886
            }
7887
            else {
7888
                WOLFSSL_MSG("Certificate and CRL not recognized");
7889
                return cnt;
7890
            }
7891
        }
7892
7893
        wolfSSL_X509_free(x509);
7894
        wolfSSL_X509_CRL_free(crl);
7895
    #endif
7896
#else
7897
    (void)cnt;
7898
#endif /* OPENSSL_ALL && !NO_BIO */
7899
    }
7900
7901
    WOLFSSL_LEAVE("wolfSSL_X509_load_ceretificate_crl_file", cnt);
7902
    return cnt;
7903
}
7904
#endif /* !NO_FILESYSTEM */
7905
7906
7907
#ifdef HAVE_CRL
7908
7909
#ifndef NO_BIO
7910
WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL_bio(WOLFSSL_BIO *bp,
7911
                                                    WOLFSSL_X509_CRL **x)
7912
{
7913
    int derSz;
7914
    byte* der = NULL;
7915
    WOLFSSL_X509_CRL* crl = NULL;
7916
7917
    if (bp == NULL)
7918
        return NULL;
7919
7920
    if ((derSz = wolfSSL_BIO_get_len(bp)) > 0) {
7921
        der = (byte*)XMALLOC(derSz, 0, DYNAMIC_TYPE_DER);
7922
        if (der != NULL) {
7923
            if (wolfSSL_BIO_read(bp, der, derSz) == derSz) {
7924
                crl = wolfSSL_d2i_X509_CRL(x, der, derSz);
7925
            }
7926
        }
7927
    }
7928
7929
    if (der != NULL) {
7930
        XFREE(der, 0, DYNAMIC_TYPE_DER);
7931
    }
7932
7933
    return crl;
7934
}
7935
#endif
7936
7937
#ifndef NO_FILESYSTEM
7938
WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL_fp(XFILE fp, WOLFSSL_X509_CRL **crl)
7939
{
7940
    WOLFSSL_ENTER("wolfSSL_d2i_X509_CRL_fp");
7941
    return (WOLFSSL_X509_CRL *)wolfSSL_d2i_X509_fp_ex(fp, (void **)crl, CRL_TYPE);
7942
}
7943
7944
/* Read CRL file, and add it to store and corresponding cert manager     */
7945
/* @param ctx   a pointer of X509_LOOKUP back to the X509_STORE          */
7946
/* @param file  a file to read                                           */
7947
/* @param type  WOLFSSL_FILETYPE_PEM or WOLFSSL_FILETYPE_ASN1            */
7948
/* @return WOLFSSL_SUCCESS(1) on successful, otherwise WOLFSSL_FAILURE(0)*/
7949
WOLFSSL_API int wolfSSL_X509_load_crl_file(WOLFSSL_X509_LOOKUP *ctx,
7950
                                             const char *file, int type)
7951
{
7952
#ifndef NO_BIO
7953
    int ret = WOLFSSL_FAILURE;
7954
    int count = 0;
7955
    WOLFSSL_BIO *bio = NULL;
7956
    WOLFSSL_X509_CRL *crl = NULL;
7957
7958
    WOLFSSL_ENTER("wolfSSL_X509_load_crl_file");
7959
7960
    if (ctx == NULL || file == NULL)
7961
        return ret;
7962
7963
    if ((bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file())) == NULL)
7964
        return ret;
7965
7966
    if (wolfSSL_BIO_read_filename(bio, file) <= 0) {
7967
        wolfSSL_BIO_free(bio);
7968
        return ret;
7969
    }
7970
7971
    if (wolfSSL_BIO_read_filename(bio, file) <= 0) {
7972
        wolfSSL_BIO_free(bio);
7973
        return ret;
7974
    }
7975
7976
    if (type == WOLFSSL_FILETYPE_PEM) {
7977
        do {
7978
            crl = wolfSSL_PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL);
7979
            if (crl == NULL) {
7980
                if (count <= 0) {
7981
                    WOLFSSL_MSG("Load crl failed");
7982
                }
7983
                break;
7984
            }
7985
7986
            ret = wolfSSL_X509_STORE_add_crl(ctx->store, crl);
7987
            if (ret == WOLFSSL_FAILURE) {
7988
                WOLFSSL_MSG("Adding crl failed");
7989
                break;
7990
            }
7991
            count++;
7992
            wolfSSL_X509_CRL_free(crl);
7993
            crl = NULL;
7994
        }   while(crl == NULL);
7995
7996
        ret = count;
7997
    }
7998
    else if (type == WOLFSSL_FILETYPE_ASN1) {
7999
        crl = wolfSSL_d2i_X509_CRL_bio(bio, NULL);
8000
        if (crl == NULL) {
8001
            WOLFSSL_MSG("Load crl failed");
8002
        } else {
8003
            ret = wolfSSL_X509_STORE_add_crl(ctx->store, crl);
8004
            if (ret == WOLFSSL_FAILURE) {
8005
                WOLFSSL_MSG("Adding crl failed");
8006
            } else {
8007
                ret = 1;/* handled a file */
8008
            }
8009
        }
8010
    } else {
8011
        WOLFSSL_MSG("Invalid file type");
8012
    }
8013
8014
    wolfSSL_X509_CRL_free(crl);
8015
    wolfSSL_BIO_free(bio);
8016
8017
    WOLFSSL_LEAVE("wolfSSL_X509_load_crl_file", ret);
8018
    return ret;
8019
#else
8020
    int ret = WOLFSSL_FAILURE;
8021
    int count = 0;
8022
    XFILE fp;
8023
    WOLFSSL_X509_CRL *crl = NULL;
8024
8025
    WOLFSSL_ENTER("wolfSSL_X509_load_crl_file");
8026
8027
    if (ctx == NULL || file == NULL)
8028
        return ret;
8029
8030
    if ((fp = XFOPEN(file, "rb")) == XBADFILE)
8031
        return ret;
8032
8033
    if (type == WOLFSSL_FILETYPE_PEM) {
8034
        do {
8035
            crl = wolfSSL_PEM_read_X509_CRL(fp, NULL, NULL, NULL);
8036
            if (crl == NULL) {
8037
                if (count <= 0) {
8038
                    WOLFSSL_MSG("Load crl failed");
8039
                }
8040
                break;
8041
            }
8042
8043
            ret = wolfSSL_X509_STORE_add_crl(ctx->store, crl);
8044
            if (ret == WOLFSSL_FAILURE) {
8045
                WOLFSSL_MSG("Adding crl failed");
8046
                break;
8047
            }
8048
            count++;
8049
            wolfSSL_X509_CRL_free(crl);
8050
            crl = NULL;
8051
        }
8052
        while(crl == NULL);
8053
8054
        ret = count;
8055
    }
8056
    else if (type == WOLFSSL_FILETYPE_ASN1) {
8057
        crl = wolfSSL_d2i_X509_CRL_fp(fp, NULL);
8058
        if (crl == NULL) {
8059
            WOLFSSL_MSG("Load crl failed");
8060
        }
8061
        else {
8062
            ret = wolfSSL_X509_STORE_add_crl(ctx->store, crl);
8063
            if (ret == WOLFSSL_FAILURE) {
8064
                WOLFSSL_MSG("Adding crl failed");
8065
            }
8066
            else {
8067
                ret = 1;/* handled a file */
8068
            }
8069
        }
8070
    }
8071
    else {
8072
        WOLFSSL_MSG("Invalid file type");
8073
    }
8074
8075
    wolfSSL_X509_CRL_free(crl);
8076
    XFCLOSE(fp);
8077
8078
    WOLFSSL_LEAVE("wolfSSL_X509_load_crl_file", ret);
8079
    return ret;
8080
#endif /* !NO_BIO */
8081
}
8082
#endif /* !NO_FILESYSTEM */
8083
8084
8085
WOLFSSL_X509_CRL* wolfSSL_d2i_X509_CRL(WOLFSSL_X509_CRL** crl,
8086
        const unsigned char* in, int len)
8087
{
8088
    WOLFSSL_X509_CRL *newcrl = NULL;
8089
    int ret = WOLFSSL_SUCCESS;
8090
8091
    WOLFSSL_ENTER("wolfSSL_d2i_X509_CRL");
8092
8093
    if (in == NULL) {
8094
        WOLFSSL_MSG("Bad argument value");
8095
    } else {
8096
        newcrl =(WOLFSSL_X509_CRL*)XMALLOC(sizeof(WOLFSSL_X509_CRL), NULL,
8097
                DYNAMIC_TYPE_CRL);
8098
        if (newcrl == NULL){
8099
            WOLFSSL_MSG("New CRL allocation failed");
8100
        } else {
8101
            ret = InitCRL(newcrl, NULL);
8102
            if (ret < 0) {
8103
                WOLFSSL_MSG("Init tmp CRL failed");
8104
            } else {
8105
                ret = BufferLoadCRL(newcrl, in, len, WOLFSSL_FILETYPE_ASN1,
8106
                    NO_VERIFY);
8107
                if (ret != WOLFSSL_SUCCESS) {
8108
                    WOLFSSL_MSG("Buffer Load CRL failed");
8109
                } else {
8110
                    if (crl) {
8111
                        *crl = newcrl;
8112
                    }
8113
                }
8114
            }
8115
        }
8116
    }
8117
8118
    if((ret != WOLFSSL_SUCCESS) && (newcrl != NULL)) {
8119
        wolfSSL_X509_CRL_free(newcrl);
8120
        newcrl = NULL;
8121
    }
8122
8123
    return newcrl;
8124
}
8125
8126
/* Retrieve issuer X509_NAME from CRL
8127
 * return X509_NAME*  on success
8128
 * return NULL on failure
8129
 */
8130
WOLFSSL_X509_NAME* wolfSSL_X509_CRL_get_issuer_name(WOLFSSL_X509_CRL* crl)
8131
{
8132
    if (crl == NULL || crl->crlList == NULL)
8133
        return NULL;
8134
8135
    return crl->crlList->issuer;
8136
}
8137
8138
/* Retrieve version from CRL
8139
 * return version on success
8140
 * return 0 on failure
8141
 */
8142
int wolfSSL_X509_CRL_version(WOLFSSL_X509_CRL* crl)
8143
{
8144
    if (crl == NULL || crl->crlList == NULL)
8145
        return 0;
8146
8147
    return crl->crlList->version;
8148
}
8149
8150
/* Retrieve sig OID from CRL
8151
 * return OID on success
8152
 * return 0 on failure
8153
 */
8154
int wolfSSL_X509_CRL_get_signature_type(WOLFSSL_X509_CRL* crl)
8155
{
8156
    if (crl == NULL || crl->crlList == NULL)
8157
        return 0;
8158
8159
    return crl->crlList->signatureOID;
8160
}
8161
8162
/* Retrieve sig NID from CRL
8163
 * return NID on success
8164
 * return 0 on failure
8165
 */
8166
int wolfSSL_X509_CRL_get_signature_nid(const WOLFSSL_X509_CRL* crl)
8167
{
8168
    if (crl == NULL || crl->crlList == NULL)
8169
        return 0;
8170
8171
    return oid2nid(crl->crlList->signatureOID, oidSigType);
8172
}
8173
8174
/* Retrieve signature from CRL
8175
 * return WOLFSSL_SUCCESS on success and negative values on failure
8176
 */
8177
int wolfSSL_X509_CRL_get_signature(WOLFSSL_X509_CRL* crl,
8178
    unsigned char* buf, int* bufSz)
8179
{
8180
    WOLFSSL_ENTER("wolfSSL_X509_CRL_get_signature");
8181
8182
    if (crl == NULL || crl->crlList == NULL || bufSz == NULL)
8183
        return BAD_FUNC_ARG;
8184
8185
    if (buf != NULL)
8186
        XMEMCPY(buf, crl->crlList->signature, *bufSz);
8187
    *bufSz = (int)crl->crlList->signatureSz;
8188
8189
    return WOLFSSL_SUCCESS;
8190
}
8191
8192
/* Retrieve serial number from RevokedCert
8193
 * return WOLFSSL_SUCCESS on success and negative values on failure
8194
 */
8195
int wolfSSL_X509_REVOKED_get_serial_number(RevokedCert* rev,
8196
    byte* in, int* inOutSz)
8197
{
8198
    WOLFSSL_ENTER("wolfSSL_X509_REVOKED_get_serial_number");
8199
    if (rev == NULL || inOutSz == NULL) {
8200
        return BAD_FUNC_ARG;
8201
    }
8202
8203
    if (in != NULL) {
8204
        if (*inOutSz < rev->serialSz) {
8205
            WOLFSSL_MSG("Serial buffer too small");
8206
            return BUFFER_E;
8207
        }
8208
        XMEMCPY(in, rev->serialNumber, rev->serialSz);
8209
    }
8210
    *inOutSz = rev->serialSz;
8211
8212
    return WOLFSSL_SUCCESS;
8213
}
8214
8215
const WOLFSSL_ASN1_INTEGER* wolfSSL_X509_REVOKED_get0_serial_number(const
8216
                                                      WOLFSSL_X509_REVOKED *rev)
8217
{
8218
    WOLFSSL_ENTER("wolfSSL_X509_REVOKED_get0_serial_number");
8219
8220
    if (rev != NULL) {
8221
        return rev->serialNumber;
8222
    }
8223
    else
8224
        return NULL;
8225
}
8226
8227
#ifndef NO_WOLFSSL_STUB
8228
const WOLFSSL_ASN1_TIME* wolfSSL_X509_REVOKED_get0_revocation_date(const
8229
                                                      WOLFSSL_X509_REVOKED *rev)
8230
{
8231
    WOLFSSL_STUB("wolfSSL_X509_REVOKED_get0_revocation_date");
8232
8233
    (void) rev;
8234
    return NULL;
8235
}
8236
#endif
8237
8238
8239
#ifndef NO_BIO
8240
/* print serial number out
8241
*  return WOLFSSL_SUCCESS on success
8242
*/
8243
static int X509RevokedPrintSerial(WOLFSSL_BIO* bio, RevokedCert* rev,
8244
    int indent)
8245
{
8246
    unsigned char serial[32];
8247
    int  sz = sizeof(serial);
8248
8249
    XMEMSET(serial, 0, sz);
8250
    if (wolfSSL_X509_REVOKED_get_serial_number(rev, serial, &sz)
8251
            == WOLFSSL_SUCCESS) {
8252
        X509PrintSerial_ex(bio, serial, sz, 0, indent);
8253
    }
8254
    return WOLFSSL_SUCCESS;
8255
}
8256
8257
8258
/* print out the signature in human readable format for use with
8259
* wolfSSL_X509_CRL_print()
8260
 * return WOLFSSL_SUCCESS on success
8261
 */
8262
static int X509CRLPrintSignature(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl,
8263
        int algOnly, int indent)
8264
{
8265
    int sigSz = 0;
8266
8267
    if (wolfSSL_X509_CRL_get_signature(crl, NULL, &sigSz) <= 0) {
8268
        return WOLFSSL_FAILURE;
8269
    }
8270
8271
    if (sigSz > 0) {
8272
        unsigned char* sig;
8273
        int sigNid = wolfSSL_X509_CRL_get_signature_nid(crl);
8274
8275
        sig = (unsigned char*)XMALLOC(sigSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8276
        if (sig == NULL) {
8277
            return WOLFSSL_FAILURE;
8278
        }
8279
8280
        if (wolfSSL_X509_CRL_get_signature(crl, sig, &sigSz) <= 0) {
8281
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8282
            return WOLFSSL_FAILURE;
8283
        }
8284
8285
        if (X509PrintSignature_ex(bio, sig, sigSz, sigNid, algOnly, indent)
8286
                != WOLFSSL_SUCCESS) {
8287
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8288
            return WOLFSSL_FAILURE;
8289
        }
8290
8291
        if (sig != NULL) {
8292
            XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8293
        }
8294
8295
    }
8296
8297
    return WOLFSSL_SUCCESS;
8298
}
8299
#endif /* !NO_BIO */
8300
8301
#if !defined(NO_BIO) && defined(XSNPRINTF)
8302
/* print out the extensions in human readable format for use with
8303
 * wolfSSL_X509_CRL_print()
8304
 * return WOLFSSL_SUCCESS on success
8305
 */
8306
static int X509CRLPrintExtensions(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl,
8307
        int indent)
8308
{
8309
    char tmp[MAX_WIDTH]; /* buffer for XSNPRINTF */
8310
8311
    if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s\n", indent, "",
8312
                "CRL extensions:") >= MAX_WIDTH) {
8313
        return WOLFSSL_FAILURE;
8314
    }
8315
8316
    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
8317
            return WOLFSSL_FAILURE;
8318
    }
8319
8320
    if (crl->crlList->crlNumber) {
8321
        if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s\n", indent + 4, "",
8322
                    "X509v3 CRL Number:") >= MAX_WIDTH) {
8323
            return WOLFSSL_FAILURE;
8324
        }
8325
8326
        if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
8327
            return WOLFSSL_FAILURE;
8328
        }
8329
8330
        if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%d\n", indent + 8, "",
8331
            crl->crlList->crlNumber) >= MAX_WIDTH)
8332
        {
8333
            return WOLFSSL_FAILURE;
8334
        }
8335
        if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
8336
            return WOLFSSL_FAILURE;
8337
        }
8338
        XMEMSET(tmp, 0, sizeof(tmp));
8339
    }
8340
8341
#if !defined(NO_SKID)
8342
    if (crl->crlList->extAuthKeyIdSet && crl->crlList->extAuthKeyId[0] != 0) {
8343
        word32 i;
8344
        char val[5];
8345
        int valSz = 5;
8346
8347
        if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s", indent + 4, "",
8348
                    "X509v3 Authority Key Identifier:") >= MAX_WIDTH) {
8349
            return WOLFSSL_FAILURE;
8350
        }
8351
8352
        XSTRNCAT(tmp, "\n", MAX_WIDTH - XSTRLEN(tmp) - 1);
8353
8354
        if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
8355
            return WOLFSSL_FAILURE;
8356
        }
8357
        XMEMSET(tmp, 0, MAX_WIDTH);
8358
8359
        if (XSNPRINTF(tmp, MAX_WIDTH - 1, "%*s%s",
8360
                    indent + 8, "", "keyid") >= MAX_WIDTH) {
8361
            return WOLFSSL_FAILURE;
8362
        }
8363
8364
8365
        for (i = 0; i < XSTRLEN((char*)crl->crlList->extAuthKeyId); i++) {
8366
            /* check if buffer is almost full */
8367
            if (XSTRLEN(tmp) >= sizeof(tmp) - valSz) {
8368
                if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
8369
                    return WOLFSSL_FAILURE;
8370
                }
8371
                tmp[0] = '\0';
8372
            }
8373
            if (XSNPRINTF(val, valSz, ":%02X", crl->crlList->extAuthKeyId[i])
8374
                >= valSz)
8375
            {
8376
                WOLFSSL_MSG("buffer overrun");
8377
                return WOLFSSL_FAILURE;
8378
            }
8379
            XSTRNCAT(tmp, val, valSz);
8380
        }
8381
        XSTRNCAT(tmp, "\n", XSTRLEN("\n") + 1);
8382
        if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
8383
            return WOLFSSL_FAILURE;
8384
        }
8385
    }
8386
#endif
8387
8388
    return WOLFSSL_SUCCESS;
8389
}
8390
8391
/* iterate through a CRL's Revoked Certs and print out in human
8392
 * readable format for use with wolfSSL_X509_CRL_print()
8393
 * return WOLFSSL_SUCCESS on success
8394
 */
8395
static int X509CRLPrintRevoked(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl,
8396
        int indent)
8397
{
8398
    char tmp[MAX_WIDTH]; /* buffer for XSNPRINTF */
8399
    int i;
8400
8401
    if (crl->crlList->totalCerts > 0) {
8402
        RevokedCert* revoked = crl->crlList->certs;
8403
8404
        if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s\n", indent, "",
8405
                    "Revoked Certificates:") >= MAX_WIDTH) {
8406
            return WOLFSSL_FAILURE;
8407
        }
8408
8409
        if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
8410
            return WOLFSSL_FAILURE;
8411
        }
8412
        XMEMSET(tmp, 0, MAX_WIDTH);
8413
8414
        for (i = 0; i < crl->crlList->totalCerts; i++) {
8415
            if (revoked->serialSz > 0) {
8416
                if (X509RevokedPrintSerial(bio, revoked, indent + 4)
8417
                        != WOLFSSL_SUCCESS) {
8418
                    return WOLFSSL_FAILURE;
8419
                }
8420
            }
8421
        #ifndef NO_ASN_TIME
8422
             if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s", indent + 8, "",
8423
                         "Revocation Date: ") >= MAX_WIDTH) {
8424
                return WOLFSSL_FAILURE;
8425
            }
8426
8427
            if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
8428
                return WOLFSSL_FAILURE;
8429
            }
8430
8431
            if (revoked->revDate[0] != 0) {
8432
                if (GetTimeString(revoked->revDate, ASN_UTC_TIME,
8433
                    tmp, MAX_WIDTH) != WOLFSSL_SUCCESS) {
8434
                    if (GetTimeString(revoked->revDate, ASN_GENERALIZED_TIME,
8435
                    tmp, MAX_WIDTH) != WOLFSSL_SUCCESS) {
8436
                        WOLFSSL_MSG("Error getting revocation date");
8437
                        return WOLFSSL_FAILURE;
8438
                    }
8439
                }
8440
            }
8441
            else {
8442
                XSTRNCPY(tmp, "Not Set", MAX_WIDTH-1);
8443
            }
8444
            tmp[MAX_WIDTH - 1] = '\0'; /* make sure null terminated */
8445
            if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
8446
                return WOLFSSL_FAILURE;
8447
            }
8448
8449
            if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) {
8450
                return WOLFSSL_FAILURE;
8451
            }
8452
        #endif
8453
            revoked = revoked->next;
8454
        }
8455
    }
8456
    else {
8457
        if (wolfSSL_BIO_write(bio, "No Revoked Certificates.\n",
8458
                       (int)XSTRLEN("No Revoked Certificates.\n")) <= 0) {
8459
            return WOLFSSL_FAILURE;
8460
        }
8461
    }
8462
8463
    return WOLFSSL_SUCCESS;
8464
}
8465
8466
#ifndef NO_ASN_TIME
8467
/* print out the last/next update times in human readable
8468
 * format for use with wolfSSL_X509_CRL_print()
8469
 * return WOLFSSL_SUCCESS on success
8470
 */
8471
static int X509CRLPrintDates(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl,
8472
        int indent)
8473
{
8474
    char tmp[MAX_WIDTH]; /* buffer for XSNPRINTF */
8475
8476
    if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s", indent, "",
8477
                "Last Update: ") >= MAX_WIDTH) {
8478
        return WOLFSSL_FAILURE;
8479
    }
8480
8481
    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
8482
        return WOLFSSL_FAILURE;
8483
    }
8484
8485
    if (crl->crlList->lastDate[0] != 0) {
8486
        if (GetTimeString(crl->crlList->lastDate, ASN_UTC_TIME,
8487
            tmp, MAX_WIDTH) != WOLFSSL_SUCCESS) {
8488
            if (GetTimeString(crl->crlList->lastDate, ASN_GENERALIZED_TIME,
8489
            tmp, MAX_WIDTH) != WOLFSSL_SUCCESS) {
8490
                WOLFSSL_MSG("Error getting last update date");
8491
                return WOLFSSL_FAILURE;
8492
            }
8493
        }
8494
    }
8495
    else {
8496
        XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
8497
    }
8498
    tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
8499
    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
8500
        return WOLFSSL_FAILURE;
8501
    }
8502
8503
    if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) {
8504
        return WOLFSSL_FAILURE;
8505
    }
8506
8507
    if (XSNPRINTF(tmp, MAX_WIDTH, "%*s%s", indent, "",
8508
                "Next Update: ") >= MAX_WIDTH) {
8509
        return WOLFSSL_FAILURE;
8510
    }
8511
8512
    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
8513
        return WOLFSSL_FAILURE;
8514
    }
8515
8516
    if (crl->crlList->nextDate[0] != 0) {
8517
        if (GetTimeString(crl->crlList->nextDate, ASN_UTC_TIME,
8518
            tmp, MAX_WIDTH) != WOLFSSL_SUCCESS) {
8519
            if (GetTimeString(crl->crlList->nextDate, ASN_GENERALIZED_TIME,
8520
            tmp, MAX_WIDTH) != WOLFSSL_SUCCESS) {
8521
                WOLFSSL_MSG("Error getting next update date");
8522
                return WOLFSSL_FAILURE;
8523
            }
8524
        }
8525
    }
8526
    else {
8527
        XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
8528
    }
8529
    tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
8530
    if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
8531
        return WOLFSSL_FAILURE;
8532
    }
8533
8534
    if (wolfSSL_BIO_write(bio, "\n", (int)XSTRLEN("\n")) <= 0) {
8535
        return WOLFSSL_FAILURE;
8536
    }
8537
8538
    return WOLFSSL_SUCCESS;
8539
}
8540
#endif
8541
8542
/* Writes the human readable form of x509 to bio.
8543
 *
8544
 * bio  WOLFSSL_BIO to write to.
8545
 * crl Certificate revocation list to write.
8546
 *
8547
 * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
8548
 */
8549
int wolfSSL_X509_CRL_print(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl)
8550
{
8551
    char issuType[] = "Issuer: ";
8552
8553
    if (bio == NULL || crl == NULL || crl->crlList == NULL) {
8554
        return WOLFSSL_FAILURE;
8555
    }
8556
8557
    if (wolfSSL_BIO_write(bio, "Certificate Revocation List (CRL):\n",
8558
                  (int)XSTRLEN("Certificate Revocation List (CRL):\n")) <= 0) {
8559
            return WOLFSSL_FAILURE;
8560
    }
8561
8562
    /* print version */
8563
    if (X509PrintVersion(bio, wolfSSL_X509_CRL_version(crl), 8)
8564
            != WOLFSSL_SUCCESS) {
8565
        return WOLFSSL_FAILURE;
8566
    }
8567
8568
    /* print signature algo */
8569
    if (X509CRLPrintSignature(bio, crl, 1, 8) != WOLFSSL_SUCCESS) {
8570
        return WOLFSSL_FAILURE;
8571
    }
8572
8573
    /* print issuer name */
8574
    if (X509PrintName(bio, wolfSSL_X509_CRL_get_issuer_name(crl), issuType, 8)
8575
            != WOLFSSL_SUCCESS) {
8576
        return WOLFSSL_FAILURE;
8577
    }
8578
8579
#ifndef NO_ASN_TIME
8580
    /* print last and next update times */
8581
    if (X509CRLPrintDates(bio, crl, 8) != WOLFSSL_SUCCESS) {
8582
        return WOLFSSL_FAILURE;
8583
    }
8584
#endif
8585
8586
    /* print CRL extensions */
8587
    if (X509CRLPrintExtensions(bio, crl, 8) != WOLFSSL_SUCCESS) {
8588
        return WOLFSSL_FAILURE;
8589
    }
8590
8591
    /* print CRL Revoked Certs */
8592
    if (X509CRLPrintRevoked(bio, crl, 0) != WOLFSSL_SUCCESS) {
8593
        return WOLFSSL_FAILURE;
8594
    }
8595
8596
    if (X509CRLPrintSignature(bio, crl, 0, 4) != WOLFSSL_SUCCESS) {
8597
        return WOLFSSL_FAILURE;
8598
    }
8599
8600
    if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
8601
        return WOLFSSL_FAILURE;
8602
    }
8603
8604
    return WOLFSSL_SUCCESS;
8605
}
8606
#endif /* !NO_BIO && XSNPRINTF */
8607
#endif /* HAVE_CRL */
8608
#endif /* OPENSSL_EXTRA */
8609
8610
#if defined(HAVE_CRL) && (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL))
8611
void wolfSSL_X509_CRL_free(WOLFSSL_X509_CRL *crl)
8612
{
8613
    WOLFSSL_ENTER("wolfSSL_X509_CRL_free");
8614
8615
    if (crl)
8616
        FreeCRL(crl, 1);
8617
}
8618
#endif /* HAVE_CRL && (OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL) */
8619
8620
#ifdef OPENSSL_EXTRA
8621
WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_lastUpdate(WOLFSSL_X509_CRL* crl)
8622
{
8623
    if ((crl != NULL) && (crl->crlList != NULL) &&
8624
        (crl->crlList->lastDateAsn1.data[0] != 0)) {
8625
        return &crl->crlList->lastDateAsn1;
8626
    }
8627
    else
8628
        return NULL;
8629
}
8630
8631
WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_nextUpdate(WOLFSSL_X509_CRL* crl)
8632
{
8633
    if ((crl != NULL) && (crl->crlList != NULL) &&
8634
        (crl->crlList->nextDateAsn1.data[0] != 0)) {
8635
        return &crl->crlList->nextDateAsn1;
8636
    }
8637
    else
8638
        return NULL;
8639
}
8640
8641
#ifndef NO_WOLFSSL_STUB
8642
int wolfSSL_X509_CRL_verify(WOLFSSL_X509_CRL* crl, WOLFSSL_EVP_PKEY* key)
8643
{
8644
    (void)crl;
8645
    (void)key;
8646
    WOLFSSL_STUB("X509_CRL_verify");
8647
    return 0;
8648
}
8649
#endif
8650
#endif /* OPENSSL_EXTRA */
8651
8652
#ifdef OPENSSL_EXTRA
8653
8654
8655
WOLFSSL_X509_VERIFY_PARAM* wolfSSL_X509_VERIFY_PARAM_new(void)
8656
{
8657
    WOLFSSL_X509_VERIFY_PARAM *param = NULL;
8658
    param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC(
8659
            sizeof(WOLFSSL_X509_VERIFY_PARAM), NULL, DYNAMIC_TYPE_OPENSSL);
8660
    if (param != NULL)
8661
        XMEMSET(param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM ));
8662
8663
    return(param);
8664
}
8665
8666
8667
void wolfSSL_X509_VERIFY_PARAM_free(WOLFSSL_X509_VERIFY_PARAM *param)
8668
{
8669
    if (param != NULL)
8670
        XFREE(param, NULL, DYNAMIC_TYPE_OPENSSL);
8671
}
8672
8673
8674
/* Sets flags by OR'ing with existing value. */
8675
int wolfSSL_X509_VERIFY_PARAM_set_flags(WOLFSSL_X509_VERIFY_PARAM *param,
8676
        unsigned long flags)
8677
{
8678
    int ret = WOLFSSL_FAILURE;
8679
8680
    if (param != NULL) {
8681
        param->flags |= flags;
8682
        ret = WOLFSSL_SUCCESS;
8683
    }
8684
8685
    return ret;
8686
}
8687
8688
8689
int wolfSSL_X509_VERIFY_PARAM_get_flags(WOLFSSL_X509_VERIFY_PARAM *param)
8690
{
8691
    int ret = 0;
8692
8693
    if (param != NULL) {
8694
        ret = (int)param->flags;
8695
    }
8696
8697
    return ret;
8698
}
8699
8700
8701
int wolfSSL_X509_VERIFY_PARAM_clear_flags(WOLFSSL_X509_VERIFY_PARAM *param,
8702
        unsigned long flags)
8703
{
8704
    int ret = WOLFSSL_FAILURE;
8705
8706
    if (param != NULL) {
8707
        param->flags &= ~flags;
8708
        ret = WOLFSSL_SUCCESS;
8709
    }
8710
8711
    return ret;
8712
}
8713
8714
8715
/* inherits properties of param "to" to param "from"
8716
*
8717
* WOLFSSL_VPARAM_DEFAULT          any values in "src" is copied
8718
*                                 if "src" value is new for "to".
8719
* WOLFSSL_VPARAM_OVERWRITE        all values of "form" are copied to "to"
8720
* WOLFSSL_VPARAM_RESET_FLAGS      the flag values are copied, not Ored
8721
* WOLFSSL_VPARAM_LOCKED           don't copy any values
8722
* WOLFSSL_VPARAM_ONCE             the current inherit_flags is zerroed
8723
*/
8724
static int wolfSSL_X509_VERIFY_PARAM_inherit(WOLFSSL_X509_VERIFY_PARAM *to,
8725
                                         const WOLFSSL_X509_VERIFY_PARAM *from)
8726
{
8727
    int ret = WOLFSSL_FAILURE;
8728
    int isOverWrite = 0;
8729
    int isDefault = 0;
8730
    unsigned int flags;
8731
8732
    /* sanity check */
8733
    if (!to || !from) {
8734
        /* be compatible to openssl return value */
8735
        return WOLFSSL_SUCCESS;
8736
    }
8737
    flags = to->inherit_flags | from->inherit_flags;
8738
8739
    if (flags & WOLFSSL_VPARAM_LOCKED) {
8740
        return WOLFSSL_SUCCESS;
8741
    }
8742
8743
    if (flags & WOLFSSL_VPARAM_ONCE) {
8744
        to->inherit_flags = 0;
8745
    }
8746
8747
    isOverWrite = (flags & WOLFSSL_VPARAM_OVERWRITE);
8748
    isDefault = (flags & WOLFSSL_VPARAM_DEFAULT);
8749
8750
    /* copy check_time if check time is not set */
8751
    if ((to->flags & WOLFSSL_USE_CHECK_TIME) == 0 || isOverWrite) {
8752
           to->check_time = from->check_time;
8753
           to->flags &= ~WOLFSSL_USE_CHECK_TIME;
8754
    }
8755
    /* host name */
8756
    if (isOverWrite ||
8757
        (from->hostName[0] != 0 && (to->hostName[0] == 0 || isDefault))) {
8758
            if (!(ret = wolfSSL_X509_VERIFY_PARAM_set1_host(to, from->hostName,
8759
                (int)XSTRLEN(from->hostName))))
8760
                return ret;
8761
        to->hostFlags = from->hostFlags;
8762
    }
8763
    /* ip ascii */
8764
    if (isOverWrite ||
8765
        (from->ipasc[0] != 0 && (to->ipasc[0] == 0 || isDefault))) {
8766
8767
            if (!(ret = wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(to, from->ipasc)))
8768
                return ret;
8769
    }
8770
8771
    if (flags & WOLFSSL_VPARAM_RESET_FLAGS)
8772
        to->flags = 0;
8773
8774
    to->flags |= from->flags;
8775
8776
    return ret;
8777
}
8778
8779
/******************************************************************************
8780
* wolfSSL_X509_VERIFY_PARAM_set1_host - sets the DNS hostname to name
8781
* hostnames is cleared if name is NULL or empty.
8782
*
8783
* RETURNS:
8784
*
8785
*/
8786
int wolfSSL_X509_VERIFY_PARAM_set1_host(WOLFSSL_X509_VERIFY_PARAM* pParam,
8787
                                         const char* name,
8788
                                         unsigned int nameSz)
8789
{
8790
    WOLFSSL_ENTER("wolfSSL_X509_VERIFY_PARAM_set1_host");
8791
8792
    if (pParam == NULL)
8793
        return WOLFSSL_FAILURE;
8794
8795
    /* If name is NULL, clear hostname. */
8796
    if (name == NULL) {
8797
        XMEMSET(pParam->hostName, 0, WOLFSSL_HOST_NAME_MAX);
8798
        return WOLFSSL_SUCCESS;
8799
    }
8800
8801
    /* If name is NULL-terminated, namelen can be set to zero. */
8802
    if (nameSz == 0) {
8803
        nameSz = (unsigned int)XSTRLEN(name);
8804
    }
8805
8806
    if (nameSz > 0 && name[nameSz - 1] == '\0')
8807
        nameSz--;
8808
8809
    if (nameSz > WOLFSSL_HOST_NAME_MAX-1) {
8810
        WOLFSSL_MSG("Truncating name");
8811
        nameSz = WOLFSSL_HOST_NAME_MAX-1;
8812
    }
8813
8814
    if (nameSz > 0) {
8815
        XMEMCPY(pParam->hostName, name, nameSz);
8816
        XMEMSET(pParam->hostName + nameSz, 0,
8817
                WOLFSSL_HOST_NAME_MAX - nameSz);
8818
    }
8819
8820
    pParam->hostName[nameSz] = '\0';
8821
8822
    return WOLFSSL_SUCCESS;
8823
}
8824
8825
/* Set VERIFY PARAM from "from" pointer to "to" pointer */
8826
int wolfSSL_X509_VERIFY_PARAM_set1(WOLFSSL_X509_VERIFY_PARAM *to,
8827
                                   const WOLFSSL_X509_VERIFY_PARAM *from)
8828
{
8829
    int ret = WOLFSSL_FAILURE;
8830
    unsigned int _inherit_flags;
8831
8832
    if (!to) {
8833
        return ret;
8834
    }
8835
    /* keeps the inherit flags for save */
8836
    _inherit_flags = to->inherit_flags;
8837
8838
    /* Ored DEFAULT inherit flag property to copy "from" contents to "to"
8839
    *  contents
8840
    */
8841
    to->inherit_flags |= WOLFSSL_VPARAM_DEFAULT;
8842
8843
    ret = wolfSSL_X509_VERIFY_PARAM_inherit(to, from);
8844
8845
    /* restore inherit flag */
8846
    to->inherit_flags = _inherit_flags;
8847
8848
    return ret;
8849
}
8850
8851
/* Set the host flag in the X509_VERIFY_PARAM structure */
8852
void wolfSSL_X509_VERIFY_PARAM_set_hostflags(WOLFSSL_X509_VERIFY_PARAM* param,
8853
                                             unsigned int flags)
8854
{
8855
    if (param != NULL) {
8856
        param->hostFlags = flags;
8857
    }
8858
}
8859
8860
/* Sets the expected IP address to ipasc.
8861
 *
8862
 * param is a pointer to the X509_VERIFY_PARAM structure
8863
 * ipasc is a NULL-terminated string with N.N.N.N for IPv4 and
8864
 *       HH:HH ... HH:HH for IPv6. There is no validation performed on the
8865
 *       parameter, and it must be an exact match with the IP in the cert.
8866
 *
8867
 * return 1 for success and 0 for failure*/
8868
int wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(WOLFSSL_X509_VERIFY_PARAM *param,
8869
        const char *ipasc)
8870
{
8871
    int ret = WOLFSSL_FAILURE;
8872
8873
    if (param != NULL) {
8874
        if (ipasc == NULL) {
8875
            param->ipasc[0] = '\0';
8876
        }
8877
        else {
8878
            XSTRLCPY(param->ipasc, ipasc, WOLFSSL_MAX_IPSTR);
8879
            param->ipasc[WOLFSSL_MAX_IPSTR-1] = '\0';
8880
        }
8881
        ret = WOLFSSL_SUCCESS;
8882
    }
8883
8884
    return ret;
8885
}
8886
/* Sets the expected IP address to ip(asc)
8887
 *          by re-constructing IP address in ascii
8888
 * @param  param is a pointer to the X509_VERIFY_PARAM structure
8889
 * @param  ip    in binary format of ip address
8890
 * @param  iplen size of ip, 4 for ipv4, 16 for ipv6
8891
 * @return 1 for success and 0 for failure
8892
 */
8893
int wolfSSL_X509_VERIFY_PARAM_set1_ip(WOLFSSL_X509_VERIFY_PARAM* param,
8894
    const unsigned char* ip, size_t iplen)
8895
{
8896
    int ret = WOLFSSL_FAILURE;
8897
#ifndef NO_FILESYSTEM
8898
    char* buf = NULL;
8899
    char* p = NULL;
8900
    word32 val = 0;
8901
    int i;
8902
    const size_t max_ipv6_len = 40;
8903
    byte write_zero = 0;
8904
#endif
8905
8906
    /* sanity check */
8907
    if (param == NULL || (iplen != 0 && iplen != 4 && iplen != 16)) {
8908
        WOLFSSL_MSG("bad function arg");
8909
        return ret;
8910
    }
8911
#ifndef NO_FILESYSTEM
8912
    if (iplen == 4) {
8913
        /* ipv4 www.xxx.yyy.zzz max 15 length + Null termination */
8914
        buf = (char*)XMALLOC(16, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8915
8916
        if (!buf) {
8917
            WOLFSSL_MSG("failed malloc");
8918
            return ret;
8919
        }
8920
8921
        XSPRINTF(buf, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
8922
        buf[15] = '\0';
8923
    }
8924
    else if (iplen == 16) {
8925
        /* ipv6 normal address scheme
8926
        *   y1:y2:y3:y4:y5:y6:y7:y8, len(yx):4, len(y1-y8):32. len(":"):7
8927
        *   Max len is 32 + 7 + 1(Termination) = 40 bytes
8928
        *
8929
        *   ipv6 dual address
8930
        *   Or y1:y2:y3:y4:y:y6:x.x.x.x yx is 4, y1-y6 is 24, ":" is 6
8931
        *   x.x.x.x is 15.
8932
        *   Max len is 24 + 6 + 15 + 1(Termination) = 46 bytes
8933
        *
8934
        *   Expect data in ip[16]
8935
        *   e.g (aaaa):(bbbb):(cccc):....(hhhh)
8936
        *   (aaaa) = (ip[0<<8)|ip[1]
8937
        *   ......
8938
        *   (hhhh) = (ip[14]<<8)|(ip[15])
8939
        *
8940
        *   e.g ::(gggg):(hhhh)
8941
        *   ip[0]-[11] = 0
8942
        *   (gggg) = (ip[12]<<8) |(ip[13])
8943
        *   (hhhh) = (ip[14]<<8) |(ip[15])
8944
        *
8945
        *   Because it is not able to know which ivp6 scheme uses from data to
8946
        *   reconstruct IP address, this function assumes
8947
        *   ivp6 normal address scheme, not dual address scheme,
8948
        *   to re-construct IP address in ascii.
8949
        */
8950
        buf = (char*)XMALLOC(max_ipv6_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8951
8952
        if (!buf) {
8953
            WOLFSSL_MSG("failed malloc");
8954
            return ret;
8955
        }
8956
        p = buf;
8957
        for (i = 0; i < 16; i += 2) {
8958
           val = (((word32)(ip[i]<<8)) | (ip[i+1])) & 0xFFFF;
8959
           if (val == 0){
8960
               if (!write_zero) {
8961
                    *p = ':';
8962
               }
8963
               p++;
8964
               *p = '\0';
8965
               write_zero = 1;
8966
           }
8967
           else {
8968
               if (i != 0)
8969
                *p++ = ':';
8970
               XSPRINTF(p, "%x", val);
8971
           }
8972
           /* sanity check */
8973
           if (XSTRLEN(buf) > max_ipv6_len) {
8974
               WOLFSSL_MSG("The target ip address exceeds buffer length(40)");
8975
               XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8976
               buf = NULL;
8977
               break;
8978
           }
8979
           /* move the pointer to the last */
8980
           /* XSTRLEN includes NULL because of XSPRINTF use */
8981
           p = buf + (XSTRLEN(buf));
8982
        }
8983
        /* termination */
8984
        if(i == 16 && buf) {
8985
            p--;
8986
            if ((*p) == ':') {
8987
            /* when the last character is :, the following segments are zero
8988
             * Therefore, adding : and null termination
8989
             */
8990
                 p++;
8991
                 *p++ = ':';
8992
                *p = '\0';
8993
            }
8994
        }
8995
    }
8996
    else {
8997
        WOLFSSL_MSG("iplen is zero, do nothing");
8998
        return WOLFSSL_SUCCESS;
8999
    }
9000
9001
    if (buf) {
9002
         /* set address to ip asc */
9003
        ret = wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(param, buf);
9004
        XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
9005
    }
9006
#else
9007
    (void)param;
9008
    (void)ip;
9009
    (void)iplen;
9010
#endif
9011
9012
    return ret;
9013
}
9014
9015
#ifndef NO_WOLFSSL_STUB
9016
void wolfSSL_X509_OBJECT_free_contents(WOLFSSL_X509_OBJECT* obj)
9017
{
9018
    (void)obj;
9019
    WOLFSSL_STUB("X509_OBJECT_free_contents");
9020
}
9021
#endif
9022
9023
#ifndef NO_ASN_TIME
9024
int wolfSSL_X509_cmp_current_time(const WOLFSSL_ASN1_TIME* asnTime)
9025
{
9026
    return wolfSSL_X509_cmp_time(asnTime, NULL);
9027
}
9028
9029
/* return -1 if asnTime is earlier than or equal to cmpTime, and 1 otherwise
9030
 * return 0 on error
9031
 */
9032
int wolfSSL_X509_cmp_time(const WOLFSSL_ASN1_TIME* asnTime, time_t* cmpTime)
9033
{
9034
    int ret = WOLFSSL_FAILURE;
9035
    time_t tmpTime, *pTime = &tmpTime;
9036
    struct tm ts, *tmpTs, *ct;
9037
#if defined(NEED_TMP_TIME)
9038
    /* for use with gmtime_r */
9039
    struct tm tmpTimeStorage;
9040
9041
    tmpTs = &tmpTimeStorage;
9042
#else
9043
    tmpTs = NULL;
9044
#endif
9045
    (void)tmpTs;
9046
9047
    if (asnTime == NULL) {
9048
        return WOLFSSL_FAILURE;
9049
    }
9050
9051
    if (cmpTime == NULL) {
9052
        /* Use current time */
9053
        *pTime = wc_Time(0);
9054
    }
9055
    else {
9056
        pTime = cmpTime;
9057
    }
9058
9059
    if (wolfSSL_ASN1_TIME_to_tm((WOLFSSL_ASN1_TIME*)asnTime, &ts) !=
9060
                                                              WOLFSSL_SUCCESS) {
9061
        WOLFSSL_MSG("Failed to convert WOLFSSL_ASN1_TIME to struct tm.");
9062
        return WOLFSSL_FAILURE;
9063
    }
9064
9065
    /* Convert to time struct*/
9066
    ct = XGMTIME(pTime, tmpTs);
9067
9068
    if (ct == NULL)
9069
        return GETTIME_ERROR;
9070
9071
    /* DateGreaterThan returns 1 for >; 0 for <= */
9072
    ret = DateGreaterThan(&ts, ct) ? 1 : -1;
9073
9074
    return ret;
9075
}
9076
#endif /* !NO_ASN_TIME */
9077
9078
#if (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)) && \
9079
    !defined(NO_ASN_TIME) && !defined(USER_TIME) && !defined(TIME_OVERRIDES)
9080
WOLFSSL_ASN1_TIME *wolfSSL_X509_time_adj_ex(WOLFSSL_ASN1_TIME *asnTime,
9081
    int offset_day, long offset_sec, time_t *in_tm)
9082
{
9083
    /* get current time if in_tm is null */
9084
    time_t t = in_tm ? *in_tm : wc_Time(0);
9085
    return wolfSSL_ASN1_TIME_adj(asnTime, t, offset_day, offset_sec);
9086
}
9087
9088
WOLFSSL_ASN1_TIME *wolfSSL_X509_time_adj(WOLFSSL_ASN1_TIME *asnTime,
9089
    long offset_sec, time_t *in_tm)
9090
{
9091
    return wolfSSL_X509_time_adj_ex(asnTime, 0, offset_sec, in_tm);
9092
}
9093
9094
WOLFSSL_ASN1_TIME* wolfSSL_X509_gmtime_adj(WOLFSSL_ASN1_TIME *s, long adj)
9095
{
9096
    return wolfSSL_X509_time_adj(s, adj, NULL);
9097
}
9098
#endif
9099
9100
#ifndef NO_WOLFSSL_STUB
9101
int wolfSSL_sk_X509_REVOKED_num(WOLFSSL_X509_REVOKED* revoked)
9102
{
9103
    (void)revoked;
9104
    WOLFSSL_STUB("sk_X509_REVOKED_num");
9105
    return 0;
9106
}
9107
#endif
9108
9109
#ifndef NO_WOLFSSL_STUB
9110
WOLFSSL_X509_REVOKED* wolfSSL_X509_CRL_get_REVOKED(WOLFSSL_X509_CRL* crl)
9111
{
9112
    (void)crl;
9113
    WOLFSSL_STUB("X509_CRL_get_REVOKED");
9114
    return 0;
9115
}
9116
#endif
9117
9118
#ifndef NO_WOLFSSL_STUB
9119
WOLFSSL_X509_REVOKED* wolfSSL_sk_X509_REVOKED_value(
9120
                                    WOLFSSL_X509_REVOKED* revoked, int value)
9121
{
9122
    (void)revoked;
9123
    (void)value;
9124
    WOLFSSL_STUB("sk_X509_REVOKED_value");
9125
    return 0;
9126
}
9127
#endif
9128
9129
#endif /* OPENSSL_EXTRA */
9130
9131
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
9132
9133
WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509* x509)
9134
{
9135
    WOLFSSL_ASN1_INTEGER* a;
9136
    int i = 0;
9137
9138
    WOLFSSL_ENTER("wolfSSL_X509_get_serialNumber");
9139
9140
    if (x509 == NULL) {
9141
        WOLFSSL_MSG("NULL function argument");
9142
        return NULL;
9143
    }
9144
9145
    if (x509->serialNumber != NULL)
9146
       return x509->serialNumber;
9147
9148
    a = wolfSSL_ASN1_INTEGER_new();
9149
    if (a == NULL)
9150
        return NULL;
9151
9152
    /* Make sure there is space for the data, ASN.1 type and length. */
9153
    if (x509->serialSz > (WOLFSSL_ASN1_INTEGER_MAX - 2)) {
9154
        /* dynamically create data buffer, +2 for type and length */
9155
        a->data = (unsigned char*)XMALLOC(x509->serialSz + 2, NULL,
9156
                DYNAMIC_TYPE_OPENSSL);
9157
        if (a->data == NULL) {
9158
            wolfSSL_ASN1_INTEGER_free(a);
9159
            return NULL;
9160
        }
9161
        a->dataMax   = x509->serialSz + 2;
9162
        a->isDynamic = 1;
9163
    } else {
9164
        /* Use array instead of dynamic memory */
9165
        a->data    = a->intData;
9166
        a->dataMax = WOLFSSL_ASN1_INTEGER_MAX;
9167
    }
9168
9169
    #if defined(WOLFSSL_QT) || defined(WOLFSSL_HAPROXY)
9170
        XMEMCPY(&a->data[i], x509->serial, x509->serialSz);
9171
        a->length = x509->serialSz;
9172
    #else
9173
        a->data[i++] = ASN_INTEGER;
9174
        i += SetLength(x509->serialSz, a->data + i);
9175
        XMEMCPY(&a->data[i], x509->serial, x509->serialSz);
9176
        a->length = x509->serialSz + 2;
9177
    #endif
9178
9179
    x509->serialNumber = a;
9180
9181
    return a;
9182
}
9183
9184
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
9185
9186
#ifdef OPENSSL_EXTRA
9187
9188
#if defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD) \
9189
    || defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_WPAS)
9190
WOLFSSL_X509_ALGOR* wolfSSL_X509_ALGOR_new(void)
9191
{
9192
    WOLFSSL_X509_ALGOR* ret;
9193
    ret = (WOLFSSL_X509_ALGOR*)XMALLOC(sizeof(WOLFSSL_X509_ALGOR), NULL,
9194
                                       DYNAMIC_TYPE_OPENSSL);
9195
    if (ret) {
9196
        XMEMSET(ret, 0, sizeof(WOLFSSL_X509_ALGOR));
9197
    }
9198
    return ret;
9199
}
9200
9201
void wolfSSL_X509_ALGOR_free(WOLFSSL_X509_ALGOR *alg)
9202
{
9203
    if (alg) {
9204
        wolfSSL_ASN1_OBJECT_free(alg->algorithm);
9205
        wolfSSL_ASN1_TYPE_free(alg->parameter);
9206
        XFREE(alg, NULL, DYNAMIC_TYPE_OPENSSL);
9207
    }
9208
}
9209
9210
/* Returns X509_ALGOR struct with signature algorithm */
9211
const WOLFSSL_X509_ALGOR* wolfSSL_X509_get0_tbs_sigalg(const WOLFSSL_X509 *x509)
9212
{
9213
    WOLFSSL_ENTER("wolfSSL_X509_get0_tbs_sigalg");
9214
9215
    if (x509 == NULL) {
9216
        WOLFSSL_MSG("x509 struct NULL error");
9217
        return NULL;
9218
    }
9219
9220
    return &x509->algor;
9221
}
9222
9223
/* Sets paobj pointer to X509_ALGOR signature algorithm */
9224
void wolfSSL_X509_ALGOR_get0(const WOLFSSL_ASN1_OBJECT **paobj, int *pptype,
9225
                            const void **ppval, const WOLFSSL_X509_ALGOR *algor)
9226
{
9227
    WOLFSSL_ENTER("wolfSSL_X509_ALGOR_get0");
9228
9229
    if (!algor) {
9230
        WOLFSSL_MSG("algor object is NULL");
9231
        return;
9232
    }
9233
9234
    if (paobj)
9235
        *paobj = algor->algorithm;
9236
    if (ppval && algor->parameter)
9237
        *ppval = algor->parameter->value.ptr;
9238
    if (pptype) {
9239
        if (algor->parameter) {
9240
            *pptype = algor->parameter->type;
9241
        }
9242
        else {
9243
            /* Default to V_ASN1_OBJECT */
9244
            *pptype = V_ASN1_OBJECT;
9245
        }
9246
    }
9247
}
9248
9249
/**
9250
 * Populate algor members.
9251
 *
9252
 * @param algor The object to be set
9253
 * @param aobj The value to be set in algor->algorithm
9254
 * @param ptype The type of algor->parameter
9255
 * @param pval The value of algor->parameter
9256
 * @return WOLFSSL_SUCCESS on success
9257
 *         WOLFSSL_FAILURE on missing parameters or bad malloc
9258
 */
9259
int wolfSSL_X509_ALGOR_set0(WOLFSSL_X509_ALGOR *algor, WOLFSSL_ASN1_OBJECT *aobj,
9260
                            int ptype, void *pval)
9261
{
9262
    if (!algor) {
9263
        return WOLFSSL_FAILURE;
9264
    }
9265
9266
    if (!algor->parameter) {
9267
        algor->parameter = wolfSSL_ASN1_TYPE_new();
9268
        if (!algor->parameter) {
9269
            return WOLFSSL_FAILURE;
9270
        }
9271
    }
9272
9273
    if (aobj) {
9274
        algor->algorithm = aobj;
9275
    }
9276
    wolfSSL_ASN1_TYPE_set(algor->parameter, ptype, pval);
9277
9278
    return WOLFSSL_SUCCESS;
9279
}
9280
9281
/**
9282
 * Allocate a new WOLFSSL_X509_PUBKEY object.
9283
 *
9284
 * @return New zero'ed WOLFSSL_X509_PUBKEY object
9285
 */
9286
WOLFSSL_X509_PUBKEY *wolfSSL_X509_PUBKEY_new(void)
9287
{
9288
    WOLFSSL_X509_PUBKEY *ret;
9289
    ret = (WOLFSSL_X509_PUBKEY*)XMALLOC(sizeof(WOLFSSL_X509_PUBKEY), NULL,
9290
                                        DYNAMIC_TYPE_OPENSSL);
9291
    if (!ret) {
9292
        return NULL;
9293
    }
9294
    XMEMSET(ret, 0, sizeof(WOLFSSL_X509_PUBKEY));
9295
    ret->algor = wolfSSL_X509_ALGOR_new();
9296
    if (!ret->algor) {
9297
        wolfSSL_X509_PUBKEY_free(ret);
9298
        return NULL;
9299
    }
9300
    return ret;
9301
}
9302
9303
/**
9304
 * Free WOLFSSL_X509_PUBKEY and all its members.
9305
 *
9306
 * @param at Object to free
9307
 */
9308
void wolfSSL_X509_PUBKEY_free(WOLFSSL_X509_PUBKEY *x)
9309
{
9310
    if (x) {
9311
        if (x->algor) {
9312
            wolfSSL_X509_ALGOR_free(x->algor);
9313
        }
9314
        if (x->pkey) {
9315
            wolfSSL_EVP_PKEY_free(x->pkey);
9316
        }
9317
        XFREE(x, NULL, DYNAMIC_TYPE_OPENSSL);
9318
    }
9319
}
9320
9321
/* Returns X509_PUBKEY structure containing X509_ALGOR and EVP_PKEY */
9322
WOLFSSL_X509_PUBKEY* wolfSSL_X509_get_X509_PUBKEY(const WOLFSSL_X509* x509)
9323
{
9324
    WOLFSSL_ENTER("wolfSSL_X509_get_X509_PUBKEY");
9325
9326
    if (x509 == NULL) {
9327
        WOLFSSL_MSG("x509 struct NULL error");
9328
        return NULL;
9329
    }
9330
9331
    return (WOLFSSL_X509_PUBKEY*)&x509->key;
9332
}
9333
9334
/* Sets ppkalg pointer to X509_PUBKEY algorithm. Returns WOLFSSL_SUCCESS on
9335
    success or WOLFSSL_FAILURE on error. */
9336
int wolfSSL_X509_PUBKEY_get0_param(WOLFSSL_ASN1_OBJECT **ppkalg,
9337
     const unsigned char **pk, int *ppklen, WOLFSSL_X509_ALGOR **pa,
9338
     WOLFSSL_X509_PUBKEY *pub)
9339
{
9340
    WOLFSSL_ENTER("wolfSSL_X509_PUBKEY_get0_param");
9341
9342
    if (!pub || !pub->pubKeyOID) {
9343
        WOLFSSL_MSG("X509_PUBKEY struct not populated");
9344
        return WOLFSSL_FAILURE;
9345
    }
9346
9347
    if (!pub->algor) {
9348
        if (!(pub->algor = wolfSSL_X509_ALGOR_new())) {
9349
            return WOLFSSL_FAILURE;
9350
        }
9351
        pub->algor->algorithm = wolfSSL_OBJ_nid2obj(pub->pubKeyOID);
9352
        if (pub->algor->algorithm == NULL) {
9353
            WOLFSSL_MSG("Failed to create object from NID");
9354
            return WOLFSSL_FAILURE;
9355
        }
9356
    }
9357
9358
    if (pa)
9359
        *pa = pub->algor;
9360
    if (ppkalg)
9361
        *ppkalg = pub->algor->algorithm;
9362
    if (pk)
9363
        *pk = (unsigned char*)pub->pkey->pkey.ptr;
9364
    if (ppklen)
9365
        *ppklen = pub->pkey->pkey_sz;
9366
9367
    return WOLFSSL_SUCCESS;
9368
}
9369
9370
/* Returns a pointer to the pkey when passed a key */
9371
WOLFSSL_EVP_PKEY* wolfSSL_X509_PUBKEY_get(WOLFSSL_X509_PUBKEY* key)
9372
{
9373
    WOLFSSL_ENTER("wolfSSL_X509_PUBKEY_get");
9374
    if (key == NULL || key->pkey == NULL) {
9375
        WOLFSSL_LEAVE("wolfSSL_X509_PUBKEY_get", BAD_FUNC_ARG);
9376
        return NULL;
9377
    }
9378
    if (wolfSSL_EVP_PKEY_up_ref(key->pkey) != WOLFSSL_SUCCESS) {
9379
        WOLFSSL_LEAVE("wolfSSL_X509_PUBKEY_get", BAD_MUTEX_E);
9380
        return NULL;
9381
    }
9382
    WOLFSSL_LEAVE("wolfSSL_X509_PUBKEY_get", WOLFSSL_SUCCESS);
9383
    return key->pkey;
9384
}
9385
9386
int wolfSSL_X509_PUBKEY_set(WOLFSSL_X509_PUBKEY **x, WOLFSSL_EVP_PKEY *key)
9387
{
9388
    WOLFSSL_X509_PUBKEY *pk = NULL;
9389
    int ptype;
9390
    void *pval;
9391
#ifndef NO_DSA
9392
    WOLFSSL_ASN1_STRING *str;
9393
#endif
9394
#ifdef HAVE_ECC
9395
    int nid;
9396
    const WOLFSSL_EC_GROUP *group;
9397
#endif
9398
    WOLFSSL_ASN1_OBJECT *keyTypeObj;
9399
9400
    WOLFSSL_ENTER("wolfSSL_X509_PUBKEY_set");
9401
9402
    if (!x || !key) {
9403
        return WOLFSSL_FAILURE;
9404
    }
9405
9406
    if (!(pk = wolfSSL_X509_PUBKEY_new())) {
9407
        return WOLFSSL_FAILURE;
9408
    }
9409
9410
    switch (key->type) {
9411
#ifndef NO_RSA
9412
    case EVP_PKEY_RSA:
9413
        pval = NULL;
9414
        ptype = V_ASN1_NULL;
9415
        pk->pubKeyOID = RSAk;
9416
        break;
9417
#endif
9418
#ifndef NO_DSA
9419
    case EVP_PKEY_DSA:
9420
        if (!key->dsa->p || !key->dsa->q || !key->dsa->g)
9421
            goto error;
9422
9423
        str = wolfSSL_ASN1_STRING_new();
9424
        if (str == NULL)
9425
            goto error;
9426
9427
        str->length = wolfSSL_i2d_DSAparams(key->dsa,
9428
             (unsigned char **)&str->data);
9429
        if (str->length <= 0) {
9430
            wolfSSL_ASN1_STRING_free(str);
9431
            goto error;
9432
        }
9433
        str->isDynamic = 1;
9434
9435
        pval = str;
9436
        ptype = V_ASN1_SEQUENCE;
9437
        pk->pubKeyOID = DSAk;
9438
        break;
9439
#endif
9440
#ifdef HAVE_ECC
9441
    case EVP_PKEY_EC:
9442
        group = wolfSSL_EC_KEY_get0_group(key->ecc);
9443
        if (!group)
9444
            goto error;
9445
9446
        nid = wolfSSL_EC_GROUP_get_curve_name(group);
9447
        if (nid <= 0) {
9448
            /* TODO: Add support for no nid case */
9449
            WOLFSSL_MSG("nid not found");
9450
            goto error;
9451
        }
9452
9453
        pval = wolfSSL_OBJ_nid2obj(nid);
9454
        if (!pval)
9455
            goto error;
9456
9457
        ptype = V_ASN1_OBJECT;
9458
        pk->pubKeyOID = ECDSAk;
9459
        break;
9460
#endif
9461
    default:
9462
        WOLFSSL_MSG("Unknown key type");
9463
        goto error;
9464
    }
9465
9466
    keyTypeObj = wolfSSL_OBJ_nid2obj(key->type);
9467
    if (keyTypeObj == NULL) {
9468
        if (ptype == V_ASN1_OBJECT)
9469
            ASN1_OBJECT_free((WOLFSSL_ASN1_OBJECT *)pval);
9470
        else
9471
            ASN1_STRING_free((WOLFSSL_ASN1_STRING *)pval);
9472
        goto error;
9473
    }
9474
    if (!wolfSSL_X509_ALGOR_set0(pk->algor, keyTypeObj, ptype, pval)) {
9475
        WOLFSSL_MSG("Failed to create algorithm object");
9476
        ASN1_OBJECT_free(keyTypeObj);
9477
        if (ptype == V_ASN1_OBJECT)
9478
            ASN1_OBJECT_free((WOLFSSL_ASN1_OBJECT *)pval);
9479
        else
9480
            ASN1_STRING_free((WOLFSSL_ASN1_STRING *)pval);
9481
        goto error;
9482
    }
9483
9484
    if (!wolfSSL_EVP_PKEY_up_ref(key)) {
9485
        WOLFSSL_MSG("Failed to up key reference");
9486
        goto error;
9487
    }
9488
    pk->pkey = key;
9489
9490
    wolfSSL_X509_PUBKEY_free(*x);
9491
    *x = pk;
9492
    return WOLFSSL_SUCCESS;
9493
error:
9494
    if (pk) {
9495
        wolfSSL_X509_PUBKEY_free(pk);
9496
    }
9497
    return WOLFSSL_FAILURE;
9498
}
9499
9500
#endif /* OPENSSL_ALL || WOLFSSL_APACHE_HTTPD || WOLFSSL_HAPROXY || WOLFSSL_WPAS */
9501
9502
#endif /* OPENSSL_EXTRA */
9503
9504
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
9505
WOLFSSL_BASIC_CONSTRAINTS* wolfSSL_BASIC_CONSTRAINTS_new(void)
9506
{
9507
    WOLFSSL_BASIC_CONSTRAINTS* bc;
9508
    bc = (WOLFSSL_BASIC_CONSTRAINTS*)
9509
          XMALLOC(sizeof(WOLFSSL_BASIC_CONSTRAINTS), NULL,
9510
          DYNAMIC_TYPE_X509_EXT);
9511
    if (bc == NULL) {
9512
        WOLFSSL_MSG("Failed to malloc basic constraints");
9513
        return NULL;
9514
    }
9515
    XMEMSET(bc, 0, sizeof(WOLFSSL_BASIC_CONSTRAINTS));
9516
    return bc;
9517
}
9518
9519
/* frees the wolfSSL_BASIC_CONSTRAINTS object */
9520
void wolfSSL_BASIC_CONSTRAINTS_free(WOLFSSL_BASIC_CONSTRAINTS *bc)
9521
{
9522
    WOLFSSL_ENTER("wolfSSL_BASIC_CONSTRAINTS_free");
9523
    if (bc == NULL) {
9524
        WOLFSSL_MSG("Argument is NULL");
9525
        return;
9526
    }
9527
    if (bc->pathlen) {
9528
        wolfSSL_ASN1_INTEGER_free(bc->pathlen);
9529
    }
9530
    XFREE(bc, NULL, DYNAMIC_TYPE_OPENSSL);
9531
}
9532
9533
WOLFSSL_AUTHORITY_KEYID* wolfSSL_AUTHORITY_KEYID_new(void)
9534
{
9535
    WOLFSSL_AUTHORITY_KEYID* akey = (WOLFSSL_AUTHORITY_KEYID*)XMALLOC(
9536
          sizeof(WOLFSSL_AUTHORITY_KEYID), NULL, DYNAMIC_TYPE_OPENSSL);
9537
    if (!akey) {
9538
        WOLFSSL_MSG("Issue creating WOLFSSL_AUTHORITY_KEYID struct");
9539
        return NULL;
9540
    }
9541
    XMEMSET(akey, 0, sizeof(WOLFSSL_AUTHORITY_KEYID));
9542
    return akey;
9543
}
9544
9545
/* frees the wolfSSL_AUTHORITY_KEYID object */
9546
void wolfSSL_AUTHORITY_KEYID_free(WOLFSSL_AUTHORITY_KEYID *id)
9547
{
9548
    WOLFSSL_ENTER("wolfSSL_AUTHORITY_KEYID_free");
9549
    if(id == NULL) {
9550
        WOLFSSL_MSG("Argument is NULL");
9551
        return;
9552
    }
9553
    if (id->keyid) {
9554
        wolfSSL_ASN1_STRING_free(id->keyid);
9555
    }
9556
    if (id->issuer) {
9557
        wolfSSL_ASN1_OBJECT_free(id->issuer);
9558
    }
9559
    if (id->serial) {
9560
        wolfSSL_ASN1_INTEGER_free(id->serial);
9561
    }
9562
    XFREE(id, NULL, DYNAMIC_TYPE_OPENSSL);
9563
}
9564
9565
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
9566
9567
#ifdef KEEP_PEER_CERT
9568
char*  wolfSSL_X509_get_subjectCN(WOLFSSL_X509* x509)
9569
{
9570
    if (x509 == NULL)
9571
        return NULL;
9572
9573
    return x509->subjectCN;
9574
}
9575
#endif /* KEEP_PEER_CERT */
9576
9577
#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA)
9578
/* increments ref count of WOLFSSL_X509. Return 1 on success, 0 on error */
9579
int wolfSSL_X509_up_ref(WOLFSSL_X509* x509)
9580
{
9581
    if (x509) {
9582
        int ret;
9583
        wolfSSL_RefInc(&x509->ref, &ret);
9584
        if (ret != 0) {
9585
            WOLFSSL_MSG("Failed to lock x509 mutex");
9586
            return WOLFSSL_FAILURE;
9587
        }
9588
9589
        return WOLFSSL_SUCCESS;
9590
    }
9591
9592
    return WOLFSSL_FAILURE;
9593
}
9594
#endif /* OPENSSL_EXTRA_X509_SMALL || OPENSSL_EXTRA */
9595
9596
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
9597
WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_chain_up_ref(
9598
        WOLF_STACK_OF(WOLFSSL_X509)* chain)
9599
{
9600
    /* wolfSSL_sk_dup takes care of doing a deep copy */
9601
    return wolfSSL_sk_dup(chain);
9602
}
9603
#endif
9604
9605
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
9606
    void wolfSSL_X509_NAME_free(WOLFSSL_X509_NAME *name)
9607
    {
9608
        WOLFSSL_ENTER("wolfSSL_X509_NAME_free");
9609
        FreeX509Name(name);
9610
        if (name != NULL) {
9611
            XFREE(name, name->heap, DYNAMIC_TYPE_X509);
9612
        }
9613
    }
9614
9615
9616
    /* Malloc's a new WOLFSSL_X509_NAME structure
9617
     *
9618
     * returns NULL on failure, otherwise returns a new structure.
9619
     */
9620
    WOLFSSL_X509_NAME* wolfSSL_X509_NAME_new_ex(void *heap)
9621
    {
9622
        WOLFSSL_X509_NAME* name;
9623
9624
        WOLFSSL_ENTER("wolfSSL_X509_NAME_new_ex");
9625
9626
        name = (WOLFSSL_X509_NAME*)XMALLOC(sizeof(WOLFSSL_X509_NAME), heap,
9627
                DYNAMIC_TYPE_X509);
9628
        if (name != NULL) {
9629
            InitX509Name(name, 1, heap);
9630
        }
9631
        return name;
9632
    }
9633
9634
    WOLFSSL_X509_NAME* wolfSSL_X509_NAME_new(void) {
9635
        return wolfSSL_X509_NAME_new_ex(NULL);
9636
    }
9637
9638
    /* Creates a duplicate of a WOLFSSL_X509_NAME structure.
9639
       Returns a new WOLFSSL_X509_NAME structure or NULL on failure */
9640
    WOLFSSL_X509_NAME* wolfSSL_X509_NAME_dup(WOLFSSL_X509_NAME *name)
9641
    {
9642
        WOLFSSL_X509_NAME* copy = NULL;
9643
9644
        WOLFSSL_ENTER("wolfSSL_X509_NAME_dup");
9645
9646
        if (name == NULL) {
9647
            WOLFSSL_MSG("NULL parameter");
9648
            return NULL;
9649
        }
9650
9651
        if (!(copy = wolfSSL_X509_NAME_new_ex(name->heap))) {
9652
            return NULL;
9653
        }
9654
9655
        /* copy contents */
9656
        InitX509Name(copy, 1, name->heap);
9657
        if (wolfSSL_X509_NAME_copy(name, copy) != WOLFSSL_SUCCESS) {
9658
            wolfSSL_X509_NAME_free(copy);
9659
            return NULL;
9660
        }
9661
9662
        return copy;
9663
    }
9664
9665
#ifdef WOLFSSL_CERT_GEN
9666
9667
#if defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
9668
    /* Helper function to copy cert name from a WOLFSSL_X509_NAME structure to
9669
    * a Cert structure.
9670
    *
9671
    * returns length of DER on success and a negative error value on failure
9672
    */
9673
    static int CopyX509NameToCert(WOLFSSL_X509_NAME* n, byte* out)
9674
    {
9675
        unsigned char* der = NULL;
9676
        int length = BAD_FUNC_ARG, ret;
9677
        word32 idx = 0;
9678
9679
        ret = wolfSSL_i2d_X509_NAME(n, &der);
9680
        if (ret > (int)sizeof(CertName) || ret < 0) {
9681
            WOLFSSL_MSG("Name conversion error");
9682
            ret = MEMORY_E;
9683
        }
9684
9685
        if (ret > 0) {
9686
            /* strip off sequence, this gets added on certificate creation */
9687
            ret = GetSequence(der, &idx, &length, ret);
9688
        }
9689
9690
        if (ret > 0) {
9691
            XMEMCPY(out, der + idx, length);
9692
        }
9693
9694
        if (der != NULL)
9695
            XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
9696
9697
        return length;
9698
    }
9699
#endif
9700
9701
#ifdef WOLFSSL_CERT_REQ
9702
    static int ReqCertFromX509(Cert* cert, WOLFSSL_X509* req)
9703
    {
9704
        int ret;
9705
9706
        if (wc_InitCert(cert) != 0)
9707
            return WOLFSSL_FAILURE;
9708
9709
9710
        ret = CopyX509NameToCert(&req->subject, cert->sbjRaw);
9711
        if (ret < 0) {
9712
            WOLFSSL_MSG("REQ subject conversion error");
9713
            ret = MEMORY_E;
9714
        }
9715
        else {
9716
            ret = WOLFSSL_SUCCESS;
9717
        }
9718
9719
        if (ret == WOLFSSL_SUCCESS) {
9720
        #if defined(OPENSSL_ALL)
9721
            int idx;
9722
        #endif
9723
9724
            cert->version = req->version;
9725
            cert->isCA = req->isCa;
9726
            cert->basicConstSet = req->basicConstSet;
9727
    #ifdef WOLFSSL_CERT_EXT
9728
            if (req->subjKeyIdSz != 0) {
9729
                XMEMCPY(cert->skid, req->subjKeyId, req->subjKeyIdSz);
9730
                cert->skidSz = req->subjKeyIdSz;
9731
            }
9732
            if (req->keyUsageSet)
9733
                cert->keyUsage = req->keyUsage;
9734
9735
            cert->extKeyUsage = req->extKeyUsage;
9736
    #endif
9737
9738
            XMEMCPY(cert->challengePw, req->challengePw, CTC_NAME_SIZE);
9739
            cert->challengePwPrintableString = req->challengePw[0] != 0;
9740
9741
        #if defined(OPENSSL_ALL)
9742
            idx = wolfSSL_X509_REQ_get_attr_by_NID(req,
9743
                    NID_pkcs9_unstructuredName, -1);
9744
            if (idx != WOLFSSL_FATAL_ERROR) {
9745
                WOLFSSL_X509_ATTRIBUTE *attr;
9746
                attr = wolfSSL_X509_REQ_get_attr(req, idx);
9747
                if (attr != NULL) {
9748
                    const unsigned char *attrData;
9749
                    int attrDataSz;
9750
9751
                    attrData = wolfSSL_ASN1_STRING_get0_data(
9752
                            attr->value->value.asn1_string);
9753
                    attrDataSz = wolfSSL_ASN1_STRING_length(
9754
                            attr->value->value.asn1_string);
9755
9756
                    /* +1 to make sure is terminated string */
9757
                    if (attrDataSz + 1 > CTC_NAME_SIZE) {
9758
                        WOLFSSL_MSG("attribute size was too large to copy");
9759
                        ret = REQ_ATTRIBUTE_E;
9760
                    }
9761
                    else {
9762
                        XMEMCPY(cert->unstructuredName, attrData, attrDataSz);
9763
                        cert->unstructuredName[attrDataSz] = '\0';
9764
                    }
9765
                }
9766
            }
9767
9768
        #ifdef WOLFSSL_CUSTOM_OID
9769
            if (ret == WOLFSSL_SUCCESS) {
9770
                if ((req->customExtCount < 0) ||
9771
                    (req->customExtCount >= NUM_CUSTOM_EXT)) {
9772
                    WOLFSSL_MSG("Bad value for customExtCount.");
9773
                    ret = WOLFSSL_FAILURE;
9774
                }
9775
9776
                if (ret == WOLFSSL_SUCCESS) {
9777
                    for (idx = 0; idx < req->customExtCount; idx++) {
9778
                        /* Note that ownership is NOT transferred.
9779
                         * req->custom_exts buffers still need to be cleaned
9780
                         * up. */
9781
                        cert->customCertExt[idx] = req->custom_exts[idx];
9782
                    }
9783
                    cert->customCertExtCount = req->customExtCount;
9784
                }
9785
            }
9786
        #endif /* WOLFSSL_CUSTOM_OID */
9787
        #endif /* OPENSSL_ALL */
9788
9789
    #ifdef WOLFSSL_ALT_NAMES
9790
            if (ret == WOLFSSL_SUCCESS) {
9791
                cert->altNamesSz = FlattenAltNames(cert->altNames,
9792
                        sizeof(cert->altNames), req->altNames);
9793
            }
9794
    #endif /* WOLFSSL_ALT_NAMES */
9795
        }
9796
9797
        return ret;
9798
    }
9799
#endif /* WOLFSSL_CERT_REQ */
9800
9801
    /* converts WOLFSSL_AN1_TIME to Cert form, returns positive size on
9802
     * success */
9803
    static int CertDateFromX509(byte* out, int outSz, WOLFSSL_ASN1_TIME* t)
9804
    {
9805
        int sz, i;
9806
9807
        if (t->length + 1 >= outSz) {
9808
            return BUFFER_E;
9809
        }
9810
9811
        out[0] = (byte) t->type;
9812
        sz = SetLength(t->length, out + 1) + 1;  /* gen tag */
9813
        for (i = 0; i < t->length; i++) {
9814
            out[sz + i] = t->data[i];
9815
        }
9816
        return t->length + sz;
9817
    }
9818
9819
    /* convert a WOLFSSL_X509 to a Cert structure for writing out */
9820
    static int CertFromX509(Cert* cert, WOLFSSL_X509* x509)
9821
    {
9822
        int ret;
9823
        #ifdef WOLFSSL_CERT_EXT
9824
        int i;
9825
        #endif
9826
9827
        WOLFSSL_ENTER("wolfSSL_X509_to_Cert");
9828
9829
        if (x509 == NULL || cert == NULL) {
9830
            return BAD_FUNC_ARG;
9831
        }
9832
9833
        wc_InitCert(cert);
9834
9835
        cert->version = (int)wolfSSL_X509_get_version(x509);
9836
9837
        if (x509->notBefore.length > 0) {
9838
            cert->beforeDateSz = CertDateFromX509(cert->beforeDate,
9839
                        CTC_DATE_SIZE, &x509->notBefore);
9840
            if (cert->beforeDateSz <= 0){
9841
                WOLFSSL_MSG("Error converting WOLFSSL_X509 not before date");
9842
                return WOLFSSL_FAILURE;
9843
            }
9844
        }
9845
        else {
9846
            cert->beforeDateSz = 0;
9847
        }
9848
9849
        if (x509->notAfter.length > 0) {
9850
            cert->afterDateSz = CertDateFromX509(cert->afterDate,
9851
                        CTC_DATE_SIZE, &x509->notAfter);
9852
            if (cert->afterDateSz <= 0){
9853
                WOLFSSL_MSG("Error converting WOLFSSL_X509 not after date");
9854
                return WOLFSSL_FAILURE;
9855
            }
9856
        }
9857
        else {
9858
            cert->afterDateSz = 0;
9859
        }
9860
9861
    #ifdef WOLFSSL_ALT_NAMES
9862
        cert->altNamesSz = FlattenAltNames(cert->altNames,
9863
                sizeof(cert->altNames), x509->altNames);
9864
    #endif /* WOLFSSL_ALT_NAMES */
9865
9866
        cert->sigType = wolfSSL_X509_get_signature_type(x509);
9867
        cert->keyType = x509->pubKeyOID;
9868
        cert->isCA    = wolfSSL_X509_get_isCA(x509);
9869
        cert->basicConstSet = x509->basicConstSet;
9870
9871
    #ifdef WOLFSSL_CERT_EXT
9872
        if (x509->subjKeyIdSz <= CTC_MAX_SKID_SIZE) {
9873
            if (x509->subjKeyId) {
9874
                XMEMCPY(cert->skid, x509->subjKeyId, x509->subjKeyIdSz);
9875
            }
9876
            cert->skidSz = (int)x509->subjKeyIdSz;
9877
        }
9878
        else {
9879
            WOLFSSL_MSG("Subject Key ID too large");
9880
            WOLFSSL_ERROR_VERBOSE(BUFFER_E);
9881
            return WOLFSSL_FAILURE;
9882
        }
9883
9884
        if (x509->authKeyIdSz < sizeof(cert->akid)) {
9885
        #ifdef WOLFSSL_AKID_NAME
9886
            cert->rawAkid = 0;
9887
            if (x509->authKeyIdSrc) {
9888
                XMEMCPY(cert->akid, x509->authKeyIdSrc, x509->authKeyIdSrcSz);
9889
                cert->akidSz = (int)x509->authKeyIdSrcSz;
9890
                cert->rawAkid = 1;
9891
            }
9892
            else
9893
        #endif
9894
            if (x509->authKeyId) {
9895
                XMEMCPY(cert->akid, x509->authKeyId, x509->authKeyIdSz);
9896
                cert->akidSz = (int)x509->authKeyIdSz;
9897
            }
9898
        }
9899
        else {
9900
            WOLFSSL_MSG("Auth Key ID too large");
9901
            WOLFSSL_ERROR_VERBOSE(BUFFER_E);
9902
            return WOLFSSL_FAILURE;
9903
        }
9904
9905
        for (i = 0; i < x509->certPoliciesNb; i++) {
9906
            /* copy the smaller of MAX macros, by default they are currently equal*/
9907
            if ((int)CTC_MAX_CERTPOL_SZ <= (int)MAX_CERTPOL_SZ) {
9908
                XMEMCPY(cert->certPolicies[i], x509->certPolicies[i],
9909
                        CTC_MAX_CERTPOL_SZ);
9910
            }
9911
            else {
9912
                XMEMCPY(cert->certPolicies[i], x509->certPolicies[i],
9913
                        MAX_CERTPOL_SZ);
9914
            }
9915
        }
9916
        cert->certPoliciesNb = (word16)x509->certPoliciesNb;
9917
9918
        cert->keyUsage = x509->keyUsage;
9919
        cert->extKeyUsage = x509->extKeyUsage;
9920
        cert->nsCertType = x509->nsCertType;
9921
9922
        if (x509->rawCRLInfo != NULL) {
9923
            if (x509->rawCRLInfoSz > CTC_MAX_CRLINFO_SZ) {
9924
                WOLFSSL_MSG("CRL Info too large");
9925
                WOLFSSL_ERROR_VERBOSE(BUFFER_E);
9926
                return WOLFSSL_FAILURE;
9927
            }
9928
            XMEMCPY(cert->crlInfo, x509->rawCRLInfo, x509->rawCRLInfoSz);
9929
            cert->crlInfoSz = x509->rawCRLInfoSz;
9930
        }
9931
    #endif /* WOLFSSL_CERT_EXT */
9932
9933
    #ifdef WOLFSSL_CERT_REQ
9934
        /* copy over challenge password for REQ certs */
9935
        XMEMCPY(cert->challengePw, x509->challengePw, CTC_NAME_SIZE);
9936
    #endif
9937
9938
        /* Only makes sense to do this for OPENSSL_EXTRA because without
9939
         * this define the function will error out below */
9940
        #ifdef OPENSSL_EXTRA
9941
        if (x509->serialSz == 0 && x509->serialNumber != NULL &&
9942
                /* Check if the buffer contains more than just the
9943
                 * ASN tag and length */
9944
                x509->serialNumber->length > 2) {
9945
            if (wolfSSL_X509_set_serialNumber(x509, x509->serialNumber)
9946
                    != WOLFSSL_SUCCESS) {
9947
                WOLFSSL_MSG("Failed to set serial number");
9948
                return WOLFSSL_FAILURE;
9949
            }
9950
        }
9951
        #endif
9952
9953
        /* set serial number */
9954
        if (x509->serialSz > 0) {
9955
        #if defined(OPENSSL_EXTRA)
9956
            byte serial[EXTERNAL_SERIAL_SIZE];
9957
            int  serialSz = EXTERNAL_SERIAL_SIZE;
9958
9959
            ret = wolfSSL_X509_get_serial_number(x509, serial, &serialSz);
9960
            if (ret != WOLFSSL_SUCCESS) {
9961
                WOLFSSL_MSG("Serial size error");
9962
                return WOLFSSL_FAILURE;
9963
            }
9964
9965
            if (serialSz > EXTERNAL_SERIAL_SIZE ||
9966
                    serialSz > CTC_SERIAL_SIZE) {
9967
                WOLFSSL_MSG("Serial size too large error");
9968
                WOLFSSL_ERROR_VERBOSE(BUFFER_E);
9969
                return WOLFSSL_FAILURE;
9970
            }
9971
            XMEMCPY(cert->serial, serial, serialSz);
9972
            cert->serialSz = serialSz;
9973
        #else
9974
            WOLFSSL_MSG("Getting X509 serial number not supported");
9975
            return WOLFSSL_FAILURE;
9976
        #endif
9977
        }
9978
9979
        /* copy over Name structures */
9980
        if (x509->issuerSet)
9981
            cert->selfSigned = 0;
9982
9983
    #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
9984
        ret = CopyX509NameToCert(&x509->subject, cert->sbjRaw);
9985
        if (ret < 0) {
9986
            WOLFSSL_MSG("Subject conversion error");
9987
            return MEMORY_E;
9988
        }
9989
        if (cert->selfSigned) {
9990
            XMEMCPY(cert->issRaw, cert->sbjRaw, sizeof(CertName));
9991
        }
9992
        else {
9993
            ret = CopyX509NameToCert(&x509->issuer, cert->issRaw);
9994
            if (ret < 0) {
9995
                WOLFSSL_MSG("Issuer conversion error");
9996
                return MEMORY_E;
9997
            }
9998
        }
9999
    #endif
10000
10001
        cert->heap = x509->heap;
10002
10003
        (void)ret;
10004
        return WOLFSSL_SUCCESS;
10005
    }
10006
10007
10008
    /* returns the sig type to use on success i.e CTC_SHAwRSA and WOLFSSL_FALURE
10009
     * on fail case */
10010
    static int wolfSSL_sigTypeFromPKEY(WOLFSSL_EVP_MD* md,
10011
            WOLFSSL_EVP_PKEY* pkey)
10012
    {
10013
    #if !defined(NO_PWDBASED) && defined(OPENSSL_EXTRA)
10014
        int hashType;
10015
        int sigType = WOLFSSL_FAILURE;
10016
10017
        /* Convert key type and hash algorithm to a signature algorithm */
10018
        if (wolfSSL_EVP_get_hashinfo(md, &hashType, NULL) == WOLFSSL_FAILURE) {
10019
            return WOLFSSL_FAILURE;
10020
        }
10021
10022
        if (pkey->type == EVP_PKEY_RSA) {
10023
            switch (hashType) {
10024
                case WC_HASH_TYPE_SHA:
10025
                    sigType = CTC_SHAwRSA;
10026
                    break;
10027
                case WC_HASH_TYPE_SHA224:
10028
                    sigType = CTC_SHA224wRSA;
10029
                    break;
10030
                case WC_HASH_TYPE_SHA256:
10031
                    sigType = CTC_SHA256wRSA;
10032
                    break;
10033
                case WC_HASH_TYPE_SHA384:
10034
                    sigType = CTC_SHA384wRSA;
10035
                    break;
10036
                case WC_HASH_TYPE_SHA512:
10037
                    sigType = CTC_SHA512wRSA;
10038
                    break;
10039
            #ifdef WOLFSSL_SHA3
10040
                case WC_HASH_TYPE_SHA3_224:
10041
                    sigType = CTC_SHA3_224wRSA;
10042
                    break;
10043
                case WC_HASH_TYPE_SHA3_256:
10044
                    sigType = CTC_SHA3_256wRSA;
10045
                    break;
10046
                case WC_HASH_TYPE_SHA3_384:
10047
                    sigType = CTC_SHA3_384wRSA;
10048
                    break;
10049
                case WC_HASH_TYPE_SHA3_512:
10050
                    sigType = CTC_SHA3_512wRSA;
10051
                    break;
10052
            #endif
10053
                default:
10054
                    return WOLFSSL_FAILURE;
10055
            }
10056
        }
10057
        else if (pkey->type == EVP_PKEY_EC) {
10058
            switch (hashType) {
10059
                case WC_HASH_TYPE_SHA:
10060
                    sigType = CTC_SHAwECDSA;
10061
                    break;
10062
                case WC_HASH_TYPE_SHA224:
10063
                    sigType = CTC_SHA224wECDSA;
10064
                    break;
10065
                case WC_HASH_TYPE_SHA256:
10066
                    sigType = CTC_SHA256wECDSA;
10067
                    break;
10068
                case WC_HASH_TYPE_SHA384:
10069
                    sigType = CTC_SHA384wECDSA;
10070
                    break;
10071
                case WC_HASH_TYPE_SHA512:
10072
                    sigType = CTC_SHA512wECDSA;
10073
                    break;
10074
            #ifdef WOLFSSL_SHA3
10075
                case WC_HASH_TYPE_SHA3_224:
10076
                    sigType = CTC_SHA3_224wECDSA;
10077
                    break;
10078
                case WC_HASH_TYPE_SHA3_256:
10079
                    sigType = CTC_SHA3_256wECDSA;
10080
                    break;
10081
                case WC_HASH_TYPE_SHA3_384:
10082
                    sigType = CTC_SHA3_384wECDSA;
10083
                    break;
10084
                case WC_HASH_TYPE_SHA3_512:
10085
                    sigType = CTC_SHA3_512wECDSA;
10086
                    break;
10087
            #endif
10088
                default:
10089
                    return WOLFSSL_FAILURE;
10090
            }
10091
        }
10092
        else
10093
            return WOLFSSL_FAILURE;
10094
        return sigType;
10095
#else
10096
        (void)md;
10097
        (void)pkey;
10098
        WOLFSSL_MSG("Cannot get hashinfo when NO_PWDBASED is defined");
10099
        return WOLFSSL_FAILURE;
10100
#endif /* !NO_PWDBASED && OPENSSL_EXTRA */
10101
    }
10102
10103
10104
    /* generates DER buffer from WOLFSSL_X509
10105
     * If req == 1 then creates a request DER buffer
10106
     *
10107
     * updates derSz with certificate body size on success
10108
     * return WOLFSSL_SUCCESS on success
10109
     */
10110
    static int wolfssl_x509_make_der(WOLFSSL_X509* x509, int req,
10111
            unsigned char* der, int* derSz, int includeSig)
10112
    {
10113
        int ret = WOLFSSL_FAILURE;
10114
        int totalLen;
10115
        Cert* cert = NULL;
10116
        void* key = NULL;
10117
        int type = -1;
10118
    #ifndef NO_RSA
10119
        RsaKey* rsa = NULL;
10120
    #endif
10121
    #ifdef HAVE_ECC
10122
        ecc_key* ecc = NULL;
10123
    #endif
10124
    #ifndef NO_DSA
10125
        DsaKey* dsa = NULL;
10126
    #endif
10127
        WC_RNG rng;
10128
        word32 idx = 0;
10129
10130
        if (x509 == NULL || der == NULL || derSz == NULL)
10131
            return BAD_FUNC_ARG;
10132
10133
    #ifndef WOLFSSL_CERT_REQ
10134
        if (req) {
10135
            WOLFSSL_MSG("WOLFSSL_CERT_REQ needed for certificate request");
10136
            return WOLFSSL_FAILURE;
10137
        }
10138
    #endif
10139
10140
        /* allocate Cert struct on heap since it is large */
10141
        cert = (Cert*)XMALLOC(sizeof(Cert), NULL, DYNAMIC_TYPE_CERT);
10142
        if (cert == NULL) {
10143
            WOLFSSL_MSG("Failed to allocate memory for Cert struct");
10144
            return WOLFSSL_FAILURE;
10145
        }
10146
        XMEMSET(cert, 0, sizeof(Cert));
10147
10148
    #ifdef WOLFSSL_CERT_REQ
10149
        if (req) {
10150
            if (ReqCertFromX509(cert, x509) != WOLFSSL_SUCCESS) {
10151
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
10152
                return WOLFSSL_FAILURE;
10153
            }
10154
        }
10155
        else
10156
    #endif
10157
        {
10158
            /* Create a Cert that has the certificate fields. */
10159
            if (CertFromX509(cert, x509) != WOLFSSL_SUCCESS) {
10160
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
10161
                return WOLFSSL_FAILURE;
10162
            }
10163
        }
10164
10165
        /* Create a public key object from requests public key. */
10166
    #ifndef NO_RSA
10167
        if (x509->pubKeyOID == RSAk) {
10168
10169
            rsa = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
10170
            if (rsa == NULL) {
10171
                WOLFSSL_MSG("Failed to allocate memory for RsaKey");
10172
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
10173
                return WOLFSSL_FAILURE;
10174
            }
10175
10176
            type = RSA_TYPE;
10177
            ret = wc_InitRsaKey(rsa, x509->heap);
10178
            if (ret != 0) {
10179
                XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
10180
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
10181
                return ret;
10182
            }
10183
            ret = wc_RsaPublicKeyDecode(x509->pubKey.buffer, &idx, rsa,
10184
                                                           x509->pubKey.length);
10185
            if (ret != 0) {
10186
                WOLFSSL_ERROR_VERBOSE(ret);
10187
                wc_FreeRsaKey(rsa);
10188
                XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
10189
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
10190
                return ret;
10191
            }
10192
            key = (void*)rsa;
10193
        }
10194
    #endif
10195
    #ifdef HAVE_ECC
10196
        if (x509->pubKeyOID == ECDSAk) {
10197
10198
            ecc = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
10199
            if (ecc == NULL) {
10200
                WOLFSSL_MSG("Failed to allocate memory for ecc_key");
10201
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
10202
                return WOLFSSL_FAILURE;
10203
            }
10204
10205
            type = ECC_TYPE;
10206
            ret = wc_ecc_init(ecc);
10207
            if (ret != 0) {
10208
                XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
10209
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
10210
                return ret;
10211
            }
10212
            ret = wc_EccPublicKeyDecode(x509->pubKey.buffer, &idx, ecc,
10213
                                                           x509->pubKey.length);
10214
            if (ret != 0) {
10215
                WOLFSSL_ERROR_VERBOSE(ret);
10216
                wc_ecc_free(ecc);
10217
                XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
10218
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
10219
                return ret;
10220
            }
10221
            key = (void*)ecc;
10222
        }
10223
    #endif
10224
    #ifndef NO_DSA
10225
        if (x509->pubKeyOID == DSAk) {
10226
10227
            dsa = (DsaKey*)XMALLOC(sizeof(DsaKey), NULL, DYNAMIC_TYPE_DSA);
10228
            if (dsa == NULL) {
10229
                WOLFSSL_MSG("Failed to allocate memory for DsaKey");
10230
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
10231
                return WOLFSSL_FAILURE;
10232
            }
10233
10234
            type = DSA_TYPE;
10235
            ret = wc_InitDsaKey(dsa);
10236
            if (ret != 0) {
10237
                XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
10238
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
10239
                return ret;
10240
            }
10241
            ret = wc_DsaPublicKeyDecode(x509->pubKey.buffer, &idx, dsa,
10242
                                                           x509->pubKey.length);
10243
            if (ret != 0) {
10244
                WOLFSSL_ERROR_VERBOSE(ret);
10245
                wc_FreeDsaKey(dsa);
10246
                XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
10247
                XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
10248
                return ret;
10249
            }
10250
            key = (void*)dsa;
10251
        }
10252
    #endif
10253
        if (key == NULL) {
10254
            WOLFSSL_MSG("No public key found for certificate");
10255
            XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
10256
            return WOLFSSL_FAILURE;
10257
        }
10258
10259
        /* Make the body of the certificate request. */
10260
    #ifdef WOLFSSL_CERT_REQ
10261
        if (req) {
10262
            ret = wc_MakeCertReq_ex(cert, der, *derSz, type, key);
10263
        }
10264
        else
10265
    #endif
10266
        {
10267
            ret = wc_InitRng(&rng);
10268
            if (ret != 0) {
10269
                ret = WOLFSSL_FAILURE;
10270
                goto cleanup;
10271
            }
10272
10273
            ret = wc_MakeCert_ex(cert, der, *derSz, type, key, &rng);
10274
            wc_FreeRng(&rng);
10275
        }
10276
        if (ret <= 0) {
10277
            WOLFSSL_ERROR_VERBOSE(ret);
10278
            ret = WOLFSSL_FAILURE;
10279
            goto cleanup;
10280
        }
10281
10282
        if ((x509->serialSz == 0) &&
10283
                (cert->serialSz <= EXTERNAL_SERIAL_SIZE) &&
10284
                (cert->serialSz > 0)) {
10285
        #if defined(OPENSSL_EXTRA)
10286
            WOLFSSL_ASN1_INTEGER *i = wolfSSL_ASN1_INTEGER_new();
10287
10288
            if (i == NULL) {
10289
                WOLFSSL_MSG("wolfSSL_ASN1_INTEGER_new error");
10290
                ret = WOLFSSL_FAILURE;
10291
                goto cleanup;
10292
            }
10293
            else {
10294
                i->length = cert->serialSz + 2;
10295
                i->data[0] = ASN_INTEGER;
10296
                i->data[1] = (unsigned char)cert->serialSz;
10297
                XMEMCPY(i->data + 2, cert->serial, cert->serialSz);
10298
                if (wolfSSL_X509_set_serialNumber(x509, i) != WOLFSSL_SUCCESS) {
10299
                    WOLFSSL_MSG("Issue setting generated serial number");
10300
                    wolfSSL_ASN1_INTEGER_free(i);
10301
                    ret = WOLFSSL_FAILURE;
10302
                    goto cleanup;
10303
                }
10304
                wolfSSL_ASN1_INTEGER_free(i);
10305
            }
10306
        #else
10307
            WOLFSSL_MSG("ASN1_INTEGER API not in build");
10308
10309
            ret = WOLFSSL_FAILURE;
10310
            goto cleanup;
10311
        #endif /* OPENSSL_EXTRA */
10312
        }
10313
10314
        if (includeSig) {
10315
            if (!x509->sig.buffer) {
10316
                WOLFSSL_MSG("No signature buffer");
10317
                ret = WOLFSSL_FAILURE;
10318
                goto cleanup;
10319
            }
10320
            totalLen = AddSignature(NULL, ret, NULL, x509->sig.length,
10321
                                  x509->sigOID);
10322
            if (totalLen > *derSz) {
10323
                WOLFSSL_MSG("Output der buffer too short");
10324
                ret = WOLFSSL_FAILURE;
10325
                goto cleanup;
10326
            }
10327
            ret = AddSignature(der, ret, x509->sig.buffer,
10328
                               x509->sig.length, x509->sigOID);
10329
        }
10330
10331
        *derSz = ret;
10332
        ret = WOLFSSL_SUCCESS;
10333
cleanup:
10334
        /* Dispose of the public key object. */
10335
    #ifndef NO_RSA
10336
        if (x509->pubKeyOID == RSAk) {
10337
            wc_FreeRsaKey(rsa);
10338
            XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
10339
        }
10340
    #endif
10341
    #ifdef HAVE_ECC
10342
        if (x509->pubKeyOID == ECDSAk) {
10343
            wc_ecc_free(ecc);
10344
            XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
10345
        }
10346
    #endif
10347
    #ifndef NO_DSA
10348
        if (x509->pubKeyOID == DSAk) {
10349
            wc_FreeDsaKey(dsa);
10350
            XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
10351
        }
10352
    #endif
10353
        XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
10354
10355
        return ret;
10356
    }
10357
10358
10359
    /* signs a der buffer for the WOLFSSL_X509 structure using the PKEY and MD
10360
     * hash passed in
10361
     *
10362
     * WARNING: this free's and replaces the existing DER buffer in the
10363
     *          WOLFSSL_X509 with the newly signed buffer.
10364
     * returns size of signed buffer on success and negative values on fail
10365
     */
10366
    static int wolfSSL_X509_resign_cert(WOLFSSL_X509* x509, int req,
10367
            unsigned char* der, int derSz, int certBodySz, WOLFSSL_EVP_MD* md,
10368
            WOLFSSL_EVP_PKEY* pkey)
10369
    {
10370
        int ret;
10371
        void* key = NULL;
10372
        int type = -1;
10373
        int sigType;
10374
        WC_RNG rng;
10375
10376
        (void)req;
10377
        WOLFSSL_ENTER("wolfSSL_X509_resign_cert");
10378
10379
        sigType = wolfSSL_sigTypeFromPKEY(md, pkey);
10380
        if (sigType == WOLFSSL_FAILURE) {
10381
            WOLFSSL_MSG("Error getting signature type from pkey");
10382
            return WOLFSSL_FATAL_ERROR;
10383
        }
10384
10385
10386
        /* Get the private key object and type from pkey. */
10387
    #ifndef NO_RSA
10388
        if (pkey->type == EVP_PKEY_RSA) {
10389
            type = RSA_TYPE;
10390
            key = pkey->rsa->internal;
10391
        }
10392
    #endif
10393
    #ifdef HAVE_ECC
10394
        if (pkey->type == EVP_PKEY_EC) {
10395
            type = ECC_TYPE;
10396
            key = pkey->ecc->internal;
10397
        }
10398
    #endif
10399
10400
        /* Sign the certificate (request) body. */
10401
        ret = wc_InitRng(&rng);
10402
        if (ret != 0)
10403
            return ret;
10404
        ret = wc_SignCert_ex(certBodySz, sigType, der, derSz, type, key, &rng);
10405
        wc_FreeRng(&rng);
10406
        if (ret < 0) {
10407
            WOLFSSL_LEAVE("wolfSSL_X509_resign_cert", ret);
10408
            return ret;
10409
        }
10410
        derSz = ret;
10411
10412
        /* Extract signature from buffer */
10413
        {
10414
            word32 idx = 0;
10415
            int    len = 0;
10416
10417
            /* Read top level sequence */
10418
            if (GetSequence(der, &idx, &len, derSz) < 0) {
10419
                WOLFSSL_MSG("GetSequence error");
10420
                return WOLFSSL_FATAL_ERROR;
10421
            }
10422
            /* Move idx to signature */
10423
            idx += certBodySz;
10424
            /* Read signature algo sequence */
10425
            if (GetSequence(der, &idx, &len, derSz) < 0) {
10426
                WOLFSSL_MSG("GetSequence error");
10427
                return WOLFSSL_FATAL_ERROR;
10428
            }
10429
            idx += len;
10430
            /* Read signature bit string */
10431
            if (CheckBitString(der, &idx, &len, derSz, 0, NULL) != 0) {
10432
                WOLFSSL_MSG("CheckBitString error");
10433
                return WOLFSSL_FATAL_ERROR;
10434
            }
10435
            /* Sanity check */
10436
            if (idx + len != (word32)derSz) {
10437
                WOLFSSL_MSG("unexpected asn1 structure");
10438
                return WOLFSSL_FATAL_ERROR;
10439
            }
10440
            x509->sig.length = 0;
10441
            if (x509->sig.buffer)
10442
                XFREE(x509->sig.buffer, x509->heap, DYNAMIC_TYPE_SIGNATURE);
10443
            x509->sig.buffer = (byte*)XMALLOC(len, x509->heap,
10444
                                              DYNAMIC_TYPE_SIGNATURE);
10445
            if (!x509->sig.buffer) {
10446
                WOLFSSL_MSG("malloc error");
10447
                return WOLFSSL_FATAL_ERROR;
10448
            }
10449
            XMEMCPY(x509->sig.buffer, der + idx, len);
10450
            x509->sig.length = len;
10451
        }
10452
10453
        /* Put in the new certificate encoding into the x509 object. */
10454
        FreeDer(&x509->derCert);
10455
        type = CERT_TYPE;
10456
    #ifdef WOLFSSL_CERT_REQ
10457
        if (req) {
10458
            type = CERTREQ_TYPE;
10459
        }
10460
    #endif
10461
        if (AllocDer(&x509->derCert, derSz, type, NULL) != 0)
10462
            return WOLFSSL_FATAL_ERROR;
10463
        XMEMCPY(x509->derCert->buffer, der, derSz);
10464
        x509->derCert->length = derSz;
10465
10466
        return ret;
10467
    }
10468
10469
10470
    #ifndef WC_MAX_X509_GEN
10471
        /* able to override max size until dynamic buffer created */
10472
        #define WC_MAX_X509_GEN 4096
10473
    #endif
10474
10475
    /* returns the size of signature on success */
10476
    int wolfSSL_X509_sign(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey,
10477
            const WOLFSSL_EVP_MD* md)
10478
    {
10479
        int  ret;
10480
        /* @TODO dynamic set based on expected cert size */
10481
        byte *der = (byte *)XMALLOC(WC_MAX_X509_GEN, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10482
        int  derSz = WC_MAX_X509_GEN;
10483
10484
        WOLFSSL_ENTER("wolfSSL_X509_sign");
10485
10486
        if (x509 == NULL || pkey == NULL || md == NULL) {
10487
            ret = WOLFSSL_FAILURE;
10488
            goto out;
10489
        }
10490
10491
        x509->sigOID = wolfSSL_sigTypeFromPKEY((WOLFSSL_EVP_MD*)md, pkey);
10492
        if ((ret = wolfssl_x509_make_der(x509, 0, der, &derSz, 0)) !=
10493
                WOLFSSL_SUCCESS) {
10494
            WOLFSSL_MSG("Unable to make DER for X509");
10495
            WOLFSSL_LEAVE("wolfSSL_X509_sign", ret);
10496
            (void)ret;
10497
            ret = WOLFSSL_FAILURE;
10498
            goto out;
10499
        }
10500
10501
        ret = wolfSSL_X509_resign_cert(x509, 0, der, WC_MAX_X509_GEN, derSz,
10502
                (WOLFSSL_EVP_MD*)md, pkey);
10503
        if (ret <= 0) {
10504
            WOLFSSL_LEAVE("wolfSSL_X509_sign", ret);
10505
            ret = WOLFSSL_FAILURE;
10506
            goto out;
10507
        }
10508
10509
    out:
10510
        if (der)
10511
            XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10512
10513
        return ret;
10514
    }
10515
10516
#if defined(OPENSSL_EXTRA)
10517
    int wolfSSL_X509_sign_ctx(WOLFSSL_X509 *x509, WOLFSSL_EVP_MD_CTX *ctx)
10518
    {
10519
        WOLFSSL_ENTER("wolfSSL_X509_sign_ctx");
10520
10521
        if (!x509 || !ctx || !ctx->pctx || !ctx->pctx->pkey) {
10522
            WOLFSSL_MSG("Bad parameter");
10523
            return WOLFSSL_FAILURE;
10524
        }
10525
10526
        return wolfSSL_X509_sign(x509, ctx->pctx->pkey, wolfSSL_EVP_MD_CTX_md(ctx));
10527
    }
10528
#endif /* OPENSSL_EXTRA */
10529
#endif /* WOLFSSL_CERT_GEN */
10530
10531
10532
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
10533
    defined(OPENSSL_EXTRA_X509_SMALL) || defined(WOLFSSL_WPAS_SMALL)
10534
/* Converts from NID_* value to wolfSSL value if needed.
10535
 *
10536
 * @param [in] nid  Numeric Id of a domain name component.
10537
 * @return  Domain name tag values - wolfSSL internal values.
10538
 * @return  -1 when nid isn't known.
10539
 */
10540
static int ConvertNIDToWolfSSL(int nid)
10541
{
10542
    switch (nid) {
10543
        case NID_commonName : return ASN_COMMON_NAME;
10544
    #ifdef WOLFSSL_CERT_NAME_ALL
10545
        case NID_name :       return ASN_NAME;
10546
        case NID_givenName:   return ASN_GIVEN_NAME;
10547
        case NID_dnQualifier :   return ASN_DNQUALIFIER;
10548
        case NID_initials:   return ASN_INITIALS;
10549
    #endif /* WOLFSSL_CERT_NAME_ALL */
10550
        case NID_surname :    return ASN_SUR_NAME;
10551
        case NID_countryName: return ASN_COUNTRY_NAME;
10552
        case NID_localityName: return ASN_LOCALITY_NAME;
10553
        case NID_stateOrProvinceName: return ASN_STATE_NAME;
10554
        case NID_streetAddress: return ASN_STREET_ADDR;
10555
        case NID_organizationName: return ASN_ORG_NAME;
10556
        case NID_organizationalUnitName: return ASN_ORGUNIT_NAME;
10557
        case NID_emailAddress: return ASN_EMAIL_NAME;
10558
        case NID_pkcs9_contentType: return ASN_CONTENT_TYPE;
10559
        case NID_serialNumber: return ASN_SERIAL_NUMBER;
10560
        case NID_userId: return ASN_USER_ID;
10561
        case NID_businessCategory: return ASN_BUS_CAT;
10562
        case NID_domainComponent: return ASN_DOMAIN_COMPONENT;
10563
        case NID_postalCode: return ASN_POSTAL_CODE;
10564
        case NID_favouriteDrink: return ASN_FAVOURITE_DRINK;
10565
        default:
10566
            WOLFSSL_MSG("Attribute NID not found");
10567
            return -1;
10568
    }
10569
}
10570
#endif /* OPENSSL_ALL || OPENSSL_EXTRA ||
10571
          OPENSSL_EXTRA_X509_SMALL || WOLFSSL_WPAS_SMALL*/
10572
10573
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
10574
/* This is to convert the x509 name structure into canonical DER format     */
10575
/*  , which has the following rules:                                        */
10576
/*   convert to UTF8                                                        */
10577
/*   convert to lower case                                                  */
10578
/*   multi-spaces collapsed                                                 */
10579
/*   leading SEQUENCE header is skipped                                     */
10580
/* @param  name a pointer to X509_NAME that is to be converted              */
10581
/* @param  out  a pointer to converted data                                 */
10582
/* @return a number of converted bytes, otherwise <=0 error code            */
10583
int wolfSSL_i2d_X509_NAME_canon(WOLFSSL_X509_NAME* name, unsigned char** out)
10584
{
10585
    int  totalBytes = 0, i, idx;
10586
    byte *output, *local = NULL;
10587
#ifdef WOLFSSL_SMALL_STACK
10588
    EncodedName* names = NULL;
10589
#else
10590
    EncodedName  names[MAX_NAME_ENTRIES];
10591
#endif
10592
10593
    if (name == NULL)
10594
        return BAD_FUNC_ARG;
10595
10596
#ifdef WOLFSSL_SMALL_STACK
10597
    names = (EncodedName*)XMALLOC(sizeof(EncodedName) * MAX_NAME_ENTRIES, NULL,
10598
                                                       DYNAMIC_TYPE_TMP_BUFFER);
10599
    if (names == NULL)
10600
        return MEMORY_E;
10601
#endif
10602
10603
    XMEMSET(names, 0, sizeof(EncodedName) * MAX_NAME_ENTRIES);
10604
10605
    for (i = 0; i < MAX_NAME_ENTRIES; i++) {
10606
        WOLFSSL_X509_NAME_ENTRY* entry;
10607
        int ret;
10608
10609
        entry = wolfSSL_X509_NAME_get_entry(name, i);
10610
        if (entry != NULL && entry->set >= 1) {
10611
            const char* nameStr;
10612
            WOLFSSL_ASN1_STRING* data;
10613
            WOLFSSL_ASN1_STRING* cano_data;
10614
10615
            cano_data = wolfSSL_ASN1_STRING_new();
10616
            if (cano_data == NULL) {
10617
                #ifdef WOLFSSL_SMALL_STACK
10618
                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10619
                #endif
10620
                return MEMORY_E;
10621
            }
10622
10623
            data = wolfSSL_X509_NAME_ENTRY_get_data(entry);
10624
            if (data == NULL) {
10625
            #ifdef WOLFSSL_SMALL_STACK
10626
                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10627
            #endif
10628
                wolfSSL_ASN1_STRING_free(cano_data);
10629
                WOLFSSL_MSG("Error getting entry data");
10630
                return WOLFSSL_FATAL_ERROR;
10631
            }
10632
            if (wolfSSL_ASN1_STRING_canon(cano_data, data) != WOLFSSL_SUCCESS) {
10633
            #ifdef WOLFSSL_SMALL_STACK
10634
                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10635
            #endif
10636
                wolfSSL_ASN1_STRING_free(cano_data);
10637
                return WOLFSSL_FAILURE;
10638
            }
10639
            nameStr = (const char*)wolfSSL_ASN1_STRING_data(cano_data);
10640
10641
            ret = wc_EncodeNameCanonical(&names[i], nameStr, CTC_UTF8,
10642
                (byte)ConvertNIDToWolfSSL(entry->nid));
10643
            if (ret < 0) {
10644
            #ifdef WOLFSSL_SMALL_STACK
10645
                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10646
            #endif
10647
                wolfSSL_ASN1_STRING_free(cano_data);
10648
                WOLFSSL_MSG("EncodeName failed");
10649
                return WOLFSSL_FATAL_ERROR;
10650
            }
10651
            totalBytes += ret;
10652
            wolfSSL_ASN1_STRING_free(cano_data);
10653
        }
10654
    }
10655
10656
    if (out == NULL) {
10657
        /* If out is NULL, caller just wants length. */
10658
#ifdef WOLFSSL_SMALL_STACK
10659
        XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10660
#endif
10661
        return totalBytes;
10662
    }
10663
10664
    /* skip header */
10665
    /* check if using buffer passed in */
10666
    if (*out == NULL) {
10667
        *out = local = (unsigned char*)XMALLOC(totalBytes, NULL,
10668
                DYNAMIC_TYPE_OPENSSL);
10669
        if (*out == NULL) {
10670
            return MEMORY_E;
10671
        }
10672
    }
10673
    output = *out;
10674
    idx = 0;
10675
10676
    for (i = 0; i < MAX_NAME_ENTRIES; i++) {
10677
        if (names[i].used) {
10678
            XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
10679
            idx += names[i].totalLen;
10680
        }
10681
    }
10682
10683
#ifdef WOLFSSL_SMALL_STACK
10684
    XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10685
#endif
10686
10687
    /* used existing buffer passed in, so increment pointer */
10688
    if (local == NULL) {
10689
        *out += totalBytes;
10690
    }
10691
    return totalBytes;
10692
}
10693
#endif /* OPENSSL_ALL || OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
10694
10695
#ifdef WOLFSSL_CERT_GEN
10696
/* Guarded by either
10697
 * A) WOLFSSL_WPAS_SMALL is on or
10698
 * B) (OPENSSL_EXTRA or OPENSSL_EXTRA_X509_SMALL) + WOLFSSL_CERT_GEN +
10699
 *    (WOLFSSL_CERT_REQ or WOLFSSL_CERT_EXT or OPENSSL_EXTRA) has been
10700
 *    defined
10701
 */
10702
#if defined(WOLFSSL_WPAS_SMALL) || \
10703
    (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
10704
    defined(WOLFSSL_CERT_GEN) && \
10705
    (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT) || \
10706
     defined(OPENSSL_EXTRA))
10707
10708
/* Converts the x509 name structure into DER format.
10709
 *
10710
 * out  pointer to either a pre setup buffer or a pointer to null for
10711
 *      creating a dynamic buffer. In the case that a pre-existing buffer is
10712
 *      used out will be incremented the size of the DER buffer on success. If
10713
 *      out is NULL, the function returns the necessary output buffer length.
10714
 *
10715
 * returns the size of the buffer on success, or negative value with failure
10716
 */
10717
int wolfSSL_i2d_X509_NAME(WOLFSSL_X509_NAME* name, unsigned char** out)
10718
{
10719
    int  totalBytes = 0, i, idx;
10720
    byte temp[MAX_SEQ_SZ];
10721
    byte *output, *local = NULL;
10722
#ifdef WOLFSSL_SMALL_STACK
10723
    EncodedName* names = NULL;
10724
#else
10725
    EncodedName  names[MAX_NAME_ENTRIES];
10726
#endif
10727
10728
    if (name == NULL)
10729
        return BAD_FUNC_ARG;
10730
10731
#ifdef WOLFSSL_SMALL_STACK
10732
    names = (EncodedName*)XMALLOC(sizeof(EncodedName) * MAX_NAME_ENTRIES, NULL,
10733
                                                       DYNAMIC_TYPE_TMP_BUFFER);
10734
    if (names == NULL)
10735
        return MEMORY_E;
10736
#endif
10737
10738
    XMEMSET(names, 0, sizeof(EncodedName) * MAX_NAME_ENTRIES);
10739
10740
    for (i = 0; i < MAX_NAME_ENTRIES; i++) {
10741
        WOLFSSL_X509_NAME_ENTRY* entry;
10742
        int ret;
10743
10744
        entry = wolfSSL_X509_NAME_get_entry(name, i);
10745
        if (entry != NULL && entry->set >= 1) {
10746
            const char* nameStr;
10747
            int type;
10748
            WOLFSSL_ASN1_STRING* data;
10749
10750
            data = wolfSSL_X509_NAME_ENTRY_get_data(entry);
10751
            if (data == NULL) {
10752
            #ifdef WOLFSSL_SMALL_STACK
10753
                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10754
            #endif
10755
                WOLFSSL_MSG("Error getting entry data");
10756
                return WOLFSSL_FATAL_ERROR;
10757
            }
10758
10759
            nameStr = (const char*)wolfSSL_ASN1_STRING_data(data);
10760
            type    = wolfSSL_ASN1_STRING_type(data);
10761
10762
            switch (type) {
10763
                case MBSTRING_UTF8:
10764
                    type = CTC_UTF8;
10765
                    break;
10766
                case MBSTRING_ASC:
10767
                case V_ASN1_PRINTABLESTRING:
10768
                    type = CTC_PRINTABLE;
10769
                    break;
10770
                default:
10771
                    WOLFSSL_MSG("Unknown encoding type conversion UTF8 by default");
10772
                    type = CTC_UTF8;
10773
            }
10774
            ret = wc_EncodeName(&names[i], nameStr, (char)type,
10775
                (byte)ConvertNIDToWolfSSL(entry->nid));
10776
            if (ret < 0) {
10777
            #ifdef WOLFSSL_SMALL_STACK
10778
                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10779
            #endif
10780
                WOLFSSL_MSG("EncodeName failed");
10781
                return WOLFSSL_FATAL_ERROR;
10782
            }
10783
            totalBytes += ret;
10784
        }
10785
    }
10786
10787
    /* header */
10788
    idx = SetSequence(totalBytes, temp);
10789
    if (totalBytes + idx > ASN_NAME_MAX) {
10790
#ifdef WOLFSSL_SMALL_STACK
10791
        XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10792
#endif
10793
        WOLFSSL_MSG("Total Bytes is greater than ASN_NAME_MAX");
10794
        return BUFFER_E;
10795
    }
10796
10797
    if (out == NULL) {
10798
        /* If out is NULL, caller just wants length. */
10799
        totalBytes += idx;
10800
#ifdef WOLFSSL_SMALL_STACK
10801
        XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10802
#endif
10803
        return totalBytes;
10804
    }
10805
10806
    /* check if using buffer passed in */
10807
    if (*out == NULL) {
10808
        *out = local = (unsigned char*)XMALLOC(totalBytes + idx, name->heap,
10809
                DYNAMIC_TYPE_OPENSSL);
10810
        if (*out == NULL) {
10811
            return MEMORY_E;
10812
        }
10813
    }
10814
    output = *out;
10815
10816
    idx = SetSequence(totalBytes, output);
10817
    totalBytes += idx;
10818
    for (i = 0; i < MAX_NAME_ENTRIES; i++) {
10819
        if (names[i].used) {
10820
            XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
10821
            idx += names[i].totalLen;
10822
        }
10823
    }
10824
10825
#ifdef WOLFSSL_SMALL_STACK
10826
    XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10827
#endif
10828
10829
    /* used existing buffer passed in, so increment pointer */
10830
    if (local == NULL) {
10831
        *out += totalBytes;
10832
    }
10833
    return totalBytes;
10834
}
10835
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
10836
#endif /* WOLFSSL_CERT_GEN */
10837
10838
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) || \
10839
    defined (WOLFSSL_WPAS_SMALL)
10840
10841
    WOLFSSL_X509_NAME *wolfSSL_d2i_X509_NAME(WOLFSSL_X509_NAME **name,
10842
                                             unsigned char **in, long length)
10843
    {
10844
        WOLFSSL_X509_NAME* tmp = NULL;
10845
    #ifdef WOLFSSL_SMALL_STACK
10846
        DecodedCert* cert = NULL;
10847
    #else
10848
        DecodedCert cert[1];
10849
    #endif
10850
10851
        WOLFSSL_ENTER("wolfSSL_d2i_X509_NAME");
10852
10853
        if (!in || !*in || length <= 0) {
10854
            WOLFSSL_MSG("Bad argument");
10855
            return NULL;
10856
        }
10857
10858
    #ifdef WOLFSSL_SMALL_STACK
10859
        cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
10860
                                     DYNAMIC_TYPE_DCERT);
10861
        if (cert == NULL) {
10862
            return NULL;
10863
        }
10864
    #endif
10865
10866
        /* Set the X509_NAME buffer as the input data for cert.
10867
         * in is NOT a full certificate. Just the name. */
10868
        InitDecodedCert(cert, *in, (word32)length, NULL);
10869
10870
        /* Parse the X509 subject name */
10871
        if (GetName(cert, SUBJECT, (int)length) != 0) {
10872
            WOLFSSL_MSG("WOLFSSL_X509_NAME parse error");
10873
            goto cleanup;
10874
        }
10875
10876
        if (!(tmp = wolfSSL_X509_NAME_new_ex(cert->heap))) {
10877
            WOLFSSL_MSG("wolfSSL_X509_NAME_new_ex error");
10878
            goto cleanup;
10879
        }
10880
10881
        if (wolfSSL_X509_NAME_copy((WOLFSSL_X509_NAME*)cert->subjectName,
10882
                    tmp) != WOLFSSL_SUCCESS) {
10883
            wolfSSL_X509_NAME_free(tmp);
10884
            tmp = NULL;
10885
            goto cleanup;
10886
        }
10887
10888
        if (name)
10889
            *name = tmp;
10890
cleanup:
10891
        FreeDecodedCert(cert);
10892
    #ifdef WOLFSSL_SMALL_STACK
10893
        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
10894
    #endif
10895
        return tmp;
10896
    }
10897
#endif /* OPENSSL_EXTRA || OPENSSL_ALL || WOLFSSL_WPAS_SMALL */
10898
10899
10900
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
10901
10902
    /* Compares the two X509 names. If the size of x is larger then y then a
10903
     * positive value is returned if x is smaller a negative value is returned.
10904
     * In the case that the sizes are equal a the value of strcmp between the
10905
     * two names is returned.
10906
     *
10907
     * x First name for comparison
10908
     * y Second name to compare with x
10909
     */
10910
    int wolfSSL_X509_NAME_cmp(const WOLFSSL_X509_NAME* x,
10911
            const WOLFSSL_X509_NAME* y)
10912
    {
10913
        const char* _x;
10914
        const char* _y;
10915
        WOLFSSL_ENTER("wolfSSL_X509_NAME_cmp");
10916
10917
        if (x == NULL || y == NULL) {
10918
            WOLFSSL_MSG("Bad argument passed in");
10919
            return -2;
10920
        }
10921
10922
        if (x == y) {
10923
            return 0; /* match */
10924
        }
10925
10926
        if (x->sz != y->sz) {
10927
            return x->sz - y->sz;
10928
        }
10929
10930
        /*
10931
         * If the name member is not set or is immediately null terminated then
10932
         * compare the staticName member
10933
         */
10934
        _x = (x->name && *x->name) ? x->name : x->staticName;
10935
        _y = (y->name && *y->name) ? y->name : y->staticName;
10936
10937
        return XSTRNCMP(_x, _y, x->sz); /* y sz is the same */
10938
    }
10939
10940
#ifndef NO_BIO
10941
10942
    static WOLFSSL_X509 *loadX509orX509REQFromPemBio(WOLFSSL_BIO *bp,
10943
            WOLFSSL_X509 **x, wc_pem_password_cb *cb, void *u, int type)
10944
    {
10945
        WOLFSSL_X509* x509 = NULL;
10946
#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
10947
        unsigned char* pem = NULL;
10948
        int pemSz;
10949
        long  i = 0, l, footerSz;
10950
        const char* footer = NULL;
10951
10952
        WOLFSSL_ENTER("loadX509orX509REQFromPemBio");
10953
10954
        if (bp == NULL || (type != CERT_TYPE && type != CERTREQ_TYPE)) {
10955
            WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_X509", BAD_FUNC_ARG);
10956
            return NULL;
10957
        }
10958
10959
        if ((l = wolfSSL_BIO_get_len(bp)) <= 0) {
10960
            /* No certificate in buffer */
10961
#if defined (WOLFSSL_HAPROXY)
10962
            WOLFSSL_ERROR(PEM_R_NO_START_LINE);
10963
#else
10964
            WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
10965
#endif
10966
            return NULL;
10967
        }
10968
10969
        pemSz = (int)l;
10970
        pem   = (unsigned char*)XMALLOC(pemSz, 0, DYNAMIC_TYPE_PEM);
10971
        if (pem == NULL)
10972
            return NULL;
10973
        XMEMSET(pem, 0, pemSz);
10974
10975
        i = 0;
10976
        if (wc_PemGetHeaderFooter(type, NULL, &footer) != 0) {
10977
            XFREE(pem, 0, DYNAMIC_TYPE_PEM);
10978
            return NULL;
10979
        }
10980
        footerSz = (long)XSTRLEN(footer);
10981
10982
        /* TODO: Inefficient
10983
         * reading in one byte at a time until see the footer
10984
         */
10985
        while ((l = wolfSSL_BIO_read(bp, (char *)&pem[i], 1)) == 1) {
10986
            i++;
10987
            if (i > footerSz && XMEMCMP((char *)&pem[i-footerSz], footer,
10988
                    footerSz) == 0) {
10989
                if (wolfSSL_BIO_read(bp, (char *)&pem[i], 1) == 1) {
10990
                    /* attempt to read newline following footer */
10991
                    i++;
10992
                    if (pem[i-1] == '\r') {
10993
                        /* found \r , Windows line ending is \r\n so try to read one
10994
                         * more byte for \n, ignoring return value */
10995
                        (void)wolfSSL_BIO_read(bp, (char *)&pem[i++], 1);
10996
                    }
10997
                }
10998
                break;
10999
            }
11000
        }
11001
        if (l == 0)
11002
            WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
11003
        if (i > pemSz) {
11004
            WOLFSSL_MSG("Error parsing PEM");
11005
        }
11006
        else {
11007
            pemSz = (int)i;
11008
        #ifdef WOLFSSL_CERT_REQ
11009
            if (type == CERTREQ_TYPE)
11010
                x509 = wolfSSL_X509_REQ_load_certificate_buffer(pem, pemSz,
11011
                                                          WOLFSSL_FILETYPE_PEM);
11012
            else
11013
        #endif
11014
                x509 = wolfSSL_X509_load_certificate_buffer(pem, pemSz,
11015
                                                          WOLFSSL_FILETYPE_PEM);
11016
        }
11017
11018
        if (x != NULL) {
11019
            *x = x509;
11020
        }
11021
11022
        XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
11023
11024
#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
11025
        (void)bp;
11026
        (void)x;
11027
        (void)cb;
11028
        (void)u;
11029
11030
        return x509;
11031
    }
11032
11033
11034
    WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x,
11035
                                            wc_pem_password_cb *cb, void *u)
11036
    {
11037
        return loadX509orX509REQFromPemBio(bp, x, cb, u, CERT_TYPE);
11038
    }
11039
11040
#ifdef WOLFSSL_CERT_REQ
11041
    WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_REQ(WOLFSSL_BIO *bp, WOLFSSL_X509 **x,
11042
                                                wc_pem_password_cb *cb, void *u)
11043
    {
11044
        return loadX509orX509REQFromPemBio(bp, x, cb, u, CERTREQ_TYPE);
11045
    }
11046
11047
#ifndef NO_FILESYSTEM
11048
    WOLFSSL_X509* wolfSSL_PEM_read_X509_REQ(XFILE fp, WOLFSSL_X509** x,
11049
                                            wc_pem_password_cb* cb, void* u)
11050
    {
11051
        int err = 0;
11052
        WOLFSSL_X509* ret = NULL;
11053
        WOLFSSL_BIO* bio = NULL;
11054
11055
        WOLFSSL_ENTER("wolfSSL_PEM_read_X509_REQ");
11056
11057
        if (fp == XBADFILE) {
11058
            WOLFSSL_MSG("Invalid file.");
11059
            err = 1;
11060
        }
11061
11062
        if (err == 0) {
11063
            bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
11064
            if (bio == NULL) {
11065
                WOLFSSL_MSG("Failed to create new BIO with input file.");
11066
                err = 1;
11067
            }
11068
        }
11069
        if (err == 0 && wolfSSL_BIO_set_fp(bio, fp, BIO_CLOSE)
11070
                != WOLFSSL_SUCCESS) {
11071
            WOLFSSL_MSG("Failed to set BIO file pointer.");
11072
            err = 1;
11073
        }
11074
        if (err == 0) {
11075
            ret = wolfSSL_PEM_read_bio_X509_REQ(bio, x, cb, u);
11076
        }
11077
11078
        if (bio != NULL) {
11079
            wolfSSL_BIO_free(bio);
11080
        }
11081
11082
        return ret;
11083
    }
11084
#endif /* !NO_FILESYSTEM */
11085
#endif /* WOLFSSL_CERT_REQ */
11086
11087
    WOLFSSL_X509_CRL *wolfSSL_PEM_read_bio_X509_CRL(WOLFSSL_BIO *bp,
11088
            WOLFSSL_X509_CRL **x, wc_pem_password_cb *cb, void *u)
11089
    {
11090
#if defined(WOLFSSL_PEM_TO_DER) && defined(HAVE_CRL)
11091
        unsigned char* pem = NULL;
11092
        int pemSz;
11093
        int derSz;
11094
        DerBuffer* der = NULL;
11095
        WOLFSSL_X509_CRL* crl = NULL;
11096
11097
        if ((pemSz = wolfSSL_BIO_get_len(bp)) <= 0) {
11098
            goto err;
11099
        }
11100
11101
        pem = (unsigned char*)XMALLOC(pemSz, 0, DYNAMIC_TYPE_PEM);
11102
        if (pem == NULL) {
11103
            goto err;
11104
        }
11105
11106
        if (wolfSSL_BIO_read(bp, pem, pemSz) != pemSz) {
11107
            goto err;
11108
        }
11109
11110
        if((PemToDer(pem, pemSz, CRL_TYPE, &der, NULL, NULL, NULL)) < 0) {
11111
            goto err;
11112
        }
11113
        derSz = der->length;
11114
        if((crl = wolfSSL_d2i_X509_CRL(x, der->buffer, derSz)) == NULL) {
11115
            goto err;
11116
        }
11117
11118
err:
11119
        if(pem != NULL) {
11120
            XFREE(pem, 0, DYNAMIC_TYPE_PEM);
11121
        }
11122
        if(der != NULL) {
11123
            FreeDer(&der);
11124
        }
11125
11126
        (void)cb;
11127
        (void)u;
11128
11129
        return crl;
11130
#else
11131
        (void)bp;
11132
        (void)x;
11133
        (void)cb;
11134
        (void)u;
11135
11136
        return NULL;
11137
#endif
11138
    }
11139
11140
#endif /* !NO_BIO */
11141
11142
#if !defined(NO_FILESYSTEM)
11143
    static void* wolfSSL_PEM_read_X509_ex(XFILE fp, void **x,
11144
        wc_pem_password_cb *cb, void *u, int type)
11145
    {
11146
        unsigned char* pem = NULL;
11147
        int pemSz;
11148
        long i = 0, l;
11149
        void *newx509;
11150
        int derSz;
11151
        DerBuffer* der = NULL;
11152
11153
        WOLFSSL_ENTER("wolfSSL_PEM_read_X509");
11154
11155
        if (fp == XBADFILE) {
11156
            WOLFSSL_LEAVE("wolfSSL_PEM_read_X509", BAD_FUNC_ARG);
11157
            return NULL;
11158
        }
11159
        /* Read cert from file */
11160
        i = XFTELL(fp);
11161
        if (i < 0) {
11162
            WOLFSSL_LEAVE("wolfSSL_PEM_read_X509", BAD_FUNC_ARG);
11163
            return NULL;
11164
        }
11165
11166
        if (XFSEEK(fp, 0, XSEEK_END) != 0)
11167
            return NULL;
11168
        l = XFTELL(fp);
11169
        if (l < 0)
11170
            return NULL;
11171
        if (XFSEEK(fp, i, SEEK_SET) != 0)
11172
            return NULL;
11173
        pemSz = (int)(l - i);
11174
11175
        /* check calculated length */
11176
        if (pemSz > MAX_WOLFSSL_FILE_SIZE || pemSz < 0) {
11177
            WOLFSSL_MSG("PEM_read_X509_ex file size error");
11178
            return NULL;
11179
        }
11180
11181
        /* allocate pem buffer */
11182
        pem = (unsigned char*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_PEM);
11183
        if (pem == NULL)
11184
            return NULL;
11185
11186
        if ((int)XFREAD((char *)pem, 1, pemSz, fp) != pemSz)
11187
            goto err_exit;
11188
11189
        switch (type) {
11190
            case CERT_TYPE:
11191
                newx509 = (void *)wolfSSL_X509_load_certificate_buffer(pem,
11192
                    pemSz, WOLFSSL_FILETYPE_PEM);
11193
                break;
11194
11195
        #ifdef HAVE_CRL
11196
            case CRL_TYPE:
11197
                if ((PemToDer(pem, pemSz, CRL_TYPE, &der, NULL, NULL, NULL)) < 0)
11198
                    goto err_exit;
11199
                derSz = der->length;
11200
                newx509 = (void*)wolfSSL_d2i_X509_CRL((WOLFSSL_X509_CRL **)x,
11201
                    (const unsigned char *)der->buffer, derSz);
11202
                if (newx509 == NULL)
11203
                    goto err_exit;
11204
                FreeDer(&der);
11205
                break;
11206
        #endif
11207
11208
            default:
11209
                goto err_exit;
11210
        }
11211
        if (x != NULL) {
11212
            *x = newx509;
11213
        }
11214
        XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
11215
        return newx509;
11216
11217
    err_exit:
11218
        if (pem != NULL)
11219
            XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
11220
        if (der != NULL)
11221
            FreeDer(&der);
11222
11223
        /* unused */
11224
        (void)cb;
11225
        (void)u;
11226
        (void)derSz;
11227
11228
        return NULL;
11229
    }
11230
11231
    WOLFSSL_API WOLFSSL_X509* wolfSSL_PEM_read_X509(XFILE fp, WOLFSSL_X509 **x,
11232
                                                    wc_pem_password_cb *cb,
11233
                                                    void *u)
11234
    {
11235
        return (WOLFSSL_X509* )wolfSSL_PEM_read_X509_ex(fp, (void **)x, cb, u, CERT_TYPE);
11236
    }
11237
11238
#if defined(HAVE_CRL)
11239
    WOLFSSL_API WOLFSSL_X509_CRL* wolfSSL_PEM_read_X509_CRL(XFILE fp, WOLFSSL_X509_CRL **crl,
11240
                                                    wc_pem_password_cb *cb, void *u)
11241
    {
11242
        return (WOLFSSL_X509_CRL* )wolfSSL_PEM_read_X509_ex(fp, (void **)crl, cb, u, CRL_TYPE);
11243
    }
11244
#endif
11245
11246
#ifdef WOLFSSL_CERT_GEN
11247
#ifndef NO_BIO
11248
    int wolfSSL_PEM_write_X509(XFILE fp, WOLFSSL_X509* x)
11249
    {
11250
        int ret;
11251
        WOLFSSL_BIO* bio;
11252
11253
        if (x == NULL)
11254
            return 0;
11255
11256
        bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
11257
        if (bio == NULL)
11258
            return 0;
11259
11260
        if (wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS) {
11261
            wolfSSL_BIO_free(bio);
11262
            bio = NULL;
11263
        }
11264
11265
        ret = wolfSSL_PEM_write_bio_X509(bio, x);
11266
11267
        if (bio != NULL)
11268
            wolfSSL_BIO_free(bio);
11269
11270
        return ret;
11271
    }
11272
#endif /* !NO_BIO */
11273
#endif /* WOLFSSL_CERT_GEN */
11274
#endif /* !NO_FILESYSTEM */
11275
11276
#endif /* OPENSSL_EXTRA || OPENSSL_ALL */
11277
#ifdef OPENSSL_ALL
11278
11279
#ifndef NO_BIO
11280
    /* create and return a new WOLFSSL_X509_PKEY structure or NULL on failure */
11281
    static WOLFSSL_X509_PKEY* wolfSSL_X509_PKEY_new(void* heap)
11282
    {
11283
        WOLFSSL_X509_PKEY* ret;
11284
11285
        ret = (WOLFSSL_X509_PKEY*)XMALLOC(sizeof(WOLFSSL_X509_PKEY), heap,
11286
            DYNAMIC_TYPE_KEY);
11287
        if (ret != NULL) {
11288
            XMEMSET(ret, 0, sizeof(WOLFSSL_X509_PKEY));
11289
            ret->heap = heap;
11290
        }
11291
        return ret;
11292
    }
11293
#endif /* !NO_BIO */
11294
11295
11296
    /* free up all memory used by "xPkey" passed in */
11297
    static void wolfSSL_X509_PKEY_free(WOLFSSL_X509_PKEY* xPkey)
11298
    {
11299
        if (xPkey != NULL) {
11300
            wolfSSL_EVP_PKEY_free(xPkey->dec_pkey);
11301
            XFREE(xPkey, xPkey->heap, DYNAMIC_TYPE_KEY);
11302
        }
11303
    }
11304
11305
11306
#ifndef NO_BIO
11307
11308
#define PEM_COMPARE_HEADER(start, end, header) \
11309
        ((end) - (start) == XSTR_SIZEOF(header) && XMEMCMP(start, header, \
11310
                XSTR_SIZEOF(header)) == 0)
11311
11312
    /**
11313
     * This read one structure from bio and returns the read structure
11314
     * in the appropriate output parameter (x509, crl, x_pkey). The
11315
     * output parameters must be set to NULL.
11316
     * @param bio    Input for reading structures
11317
     * @param cb     Password callback
11318
     * @param x509   Output
11319
     * @param crl    Output
11320
     * @param x_pkey Output
11321
     * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE otherwise
11322
     */
11323
    static int wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio(
11324
            WOLFSSL_BIO* bio, wc_pem_password_cb* cb, WOLFSSL_X509** x509,
11325
            WOLFSSL_X509_CRL** crl, WOLFSSL_X509_PKEY** x_pkey)
11326
    {
11327
11328
#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
11329
        char* pem = NULL;
11330
        long  i = pem_struct_min_sz, l;
11331
        const char* header = NULL;
11332
        const char* headerEnd = NULL;
11333
        const char* footer = NULL;
11334
        const char* footerEnd = NULL;
11335
    #ifdef HAVE_CRL
11336
        DerBuffer* der = NULL;
11337
    #endif
11338
        WOLFSSL_BIO* pemBio = NULL;
11339
11340
        if (!bio || !x509 || *x509 || !crl || *crl || !x_pkey || *x_pkey) {
11341
            WOLFSSL_MSG("Bad input parameter or output parameters "
11342
                        "not set to a NULL value.");
11343
            return WOLFSSL_FAILURE;
11344
        }
11345
11346
        if ((l = wolfSSL_BIO_get_len(bio)) <= 0) {
11347
            /* No certificate in buffer */
11348
            WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
11349
            return WOLFSSL_FAILURE;
11350
        }
11351
11352
        pem = (char*)XMALLOC(l, 0, DYNAMIC_TYPE_PEM);
11353
        if (pem == NULL)
11354
            return WOLFSSL_FAILURE;
11355
11356
        if (wolfSSL_BIO_read(bio, &pem[0], pem_struct_min_sz) !=
11357
                pem_struct_min_sz) {
11358
            WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
11359
            goto err;
11360
        }
11361
11362
        /* Read the header and footer */
11363
        while (i < l && wolfSSL_BIO_read(bio, &pem[i], 1) == 1) {
11364
            i++;
11365
            if (!header) {
11366
                header = XSTRNSTR(pem, "-----BEGIN ", (unsigned int)i);
11367
            }
11368
            else if (!headerEnd) {
11369
                headerEnd = XSTRNSTR(header + XSTR_SIZEOF("-----BEGIN "),
11370
                        "-----",
11371
                        (unsigned int)
11372
                        (i - (header + XSTR_SIZEOF("-----BEGIN ") - pem)));
11373
                if (headerEnd) {
11374
                    headerEnd += XSTR_SIZEOF("-----");
11375
                    /* Read in the newline */
11376
                    if (wolfSSL_BIO_read(bio, &pem[i], 1) != 1) {
11377
                        WOLFSSL_MSG("wolfSSL_BIO_read error");
11378
                        goto err;
11379
                    }
11380
                    i++;
11381
                    if (*headerEnd != '\n' && *headerEnd != '\r') {
11382
                        WOLFSSL_MSG("Missing newline after header");
11383
                        goto err;
11384
                    }
11385
                }
11386
            }
11387
            else if (!footer) {
11388
                footer = XSTRNSTR(headerEnd, "-----END ",
11389
                        (unsigned int)(i - (headerEnd - pem)));
11390
            }
11391
            else if (!footerEnd) {
11392
                footerEnd = XSTRNSTR(footer + XSTR_SIZEOF("-----"),
11393
                        "-----", (unsigned int)(i -
11394
                            (footer + XSTR_SIZEOF("-----") - pem)));
11395
                if (footerEnd) {
11396
                    footerEnd += XSTR_SIZEOF("-----");
11397
                    /* Now check that footer matches header */
11398
                    if ((headerEnd - (header + XSTR_SIZEOF("-----BEGIN "))) ==
11399
                        (footerEnd - (footer + XSTR_SIZEOF("-----END "))) &&
11400
                        XMEMCMP(header + XSTR_SIZEOF("-----BEGIN "),
11401
                                footer + XSTR_SIZEOF("-----END "),
11402
                        headerEnd - (header + XSTR_SIZEOF("-----BEGIN ")))
11403
                            != 0) {
11404
                        WOLFSSL_MSG("Header and footer don't match");
11405
                        goto err;
11406
                    }
11407
                    /* header and footer match */
11408
                    break;
11409
                }
11410
            }
11411
        }
11412
        if (!footerEnd) {
11413
            /* Only check footerEnd since it is set last */
11414
            WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
11415
            goto err;
11416
        }
11417
        else {
11418
            if (PEM_COMPARE_HEADER(header, headerEnd,
11419
                    "-----BEGIN CERTIFICATE-----")) {
11420
                /* We have a certificate */
11421
                WOLFSSL_MSG("Parsing x509 cert");
11422
                *x509 = wolfSSL_X509_load_certificate_buffer(
11423
                        (const unsigned char*) header,
11424
                        (int)(footerEnd - header), WOLFSSL_FILETYPE_PEM);
11425
                if (!*x509) {
11426
                    WOLFSSL_MSG("wolfSSL_X509_load_certificate_buffer error");
11427
                    goto err;
11428
                }
11429
            }
11430
    #ifdef HAVE_CRL
11431
            else if (PEM_COMPARE_HEADER(header, headerEnd,
11432
                        "-----BEGIN X509 CRL-----")) {
11433
                /* We have a crl */
11434
                WOLFSSL_MSG("Parsing crl");
11435
                if((PemToDer((const unsigned char*) header, footerEnd - header,
11436
                        CRL_TYPE, &der, NULL, NULL, NULL)) < 0) {
11437
                    WOLFSSL_MSG("PemToDer error");
11438
                    goto err;
11439
                }
11440
                *crl = wolfSSL_d2i_X509_CRL(NULL, der->buffer, der->length);
11441
                if (!*crl) {
11442
                    WOLFSSL_MSG("wolfSSL_d2i_X509_CRL error");
11443
                    goto err;
11444
                }
11445
            }
11446
    #endif
11447
            else {
11448
                WOLFSSL_MSG("Parsing x509 key");
11449
11450
                if (!(*x_pkey = wolfSSL_X509_PKEY_new(NULL))) {
11451
                    WOLFSSL_MSG("wolfSSL_X509_PKEY_new error");
11452
                    goto err;
11453
                }
11454
11455
                if (!(pemBio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()))) {
11456
                    WOLFSSL_MSG("wolfSSL_BIO_new error");
11457
                    goto err;
11458
                }
11459
11460
                if (wolfSSL_BIO_write(pemBio, header,
11461
                        (int)(footerEnd - header)) != footerEnd - header) {
11462
                    WOLFSSL_MSG("wolfSSL_BIO_new error");
11463
                    goto err;
11464
                }
11465
11466
                if (wolfSSL_PEM_read_bio_PrivateKey(pemBio,
11467
                        &(*x_pkey)->dec_pkey, cb, NULL) == NULL) {
11468
                    WOLFSSL_MSG("wolfSSL_PEM_read_bio_PrivateKey error");
11469
                    goto err;
11470
                }
11471
11472
                wolfSSL_BIO_free(pemBio);
11473
            }
11474
        }
11475
11476
        XFREE(pem, 0, DYNAMIC_TYPE_PEM);
11477
    #ifdef HAVE_CRL
11478
        if (der)
11479
            FreeDer(&der);
11480
    #endif
11481
        return WOLFSSL_SUCCESS;
11482
err:
11483
        if (pem)
11484
            XFREE(pem, 0, DYNAMIC_TYPE_PEM);
11485
    #ifdef HAVE_CRL
11486
        if (der)
11487
            FreeDer(&der);
11488
    #endif
11489
        if (*x_pkey) {
11490
            wolfSSL_X509_PKEY_free(*x_pkey);
11491
            *x_pkey = NULL;
11492
        }
11493
        if (pemBio)
11494
            wolfSSL_BIO_free(pemBio);
11495
        return WOLFSSL_FAILURE;
11496
#else /* ! (WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM) */
11497
        return WOLFSSL_FAILURE;
11498
#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
11499
    }
11500
11501
#ifndef NO_FILESYSTEM
11502
    WOLF_STACK_OF(WOLFSSL_X509_INFO)* wolfSSL_PEM_X509_INFO_read(
11503
            XFILE fp, WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
11504
            pem_password_cb* cb, void* u)
11505
    {
11506
        WOLFSSL_BIO* fileBio = wolfSSL_BIO_new_fp(fp, BIO_NOCLOSE);
11507
        WOLF_STACK_OF(WOLFSSL_X509_INFO)* ret = NULL;
11508
11509
        WOLFSSL_ENTER("wolfSSL_PEM_X509_INFO_read");
11510
        if (fileBio != NULL) {
11511
            ret = wolfSSL_PEM_X509_INFO_read_bio(fileBio, sk, cb, u);
11512
            wolfSSL_BIO_free(fileBio);
11513
        }
11514
        return ret;
11515
    }
11516
#endif /* !NO_FILESYSTEM */
11517
11518
    /*
11519
     * bio WOLFSSL_BIO to read certificates from
11520
     * sk  possible stack to push more X509_INFO structs to. Can be NULL
11521
     * cb  callback password for encrypted PEM certificates
11522
     * u   user input such as password
11523
     *
11524
     * returns stack on success and NULL or default stack passed in on fail
11525
     */
11526
    WOLF_STACK_OF(WOLFSSL_X509_INFO)* wolfSSL_PEM_X509_INFO_read_bio(
11527
        WOLFSSL_BIO* bio, WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
11528
        wc_pem_password_cb* cb, void* u)
11529
    {
11530
        WOLF_STACK_OF(WOLFSSL_X509_INFO)* localSk = NULL;
11531
        int ret = WOLFSSL_SUCCESS;
11532
        WOLFSSL_X509_INFO* current = NULL;
11533
        WOLFSSL_X509*      x509 = NULL;
11534
        WOLFSSL_X509_CRL*  crl  = NULL;
11535
        WOLFSSL_X509_PKEY* x_pkey = NULL;
11536
11537
        (void)u;
11538
11539
        WOLFSSL_ENTER("wolfSSL_PEM_X509_INFO_read_bio");
11540
11541
        /* attempt to use passed in stack or create a new one */
11542
        if (sk != NULL) {
11543
            localSk = sk;
11544
        }
11545
        else {
11546
            localSk = wolfSSL_sk_X509_INFO_new_null();
11547
        }
11548
        if (localSk == NULL) {
11549
            WOLFSSL_LEAVE("wolfSSL_PEM_X509_INFO_read_bio",
11550
                    MEMORY_E);
11551
            return NULL;
11552
        }
11553
11554
        /* parse through BIO and push new info's found onto stack */
11555
        while (1) {
11556
            x509 = NULL;
11557
            crl  = NULL;
11558
            x_pkey = NULL;
11559
11560
            if (wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio(bio, cb,
11561
                    &x509, &crl, &x_pkey) == WOLFSSL_SUCCESS) {
11562
                if (current == NULL ||
11563
                        (x509 && current->x509) ||
11564
                        (crl && current->crl) ||
11565
                        (x_pkey && current->x_pkey)) {
11566
                    /* Need to create new current since existing one already
11567
                     * has the member filled or this is the first successful
11568
                     * read. */
11569
                    current = wolfSSL_X509_INFO_new();
11570
                    if (current == NULL) {
11571
                        ret = MEMORY_E;
11572
                        break;
11573
                    }
11574
                    if (wolfSSL_sk_X509_INFO_push(localSk, current) !=
11575
                            WOLFSSL_SUCCESS) {
11576
                        wolfSSL_X509_INFO_free(current);
11577
                        current = NULL;
11578
                        ret = WOLFSSL_FAILURE;
11579
                        break;
11580
                    }
11581
                }
11582
11583
                if (x509) {
11584
                    current->x509 = x509;
11585
                }
11586
                else if (crl) {
11587
                    current->crl = crl;
11588
                }
11589
                else if (x_pkey) {
11590
                    current->x_pkey = x_pkey;
11591
                }
11592
                else {
11593
                    WOLFSSL_MSG("No output parameters set");
11594
                    ret = WOLFSSL_FAILURE;
11595
                    break;
11596
                }
11597
            }
11598
            else {
11599
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
11600
                unsigned long err;
11601
                CLEAR_ASN_NO_PEM_HEADER_ERROR(err);
11602
                if (ERR_GET_LIB(err) != ERR_LIB_PEM ||
11603
                    ERR_GET_REASON(err) != PEM_R_NO_START_LINE) {
11604
                    ret = WOLFSSL_FAILURE;
11605
                }
11606
#else
11607
                if (wolfSSL_sk_X509_INFO_num(localSk) > 0) {
11608
                    WOLFSSL_MSG("At least one X509_INFO object on stack."
11609
                                "Assuming error means EOF or no more PEM"
11610
                                "headers found.");
11611
                }
11612
                else {
11613
                    ret = WOLFSSL_FAILURE;
11614
                }
11615
#endif
11616
                break;
11617
            }
11618
        }
11619
        if (ret != WOLFSSL_SUCCESS ||
11620
                wolfSSL_sk_X509_INFO_num(localSk) == 0) {
11621
            /* current should always be pushed onto the localsk stack at this
11622
             * point. The only case when it isn't is when
11623
             * wolfSSL_sk_X509_INFO_push fails but in that case the current
11624
             * free is handled inside the loop. */
11625
            if (localSk != sk) {
11626
                wolfSSL_sk_pop_free(localSk, NULL);
11627
            }
11628
            wolfSSL_X509_free(x509);
11629
#ifdef HAVE_CRL
11630
            wolfSSL_X509_CRL_free(crl);
11631
#endif
11632
            wolfSSL_X509_PKEY_free(x_pkey);
11633
            localSk = NULL;
11634
        }
11635
        WOLFSSL_LEAVE("wolfSSL_PEM_X509_INFO_read_bio", ret);
11636
        return localSk;
11637
    }
11638
#endif /* !NO_BIO */
11639
#endif /* OPENSSL_ALL */
11640
11641
    void wolfSSL_X509_NAME_ENTRY_free(WOLFSSL_X509_NAME_ENTRY* ne)
11642
    {
11643
        WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_free");
11644
        if (ne != NULL) {
11645
            wolfSSL_ASN1_OBJECT_free(ne->object);
11646
            if (ne->value != NULL) {
11647
                wolfSSL_ASN1_STRING_free(ne->value);
11648
            }
11649
            XFREE(ne, NULL, DYNAMIC_TYPE_NAME_ENTRY);
11650
        }
11651
    }
11652
11653
11654
    WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_new(void)
11655
    {
11656
        WOLFSSL_X509_NAME_ENTRY* ne;
11657
11658
        ne = (WOLFSSL_X509_NAME_ENTRY*)XMALLOC(sizeof(WOLFSSL_X509_NAME_ENTRY),
11659
                NULL, DYNAMIC_TYPE_NAME_ENTRY);
11660
        if (ne != NULL) {
11661
            XMEMSET(ne, 0, sizeof(WOLFSSL_X509_NAME_ENTRY));
11662
        }
11663
11664
        return ne;
11665
    }
11666
11667
    static void wolfssl_x509_name_entry_set(WOLFSSL_X509_NAME_ENTRY* ne,
11668
        int nid, int type, const unsigned char *data, int dataSz)
11669
    {
11670
        WOLFSSL_ASN1_OBJECT* object;
11671
11672
        ne->nid = nid;
11673
        /* Reuse the object if already available. */
11674
        object = wolfSSL_OBJ_nid2obj_ex(nid, ne->object);
11675
        if (object != NULL) {
11676
            /* Set the object when no error. */
11677
            ne->object = object;
11678
        }
11679
        ne->value = wolfSSL_ASN1_STRING_type_new(type);
11680
        if (ne->value != NULL) {
11681
            if (wolfSSL_ASN1_STRING_set(ne->value, (const void*)data,
11682
                                            dataSz) == WOLFSSL_SUCCESS) {
11683
                ne->set = 1;
11684
            }
11685
            else {
11686
                /* Free the ASN1_STRING if it is not set. */
11687
                wolfSSL_ASN1_STRING_free(ne->value);
11688
                ne->value = NULL;
11689
            }
11690
        }
11691
    }
11692
11693
    /* Create a new WOLFSSL_X509_NAME_ENTRY structure based on the text passed
11694
     * in. Returns NULL on failure */
11695
    WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_create_by_txt(
11696
            WOLFSSL_X509_NAME_ENTRY **neIn, const char *txt, int type,
11697
            const unsigned char *data, int dataSz)
11698
    {
11699
        int nid = -1;
11700
        WOLFSSL_X509_NAME_ENTRY* ne = NULL;
11701
11702
        WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_create_by_txt");
11703
11704
        if (txt == NULL) {
11705
            return NULL;
11706
        }
11707
11708
        if (neIn != NULL) {
11709
            ne = *neIn;
11710
        }
11711
11712
        nid = wolfSSL_OBJ_txt2nid(txt);
11713
        if (nid == NID_undef) {
11714
            WOLFSSL_MSG("Unable to find text");
11715
            ne = NULL;
11716
        }
11717
        else {
11718
            if (ne == NULL) {
11719
                ne = wolfSSL_X509_NAME_ENTRY_new();
11720
                if (ne == NULL) {
11721
                    return NULL;
11722
                }
11723
            }
11724
11725
            wolfssl_x509_name_entry_set(ne, nid, type, data, dataSz);
11726
        }
11727
11728
        return ne;
11729
    }
11730
11731
11732
    /* Creates a new entry given the NID, type, and data
11733
     * "dataSz" is number of bytes in data, if set to -1 then XSTRLEN is used
11734
     * "out" can be used to store the new entry data in an existing structure
11735
     *       if NULL then a new WOLFSSL_X509_NAME_ENTRY structure is created
11736
     * returns a pointer to WOLFSSL_X509_NAME_ENTRY on success and NULL on fail
11737
     */
11738
    WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_create_by_NID(
11739
            WOLFSSL_X509_NAME_ENTRY** out, int nid, int type,
11740
            const unsigned char* data, int dataSz)
11741
    {
11742
        WOLFSSL_X509_NAME_ENTRY* ne;
11743
11744
#ifdef WOLFSSL_DEBUG_OPENSSL
11745
        WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_create_by_NID");
11746
#endif
11747
11748
        if (!data) {
11749
            WOLFSSL_MSG("Bad parameter");
11750
            return NULL;
11751
        }
11752
11753
        if (out == NULL || *out == NULL) {
11754
            ne = wolfSSL_X509_NAME_ENTRY_new();
11755
            if (ne == NULL) {
11756
                return NULL;
11757
            }
11758
            if (out != NULL) {
11759
                *out = ne;
11760
            }
11761
        }
11762
        else {
11763
            ne = *out;
11764
        }
11765
11766
        wolfssl_x509_name_entry_set(ne, nid, type, data, dataSz);
11767
11768
        return ne;
11769
    }
11770
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
11771
11772
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
11773
    defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
11774
    defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
11775
    defined(HAVE_POCO_LIB) || defined(WOLFSSL_HAPROXY)
11776
WOLFSSL_ASN1_OBJECT* wolfSSL_X509_NAME_ENTRY_get_object(
11777
    WOLFSSL_X509_NAME_ENTRY *ne)
11778
{
11779
    WOLFSSL_ASN1_OBJECT* object = NULL;
11780
11781
#ifdef WOLFSSL_DEBUG_OPENSSL
11782
    WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_get_object");
11783
#endif
11784
11785
    if (ne != NULL) {
11786
        /* Create object from nid - reuse existing object if possible. */
11787
        object = wolfSSL_OBJ_nid2obj_ex(ne->nid, ne->object);
11788
        if (object != NULL) {
11789
            /* Set the object when no error. */
11790
            ne->object = object;
11791
        }
11792
    }
11793
11794
    return object;
11795
}
11796
#endif /* OPENSSL_ALL || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE ||
11797
        * HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_POCO_LIB || WOLFSSL_HAPROXY */
11798
11799
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
11800
    /* add all entry of type "nid" to the buffer "fullName" and advance "idx"
11801
     * since number of entries is small, a brute force search is used here
11802
     * returns the number of entries added
11803
     */
11804
    static int AddAllEntry(WOLFSSL_X509_NAME* name, char* fullName,
11805
            int fullNameSz, int* idx)
11806
    {
11807
        int i;
11808
        int ret = 0;
11809
11810
        for (i = 0; i < MAX_NAME_ENTRIES; i++) {
11811
            if (name->entry[i].set) {
11812
                WOLFSSL_X509_NAME_ENTRY* e;
11813
                WOLFSSL_ASN1_OBJECT* obj;
11814
11815
                int sz;
11816
                unsigned char* data;
11817
11818
                e = &name->entry[i];
11819
                obj = wolfSSL_X509_NAME_ENTRY_get_object(e);
11820
                if (obj == NULL) {
11821
                    return BAD_FUNC_ARG;
11822
                }
11823
11824
                XMEMCPY(fullName + *idx, "/", 1); *idx = *idx + 1;
11825
                sz = (int)XSTRLEN(obj->sName);
11826
                XMEMCPY(fullName + *idx, obj->sName, sz);
11827
                *idx += sz;
11828
                XMEMCPY(fullName + *idx, "=", 1); *idx = *idx + 1;
11829
11830
                data = wolfSSL_ASN1_STRING_data(e->value);
11831
                if (data != NULL) {
11832
                    sz = (int)XSTRLEN((const char*)data);
11833
                    XMEMCPY(fullName + *idx, data, sz);
11834
                    *idx += sz;
11835
                }
11836
11837
                ret++;
11838
            }
11839
        }
11840
        (void)fullNameSz;
11841
        return ret;
11842
    }
11843
11844
11845
    /* Converts a list of entries in WOLFSSL_X509_NAME struct into a string
11846
     * returns 0 on success */
11847
    static int RebuildFullName(WOLFSSL_X509_NAME* name)
11848
    {
11849
        int totalLen = 0, i, idx, entryCount = 0;
11850
        char* fullName;
11851
11852
        if (name == NULL)
11853
            return BAD_FUNC_ARG;
11854
11855
        for (i = 0; i < MAX_NAME_ENTRIES; i++) {
11856
            if (name->entry[i].set) {
11857
                WOLFSSL_X509_NAME_ENTRY* e;
11858
                WOLFSSL_ASN1_OBJECT* obj;
11859
11860
                e = &name->entry[i];
11861
                obj = wolfSSL_X509_NAME_ENTRY_get_object(e);
11862
                if (obj == NULL)
11863
                    return BAD_FUNC_ARG;
11864
11865
                totalLen += (int)XSTRLEN(obj->sName) + 2;/*+2 for '/' and '=' */
11866
                totalLen += wolfSSL_ASN1_STRING_length(e->value);
11867
            }
11868
        }
11869
11870
        fullName = (char*)XMALLOC(totalLen + 1, name->heap, DYNAMIC_TYPE_X509);
11871
        if (fullName == NULL)
11872
            return MEMORY_E;
11873
11874
        idx = 0;
11875
        entryCount = AddAllEntry(name, fullName, totalLen, &idx);
11876
        if (entryCount < 0) {
11877
            XFREE(fullName, name->heap, DYNAMIC_TYPE_X509);
11878
            return entryCount;
11879
        }
11880
11881
        if (name->dynamicName) {
11882
            XFREE(name->name, name->heap, DYNAMIC_TYPE_X509);
11883
        }
11884
        fullName[idx] = '\0';
11885
        name->name = fullName;
11886
        name->dynamicName = 1;
11887
        name->sz = idx + 1; /* size includes null terminator */
11888
        name->entrySz = entryCount;
11889
11890
        return 0;
11891
    }
11892
11893
    /* Copies entry into name. With it being copied freeing entry becomes the
11894
     * callers responsibility.
11895
     * returns 1 for success and 0 for error */
11896
    int wolfSSL_X509_NAME_add_entry(WOLFSSL_X509_NAME* name,
11897
            WOLFSSL_X509_NAME_ENTRY* entry, int idx, int set)
11898
    {
11899
        WOLFSSL_X509_NAME_ENTRY* current = NULL;
11900
        int ret, i;
11901
11902
#ifdef WOLFSSL_DEBUG_OPENSSL
11903
        WOLFSSL_ENTER("wolfSSL_X509_NAME_add_entry");
11904
#endif
11905
11906
        if (name == NULL || entry == NULL || entry->value == NULL) {
11907
            WOLFSSL_MSG("NULL argument passed in");
11908
            return WOLFSSL_FAILURE;
11909
        }
11910
11911
        if (idx >= 0) {
11912
            /* place in specific index */
11913
11914
            if (idx >= MAX_NAME_ENTRIES) {
11915
                WOLFSSL_MSG("Error index to insert entry is larger than array");
11916
                return WOLFSSL_FAILURE;
11917
            }
11918
            i = idx;
11919
        }
11920
        else {
11921
            /* iterate through and find first open spot */
11922
            for (i = 0; i < MAX_NAME_ENTRIES; i++) {
11923
                if (name->entry[i].set != 1) { /* not set so overwritten */
11924
                    WOLFSSL_MSG("Found place for name entry");
11925
                    break;
11926
                }
11927
            }
11928
11929
            if (i == MAX_NAME_ENTRIES) {
11930
                WOLFSSL_MSG("No spot found for name entry");
11931
                return WOLFSSL_FAILURE;
11932
            }
11933
        }
11934
11935
        current = &name->entry[i];
11936
        if (current->set == 0)
11937
            name->entrySz++;
11938
11939
        if (wolfSSL_X509_NAME_ENTRY_create_by_NID(&current,
11940
                            entry->nid,
11941
                            wolfSSL_ASN1_STRING_type(entry->value),
11942
                            wolfSSL_ASN1_STRING_data(entry->value),
11943
                            wolfSSL_ASN1_STRING_length(entry->value)) != NULL)
11944
        {
11945
            ret = WOLFSSL_SUCCESS;
11946
        #ifdef OPENSSL_ALL
11947
            if (name->entries == NULL) {
11948
                name->entries = wolfSSL_sk_X509_NAME_new(NULL);
11949
            }
11950
            if (wolfSSL_sk_X509_NAME_ENTRY_push(name->entries, current
11951
                                                         ) != WOLFSSL_SUCCESS) {
11952
                ret = WOLFSSL_FAILURE;
11953
            }
11954
        #endif
11955
        }
11956
        else {
11957
            ret = WOLFSSL_FAILURE;
11958
        }
11959
11960
        if (ret != WOLFSSL_SUCCESS) {
11961
            WOLFSSL_MSG("Error adding the name entry");
11962
            if (current->set == 0)
11963
                name->entrySz--;
11964
            return WOLFSSL_FAILURE;
11965
        }
11966
11967
        if (RebuildFullName(name) != 0)
11968
            return WOLFSSL_FAILURE;
11969
11970
        (void)set;
11971
        return WOLFSSL_SUCCESS;
11972
    }
11973
11974
    int wolfSSL_X509_NAME_add_entry_by_txt(WOLFSSL_X509_NAME *name,
11975
                                           const char *field, int type,
11976
                                           const unsigned char *bytes, int len,
11977
                                           int loc, int set)
11978
    {
11979
        int ret = WOLFSSL_FAILURE;
11980
        int nid;
11981
        WOLFSSL_X509_NAME_ENTRY* entry;
11982
11983
        (void)type;
11984
        WOLFSSL_ENTER("wolfSSL_X509_NAME_add_entry_by_txt");
11985
11986
        if (name == NULL || field == NULL)
11987
            return WOLFSSL_FAILURE;
11988
11989
        if ((nid = wolfSSL_OBJ_txt2nid(field)) == NID_undef) {
11990
            WOLFSSL_MSG("Unable convert text to NID");
11991
            return WOLFSSL_FAILURE;
11992
        }
11993
11994
        entry = wolfSSL_X509_NAME_ENTRY_create_by_NID(NULL,
11995
                  nid, type, (unsigned char*)bytes, len);
11996
        if (entry == NULL)
11997
            return WOLFSSL_FAILURE;
11998
11999
        ret = wolfSSL_X509_NAME_add_entry(name, entry, loc, set);
12000
        wolfSSL_X509_NAME_ENTRY_free(entry);
12001
12002
        return ret;
12003
    }
12004
12005
    int wolfSSL_X509_NAME_add_entry_by_NID(WOLFSSL_X509_NAME *name, int nid,
12006
                                           int type, const unsigned char *bytes,
12007
                                           int len, int loc, int set)
12008
    {
12009
        int ret;
12010
        WOLFSSL_X509_NAME_ENTRY* entry;
12011
        WOLFSSL_ENTER("wolfSSL_X509_NAME_add_entry_by_NID");
12012
        entry = wolfSSL_X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes,
12013
                len);
12014
        if (entry == NULL)
12015
            return WOLFSSL_FAILURE;
12016
        ret = wolfSSL_X509_NAME_add_entry(name, entry, loc, set);
12017
        wolfSSL_X509_NAME_ENTRY_free(entry);
12018
        return ret;
12019
    }
12020
12021
    WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_delete_entry(
12022
            WOLFSSL_X509_NAME *name, int loc)
12023
    {
12024
        WOLFSSL_X509_NAME_ENTRY* ret;
12025
        WOLFSSL_ENTER("wolfSSL_X509_NAME_delete_entry");
12026
12027
        if (!name) {
12028
            WOLFSSL_MSG("Bad parameter");
12029
            return NULL;
12030
        }
12031
12032
        ret = wolfSSL_X509_NAME_get_entry(name, loc);
12033
        if (!ret) {
12034
            WOLFSSL_MSG("loc entry not found");
12035
            return NULL;
12036
        }
12037
        name->entry[loc].set = 0;
12038
        return ret;
12039
    }
12040
12041
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
12042
12043
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN)
12044
    int wolfSSL_X509_NAME_get_index_by_OBJ(WOLFSSL_X509_NAME *name,
12045
                                           const WOLFSSL_ASN1_OBJECT *obj,
12046
                                           int idx) {
12047
        if (!name || idx >= MAX_NAME_ENTRIES ||
12048
                !obj || !obj->obj) {
12049
            return -1;
12050
        }
12051
12052
        if (idx < 0) {
12053
            idx = -1;
12054
        }
12055
12056
        for (idx++; idx < MAX_NAME_ENTRIES; idx++) {
12057
            /* Find index of desired name */
12058
            if (name->entry[idx].set) {
12059
                if (XSTRLEN(obj->sName) == XSTRLEN(name->entry[idx].object->sName) &&
12060
                    XSTRNCMP((const char*) obj->sName,
12061
                        name->entry[idx].object->sName, obj->objSz - 1) == 0) {
12062
                    return idx;
12063
                }
12064
            }
12065
        }
12066
        return -1;
12067
    }
12068
#endif
12069
12070
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
12071
    defined(OPENSSL_EXTRA_X509_SMALL)
12072
12073
    /* returns a pointer to the internal entry at location 'loc' on success,
12074
     * a null pointer is returned in fail cases */
12075
    WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_get_entry(
12076
                                             WOLFSSL_X509_NAME *name, int loc)
12077
    {
12078
#ifdef WOLFSSL_DEBUG_OPENSSL
12079
        WOLFSSL_ENTER("wolfSSL_X509_NAME_get_entry");
12080
#endif
12081
12082
        if (name == NULL) {
12083
            return NULL;
12084
        }
12085
12086
        if (loc < 0 || loc >= MAX_NAME_ENTRIES) {
12087
            WOLFSSL_MSG("Bad argument");
12088
            return NULL;
12089
        }
12090
12091
        if (name->entry[loc].set) {
12092
#ifdef WOLFSSL_PYTHON
12093
            /* "set" is not only flag use, but also stack index position use in
12094
            *  OpenSSL. Python makes tuple based on this number. Therefore,
12095
            *  updating "set" by position + 1. "plus 1" means to avoid "not set"
12096
            *  zero.
12097
            */
12098
            name->entry[loc].set = loc + 1;
12099
#endif
12100
            return &name->entry[loc];
12101
        }
12102
        else {
12103
            return NULL;
12104
        }
12105
    }
12106
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
12107
12108
#ifdef OPENSSL_EXTRA
12109
12110
    int wolfSSL_X509_check_private_key(WOLFSSL_X509 *x509, WOLFSSL_EVP_PKEY *key)
12111
    {
12112
        WOLFSSL_ENTER("wolfSSL_X509_check_private_key");
12113
12114
        if (!x509 || !key) {
12115
            WOLFSSL_MSG("Bad parameter");
12116
            return WOLFSSL_FAILURE;
12117
        }
12118
12119
    #ifndef NO_CHECK_PRIVATE_KEY
12120
        return wc_CheckPrivateKey((byte*)key->pkey.ptr, key->pkey_sz,
12121
                x509->pubKey.buffer, x509->pubKey.length,
12122
                (enum Key_Sum)x509->pubKeyOID) == 1 ?
12123
                        WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
12124
    #else
12125
        /* not compiled in */
12126
        return WOLFSSL_SUCCESS;
12127
    #endif
12128
    }
12129
12130
#endif /* OPENSSL_EXTRA */
12131
12132
#if defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL) \
12133
    || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA)
12134
#ifndef NO_BIO
12135
12136
#ifdef WOLFSSL_CERT_GEN
12137
12138
#ifdef WOLFSSL_CERT_REQ
12139
/* writes the x509 from x to the WOLFSSL_BIO bp
12140
 *
12141
 * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on fail
12142
 */
12143
int wolfSSL_PEM_write_bio_X509_REQ(WOLFSSL_BIO *bp, WOLFSSL_X509 *x)
12144
{
12145
    byte* pem;
12146
    int   pemSz = 0;
12147
    const unsigned char* der;
12148
    int derSz;
12149
    int ret;
12150
12151
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509_REQ");
12152
12153
    if (x == NULL || bp == NULL) {
12154
        return WOLFSSL_FAILURE;
12155
    }
12156
12157
    der = wolfSSL_X509_get_der(x, &derSz);
12158
    if (der == NULL) {
12159
        return WOLFSSL_FAILURE;
12160
    }
12161
12162
    /* get PEM size */
12163
    pemSz = wc_DerToPemEx(der, derSz, NULL, 0, NULL, CERTREQ_TYPE);
12164
    if (pemSz < 0) {
12165
        return WOLFSSL_FAILURE;
12166
    }
12167
12168
    /* create PEM buffer and convert from DER */
12169
    pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12170
    if (pem == NULL) {
12171
        return WOLFSSL_FAILURE;
12172
    }
12173
    if (wc_DerToPemEx(der, derSz, pem, pemSz, NULL, CERTREQ_TYPE) < 0) {
12174
        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12175
        return WOLFSSL_FAILURE;
12176
    }
12177
12178
    /* write the PEM to BIO */
12179
    ret = wolfSSL_BIO_write(bp, pem, pemSz);
12180
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12181
12182
    if (ret <= 0) return WOLFSSL_FAILURE;
12183
    return WOLFSSL_SUCCESS;
12184
}
12185
#endif /* WOLFSSL_CERT_REQ */
12186
12187
12188
/* writes the x509 from x to the WOLFSSL_BIO bp
12189
 *
12190
 * returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on fail
12191
 */
12192
int wolfSSL_PEM_write_bio_X509_AUX(WOLFSSL_BIO *bp, WOLFSSL_X509 *x)
12193
{
12194
    byte* pem;
12195
    int   pemSz = 0;
12196
    const unsigned char* der;
12197
    int derSz;
12198
    int ret;
12199
12200
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509_AUX");
12201
12202
    if (bp == NULL || x == NULL) {
12203
        WOLFSSL_MSG("NULL argument passed in");
12204
        return WOLFSSL_FAILURE;
12205
    }
12206
12207
    der = wolfSSL_X509_get_der(x, &derSz);
12208
    if (der == NULL) {
12209
        return WOLFSSL_FAILURE;
12210
    }
12211
12212
    /* get PEM size */
12213
    pemSz = wc_DerToPemEx(der, derSz, NULL, 0, NULL, CERT_TYPE);
12214
    if (pemSz < 0) {
12215
        return WOLFSSL_FAILURE;
12216
    }
12217
12218
    /* create PEM buffer and convert from DER */
12219
    pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12220
    if (pem == NULL) {
12221
        return WOLFSSL_FAILURE;
12222
    }
12223
    if (wc_DerToPemEx(der, derSz, pem, pemSz, NULL, CERT_TYPE) < 0) {
12224
        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12225
        return WOLFSSL_FAILURE;
12226
    }
12227
12228
    /* write the PEM to BIO */
12229
    ret = wolfSSL_BIO_write(bp, pem, pemSz);
12230
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12231
12232
    if (ret <= 0) return WOLFSSL_FAILURE;
12233
    return WOLFSSL_SUCCESS;
12234
}
12235
12236
int wolfSSL_PEM_write_bio_X509(WOLFSSL_BIO *bio, WOLFSSL_X509 *cert)
12237
{
12238
    byte* pem = NULL;
12239
    int   pemSz = 0;
12240
    /* Get large buffer to hold cert der */
12241
    const byte* der = NULL;
12242
    int derSz = X509_BUFFER_SZ;
12243
    int ret;
12244
12245
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_X509");
12246
12247
    if (bio == NULL || cert == NULL) {
12248
        WOLFSSL_MSG("NULL argument passed in");
12249
        return WOLFSSL_FAILURE;
12250
    }
12251
12252
    /* Do not call wolfssl_x509_make_der() here. If we did, then need to re-sign
12253
     * because we don't know the original order of the extensions and so we must
12254
     * assume our extensions are in a different order, thus need to re-sign. */
12255
    der = wolfSSL_X509_get_der(cert, &derSz);
12256
    if (der == NULL) {
12257
        goto error;
12258
    }
12259
12260
    /* get PEM size */
12261
    pemSz = wc_DerToPemEx(der, derSz, NULL, 0, NULL, CERT_TYPE);
12262
    if (pemSz < 0) {
12263
        goto error;
12264
    }
12265
12266
    /* create PEM buffer and convert from DER */
12267
    pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12268
    if (pem == NULL) {
12269
        goto error;
12270
    }
12271
    if (wc_DerToPemEx(der, derSz, pem, pemSz, NULL, CERT_TYPE) < 0) {
12272
        goto error;
12273
    }
12274
12275
    /* write the PEM to BIO */
12276
    ret = wolfSSL_BIO_write(bio, pem, pemSz);
12277
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12278
12279
    if (ret <= 0) return WOLFSSL_FAILURE;
12280
    return WOLFSSL_SUCCESS;
12281
12282
error:
12283
    if (pem)
12284
        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12285
    return WOLFSSL_FAILURE;
12286
}
12287
#endif /* WOLFSSL_CERT_GEN */
12288
12289
#endif /* !NO_BIO */
12290
#endif /* HAVE_LIGHTY || HAVE_STUNNEL || WOLFSSL_MYSQL_COMPATIBLE */
12291
12292
#if defined(OPENSSL_EXTRA) || defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
12293
        defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
12294
        defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB)
12295
12296
WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_sk_X509_NAME_new(
12297
        WOLF_SK_COMPARE_CB(WOLFSSL_X509_NAME, cb))
12298
{
12299
    WOLFSSL_STACK* sk;
12300
    (void)cb;
12301
12302
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_new");
12303
12304
    sk = wolfSSL_sk_new_node(NULL);
12305
    if (sk != NULL) {
12306
        sk->type = STACK_TYPE_X509_NAME;
12307
    }
12308
12309
    return sk;
12310
}
12311
12312
int wolfSSL_sk_X509_NAME_num(const WOLF_STACK_OF(WOLFSSL_X509_NAME) *sk)
12313
{
12314
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_num");
12315
12316
    if (sk == NULL)
12317
        return BAD_FUNC_ARG;
12318
12319
    return (int)sk->num;
12320
}
12321
12322
/* Getter function for WOLFSSL_X509_NAME pointer
12323
 *
12324
 * sk is the stack to retrieve pointer from
12325
 * i  is the index value in stack
12326
 *
12327
 * returns a pointer to a WOLFSSL_X509_NAME structure on success and NULL on
12328
 *         fail
12329
 */
12330
WOLFSSL_X509_NAME* wolfSSL_sk_X509_NAME_value(const STACK_OF(WOLFSSL_X509_NAME)* sk,
12331
    int i)
12332
{
12333
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_value");
12334
    return (WOLFSSL_X509_NAME*)wolfSSL_sk_value(sk, i);
12335
}
12336
12337
WOLFSSL_X509_NAME* wolfSSL_sk_X509_NAME_pop(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk)
12338
{
12339
    WOLFSSL_STACK* node;
12340
    WOLFSSL_X509_NAME* name;
12341
12342
    if (sk == NULL) {
12343
        return NULL;
12344
    }
12345
12346
    node = sk->next;
12347
    name = sk->data.name;
12348
12349
    if (node != NULL) { /* update sk and remove node from stack */
12350
        sk->data.name = node->data.name;
12351
        sk->next = node->next;
12352
        XFREE(node, NULL, DYNAMIC_TYPE_OPENSSL);
12353
    }
12354
    else { /* last x509 in stack */
12355
        sk->data.name = NULL;
12356
    }
12357
12358
    if (sk->num > 0) {
12359
        sk->num -= 1;
12360
    }
12361
12362
    return name;
12363
}
12364
12365
void wolfSSL_sk_X509_NAME_pop_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk,
12366
    void (*f) (WOLFSSL_X509_NAME*))
12367
{
12368
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_pop_free");
12369
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
12370
}
12371
12372
/* Free only the sk structure, NOT X509_NAME members */
12373
void wolfSSL_sk_X509_NAME_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk)
12374
{
12375
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_free");
12376
    wolfSSL_sk_free(sk);
12377
}
12378
12379
int wolfSSL_sk_X509_NAME_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk,
12380
    WOLFSSL_X509_NAME* name)
12381
{
12382
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_push");
12383
12384
    return wolfSSL_sk_push(sk, name);
12385
}
12386
12387
/* return index of found, or negative to indicate not found */
12388
int wolfSSL_sk_X509_NAME_find(const WOLF_STACK_OF(WOLFSSL_X509_NAME) *sk,
12389
    WOLFSSL_X509_NAME *name)
12390
{
12391
    int i;
12392
12393
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_find");
12394
12395
    if (sk == NULL)
12396
        return BAD_FUNC_ARG;
12397
12398
    for (i = 0; sk; i++, sk = sk->next) {
12399
        if (wolfSSL_X509_NAME_cmp(sk->data.name, name) == 0) {
12400
            return i;
12401
        }
12402
    }
12403
    return -1;
12404
}
12405
12406
/* Name Entry */
12407
WOLF_STACK_OF(WOLFSSL_X509_NAME_ENTRY)* wolfSSL_sk_X509_NAME_ENTRY_new(
12408
    WOLF_SK_COMPARE_CB(WOLFSSL_X509_NAME_ENTRY, cb))
12409
{
12410
    WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL);
12411
    if (sk != NULL) {
12412
        sk->type = STACK_TYPE_X509_NAME_ENTRY;
12413
        (void)cb;
12414
    }
12415
    return sk;
12416
}
12417
12418
int wolfSSL_sk_X509_NAME_ENTRY_push(WOLF_STACK_OF(WOLFSSL_X509_NAME_ENTRY)* sk,
12419
    WOLFSSL_X509_NAME_ENTRY* name_entry)
12420
{
12421
    return wolfSSL_sk_push(sk, name_entry);
12422
}
12423
12424
WOLFSSL_X509_NAME_ENTRY* wolfSSL_sk_X509_NAME_ENTRY_value(
12425
    const WOLF_STACK_OF(WOLFSSL_X509_NAME_ENTRY)* sk, int i)
12426
{
12427
    return (WOLFSSL_X509_NAME_ENTRY*)wolfSSL_sk_value(sk, i);
12428
}
12429
12430
int wolfSSL_sk_X509_NAME_ENTRY_num(const WOLF_STACK_OF(WOLFSSL_X509_NAME_ENTRY)* sk)
12431
{
12432
    if (sk == NULL)
12433
        return BAD_FUNC_ARG;
12434
    return (int)sk->num;
12435
}
12436
12437
void wolfSSL_sk_X509_NAME_ENTRY_free(WOLF_STACK_OF(WOLFSSL_X509_NAME_ENTRY)* sk)
12438
{
12439
    wolfSSL_sk_free(sk);
12440
}
12441
12442
#endif /* OPENSSL_EXTRA || HAVE_STUNNEL || WOLFSSL_NGINX ||
12443
            HAVE_LIGHTY || WOLFSSL_HAPROXY ||
12444
            WOLFSSL_OPENSSH || HAVE_SBLIM_SFCB */
12445
12446
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
12447
    (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
12448
    defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
12449
    defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB))
12450
12451
#if defined(OPENSSL_ALL)
12452
WOLFSSL_X509_INFO* wolfSSL_X509_INFO_new(void)
12453
{
12454
    WOLFSSL_X509_INFO* info;
12455
    info = (WOLFSSL_X509_INFO*)XMALLOC(sizeof(WOLFSSL_X509_INFO), NULL,
12456
        DYNAMIC_TYPE_X509);
12457
    if (info) {
12458
        XMEMSET(info, 0, sizeof(*info));
12459
    }
12460
    return info;
12461
}
12462
12463
void wolfSSL_X509_INFO_free(WOLFSSL_X509_INFO* info)
12464
{
12465
    if (info == NULL)
12466
        return;
12467
12468
    if (info->x509) {
12469
        wolfSSL_X509_free(info->x509);
12470
        info->x509 = NULL;
12471
    }
12472
#ifdef HAVE_CRL
12473
    if (info->crl) {
12474
        wolfSSL_X509_CRL_free(info->crl);
12475
        info->crl = NULL;
12476
    }
12477
#endif
12478
    wolfSSL_X509_PKEY_free(info->x_pkey);
12479
    info->x_pkey = NULL;
12480
12481
    XFREE(info, NULL, DYNAMIC_TYPE_X509);
12482
}
12483
#endif
12484
12485
WOLFSSL_STACK* wolfSSL_sk_X509_INFO_new_null(void)
12486
{
12487
    WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL);
12488
    if (sk) {
12489
        sk->type = STACK_TYPE_X509_INFO;
12490
    }
12491
    return sk;
12492
}
12493
12494
int wolfSSL_sk_X509_INFO_num(const WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk)
12495
{
12496
    WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_num");
12497
12498
    return wolfSSL_sk_num(sk);
12499
}
12500
12501
WOLFSSL_X509_INFO* wolfSSL_sk_X509_INFO_value(
12502
        const WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk, int i)
12503
{
12504
    WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_value");
12505
12506
    return (WOLFSSL_X509_INFO *)wolfSSL_sk_value(sk, i);
12507
}
12508
12509
WOLFSSL_X509_INFO* wolfSSL_sk_X509_INFO_pop(
12510
        WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk)
12511
{
12512
    WOLFSSL_STACK* node;
12513
    WOLFSSL_X509_INFO* info;
12514
12515
    if (sk == NULL) {
12516
        return NULL;
12517
    }
12518
12519
    node = sk->next;
12520
    info = sk->data.info;
12521
12522
    if (node != NULL) { /* update sk and remove node from stack */
12523
        sk->data.info = node->data.info;
12524
        sk->next = node->next;
12525
        wolfSSL_sk_free_node(node);
12526
    }
12527
    else { /* last x509 in stack */
12528
        sk->data.info = NULL;
12529
    }
12530
12531
    if (sk->num > 0) {
12532
        sk->num -= 1;
12533
    }
12534
12535
    return info;
12536
}
12537
12538
#if defined(OPENSSL_ALL)
12539
void wolfSSL_sk_X509_INFO_pop_free(WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
12540
    void (*f) (WOLFSSL_X509_INFO*))
12541
{
12542
    WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_pop_free");
12543
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
12544
}
12545
12546
void wolfSSL_sk_X509_INFO_free(WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk)
12547
{
12548
    WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_free");
12549
    wolfSSL_sk_free(sk);
12550
}
12551
12552
/* Adds the WOLFSSL_X509_INFO to the stack "sk". "sk" takes control of "in" and
12553
 * tries to free it when the stack is free'd.
12554
 *
12555
 * return 1 on success 0 on fail
12556
 */
12557
int wolfSSL_sk_X509_INFO_push(WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
12558
                                                      WOLFSSL_X509_INFO* in)
12559
{
12560
    return wolfSSL_sk_push(sk, in);
12561
}
12562
12563
/* Creates a duplicate of WOLF_STACK_OF(WOLFSSL_X509_NAME).
12564
 * Returns a new WOLF_STACK_OF(WOLFSSL_X509_NAME) or NULL on failure */
12565
WOLF_STACK_OF(WOLFSSL_X509_NAME) *wolfSSL_dup_CA_list(
12566
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk)
12567
{
12568
    int i;
12569
    const int num = wolfSSL_sk_X509_NAME_num(sk);
12570
    WOLF_STACK_OF(WOLFSSL_X509_NAME) *copy;
12571
    WOLFSSL_X509_NAME *name;
12572
12573
    WOLFSSL_ENTER("wolfSSL_dup_CA_list");
12574
12575
    copy = wolfSSL_sk_X509_NAME_new(NULL);
12576
    if (copy == NULL) {
12577
        WOLFSSL_MSG("Memory error");
12578
        return NULL;
12579
    }
12580
12581
    for (i = 0; i < num; i++) {
12582
        name = wolfSSL_X509_NAME_dup(wolfSSL_sk_X509_NAME_value(sk, i));
12583
        if (name == NULL || WOLFSSL_SUCCESS != wolfSSL_sk_X509_NAME_push(copy, name)) {
12584
            WOLFSSL_MSG("Memory error");
12585
            wolfSSL_sk_X509_NAME_pop_free(copy, wolfSSL_X509_NAME_free);
12586
            return NULL;
12587
        }
12588
    }
12589
12590
    return copy;
12591
}
12592
12593
void* wolfSSL_sk_X509_OBJECT_value(WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk, int i)
12594
{
12595
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_value");
12596
    for (; sk != NULL && i > 0; i--)
12597
        sk = sk->next;
12598
12599
    if (i != 0 || sk == NULL)
12600
        return NULL;
12601
    return sk->data.x509_obj;
12602
}
12603
12604
int wolfSSL_sk_X509_OBJECT_num(const WOLF_STACK_OF(WOLFSSL_X509_OBJECT) *s)
12605
{
12606
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_num");
12607
    if (s) {
12608
        return (int)s->num;
12609
    } else {
12610
        return 0;
12611
    }
12612
}
12613
12614
int wolfSSL_sk_X509_NAME_set_cmp_func(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk,
12615
    WOLF_SK_COMPARE_CB(WOLFSSL_X509_NAME, cb))
12616
{
12617
    WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_set_cmp_func");
12618
12619
    if (sk == NULL)
12620
        return BAD_FUNC_ARG;
12621
12622
    WOLFSSL_MSG("Stack comparison not used in wolfSSL");
12623
    (void)cb;
12624
    return 0;
12625
}
12626
#endif /* OPENSSL_ALL */
12627
12628
#ifndef NO_BIO
12629
12630
/* Helper function for X509_NAME_print_ex. Sets *buf to string for domain
12631
   name attribute based on NID. Returns size of buf */
12632
static int get_dn_attr_by_nid(int n, const char** buf)
12633
{
12634
    int len = 0;
12635
    const char *str;
12636
12637
    switch(n)
12638
    {
12639
        case NID_commonName :
12640
            str = "CN";
12641
            len = 2;
12642
            break;
12643
        case NID_countryName:
12644
            str = "C";
12645
            len = 1;
12646
            break;
12647
        case NID_localityName:
12648
            str = "L";
12649
            len = 1;
12650
            break;
12651
        case NID_stateOrProvinceName:
12652
            str = "ST";
12653
            len = 2;
12654
            break;
12655
        case NID_streetAddress:
12656
            str = "street";
12657
            len = 6;
12658
            break;
12659
        case NID_organizationName:
12660
            str = "O";
12661
            len = 1;
12662
            break;
12663
        case NID_organizationalUnitName:
12664
            str = "OU";
12665
            len = 2;
12666
            break;
12667
        case NID_postalCode:
12668
            str = "postalCode";
12669
            len = 10;
12670
            break;
12671
        case NID_emailAddress:
12672
            str = "emailAddress";
12673
            len = 12;
12674
            break;
12675
        case NID_surname:
12676
            str = "SN";
12677
            len = 2;
12678
            break;
12679
        case NID_givenName:
12680
            str = "GN";
12681
            len = 2;
12682
            break;
12683
        case NID_dnQualifier:
12684
            str = "dnQualifier";
12685
            len = 11;
12686
            break;
12687
        case NID_name:
12688
            str = "name";
12689
            len = 4;
12690
            break;
12691
        case NID_initials:
12692
            str = "initials";
12693
            len = 8;
12694
            break;
12695
        case NID_domainComponent:
12696
            str = "DC";
12697
            len = 2;
12698
            break;
12699
        case NID_pkcs9_contentType:
12700
            str = "contentType";
12701
            len = 11;
12702
            break;
12703
        case NID_userId:
12704
            str = "UID";
12705
            len = 3;
12706
            break;
12707
        default:
12708
            WOLFSSL_MSG("Attribute type not found");
12709
            str = NULL;
12710
12711
    }
12712
    if (buf != NULL)
12713
        *buf = str;
12714
    return len;
12715
}
12716
12717
/**
12718
 * Escape input string for RFC2253 requirements. The following characters
12719
 * are escaped with a backslash (\):
12720
 *
12721
 *     1. A space or '#' at the beginning of the string
12722
 *     2. A space at the end of the string
12723
 *     3. One of: ",", "+", """, "\", "<", ">", ";"
12724
 *
12725
 * in    - input string to escape
12726
 * inSz  - length of in, not including the null terminator
12727
 * out   - buffer for output string to be written, will be null terminated
12728
 * outSz - size of out
12729
 *
12730
 * Returns size of output string (not counting NULL terminator) on success,
12731
 * negative on error.
12732
 */
12733
static int wolfSSL_EscapeString_RFC2253(char* in, word32 inSz,
12734
                                        char* out, word32 outSz)
12735
{
12736
    word32 inIdx = 0;
12737
    word32 outIdx = 0;
12738
12739
    if (in == NULL || out == NULL || inSz == 0 || outSz == 0) {
12740
        return BAD_FUNC_ARG;
12741
    }
12742
12743
    for (inIdx = 0; inIdx < inSz; inIdx++) {
12744
12745
        char c = in[inIdx];
12746
12747
        if (((inIdx == 0) && (c == ' ' || c == '#')) ||
12748
            ((inIdx == (inSz-1)) && (c == ' ')) ||
12749
            c == ',' || c == '+' || c == '"' || c == '\\' ||
12750
            c == '<' || c == '>' || c == ';') {
12751
12752
            if (outIdx > (outSz - 1)) {
12753
                return BUFFER_E;
12754
            }
12755
            out[outIdx] = '\\';
12756
            outIdx++;
12757
        }
12758
        if (outIdx > (outSz - 1)) {
12759
            return BUFFER_E;
12760
        }
12761
        out[outIdx] = c;
12762
        outIdx++;
12763
    }
12764
12765
    /* null terminate out */
12766
    if (outIdx > (outSz -1)) {
12767
        return BUFFER_E;
12768
    }
12769
    out[outIdx] = '\0';
12770
12771
    return outIdx;
12772
}
12773
12774
/*
12775
 * Print human readable version of X509_NAME to provided BIO.
12776
 *
12777
 * bio    - output BIO to place name string. Does not include null terminator.
12778
 * name   - input name to convert to string
12779
 * indent - number of indent spaces to prepend to name string
12780
 * flags  - flags to control function behavior. Not all flags are currently
12781
 *          supported/implemented. Currently supported are:
12782
 *              XN_FLAG_RFC2253 - only the backslash escape requirements from
12783
 *                                RFC22523 currently implemented.
12784
 *              XN_FLAG_DN_REV  - print name reversed. Automatically done by
12785
 *                                XN_FLAG_RFC2253.
12786
 *
12787
 * Returns WOLFSSL_SUCCESS (1) on success, WOLFSSL_FAILURE (0) on failure.
12788
 */
12789
int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name,
12790
                int indent, unsigned long flags)
12791
{
12792
    int i, count = 0, nameStrSz = 0, escapeSz = 0;
12793
    char* tmp = NULL;
12794
    char* nameStr = NULL;
12795
    const char *buf = NULL;
12796
    WOLFSSL_X509_NAME_ENTRY* ne;
12797
    WOLFSSL_ASN1_STRING* str;
12798
    char escaped[ASN_NAME_MAX];
12799
12800
    WOLFSSL_ENTER("wolfSSL_X509_NAME_print_ex");
12801
12802
    if ((name == NULL) || (name->sz == 0) || (bio == NULL))
12803
        return WOLFSSL_FAILURE;
12804
12805
    for (i = 0; i < indent; i++) {
12806
        if (wolfSSL_BIO_write(bio, " ", 1) != 1)
12807
            return WOLFSSL_FAILURE;
12808
    }
12809
12810
    count = wolfSSL_X509_NAME_entry_count(name);
12811
12812
    for (i = 0; i < count; i++) {
12813
        int len;
12814
        int tmpSz;
12815
12816
        /* reverse name order for RFC2253 and DN_REV */
12817
        if ((flags & XN_FLAG_RFC2253) || (flags & XN_FLAG_DN_REV)) {
12818
            ne = wolfSSL_X509_NAME_get_entry(name, count - i - 1);
12819
        } else {
12820
            ne = wolfSSL_X509_NAME_get_entry(name, i);
12821
        }
12822
        if (ne == NULL)
12823
            return WOLFSSL_FAILURE;
12824
12825
        str = wolfSSL_X509_NAME_ENTRY_get_data(ne);
12826
        if (str == NULL)
12827
            return WOLFSSL_FAILURE;
12828
12829
        if (flags & XN_FLAG_RFC2253) {
12830
            /* escape string for RFC 2253, ret sz not counting null term */
12831
            escapeSz = wolfSSL_EscapeString_RFC2253(str->data,
12832
                            str->length, escaped, sizeof(escaped));
12833
            if (escapeSz < 0)
12834
                return WOLFSSL_FAILURE;
12835
12836
            nameStr = escaped;
12837
            nameStrSz = escapeSz;
12838
        }
12839
        else {
12840
            nameStr = str->data;
12841
            nameStrSz = str->length;
12842
        }
12843
12844
        /* len is without null terminator */
12845
        len = get_dn_attr_by_nid(ne->nid, &buf);
12846
        if (len == 0 || buf == NULL)
12847
            return WOLFSSL_FAILURE;
12848
12849
        tmpSz = nameStrSz + len + 4; /* + 4 for '=', comma space and '\0'*/
12850
        tmp = (char*)XMALLOC(tmpSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12851
        if (tmp == NULL) {
12852
            return WOLFSSL_FAILURE;
12853
        }
12854
12855
        if (i < count - 1) {
12856
            if (XSNPRINTF(tmp, tmpSz, "%s=%s, ", buf, nameStr)
12857
                >= tmpSz)
12858
            {
12859
                WOLFSSL_MSG("buffer overrun");
12860
                XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12861
                return WOLFSSL_FAILURE;
12862
            }
12863
12864
            tmpSz = len + nameStrSz + 3; /* 3 for '=', comma space */
12865
        }
12866
        else {
12867
            if (XSNPRINTF(tmp, tmpSz, "%s=%s", buf, nameStr)
12868
                >= tmpSz)
12869
            {
12870
                WOLFSSL_MSG("buffer overrun");
12871
                XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12872
                return WOLFSSL_FAILURE;
12873
            }
12874
            tmpSz = len + nameStrSz + 1; /* 1 for '=' */
12875
            if (bio->type != WOLFSSL_BIO_FILE && bio->type != WOLFSSL_BIO_MEMORY)
12876
                ++tmpSz; /* include the terminating null when not writing to a
12877
                          * file.
12878
                          */
12879
        }
12880
12881
        if (wolfSSL_BIO_write(bio, tmp, tmpSz) != tmpSz) {
12882
            XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12883
            return WOLFSSL_FAILURE;
12884
        }
12885
12886
        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12887
    }
12888
12889
    return WOLFSSL_SUCCESS;
12890
}
12891
12892
#ifndef NO_FILESYSTEM
12893
int wolfSSL_X509_NAME_print_ex_fp(XFILE file, WOLFSSL_X509_NAME* name,
12894
        int indent, unsigned long flags)
12895
{
12896
    WOLFSSL_BIO* bio;
12897
    int ret;
12898
12899
    WOLFSSL_ENTER("wolfSSL_X509_NAME_print_ex_fp");
12900
12901
    if (!(bio = wolfSSL_BIO_new_fp(file, BIO_NOCLOSE))) {
12902
        WOLFSSL_MSG("wolfSSL_BIO_new_fp error");
12903
        return WOLFSSL_FAILURE;
12904
    }
12905
12906
    ret = wolfSSL_X509_NAME_print_ex(bio, name, indent, flags);
12907
12908
    wolfSSL_BIO_free(bio);
12909
12910
    return ret;
12911
}
12912
#endif /* NO_FILESYSTEM */
12913
#endif /* !NO_BIO */
12914
12915
#ifndef NO_WOLFSSL_STUB
12916
WOLFSSL_ASN1_BIT_STRING* wolfSSL_X509_get0_pubkey_bitstr(const WOLFSSL_X509* x)
12917
{
12918
    (void)x;
12919
    WOLFSSL_ENTER("wolfSSL_X509_get0_pubkey_bitstr");
12920
    WOLFSSL_STUB("X509_get0_pubkey_bitstr");
12921
12922
    return NULL;
12923
}
12924
#endif
12925
12926
#ifdef OPENSSL_ALL
12927
WOLFSSL_X509_LOOKUP_TYPE wolfSSL_X509_OBJECT_get_type(
12928
        const WOLFSSL_X509_OBJECT* obj)
12929
{
12930
    if (obj == NULL)
12931
        return WOLFSSL_X509_LU_NONE;
12932
    return obj->type;
12933
}
12934
12935
WOLFSSL_X509_OBJECT* wolfSSL_X509_OBJECT_new(void)
12936
{
12937
    WOLFSSL_X509_OBJECT* ret = (WOLFSSL_X509_OBJECT*)
12938
            XMALLOC(sizeof(WOLFSSL_X509_OBJECT), NULL, DYNAMIC_TYPE_OPENSSL);
12939
    if (ret != NULL)
12940
        XMEMSET(ret, 0, sizeof(WOLFSSL_X509_OBJECT));
12941
    return ret;
12942
}
12943
12944
void wolfSSL_X509_OBJECT_free(WOLFSSL_X509_OBJECT *obj)
12945
{
12946
    WOLFSSL_ENTER("wolfSSL_X509_OBJECT_free");
12947
    if (obj != NULL) {
12948
        if (obj->type == WOLFSSL_X509_LU_X509) {
12949
            wolfSSL_X509_free(obj->data.x509);
12950
        }
12951
        else {
12952
            /* We don't free as this will point to
12953
             * store->cm->crl which we don't own */
12954
            WOLFSSL_MSG("Not free'ing CRL in WOLFSSL_X509_OBJECT");
12955
        }
12956
        XFREE(obj, NULL, DYNAMIC_TYPE_OPENSSL);
12957
    }
12958
}
12959
#endif /* OPENSSL_ALL */
12960
12961
#ifndef NO_WOLFSSL_STUB
12962
WOLFSSL_X509_OBJECT* wolfSSL_sk_X509_OBJECT_delete(
12963
    WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk, int i)
12964
{
12965
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_delete");
12966
    WOLFSSL_STUB("wolfSSL_sk_X509_OBJECT_delete");
12967
    (void)sk;
12968
    (void)i;
12969
    return NULL;
12970
}
12971
#endif
12972
12973
WOLFSSL_X509 *wolfSSL_X509_OBJECT_get0_X509(const WOLFSSL_X509_OBJECT *obj)
12974
{
12975
    if (obj != NULL && obj->type == WOLFSSL_X509_LU_X509)
12976
        return obj->data.x509;
12977
    return NULL;
12978
}
12979
12980
WOLFSSL_X509_CRL *wolfSSL_X509_OBJECT_get0_X509_CRL(WOLFSSL_X509_OBJECT *obj)
12981
{
12982
    if (obj != NULL && obj->type == WOLFSSL_X509_LU_CRL)
12983
        return obj->data.crl;
12984
    return NULL;
12985
}
12986
12987
#endif /* OPENSSL_ALL || (OPENSSL_EXTRA && (HAVE_STUNNEL || WOLFSSL_NGINX ||
12988
        * HAVE_LIGHTY || WOLFSSL_HAPROXY || WOLFSSL_OPENSSH ||
12989
        * HAVE_SBLIM_SFCB)) */
12990
12991
12992
#if defined(OPENSSL_EXTRA)
12993
12994
int wolfSSL_sk_X509_num(const WOLF_STACK_OF(WOLFSSL_X509) *s)
12995
{
12996
    WOLFSSL_ENTER("wolfSSL_sk_X509_num");
12997
12998
    if (s == NULL)
12999
        return -1;
13000
    return (int)s->num;
13001
}
13002
13003
#endif /* OPENSSL_EXTRA */
13004
13005
#if defined(HAVE_EX_DATA) && (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) \
13006
     || defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA)                   \
13007
     || defined(HAVE_LIGHTY))
13008
13009
int wolfSSL_X509_get_ex_new_index(int idx, void *arg,
13010
                                  WOLFSSL_CRYPTO_EX_new* new_func,
13011
                                  WOLFSSL_CRYPTO_EX_dup* dup_func,
13012
                                  WOLFSSL_CRYPTO_EX_free* free_func)
13013
{
13014
    WOLFSSL_ENTER("wolfSSL_X509_get_ex_new_index");
13015
13016
    return wolfssl_get_ex_new_index(CRYPTO_EX_INDEX_X509, idx, arg,
13017
                                    new_func, dup_func, free_func);
13018
}
13019
#endif
13020
13021
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
13022
    defined(WOLFSSL_WPAS_SMALL)
13023
void *wolfSSL_X509_get_ex_data(X509 *x509, int idx)
13024
{
13025
    WOLFSSL_ENTER("wolfSSL_X509_get_ex_data");
13026
#ifdef HAVE_EX_DATA
13027
    if (x509 != NULL) {
13028
        return wolfSSL_CRYPTO_get_ex_data(&x509->ex_data, idx);
13029
    }
13030
#else
13031
    (void)x509;
13032
    (void)idx;
13033
#endif
13034
    return NULL;
13035
}
13036
13037
int wolfSSL_X509_set_ex_data(X509 *x509, int idx, void *data)
13038
{
13039
    WOLFSSL_ENTER("wolfSSL_X509_set_ex_data");
13040
#ifdef HAVE_EX_DATA
13041
    if (x509 != NULL)
13042
    {
13043
        return wolfSSL_CRYPTO_set_ex_data(&x509->ex_data, idx, data);
13044
    }
13045
#else
13046
    (void)x509;
13047
    (void)idx;
13048
    (void)data;
13049
#endif
13050
    return WOLFSSL_FAILURE;
13051
}
13052
13053
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
13054
int wolfSSL_X509_set_ex_data_with_cleanup(
13055
    X509 *x509,
13056
    int idx,
13057
    void *data,
13058
    wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
13059
{
13060
    WOLFSSL_ENTER("wolfSSL_X509_set_ex_data_with_cleanup");
13061
    if (x509 != NULL)
13062
    {
13063
        return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&x509->ex_data, idx,
13064
                                                       data, cleanup_routine);
13065
    }
13066
    return WOLFSSL_FAILURE;
13067
}
13068
#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
13069
13070
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL || WOLFSSL_WPAS_SMALL */
13071
13072
13073
#ifndef NO_ASN
13074
int wolfSSL_X509_check_host(WOLFSSL_X509 *x, const char *chk, size_t chklen,
13075
                    unsigned int flags, char **peername)
13076
0
{
13077
0
    int         ret;
13078
0
#ifdef WOLFSSL_SMALL_STACK
13079
0
    DecodedCert *dCert;
13080
#else
13081
    DecodedCert dCert[1];
13082
#endif
13083
13084
0
    WOLFSSL_ENTER("wolfSSL_X509_check_host");
13085
13086
    /* flags and peername not needed for Nginx. */
13087
0
    (void)flags;
13088
0
    (void)peername;
13089
13090
0
    if ((x == NULL) || (chk == NULL)) {
13091
0
        WOLFSSL_MSG("Invalid parameter");
13092
0
        return WOLFSSL_FAILURE;
13093
0
    }
13094
13095
0
    if (flags == WOLFSSL_NO_WILDCARDS) {
13096
0
        WOLFSSL_MSG("X509_CHECK_FLAG_NO_WILDCARDS not yet implemented");
13097
0
        return WOLFSSL_FAILURE;
13098
0
    }
13099
0
    if (flags == WOLFSSL_NO_PARTIAL_WILDCARDS) {
13100
0
        WOLFSSL_MSG("X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS not yet implemented");
13101
0
        return WOLFSSL_FAILURE;
13102
0
    }
13103
13104
0
#ifdef WOLFSSL_SMALL_STACK
13105
0
    dCert = (DecodedCert *)XMALLOC(sizeof(*dCert), x->heap,
13106
0
                                   DYNAMIC_TYPE_DCERT);
13107
0
    if (dCert == NULL) {
13108
0
        WOLFSSL_MSG("\tout of memory");
13109
0
        return WOLFSSL_FATAL_ERROR;
13110
0
    }
13111
0
#endif
13112
13113
0
    InitDecodedCert(dCert, x->derCert->buffer, x->derCert->length, NULL);
13114
0
    ret = ParseCertRelative(dCert, CERT_TYPE, 0, NULL);
13115
0
    if (ret != 0) {
13116
0
        goto out;
13117
0
    }
13118
13119
0
    ret = CheckHostName(dCert, (char *)chk, chklen);
13120
13121
0
out:
13122
13123
0
    FreeDecodedCert(dCert);
13124
0
#ifdef WOLFSSL_SMALL_STACK
13125
0
    XFREE(dCert, x->heap, DYNAMIC_TYPE_DCERT);
13126
0
#endif
13127
13128
0
    if (ret != 0)
13129
0
        return WOLFSSL_FAILURE;
13130
0
    return WOLFSSL_SUCCESS;
13131
0
}
13132
13133
13134
int wolfSSL_X509_check_ip_asc(WOLFSSL_X509 *x, const char *ipasc,
13135
        unsigned int flags)
13136
0
{
13137
0
    int ret = WOLFSSL_FAILURE;
13138
0
#ifdef WOLFSSL_SMALL_STACK
13139
0
    DecodedCert *dCert = NULL;
13140
#else
13141
    DecodedCert dCert[1];
13142
#endif
13143
13144
0
    WOLFSSL_ENTER("wolfSSL_X509_check_ip_asc");
13145
13146
    /* flags not yet implemented */
13147
0
    (void)flags;
13148
13149
0
    if ((x == NULL) || (x->derCert == NULL) || (ipasc == NULL)) {
13150
0
        WOLFSSL_MSG("Invalid parameter");
13151
0
    }
13152
0
    else {
13153
0
        ret = WOLFSSL_SUCCESS;
13154
0
    }
13155
13156
0
#ifdef WOLFSSL_SMALL_STACK
13157
0
    if (ret == WOLFSSL_SUCCESS) {
13158
0
        dCert = (DecodedCert *)XMALLOC(sizeof(*dCert), x->heap,
13159
0
                                       DYNAMIC_TYPE_DCERT);
13160
0
        if (dCert == NULL) {
13161
0
            WOLFSSL_MSG("\tout of memory");
13162
0
            ret = WOLFSSL_FAILURE;
13163
0
        }
13164
0
    }
13165
0
#endif
13166
13167
0
    if (ret == WOLFSSL_SUCCESS) {
13168
0
        InitDecodedCert(dCert, x->derCert->buffer, x->derCert->length, NULL);
13169
0
        ret = ParseCertRelative(dCert, CERT_TYPE, 0, NULL);
13170
0
        if (ret != 0) {
13171
0
            ret = WOLFSSL_FAILURE;
13172
0
        }
13173
0
        else {
13174
0
            ret = CheckIPAddr(dCert, ipasc);
13175
0
            if (ret != 0) {
13176
0
                ret = WOLFSSL_FAILURE;
13177
0
            }
13178
0
            else {
13179
0
                ret = WOLFSSL_SUCCESS;
13180
0
            }
13181
0
        }
13182
0
        FreeDecodedCert(dCert);
13183
0
    }
13184
13185
0
#ifdef WOLFSSL_SMALL_STACK
13186
0
    if (dCert != NULL)
13187
0
        XFREE(dCert, x->heap, DYNAMIC_TYPE_DCERT);
13188
0
#endif
13189
13190
0
    return ret;
13191
0
}
13192
#endif
13193
13194
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN)
13195
int wolfSSL_X509_check_email(WOLFSSL_X509 *x, const char *chk, size_t chkLen,
13196
                             unsigned int flags)
13197
{
13198
    WOLFSSL_X509_NAME *subjName;
13199
    int emailLen;
13200
    char *emailBuf;
13201
13202
    (void)flags;
13203
13204
    WOLFSSL_ENTER("wolfSSL_X509_check_email");
13205
13206
    if ((x == NULL) || (chk == NULL)) {
13207
        WOLFSSL_MSG("Invalid parameter");
13208
        return WOLFSSL_FAILURE;
13209
    }
13210
13211
    subjName = wolfSSL_X509_get_subject_name(x);
13212
    if (subjName == NULL)
13213
        return WOLFSSL_FAILURE;
13214
13215
    /* Call with NULL buffer to get required length. */
13216
    emailLen = wolfSSL_X509_NAME_get_text_by_NID(subjName, NID_emailAddress,
13217
                                                 NULL, 0);
13218
    if (emailLen < 0)
13219
        return WOLFSSL_FAILURE;
13220
13221
    ++emailLen; /* Add 1 for the NUL. */
13222
13223
    emailBuf = (char*)XMALLOC(emailLen, x->heap, DYNAMIC_TYPE_OPENSSL);
13224
    if (emailBuf == NULL)
13225
        return WOLFSSL_FAILURE;
13226
13227
    emailLen = wolfSSL_X509_NAME_get_text_by_NID(subjName, NID_emailAddress,
13228
                                                 emailBuf, emailLen);
13229
    if (emailLen < 0) {
13230
        XFREE(emailBuf, x->heap, DYNAMIC_TYPE_OPENSSL);
13231
        return WOLFSSL_FAILURE;
13232
    }
13233
13234
    if (chkLen == 0)
13235
        chkLen = XSTRLEN(chk);
13236
13237
    if (chkLen != (size_t)emailLen
13238
     || XSTRNCMP(chk, emailBuf, chkLen)) {
13239
        XFREE(emailBuf, x->heap, DYNAMIC_TYPE_OPENSSL);
13240
        return WOLFSSL_FAILURE;
13241
    }
13242
13243
    XFREE(emailBuf, x->heap, DYNAMIC_TYPE_OPENSSL);
13244
    return WOLFSSL_SUCCESS;
13245
}
13246
#endif /* OPENSSL_EXTRA && WOLFSSL_CERT_GEN */
13247
13248
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \
13249
    || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY)
13250
13251
int wolfSSL_X509_NAME_digest(const WOLFSSL_X509_NAME *name,
13252
        const WOLFSSL_EVP_MD *type, unsigned char *md, unsigned int *len)
13253
{
13254
    WOLFSSL_ENTER("wolfSSL_X509_NAME_digest");
13255
13256
    if (name == NULL || type == NULL)
13257
        return WOLFSSL_FAILURE;
13258
13259
#if !defined(NO_FILESYSTEM) && !defined(NO_PWDBASED)
13260
    return wolfSSL_EVP_Digest((unsigned char*)name->name,
13261
                              name->sz, md, len, type, NULL);
13262
#else
13263
    (void)md;
13264
    (void)len;
13265
    return NOT_COMPILED_IN;
13266
#endif
13267
}
13268
13269
#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY ||
13270
    OPENSSL_EXTRA || HAVE_LIGHTY */
13271
13272
#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
13273
    defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
13274
13275
/**
13276
 * Find the issuing cert of the input cert. On a self-signed cert this
13277
 * function will return an error.
13278
 * @param issuer The issuer x509 struct is returned here
13279
 * @param cm     The cert manager that is queried for the issuer
13280
 * @param x      This cert's issuer will be queried in cm
13281
 * @return       WOLFSSL_SUCCESS on success
13282
 *               WOLFSSL_FAILURE on error
13283
 */
13284
static int x509GetIssuerFromCM(WOLFSSL_X509 **issuer, WOLFSSL_CERT_MANAGER* cm,
13285
        WOLFSSL_X509 *x)
13286
{
13287
    Signer* ca = NULL;
13288
#ifdef WOLFSSL_SMALL_STACK
13289
    DecodedCert* cert = NULL;
13290
#else
13291
    DecodedCert  cert[1];
13292
#endif
13293
13294
    if (cm == NULL || x == NULL || x->derCert == NULL) {
13295
        WOLFSSL_MSG("No cert DER buffer or NULL cm. Defining "
13296
                    "WOLFSSL_SIGNER_DER_CERT could solve the issue");
13297
        return WOLFSSL_FAILURE;
13298
    }
13299
13300
#ifdef WOLFSSL_SMALL_STACK
13301
    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT);
13302
    if (cert == NULL)
13303
        return WOLFSSL_FAILURE;
13304
#endif
13305
13306
    /* Use existing CA retrieval APIs that use DecodedCert. */
13307
    InitDecodedCert(cert, x->derCert->buffer, x->derCert->length, NULL);
13308
    if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0
13309
            && !cert->selfSigned) {
13310
    #ifndef NO_SKID
13311
        if (cert->extAuthKeyIdSet)
13312
            ca = GetCA(cm, cert->extAuthKeyId);
13313
        if (ca == NULL)
13314
            ca = GetCAByName(cm, cert->issuerHash);
13315
    #else /* NO_SKID */
13316
        ca = GetCA(cm, cert->issuerHash);
13317
    #endif /* NO SKID */
13318
    }
13319
    FreeDecodedCert(cert);
13320
#ifdef WOLFSSL_SMALL_STACK
13321
    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
13322
#endif
13323
13324
    if (ca == NULL)
13325
        return WOLFSSL_FAILURE;
13326
13327
#ifdef WOLFSSL_SIGNER_DER_CERT
13328
    /* populate issuer with Signer DER */
13329
    if (wolfSSL_X509_d2i(issuer, ca->derCert->buffer,
13330
            ca->derCert->length) == NULL)
13331
        return WOLFSSL_FAILURE;
13332
#else
13333
    /* Create an empty certificate as CA doesn't have a certificate. */
13334
    *issuer = (WOLFSSL_X509 *)XMALLOC(sizeof(WOLFSSL_X509), 0,
13335
        DYNAMIC_TYPE_OPENSSL);
13336
    if (*issuer == NULL)
13337
        return WOLFSSL_FAILURE;
13338
13339
    InitX509((*issuer), 1, NULL);
13340
#endif
13341
13342
    return WOLFSSL_SUCCESS;
13343
}
13344
13345
void wolfSSL_X509_email_free(WOLF_STACK_OF(WOLFSSL_STRING) *sk)
13346
{
13347
    WOLFSSL_STACK *curr;
13348
13349
    while (sk != NULL) {
13350
        curr = sk;
13351
        sk = sk->next;
13352
13353
        XFREE(curr, NULL, DYNAMIC_TYPE_OPENSSL);
13354
    }
13355
}
13356
13357
WOLF_STACK_OF(WOLFSSL_STRING) *wolfSSL_X509_get1_ocsp(WOLFSSL_X509 *x)
13358
{
13359
    WOLFSSL_STACK* list = NULL;
13360
    char*          url;
13361
13362
    if (x == NULL || x->authInfoSz == 0)
13363
        return NULL;
13364
13365
    list = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK) + x->authInfoSz + 1,
13366
                                   NULL, DYNAMIC_TYPE_OPENSSL);
13367
    if (list == NULL)
13368
        return NULL;
13369
13370
    url = (char*)list;
13371
    url += sizeof(WOLFSSL_STACK);
13372
    XMEMCPY(url, x->authInfo, x->authInfoSz);
13373
    url[x->authInfoSz] = '\0';
13374
13375
    list->data.string = url;
13376
    list->next = NULL;
13377
    list->num = 1;
13378
13379
    return list;
13380
}
13381
13382
int wolfSSL_X509_check_issued(WOLFSSL_X509 *issuer, WOLFSSL_X509 *subject)
13383
{
13384
    WOLFSSL_X509_NAME *issuerName = wolfSSL_X509_get_issuer_name(subject);
13385
    WOLFSSL_X509_NAME *subjectName = wolfSSL_X509_get_subject_name(issuer);
13386
13387
    if (issuerName == NULL || subjectName == NULL)
13388
        return WOLFSSL_X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
13389
13390
    /* Literal matching of encoded names and key ids. */
13391
    if (issuerName->sz != subjectName->sz ||
13392
           XMEMCMP(issuerName->name, subjectName->name, subjectName->sz) != 0) {
13393
        return WOLFSSL_X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
13394
    }
13395
13396
    if (subject->authKeyId != NULL && issuer->subjKeyId != NULL) {
13397
        if (subject->authKeyIdSz != issuer->subjKeyIdSz ||
13398
                XMEMCMP(subject->authKeyId, issuer->subjKeyId,
13399
                        issuer->subjKeyIdSz) != 0) {
13400
            return WOLFSSL_X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
13401
        }
13402
    }
13403
13404
    return WOLFSSL_X509_V_OK;
13405
}
13406
13407
#endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */
13408
13409
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
13410
    defined(KEEP_PEER_CERT)
13411
WOLFSSL_X509* wolfSSL_X509_dup(WOLFSSL_X509 *x)
13412
{
13413
    WOLFSSL_ENTER("wolfSSL_X509_dup");
13414
13415
    if (x == NULL) {
13416
        WOLFSSL_MSG("Error: NULL input");
13417
        return NULL;
13418
    }
13419
13420
    if (x->derCert == NULL) {
13421
        WOLFSSL_MSG("Error: NULL derCert parameter");
13422
        return NULL;
13423
    }
13424
13425
    return wolfSSL_X509_d2i(NULL, x->derCert->buffer, x->derCert->length);
13426
}
13427
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
13428
13429
#if defined(OPENSSL_EXTRA)
13430
int wolfSSL_X509_check_ca(WOLFSSL_X509 *x509)
13431
{
13432
    WOLFSSL_ENTER("wolfSSL_X509_check_ca");
13433
13434
    if (x509 == NULL)
13435
        return WOLFSSL_FAILURE;
13436
    if (x509->isCa)
13437
        return 1;
13438
    if (x509->extKeyUsageCrit)
13439
        return 4;
13440
13441
    return 0;
13442
}
13443
#endif /* OPENSSL_EXTRA */
13444
13445
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
13446
long wolfSSL_X509_get_version(const WOLFSSL_X509 *x509)
13447
{
13448
    int version = 0;
13449
13450
    WOLFSSL_ENTER("wolfSSL_X509_get_version");
13451
13452
    if (x509 == NULL){
13453
        WOLFSSL_MSG("invalid parameter");
13454
        return 0L;
13455
    }
13456
    version = x509->version;
13457
    if (version != 0)
13458
        return (long)version - 1L;
13459
13460
    return 0L;
13461
}
13462
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
13463
13464
#if defined(OPENSSL_EXTRA)
13465
int wolfSSL_X509_get_signature_nid(const WOLFSSL_X509 *x)
13466
{
13467
    if (x == NULL)
13468
        return 0;
13469
13470
    return oid2nid(x->sigOID, oidSigType);
13471
}
13472
#endif  /* OPENSSL_EXTRA */
13473
13474
#if defined(OPENSSL_EXTRA)
13475
WOLFSSL_STACK* wolfSSL_sk_X509_new(WOLF_SK_COMPARE_CB(WOLFSSL_X509, cb))
13476
{
13477
    (void)cb;
13478
    return wolfSSL_sk_X509_new_null();
13479
}
13480
13481
WOLFSSL_STACK* wolfSSL_sk_X509_new_null(void)
13482
{
13483
    WOLFSSL_STACK* s = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
13484
            DYNAMIC_TYPE_OPENSSL);
13485
    if (s != NULL) {
13486
        XMEMSET(s, 0, sizeof(*s));
13487
        s->type = STACK_TYPE_X509;
13488
    }
13489
13490
    return s;
13491
}
13492
#endif  /* OPENSSL_EXTRA */
13493
13494
#ifdef OPENSSL_ALL
13495
13496
WOLFSSL_STACK* wolfSSL_sk_X509_OBJECT_new(void)
13497
{
13498
    WOLFSSL_STACK* s = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
13499
            DYNAMIC_TYPE_OPENSSL);
13500
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_new");
13501
    if (s != NULL) {
13502
        XMEMSET(s, 0, sizeof(*s));
13503
        s->type = STACK_TYPE_X509_OBJ;
13504
    }
13505
    return s;
13506
}
13507
13508
void wolfSSL_sk_X509_OBJECT_free(WOLFSSL_STACK* s)
13509
{
13510
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_free");
13511
    wolfSSL_sk_free(s);
13512
}
13513
13514
void wolfSSL_sk_X509_OBJECT_pop_free(WOLFSSL_STACK* s,
13515
        void (*f) (WOLFSSL_X509_OBJECT*))
13516
{
13517
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_pop_free");
13518
    wolfSSL_sk_pop_free(s, (wolfSSL_sk_freefunc)f);
13519
}
13520
13521
int wolfSSL_sk_X509_OBJECT_push(WOLFSSL_STACK* sk, WOLFSSL_X509_OBJECT* obj)
13522
{
13523
    WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_push");
13524
13525
    if (sk == NULL || obj == NULL) {
13526
        return WOLFSSL_FAILURE;
13527
    }
13528
13529
    return wolfSSL_sk_push(sk, obj);
13530
}
13531
13532
#endif /* OPENSSL_ALL */
13533
13534
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
13535
/* unlike wolfSSL_X509_NAME_dup this does not malloc a duplicate, only deep
13536
 * copy. "to" is expected to be a fresh blank name, if not pointers could be
13537
 * lost */
13538
int wolfSSL_X509_NAME_copy(WOLFSSL_X509_NAME* from, WOLFSSL_X509_NAME* to)
13539
{
13540
    int i;
13541
13542
    WOLFSSL_ENTER("wolfSSL_X509_NAME_copy");
13543
13544
    if (from == NULL || to == NULL) {
13545
        WOLFSSL_MSG("NULL parameter");
13546
        return BAD_FUNC_ARG;
13547
    }
13548
13549
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY)
13550
    if (from->rawLen > 0) {
13551
        if (from->rawLen > ASN_NAME_MAX) {
13552
            WOLFSSL_MSG("Bad raw size");
13553
            return BAD_FUNC_ARG;
13554
        }
13555
        XMEMCPY(to->raw, from->raw, from->rawLen);
13556
        to->rawLen = from->rawLen;
13557
    }
13558
#endif
13559
13560
    if (from->dynamicName) {
13561
        to->name = (char*)XMALLOC(from->sz, to->heap, DYNAMIC_TYPE_SUBJECT_CN);
13562
        if (to->name == NULL)
13563
            return WOLFSSL_FAILURE;
13564
        to->dynamicName = 1;
13565
    }
13566
    XMEMCPY(to->name, from->name, from->sz);
13567
    to->sz = from->sz;
13568
13569
    for (i = 0; i < MAX_NAME_ENTRIES; i++) {
13570
        WOLFSSL_X509_NAME_ENTRY* ne = wolfSSL_X509_NAME_get_entry(from, i);
13571
        if (ne != NULL) {
13572
            if (wolfSSL_X509_NAME_add_entry(to, ne, i, 1) != WOLFSSL_SUCCESS) {
13573
                return WOLFSSL_FAILURE;
13574
            }
13575
        }
13576
    }
13577
    to->entrySz = from->entrySz;
13578
    return WOLFSSL_SUCCESS;
13579
}
13580
13581
13582
/* copies over information from "name" to the "cert" subject name
13583
 * returns WOLFSSL_SUCCESS on success */
13584
int wolfSSL_X509_set_subject_name(WOLFSSL_X509 *cert, WOLFSSL_X509_NAME *name)
13585
{
13586
    WOLFSSL_ENTER("wolfSSL_X509_set_subject_name");
13587
    if (cert == NULL || name == NULL)
13588
        return WOLFSSL_FAILURE;
13589
13590
    FreeX509Name(&cert->subject);
13591
    InitX509Name(&cert->subject, 0, cert->heap);
13592
13593
    if (wolfSSL_X509_NAME_copy(name, &cert->subject) != WOLFSSL_SUCCESS) {
13594
        FreeX509Name(&cert->subject);
13595
        return WOLFSSL_FAILURE;
13596
    }
13597
13598
    cert->subject.x509 = cert;
13599
    return WOLFSSL_SUCCESS;
13600
}
13601
13602
13603
/* copies over information from "name" to the "cert" issuer name
13604
 * returns WOLFSSL_SUCCESS on success */
13605
int wolfSSL_X509_set_issuer_name(WOLFSSL_X509 *cert, WOLFSSL_X509_NAME *name)
13606
{
13607
    WOLFSSL_ENTER("wolfSSL_X509_set_issuer_name");
13608
    if (cert == NULL || name == NULL)
13609
        return WOLFSSL_FAILURE;
13610
13611
    FreeX509Name(&cert->issuer);
13612
    InitX509Name(&cert->issuer, 0, cert->heap);
13613
13614
    if (wolfSSL_X509_NAME_copy(name, &cert->issuer) != WOLFSSL_SUCCESS) {
13615
        FreeX509Name(&cert->issuer);
13616
        return WOLFSSL_FAILURE;
13617
    }
13618
13619
    cert->issuer.x509 = cert;
13620
    cert->issuerSet = 1;
13621
13622
    return WOLFSSL_SUCCESS;
13623
}
13624
13625
13626
int wolfSSL_X509_set_notAfter(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME* t)
13627
{
13628
    if (x509 == NULL || t == NULL) {
13629
        return WOLFSSL_FAILURE;
13630
    }
13631
13632
    x509->notAfter.type = t->type;
13633
    x509->notAfter.length = t->length;
13634
13635
    XMEMCPY(x509->notAfter.data, t->data, CTC_DATE_SIZE);
13636
13637
    return WOLFSSL_SUCCESS;
13638
}
13639
13640
int wolfSSL_X509_set_notBefore(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME* t)
13641
{
13642
    if (x509 == NULL || t == NULL) {
13643
        return WOLFSSL_FAILURE;
13644
    }
13645
13646
    x509->notBefore.type = t->type;
13647
    x509->notBefore.length = t->length;
13648
13649
    XMEMCPY(x509->notBefore.data, t->data, CTC_DATE_SIZE);
13650
13651
    return WOLFSSL_SUCCESS;
13652
}
13653
13654
int wolfSSL_X509_set_serialNumber(WOLFSSL_X509* x509, WOLFSSL_ASN1_INTEGER* s)
13655
{
13656
    WOLFSSL_ENTER("wolfSSL_X509_set_serialNumber");
13657
    if (x509 == NULL || s == NULL || s->length >= EXTERNAL_SERIAL_SIZE)
13658
        return WOLFSSL_FAILURE;
13659
13660
    /* WOLFSSL_ASN1_INTEGER has type | size | data
13661
     * Sanity check that the data is actually in ASN format */
13662
    if (s->length < 3 && s->data[0] != ASN_INTEGER &&
13663
            s->data[1] != s->length - 2) {
13664
        return WOLFSSL_FAILURE;
13665
    }
13666
    XMEMCPY(x509->serial, s->data + 2, s->length - 2);
13667
    x509->serialSz = s->length - 2;
13668
    x509->serial[s->length] = 0;
13669
13670
    return WOLFSSL_SUCCESS;
13671
}
13672
13673
13674
int wolfSSL_X509_set_pubkey(WOLFSSL_X509 *cert, WOLFSSL_EVP_PKEY *pkey)
13675
{
13676
    byte* p = NULL;
13677
    int derSz = 0;
13678
    WOLFSSL_ENTER("wolfSSL_X509_set_pubkey");
13679
13680
    if (cert == NULL || pkey == NULL)
13681
        return WOLFSSL_FAILURE;
13682
13683
    /* Regenerate since pkey->pkey.ptr may contain private key */
13684
    switch (pkey->type) {
13685
#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(NO_RSA)
13686
    case EVP_PKEY_RSA:
13687
        {
13688
            RsaKey* rsa;
13689
13690
            if (pkey->rsa == NULL || pkey->rsa->internal == NULL)
13691
                return WOLFSSL_FAILURE;
13692
13693
            rsa = (RsaKey*)pkey->rsa->internal;
13694
            derSz = wc_RsaPublicKeyDerSize(rsa, 1);
13695
            if (derSz <= 0)
13696
                return WOLFSSL_FAILURE;
13697
13698
            p = (byte*)XMALLOC(derSz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
13699
            if (p == NULL)
13700
                return WOLFSSL_FAILURE;
13701
13702
            if ((derSz = wc_RsaKeyToPublicDer(rsa, p, derSz)) <= 0) {
13703
                XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
13704
                return WOLFSSL_FAILURE;
13705
            }
13706
            cert->pubKeyOID = RSAk;
13707
        }
13708
        break;
13709
#endif /* (WOLFSSL_KEY_GEN || OPENSSL_EXTRA) && !NO_RSA */
13710
#if !defined(HAVE_SELFTEST) && (defined(WOLFSSL_KEY_GEN) || \
13711
        defined(WOLFSSL_CERT_GEN)) && !defined(NO_DSA)
13712
    case EVP_PKEY_DSA:
13713
        {
13714
            DsaKey* dsa;
13715
13716
            if (pkey->dsa == NULL || pkey->dsa->internal == NULL)
13717
                return WOLFSSL_FAILURE;
13718
13719
            dsa = (DsaKey*)pkey->dsa->internal;
13720
            /* size of pub, priv, p, q, g + ASN.1 additional information */
13721
            derSz = 5 * mp_unsigned_bin_size(&dsa->g) + MAX_ALGO_SZ;
13722
            p = (byte*)XMALLOC(derSz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
13723
            if (p == NULL)
13724
                return WOLFSSL_FAILURE;
13725
13726
            if ((derSz = wc_DsaKeyToPublicDer(dsa, p, derSz)) <= 0) {
13727
                XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
13728
                return WOLFSSL_FAILURE;
13729
            }
13730
            cert->pubKeyOID = RSAk;
13731
        }
13732
        break;
13733
#endif /* !HAVE_SELFTEST && (WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN) && !NO_DSA */
13734
#ifdef HAVE_ECC
13735
    case EVP_PKEY_EC:
13736
        {
13737
            ecc_key* ecc;
13738
13739
            if (pkey->ecc == NULL || pkey->ecc->internal == NULL)
13740
                return WOLFSSL_FAILURE;
13741
13742
            ecc = (ecc_key*)pkey->ecc->internal;
13743
            derSz = wc_EccPublicKeyDerSize(ecc, 1);
13744
            if (derSz <= 0)
13745
                return WOLFSSL_FAILURE;
13746
13747
            p = (byte*)XMALLOC(derSz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
13748
            if (p == NULL)
13749
                return WOLFSSL_FAILURE;
13750
13751
            if ((derSz = wc_EccPublicKeyToDer(ecc, p, derSz, 1)) <= 0) {
13752
                XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
13753
                return WOLFSSL_FAILURE;
13754
            }
13755
            cert->pubKeyOID = ECDSAk;
13756
        }
13757
        break;
13758
#endif
13759
    default:
13760
        return WOLFSSL_FAILURE;
13761
    }
13762
    cert->pubKey.buffer = p;
13763
    cert->pubKey.length = derSz;
13764
13765
    return WOLFSSL_SUCCESS;
13766
}
13767
13768
int wolfSSL_X509_set_version(WOLFSSL_X509* x509, long v)
13769
{
13770
    WOLFSSL_ENTER("wolfSSL_X509_set_version");
13771
    if ((x509 == NULL) || (v < 0) || (v >= INT_MAX)) {
13772
        return WOLFSSL_FAILURE;
13773
    }
13774
    x509->version = (int) v + 1;
13775
13776
    return WOLFSSL_SUCCESS;
13777
}
13778
13779
#endif /* (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) && WOLFSSL_CERT_GEN */
13780
13781
#if defined(OPENSSL_ALL) && \
13782
    defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ)
13783
13784
void wolfSSL_X509V3_set_ctx(WOLFSSL_X509V3_CTX* ctx, WOLFSSL_X509* issuer,
13785
        WOLFSSL_X509* subject, WOLFSSL_X509* req, WOLFSSL_X509_CRL* crl,
13786
        int flag)
13787
{
13788
    int ret = WOLFSSL_SUCCESS;
13789
    WOLFSSL_ENTER("wolfSSL_X509V3_set_ctx");
13790
    if (!ctx)
13791
        return;
13792
13793
    /* not checking ctx->x509 for null first since app won't have initialized
13794
     * this X509V3_CTX before this function call */
13795
    ctx->x509 = wolfSSL_X509_new();
13796
    if (!ctx->x509)
13797
        return;
13798
13799
    /* Set parameters in ctx as long as ret == WOLFSSL_SUCCESS */
13800
    if (issuer)
13801
        ret = wolfSSL_X509_set_issuer_name(ctx->x509,&issuer->issuer);
13802
13803
    if (subject && ret == WOLFSSL_SUCCESS)
13804
        ret = wolfSSL_X509_set_subject_name(ctx->x509,&subject->subject);
13805
13806
    if (req && ret == WOLFSSL_SUCCESS) {
13807
        WOLFSSL_MSG("req not implemented.");
13808
    }
13809
13810
    if (crl && ret == WOLFSSL_SUCCESS) {
13811
        WOLFSSL_MSG("crl not implemented.");
13812
    }
13813
13814
    if (flag && ret == WOLFSSL_SUCCESS) {
13815
        WOLFSSL_MSG("flag not implemented.");
13816
    }
13817
13818
    if (!ret) {
13819
        WOLFSSL_MSG("Error setting WOLFSSL_X509V3_CTX parameters.");
13820
    }
13821
}
13822
13823
#ifndef NO_BIO
13824
int wolfSSL_i2d_X509_REQ(WOLFSSL_X509* req, unsigned char** out)
13825
{
13826
    int derSz = 0;
13827
    int ret = WOLFSSL_FAILURE;
13828
    WOLFSSL_BIO* bio = NULL;
13829
    WOLFSSL_ENTER("wolfSSL_i2d_X509_REQ");
13830
13831
    if (req == NULL || out == NULL) {
13832
        return BAD_FUNC_ARG;
13833
    }
13834
13835
    if (!(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()))) {
13836
        return WOLFSSL_FAILURE;
13837
    }
13838
13839
    if (wolfSSL_i2d_X509_REQ_bio(bio, req) != WOLFSSL_SUCCESS) {
13840
        WOLFSSL_MSG("wolfSSL_i2d_X509_REQ_bio error");
13841
        goto cleanup;
13842
    }
13843
13844
    derSz = wolfSSL_BIO_get_len(bio);
13845
13846
    if (*out == NULL) {
13847
        *out = (unsigned char*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL);
13848
        if (!*out) {
13849
            WOLFSSL_MSG("malloc error");
13850
            ret = MEMORY_E;
13851
            goto cleanup;
13852
        }
13853
    }
13854
13855
    if (wolfSSL_BIO_read(bio, *out, derSz) != derSz) {
13856
        WOLFSSL_MSG("wolfSSL_BIO_read error");
13857
        goto cleanup;
13858
    }
13859
13860
    ret = derSz;
13861
cleanup:
13862
    wolfSSL_BIO_free(bio);
13863
13864
    return ret;
13865
}
13866
#endif /* !NO_BIO */
13867
13868
WOLFSSL_X509* wolfSSL_X509_REQ_new(void)
13869
{
13870
    return wolfSSL_X509_new();
13871
}
13872
13873
void wolfSSL_X509_REQ_free(WOLFSSL_X509* req)
13874
{
13875
    wolfSSL_X509_free(req);
13876
}
13877
13878
int wolfSSL_X509_REQ_sign(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey,
13879
                          const WOLFSSL_EVP_MD *md)
13880
{
13881
    int ret;
13882
#ifdef WOLFSSL_SMALL_STACK
13883
    byte* der = NULL;
13884
#else
13885
    byte der[2048];
13886
#endif
13887
    int derSz = 2048;
13888
13889
    if (req == NULL || pkey == NULL || md == NULL) {
13890
        WOLFSSL_LEAVE("wolfSSL_X509_REQ_sign", BAD_FUNC_ARG);
13891
        return WOLFSSL_FAILURE;
13892
    }
13893
13894
#ifdef WOLFSSL_SMALL_STACK
13895
    der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13896
    if (der == NULL) {
13897
        return WOLFSSL_FAILURE;
13898
    }
13899
#endif
13900
13901
    /* Create a Cert that has the certificate request fields. */
13902
    req->sigOID = wolfSSL_sigTypeFromPKEY((WOLFSSL_EVP_MD*)md, pkey);
13903
    ret = wolfssl_x509_make_der(req, 1, der, &derSz, 0);
13904
    if (ret != WOLFSSL_SUCCESS) {
13905
#ifdef WOLFSSL_SMALL_STACK
13906
        XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13907
#endif
13908
        WOLFSSL_MSG("Unable to make DER for X509");
13909
        WOLFSSL_LEAVE("wolfSSL_X509_REQ_sign", ret);
13910
        return WOLFSSL_FAILURE;
13911
    }
13912
13913
    if (wolfSSL_X509_resign_cert(req, 1, der, 2048, derSz,
13914
            (WOLFSSL_EVP_MD*)md, pkey) <= 0) {
13915
#ifdef WOLFSSL_SMALL_STACK
13916
        XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13917
#endif
13918
        return WOLFSSL_FAILURE;
13919
    }
13920
#ifdef WOLFSSL_SMALL_STACK
13921
    XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13922
#endif
13923
    return WOLFSSL_SUCCESS;
13924
}
13925
13926
int wolfSSL_X509_REQ_sign_ctx(WOLFSSL_X509 *req,
13927
                              WOLFSSL_EVP_MD_CTX* md_ctx)
13928
{
13929
    if (md_ctx && md_ctx->pctx)
13930
        return wolfSSL_X509_REQ_sign(req, md_ctx->pctx->pkey,
13931
                wolfSSL_EVP_MD_CTX_md(md_ctx));
13932
    else
13933
        return WOLFSSL_FAILURE;
13934
}
13935
13936
static int regenX509REQDerBuffer(WOLFSSL_X509* x509)
13937
{
13938
    int derSz = X509_BUFFER_SZ;
13939
    int ret = WOLFSSL_FAILURE;
13940
#ifdef WOLFSSL_SMALL_STACK
13941
    byte* der;
13942
    der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13943
    if (!der) {
13944
        WOLFSSL_MSG("malloc failed");
13945
        return WOLFSSL_FAILURE;
13946
    }
13947
#else
13948
    byte der[X509_BUFFER_SZ];
13949
#endif
13950
13951
    if (wolfssl_x509_make_der(x509, 1, der, &derSz, 0) == WOLFSSL_SUCCESS) {
13952
        FreeDer(&x509->derCert);
13953
        if (AllocDer(&x509->derCert, derSz, CERT_TYPE, x509->heap) == 0) {
13954
            XMEMCPY(x509->derCert->buffer, der, derSz);
13955
            ret = WOLFSSL_SUCCESS;
13956
        }
13957
        else {
13958
            WOLFSSL_MSG("Failed to allocate DER buffer for X509");
13959
        }
13960
    }
13961
    else {
13962
        WOLFSSL_MSG("Unable to make DER for X509 REQ");
13963
    }
13964
#ifdef WOLFSSL_SMALL_STACK
13965
    XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13966
#endif
13967
    return ret;
13968
}
13969
13970
int wolfSSL_X509_REQ_add_extensions(WOLFSSL_X509* req,
13971
        WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* ext_sk)
13972
{
13973
    WOLFSSL_X509_EXTENSION* ext = NULL;
13974
13975
    if (!req || !ext_sk) {
13976
        WOLFSSL_MSG("Bad parameter");
13977
        return WOLFSSL_FAILURE;
13978
    }
13979
13980
    /* It is not an error if the stack is empty. */
13981
    ext = ext_sk->data.ext;
13982
    if (ext == NULL) {
13983
        return WOLFSSL_SUCCESS;
13984
    }
13985
13986
    while (ext_sk) {
13987
        ext = ext_sk->data.ext;
13988
13989
        if (wolfSSL_X509_add_ext(req, ext, -1) != WOLFSSL_SUCCESS) {
13990
            WOLFSSL_MSG("wolfSSL_X509_add_ext error");
13991
            return WOLFSSL_FAILURE;
13992
        }
13993
13994
        ext_sk = ext_sk->next;
13995
    }
13996
13997
    return regenX509REQDerBuffer(req);
13998
}
13999
14000
int wolfSSL_X509_REQ_add1_attr_by_txt(WOLFSSL_X509 *req,
14001
                              const char *attrname, int type,
14002
                              const unsigned char *bytes, int len)
14003
{
14004
    WOLFSSL_ENTER("wolfSSL_X509_REQ_add1_attr_by_txt");
14005
14006
#ifdef HAVE_LIBEST
14007
    if (!req || !attrname || !bytes || type != MBSTRING_ASC) {
14008
        WOLFSSL_MSG("Bad parameter");
14009
        return WOLFSSL_FAILURE;
14010
    }
14011
14012
    if (len < 0) {
14013
        len = (int)XSTRLEN((char*)bytes);
14014
    }
14015
14016
    /* For now just pretend that we support this for libest testing */
14017
    if (len == XSTR_SIZEOF("1.3.6.1.1.1.1.22") &&
14018
            XMEMCMP("1.3.6.1.1.1.1.22", bytes, len) == 0) {
14019
        /* MAC Address */
14020
    }
14021
    else if (len == XSTR_SIZEOF("1.2.840.10045.2.1") &&
14022
            XMEMCMP("1.2.840.10045.2.1", bytes, len) == 0) {
14023
        /* ecPublicKey */
14024
    }
14025
    else if (len == XSTR_SIZEOF("1.2.840.10045.4.3.3") &&
14026
            XMEMCMP("1.2.840.10045.4.3.3", bytes, len) == 0) {
14027
        /* ecdsa-with-SHA384 */
14028
    }
14029
    else {
14030
        return WOLFSSL_FAILURE;
14031
    }
14032
14033
    /* return error if not built for libest */
14034
    return WOLFSSL_SUCCESS;
14035
#else
14036
    (void)req;
14037
    (void)attrname;
14038
    (void)type;
14039
    (void)bytes;
14040
    (void)len;
14041
    return WOLFSSL_FAILURE;
14042
#endif
14043
}
14044
14045
14046
static int wolfSSL_X509_ATTRIBUTE_set(WOLFSSL_X509_ATTRIBUTE* attr,
14047
        const char* data, int dataSz, int type, int nid)
14048
{
14049
    if (attr) {
14050
        attr->value->value.asn1_string = wolfSSL_ASN1_STRING_new();
14051
        if (wolfSSL_ASN1_STRING_set(attr->value->value.asn1_string,
14052
                data, dataSz) != WOLFSSL_SUCCESS) {
14053
            wolfSSL_ASN1_STRING_free(attr->value->value.asn1_string);
14054
            WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
14055
            return WOLFSSL_FAILURE;
14056
        }
14057
        attr->value->type = type;
14058
        attr->object->nid = nid;
14059
    }
14060
    else {
14061
        WOLFSSL_MSG("wolfSSL_X509_ATTRIBUTE_new error");
14062
        return WOLFSSL_FAILURE;
14063
    }
14064
14065
    return WOLFSSL_SUCCESS;
14066
}
14067
14068
14069
int wolfSSL_X509_REQ_add1_attr_by_NID(WOLFSSL_X509 *req,
14070
                                      int nid, int type,
14071
                                      const unsigned char *bytes,
14072
                                      int len)
14073
{
14074
    int ret;
14075
    WOLFSSL_X509_ATTRIBUTE* attr;
14076
14077
    WOLFSSL_ENTER("wolfSSL_X509_REQ_add1_attr_by_NID");
14078
14079
    if (!req || !bytes || type != MBSTRING_ASC) {
14080
        WOLFSSL_MSG("Bad parameter");
14081
        return WOLFSSL_FAILURE;
14082
    }
14083
14084
    switch (nid) {
14085
    case NID_pkcs9_challengePassword:
14086
        if (len < 0)
14087
            len = (int)XSTRLEN((char*)bytes);
14088
        if (len < CTC_NAME_SIZE) {
14089
            XMEMCPY(req->challengePw, bytes, len);
14090
            req->challengePw[len] = '\0';
14091
        }
14092
        else {
14093
            WOLFSSL_MSG("Challenge password too long");
14094
            WOLFSSL_ERROR_VERBOSE(BUFFER_E);
14095
            return WOLFSSL_FAILURE;
14096
        }
14097
        break;
14098
    case NID_serialNumber:
14099
        if (len < 0)
14100
            len = (int)XSTRLEN((char*)bytes);
14101
        if (len + 1 > EXTERNAL_SERIAL_SIZE) {
14102
            WOLFSSL_MSG("SerialNumber too long");
14103
            WOLFSSL_ERROR_VERBOSE(BUFFER_E);
14104
            return WOLFSSL_FAILURE;
14105
        }
14106
        XMEMCPY(req->serial, bytes, len);
14107
        req->serialSz = len;
14108
        break;
14109
14110
    case NID_pkcs9_unstructuredName:
14111
    case NID_pkcs9_contentType:
14112
    case NID_surname:
14113
    case NID_initials:
14114
    case NID_givenName:
14115
    case NID_dnQualifier:
14116
        break;
14117
14118
    default:
14119
        WOLFSSL_MSG("Unsupported attribute");
14120
        return WOLFSSL_FAILURE;
14121
    }
14122
14123
    attr = wolfSSL_X509_ATTRIBUTE_new();
14124
    ret = wolfSSL_X509_ATTRIBUTE_set(attr, (const char*)bytes, len,
14125
            V_ASN1_PRINTABLESTRING, nid);
14126
    if (ret != WOLFSSL_SUCCESS) {
14127
        wolfSSL_X509_ATTRIBUTE_free(attr);
14128
    }
14129
    else {
14130
        if (req->reqAttributes == NULL) {
14131
            req->reqAttributes = wolfSSL_sk_new_node(req->heap);
14132
            if (req->reqAttributes != NULL) {
14133
                req->reqAttributes->type = STACK_TYPE_X509_REQ_ATTR;
14134
            }
14135
        }
14136
        ret = wolfSSL_sk_push(req->reqAttributes, attr);
14137
        if ((ret != WOLFSSL_SUCCESS) || (req->reqAttributes->type == STACK_TYPE_CIPHER)) {
14138
            /* CIPHER type makes a copy */
14139
            wolfSSL_X509_ATTRIBUTE_free(attr);
14140
        }
14141
    }
14142
14143
    return ret;
14144
}
14145
14146
WOLFSSL_X509 *wolfSSL_X509_to_X509_REQ(WOLFSSL_X509 *x,
14147
        WOLFSSL_EVP_PKEY *pkey, const WOLFSSL_EVP_MD *md)
14148
{
14149
    WOLFSSL_ENTER("wolfSSL_X509_to_X509_REQ");
14150
    (void)pkey;
14151
    (void)md;
14152
    return wolfSSL_X509_dup(x);
14153
}
14154
14155
int wolfSSL_X509_REQ_set_subject_name(WOLFSSL_X509 *req,
14156
                                      WOLFSSL_X509_NAME *name)
14157
{
14158
    return wolfSSL_X509_set_subject_name(req, name);
14159
}
14160
14161
int wolfSSL_X509_REQ_set_pubkey(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey)
14162
{
14163
    return wolfSSL_X509_set_pubkey(req, pkey);
14164
}
14165
#endif /* OPENSSL_ALL && WOLFSSL_CERT_GEN && WOLFSSL_CERT_REQ */
14166
14167
#if (defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)) && \
14168
    (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_REQ))
14169
14170
WOLFSSL_ASN1_TYPE *wolfSSL_X509_ATTRIBUTE_get0_type(
14171
        WOLFSSL_X509_ATTRIBUTE *attr, int idx)
14172
{
14173
    WOLFSSL_ENTER("wolfSSL_X509_ATTRIBUTE_get0_type");
14174
14175
    if (!attr || idx != 0) {
14176
        WOLFSSL_MSG("Bad parameter");
14177
        return NULL;
14178
    }
14179
14180
    return attr->value;
14181
}
14182
14183
14184
/**
14185
 * @param req X509_REQ containing attribute
14186
 * @return the number of attributes
14187
 */
14188
int wolfSSL_X509_REQ_get_attr_count(const WOLFSSL_X509 *req)
14189
{
14190
    if (req == NULL || req->reqAttributes == NULL)
14191
        return 0;
14192
14193
    return wolfSSL_sk_num(req->reqAttributes);
14194
}
14195
14196
14197
/**
14198
 * @param req X509_REQ containing attribute
14199
 * @param loc NID of the attribute to return
14200
 */
14201
WOLFSSL_X509_ATTRIBUTE *wolfSSL_X509_REQ_get_attr(
14202
        const WOLFSSL_X509 *req, int loc)
14203
{
14204
    WOLFSSL_ENTER("wolfSSL_X509_REQ_get_attr");
14205
14206
    if (!req || req->reqAttributes == NULL) {
14207
        WOLFSSL_MSG("Bad parameter");
14208
        return NULL;
14209
    }
14210
14211
    return (WOLFSSL_X509_ATTRIBUTE*)wolfSSL_sk_value(req->reqAttributes, loc);
14212
}
14213
14214
/* Return NID as the attr index */
14215
int wolfSSL_X509_REQ_get_attr_by_NID(const WOLFSSL_X509 *req,
14216
        int nid, int lastpos)
14217
{
14218
    WOLFSSL_STACK* sk;
14219
    int idx;
14220
14221
    WOLFSSL_ENTER("wolfSSL_X509_REQ_get_attr_by_NID");
14222
14223
    if (!req) {
14224
        WOLFSSL_MSG("Bad parameter");
14225
        return WOLFSSL_FATAL_ERROR;
14226
    }
14227
14228
    /* search through stack for first matching nid */
14229
    idx = lastpos + 1;
14230
    do {
14231
        sk = wolfSSL_sk_get_node(req->reqAttributes, idx);
14232
        if (sk != NULL) {
14233
            WOLFSSL_X509_ATTRIBUTE* attr;
14234
            attr = (WOLFSSL_X509_ATTRIBUTE*)sk->data.generic;
14235
            if (nid == attr->object->nid) {
14236
                /* found a match */
14237
                break;
14238
            }
14239
        }
14240
        idx++;
14241
    } while (sk != NULL);
14242
14243
    /* no matches found */
14244
    if (sk == NULL) {
14245
        idx = WOLFSSL_FATAL_ERROR;
14246
    }
14247
14248
    return idx;
14249
}
14250
14251
WOLFSSL_X509_ATTRIBUTE* wolfSSL_X509_ATTRIBUTE_new(void)
14252
{
14253
    WOLFSSL_X509_ATTRIBUTE* ret;
14254
    WOLFSSL_ENTER("wolfSSL_X509_ATTRIBUTE_new");
14255
    ret = (WOLFSSL_X509_ATTRIBUTE*)XMALLOC(sizeof(WOLFSSL_X509_ATTRIBUTE),
14256
            NULL, DYNAMIC_TYPE_OPENSSL);
14257
    if (!ret) {
14258
        WOLFSSL_MSG("malloc error");
14259
        return NULL;
14260
    }
14261
    XMEMSET(ret, 0, sizeof(WOLFSSL_X509_ATTRIBUTE));
14262
    ret->object = wolfSSL_ASN1_OBJECT_new();
14263
    ret->value = wolfSSL_ASN1_TYPE_new();
14264
    /* Don't allocate ret->set since WOLFSSL_ASN1_TYPE
14265
     * is not supported as a stack type */
14266
    if (!ret->object || !ret->value) {
14267
        WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new or wolfSSL_ASN1_TYPE_new error");
14268
        wolfSSL_X509_ATTRIBUTE_free(ret);
14269
        return NULL;
14270
    }
14271
    return ret;
14272
}
14273
14274
void wolfSSL_X509_ATTRIBUTE_free(WOLFSSL_X509_ATTRIBUTE* attr)
14275
{
14276
    WOLFSSL_ENTER("wolfSSL_X509_ATTRIBUTE_free");
14277
    if (attr) {
14278
        if (attr->object) {
14279
            wolfSSL_ASN1_OBJECT_free(attr->object);
14280
        }
14281
        if (attr->value) {
14282
            wolfSSL_ASN1_TYPE_free(attr->value);
14283
        }
14284
        if (attr->set) {
14285
            wolfSSL_sk_pop_free(attr->set, NULL);
14286
        }
14287
        XFREE(attr, NULL, DYNAMIC_TYPE_OPENSSL);
14288
    }
14289
}
14290
#endif
14291
14292
#endif /* !NO_CERT */
14293
14294
#endif /* !WOLFCRYPT_ONLY */
14295
14296
#endif /* WOLFSSL_X509_INCLUDED */