Coverage Report

Created: 2022-08-24 06:26

/src/wolfssl-sp-math/wolfcrypt/src/asn.c
Line
Count
Source (jump to first uncovered line)
1
/* asn.c
2
 *
3
 * Copyright (C) 2006-2022 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
 * DESCRIPTION
24
 * This library provides the interface to Abstract Syntax Notation One (ASN.1)
25
 * objects.
26
 * ASN.1 is a standard interface description language for defining data
27
 * structures that can be serialized and deserialized in a cross-platform way.
28
 *
29
 * Encoding of ASN.1 is either using Basic Encoding Rules (BER) or
30
 * Distinguished Encoding Rules (DER). DER has only one possible encoding for a
31
 * ASN.1 description and the data.
32
 * Encode using DER and decode BER or DER.
33
 *
34
 * Provides routines to convert BER into DER. Replaces indefinite length
35
 * encoded items with explicit lengths.
36
 */
37
#ifdef HAVE_CONFIG_H
38
    #include <config.h>
39
#endif
40
41
#include <wolfssl/wolfcrypt/settings.h>
42
43
/*
44
ASN Options:
45
 * NO_ASN_TIME: Disables time parts of the ASN code for systems without an RTC
46
    or wishing to save space.
47
 * IGNORE_NAME_CONSTRAINTS: Skip ASN name checks.
48
 * ASN_DUMP_OID: Allows dump of OID information for debugging.
49
 * RSA_DECODE_EXTRA: Decodes extra information in RSA public key.
50
 * WOLFSSL_CERT_GEN: Cert generation. Saves extra certificate info in GetName.
51
 * WOLFSSL_NO_ASN_STRICT: Disable strict RFC compliance checks to
52
    restore 3.13.0 behavior.
53
 * WOLFSSL_NO_OCSP_OPTIONAL_CERTS: Skip optional OCSP certs (responder issuer
54
    must still be trusted)
55
 * WOLFSSL_NO_TRUSTED_CERTS_VERIFY: Workaround for situation where entire cert
56
    chain is not loaded. This only matches on subject and public key and
57
    does not perform a PKI validation, so it is not a secure solution.
58
    Only enabled for OCSP.
59
 * WOLFSSL_NO_OCSP_ISSUER_CHECK: Can be defined for backwards compatibility to
60
    disable checking of OCSP subject hash with issuer hash.
61
 * WOLFSSL_SMALL_CERT_VERIFY: Verify the certificate signature without using
62
    DecodedCert. Doubles up on some code but allows smaller dynamic memory
63
    usage.
64
 * WOLFSSL_NO_OCSP_DATE_CHECK: Disable date checks for OCSP responses. This
65
    may be required when the system's real-time clock is not very accurate.
66
    It is recommended to enforce the nonce check instead if possible.
67
 * WOLFSSL_FORCE_OCSP_NONCE_CHECK: Require nonces to be available in OCSP
68
    responses. The nonces are optional and may not be supported by all
69
    responders. If it can be ensured that the used responder sends nonces this
70
    option may improve security.
71
 * WOLFSSL_ASN_TEMPLATE: Encoding and decoding using a template.
72
 * WOLFSSL_DEBUG_ASN_TEMPLATE: Enables debugging output when using ASN.1
73
    templates.
74
 * WOLFSSL_ASN_TEMPLATE_TYPE_CHECK: Use ASN functions to better test compiler
75
    type issues for testing
76
 * CRLDP_VALIDATE_DATA: For ASN template only, validates the reason data
77
 * WOLFSSL_AKID_NAME: Enable support for full AuthorityKeyIdentifier extension.
78
    Only supports copying full AKID from an existing certificate.
79
 * WOLFSSL_CUSTOM_OID: Enable custom OID support for subject and request
80
    extensions
81
 * WOLFSSL_HAVE_ISSUER_NAMES: Store pointers to issuer name components and their
82
    lengths and encodings.
83
 * WOLFSSL_SUBJ_DIR_ATTR: Enable support for SubjectDirectoryAttributes
84
    extension.
85
 * WOLFSSL_SUBJ_INFO_ACC: Enable support for SubjectInfoAccess extension.
86
 * WOLFSSL_FPKI: Enable support for FPKI (Federal PKI) extensions.
87
 * WOLFSSL_CERT_NAME_ALL: Adds more certificate name capability at the
88
    cost of taking up more memory. Adds initials, givenname, dnQualifer for
89
    example.
90
*/
91
92
#ifndef NO_ASN
93
#include <wolfssl/wolfcrypt/asn.h>
94
#include <wolfssl/wolfcrypt/coding.h>
95
#include <wolfssl/wolfcrypt/md2.h>
96
#include <wolfssl/wolfcrypt/hmac.h>
97
#include <wolfssl/wolfcrypt/error-crypt.h>
98
#include <wolfssl/wolfcrypt/pwdbased.h>
99
#include <wolfssl/wolfcrypt/des3.h>
100
#include <wolfssl/wolfcrypt/aes.h>
101
#include <wolfssl/wolfcrypt/rc2.h>
102
#include <wolfssl/wolfcrypt/wc_encrypt.h>
103
#include <wolfssl/wolfcrypt/logging.h>
104
105
#include <wolfssl/wolfcrypt/random.h>
106
#include <wolfssl/wolfcrypt/hash.h>
107
#ifdef NO_INLINE
108
    #include <wolfssl/wolfcrypt/misc.h>
109
#else
110
    #define WOLFSSL_MISC_INCLUDED
111
    #include <wolfcrypt/src/misc.c>
112
#endif
113
114
#ifndef NO_RC4
115
    #include <wolfssl/wolfcrypt/arc4.h>
116
#endif
117
118
#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
119
    #include <wolfssl/wolfcrypt/sha512.h>
120
#endif
121
122
#ifndef NO_SHA256
123
    #include <wolfssl/wolfcrypt/sha256.h>
124
#endif
125
126
#ifdef HAVE_ECC
127
    #include <wolfssl/wolfcrypt/ecc.h>
128
#endif
129
130
#ifdef HAVE_ED25519
131
    #include <wolfssl/wolfcrypt/ed25519.h>
132
#endif
133
#ifdef HAVE_CURVE25519
134
    #include <wolfssl/wolfcrypt/curve25519.h>
135
#endif
136
137
#ifdef HAVE_ED448
138
    #include <wolfssl/wolfcrypt/ed448.h>
139
#endif
140
#ifdef HAVE_CURVE448
141
    #include <wolfssl/wolfcrypt/curve448.h>
142
#endif
143
144
#ifdef HAVE_PQC
145
    #if defined(HAVE_FALCON)
146
    #include <wolfssl/wolfcrypt/falcon.h>
147
    #endif
148
    #if defined(HAVE_DILITHIUM)
149
    #include <wolfssl/wolfcrypt/dilithium.h>
150
    #endif
151
#endif
152
153
#ifdef WOLFSSL_QNX_CAAM
154
    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
155
#endif
156
157
#if defined(WOLFSSL_RENESAS_SCEPROTECT) || defined(WOLFSSL_RENESAS_TSIP_TLS)
158
    #include <wolfssl/wolfcrypt/port/Renesas/renesas_cmn.h>
159
#endif
160
161
#ifndef NO_RSA
162
    #include <wolfssl/wolfcrypt/rsa.h>
163
#if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_CRYPTOCELL)
164
extern int wc_InitRsaHw(RsaKey* key);
165
#endif
166
#endif
167
168
#ifndef NO_DSA
169
    #include <wolfssl/wolfcrypt/dsa.h>
170
#else
171
    typedef void* DsaKey;
172
#endif
173
174
#ifdef WOLF_CRYPTO_CB
175
    #include <wolfssl/wolfcrypt/cryptocb.h>
176
#endif
177
178
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
179
    #include <wolfssl/internal.h>
180
    #include <wolfssl/openssl/objects.h>
181
#endif
182
183
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
184
        !defined(WOLFCRYPT_ONLY)
185
    #define WOLFSSL_X509_NAME_AVAILABLE
186
#endif
187
188
#ifdef _MSC_VER
189
    /* 4996 warning to use MS extensions e.g., strcpy_s instead of XSTRNCPY */
190
    #pragma warning(disable: 4996)
191
#endif
192
193
0
#define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; }
194
195
#if !defined(NO_SKID) && (!defined(HAVE_FIPS) || !defined(HAVE_FIPS_VERSION))
196
    #if !defined(HAVE_SELFTEST) || (defined(HAVE_SELFTEST) && \
197
                                   (!defined(HAVE_SELFTEST_VERSION) || \
198
                                    HAVE_SELFTEST_VERSION < 2))
199
    #ifndef WOLFSSL_AES_KEY_SIZE_ENUM
200
    #define WOLFSSL_AES_KEY_SIZE_ENUM
201
    enum Asn_Misc {
202
        AES_IV_SIZE         = 16,
203
        AES_128_KEY_SIZE    = 16,
204
        AES_192_KEY_SIZE    = 24,
205
        AES_256_KEY_SIZE    = 32
206
    };
207
    #endif
208
    #endif /* HAVE_SELFTEST */
209
#endif
210
211
212
/* Calculates the minimum number of bytes required to encode the value.
213
 *
214
 * @param [in] value  Value to be encoded.
215
 * @return  Number of bytes to encode value.
216
 */
217
static word32 BytePrecision(word32 value)
218
829
{
219
829
    word32 i;
220
3.31k
    for (i = (word32)sizeof(value); i; --i)
221
3.31k
        if (value >> ((i - 1) * WOLFSSL_BIT_SIZE))
222
829
            break;
223
224
829
    return i;
225
829
}
226
227
/* DER encodes the length value in output buffer.
228
 *
229
 *    0 ->  2^7-1: <len byte>.
230
 *  2^7 ->       : <0x80 + #bytes> <len big-endian bytes>
231
 *
232
 * @param [in]      length  Value to encode.
233
 * @param [in, out] output  Buffer to encode into.
234
 * @return  Number of bytes used in encoding.
235
 */
236
WOLFSSL_LOCAL word32 SetASNLength(word32 length, byte* output)
237
0
{
238
0
    word32 i = 0, j;
239
240
0
    if (length < ASN_LONG_LENGTH)
241
0
        output[i++] = (byte)length;
242
0
    else {
243
0
        output[i++] = (byte)(BytePrecision(length) | ASN_LONG_LENGTH);
244
245
0
        for (j = BytePrecision(length); j; --j) {
246
0
            output[i] = (byte)(length >> ((j - 1) * WOLFSSL_BIT_SIZE));
247
0
            i++;
248
0
        }
249
0
    }
250
251
0
    return i;
252
0
}
253
254
#ifdef WOLFSSL_ASN_TEMPLATE
255
/* Calculate the size of a DER encoded length value.
256
 *
257
 *    0 ->  2^7-1: <length byte>.
258
 *  2^7 ->       : <0x80 + #bytes> <big-endian length bytes>
259
 *
260
 * @param [in] length  Value to encode.
261
 * @return  Number of bytes required to encode.
262
 */
263
static word32 SizeASNLength(word32 length)
264
{
265
    return 1 + ((length >= ASN_LONG_LENGTH) ? BytePrecision(length) : 0);
266
}
267
268
/* Calculate the size of a DER encoded header.
269
 *
270
 * Header = Tag | Encoded length
271
 *
272
 * @param [in] length  Length value to encode.
273
 * @return  Number of bytes required to encode a DER header.
274
 */
275
#define SizeASNHeader(length) \
276
    (1 + SizeASNLength(length))
277
#endif
278
279
#ifdef WOLFSSL_ASN_TEMPLATE
280
#ifdef WOLFSSL_SMALL_STACK
281
    /* Declare the variable that is the dynamic data for decoding BER data.
282
     *
283
     * @param [in] name  Variable name to declare.
284
     * @param [in] cnt   Number of elements required.
285
     */
286
    #define DECL_ASNGETDATA(name, cnt)                                         \
287
        ASNGetData* name = NULL
288
289
    /* Allocates the dynamic BER decoding data.
290
     *
291
     * @param [in]      name  Variable name to declare.
292
     * @param [in]      cnt   Number of elements required.
293
     * @param [in, out] err   Error variable.
294
     * @param [in]      heap  Dynamic memory allocation hint.
295
     */
296
    #define ALLOC_ASNGETDATA(name, cnt, err, heap)                             \
297
    do {                                                                       \
298
        if ((err) == 0) {                                                      \
299
            (name) = (ASNGetData*)XMALLOC(sizeof(ASNGetData) * (cnt), (heap),  \
300
                                        DYNAMIC_TYPE_TMP_BUFFER);              \
301
            if ((name) == NULL) {                                              \
302
                (err) = MEMORY_E;                                              \
303
            }                                                                  \
304
        }                                                                      \
305
    }                                                                          \
306
    while (0)
307
308
    /* Allocates the dynamic BER decoding data and clears the memory.
309
     *
310
     * @param [in]      name  Variable name to declare.
311
     * @param [in]      cnt   Number of elements required.
312
     * @param [in, out] err   Error variable.
313
     * @param [in]      heap  Dynamic memory allocation hint.
314
     */
315
    #define CALLOC_ASNGETDATA(name, cnt, err, heap)                            \
316
    do {                                                                       \
317
        ALLOC_ASNGETDATA(name, cnt, err, heap);                                \
318
        if ((err) == 0) {                                                      \
319
            XMEMSET((name), 0, sizeof(ASNGetData) * (cnt));                    \
320
        }                                                                      \
321
    }                                                                          \
322
    while (0)
323
324
    /* Disposes of the dynamic BER decoding data.
325
     *
326
     * @param [in]      name  Variable name to declare.
327
     * @param [in]      heap  Dynamic memory allocation hint.
328
     */
329
    #define FREE_ASNGETDATA(name, heap)                                        \
330
    do {                                                                       \
331
        if ((name) != NULL) {                                                  \
332
            XFREE((name), (heap), DYNAMIC_TYPE_TMP_BUFFER);                    \
333
        }                                                                      \
334
    }                                                                          \
335
    while (0)
336
337
    /* Declare the variable that is the dynamic data for encoding DER data.
338
     *
339
     * @param [in] name  Variable name to declare.
340
     * @param [in] cnt   Number of elements required.
341
     */
342
    #define DECL_ASNSETDATA(name, cnt)                                         \
343
        ASNSetData* name = NULL
344
345
    /* Allocates the dynamic DER encoding data.
346
     *
347
     * @param [in]      name  Variable name to declare.
348
     * @param [in]      cnt   Number of elements required.
349
     * @param [in, out] err   Error variable.
350
     * @param [in]      heap  Dynamic memory allocation hint.
351
     */
352
    #define ALLOC_ASNSETDATA(name, cnt, err, heap)                             \
353
    do {                                                                       \
354
        if ((err) == 0) {                                                      \
355
            (name) = (ASNSetData*)XMALLOC(sizeof(ASNGetData) * (cnt), (heap),  \
356
                                    DYNAMIC_TYPE_TMP_BUFFER);                  \
357
            if ((name) == NULL) {                                              \
358
                (err) = MEMORY_E;                                              \
359
            }                                                                  \
360
        }                                                                      \
361
    }                                                                          \
362
    while (0)
363
364
    /* Allocates the dynamic DER encoding data and clears the memory.
365
     *
366
     * @param [in]      name  Variable name to declare.
367
     * @param [in]      cnt   Number of elements required.
368
     * @param [in, out] err   Error variable.
369
     * @param [in]      heap  Dynamic memory allocation hint.
370
     */
371
    #define CALLOC_ASNSETDATA(name, cnt, err, heap)                            \
372
    do {                                                                       \
373
        ALLOC_ASNSETDATA(name, cnt, err, heap);                                \
374
        if ((err) == 0) {                                                      \
375
            XMEMSET(name, 0, sizeof(ASNSetData) * (cnt));                      \
376
        }                                                                      \
377
    }                                                                          \
378
    while (0)
379
380
    /* Disposes of the dynamic DER encoding data.
381
     *
382
     * @param [in]      name  Variable name to declare.
383
     * @param [in]      heap  Dynamic memory allocation hint.
384
     */
385
    #define FREE_ASNSETDATA(name, heap)                                        \
386
    do {                                                                       \
387
        if ((name) != NULL) {                                                  \
388
            XFREE(name, heap, DYNAMIC_TYPE_TMP_BUFFER);                        \
389
        }                                                                      \
390
    }                                                                          \
391
    while (0)
392
#else
393
    /* Declare the variable that is the dynamic data for decoding BER data.
394
     *
395
     * @param [in] name  Variable name to declare.
396
     * @param [in] cnt   Number of elements required.
397
     */
398
    #define DECL_ASNGETDATA(name, cnt)                  \
399
        ASNGetData name[cnt]
400
401
    /* No implementation as declartion is static.
402
     *
403
     * @param [in]      name  Variable name to declare.
404
     * @param [in]      cnt   Number of elements required.
405
     * @param [in, out] err   Error variable.
406
     * @param [in]      heap  Dynamic memory allocation hint.
407
     */
408
    #define ALLOC_ASNGETDATA(name, cnt, err, heap)
409
410
    /* Clears the memory of the dynamic BER encoding data.
411
     *
412
     * @param [in]      name  Variable name to declare.
413
     * @param [in]      cnt   Number of elements required.
414
     * @param [in, out] err   Error variable.
415
     * @param [in]      heap  Dynamic memory allocation hint.
416
     */
417
    #define CALLOC_ASNGETDATA(name, cnt, err, heap)     \
418
        XMEMSET(name, 0, sizeof(name))
419
420
    /* No implementation as declartion is static.
421
     *
422
     * @param [in]      name  Variable name to declare.
423
     * @param [in]      heap  Dynamic memory allocation hint.
424
     */
425
    #define FREE_ASNGETDATA(name, heap)
426
427
    /* Declare the variable that is the dynamic data for encoding DER data.
428
     *
429
     * @param [in] name  Variable name to declare.
430
     * @param [in] cnt   Number of elements required.
431
     */
432
    #define DECL_ASNSETDATA(name, cnt)                  \
433
        ASNSetData name[cnt]
434
435
    /* No implementation as declartion is static.
436
     *
437
     * @param [in]      name  Variable name to declare.
438
     * @param [in]      cnt   Number of elements required.
439
     * @param [in, out] err   Error variable.
440
     * @param [in]      heap  Dynamic memory allocation hint.
441
     */
442
    #define ALLOC_ASNSETDATA(name, cnt, err, heap)
443
444
    /* Clears the memory of the dynamic BER encoding data.
445
     *
446
     * @param [in]      name  Variable name to declare.
447
     * @param [in]      cnt   Number of elements required.
448
     * @param [in, out] err   Error variable.
449
     * @param [in]      heap  Dynamic memory allocation hint.
450
     */
451
    #define CALLOC_ASNSETDATA(name, cnt, err, heap)     \
452
        XMEMSET(name, 0, sizeof(name))
453
454
    /* No implementation as declartion is static.
455
     *
456
     * @param [in]      name  Variable name to declare.
457
     * @param [in]      heap  Dynamic memory allocation hint.
458
     */
459
    #define FREE_ASNSETDATA(name, heap)
460
#endif
461
462
463
#ifdef DEBUG_WOLFSSL
464
    /* Enable this when debugging the parsing or creation of ASN.1 data. */
465
    #if 0
466
        #define WOLFSSL_DEBUG_ASN_TEMPLATE
467
    #endif
468
#endif
469
470
#ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
471
/* String representations of tags. */
472
static const char* tagString[4][32] = {
473
    /* Universal */
474
    {
475
        "EOC",
476
        "BOOLEAN",
477
        "INTEGER",
478
        "BIT STRING",
479
        "OCTET STRING",
480
        "NULL",
481
        "OBJECT ID",
482
        "ObjectDescriptor",
483
        "INSTANCE OF",
484
        "REAL",
485
        "ENUMERATED",
486
        "EMBEDDED PDV",
487
        "UT8String",
488
        "RELATIVE-OID",
489
        "(0x0e) 14",
490
        "(0x0f) 15",
491
        "SEQUENCE",
492
        "SET",
493
        "NumericString",
494
        "PrintableString",
495
        "T61String",
496
        "VideotexString",
497
        "IA5String",
498
        "UTCTime",
499
        "GeneralizedTime",
500
        "GraphicString",
501
        "ISO646String",
502
        "GeneralString",
503
        "UniversalString",
504
        "CHARACTER STRING",
505
        "BMPString",
506
        "(0x1f) 31",
507
    },
508
    /* Application */
509
    {
510
         "[A 0]",  "[A 1]",  "[A 2]",  "[A 3]",
511
         "[A 4]",  "[A 5]",  "[A 6]",  "[A 7]",
512
         "[A 8]",  "[A 9]", "[A 10]", "[A 11]",
513
        "[A 12]", "[A 13]", "[A 14]", "[A 15]",
514
        "[A 16]", "[A 17]", "[A 18]", "[A 19]",
515
        "[A 20]", "[A 21]", "[A 22]", "[A 23]",
516
        "[A 24]", "[A 25]", "[A 26]", "[A 27]",
517
        "[A 28]", "[A 20]", "[A 30]", "[A 31]"
518
    },
519
    /* Context-Specific */
520
    {
521
         "[0]",  "[1]",  "[2]",  "[3]",  "[4]",  "[5]",  "[6]",  "[7]",
522
         "[8]",  "[9]", "[10]", "[11]", "[12]", "[13]", "[14]", "[15]",
523
        "[16]", "[17]", "[18]", "[19]", "[20]", "[21]", "[22]", "[23]",
524
        "[24]", "[25]", "[26]", "[27]", "[28]", "[20]", "[30]", "[31]"
525
    },
526
    /* Private */
527
    {
528
         "[P 0]",  "[P 1]",  "[P 2]",  "[P 3]",
529
         "[P 4]",  "[P 5]",  "[P 6]",  "[P 7]",
530
         "[P 8]",  "[P 9]", "[P 10]", "[P 11]",
531
        "[P 12]", "[P 13]", "[P 14]", "[P 15]",
532
        "[P 16]", "[P 17]", "[P 18]", "[P 19]",
533
        "[P 20]", "[P 21]", "[P 22]", "[P 23]",
534
        "[P 24]", "[P 25]", "[P 26]", "[P 27]",
535
        "[P 28]", "[P 20]", "[P 30]", "[P 31]"
536
    }
537
};
538
539
/* Converts a tag byte to string.
540
 *
541
 * @param [in] tag  BER tag value to interpret.
542
 * @return  String corresponding to tag.
543
 */
544
static const char* TagString(byte tag)
545
{
546
    return tagString[tag >> 6][tag & ASN_TYPE_MASK];
547
}
548
549
#include <stdarg.h>
550
551
/* Log a message that has the printf format string.
552
 *
553
 * @param [in] <va_args>  printf style arguments.
554
 */
555
#define WOLFSSL_MSG_VSNPRINTF(...)                    \
556
    do {                                              \
557
      char line[81];                                  \
558
      snprintf(line, sizeof(line) - 1, __VA_ARGS__);  \
559
      line[sizeof(line) - 1] = '\0';                  \
560
      WOLFSSL_MSG(line);                              \
561
    }                                                 \
562
    while (0)
563
#endif
564
565
/* Returns whether ASN.1 item is an integer and the Most-Significant Bit is set.
566
 *
567
 * @param [in] asn     ASN.1 items to encode.
568
 * @param [in] data_a  Data to place in each item. Lengths set were not known.
569
 * @param [in] i       Index of item to check.
570
 * @return  1 when ASN.1 item is an integer and MSB is 1.
571
 * @erturn  0 otherwise.
572
 */
573
#define ASNIntMSBSet(asn, data_a, i)                  \
574
    (((asn)[i].tag == ASN_INTEGER) &&                 \
575
      ((data_a)[i].data.buffer.data != NULL &&        \
576
      ((data_a)[i].data.buffer.data[0] & 0x80) == 0x80))
577
578
579
/* Calculate the size of a DER encoded number.
580
 *
581
 * @param [in] n     Number to be encoded.
582
 * @param [in] bits  Maximum number of bits to encode.
583
 * @param [in] tag   BER tag e.g. INTEGER, BIT_STRING, etc.
584
 * @return  Number of bytes to the ASN.1 item.
585
 */
586
static word32 SizeASN_Num(word32 n, int bits, byte tag)
587
{
588
    int    j;
589
    word32 len;
590
591
    len = 1 + 1 + bits / 8;
592
    /* Discover actual size by checking for high zeros. */
593
    for (j = bits - 8; j > 0; j -= 8) {
594
        if (n >> j)
595
            break;
596
        len--;
597
    }
598
    if (tag == ASN_BIT_STRING)
599
        len++;
600
    else if ((tag == ASN_INTEGER) && (((n >> j) & 0x80) == 0x80))
601
        len++;
602
603
    return len;
604
}
605
606
/* Calculate the size of the data in the constructed item based on the
607
 * length of the ASN.1 items below.
608
 *
609
 * @param [in]      asn    ASN.1 items to encode.
610
 * @param [in, out] data   Data to place in each item. Lengths set were not
611
 *                         known.
612
 * @param [in]      idx    Index of item working on.
613
 */
614
static void SizeASN_CalcDataLength(const ASNItem* asn, ASNSetData *data,
615
                                   int idx, int max)
616
{
617
    int j;
618
619
    data[idx].data.buffer.length = 0;
620
    /* Sum the item length of all items underneath. */
621
    for (j = idx + 1; j < max; j++) {
622
        /* Stop looking if the next ASN.1 is same level or higher. */
623
        if (asn[j].depth <= asn[idx].depth)
624
            break;
625
        /* Only add in length if it is one level below. */
626
        if (asn[j].depth - 1 == asn[idx].depth) {
627
            data[idx].data.buffer.length += data[j].length;
628
            /* The length of a header only item doesn't include the data unless
629
             * a replacement buffer is supplied.
630
             */
631
            if (asn[j].headerOnly && data[j].data.buffer.data == NULL &&
632
                    data[j].dataType != ASN_DATA_TYPE_REPLACE_BUFFER) {
633
                data[idx].data.buffer.length += data[j].data.buffer.length;
634
            }
635
        }
636
    }
637
}
638
639
/* Calculate the size of the DER encoding.
640
 *
641
 * Call SetASN_Items() to write encoding to a buffer.
642
 *
643
 * @param [in]      asn    ASN.1 items to encode.
644
 * @param [in, out] data   Data to place in each item. Lengths set where not
645
 *                         known.
646
 * @param [in]      count  Count of items to encode.
647
 * @param [out]     encSz  Length of the DER encoding.
648
 * @return  0 on success.
649
 * @return  BAD_STATE_E when the data type is not supported.
650
 */
651
int SizeASN_Items(const ASNItem* asn, ASNSetData *data, int count, int* encSz)
652
{
653
    int    i;
654
    word32 sz = 0;
655
    word32 len;
656
    word32 dataLen;
657
    int    length;
658
659
#ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
660
    WOLFSSL_ENTER("SizeASN_Items");
661
#endif
662
663
    for (i = count - 1; i >= 0; i--) {
664
        /* Skip this ASN.1 item when encoding. */
665
        if (data[i].noOut) {
666
            /* Set the offset to the current size - used in writing DER. */
667
            data[i].offset = sz;
668
            continue;
669
        }
670
671
        len = 0;
672
        switch (data[i].dataType) {
673
            /* Calculate the size of the number of different sizes. */
674
            case ASN_DATA_TYPE_WORD8:
675
                len = SizeASN_Num(data[i].data.u8, 8, asn[i].tag);
676
                break;
677
            case ASN_DATA_TYPE_WORD16:
678
                len = SizeASN_Num(data[i].data.u16, 16, asn[i].tag);
679
                break;
680
        #ifdef WOLFSSL_ASN_TEMPLATE_NEED_SET_INT32
681
            /* Not used yet! */
682
            case ASN_DATA_TYPE_WORD32:
683
                len = SizeASN_Num(data[i].data.u32, 32, asn[i].tag);
684
                break;
685
        #endif
686
687
            case ASN_DATA_TYPE_MP:
688
                /* Calculate the size of the MP integer data. */
689
                length = mp_unsigned_bin_size(data[i].data.mp);
690
                length += mp_leading_bit(data[i].data.mp) ? 1 : 0;
691
                len = SizeASNHeader(length) + length;
692
                break;
693
694
            case ASN_DATA_TYPE_REPLACE_BUFFER:
695
                /* Buffer is put in directly - use the length. */
696
                len = data[i].data.buffer.length;
697
                break;
698
699
            case ASN_DATA_TYPE_NONE:
700
                /* Calculate the size based on the data to be included.
701
                 * Mostly used for constructed items.
702
                 */
703
                if (asn[i].headerOnly) {
704
                    if (data[i].data.buffer.data != NULL) {
705
                        /* Force all child nodes to be ignored. Buffer
706
                         * overwrites children. */
707
                        {
708
                            int ii;
709
                            for (ii = i + 1; ii < count; ii++) {
710
                                if (asn[ii].depth <= asn[i].depth)
711
                                    break;
712
                                sz -= data[ii].length;
713
                                data[ii].noOut = 1;
714
                            }
715
                        }
716
                    }
717
                    else {
718
                        /* Calculate data length from items below if no buffer
719
                         * supplied. */
720
                        SizeASN_CalcDataLength(asn, data, i, count);
721
                    }
722
                }
723
                if (asn[i].tag == ASN_BOOLEAN) {
724
                    dataLen = 1;
725
                }
726
                else {
727
                    dataLen = data[i].data.buffer.length;
728
                }
729
                /* BIT_STRING and INTEGER have one byte prepended. */
730
                if ((asn[i].tag == ASN_BIT_STRING) ||
731
                                                   ASNIntMSBSet(asn, data, i)) {
732
                    dataLen++;
733
                    /* ASN.1 items are below and cannot include extra byte. */
734
                    if (asn[i].headerOnly) {
735
                        len++;
736
                    }
737
                }
738
                /* Add in the size of tag and length. */
739
                len += SizeASNHeader(dataLen);
740
                /* Include data in length if not header only or if
741
                 * buffer supplied. */
742
                if (!asn[i].headerOnly || data[i].data.buffer.data != NULL) {
743
                    len += dataLen;
744
                }
745
                break;
746
747
        #ifdef DEBUG_WOLFSSL
748
            default:
749
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
750
                WOLFSSL_MSG_VSNPRINTF("%2d: %d", i, data[i].dataType);
751
                WOLFSSL_MSG("Bad data type");
752
            #endif
753
                return BAD_STATE_E;
754
        #endif
755
        }
756
757
        /* Set the total length of the item. */
758
        data[i].length = len;
759
        /* Add length to total size. */
760
        sz += len;
761
        /* Set the offset to the current size - used in writing DER. */
762
        data[i].offset = sz;
763
764
    #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
765
        WOLFSSL_MSG_VSNPRINTF("%2d: %4d %4d %c %*s %-16s", i,
766
                data[i].offset, data[i].length, asn[i].constructed ? '+' : ' ',
767
                asn[i].depth, "", TagString(asn[i].tag));
768
    #endif
769
    }
770
771
    *encSz = sz;
772
    return 0;
773
}
774
775
/* Create the DER encoding of a number.
776
 *
777
 * Assumes that the out buffer is large enough for encoding.
778
 *
779
 * @param [in] n     Number to be encoded.
780
 * @param [in] bits  Maximum number of bits to encode.
781
 * @param [in] tag   DER tag e.g. INTEGER, BIT_STRING, etc.
782
 */
783
static void SetASN_Num(word32 n, int bits, byte* out, byte tag)
784
{
785
    int    j;
786
    word32 idx;
787
    byte   len;
788
789
    /* Encoding: Tag (1 byte) | Length (1 byte) | Data (number) */
790
791
    /* Data will start at index 2 unless BIT_STRING or INTEGER */
792
    idx = 2;
793
794
    /* Set the length of the number based on maximum bit length. */
795
    len = bits / 8;
796
    /* Discover actual size by checking for leading zero bytes. */
797
    for (j = bits - 8; j > 0; j -= 8) {
798
        if ((n >> j) != 0) {
799
            break;
800
        }
801
        len--;
802
    }
803
    /* Keep j, index of first non-zero byte, for writing out. */
804
805
    /* A BIT_STRING has the number of unused bits in last byte prepended to
806
     * data.
807
     */
808
    if (tag == ASN_BIT_STRING) {
809
        byte unusedBits = 0;
810
        byte lastByte = n >> j;
811
812
        /* Quick check last bit. */
813
        if ((lastByte & 0x01) == 0x00) {
814
            unusedBits++;
815
            /* Check each bit for first least significant bit set. */
816
            while (((lastByte >> unusedBits) & 0x01) == 0x00)
817
                unusedBits++;
818
        }
819
        /* Add unused bits byte. */
820
        len++;
821
        out[idx++] = unusedBits;
822
    }
823
824
    /* An INTEGER has a prepended byte if MSB of number is 1 - makes encoded
825
     * value positive. */
826
    if ((tag == ASN_INTEGER) && (((n >> j) & 0x80) == 0x80)) {
827
        len++;
828
        out[idx++] = 0;
829
    }
830
831
    /* Go back and put in length. */
832
    out[1] = len;
833
    /* Place in the required bytes of the number. */
834
    for (; j >= 0; j -= 8)
835
        out[idx++] = n >> j;
836
}
837
838
/* Creates the DER encoding of the ASN.1 items.
839
 *
840
 * Assumes the output buffer is large enough to hold encoding.
841
 * Must call SizeASN_Items() to determine size of encoding and offsets.
842
 *
843
 * @param [in]      asn     ASN.1 items to encode.
844
 * @param [in]      data    Data to place in each item.
845
 * @param [in]      count   Count of items to encode.
846
 * @param [in, out] output  Buffer to write encoding into.
847
 * @return  Size of the DER encoding in bytes.
848
 */
849
int SetASN_Items(const ASNItem* asn, ASNSetData *data, int count, byte* output)
850
{
851
    int    i;
852
    int    length;
853
    int    err;
854
    word32 sz;
855
    word32 idx;
856
    byte*  out;
857
858
#ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
859
    WOLFSSL_ENTER("SetASN_Items");
860
#endif
861
862
    /* Offset of first item is the total length.
863
     * SizeASN_Items() calculated this. */
864
    sz = data[0].offset;
865
866
    /* Write out each item. */
867
    for (i = 0; i < count; i++) {
868
        /* Skip items not writing out. */
869
        if (data[i].noOut)
870
            continue;
871
872
        /* Start position to write item based on reverse offsets. */
873
        out = output + sz - data[i].offset;
874
        /* Index from start of item out. */
875
        idx = 0;
876
877
        if (data[i].dataType != ASN_DATA_TYPE_REPLACE_BUFFER) {
878
            /* Put in the tag - not dumping in DER from buffer. */
879
            out[idx++] = asn[i].tag |
880
                         (asn[i].constructed ? ASN_CONSTRUCTED : 0);
881
        }
882
883
    #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
884
        WOLFSSL_MSG_VSNPRINTF("%2d: %4d %4d %c %*s %-16s", i,
885
                sz - data[i].offset,
886
                data[i].length, asn[i].constructed ? '+' : ' ', asn[i].depth,
887
                "", TagString(asn[i].tag));
888
    #endif
889
890
        switch (data[i].dataType) {
891
            /* Write out the length and data of a number. */
892
            case ASN_DATA_TYPE_WORD8:
893
                SetASN_Num(data[i].data.u8, 8, out, asn[i].tag);
894
                break;
895
            case ASN_DATA_TYPE_WORD16:
896
                SetASN_Num(data[i].data.u16, 16, out, asn[i].tag);
897
                break;
898
        #ifdef WOLFSSL_ASN_TEMPLATE_NEED_SET_INT32
899
            /* Not used yet! */
900
            case ASN_DATA_TYPE_WORD32:
901
                SetASN_Num(data[i].data.u32, 32, out, asn[i].tag);
902
                break;
903
        #endif
904
905
            /* Write out the length and data of a multi-precision number. */
906
            case ASN_DATA_TYPE_MP:
907
                /* Get length in bytes. */
908
                length = mp_unsigned_bin_size(data[i].data.mp);
909
                /* Add one for leading zero to make encoding a positive num. */
910
                length += mp_leading_bit(data[i].data.mp) ? 1 : 0;
911
                /* Write out length. */
912
                idx += SetASNLength(length, out + idx);
913
                /* Write out leading zero to make positive. */
914
                if (mp_leading_bit(data[i].data.mp)) {
915
                    out[idx++] = 0;
916
                }
917
                /* Encode number in big-endian byte array. */
918
                err = mp_to_unsigned_bin(data[i].data.mp, out + idx);
919
                if (err != MP_OKAY) {
920
                    WOLFSSL_MSG("SetASN_Items: Failed to write mp_int");
921
                    return MP_TO_E;
922
                }
923
                break;
924
925
            case ASN_DATA_TYPE_REPLACE_BUFFER:
926
                if (data[i].data.buffer.data == NULL) {
927
                    /* Return pointer for caller to use. */
928
                    data[i].data.buffer.data = out + idx;
929
                }
930
                else {
931
                    /* Dump in the DER encoded data. */
932
                    XMEMCPY(out + idx, data[i].data.buffer.data,
933
                            data[i].data.buffer.length);
934
                }
935
                break;
936
937
            case ASN_DATA_TYPE_NONE:
938
                if (asn[i].tag == ASN_BOOLEAN) {
939
                    /* Always one byte of data. */
940
                    out[idx++] = 1;
941
                    /* TRUE = 0xff, FALSE = 0x00 */
942
                    out[idx] = data[i].data.u8 ? -1 : 0;
943
                }
944
                else if (asn[i].tag == ASN_TAG_NULL) {
945
                    /* NULL tag is always a zero length item. */
946
                    out[idx] = 0;
947
                }
948
                else {
949
                    word32 dataLen = data[i].data.buffer.length;
950
                    /* Add one to data length for BIT_STRING unused bits and
951
                     * INTEGER leading zero to make positive.
952
                     */
953
                    if ((asn[i].tag == ASN_BIT_STRING) ||
954
                                                   ASNIntMSBSet(asn, data, i)) {
955
                        dataLen++;
956
                    }
957
                    /* Write out length. */
958
                    idx += SetASNLength(dataLen, out + idx);
959
                    if ((asn[i].tag == ASN_BIT_STRING) ||
960
                                                   ASNIntMSBSet(asn, data, i)) {
961
                       /* Write out leading byte. BIT_STRING has no unused bits
962
                        * - use number data types if needed. */
963
                        out[idx++] = 0x00;
964
                    }
965
                    /* Record pointer for caller if data not supplied. */
966
                    if (data[i].data.buffer.data == NULL) {
967
                        data[i].data.buffer.data = out + idx;
968
                    }
969
                    /* Copy supplied data if not putting out header only or
970
                     * if buffer supplied. */
971
                    else if (!asn[i].headerOnly ||
972
                            data[i].data.buffer.data != NULL) {
973
                        /* Allow data to come from output buffer. */
974
                        XMEMMOVE(out + idx, data[i].data.buffer.data,
975
                                 data[i].data.buffer.length);
976
                    }
977
                }
978
                break;
979
980
        #ifdef DEBUG_WOLFSSL
981
            default:
982
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
983
                WOLFSSL_MSG_VSNPRINTF("Bad data type: %d", data[i].dataType);
984
            #endif
985
                return BAD_STATE_E;
986
        #endif
987
        }
988
    }
989
990
    return sz;
991
}
992
993
994
static int GetOID(const byte* input, word32* inOutIdx, word32* oid,
995
                  word32 oidType, int length);
996
997
/* Maximum supported depth in ASN.1 description. */
998
#define GET_ASN_MAX_DEPTH          7
999
/* Maximum number of checked numbered choices. Only one of the items with the
1000
 * number is allowed.
1001
 */
1002
#define GET_ASN_MAX_CHOICES        2
1003
1004
/* Use existing function to decode BER length encoding. */
1005
#define GetASN_Length GetLength_ex
1006
1007
/* Check an INTEGER's first byte - must be a positive number.
1008
 *
1009
 * @param [in] input    BER encoded data.
1010
 * @param [in] idx      Index of BIT_STRING data.
1011
 * @param [in] length   Length of input data.
1012
 * @param [in] positive Indicates number must be positive.
1013
 * @return  0 on success.
1014
 * @return  ASN_PARSE_E when 0 is not required but seen.
1015
 * @return  ASN_EXPECT_0_E when 0 is required and not seen.
1016
 */
1017
static int GetASN_Integer(const byte* input, word32 idx, int length,
1018
                          int positive)
1019
{
1020
    if (input[idx] == 0) {
1021
        /* Check leading zero byte required. */
1022
        if ((length > 1) && ((input[idx + 1] & 0x80) == 0)) {
1023
        #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1024
            WOLFSSL_MSG("Zero not required on INTEGER");
1025
        #endif
1026
            return ASN_PARSE_E;
1027
        }
1028
    }
1029
    /* Check whether a leading zero byte was required. */
1030
    else if (positive && (input[idx] & 0x80)) {
1031
    #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1032
        WOLFSSL_MSG("INTEGER is negative");
1033
    #endif
1034
        return ASN_EXPECT_0_E;
1035
    }
1036
1037
    return 0;
1038
}
1039
1040
/* Check a BIT_STRING's first byte - unused bits.
1041
 *
1042
 * @param [in] input   BER encoded data.
1043
 * @param [in] idx     Index of BIT_STRING data.
1044
 * @param [in] length  Length of input data.
1045
 * @return  0 on success.
1046
 * @return  ASN_PARSE_E when unused bits is invalid.
1047
 */
1048
static int GetASN_BitString(const byte* input, word32 idx, int length)
1049
{
1050
    /* Ensure unused bits value is valid range. */
1051
    if (input[idx] > 7) {
1052
    #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1053
        WOLFSSL_MSG_VSNPRINTF("BIT STRING unused bits too big: %d > 7",
1054
                input[idx]);
1055
    #endif
1056
        return ASN_PARSE_E;
1057
    }
1058
    /* Ensure unused bits are zero. */
1059
    if ((byte)(input[idx + length - 1] << (8 - input[idx])) != 0) {
1060
    #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1061
        WOLFSSL_MSG_VSNPRINTF("BIT STRING unused bits used: %d %02x",
1062
                input[idx], input[idx + length - 1]);
1063
    #endif
1064
        return ASN_PARSE_E;
1065
    }
1066
1067
    return 0;
1068
}
1069
1070
/* Get the ASN.1 items from the BER encoding.
1071
 *
1072
 * @param [in] asn         ASN.1 item expected.
1073
 * @param [in] data        Data array to place found item into.
1074
 * @param [in] input       BER encoded data.
1075
 * @param [in] idx         Starting index of item data.
1076
 * @param [in] len         Length of input buffer upto end of this item's data.
1077
 * @param [in] zeroPadded  INTEGER was zero padded to make positive.
1078
 * @return  0 on success.
1079
 * @return  ASN_PARSE_E when BER encoded data is invalid.
1080
 * @return  ASN_EXPECT_0_E when NULL tagged item has a non-zero length.
1081
 * @return  MP_INIT_E when the unable to initialize an mp_int.
1082
 * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
1083
 * @return  BAD_STATE_E when the data type is not supported.
1084
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
1085
 */
1086
static int GetASN_StoreData(const ASNItem* asn, ASNGetData* data,
1087
                            const byte* input, word32 idx, int len,
1088
                            int zeroPadded)
1089
{
1090
    int i;
1091
    int err;
1092
1093
    /* Parse data based on data type to extract. */
1094
    switch (data->dataType) {
1095
        /* Parse a data into a number of specified bits. */
1096
        case ASN_DATA_TYPE_WORD8:
1097
            /* Check data is small enough to fit. */
1098
            if (len != 1) {
1099
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1100
                WOLFSSL_MSG_VSNPRINTF("Expecting one byte: %d", len);
1101
            #endif
1102
                return ASN_PARSE_E;
1103
            }
1104
            /* Fill number with all of data. */
1105
            *data->data.u8 = input[idx];
1106
            break;
1107
        case ASN_DATA_TYPE_WORD16:
1108
            /* Check data is small enough to fit. */
1109
            if (len == 0 || len > 2) {
1110
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1111
                WOLFSSL_MSG_VSNPRINTF("Expecting 1 or 2 bytes: %d", len);
1112
            #endif
1113
                return ASN_PARSE_E;
1114
            }
1115
            /* Fill number with all of data. */
1116
            *data->data.u16 = 0;
1117
            for (i = 0; i < len; i++) {
1118
                *data->data.u16 <<= 8;
1119
                *data->data.u16 |= input[idx + i] ;
1120
            }
1121
            break;
1122
        case ASN_DATA_TYPE_WORD32:
1123
            /* Check data is small enough to fit. */
1124
            if (len == 0 || len > 4) {
1125
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1126
                WOLFSSL_MSG_VSNPRINTF("Expecting 1 to 4 bytes: %d", len);
1127
            #endif
1128
                return ASN_PARSE_E;
1129
            }
1130
            /* Fill number with all of data. */
1131
            *data->data.u32 = 0;
1132
            for (i = 0; i < len; i++) {
1133
                *data->data.u32 <<= 8;
1134
                *data->data.u32 |= input[idx + i] ;
1135
            }
1136
            break;
1137
1138
        case ASN_DATA_TYPE_BUFFER:
1139
            /* Check buffer is big enough to hold data. */
1140
            if (len > (int)*data->data.buffer.length) {
1141
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1142
                WOLFSSL_MSG_VSNPRINTF("Buffer too small for data: %d %d", len,
1143
                        *data->data.buffer.length);
1144
            #endif
1145
                return ASN_PARSE_E;
1146
            }
1147
            /* Copy in data and record actual length seen. */
1148
            XMEMCPY(data->data.buffer.data, input + idx, len);
1149
            *data->data.buffer.length = len;
1150
            break;
1151
1152
        case ASN_DATA_TYPE_EXP_BUFFER:
1153
            /* Check data is same size expected. */
1154
            if (len != (int)data->data.ref.length) {
1155
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1156
                WOLFSSL_MSG_VSNPRINTF("Data not expected length: %d %d", len,
1157
                        data->data.ref.length);
1158
            #endif
1159
                return ASN_PARSE_E;
1160
            }
1161
            /* Check data is same as expected. */
1162
            if (XMEMCMP(data->data.ref.data, input + idx, len) != 0) {
1163
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1164
                WOLFSSL_MSG("Data not as expected");
1165
            #endif
1166
                return ASN_PARSE_E;
1167
            }
1168
            break;
1169
1170
        case ASN_DATA_TYPE_MP:
1171
        case ASN_DATA_TYPE_MP_POS_NEG:
1172
            /* Initialize mp_int and read in big-endian byte array. */
1173
            if (mp_init(data->data.mp) != MP_OKAY) {
1174
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1175
                WOLFSSL_MSG_VSNPRINTF("Failed to init mp: %p", data->data.mp);
1176
            #endif
1177
                return MP_INIT_E;
1178
            }
1179
            err = mp_read_unsigned_bin(data->data.mp, (byte*)input + idx, len);
1180
            if (err != 0) {
1181
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1182
                WOLFSSL_MSG_VSNPRINTF("Failed to read mp: %d", err);
1183
            #endif
1184
                mp_clear(data->data.mp);
1185
                return ASN_GETINT_E;
1186
            }
1187
        #ifdef HAVE_WOLF_BIGINT
1188
            err = wc_bigint_from_unsigned_bin(&data->data.mp->raw, input + idx,
1189
                    len);
1190
            if (err != 0) {
1191
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1192
                WOLFSSL_MSG_VSNPRINTF("Failed to create bigint: %d", err);
1193
            #endif
1194
                mp_clear(data->data.mp);
1195
                return ASN_GETINT_E;
1196
            }
1197
        #endif /* HAVE_WOLF_BIGINT */
1198
1199
        #ifdef WOLFSSL_SP_INT_NEGATIVE
1200
            /* Don't always read as positive. */
1201
            if ((data->dataType == ASN_DATA_TYPE_MP_POS_NEG) && (!zeroPadded) &&
1202
                (input[idx] & 0x80)) {
1203
                #ifdef MP_NEG
1204
                    data->data.mp->sign = MP_NEG;
1205
                #else
1206
                    #ifdef OPENSSL_EXTRA
1207
                        /* public API wolfSSL_ASN1_INTEGER_get() depends
1208
                         * indirectly on negative bignum handling here.
1209
                         */
1210
                        #error OPENSSL_EXTRA requires negative bignum support.
1211
                    #endif
1212
                    #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1213
                    WOLFSSL_MSG_VSNPRINTF("ASN negative integer without bignum support.");
1214
                    #endif
1215
                    mp_clear(data->data.mp);
1216
                    return ASN_GETINT_E;
1217
                #endif
1218
            }
1219
        #else
1220
            (void)zeroPadded;
1221
        #endif
1222
            break;
1223
1224
        case ASN_DATA_TYPE_CHOICE:
1225
            /* Check if tag matched any of the choices specified. */
1226
            for (i = 0; data->data.choice[i] != 0; i++)
1227
                if (data->data.choice[i] == data->tag)
1228
                    break;
1229
            if (data->data.choice[i] == 0) {
1230
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1231
                WOLFSSL_MSG("Tag didn't match a choice");
1232
            #endif
1233
                return ASN_PARSE_E;
1234
            }
1235
1236
            /* Store data pointer and length for caller. */
1237
            data->data.ref.data = input + idx;
1238
            data->data.ref.length = len;
1239
            break;
1240
1241
        case ASN_DATA_TYPE_NONE:
1242
            /* Default behaviour based on tag. */
1243
            if (asn->tag == ASN_BOOLEAN) {
1244
                /* BOOLEAN has only one byte of data in BER. */
1245
                if (len != 1) {
1246
                #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1247
                    WOLFSSL_MSG_VSNPRINTF("BOOLEAN length too long: %d", len);
1248
                #endif
1249
                    return ASN_PARSE_E;
1250
                }
1251
                if (data->data.u8 == NULL)
1252
                    return BAD_STATE_E;
1253
                /* Store C boolean value. */
1254
                *data->data.u8 = (input[idx] != 0);
1255
                break;
1256
            }
1257
            if (asn->tag == ASN_TAG_NULL) {
1258
                /* NULL has no data in BER. */
1259
                if (len != 0) {
1260
                #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1261
                    WOLFSSL_MSG_VSNPRINTF("NULL length too long: %d", len);
1262
                #endif
1263
                    return ASN_EXPECT_0_E;
1264
                }
1265
                data->data.ref.data = input + idx;
1266
                break;
1267
            }
1268
            if (asn->tag == ASN_OBJECT_ID) {
1269
                word32 oidIdx = 0;
1270
                /* Store OID data pointer and length */
1271
                data->data.oid.data = input + idx;
1272
                data->data.oid.length = len;
1273
                /* Get the OID sum. */
1274
                err = GetOID(input + idx, &oidIdx, &data->data.oid.sum,
1275
                        data->data.oid.type, len);
1276
                if (err < 0) {
1277
                #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1278
                    WOLFSSL_MSG_VSNPRINTF("OID check failed: %d", err);
1279
                #endif
1280
                    return err;
1281
                }
1282
                break;
1283
            }
1284
1285
            /* Otherwise store data pointer and length. */
1286
            data->data.ref.data = input + idx;
1287
            data->data.ref.length = len;
1288
            break;
1289
1290
    #ifdef DEBUG_WOLFSSL
1291
        default:
1292
            /* Bad ASN data type. */
1293
        #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1294
            WOLFSSL_MSG_VSNPRINTF("Bad data type: %d", data->dataType);
1295
        #endif
1296
            return BAD_STATE_E;
1297
    #endif
1298
    }
1299
1300
    return 0;
1301
}
1302
1303
/* Get the ASN.1 items from the BER encoding.
1304
 *
1305
 * @param [in]      asn       ASN.1 items expected.
1306
 * @param [in]      data      Data array to place found items into.
1307
 * @param [in]      count     Count of items to parse.
1308
 * @param [in]      complete  Whether the whole buffer is to be used up.
1309
 * @param [in]      input     BER encoded data.
1310
 * @param [in, out] inOutIdx  On in, starting index of data.
1311
 *                            On out, end of parsed data.
1312
 * @param [in]      length    Length of input buffer.
1313
 * @return  0 on success.
1314
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
1315
 *          is invalid.
1316
 * @return  BUFFER_E when data in buffer is too small.
1317
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
1318
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
1319
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
1320
 *          non-zero length.
1321
 * @return  MP_INIT_E when the unable to initialize an mp_int.
1322
 * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
1323
 * @return  BAD_STATE_E when the data type is not supported.
1324
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
1325
 */
1326
int GetASN_Items(const ASNItem* asn, ASNGetData *data, int count, int complete,
1327
                 const byte* input, word32* inOutIdx, word32 length)
1328
{
1329
    int    i;
1330
    int    j;
1331
    int    err;
1332
    int    len;
1333
    /* Current index into buffer. */
1334
    word32 idx = *inOutIdx;
1335
    /* Initialize the end index at each depth to be the length. */
1336
    word32 endIdx[GET_ASN_MAX_DEPTH] = { length, length, length, length, length,
1337
                                         length, length };
1338
    /* Set choices to -1 to indicate they haven't been seen or found. */
1339
    signed char   choiceMet[GET_ASN_MAX_CHOICES] = { -1, -1 };
1340
    /* Not matching a choice right now. */
1341
    int    choice = 0;
1342
    /* Current depth of ASN.1 item. */
1343
    int    depth;
1344
    /* Minimum depth value seen. */
1345
    int    minDepth;
1346
    /* Integer had a zero prepended. */
1347
    int    zeroPadded;
1348
1349
#ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1350
    WOLFSSL_ENTER("GetASN_Items");
1351
#endif
1352
1353
    /* Start depth at first items depth. */
1354
    minDepth = depth = asn[0].depth;
1355
    /* Check every ASN.1 item. */
1356
    for (i = 0; i < count; i++) {
1357
        /* Store offset of ASN.1 item. */
1358
        data[i].offset = idx;
1359
        /* Length of data in ASN.1 item starts empty. */
1360
        data[i].length = 0;
1361
        /* Get current item depth. */
1362
        depth = asn[i].depth;
1363
    #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1364
        if (depth > GET_ASN_MAX_DEPTH) {
1365
            WOLFSSL_MSG("Depth in template too large");
1366
            return ASN_PARSE_E;
1367
        }
1368
    #endif
1369
        /* Keep track of minimum depth. */
1370
        if (depth < minDepth) {
1371
            minDepth = depth;
1372
        }
1373
1374
        /* Reset choice if different from previous. */
1375
        if (choice > 0 && asn[i].optional != choice) {
1376
            choice = 0;
1377
        }
1378
        /* Check if first of numbered choice. */
1379
        if (choice == 0 && asn[i].optional > 1) {
1380
            choice = asn[i].optional;
1381
            if (choiceMet[choice - 2] == -1) {
1382
                /* Choice seen but not found a match yet. */
1383
                choiceMet[choice - 2] = 0;
1384
            }
1385
        }
1386
1387
        /* Check for end of data or not a choice and tag not matching. */
1388
        if (idx == endIdx[depth] || (data[i].dataType != ASN_DATA_TYPE_CHOICE &&
1389
                              (input[idx] & ~ASN_CONSTRUCTED) != asn[i].tag)) {
1390
            if (asn[i].optional) {
1391
                /* Skip over ASN.1 items underneath this optional item. */
1392
                for (j = i + 1; j < count; j++) {
1393
                    if (asn[i].depth >= asn[j].depth)
1394
                        break;
1395
                    data[j].offset = idx;
1396
                    data[j].length = 0;
1397
                }
1398
                i = j - 1;
1399
                continue;
1400
            }
1401
1402
            /* Check for end of data. */
1403
            if (idx == length) {
1404
        #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1405
                WOLFSSL_MSG_VSNPRINTF(
1406
                    "%2d: %4d %4d %c %*s %-16s%*s  (index past end)",
1407
                    i, data[i].offset, data[i].length,
1408
                    asn[i].constructed ? '+' : ' ', asn[i].depth, "",
1409
                    TagString(asn[i].tag), 6 - asn[i].depth, "");
1410
                WOLFSSL_MSG_VSNPRINTF("Index past end of data: %d %d", idx,
1411
                        length);
1412
        #endif
1413
                return BUFFER_E;
1414
            }
1415
        #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1416
            /* Show expected versus found. */
1417
            WOLFSSL_MSG_VSNPRINTF(
1418
                "%2d: %4d %4d %c %*s %-16s%*s  Tag=0x%02x (%s)",
1419
                i, data[i].offset, data[i].length,
1420
                asn[i].constructed ? '+' : ' ', asn[i].depth, "",
1421
                TagString(asn[i].tag), 6 - asn[i].depth, "",
1422
                input[idx], TagString(input[idx]));
1423
        #endif
1424
            /* Check for end of data at this depth. */
1425
            if (idx == endIdx[depth]) {
1426
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1427
                WOLFSSL_MSG_VSNPRINTF("Index past outer item: %d %d", idx,
1428
                        endIdx[depth]);
1429
            #endif
1430
                return ASN_PARSE_E;
1431
            }
1432
1433
            /* Expecting an OBJECT_ID */
1434
            if (asn[i].tag == ASN_OBJECT_ID) {
1435
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1436
                WOLFSSL_MSG("Expecting OBJECT ID");
1437
            #endif
1438
                return ASN_OBJECT_ID_E;
1439
            }
1440
            /* Expecting a BIT_STRING */
1441
            if (asn[i].tag == ASN_BIT_STRING) {
1442
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1443
                WOLFSSL_MSG("Expecting BIT STRING");
1444
            #endif
1445
                return ASN_BITSTR_E;
1446
            }
1447
            /* Not the expected tag. */
1448
        #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1449
            WOLFSSL_MSG("Bad tag");
1450
        #endif
1451
            return ASN_PARSE_E;
1452
        }
1453
1454
        /* Store found tag in data. */
1455
        data[i].tag = input[idx];
1456
        if (data[i].dataType != ASN_DATA_TYPE_CHOICE) {
1457
            int constructed = (input[idx] & ASN_CONSTRUCTED) == ASN_CONSTRUCTED;
1458
            /* Check constructed match expected for non-choice ASN.1 item. */
1459
            if (asn[i].constructed != constructed) {
1460
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1461
                WOLFSSL_MSG_VSNPRINTF(
1462
                        "%2d: %4d %4d %c %*s %-16s%*s  Tag=0x%02x (%s)",
1463
                        i, data[i].offset, data[i].length,
1464
                        asn[i].constructed ? '+' : ' ', asn[i].depth, "",
1465
                        TagString(asn[i].tag), 6 - asn[i].depth, "",
1466
                        input[idx], TagString(input[idx]));
1467
                if (!constructed) {
1468
                    WOLFSSL_MSG("Not constructed");
1469
                }
1470
                else {
1471
                    WOLFSSL_MSG("Not expected to be constructed");
1472
                }
1473
            #endif
1474
                return ASN_PARSE_E;
1475
            }
1476
        }
1477
        /* Move index to start of length. */
1478
        idx++;
1479
        /* Get the encoded length. */
1480
        if (GetASN_Length(input, &idx, &len, endIdx[depth], 1) < 0) {
1481
        #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1482
            WOLFSSL_MSG_VSNPRINTF("%2d: idx=%d len=%d end=%d", i, idx, len,
1483
                    endIdx[depth]);
1484
        #endif
1485
            return ASN_PARSE_E;
1486
        }
1487
        /* Store length of data. */
1488
        data[i].length = len;
1489
        /* Note the max length of items under this one. */
1490
        endIdx[depth + 1] = idx + len;
1491
        if (choice > 1) {
1492
            /* Note we found a number choice. */
1493
            choiceMet[choice - 2] = 1;
1494
        }
1495
1496
    #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1497
        WOLFSSL_MSG_VSNPRINTF("%2d: %4d %4d %c %*s %-16s", i,
1498
                data[i].offset, data[i].length, asn[i].constructed ? '+' : ' ',
1499
                asn[i].depth, "", TagString(data[i].tag));
1500
    #endif
1501
1502
        /* Assume no zero padding on INTEGER. */
1503
        zeroPadded = 0;
1504
        /* Check data types that prepended a byte. */
1505
        if (asn[i].tag == ASN_INTEGER) {
1506
            /* Check validity of first byte. */
1507
            err = GetASN_Integer(input, idx, len,
1508
                    data[i].dataType == ASN_DATA_TYPE_MP);
1509
            if (err != 0)
1510
                return err;
1511
            if (len > 1 && input[idx] == 0) {
1512
                zeroPadded = 1;
1513
                /* Move over prepended byte. */
1514
                idx++;
1515
                len--;
1516
            }
1517
        }
1518
        else if (asn[i].tag == ASN_BIT_STRING) {
1519
            /* Check prepended byte is correct. */
1520
            err = GetASN_BitString(input, idx, len);
1521
            if (err != 0)
1522
                return err;
1523
            /* Move over prepended byte. */
1524
            idx++;
1525
            len--;
1526
        }
1527
        else if ((asn[i].tag == ASN_OBJECT_ID) && (len < 3)) {
1528
        #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1529
            WOLFSSL_MSG_VSNPRINTF("OID length must be 3 or more: %d", len);
1530
        #endif
1531
            return ASN_PARSE_E;
1532
        }
1533
1534
        /* Don't parse data if only header required. */
1535
        if (asn[i].headerOnly) {
1536
            /* Store reference to data and length. */
1537
            data[i].data.ref.data = input + idx;
1538
            data[i].data.ref.length = len;
1539
            continue;
1540
        }
1541
1542
        /* Store the data at idx in the ASN data item. */
1543
        err = GetASN_StoreData(&asn[i], &data[i], input, idx, len, zeroPadded);
1544
        if (err != 0) {
1545
            return err;
1546
        }
1547
1548
        /* Move index to next item. */
1549
        idx += len;
1550
1551
        /* When matched numbered choice ... */
1552
        if (asn[i].optional > 1) {
1553
            /* Skip over other ASN.1 items of the same number. */
1554
            for (j = i + 1; j < count; j++) {
1555
                if (asn[j].depth <= asn[i].depth &&
1556
                                           asn[j].optional != asn[i].optional) {
1557
                   break;
1558
                }
1559
            }
1560
            i = j - 1;
1561
        }
1562
    }
1563
1564
    if (complete) {
1565
        /* When expecting ASN.1 items to completely use data, check we did. */
1566
        for (j = depth; j > minDepth; j--) {
1567
            if (idx < endIdx[j]) {
1568
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1569
                WOLFSSL_MSG_VSNPRINTF(
1570
                    "More data in constructed item at depth: %d", j - 1);
1571
            #endif
1572
                return ASN_PARSE_E;
1573
            }
1574
        }
1575
    }
1576
1577
    /* Check all choices where met - found an item for them. */
1578
    for (j = 0; j < GET_ASN_MAX_CHOICES; j++) {
1579
        if (choiceMet[j] == 0) {
1580
        #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1581
            WOLFSSL_MSG_VSNPRINTF("No choice seen: %d", j + 2);
1582
        #endif
1583
            return ASN_PARSE_E;
1584
        }
1585
    }
1586
1587
    /* Return index after ASN.1 data has been parsed. */
1588
    *inOutIdx = idx;
1589
1590
    return 0;
1591
}
1592
1593
#ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1594
/* Calculate the size of the DER encoding.
1595
 *
1596
 * Call SetASN_Items() to write encoding to a buffer.
1597
 *
1598
 * @param [in]      asn    ASN.1 items to encode.
1599
 * @param [in, out] data   Data to place in each item. Lengths set were not
1600
 *                         known.
1601
 * @param [in]      count  Count of items to encode.
1602
 * @param [out]     len    Length of the DER encoding.
1603
 * @return  Size of the DER encoding in bytes.
1604
 */
1605
static int SizeASN_ItemsDebug(const char* name, const ASNItem* asn,
1606
    ASNSetData *data, int count, int* encSz)
1607
{
1608
    WOLFSSL_MSG_VSNPRINTF("TEMPLATE: %s", name);
1609
    return SizeASN_Items(asn, data, count, encSz);
1610
}
1611
1612
/* Creates the DER encoding of the ASN.1 items.
1613
 *
1614
 * Assumes the output buffer is large enough to hold encoding.
1615
 * Must call SizeASN_Items() to determine size of encoding and offsets.
1616
 *
1617
 * Displays the template name first.
1618
 *
1619
 * @param [in]      name    Name of ASN.1 template.
1620
 * @param [in]      asn     ASN.1 items to encode.
1621
 * @param [in]      data    Data to place in each item.
1622
 * @param [in]      count   Count of items to encode.
1623
 * @param [in, out] output  Buffer to write encoding into.
1624
 * @return  Size of the DER encoding in bytes.
1625
 */
1626
static int SetASN_ItemsDebug(const char* name, const ASNItem* asn,
1627
    ASNSetData *data, int count, byte* output)
1628
{
1629
    WOLFSSL_MSG_VSNPRINTF("TEMPLATE: %s", name);
1630
    return SetASN_Items(asn, data, count, output);
1631
}
1632
1633
/* Get the ASN.1 items from the BER encoding.
1634
 *
1635
 * Displays the template name first.
1636
 *
1637
 * @param [in]      name      Name of ASN.1 template.
1638
 * @param [in]      asn       ASN.1 items expected.
1639
 * @param [in]      data      Data array to place found items into.
1640
 * @param [in]      count     Count of items to parse.
1641
 * @param [in]      complete  Whether the whole buffer is to be used up.
1642
 * @param [in]      input     BER encoded data.
1643
 * @param [in, out] inOutIdx  On in, starting index of data.
1644
 *                            On out, end of parsed data.
1645
 * @param [in]      maxIdx    Maximum index of input data.
1646
 * @return  0 on success.
1647
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
1648
 * is invalid.
1649
 * @return  BUFFER_E when data in buffer is too small.
1650
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
1651
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
1652
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
1653
 *          non-zero length.
1654
 * @return  MP_INIT_E when the unable to initialize an mp_int.
1655
 * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
1656
 * @return  BAD_STATE_E when the data type is not supported.
1657
 */
1658
static int GetASN_ItemsDebug(const char* name, const ASNItem* asn,
1659
    ASNGetData *data, int count, int complete, const byte* input,
1660
    word32* inOutIdx, word32 maxIdx)
1661
{
1662
    WOLFSSL_MSG_VSNPRINTF("TEMPLATE: %s", name);
1663
    return GetASN_Items(asn, data, count, complete, input, inOutIdx, maxIdx);
1664
}
1665
1666
/* Calculate the size of the DER encoding.
1667
 *
1668
 * Call SetASN_Items() to write encoding to a buffer.
1669
 *
1670
 * @param [in]      asn    ASN.1 items to encode.
1671
 * @param [in, out] data   Data to place in each item. Lengths set were not
1672
 *                         known.
1673
 * @param [in]      count  Count of items to encode.
1674
 * @param [out]     len    Length of the DER encoding.
1675
 * @return  Size of the DER encoding in bytes.
1676
 */
1677
#define SizeASN_Items(asn, data, count, encSz)  \
1678
    SizeASN_ItemsDebug(#asn, asn, data, count, encSz)
1679
1680
/* Creates the DER encoding of the ASN.1 items.
1681
 *
1682
 * Assumes the output buffer is large enough to hold encoding.
1683
 * Must call SizeASN_Items() to determine size of encoding and offsets.
1684
 *
1685
 * Displays the template name first.
1686
 *
1687
 * @param [in]      name    Name of ASN.1 template.
1688
 * @param [in]      asn     ASN.1 items to encode.
1689
 * @param [in]      data    Data to place in each item.
1690
 * @param [in]      count   Count of items to encode.
1691
 * @param [in, out] output  Buffer to write encoding into.
1692
 * @return  Size of the DER encoding in bytes.
1693
 */
1694
#define SetASN_Items(asn, data, count, output)  \
1695
    SetASN_ItemsDebug(#asn, asn, data, count, output)
1696
1697
/* Get the ASN.1 items from the BER encoding.
1698
 *
1699
 * Displays the template name first.
1700
 *
1701
 * @param [in]      name      Name of ASN.1 template.
1702
 * @param [in]      asn       ASN.1 items expected.
1703
 * @param [in]      data      Data array to place found items into.
1704
 * @param [in]      count     Count of items to parse.
1705
 * @param [in]      complete  Whether the whole buffer is to be used up.
1706
 * @param [in]      input     BER encoded data.
1707
 * @param [in, out] inOutIdx  On in, starting index of data.
1708
 *                            On out, end of parsed data.
1709
 * @param [in]      maxIdx    Maximum index of input data.
1710
 * @return  0 on success.
1711
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
1712
 * is invalid.
1713
 * @return  BUFFER_E when data in buffer is too small.
1714
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
1715
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
1716
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
1717
 *          non-zero length.
1718
 * @return  MP_INIT_E when the unable to initialize an mp_int.
1719
 * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
1720
 * @return  BAD_STATE_E when the data type is not supported.
1721
 */
1722
#define GetASN_Items(asn, data, count, complete, input, inOutIdx, maxIdx)  \
1723
    GetASN_ItemsDebug(#asn, asn, data, count, complete, input, inOutIdx, maxIdx)
1724
#endif /* WOLFSSL_DEBUG_ASN_TEMPLATE */
1725
1726
/* Decode a BER encoded constructed sequence.
1727
 *
1728
 * @param [in]       input     Buffer of BER encoded data.
1729
 * @param [in, out]  inOutIdx  On in, index to start decoding from.
1730
 *                             On out, index of next encoded byte.
1731
 * @param [out]      len       Length of data under SEQUENCE.
1732
 * @param [in]       maxIdx    Maximim index of data. Index of byte after SEQ.
1733
 * @param [in]       complete  All data used with SEQUENCE and data under.
1734
 * @return  0 on success.
1735
 * @return  BUFFER_E when not enough data to complete decode.
1736
 * @return  ASN_PARSE when decoding failed.
1737
 */
1738
static int GetASN_Sequence(const byte* input, word32* inOutIdx, int* len,
1739
                           word32 maxIdx, int complete)
1740
{
1741
    int ret = 0;
1742
    word32 idx = *inOutIdx;
1743
1744
    /* Check buffer big enough for tag. */
1745
    if (idx + 1 > maxIdx) {
1746
        ret = BUFFER_E;
1747
    }
1748
    /* Check it is a constructed SEQUENCE. */
1749
    if ((ret == 0) && (input[idx++] != (ASN_SEQUENCE | ASN_CONSTRUCTED))) {
1750
        ret = ASN_PARSE_E;
1751
    }
1752
    /* Get the length. */
1753
    if ((ret == 0) && (GetASN_Length(input, &idx, len, maxIdx, 1) < 0)) {
1754
        ret = ASN_PARSE_E;
1755
    }
1756
    /* Check all data used if complete set. */
1757
    if ((ret == 0) && complete && (idx + *len != maxIdx)) {
1758
        ret = ASN_PARSE_E;
1759
    }
1760
    if (ret == 0) {
1761
        /* Return index of next byte of encoded data. */
1762
        *inOutIdx = idx;
1763
    }
1764
1765
    return ret;
1766
}
1767
1768
1769
#ifdef WOLFSSL_ASN_TEMPLATE_TYPE_CHECK
1770
/* Setup ASN data item to get an 8-bit number.
1771
 *
1772
 * @param [in] dataASN  Dynamic ASN data item.
1773
 * @param [in] num      Pointer to an 8-bit variable.
1774
 */
1775
void GetASN_Int8Bit(ASNGetData *dataASN, byte* num)
1776
{
1777
    dataASN->dataType = ASN_DATA_TYPE_WORD8;
1778
    dataASN->data.u8  = num;
1779
}
1780
1781
/* Setup ASN data item to get a 16-bit number.
1782
 *
1783
 * @param [in] dataASN  Dynamic ASN data item.
1784
 * @param [in] num      Pointer to a 16-bit variable.
1785
 */
1786
void GetASN_Int16Bit(ASNGetData *dataASN, word16* num)
1787
{
1788
    dataASN->dataType = ASN_DATA_TYPE_WORD16;
1789
    dataASN->data.u16 = num;
1790
}
1791
1792
/* Setup ASN data item to get a 32-bit number.
1793
 *
1794
 * @param [in] dataASN  Dynamic ASN data item.
1795
 * @param [in] num      Pointer to a 32-bit variable.
1796
 */
1797
void GetASN_Int32Bit(ASNGetData *dataASN, word32* num)
1798
{
1799
    dataASN->dataType = ASN_DATA_TYPE_WORD32;
1800
    dataASN->data.u32 = num;
1801
}
1802
1803
/* Setup ASN data item to get data into a buffer of a specific length.
1804
 *
1805
 * @param [in] dataASN  Dynamic ASN data item.
1806
 * @param [in] data     Buffer to hold data.
1807
 * @param [in] length   Length of buffer in bytes.
1808
 */
1809
void GetASN_Buffer(ASNGetData *dataASN, byte* data, word32* length)
1810
{
1811
    dataASN->dataType           = ASN_DATA_TYPE_BUFFER;
1812
    dataASN->data.buffer.data   = data;
1813
    dataASN->data.buffer.length = length;
1814
}
1815
1816
/* Setup ASN data item to check parsed data against expected buffer.
1817
 *
1818
 * @param [in] dataASN  Dynamic ASN data item.
1819
 * @param [in] data     Buffer containing expected data.
1820
 * @param [in] length   Length of buffer in bytes.
1821
 */
1822
void GetASN_ExpBuffer(ASNGetData *dataASN, const byte* data, word32 length)
1823
{
1824
    dataASN->dataType        = ASN_DATA_TYPE_EXP_BUFFER;
1825
    dataASN->data.ref.data   = data;
1826
    dataASN->data.ref.length = length;
1827
}
1828
1829
/* Setup ASN data item to get a number into an mp_int.
1830
 *
1831
 * @param [in] dataASN  Dynamic ASN data item.
1832
 * @param [in] num      Multi-precision number object.
1833
 */
1834
void GetASN_MP(ASNGetData *dataASN, mp_int* num)
1835
{
1836
    dataASN->dataType = ASN_DATA_TYPE_MP;
1837
    dataASN->data.mp  = num;
1838
}
1839
1840
/* Setup ASN data item to get a positive or negative number into an mp_int.
1841
 *
1842
 * @param [in] dataASN  Dynamic ASN data item.
1843
 * @param [in] num      Multi-precision number object.
1844
 */
1845
void GetASN_MP_PosNeg(ASNGetData *dataASN, mp_int* num)
1846
{
1847
    dataASN->dataType = ASN_DATA_TYPE_MP_POS_NEG;
1848
    dataASN->data.mp  = num;
1849
}
1850
1851
/* Setup ASN data item to be a choice of tags.
1852
 *
1853
 * @param [in] dataASN  Dynamic ASN data item.
1854
 * @param [in] options  0 terminated list of tags that are valid.
1855
 */
1856
void GetASN_Choice(ASNGetData *dataASN, const byte* options)
1857
{
1858
    dataASN->dataType    = ASN_DATA_TYPE_CHOICE;
1859
    dataASN->data.choice = options;
1860
}
1861
1862
/* Setup ASN data item to get a boolean value.
1863
 *
1864
 * @param [in] dataASN  Dynamic ASN data item.
1865
 * @param [in] num      Pointer to an 8-bit variable.
1866
 */
1867
void GetASN_Boolean(ASNGetData *dataASN, byte* num)
1868
{
1869
    dataASN->dataType    = ASN_DATA_TYPE_NONE;
1870
    dataASN->data.choice = num;
1871
}
1872
1873
/* Setup ASN data item to be a an OID of a specific type.
1874
 *
1875
 * @param [in] dataASN  Dynamic ASN data item.
1876
 * @param [in] oidType  Type of OID to expect.
1877
 */
1878
void GetASN_OID(ASNGetData *dataASN, int oidType)
1879
{
1880
    dataASN->data.oid.type = oidType;
1881
}
1882
1883
/* Get the data and length from an ASN data item.
1884
 *
1885
 * @param [in]  dataASN  Dynamic ASN data item.
1886
 * @param [out] data     Pointer to data of item.
1887
 * @param [out] length   Length of buffer in bytes.
1888
 */
1889
void GetASN_GetConstRef(ASNGetData * dataASN, const byte** data, word32* length)
1890
{
1891
    *data   = dataASN->data.ref.data;
1892
    *length = dataASN->data.ref.length;
1893
}
1894
1895
/* Get the data and length from an ASN data item.
1896
 *
1897
 * @param [in]  dataASN  Dynamic ASN data item.
1898
 * @param [out] data     Pointer to data of item.
1899
 * @param [out] length   Length of buffer in bytes.
1900
 */
1901
void GetASN_GetRef(ASNGetData * dataASN, byte** data, word32* length)
1902
{
1903
    *data   = (byte*)dataASN->data.ref.data;
1904
    *length =        dataASN->data.ref.length;
1905
}
1906
1907
/* Get the data and length from an ASN data item that is an OID.
1908
 *
1909
 * @param [in]  dataASN  Dynamic ASN data item.
1910
 * @param [out] data     Pointer to .
1911
 * @param [out] length   Length of buffer in bytes.
1912
 */
1913
void GetASN_OIDData(ASNGetData * dataASN, byte** data, word32* length)
1914
{
1915
    *data   = (byte*)dataASN->data.oid.data;
1916
    *length =        dataASN->data.oid.length;
1917
}
1918
1919
/* Setup an ASN data item to set a boolean.
1920
 *
1921
 * @param [in] dataASN  Dynamic ASN data item.
1922
 * @param [in] val      Boolean value.
1923
 */
1924
void SetASN_Boolean(ASNSetData *dataASN, byte val)
1925
{
1926
    dataASN->dataType = ASN_DATA_TYPE_NONE;
1927
    dataASN->data.u8  = val;
1928
}
1929
1930
/* Setup an ASN data item to set an 8-bit number.
1931
 *
1932
 * @param [in] dataASN  Dynamic ASN data item.
1933
 * @param [in] num      8-bit number to set.
1934
 */
1935
void SetASN_Int8Bit(ASNSetData *dataASN, byte num)
1936
{
1937
    dataASN->dataType = ASN_DATA_TYPE_WORD8;
1938
    dataASN->data.u8  = num;
1939
}
1940
1941
/* Setup an ASN data item to set a 16-bit number.
1942
 *
1943
 * @param [in] dataASN  Dynamic ASN data item.
1944
 * @param [in] num      16-bit number to set.
1945
 */
1946
void SetASN_Int16Bit(ASNSetData *dataASN, word16 num)
1947
{
1948
    dataASN->dataType = ASN_DATA_TYPE_WORD16;
1949
    dataASN->data.u16 = num;
1950
}
1951
1952
/* Setup an ASN data item to set the data in a buffer.
1953
 *
1954
 * @param [in] dataASN  Dynamic ASN data item.
1955
 * @param [in] data     Buffer containing data to set.
1956
 * @param [in] length   Length of data in buffer in bytes.
1957
 */
1958
void SetASN_Buffer(ASNSetData *dataASN, const byte* data, word32 length)
1959
{
1960
    dataASN->data.buffer.data   = data;
1961
    dataASN->data.buffer.length = length;
1962
}
1963
1964
/* Setup an ASN data item to set the DER encode data in a buffer.
1965
 *
1966
 * @param [in] dataASN  Dynamic ASN data item.
1967
 * @param [in] data     Buffer containing BER encoded data to set.
1968
 * @param [in] length   Length of data in buffer in bytes.
1969
 */
1970
void SetASN_ReplaceBuffer(ASNSetData *dataASN, const byte* data, word32 length)
1971
{
1972
    dataASN->dataType           = ASN_DATA_TYPE_REPLACE_BUFFER;
1973
    dataASN->data.buffer.data   = data;
1974
    dataASN->data.buffer.length = length;
1975
}
1976
1977
/* Setup an ASN data item to set an multi-precision number.
1978
 *
1979
 * @param [in] dataASN  Dynamic ASN data item.
1980
 * @param [in] num      Multi-precision number.
1981
 */
1982
void SetASN_MP(ASNSetData *dataASN, mp_int* num)
1983
{
1984
    dataASN->dataType = ASN_DATA_TYPE_MP;
1985
    dataASN->data.mp  = num;
1986
}
1987
1988
/* Setup an ASN data item to set an OID based on id and type.
1989
 *
1990
 * oid and oidType pair are unique.
1991
 *
1992
 * @param [in] dataASN  Dynamic ASN data item.
1993
 * @param [in] oid      OID identifier.
1994
 * @param [in] oidType  Type of OID.
1995
 */
1996
void SetASN_OID(ASNSetData *dataASN, int oid, int oidType)
1997
{
1998
    dataASN->data.buffer.data = OidFromId(oid, oidType,
1999
                                                  &dataASN->data.buffer.length);
2000
}
2001
#endif /* WOLFSSL_ASN_TEMPLATE_TYPE_CHECK */
2002
2003
#ifdef CRLDP_VALIDATE_DATA
2004
/* Get the data of the BIT_STRING as a 16-bit number.
2005
 *
2006
 * @param [in]  dataASN  Dynamic ASN data item.
2007
 * @param [out] val      ASN.1 item's data as a 16-bit number.
2008
 * @return  0 on success.
2009
 * @return  ASN_PARSE_E when BITSTRING value is more than 2 bytes.
2010
 * @return  ASN_PARSE_E when unused bits of BITSTRING is invalid.
2011
 */
2012
static int GetASN_BitString_Int16Bit(ASNGetData* dataASN, word16* val)
2013
{
2014
    int ret;
2015
    int i;
2016
    const byte* input = dataASN->data.ref.data;
2017
    int length = dataASN->data.ref.length;
2018
2019
    /* Validate the BIT_STRING data. */
2020
    ret = GetASN_BitString(input, 0, length);
2021
    if (ret == 0) {
2022
        /* Skip unused bits byte. */
2023
        input++;
2024
        length--;
2025
2026
        /* Check the data is usable. */
2027
        if (length == 0 || length > 2) {
2028
#ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
2029
            WOLFSSL_MSG_VSNPRINTF("Expecting 1 or 2 bytes: %d", length);
2030
#endif
2031
            ret = ASN_PARSE_E;
2032
        }
2033
    }
2034
    if (ret == 0) {
2035
        /* Fill 16-bit var with all the data. */
2036
        *val = 0;
2037
        for (i = 0; i < length; i++) {
2038
            *val <<= 8;
2039
            *val |= input[i];
2040
        }
2041
    }
2042
    return ret;
2043
}
2044
#endif /* CRLDP_VALIDATE_DATA */
2045
2046
#endif /* WOLFSSL_ASN_TEMPLATE */
2047
2048
2049
/* Decode the BER/DER length field.
2050
 *
2051
 * @param [in]      input     BER encoded data.
2052
 * @param [in, out] inOutIdx  On in, starting index of length.
2053
 *                            On out, end of parsed length.
2054
 * @param [out]     len       Length value decoded.
2055
 * @param [in]      maxIdx    Maximum index of input data.
2056
 * @return  Length on success.
2057
 * @return  ASN_PARSE_E if the encoding is invalid.
2058
 * @return  BUFFER_E when not enough data to complete decode.
2059
 */
2060
int GetLength(const byte* input, word32* inOutIdx, int* len, word32 maxIdx)
2061
0
{
2062
0
    return GetLength_ex(input, inOutIdx, len, maxIdx, 1);
2063
0
}
2064
2065
2066
/* Decode the BER/DER length field and check the length is valid on request.
2067
 *
2068
 * BER/DER has Type-Length-Value triplets.
2069
 * When requested will check that the Length decoded, indicating the number
2070
 * of bytes in the Value, is available in the buffer after the Length bytes.
2071
 *
2072
 * Only supporting a length upto INT_MAX.
2073
 *
2074
 * @param [in]      input     BER encoded data.
2075
 * @param [in, out] inOutIdx  On in, starting index of length.
2076
 *                            On out, end of parsed length.
2077
 * @param [out]     len       Length value decoded.
2078
 * @param [in]      maxIdx    Maximum index of input data.
2079
 * @param [in]      check     Whether to check the buffer has at least the
2080
 *                            decoded length of bytes remaining.
2081
 * @return  Length on success.
2082
 * @return  ASN_PARSE_E if the encoding is invalid.
2083
 * @return  BUFFER_E when not enough data to complete decode.
2084
 */
2085
int GetLength_ex(const byte* input, word32* inOutIdx, int* len, word32 maxIdx,
2086
                 int check)
2087
11.1k
{
2088
11.1k
    int     length = 0;
2089
11.1k
    word32  idx = *inOutIdx;
2090
11.1k
    byte    b;
2091
2092
    /* Ensure zero return length on error. */
2093
11.1k
    *len = 0;
2094
2095
    /* Check there is at least on byte available containing length information.
2096
     */
2097
11.1k
    if ((idx + 1) > maxIdx) {
2098
0
        WOLFSSL_MSG("GetLength - bad index on input");
2099
0
        return BUFFER_E;
2100
0
    }
2101
2102
    /* Get the first length byte. */
2103
11.1k
    b = input[idx++];
2104
    /* Check if the first byte indicates the count of bytes. */
2105
11.1k
    if (b >= ASN_LONG_LENGTH) {
2106
        /* Bottom 7 bits are the number of bytes to calculate length with.
2107
         * Note: 0 indicates indefinte length encoding *not* 0 bytes of length.
2108
         */
2109
1.22k
        word32 bytes = b & 0x7F;
2110
1.22k
        int minLen;
2111
2112
        /* Calculate minimum length to be encoded with bytes. */
2113
1.22k
        if (b == 0x80) {
2114
            /* Indefinite length encoding - no length bytes. */
2115
0
            minLen = 0;
2116
0
        }
2117
1.22k
        else if (bytes == 1) {
2118
1.22k
            minLen = 0x80;
2119
1.22k
        }
2120
        /* Only support up to the number of bytes that fit into return var. */
2121
0
        else if (bytes > sizeof(length)) {
2122
0
            WOLFSSL_MSG("GetLength - overlong data length spec");
2123
0
            return ASN_PARSE_E;
2124
0
        } else {
2125
0
            minLen = 1 << ((bytes - 1) * 8);
2126
0
        }
2127
2128
        /* Check the number of bytes required are available. */
2129
1.22k
        if ((idx + bytes) > maxIdx) {
2130
0
            WOLFSSL_MSG("GetLength - bad long length");
2131
0
            return BUFFER_E;
2132
0
        }
2133
2134
        /* Big-endian encoding of number. */
2135
2.45k
        while (bytes--) {
2136
1.22k
            b = input[idx++];
2137
1.22k
            length = (length << 8) | b;
2138
1.22k
        }
2139
        /* Negative value indicates we overflowed the signed int. */
2140
1.22k
        if (length < 0) {
2141
0
            return ASN_PARSE_E;
2142
0
        }
2143
        /* Don't allow lengths that are longer than strictly required. */
2144
1.22k
        if (length < minLen) {
2145
0
            return ASN_PARSE_E;
2146
0
        }
2147
1.22k
    }
2148
9.91k
    else {
2149
        /* Length in first byte. */
2150
9.91k
        length = b;
2151
9.91k
    }
2152
2153
    /* When request, check the buffer has at least length bytes left. */
2154
11.1k
    if (check && ((idx + length) > maxIdx)) {
2155
0
        WOLFSSL_MSG("GetLength - value exceeds buffer length");
2156
0
        return BUFFER_E;
2157
0
    }
2158
2159
    /* Return index after length encoding. */
2160
11.1k
    *inOutIdx = idx;
2161
    /* Return length if valid. */
2162
11.1k
    if (length > 0) {
2163
11.1k
        *len = length;
2164
11.1k
    }
2165
2166
    /* Return length calculated or error code. */
2167
11.1k
    return length;
2168
11.1k
}
2169
2170
2171
/* Gets the tag of next BER/DER encoded item.
2172
 *
2173
 * Checks there is enough data in the buffer for the tag byte.
2174
 *
2175
 * @param [in]      input     BER encoded data.
2176
 * @param [in, out] inOutIdx  On in, starting index of tag.
2177
 *                            On out, end of parsed tag.
2178
 * @param [out]     tag       Tag value found.
2179
 * @param [in]      maxIdx    Maximum index of input data.
2180
 *
2181
 * return  0 on success
2182
 * return  BAD_FUNC_ARG when tag, inOutIdx or input is NULL.
2183
 * return  BUFFER_E when not enough space in buffer for tag.
2184
 */
2185
int GetASNTag(const byte* input, word32* inOutIdx, byte* tag, word32 maxIdx)
2186
11.1k
{
2187
11.1k
    int ret = 0;
2188
11.1k
    word32 idx = 0;
2189
2190
    /* Check validity of parameters. */
2191
11.1k
    if ((tag == NULL) || (inOutIdx == NULL) || (input == NULL)) {
2192
0
        ret = BAD_FUNC_ARG;
2193
0
    }
2194
11.1k
    if (ret == 0) {
2195
        /* Get index and ensure space for tag. */
2196
11.1k
        idx = *inOutIdx;
2197
11.1k
        if (idx + ASN_TAG_SZ > maxIdx) {
2198
0
            WOLFSSL_MSG("Buffer too small for ASN tag");
2199
0
            ret = BUFFER_E;
2200
0
        }
2201
11.1k
    }
2202
11.1k
    if (ret == 0) {
2203
        /* Return the tag and the index after tag. */
2204
11.1k
        *tag = input[idx];
2205
11.1k
        *inOutIdx = idx + ASN_TAG_SZ;
2206
11.1k
    }
2207
    /* Return error code. */
2208
11.1k
    return ret;
2209
11.1k
}
2210
2211
2212
/* Decode the DER/BER header (Type-Length) and check the length when requested.
2213
 *
2214
 * BER/DER has Type-Length-Value triplets.
2215
 * Check that the tag/type is the required value.
2216
 * When requested will check that the Length decoded, indicating the number
2217
 * of bytes in the Value, is available in the buffer after the Length bytes.
2218
 *
2219
 * Only supporting a length upto INT_MAX.
2220
 *
2221
 * @param [in]      input     Buffer holding DER/BER encoded data.
2222
 * @param [in]      tag       ASN.1 tag value expected in header.
2223
 * @param [in, out] inOutIdx  On in, starting index of header.
2224
 *                            On out, end of parsed header.
2225
 * @param [out]     len       Number of bytes in the ASN.1 data.
2226
 * @param [in]      maxIdx    Length of data in buffer.
2227
 * @param [in]      check     Whether to check the buffer has at least the
2228
 *                            decoded length of bytes remaining.
2229
 * @return  Number of bytes in the ASN.1 data on success.
2230
 * @return  BUFFER_E when there is not enough data to parse.
2231
 * @return  ASN_PARSE_E when the expected tag is not found or length is invalid.
2232
 */
2233
static int GetASNHeader_ex(const byte* input, byte tag, word32* inOutIdx,
2234
                           int* len, word32 maxIdx, int check)
2235
11.1k
{
2236
11.1k
    int    ret = 0;
2237
11.1k
    word32 idx = *inOutIdx;
2238
11.1k
    byte   tagFound;
2239
11.1k
    int    length = 0;
2240
2241
    /* Get tag/type. */
2242
11.1k
    if (GetASNTag(input, &idx, &tagFound, maxIdx) != 0) {
2243
0
        ret = ASN_PARSE_E;
2244
0
    }
2245
    /* Ensure tag is the expected value. */
2246
11.1k
    if ((ret == 0) && (tagFound != tag)) {
2247
0
        ret = ASN_PARSE_E;
2248
0
    }
2249
    /* Get the encoded length. */
2250
11.1k
    if ((ret == 0) && (GetLength_ex(input, &idx, &length, maxIdx, check) < 0)) {
2251
0
        ret = ASN_PARSE_E;
2252
0
    }
2253
11.1k
    if (ret == 0) {
2254
        /* Return the length of data and index after header. */
2255
11.1k
        *len      = length;
2256
11.1k
        *inOutIdx = idx;
2257
11.1k
        ret = length;
2258
11.1k
    }
2259
    /* Return number of data bytes or error code. */
2260
11.1k
    return ret;
2261
11.1k
}
2262
2263
2264
/* Decode the DER/BER header (Type-Length) and check the length.
2265
 *
2266
 * BER/DER has Type-Length-Value triplets.
2267
 * Check that the tag/type is the required value.
2268
 * Checks that the Length decoded, indicating the number of bytes in the Value,
2269
 * is available in the buffer after the Length bytes.
2270
 *
2271
 * @param [in]      input     Buffer holding DER/BER encoded data.
2272
 * @param [in]      tag       ASN.1 tag value expected in header.
2273
 * @param [in, out] inOutIdx  On in, starting index of header.
2274
 *                            On out, end of parsed header.
2275
 * @param [out]     len       Number of bytes in the ASN.1 data.
2276
 * @param [in]      maxIdx    Length of data in buffer.
2277
 * @return  Number of bytes in the ASN.1 data on success.
2278
 * @return  BUFFER_E when there is not enough data to parse.
2279
 * @return  ASN_PARSE_E when the expected tag is not found or length is invalid.
2280
 */
2281
static int GetASNHeader(const byte* input, byte tag, word32* inOutIdx, int* len,
2282
                        word32 maxIdx)
2283
11.1k
{
2284
11.1k
    return GetASNHeader_ex(input, tag, inOutIdx, len, maxIdx, 1);
2285
11.1k
}
2286
2287
#ifndef WOLFSSL_ASN_TEMPLATE
2288
static int GetHeader(const byte* input, byte* tag, word32* inOutIdx, int* len,
2289
                     word32 maxIdx, int check)
2290
0
{
2291
0
    word32 idx = *inOutIdx;
2292
0
    int    length;
2293
2294
0
    if ((idx + 1) > maxIdx)
2295
0
        return BUFFER_E;
2296
2297
0
    *tag = input[idx++];
2298
2299
0
    if (GetLength_ex(input, &idx, &length, maxIdx, check) < 0)
2300
0
        return ASN_PARSE_E;
2301
2302
0
    *len      = length;
2303
0
    *inOutIdx = idx;
2304
0
    return length;
2305
0
}
2306
#endif
2307
2308
/* Decode the header of a BER/DER encoded SEQUENCE.
2309
 *
2310
 * @param [in]      input     Buffer holding DER/BER encoded data.
2311
 * @param [in, out] inOutIdx  On in, starting index of header.
2312
 *                            On out, end of parsed header.
2313
 * @param [out]     len       Number of bytes in the ASN.1 data.
2314
 * @param [in]      maxIdx    Length of data in buffer.
2315
 * @return  Number of bytes in the ASN.1 data on success.
2316
 * @return  BUFFER_E when there is not enough data to parse.
2317
 * @return  ASN_PARSE_E when the tag is not a SEQUENCE or length is invalid.
2318
 */
2319
int GetSequence(const byte* input, word32* inOutIdx, int* len,
2320
                           word32 maxIdx)
2321
3.71k
{
2322
3.71k
    return GetASNHeader(input, ASN_SEQUENCE | ASN_CONSTRUCTED, inOutIdx, len,
2323
3.71k
                        maxIdx);
2324
3.71k
}
2325
2326
/* Decode the header of a BER/DER encoded SEQUENCE.
2327
 *
2328
 * @param [in]      input     Buffer holding DER/BER encoded data.
2329
 * @param [in, out] inOutIdx  On in, starting index of header.
2330
 *                            On out, end of parsed header.
2331
 * @param [out]     len       Number of bytes in the ASN.1 data.
2332
 * @param [in]      maxIdx    Length of data in buffer.
2333
 * @param [in]      check     Whether to check the buffer has at least the
2334
 *                            decoded length of bytes remaining.
2335
 * @return  Number of bytes in the ASN.1 data on success.
2336
 * @return  BUFFER_E when there is not enough data to parse.
2337
 * @return  ASN_PARSE_E when the tag is not a SEQUENCE or length is invalid.
2338
 */
2339
int GetSequence_ex(const byte* input, word32* inOutIdx, int* len,
2340
                           word32 maxIdx, int check)
2341
0
{
2342
0
    return GetASNHeader_ex(input, ASN_SEQUENCE | ASN_CONSTRUCTED, inOutIdx, len,
2343
0
                        maxIdx, check);
2344
0
}
2345
2346
/* Decode the header of a BER/DER encoded SET.
2347
 *
2348
 * @param [in]      input     Buffer holding DER/BER encoded data.
2349
 * @param [in, out] inOutIdx  On in, starting index of header.
2350
 *                            On out, end of parsed header.
2351
 * @param [out]     len       Number of bytes in the ASN.1 data.
2352
 * @param [in]      maxIdx    Length of data in buffer.
2353
 * @return  Number of bytes in the ASN.1 data on success.
2354
 * @return  BUFFER_E when there is not enough data to parse.
2355
 * @return  ASN_PARSE_E when the tag is not a SET or length is invalid.
2356
 */
2357
int GetSet(const byte* input, word32* inOutIdx, int* len,
2358
                        word32 maxIdx)
2359
0
{
2360
0
    return GetASNHeader(input, ASN_SET | ASN_CONSTRUCTED, inOutIdx, len,
2361
0
                        maxIdx);
2362
0
}
2363
2364
/* Decode the header of a BER/DER encoded SET.
2365
 *
2366
 * @param [in]      input     Buffer holding DER/BER encoded data.
2367
 * @param [in, out] inOutIdx  On in, starting index of header.
2368
 *                            On out, end of parsed header.
2369
 * @param [out]     len       Number of bytes in the ASN.1 data.
2370
 * @param [in]      maxIdx    Length of data in buffer.
2371
 * @param [in]      check     Whether to check the buffer has at least the
2372
 *                            decoded length of bytes remaining.
2373
 * @return  Number of bytes in the ASN.1 data on success.
2374
 * @return  BUFFER_E when there is not enough data to parse.
2375
 * @return  ASN_PARSE_E when the tag is not a SET or length is invalid.
2376
 */
2377
int GetSet_ex(const byte* input, word32* inOutIdx, int* len,
2378
                        word32 maxIdx, int check)
2379
0
{
2380
0
    return GetASNHeader_ex(input, ASN_SET | ASN_CONSTRUCTED, inOutIdx, len,
2381
0
                        maxIdx, check);
2382
0
}
2383
2384
#if !defined(WOLFSSL_ASN_TEMPLATE) || defined(HAVE_OCSP)
2385
/* Decode the BER/DER encoded NULL.
2386
 *
2387
 * No data in a NULL ASN.1 item.
2388
 * Ensure that the all fields are as expected and move index past the element.
2389
 *
2390
 * @param [in]      input     Buffer holding DER/BER encoded data.
2391
 * @param [in, out] inOutIdx  On in, starting index of NULL item.
2392
 *                            On out, end of parsed NULL item.
2393
 * @param [in]      maxIdx    Length of data in buffer.
2394
 * @return  0 on success.
2395
 * @return  BUFFER_E when there is not enough data to parse.
2396
 * @return  ASN_TAG_NULL_E when the NULL tag is not found.
2397
 * @return  ASN_EXPECT_0_E when the length is not zero.
2398
 */
2399
static int GetASNNull(const byte* input, word32* inOutIdx, word32 maxIdx)
2400
0
{
2401
0
    int ret = 0;
2402
0
    word32 idx = *inOutIdx;
2403
2404
    /* Check buffer has enough data for a NULL item. */
2405
0
    if ((idx + 2) > maxIdx) {
2406
0
        ret = BUFFER_E;
2407
0
    }
2408
    /* Check the tag is NULL. */
2409
0
    if ((ret == 0) && (input[idx++] != ASN_TAG_NULL)) {
2410
0
        ret = ASN_TAG_NULL_E;
2411
0
    }
2412
    /* Check the length is zero. */
2413
0
    if ((ret == 0) && (input[idx++] != 0)) {
2414
0
        ret = ASN_EXPECT_0_E;
2415
0
    }
2416
0
    if (ret == 0) {
2417
        /* Return the index after NULL tag. */
2418
0
        *inOutIdx = idx;
2419
0
    }
2420
    /* Return error code. */
2421
0
    return ret;
2422
0
}
2423
#endif
2424
2425
#ifndef WOLFSSL_ASN_TEMPLATE
2426
/* Set the DER/BER encoding of the ASN.1 NULL element.
2427
 *
2428
 * output  Buffer to write into.
2429
 * returns the number of bytes added to the buffer.
2430
 */
2431
static int SetASNNull(byte* output)
2432
0
{
2433
0
    output[0] = ASN_TAG_NULL;
2434
0
    output[1] = 0;
2435
2436
0
    return 2;
2437
0
}
2438
#endif
2439
2440
#ifndef NO_CERTS
2441
#ifndef WOLFSSL_ASN_TEMPLATE
2442
/* Get the DER/BER encoding of an ASN.1 BOOLEAN.
2443
 *
2444
 * input     Buffer holding DER/BER encoded data.
2445
 * inOutIdx  Current index into buffer to parse.
2446
 * maxIdx    Length of data in buffer.
2447
 * returns BUFFER_E when there is not enough data to parse.
2448
 *         ASN_PARSE_E when the BOOLEAN tag is not found or length is not 1.
2449
 *         Otherwise, 0 to indicate the value was false and 1 to indicate true.
2450
 */
2451
static int GetBoolean(const byte* input, word32* inOutIdx, word32 maxIdx)
2452
0
{
2453
0
    word32 idx = *inOutIdx;
2454
0
    byte   b;
2455
2456
0
    if ((idx + 3) > maxIdx)
2457
0
        return BUFFER_E;
2458
2459
0
    b = input[idx++];
2460
0
    if (b != ASN_BOOLEAN)
2461
0
        return ASN_PARSE_E;
2462
2463
0
    if (input[idx++] != 1)
2464
0
        return ASN_PARSE_E;
2465
2466
0
    b = input[idx++] != 0;
2467
2468
0
    *inOutIdx = idx;
2469
0
    return b;
2470
0
}
2471
#endif
2472
#endif /* !NO_CERTS*/
2473
2474
2475
/* Decode the header of a BER/DER encoded OCTET STRING.
2476
 *
2477
 * @param [in]      input     Buffer holding DER/BER encoded data.
2478
 * @param [in, out] inOutIdx  On in, starting index of header.
2479
 *                            On out, end of parsed header.
2480
 * @param [out]     len       Number of bytes in the ASN.1 data.
2481
 * @param [in]      maxIdx    Length of data in buffer.
2482
 * @return  Number of bytes in the ASN.1 data on success.
2483
 * @return  BUFFER_E when there is not enough data to parse.
2484
 * @return  ASN_PARSE_E when the tag is not a OCTET STRING or length is invalid.
2485
 */
2486
int GetOctetString(const byte* input, word32* inOutIdx, int* len, word32 maxIdx)
2487
0
{
2488
0
    return GetASNHeader(input, ASN_OCTET_STRING, inOutIdx, len, maxIdx);
2489
0
}
2490
2491
#ifndef WOLFSSL_ASN_TEMPLATE
2492
/* Get the DER/BER encoding of an ASN.1 INTEGER header.
2493
 *
2494
 * Removes the leading zero byte when found.
2495
 *
2496
 * input     Buffer holding DER/BER encoded data.
2497
 * inOutIdx  Current index into buffer to parse.
2498
 * len       The number of bytes in the ASN.1 data (excluding any leading zero).
2499
 * maxIdx    Length of data in buffer.
2500
 * returns BUFFER_E when there is not enough data to parse.
2501
 *         ASN_PARSE_E when the INTEGER tag is not found, length is invalid,
2502
 *         or invalid use of or missing leading zero.
2503
 *         Otherwise, 0 to indicate success.
2504
 */
2505
static int GetASNInt(const byte* input, word32* inOutIdx, int* len,
2506
                     word32 maxIdx)
2507
7.42k
{
2508
7.42k
    int    ret;
2509
2510
7.42k
    ret = GetASNHeader(input, ASN_INTEGER, inOutIdx, len, maxIdx);
2511
7.42k
    if (ret < 0)
2512
0
        return ret;
2513
2514
7.42k
    if (*len > 0) {
2515
2516
7.42k
#ifndef WOLFSSL_ASN_INT_LEAD_0_ANY
2517
        /* check for invalid padding on negative integer.
2518
         * c.f. X.690 (ISO/IEC 8825-2:2003 (E)) 10.4.6; RFC 5280 4.1
2519
         */
2520
7.42k
        if (*len > 1) {
2521
7.26k
            if ((input[*inOutIdx] == 0xff) && (input[*inOutIdx + 1] & 0x80))
2522
0
                return ASN_PARSE_E;
2523
7.26k
        }
2524
7.42k
#endif
2525
2526
        /* remove leading zero, unless there is only one 0x00 byte */
2527
7.42k
        if ((input[*inOutIdx] == 0x00) && (*len > 1)) {
2528
2.84k
            (*inOutIdx)++;
2529
2.84k
            (*len)--;
2530
2531
2.84k
#ifndef WOLFSSL_ASN_INT_LEAD_0_ANY
2532
2.84k
            if (*len > 0 && (input[*inOutIdx] & 0x80) == 0)
2533
0
                return ASN_PARSE_E;
2534
2.84k
#endif
2535
2.84k
        }
2536
7.42k
    }
2537
2538
7.42k
    return 0;
2539
7.42k
}
2540
2541
#ifndef NO_CERTS
2542
/* Get the DER/BER encoding of an ASN.1 INTEGER that has a value of no more than
2543
 * 7 bits.
2544
 *
2545
 * input     Buffer holding DER/BER encoded data.
2546
 * inOutIdx  Current index into buffer to parse.
2547
 * maxIdx    Length of data in buffer.
2548
 * returns BUFFER_E when there is not enough data to parse.
2549
 *         ASN_PARSE_E when the INTEGER tag is not found or length is invalid.
2550
 *         Otherwise, the 7-bit value.
2551
 */
2552
static int GetInteger7Bit(const byte* input, word32* inOutIdx, word32 maxIdx)
2553
0
{
2554
0
    word32 idx = *inOutIdx;
2555
0
    byte   b;
2556
2557
0
    if ((idx + 3) > maxIdx)
2558
0
        return BUFFER_E;
2559
2560
0
    if (GetASNTag(input, &idx, &b, maxIdx) != 0)
2561
0
        return ASN_PARSE_E;
2562
0
    if (b != ASN_INTEGER)
2563
0
        return ASN_PARSE_E;
2564
0
    if (input[idx++] != 1)
2565
0
        return ASN_PARSE_E;
2566
0
    b = input[idx++];
2567
2568
0
    *inOutIdx = idx;
2569
0
    return b;
2570
0
}
2571
2572
#if defined(WC_RSA_PSS) && !defined(NO_RSA)
2573
/* Get the DER/BER encoding of an ASN.1 INTEGER that has a value of no more than
2574
 * 16 bits.
2575
 *
2576
 * input     Buffer holding DER/BER encoded data.
2577
 * inOutIdx  Current index into buffer to parse.
2578
 * maxIdx    Length of data in buffer.
2579
 * returns BUFFER_E when there is not enough data to parse.
2580
 *         ASN_PARSE_E when the INTEGER tag is not found or length is invalid.
2581
 *         Otherwise, the 16-bit value.
2582
 */
2583
static int GetInteger16Bit(const byte* input, word32* inOutIdx, word32 maxIdx)
2584
0
{
2585
0
    word32 idx = *inOutIdx;
2586
0
    byte tag;
2587
0
    word16 n;
2588
2589
0
    if ((idx + 2) > maxIdx)
2590
0
        return BUFFER_E;
2591
2592
0
    if (GetASNTag(input, &idx, &tag, maxIdx) != 0)
2593
0
        return ASN_PARSE_E;
2594
0
    if (tag != ASN_INTEGER)
2595
0
        return ASN_PARSE_E;
2596
0
    if (input[idx] == 1) {
2597
0
        idx++;
2598
0
        if ((idx + 1) > maxIdx) {
2599
0
            return ASN_PARSE_E;
2600
0
        }
2601
0
        n = input[idx++];
2602
0
    }
2603
0
    else if (input[idx] == 2) {
2604
0
        idx++;
2605
0
        if ((idx + 2) > maxIdx) {
2606
0
            return ASN_PARSE_E;
2607
0
        }
2608
0
        n = input[idx++];
2609
0
        n = (n << 8) | input[idx++];
2610
0
    }
2611
0
    else
2612
0
        return ASN_PARSE_E;
2613
2614
0
    *inOutIdx = idx;
2615
0
    return n;
2616
0
}
2617
#endif /* WC_RSA_PSS && !NO_RSA */
2618
#endif /* !NO_CERTS */
2619
#endif /* !WOLFSSL_ASN_TEMPLATE */
2620
2621
#if !defined(NO_DSA) && !defined(NO_SHA)
2622
static const char sigSha1wDsaName[] = "SHAwDSA";
2623
static const char sigSha256wDsaName[] = "SHA256wDSA";
2624
#endif /* NO_DSA */
2625
#ifndef NO_RSA
2626
#ifdef WOLFSSL_MD2
2627
    static const char  sigMd2wRsaName[] = "md2WithRSAEncryption";
2628
#endif
2629
#ifndef NO_MD5
2630
    static const char  sigMd5wRsaName[] = "md5WithRSAEncryption";
2631
#endif
2632
#ifndef NO_SHA
2633
    static const char  sigSha1wRsaName[] = "sha1WithRSAEncryption";
2634
#endif
2635
#ifdef WOLFSSL_SHA224
2636
    static const char sigSha224wRsaName[] = "sha224WithRSAEncryption";
2637
#endif
2638
#ifndef NO_SHA256
2639
    static const char sigSha256wRsaName[] = "sha256WithRSAEncryption";
2640
#endif
2641
#ifdef WOLFSSL_SHA384
2642
    static const char sigSha384wRsaName[] = "sha384WithRSAEncryption";
2643
#endif
2644
#ifdef WOLFSSL_SHA512
2645
    static const char sigSha512wRsaName[] = "sha512WithRSAEncryption";
2646
#endif
2647
#ifdef WOLFSSL_SHA3
2648
#ifndef WOLFSSL_NOSHA3_224
2649
    static const char sigSha3_224wRsaName[] = "sha3_224WithRSAEncryption";
2650
#endif
2651
#ifndef WOLFSSL_NOSHA3_256
2652
    static const char sigSha3_256wRsaName[] = "sha3_256WithRSAEncryption";
2653
#endif
2654
#ifndef WOLFSSL_NOSHA3_384
2655
    static const char sigSha3_384wRsaName[] = "sha3_384WithRSAEncryption";
2656
#endif
2657
#ifndef WOLFSSL_NOSHA3_512
2658
    static const char sigSha3_512wRsaName[] = "sha3_512WithRSAEncryption";
2659
#endif
2660
#endif
2661
#ifdef WC_RSA_PSS
2662
    static const char sigRsaSsaPssName[] = "rsassaPss";
2663
#endif
2664
#endif /* NO_RSA */
2665
#ifdef HAVE_ECC
2666
#ifndef NO_SHA
2667
    static const char sigSha1wEcdsaName[] = "SHAwECDSA";
2668
#endif
2669
#ifdef WOLFSSL_SHA224
2670
    static const char sigSha224wEcdsaName[] = "SHA224wECDSA";
2671
#endif
2672
#ifndef NO_SHA256
2673
    static const char sigSha256wEcdsaName[] = "SHA256wECDSA";
2674
#endif
2675
#ifdef WOLFSSL_SHA384
2676
    static const char sigSha384wEcdsaName[] = "SHA384wECDSA";
2677
#endif
2678
#ifdef WOLFSSL_SHA512
2679
    static const char sigSha512wEcdsaName[] = "SHA512wECDSA";
2680
#endif
2681
#ifdef WOLFSSL_SHA3
2682
#ifndef WOLFSSL_NOSHA3_224
2683
    static const char sigSha3_224wEcdsaName[] = "SHA3_224wECDSA";
2684
#endif
2685
#ifndef WOLFSSL_NOSHA3_256
2686
    static const char sigSha3_256wEcdsaName[] = "SHA3_256wECDSA";
2687
#endif
2688
#ifndef WOLFSSL_NOSHA3_384
2689
    static const char sigSha3_384wEcdsaName[] = "SHA3_384wECDSA";
2690
#endif
2691
#ifndef WOLFSSL_NOSHA3_512
2692
    static const char sigSha3_512wEcdsaName[] = "SHA3_512wECDSA";
2693
#endif
2694
#endif
2695
#endif /* HAVE_ECC */
2696
static const char sigUnknownName[] = "Unknown";
2697
2698
2699
/* Get the human readable string for a signature type
2700
 *
2701
 * oid  Oid value for signature
2702
 */
2703
0
const char* GetSigName(int oid) {
2704
0
    switch (oid) {
2705
    #if !defined(NO_DSA) && !defined(NO_SHA)
2706
        case CTC_SHAwDSA:
2707
            return sigSha1wDsaName;
2708
        case CTC_SHA256wDSA:
2709
            return sigSha256wDsaName;
2710
    #endif /* NO_DSA && NO_SHA */
2711
0
    #ifndef NO_RSA
2712
0
        #ifdef WOLFSSL_MD2
2713
0
        case CTC_MD2wRSA:
2714
0
            return sigMd2wRsaName;
2715
0
        #endif
2716
0
        #ifndef NO_MD5
2717
0
        case CTC_MD5wRSA:
2718
0
            return sigMd5wRsaName;
2719
0
        #endif
2720
0
        #ifndef NO_SHA
2721
0
        case CTC_SHAwRSA:
2722
0
            return sigSha1wRsaName;
2723
0
        #endif
2724
0
        #ifdef WOLFSSL_SHA224
2725
0
        case CTC_SHA224wRSA:
2726
0
            return sigSha224wRsaName;
2727
0
        #endif
2728
0
        #ifndef NO_SHA256
2729
0
        case CTC_SHA256wRSA:
2730
0
            return sigSha256wRsaName;
2731
0
        #endif
2732
0
        #ifdef WOLFSSL_SHA384
2733
0
        case CTC_SHA384wRSA:
2734
0
            return sigSha384wRsaName;
2735
0
        #endif
2736
0
        #ifdef WOLFSSL_SHA512
2737
0
        case CTC_SHA512wRSA:
2738
0
            return sigSha512wRsaName;
2739
0
        #endif
2740
0
        #ifdef WOLFSSL_SHA3
2741
0
        #ifndef WOLFSSL_NOSHA3_224
2742
0
        case CTC_SHA3_224wRSA:
2743
0
            return sigSha3_224wRsaName;
2744
0
        #endif
2745
0
        #ifndef WOLFSSL_NOSHA3_256
2746
0
        case CTC_SHA3_256wRSA:
2747
0
            return sigSha3_256wRsaName;
2748
0
        #endif
2749
0
        #ifndef WOLFSSL_NOSHA3_384
2750
0
        case CTC_SHA3_384wRSA:
2751
0
            return sigSha3_384wRsaName;
2752
0
        #endif
2753
0
        #ifndef WOLFSSL_NOSHA3_512
2754
0
        case CTC_SHA3_512wRSA:
2755
0
            return sigSha3_512wRsaName;
2756
0
        #endif
2757
0
        #endif
2758
0
        #ifdef WC_RSA_PSS
2759
0
        case CTC_RSASSAPSS:
2760
0
            return sigRsaSsaPssName;
2761
0
        #endif
2762
0
    #endif /* NO_RSA */
2763
0
    #ifdef HAVE_ECC
2764
0
        #ifndef NO_SHA
2765
0
        case CTC_SHAwECDSA:
2766
0
            return sigSha1wEcdsaName;
2767
0
        #endif
2768
0
        #ifdef WOLFSSL_SHA224
2769
0
        case CTC_SHA224wECDSA:
2770
0
            return sigSha224wEcdsaName;
2771
0
        #endif
2772
0
        #ifndef NO_SHA256
2773
0
        case CTC_SHA256wECDSA:
2774
0
            return sigSha256wEcdsaName;
2775
0
        #endif
2776
0
        #ifdef WOLFSSL_SHA384
2777
0
        case CTC_SHA384wECDSA:
2778
0
            return sigSha384wEcdsaName;
2779
0
        #endif
2780
0
        #ifdef WOLFSSL_SHA512
2781
0
        case CTC_SHA512wECDSA:
2782
0
            return sigSha512wEcdsaName;
2783
0
        #endif
2784
0
        #ifdef WOLFSSL_SHA3
2785
0
        #ifndef WOLFSSL_NOSHA3_224
2786
0
        case CTC_SHA3_224wECDSA:
2787
0
            return sigSha3_224wEcdsaName;
2788
0
        #endif
2789
0
        #ifndef WOLFSSL_NOSHA3_256
2790
0
        case CTC_SHA3_256wECDSA:
2791
0
            return sigSha3_256wEcdsaName;
2792
0
        #endif
2793
0
        #ifndef WOLFSSL_NOSHA3_384
2794
0
        case CTC_SHA3_384wECDSA:
2795
0
            return sigSha3_384wEcdsaName;
2796
0
        #endif
2797
0
        #ifndef WOLFSSL_NOSHA3_512
2798
0
        case CTC_SHA3_512wECDSA:
2799
0
            return sigSha3_512wEcdsaName;
2800
0
        #endif
2801
0
        #endif
2802
0
    #endif /* HAVE_ECC */
2803
0
        default:
2804
0
            return sigUnknownName;
2805
0
    }
2806
0
}
2807
2808
2809
#if !defined(WOLFSSL_ASN_TEMPLATE) || defined(HAVE_PKCS7) || \
2810
    defined(OPENSSL_EXTRA)
2811
#if !defined(NO_DSA) || defined(HAVE_ECC) || !defined(NO_CERTS) || \
2812
   (!defined(NO_RSA) && \
2813
        (defined(WOLFSSL_CERT_GEN) || \
2814
        ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(HAVE_USER_RSA))))
2815
/* Set the DER/BER encoding of the ASN.1 INTEGER header.
2816
 *
2817
 * When output is NULL, calculate the header length only.
2818
 *
2819
 * @param [in]  len        Length of INTEGER data in bytes.
2820
 * @param [in]  firstByte  First byte of data, most significant byte of integer,
2821
 *                         to encode.
2822
 * @param [out] output     Buffer to write into.
2823
 * @return  Number of bytes added to the buffer.
2824
 */
2825
int SetASNInt(int len, byte firstByte, byte* output)
2826
5.09k
{
2827
5.09k
    word32 idx = 0;
2828
2829
5.09k
    if (output) {
2830
        /* Write out tag. */
2831
5.09k
        output[idx] = ASN_INTEGER;
2832
5.09k
    }
2833
    /* Step over tag. */
2834
5.09k
    idx += ASN_TAG_SZ;
2835
    /* Check if first byte has top bit set in which case a 0 is needed to
2836
     * maintain positive value. */
2837
5.09k
    if (firstByte & 0x80) {
2838
        /* Add pre-prepended byte to length of data in INTEGER. */
2839
1.84k
        len++;
2840
1.84k
    }
2841
    /* Encode length - passing NULL for output will not encode. */
2842
5.09k
    idx += SetLength(len, output ? output + idx : NULL);
2843
    /* Put out pre-pended 0 as well. */
2844
5.09k
    if (firstByte & 0x80) {
2845
1.84k
        if (output) {
2846
            /* Write out 0 byte. */
2847
1.84k
            output[idx] = 0x00;
2848
1.84k
        }
2849
        /* Update index. */
2850
1.84k
        idx++;
2851
1.84k
    }
2852
2853
    /* Return index after header. */
2854
5.09k
    return idx;
2855
5.09k
}
2856
#endif
2857
#endif
2858
2859
#ifndef WOLFSSL_ASN_TEMPLATE
2860
#if !defined(NO_DSA) || defined(HAVE_ECC) || (defined(WOLFSSL_CERT_GEN) && \
2861
    !defined(NO_RSA)) || ((defined(WOLFSSL_KEY_GEN) || \
2862
    (!defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)) || \
2863
    defined(OPENSSL_EXTRA)) && !defined(NO_RSA) && !defined(HAVE_USER_RSA))
2864
/* Set the DER/BER encoding of the ASN.1 INTEGER element with an mp_int.
2865
 * The number is assumed to be positive.
2866
 *
2867
 * n       Multi-precision integer to encode.
2868
 * maxSz   Maximum size of the encoded integer.
2869
 *         A negative value indicates no check of length requested.
2870
 * output  Buffer to write into.
2871
 * returns BUFFER_E when the data is too long for the buffer.
2872
 *         MP_TO_E when encoding the integer fails.
2873
 *         Otherwise, the number of bytes added to the buffer.
2874
 */
2875
static int SetASNIntMP(mp_int* n, int maxSz, byte* output)
2876
5.09k
{
2877
5.09k
    int idx = 0;
2878
5.09k
    int leadingBit;
2879
5.09k
    int length;
2880
5.09k
    int err;
2881
2882
5.09k
    leadingBit = mp_leading_bit(n);
2883
5.09k
    length = mp_unsigned_bin_size(n);
2884
5.09k
    if (maxSz >= 0 && (1 + length + (leadingBit ? 1 : 0)) > maxSz)
2885
3
        return BUFFER_E;
2886
5.09k
    idx = SetASNInt(length, leadingBit ? 0x80 : 0x00, output);
2887
5.09k
    if (maxSz >= 0 && (idx + length) > maxSz)
2888
1
        return BUFFER_E;
2889
2890
5.09k
    if (output) {
2891
5.09k
        err = mp_to_unsigned_bin(n, output + idx);
2892
5.09k
        if (err != MP_OKAY)
2893
0
            return MP_TO_E;
2894
5.09k
    }
2895
5.09k
    idx += length;
2896
2897
5.09k
    return idx;
2898
5.09k
}
2899
#endif
2900
2901
#if !defined(NO_RSA) && defined(HAVE_USER_RSA) && \
2902
    (defined(WOLFSSL_CERT_GEN) || defined(OPENSSL_EXTRA))
2903
/* Set the DER/BER encoding of the ASN.1 INTEGER element with an mp_int from
2904
 * an RSA key.
2905
 * The number is assumed to be positive.
2906
 *
2907
 * n       Multi-precision integer to encode.
2908
 * output  Buffer to write into.
2909
 * returns BUFFER_E when the data is too long for the buffer.
2910
 *         MP_TO_E when encoding the integer fails.
2911
 *         Otherwise, the number of bytes added to the buffer.
2912
 */
2913
static int SetASNIntRSA(void* n, byte* output)
2914
{
2915
    int idx = 0;
2916
    int leadingBit;
2917
    int length;
2918
    int err;
2919
2920
    leadingBit = wc_Rsa_leading_bit(n);
2921
    length = wc_Rsa_unsigned_bin_size(n);
2922
    idx = SetASNInt(length, leadingBit ? 0x80 : 0x00, output);
2923
    if ((idx + length) > MAX_RSA_INT_SZ)
2924
        return BUFFER_E;
2925
2926
    if (output) {
2927
        err = wc_Rsa_to_unsigned_bin(n, output + idx, length);
2928
        if (err != MP_OKAY)
2929
            return MP_TO_E;
2930
    }
2931
    idx += length;
2932
2933
    return idx;
2934
}
2935
#endif /* !NO_RSA && HAVE_USER_RSA && WOLFSSL_CERT_GEN */
2936
#endif /* !WOLFSSL_ASN_TEMPLATE */
2937
2938
#ifdef WOLFSSL_ASN_TEMPLATE
2939
/* ASN.1 template for an INTEGER. */
2940
static const ASNItem intASN[] = {
2941
/* INT */ { 0, ASN_INTEGER, 0, 0, 0 }
2942
};
2943
enum {
2944
    INTASN_IDX_INT = 0
2945
};
2946
2947
/* Number of items in ASN.1 template for an INTEGER. */
2948
#define intASN_Length (sizeof(intASN) / sizeof(ASNItem))
2949
#endif /* WOLFSSL_ASN_TEMPLATE */
2950
2951
/* Windows header clash for WinCE using GetVersion */
2952
/* Decode Version - one byte INTEGER.
2953
 *
2954
 * @param [in]      input     Buffer of BER data.
2955
 * @param [in, out] inOutIdx  On in, start of encoded Version.
2956
 *                            On out, start of next encode ASN.1 item.
2957
 * @param [out]     version   Number encoded in INTEGER.
2958
 * @param [in]      maxIdx    Maximum index of data in buffer.
2959
 * @return  0 on success.
2960
 * @return  ASN_PARSE_E when encoding is invalid.
2961
 * @return  BUFFER_E when data in buffer is too small.
2962
 * @return  ASN_EXPECT_0_E when the most significant bit is set.
2963
 */
2964
int GetMyVersion(const byte* input, word32* inOutIdx,
2965
                               int* version, word32 maxIdx)
2966
0
{
2967
0
#ifndef WOLFSSL_ASN_TEMPLATE
2968
0
    word32 idx = *inOutIdx;
2969
0
    byte   tag;
2970
2971
0
    if ((idx + MIN_VERSION_SZ) > maxIdx)
2972
0
        return ASN_PARSE_E;
2973
2974
0
    if (GetASNTag(input, &idx, &tag, maxIdx) != 0)
2975
0
        return ASN_PARSE_E;
2976
2977
0
    if (tag != ASN_INTEGER)
2978
0
        return ASN_PARSE_E;
2979
2980
0
    if (input[idx++] != 0x01)
2981
0
        return ASN_VERSION_E;
2982
2983
0
    *version  = input[idx++];
2984
0
    *inOutIdx = idx;
2985
2986
0
    return *version;
2987
#else
2988
    ASNGetData dataASN[intASN_Length];
2989
    int ret;
2990
    byte num;
2991
2992
    /* Clear dynamic data and set the version number variable. */
2993
    XMEMSET(dataASN, 0, sizeof(dataASN));
2994
    GetASN_Int8Bit(&dataASN[INTASN_IDX_INT], &num);
2995
    /* Decode the version (INTEGER). */
2996
    ret = GetASN_Items(intASN, dataASN, intASN_Length, 0, input, inOutIdx,
2997
                       maxIdx);
2998
    if (ret == 0) {
2999
        /* Return version through variable and return value. */
3000
        *version = num;
3001
        ret = num;
3002
    }
3003
    return ret;
3004
#endif /* WOLFSSL_ASN_TEMPLATE */
3005
0
}
3006
3007
3008
#ifndef NO_PWDBASED
3009
/* Decode small integer, 32 bits or less.
3010
 *
3011
 * @param [in]      input     Buffer of BER data.
3012
 * @param [in, out] inOutIdx  On in, start of encoded INTEGER.
3013
 *                            On out, start of next encode ASN.1 item.
3014
 * @param [out]     number    Number encoded in INTEGER.
3015
 * @param [in]      maxIdx    Maximum index of data in buffer.
3016
 * @return  0 on success.
3017
 * @return  ASN_PARSE_E when encoding is invalid.
3018
 * @return  BUFFER_E when data in buffer is too small.
3019
 * @return  ASN_EXPECT_0_E when the most significant bit is set.
3020
 */
3021
int GetShortInt(const byte* input, word32* inOutIdx, int* number, word32 maxIdx)
3022
0
{
3023
0
#ifndef WOLFSSL_ASN_TEMPLATE
3024
0
    word32 idx = *inOutIdx;
3025
0
    word32 len;
3026
0
    byte   tag;
3027
3028
0
    *number = 0;
3029
3030
    /* check for type and length bytes */
3031
0
    if ((idx + 2) > maxIdx)
3032
0
        return BUFFER_E;
3033
3034
0
    if (GetASNTag(input, &idx, &tag, maxIdx) != 0)
3035
0
        return ASN_PARSE_E;
3036
3037
0
    if (tag != ASN_INTEGER)
3038
0
        return ASN_PARSE_E;
3039
3040
0
    len = input[idx++];
3041
0
    if (len > 4)
3042
0
        return ASN_PARSE_E;
3043
3044
0
    if (len + idx > maxIdx)
3045
0
        return ASN_PARSE_E;
3046
3047
0
    while (len--) {
3048
0
        *number  = *number << 8 | input[idx++];
3049
0
    }
3050
3051
0
    *inOutIdx = idx;
3052
3053
0
    return *number;
3054
#else
3055
    ASNGetData dataASN[intASN_Length];
3056
    int ret;
3057
    word32 num;
3058
3059
    /* Clear dynamic data and set the 32-bit number variable. */
3060
    XMEMSET(dataASN, 0, sizeof(dataASN));
3061
    GetASN_Int32Bit(&dataASN[INTASN_IDX_INT], &num);
3062
    /* Decode the short int (INTEGER). */
3063
    ret = GetASN_Items(intASN, dataASN, intASN_Length, 0, input, inOutIdx,
3064
                       maxIdx);
3065
    if (ret == 0) {
3066
        /* Return number through variable and return value. */
3067
        *number = num;
3068
        ret = num;
3069
    }
3070
    return ret;
3071
#endif
3072
0
}
3073
3074
3075
#if !defined(WOLFSSL_ASN_TEMPLATE) || defined(HAVE_PKCS12)
3076
/* Set small integer, 32 bits or less. DER encoding with no leading 0s
3077
 * returns total amount written including ASN tag and length byte on success */
3078
int SetShortInt(byte* input, word32* inOutIdx, word32 number, word32 maxIdx)
3079
0
{
3080
0
    word32 idx = *inOutIdx;
3081
0
    word32 len = 0;
3082
0
    int    i;
3083
0
    byte ar[MAX_LENGTH_SZ];
3084
3085
    /* check for room for type and length bytes */
3086
0
    if ((idx + 2) > maxIdx)
3087
0
        return BUFFER_E;
3088
3089
0
    input[idx++] = ASN_INTEGER;
3090
0
    idx++; /* place holder for length byte */
3091
0
    if (MAX_LENGTH_SZ + idx > maxIdx)
3092
0
        return ASN_PARSE_E;
3093
3094
    /* find first non zero byte */
3095
0
    XMEMSET(ar, 0, MAX_LENGTH_SZ);
3096
0
    c32toa(number, ar);
3097
0
    for (i = 0; i < MAX_LENGTH_SZ; i++) {
3098
0
        if (ar[i] != 0) {
3099
0
            break;
3100
0
        }
3101
0
    }
3102
3103
    /* handle case of 0 */
3104
0
    if (i == MAX_LENGTH_SZ) {
3105
0
        input[idx++] = 0; len++;
3106
0
    }
3107
3108
0
    for (; i < MAX_LENGTH_SZ && idx < maxIdx; i++) {
3109
0
        input[idx++] = ar[i]; len++;
3110
0
    }
3111
3112
    /* jump back to beginning of input buffer using unaltered inOutIdx value
3113
     * and set number of bytes for integer, then update the index value */
3114
0
    input[*inOutIdx + 1] = (byte)len;
3115
0
    *inOutIdx = idx;
3116
3117
0
    return len + 2; /* size of integer bytes plus ASN TAG and length byte */
3118
0
}
3119
#endif /* !WOLFSSL_ASN_TEMPLATE */
3120
#endif /* !NO_PWDBASED */
3121
3122
#ifndef WOLFSSL_ASN_TEMPLATE
3123
/* May not have one, not an error */
3124
static int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version,
3125
                              word32 maxIdx)
3126
0
{
3127
0
    word32 idx = *inOutIdx;
3128
0
    byte tag;
3129
3130
0
    WOLFSSL_ENTER("GetExplicitVersion");
3131
3132
0
    if (GetASNTag(input, &idx, &tag, maxIdx) != 0)
3133
0
        return ASN_PARSE_E;
3134
3135
0
    if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
3136
0
        int ret;
3137
3138
0
        *inOutIdx = ++idx;  /* skip header */
3139
0
        ret = GetMyVersion(input, inOutIdx, version, maxIdx);
3140
0
        if (ret >= 0) {
3141
            /* check if version is expected value rfc 5280 4.1 {0, 1, 2} */
3142
0
            if (*version > MAX_X509_VERSION || *version < MIN_X509_VERSION) {
3143
0
                WOLFSSL_MSG("Unexpected certificate version");
3144
0
                WOLFSSL_ERROR_VERBOSE(ASN_VERSION_E);
3145
0
                ret = ASN_VERSION_E;
3146
0
            }
3147
0
        }
3148
0
        return ret;
3149
0
    }
3150
3151
    /* go back as is */
3152
0
    *version = 0;
3153
3154
0
    return 0;
3155
0
}
3156
#endif
3157
3158
/* Decode small integer, 32 bits or less.
3159
 *
3160
 * mp_int is initialized.
3161
 *
3162
 * @param [out]     mpi       mp_int to hold number.
3163
 * @param [in]      input     Buffer of BER data.
3164
 * @param [in, out] inOutIdx  On in, start of encoded INTEGER.
3165
 *                            On out, start of next encode ASN.1 item.
3166
 * @param [in]      maxIdx    Maximum index of data in buffer.
3167
 * @return  0 on success.
3168
 * @return  ASN_PARSE_E when encoding is invalid.
3169
 * @return  BUFFER_E when data in buffer is too small.
3170
 * @return  ASN_EXPECT_0_E when the most significant bit is set.
3171
 * @return  MP_INIT_E when the unable to initialize an mp_int.
3172
 * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
3173
 */
3174
int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx, word32 maxIdx)
3175
0
{
3176
0
#ifndef WOLFSSL_ASN_TEMPLATE
3177
0
    word32 idx = *inOutIdx;
3178
0
    int    ret;
3179
0
    int    length;
3180
3181
0
    ret = GetASNInt(input, &idx, &length, maxIdx);
3182
0
    if (ret != 0)
3183
0
        return ret;
3184
3185
0
    if (mp_init(mpi) != MP_OKAY)
3186
0
        return MP_INIT_E;
3187
3188
0
    if (mp_read_unsigned_bin(mpi, input + idx, length) != 0) {
3189
0
        mp_clear(mpi);
3190
0
        return ASN_GETINT_E;
3191
0
    }
3192
3193
#ifdef HAVE_WOLF_BIGINT
3194
    if (wc_bigint_from_unsigned_bin(&mpi->raw, input + idx, length) != 0) {
3195
        mp_clear(mpi);
3196
        return ASN_GETINT_E;
3197
    }
3198
#endif /* HAVE_WOLF_BIGINT */
3199
3200
0
    *inOutIdx = idx + length;
3201
3202
0
    return 0;
3203
#else
3204
    ASNGetData dataASN[intASN_Length];
3205
3206
    /* Clear dynamic data and set the mp_int to fill with value. */
3207
    XMEMSET(dataASN, 0, sizeof(dataASN));
3208
    GetASN_MP_PosNeg(&dataASN[INTASN_IDX_INT], mpi);
3209
    /* Decode the big number (INTEGER). */
3210
    return GetASN_Items(intASN, dataASN, intASN_Length, 0, input, inOutIdx,
3211
                        maxIdx);
3212
#endif
3213
0
}
3214
3215
#if (defined(HAVE_ECC) || !defined(NO_DSA)) && !defined(WOLFSSL_ASN_TEMPLATE)
3216
static int GetIntPositive(mp_int* mpi, const byte* input, word32* inOutIdx,
3217
    word32 maxIdx)
3218
7.42k
{
3219
7.42k
    word32 idx = *inOutIdx;
3220
7.42k
    int    ret;
3221
7.42k
    int    length;
3222
3223
7.42k
    ret = GetASNInt(input, &idx, &length, maxIdx);
3224
7.42k
    if (ret != 0)
3225
0
        return ret;
3226
3227
7.42k
    if (((input[idx] & 0x80) == 0x80) && (input[idx - 1] != 0x00))
3228
0
        return MP_INIT_E;
3229
3230
7.42k
    if (mp_init(mpi) != MP_OKAY)
3231
0
        return MP_INIT_E;
3232
3233
7.42k
    if (mp_read_unsigned_bin(mpi, input + idx, length) != 0) {
3234
0
        mp_clear(mpi);
3235
0
        return ASN_GETINT_E;
3236
0
    }
3237
3238
#ifdef HAVE_WOLF_BIGINT
3239
    if (wc_bigint_from_unsigned_bin(&mpi->raw, input + idx, length) != 0) {
3240
        mp_clear(mpi);
3241
        return ASN_GETINT_E;
3242
    }
3243
#endif /* HAVE_WOLF_BIGINT */
3244
3245
7.42k
    *inOutIdx = idx + length;
3246
3247
7.42k
    return 0;
3248
7.42k
}
3249
#endif /* (ECC || !NO_DSA) && !WOLFSSL_ASN_TEMPLATE */
3250
3251
#ifndef WOLFSSL_ASN_TEMPLATE
3252
#if (!defined(WOLFSSL_KEY_GEN) && !defined(OPENSSL_EXTRA) && defined(RSA_LOW_MEM)) \
3253
    || defined(WOLFSSL_RSA_PUBLIC_ONLY) || (!defined(NO_DSA))
3254
#if (!defined(NO_RSA) && !defined(HAVE_USER_RSA)) || !defined(NO_DSA)
3255
static int SkipInt(const byte* input, word32* inOutIdx, word32 maxIdx)
3256
{
3257
    word32 idx = *inOutIdx;
3258
    int    ret;
3259
    int    length;
3260
3261
    ret = GetASNInt(input, &idx, &length, maxIdx);
3262
    if (ret != 0)
3263
        return ret;
3264
3265
    *inOutIdx = idx + length;
3266
3267
    return 0;
3268
}
3269
#endif
3270
#endif
3271
#endif /* !WOLFSSL_ASN_TEMPLATE */
3272
3273
#ifdef WOLFSSL_ASN_TEMPLATE
3274
/* ASN.1 template for a BIT_STRING. */
3275
static const ASNItem bitStringASN[] = {
3276
/* BIT_STR */ { 0, ASN_BIT_STRING, 0, 1, 0 }
3277
};
3278
enum {
3279
    BITSTRINGASN_IDX_BIT_STR = 0
3280
};
3281
3282
/* Number of items in ASN.1 template for a BIT_STRING. */
3283
#define bitStringASN_Length (sizeof(bitStringASN) / sizeof(ASNItem))
3284
#endif
3285
3286
/* Decode and check the BIT_STRING is valid. Return length and unused bits.
3287
 *
3288
 * @param [in]      input       Buffer holding BER encoding.
3289
 * @param [in, out] inOutIdx    On in, start of BIT_STRING.
3290
 *                              On out, start of ASN.1 item after BIT_STRING.
3291
 * @param [out]     len         Length of BIT_STRING data.
3292
 * @param [in]      maxIdx      Maximum index of data in buffer.
3293
 * @param [in]      zeroBits    Indicates whether zero unused bits is expected.
3294
 * @param [in]      unusedBits  Number of unused bits in last byte.
3295
 * @return  0 on success.
3296
 * @return  ASN_PARSE_E when encoding is invalid.
3297
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
3298
 * @return  BUFFER_E when data in buffer is too small.
3299
 * @return  ASN_EXPECT_0_E when unused bits is not zero when expected.
3300
 */
3301
int CheckBitString(const byte* input, word32* inOutIdx, int* len,
3302
                          word32 maxIdx, int zeroBits, byte* unusedBits)
3303
0
{
3304
0
#ifndef WOLFSSL_ASN_TEMPLATE
3305
0
    word32 idx = *inOutIdx;
3306
0
    int    length;
3307
0
    byte   b;
3308
3309
0
    if (GetASNTag(input, &idx, &b, maxIdx) != 0) {
3310
0
        return ASN_BITSTR_E;
3311
0
    }
3312
3313
0
    if (b != ASN_BIT_STRING) {
3314
0
        return ASN_BITSTR_E;
3315
0
    }
3316
3317
0
    if (GetLength(input, &idx, &length, maxIdx) < 0)
3318
0
        return ASN_PARSE_E;
3319
3320
    /* extra sanity check that length is greater than 0 */
3321
0
    if (length <= 0) {
3322
0
        WOLFSSL_MSG("Error length was 0 in CheckBitString");
3323
0
        return BUFFER_E;
3324
0
    }
3325
3326
0
    if (idx + 1 > maxIdx) {
3327
0
        WOLFSSL_MSG("Attempted buffer read larger than input buffer");
3328
0
        return BUFFER_E;
3329
0
    }
3330
3331
0
    b = input[idx];
3332
0
    if (zeroBits && b != 0x00)
3333
0
        return ASN_EXPECT_0_E;
3334
0
    if (b >= 0x08)
3335
0
        return ASN_PARSE_E;
3336
0
    if (b != 0) {
3337
0
        if ((byte)(input[idx + length - 1] << (8 - b)) != 0)
3338
0
            return ASN_PARSE_E;
3339
0
    }
3340
0
    idx++;
3341
0
    length--; /* length has been checked for greater than 0 */
3342
3343
0
    *inOutIdx = idx;
3344
0
    if (len != NULL)
3345
0
        *len = length;
3346
0
    if (unusedBits != NULL)
3347
0
        *unusedBits = b;
3348
3349
0
    return 0;
3350
#else
3351
    ASNGetData dataASN[bitStringASN_Length];
3352
    int ret;
3353
    int bits;
3354
3355
    /* Parse BIT_STRING and check validity of unused bits. */
3356
    XMEMSET(dataASN, 0, sizeof(dataASN));
3357
    /* Decode BIT_STRING. */
3358
    ret = GetASN_Items(bitStringASN, dataASN, bitStringASN_Length, 0, input,
3359
            inOutIdx, maxIdx);
3360
    if (ret == 0) {
3361
        /* Get unused bits from dynamic ASN.1 data. */
3362
        bits = GetASNItem_UnusedBits(dataASN[BITSTRINGASN_IDX_BIT_STR]);
3363
        /* Check unused bits is 0 when expected. */
3364
        if (zeroBits && (bits != 0)) {
3365
            ret = ASN_EXPECT_0_E;
3366
        }
3367
    }
3368
    if (ret == 0) {
3369
        /* Return length of data and unused bits if required. */
3370
        if (len != NULL) {
3371
            *len = dataASN[BITSTRINGASN_IDX_BIT_STR].data.ref.length;
3372
        }
3373
        if (unusedBits != NULL) {
3374
            *unusedBits = bits;
3375
        }
3376
    }
3377
3378
    return ret;
3379
#endif
3380
0
}
3381
3382
/* RSA (with CertGen or KeyGen) OR ECC OR ED25519 OR ED448 (with CertGen or
3383
 * KeyGen) */
3384
#if (!defined(NO_RSA) && !defined(HAVE_USER_RSA) && \
3385
     (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || \
3386
      defined(OPENSSL_EXTRA))) || \
3387
    (defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)) || \
3388
    ((defined(HAVE_ED25519) || defined(HAVE_ED448)) && \
3389
     (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || \
3390
      defined(OPENSSL_EXTRA))) || \
3391
    (defined(WC_ENABLE_ASYM_KEY_EXPORT) && !defined(NO_CERT)) || \
3392
    (!defined(NO_DSA) && !defined(HAVE_SELFTEST) && defined(WOLFSSL_KEY_GEN)) || \
3393
    (!defined(NO_DH) && defined(WOLFSSL_DH_EXTRA))
3394
3395
/* Set the DER/BER encoding of the ASN.1 BIT STRING header.
3396
 *
3397
 * When output is NULL, calculate the header length only.
3398
 *
3399
 * @param [in]  len         Length of BIT STRING data.
3400
 *                          That is, the number of least significant zero bits
3401
 *                          before a one.
3402
 *                          The last byte is the most-significant non-zero byte
3403
 *                          of a number.
3404
 * @param [out] output      Buffer to write into.
3405
 * @return  Number of bytes added to the buffer.
3406
 */
3407
word32 SetBitString(word32 len, byte unusedBits, byte* output)
3408
0
{
3409
0
    word32 idx = 0;
3410
3411
0
    if (output) {
3412
        /* Write out tag. */
3413
0
        output[idx] = ASN_BIT_STRING;
3414
0
    }
3415
    /* Step over tag. */
3416
0
    idx += ASN_TAG_SZ;
3417
3418
    /* Encode length - passing NULL for output will not encode.
3419
     * Add one to length for unused bits. */
3420
0
    idx += SetLength(len + 1, output ? output + idx : NULL);
3421
0
    if (output) {
3422
        /* Write out unused bits. */
3423
0
        output[idx] = unusedBits;
3424
0
    }
3425
    /* Skip over unused bits. */
3426
0
    idx++;
3427
3428
    /* Return index after header. */
3429
0
    return idx;
3430
0
}
3431
#endif /* !NO_RSA || HAVE_ECC || HAVE_ED25519 || HAVE_ED448 */
3432
3433
#ifdef ASN_BER_TO_DER
3434
/* Convert BER to DER */
3435
3436
/* Pull informtation from the ASN.1 BER encoded item header */
3437
static int GetBerHeader(const byte* data, word32* idx, word32 maxIdx,
3438
                        byte* pTag, word32* pLen, int* indef)
3439
{
3440
    int len = 0;
3441
    byte tag;
3442
    word32 i = *idx;
3443
3444
    *indef = 0;
3445
3446
    /* Check there is enough data for a minimal header */
3447
    if (i + 2 > maxIdx) {
3448
        return ASN_PARSE_E;
3449
    }
3450
3451
    /* Retrieve tag */
3452
    tag = data[i++];
3453
3454
    /* Indefinite length handled specially */
3455
    if (data[i] == ASN_INDEF_LENGTH) {
3456
        /* Check valid tag for indefinite */
3457
        if (((tag & 0xc0) == 0) && ((tag & ASN_CONSTRUCTED) == 0x00)) {
3458
            return ASN_PARSE_E;
3459
        }
3460
        i++;
3461
        *indef = 1;
3462
    }
3463
    else if (GetLength(data, &i, &len, maxIdx) < 0) {
3464
        return ASN_PARSE_E;
3465
    }
3466
3467
    /* Return tag, length and index after BER item header */
3468
    *pTag = tag;
3469
    *pLen = len;
3470
    *idx = i;
3471
    return 0;
3472
}
3473
3474
#ifndef INDEF_ITEMS_MAX
3475
#define INDEF_ITEMS_MAX       20
3476
#endif
3477
3478
/* Indef length item data */
3479
typedef struct Indef {
3480
    word32 start;
3481
    int depth;
3482
    int headerLen;
3483
    word32 len;
3484
} Indef;
3485
3486
/* Indef length items */
3487
typedef struct IndefItems
3488
{
3489
    Indef len[INDEF_ITEMS_MAX];
3490
    int cnt;
3491
    int idx;
3492
    int depth;
3493
} IndefItems;
3494
3495
3496
/* Get header length of current item */
3497
static int IndefItems_HeaderLen(IndefItems* items)
3498
{
3499
    return items->len[items->idx].headerLen;
3500
}
3501
3502
/* Get data length of current item */
3503
static word32 IndefItems_Len(IndefItems* items)
3504
{
3505
    return items->len[items->idx].len;
3506
}
3507
3508
/* Add a indefinite length item */
3509
static int IndefItems_AddItem(IndefItems* items, word32 start)
3510
{
3511
    int ret = 0;
3512
    int i;
3513
3514
    if (items->cnt == INDEF_ITEMS_MAX) {
3515
        ret = MEMORY_E;
3516
    }
3517
    else {
3518
        i = items->cnt++;
3519
        items->len[i].start = start;
3520
        items->len[i].depth = items->depth++;
3521
        items->len[i].headerLen = 1;
3522
        items->len[i].len = 0;
3523
        items->idx = i;
3524
    }
3525
3526
    return ret;
3527
}
3528
3529
/* Increase data length of current item */
3530
static void IndefItems_AddData(IndefItems* items, word32 length)
3531
{
3532
    items->len[items->idx].len += length;
3533
}
3534
3535
/* Update header length of current item to reflect data length */
3536
static void IndefItems_UpdateHeaderLen(IndefItems* items)
3537
{
3538
    items->len[items->idx].headerLen +=
3539
                                    SetLength(items->len[items->idx].len, NULL);
3540
}
3541
3542
/* Go to indefinite parent of current item */
3543
static void IndefItems_Up(IndefItems* items)
3544
{
3545
    int i;
3546
    int depth = items->len[items->idx].depth - 1;
3547
3548
    for (i = items->cnt - 1; i >= 0; i--) {
3549
        if (items->len[i].depth == depth) {
3550
            break;
3551
        }
3552
    }
3553
    items->idx = i;
3554
    items->depth = depth + 1;
3555
}
3556
3557
/* Calculate final length by adding length of indefinite child items */
3558
static void IndefItems_CalcLength(IndefItems* items)
3559
{
3560
    int i;
3561
    int idx = items->idx;
3562
3563
    for (i = idx + 1; i < items->cnt; i++) {
3564
        if (items->len[i].depth == items->depth) {
3565
            items->len[idx].len += items->len[i].headerLen;
3566
            items->len[idx].len += items->len[i].len;
3567
        }
3568
    }
3569
    items->len[idx].headerLen += SetLength(items->len[idx].len, NULL);
3570
}
3571
3572
/* Add more data to indefinite length item */
3573
static void IndefItems_MoreData(IndefItems* items, word32 length)
3574
{
3575
    if (items->cnt > 0 && items->idx >= 0) {
3576
        items->len[items->idx].len += length;
3577
    }
3578
}
3579
3580
/* Convert a BER encoding with indefinite length items to DER.
3581
 *
3582
 * ber    BER encoded data.
3583
 * berSz  Length of BER encoded data.
3584
 * der    Buffer to hold DER encoded version of data.
3585
 *        NULL indicates only the length is required.
3586
 * derSz  The size of the buffer to hold the DER encoded data.
3587
 *        Will be set if der is NULL, otherwise the value is checked as der is
3588
 *        filled.
3589
 * returns ASN_PARSE_E if the BER data is invalid and BAD_FUNC_ARG if ber or
3590
 * derSz are NULL.
3591
 */
3592
int wc_BerToDer(const byte* ber, word32 berSz, byte* der, word32* derSz)
3593
{
3594
    int ret = 0;
3595
    word32 i, j;
3596
#ifdef WOLFSSL_SMALL_STACK
3597
    IndefItems* indefItems = NULL;
3598
#else
3599
    IndefItems indefItems[1];
3600
#endif
3601
    byte tag, basic;
3602
    word32 length;
3603
    int indef;
3604
3605
    if (ber == NULL || derSz == NULL)
3606
        return BAD_FUNC_ARG;
3607
3608
#ifdef WOLFSSL_SMALL_STACK
3609
    indefItems = (IndefItems *)XMALLOC(sizeof(IndefItems), NULL,
3610
                                                       DYNAMIC_TYPE_TMP_BUFFER);
3611
    if (indefItems == NULL) {
3612
        ret = MEMORY_E;
3613
        goto end;
3614
    }
3615
#endif
3616
3617
    XMEMSET(indefItems, 0, sizeof(*indefItems));
3618
3619
    /* Calculate indefinite item lengths */
3620
    for (i = 0; i < berSz; ) {
3621
        word32 start = i;
3622
3623
        /* Get next BER item */
3624
        ret = GetBerHeader(ber, &i, berSz, &tag, &length, &indef);
3625
        if (ret != 0) {
3626
            goto end;
3627
        }
3628
3629
        if (indef) {
3630
            /* Indefinite item - add to list */
3631
            ret = IndefItems_AddItem(indefItems, i);
3632
            if (ret != 0) {
3633
                goto end;
3634
            }
3635
3636
            if ((tag & 0xC0) == 0 &&
3637
                tag != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&
3638
                tag != (ASN_SET      | ASN_CONSTRUCTED)) {
3639
                /* Constructed basic type - get repeating tag */
3640
                basic = tag & (~ASN_CONSTRUCTED);
3641
3642
                /* Add up lengths of each item below */
3643
                for (; i < berSz; ) {
3644
                    /* Get next BER_item */
3645
                    ret = GetBerHeader(ber, &i, berSz, &tag, &length, &indef);
3646
                    if (ret != 0) {
3647
                        goto end;
3648
                    }
3649
3650
                    /* End of content closes item */
3651
                    if (tag == ASN_EOC) {
3652
                        /* Must be zero length */
3653
                        if (length != 0) {
3654
                            ret = ASN_PARSE_E;
3655
                            goto end;
3656
                        }
3657
                        break;
3658
                    }
3659
3660
                    /* Must not be indefinite and tag must match parent */
3661
                    if (indef || tag != basic) {
3662
                        ret = ASN_PARSE_E;
3663
                        goto end;
3664
                    }
3665
3666
                    /* Add to length */
3667
                    IndefItems_AddData(indefItems, length);
3668
                    /* Skip data */
3669
                    i += length;
3670
                }
3671
3672
                /* Ensure we got an EOC and not end of data */
3673
                if (tag != ASN_EOC) {
3674
                    ret = ASN_PARSE_E;
3675
                    goto end;
3676
                }
3677
3678
                /* Set the header length to include the length field */
3679
                IndefItems_UpdateHeaderLen(indefItems);
3680
                /* Go to indefinte parent item */
3681
                IndefItems_Up(indefItems);
3682
            }
3683
        }
3684
        else if (tag == ASN_EOC) {
3685
            /* End-of-content must be 0 length */
3686
            if (length != 0) {
3687
                ret = ASN_PARSE_E;
3688
                goto end;
3689
            }
3690
            /* Check there is an item to close - missing EOC */
3691
            if (indefItems->depth == 0) {
3692
                ret = ASN_PARSE_E;
3693
                goto end;
3694
            }
3695
3696
            /* Finish calculation of data length for indefinite item */
3697
            IndefItems_CalcLength(indefItems);
3698
            /* Go to indefinte parent item */
3699
            IndefItems_Up(indefItems);
3700
        }
3701
        else {
3702
            /* Known length item to add in - make sure enough data for it */
3703
            if (i + length > berSz) {
3704
                ret = ASN_PARSE_E;
3705
                goto end;
3706
            }
3707
3708
            /* Include all data - can't have indefinite inside definite */
3709
            i += length;
3710
            /* Add entire item to current indefinite item */
3711
            IndefItems_MoreData(indefItems, i - start);
3712
        }
3713
    }
3714
    /* Check we had a EOC for each indefinite item */
3715
    if (indefItems->depth != 0) {
3716
        ret = ASN_PARSE_E;
3717
        goto end;
3718
    }
3719
3720
    /* Write out DER */
3721
3722
    j = 0;
3723
    /* Reset index */
3724
    indefItems->idx = 0;
3725
    for (i = 0; i < berSz; ) {
3726
        word32 start = i;
3727
3728
        /* Get item - checked above */
3729
        (void)GetBerHeader(ber, &i, berSz, &tag, &length, &indef);
3730
        if (indef) {
3731
            if (der != NULL) {
3732
                /* Check enough space for header */
3733
                if (j + IndefItems_HeaderLen(indefItems) > *derSz) {
3734
                    ret = BUFFER_E;
3735
                    goto end;
3736
                }
3737
3738
                if ((tag & 0xC0) == 0 &&
3739
                    tag != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&
3740
                    tag != (ASN_SET      | ASN_CONSTRUCTED)) {
3741
                    /* Remove constructed tag for basic types */
3742
                    tag &= ~ASN_CONSTRUCTED;
3743
                }
3744
                /* Add tag and length */
3745
                der[j] = tag;
3746
                (void)SetLength(IndefItems_Len(indefItems), der + j + 1);
3747
            }
3748
            /* Add header length of indefinite item */
3749
            j += IndefItems_HeaderLen(indefItems);
3750
3751
            if ((tag & 0xC0) == 0 &&
3752
                tag != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&
3753
                tag != (ASN_SET      | ASN_CONSTRUCTED)) {
3754
                /* For basic type - get each child item and add data */
3755
                for (; i < berSz; ) {
3756
                    (void)GetBerHeader(ber, &i, berSz, &tag, &length, &indef);
3757
                    if (tag == ASN_EOC) {
3758
                        break;
3759
                    }
3760
                    if (der != NULL) {
3761
                        if (j + length > *derSz) {
3762
                            ret = BUFFER_E;
3763
                            goto end;
3764
                        }
3765
                        XMEMCPY(der + j, ber + i, length);
3766
                    }
3767
                    j += length;
3768
                    i += length;
3769
                }
3770
            }
3771
3772
            /* Move to next indef item in list */
3773
            indefItems->idx++;
3774
        }
3775
        else if (tag == ASN_EOC) {
3776
            /* End-Of-Content is not written out in DER */
3777
        }
3778
        else {
3779
            /* Write out definite length item as is. */
3780
            i += length;
3781
            if (der != NULL) {
3782
                /* Ensure space for item */
3783
                if (j + i - start > *derSz) {
3784
                    ret = BUFFER_E;
3785
                    goto end;
3786
                }
3787
                /* Copy item as is */
3788
                XMEMCPY(der + j, ber + start, i - start);
3789
            }
3790
            j += i - start;
3791
        }
3792
    }
3793
3794
    /* Return the length of the DER encoded ASN.1 */
3795
    *derSz = j;
3796
    if (der == NULL) {
3797
        ret = LENGTH_ONLY_E;
3798
    }
3799
end:
3800
#ifdef WOLFSSL_SMALL_STACK
3801
    if (indefItems != NULL) {
3802
        XFREE(indefItems, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3803
    }
3804
#endif
3805
    return ret;
3806
}
3807
#endif
3808
3809
#ifndef WOLFSSL_ASN_TEMPLATE
3810
#if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)
3811
/* Set the DER/BER encoding of the ASN.1 BIT_STRING with a 16-bit value.
3812
 *
3813
 * val         16-bit value to encode.
3814
 * output      Buffer to write into.
3815
 * returns the number of bytes added to the buffer.
3816
 */
3817
static word32 SetBitString16Bit(word16 val, byte* output)
3818
{
3819
    word32 idx;
3820
    int    len;
3821
    byte   lastByte;
3822
    byte   unusedBits = 0;
3823
3824
    if ((val >> 8) != 0) {
3825
        len = 2;
3826
        lastByte = (byte)(val >> 8);
3827
    }
3828
    else {
3829
        len = 1;
3830
        lastByte = (byte)val;
3831
    }
3832
3833
    while (((lastByte >> unusedBits) & 0x01) == 0x00)
3834
        unusedBits++;
3835
3836
    idx = SetBitString(len, unusedBits, output);
3837
    output[idx++] = (byte)val;
3838
    if (len > 1)
3839
        output[idx++] = (byte)(val >> 8);
3840
3841
    return idx;
3842
}
3843
#endif /* WOLFSSL_CERT_EXT || WOLFSSL_CERT_GEN */
3844
#endif /* !WOLFSSL_ASN_TEMPLATE */
3845
3846
/* hashType */
3847
#ifdef WOLFSSL_MD2
3848
    static const byte hashMd2hOid[] = {42, 134, 72, 134, 247, 13, 2, 2};
3849
#endif
3850
#ifndef NO_MD5
3851
    static const byte hashMd5hOid[] = {42, 134, 72, 134, 247, 13, 2, 5};
3852
#endif
3853
#ifndef NO_SHA
3854
    static const byte hashSha1hOid[] = {43, 14, 3, 2, 26};
3855
#endif
3856
#ifdef WOLFSSL_SHA224
3857
    static const byte hashSha224hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 4};
3858
#endif
3859
#ifndef NO_SHA256
3860
    static const byte hashSha256hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 1};
3861
#endif
3862
#ifdef WOLFSSL_SHA384
3863
    static const byte hashSha384hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 2};
3864
#endif
3865
#ifdef WOLFSSL_SHA512
3866
    static const byte hashSha512hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 3};
3867
    #ifndef WOLFSSL_NOSHA512_224
3868
    static const byte hashSha512_224hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 5};
3869
    #endif
3870
    #ifndef WOLFSSL_NOSHA512_256
3871
    static const byte hashSha512_256hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 6};
3872
    #endif
3873
#endif
3874
#ifdef WOLFSSL_SHA3
3875
#ifndef WOLFSSL_NOSHA3_224
3876
    static const byte hashSha3_224hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 7};
3877
#endif /* WOLFSSL_NOSHA3_224 */
3878
#ifndef WOLFSSL_NOSHA3_256
3879
    static const byte hashSha3_256hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 8};
3880
#endif /* WOLFSSL_NOSHA3_256 */
3881
#ifndef WOLFSSL_NOSHA3_384
3882
    static const byte hashSha3_384hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 9};
3883
#endif /* WOLFSSL_NOSHA3_384 */
3884
#ifndef WOLFSSL_NOSHA3_512
3885
    static const byte hashSha3_512hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 10};
3886
#endif /* WOLFSSL_NOSHA3_512 */
3887
#endif /* WOLFSSL_SHA3 */
3888
3889
/* hmacType */
3890
#ifndef NO_HMAC
3891
    #ifdef WOLFSSL_SHA224
3892
    static const byte hmacSha224Oid[] = {42, 134, 72, 134, 247, 13, 2, 8};
3893
    #endif
3894
    #ifndef NO_SHA256
3895
    static const byte hmacSha256Oid[] = {42, 134, 72, 134, 247, 13, 2, 9};
3896
    #endif
3897
    #ifdef WOLFSSL_SHA384
3898
    static const byte hmacSha384Oid[] = {42, 134, 72, 134, 247, 13, 2, 10};
3899
    #endif
3900
    #ifdef WOLFSSL_SHA512
3901
    static const byte hmacSha512Oid[] = {42, 134, 72, 134, 247, 13, 2, 11};
3902
    #endif
3903
#endif
3904
3905
/* sigType */
3906
#if !defined(NO_DSA) && !defined(NO_SHA)
3907
    static const byte sigSha1wDsaOid[] = {42, 134, 72, 206, 56, 4, 3};
3908
    static const byte sigSha256wDsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 2};
3909
#endif /* NO_DSA */
3910
#ifndef NO_RSA
3911
    #ifdef WOLFSSL_MD2
3912
    static const byte sigMd2wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 2};
3913
    #endif
3914
    #ifndef NO_MD5
3915
    static const byte sigMd5wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 4};
3916
    #endif
3917
    #ifndef NO_SHA
3918
    static const byte sigSha1wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 5};
3919
    #endif
3920
    #ifdef WOLFSSL_SHA224
3921
    static const byte sigSha224wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,14};
3922
    #endif
3923
    #ifndef NO_SHA256
3924
    static const byte sigSha256wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,11};
3925
    #endif
3926
    #ifdef WOLFSSL_SHA384
3927
    static const byte sigSha384wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,12};
3928
    #endif
3929
    #ifdef WOLFSSL_SHA512
3930
    static const byte sigSha512wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,13};
3931
    #endif
3932
    #ifdef WOLFSSL_SHA3
3933
    #ifndef WOLFSSL_NOSHA3_224
3934
    static const byte sigSha3_224wRsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 13};
3935
    #endif
3936
    #ifndef WOLFSSL_NOSHA3_256
3937
    static const byte sigSha3_256wRsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 14};
3938
    #endif
3939
    #ifndef WOLFSSL_NOSHA3_384
3940
    static const byte sigSha3_384wRsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 15};
3941
    #endif
3942
    #ifndef WOLFSSL_NOSHA3_512
3943
    static const byte sigSha3_512wRsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 16};
3944
    #endif
3945
    #endif
3946
    #ifdef WC_RSA_PSS
3947
    static const byte sigRsaSsaPssOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 10};
3948
    #endif
3949
#endif /* NO_RSA */
3950
#ifdef HAVE_ECC
3951
    #ifndef NO_SHA
3952
    static const byte sigSha1wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 1};
3953
    #endif
3954
    #ifdef WOLFSSL_SHA224
3955
    static const byte sigSha224wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 1};
3956
    #endif
3957
    #ifndef NO_SHA256
3958
    static const byte sigSha256wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 2};
3959
    #endif
3960
    #ifdef WOLFSSL_SHA384
3961
    static const byte sigSha384wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 3};
3962
    #endif
3963
    #ifdef WOLFSSL_SHA512
3964
    static const byte sigSha512wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 4};
3965
    #endif
3966
    #ifdef WOLFSSL_SHA3
3967
    #ifndef WOLFSSL_NOSHA3_224
3968
    static const byte sigSha3_224wEcdsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 9};
3969
    #endif
3970
    #ifndef WOLFSSL_NOSHA3_256
3971
    static const byte sigSha3_256wEcdsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 10};
3972
    #endif
3973
    #ifndef WOLFSSL_NOSHA3_384
3974
    static const byte sigSha3_384wEcdsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 11};
3975
    #endif
3976
    #ifndef WOLFSSL_NOSHA3_512
3977
    static const byte sigSha3_512wEcdsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 12};
3978
    #endif
3979
    #endif
3980
#endif /* HAVE_ECC */
3981
#ifdef HAVE_ED25519
3982
    static const byte sigEd25519Oid[] = {43, 101, 112};
3983
#endif /* HAVE_ED25519 */
3984
#ifdef HAVE_ED448
3985
    static const byte sigEd448Oid[] = {43, 101, 113};
3986
#endif /* HAVE_ED448 */
3987
#ifdef HAVE_PQC
3988
#ifdef HAVE_FALCON
3989
    /* Falcon Level 1: 1 3 9999 3 1 */
3990
    static const byte sigFalcon_Level1Oid[] = {43, 206, 15, 3, 1};
3991
3992
    /* Falcon Level 5: 1 3 9999 3 4 */
3993
    static const byte sigFalcon_Level5Oid[] = {43, 206, 15, 3, 4};
3994
#endif /* HAVE_FACON */
3995
#ifdef HAVE_DILITHIUM
3996
    /* Dilithium Level 2: 1.3.6.1.4.1.2.267.7.4.4 */
3997
    static const byte sigDilithium_Level2Oid[] =
3998
        {43, 6, 1, 4, 1, 2, 130, 11, 7, 4, 4};
3999
4000
    /* Dilithium Level 3: 1.3.6.1.4.1.2.267.7.6.5 */
4001
    static const byte sigDilithium_Level3Oid[] =
4002
        {43, 6, 1, 4, 1, 2, 130, 11, 7, 6, 5};
4003
4004
    /* Dilithium Level 5: 1.3.6.1.4.1.2.267.7.8.7 */
4005
    static const byte sigDilithium_Level5Oid[] =
4006
        {43, 6, 1, 4, 1, 2, 130, 11, 7, 8, 7};
4007
4008
    /* Dilithium AES Level 2: 1.3.6.1.4.1.2.267.11.4.4 */
4009
    static const byte sigDilithiumAes_Level2Oid[] =
4010
        {43, 6, 1, 4, 1, 2, 130, 11, 11, 4, 4};
4011
4012
    /* Dilithium AES Level 3: 1.3.6.1.4.1.2.267.11.6.5 */
4013
    static const byte sigDilithiumAes_Level3Oid[] =
4014
        {43, 6, 1, 4, 1, 2, 130, 11, 11, 6, 5};
4015
4016
    /* Dilithium AES Level 5: 1.3.6.1.4.1.2.267.11.8.7 */
4017
    static const byte sigDilithiumAes_Level5Oid[] =
4018
        {43, 6, 1, 4, 1, 2, 130, 11, 11, 8, 7};
4019
#endif /* HAVE_DILITHIUM */
4020
#endif /* HAVE_PQC */
4021
4022
/* keyType */
4023
#ifndef NO_DSA
4024
    static const byte keyDsaOid[] = {42, 134, 72, 206, 56, 4, 1};
4025
#endif /* NO_DSA */
4026
#ifndef NO_RSA
4027
    static const byte keyRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 1};
4028
#ifdef WC_RSA_PSS
4029
    static const byte keyRsaPssOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 10};
4030
#endif
4031
#endif /* NO_RSA */
4032
#ifdef HAVE_ECC
4033
    static const byte keyEcdsaOid[] = {42, 134, 72, 206, 61, 2, 1};
4034
#endif /* HAVE_ECC */
4035
#ifdef HAVE_ED25519
4036
    static const byte keyEd25519Oid[] = {43, 101, 112};
4037
#endif /* HAVE_ED25519 */
4038
#ifdef HAVE_CURVE25519
4039
    static const byte keyCurve25519Oid[] = {43, 101, 110};
4040
#endif
4041
#ifdef HAVE_ED448
4042
    static const byte keyEd448Oid[] = {43, 101, 113};
4043
#endif /* HAVE_ED448 */
4044
#ifdef HAVE_CURVE448
4045
    static const byte keyCurve448Oid[] = {43, 101, 111};
4046
#endif /* HAVE_CURVE448 */
4047
#ifndef NO_DH
4048
    static const byte keyDhOid[] = {42, 134, 72, 134, 247, 13, 1, 3, 1};
4049
#endif /* !NO_DH */
4050
#ifdef HAVE_PQC
4051
#ifdef HAVE_FALCON
4052
    /* Falcon Level 1: 1 3 9999 3 1 */
4053
    static const byte keyFalcon_Level1Oid[] = {43, 206, 15, 3, 1};
4054
4055
    /* Falcon Level 5: 1 3 9999 3 4 */
4056
    static const byte keyFalcon_Level5Oid[] = {43, 206, 15, 3, 4};
4057
#endif /* HAVE_FALCON */
4058
#ifdef HAVE_DILITHIUM
4059
    /* Dilithium Level 2: 1.3.6.1.4.1.2.267.7.4.4 */
4060
    static const byte keyDilithium_Level2Oid[] =
4061
        {43, 6, 1, 4, 1, 2, 130, 11, 7, 4, 4};
4062
4063
    /* Dilithium Level 3: 1.3.6.1.4.1.2.267.7.6.5 */
4064
    static const byte keyDilithium_Level3Oid[] =
4065
        {43, 6, 1, 4, 1, 2, 130, 11, 7, 6, 5};
4066
4067
    /* Dilithium Level 5: 1.3.6.1.4.1.2.267.7.8.7 */
4068
    static const byte keyDilithium_Level5Oid[] =
4069
        {43, 6, 1, 4, 1, 2, 130, 11, 7, 8, 7};
4070
4071
    /* Dilithium AES Level 2: 1.3.6.1.4.1.2.267.11.4.4 */
4072
    static const byte keyDilithiumAes_Level2Oid[] =
4073
        {43, 6, 1, 4, 1, 2, 130, 11, 11, 4, 4};
4074
4075
    /* Dilithium AES Level 3: 1.3.6.1.4.1.2.267.11.6.5 */
4076
    static const byte keyDilithiumAes_Level3Oid[] =
4077
        {43, 6, 1, 4, 1, 2, 130, 11, 11, 6, 5};
4078
4079
    /* Dilithium AES Level 5: 1.3.6.1.4.1.2.267.11.8.7 */
4080
    static const byte keyDilithiumAes_Level5Oid[] =
4081
        {43, 6, 1, 4, 1, 2, 130, 11, 11, 8, 7};
4082
#endif /* HAVE_DILITHIUM */
4083
#endif /* HAVE_PQC */
4084
4085
/* curveType */
4086
#ifdef HAVE_ECC
4087
    /* See "ecc_sets" table in ecc.c */
4088
#endif /* HAVE_ECC */
4089
4090
#ifdef HAVE_AES_CBC
4091
/* blkType */
4092
    #ifdef WOLFSSL_AES_128
4093
    static const byte blkAes128CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 2};
4094
    #endif
4095
    #ifdef WOLFSSL_AES_192
4096
    static const byte blkAes192CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 22};
4097
    #endif
4098
    #ifdef WOLFSSL_AES_256
4099
    static const byte blkAes256CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 42};
4100
    #endif
4101
#endif /* HAVE_AES_CBC */
4102
#ifdef HAVE_AESGCM
4103
    #ifdef WOLFSSL_AES_128
4104
    static const byte blkAes128GcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 6};
4105
    #endif
4106
    #ifdef WOLFSSL_AES_192
4107
    static const byte blkAes192GcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 26};
4108
    #endif
4109
    #ifdef WOLFSSL_AES_256
4110
    static const byte blkAes256GcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 46};
4111
    #endif
4112
#endif /* HAVE_AESGCM */
4113
#ifdef HAVE_AESCCM
4114
    #ifdef WOLFSSL_AES_128
4115
    static const byte blkAes128CcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 7};
4116
    #endif
4117
    #ifdef WOLFSSL_AES_192
4118
    static const byte blkAes192CcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 27};
4119
    #endif
4120
    #ifdef WOLFSSL_AES_256
4121
    static const byte blkAes256CcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 47};
4122
    #endif
4123
#endif /* HAVE_AESCCM */
4124
4125
#ifndef NO_DES3
4126
    static const byte blkDesCbcOid[]  = {43, 14, 3, 2, 7};
4127
    static const byte blkDes3CbcOid[] = {42, 134, 72, 134, 247, 13, 3, 7};
4128
#endif
4129
4130
/* keyWrapType */
4131
#ifdef WOLFSSL_AES_128
4132
    static const byte wrapAes128Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 5};
4133
#endif
4134
#ifdef WOLFSSL_AES_192
4135
    static const byte wrapAes192Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 25};
4136
#endif
4137
#ifdef WOLFSSL_AES_256
4138
    static const byte wrapAes256Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 45};
4139
#endif
4140
#ifdef HAVE_PKCS7
4141
/* From RFC 3211 */
4142
static const byte wrapPwriKekOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 16, 3,9};
4143
#endif
4144
4145
/* cmsKeyAgreeType */
4146
#ifndef NO_SHA
4147
    static const byte dhSinglePass_stdDH_sha1kdf_Oid[]   =
4148
                                          {43, 129, 5, 16, 134, 72, 63, 0, 2};
4149
#endif
4150
#ifdef WOLFSSL_SHA224
4151
    static const byte dhSinglePass_stdDH_sha224kdf_Oid[] = {43, 129, 4, 1, 11, 0};
4152
#endif
4153
#ifndef NO_SHA256
4154
    static const byte dhSinglePass_stdDH_sha256kdf_Oid[] = {43, 129, 4, 1, 11, 1};
4155
#endif
4156
#ifdef WOLFSSL_SHA384
4157
    static const byte dhSinglePass_stdDH_sha384kdf_Oid[] = {43, 129, 4, 1, 11, 2};
4158
#endif
4159
#ifdef WOLFSSL_SHA512
4160
    static const byte dhSinglePass_stdDH_sha512kdf_Oid[] = {43, 129, 4, 1, 11, 3};
4161
#endif
4162
4163
/* ocspType */
4164
#ifdef HAVE_OCSP
4165
    static const byte ocspBasicOid[]    = {43, 6, 1, 5, 5, 7, 48, 1, 1};
4166
    static const byte ocspNonceOid[]    = {43, 6, 1, 5, 5, 7, 48, 1, 2};
4167
    static const byte ocspNoCheckOid[]  = {43, 6, 1, 5, 5, 7, 48, 1, 5};
4168
#endif /* HAVE_OCSP */
4169
4170
/* certExtType */
4171
static const byte extBasicCaOid[] = {85, 29, 19};
4172
static const byte extAltNamesOid[] = {85, 29, 17};
4173
static const byte extCrlDistOid[] = {85, 29, 31};
4174
static const byte extAuthInfoOid[] = {43, 6, 1, 5, 5, 7, 1, 1};
4175
static const byte extAuthKeyOid[] = {85, 29, 35};
4176
static const byte extSubjKeyOid[] = {85, 29, 14};
4177
static const byte extCertPolicyOid[] = {85, 29, 32};
4178
static const byte extKeyUsageOid[] = {85, 29, 15};
4179
static const byte extInhibitAnyOid[] = {85, 29, 54};
4180
static const byte extExtKeyUsageOid[] = {85, 29, 37};
4181
#ifndef IGNORE_NAME_CONSTRAINTS
4182
    static const byte extNameConsOid[] = {85, 29, 30};
4183
#endif
4184
#ifdef HAVE_CRL
4185
static const byte extCrlNumberOid[] = {85, 29, 20};
4186
#endif
4187
#ifdef WOLFSSL_SUBJ_DIR_ATTR
4188
    static const byte extSubjDirAttrOid[] = {85, 29, 9};
4189
#endif
4190
#ifdef WOLFSSL_SUBJ_INFO_ACC
4191
    static const byte extSubjInfoAccessOid[] = {43, 6, 1, 5, 5, 7, 1, 11};
4192
#endif
4193
4194
/* certAuthInfoType */
4195
static const byte extAuthInfoOcspOid[] = {43, 6, 1, 5, 5, 7, 48, 1};
4196
static const byte extAuthInfoCaIssuerOid[] = {43, 6, 1, 5, 5, 7, 48, 2};
4197
#ifdef WOLFSSL_SUBJ_INFO_ACC
4198
    static const byte extAuthInfoCaRespOid[] = {43, 6, 1, 5, 5, 7, 48, 5};
4199
#endif /* WOLFSSL_SUBJ_INFO_ACC */
4200
4201
/* certPolicyType */
4202
static const byte extCertPolicyAnyOid[] = {85, 29, 32, 0};
4203
#ifdef WOLFSSL_FPKI
4204
#define CERT_POLICY_TYPE_OID_BASE(num) {96, 134, 72, 1, 101, 3, 2, 1, 3, num}
4205
    static const byte extCertPolicyFpkiCommonAuthOid[] =
4206
            CERT_POLICY_TYPE_OID_BASE(13);
4207
    static const byte extCertPolicyFpkiPivAuthOid[] =
4208
            CERT_POLICY_TYPE_OID_BASE(40);
4209
    static const byte extCertPolicyFpkiPivAuthHwOid[] =
4210
            CERT_POLICY_TYPE_OID_BASE(41);
4211
    static const byte extCertPolicyFpkiPiviAuthOid[] =
4212
            CERT_POLICY_TYPE_OID_BASE(45);
4213
#endif /* WOLFSSL_FPKI */
4214
4215
/* certAltNameType */
4216
static const byte extAltNamesHwNameOid[] = {43, 6, 1, 5, 5, 7, 8, 4};
4217
4218
/* certKeyUseType */
4219
static const byte extExtKeyUsageAnyOid[] = {85, 29, 37, 0};
4220
static const byte extExtKeyUsageServerAuthOid[]   = {43, 6, 1, 5, 5, 7, 3, 1};
4221
static const byte extExtKeyUsageClientAuthOid[]   = {43, 6, 1, 5, 5, 7, 3, 2};
4222
static const byte extExtKeyUsageCodeSigningOid[]  = {43, 6, 1, 5, 5, 7, 3, 3};
4223
static const byte extExtKeyUsageEmailProtectOid[] = {43, 6, 1, 5, 5, 7, 3, 4};
4224
static const byte extExtKeyUsageTimestampOid[]    = {43, 6, 1, 5, 5, 7, 3, 8};
4225
static const byte extExtKeyUsageOcspSignOid[]     = {43, 6, 1, 5, 5, 7, 3, 9};
4226
#ifdef WOLFSSL_WOLFSSH
4227
#define EXT_KEY_USAGE_OID_BASE(num) {43, 6, 1, 5, 5, 7, 3, num}
4228
    static const byte extExtKeyUsageSshClientAuthOid[] =
4229
            EXT_KEY_USAGE_OID_BASE(21);
4230
    static const byte extExtKeyUsageSshMSCLOid[] =
4231
            {43, 6, 1, 4, 1, 130, 55, 20, 2, 2};
4232
    static const byte extExtKeyUsageSshKpClientAuthOid[] =
4233
            {43, 6, 1, 5, 2, 3, 4};
4234
#endif /* WOLFSSL_WOLFSSH */
4235
4236
#ifdef WOLFSSL_SUBJ_DIR_ATTR
4237
#define SUBJ_DIR_ATTR_TYPE_OID_BASE(num) {43, 6, 1, 5, 5, 7, 9, num}
4238
    static const byte extSubjDirAttrDobOid[] = SUBJ_DIR_ATTR_TYPE_OID_BASE(1);
4239
    static const byte extSubjDirAttrPobOid[] = SUBJ_DIR_ATTR_TYPE_OID_BASE(2);
4240
    static const byte extSubjDirAttrGenderOid[] =
4241
            SUBJ_DIR_ATTR_TYPE_OID_BASE(3);
4242
    static const byte extSubjDirAttrCocOid[] = SUBJ_DIR_ATTR_TYPE_OID_BASE(4);
4243
    static const byte extSubjDirAttrCorOid[] = SUBJ_DIR_ATTR_TYPE_OID_BASE(5);
4244
#endif
4245
4246
#if defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_GEN) || \
4247
    defined(WOLFSSL_ASN_TEMPLATE) || defined(OPENSSL_EXTRA) || \
4248
    defined(OPENSSL_EXTRA_X509_SMALL)
4249
/* csrAttrType */
4250
#define CSR_ATTR_TYPE_OID_BASE(num) {42, 134, 72, 134, 247, 13, 1, 9, num}
4251
#if !defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_GEN) || \
4252
    defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
4253
    defined(WOLFSSL_ASN_TEMPLATE)
4254
static const byte attrEmailOid[] =             CSR_ATTR_TYPE_OID_BASE(1);
4255
#endif
4256
#ifdef WOLFSSL_CERT_REQ
4257
static const byte attrUnstructuredNameOid[] =  CSR_ATTR_TYPE_OID_BASE(2);
4258
static const byte attrPkcs9ContentTypeOid[] =  CSR_ATTR_TYPE_OID_BASE(3);
4259
static const byte attrChallengePasswordOid[] = CSR_ATTR_TYPE_OID_BASE(7);
4260
static const byte attrExtensionRequestOid[] =  CSR_ATTR_TYPE_OID_BASE(14);
4261
static const byte attrSerialNumberOid[] = {85, 4, 5};
4262
static const byte attrDnQualifier[] = {85, 4, 46};
4263
static const byte attrInitals[] = {85, 4, 43};
4264
static const byte attrSurname[] = {85, 4, 4};
4265
static const byte attrGivenName[] = {85, 4, 42};
4266
#endif
4267
#endif
4268
4269
/* kdfType */
4270
static const byte pbkdf2Oid[] = {42, 134, 72, 134, 247, 13, 1, 5, 12};
4271
4272
/* PKCS5 */
4273
#if !defined(NO_DES3) && !defined(NO_MD5)
4274
static const byte pbeMd5Des[] = {42, 134, 72, 134, 247, 13, 1, 5, 3};
4275
#endif
4276
#if !defined(NO_DES3) && !defined(NO_SHA)
4277
static const byte pbeSha1Des[] = {42, 134, 72, 134, 247, 13, 1, 5, 10};
4278
#endif
4279
static const byte pbes2[] = {42, 134, 72, 134, 247, 13, 1, 5, 13};
4280
4281
/* PKCS12 */
4282
#if !defined(NO_RC4) && !defined(NO_SHA)
4283
static const byte pbeSha1RC4128[] = {42, 134, 72, 134, 247, 13, 1, 12, 1, 1};
4284
#endif
4285
#if !defined(NO_DES3) && !defined(NO_SHA)
4286
static const byte pbeSha1Des3[] = {42, 134, 72, 134, 247, 13, 1, 12, 1, 3};
4287
#endif
4288
4289
#ifdef HAVE_LIBZ
4290
/* zlib compression */
4291
static const byte zlibCompress[] = {42, 134, 72, 134, 247, 13, 1, 9, 16, 3, 8};
4292
#endif
4293
#ifdef WOLFSSL_APACHE_HTTPD
4294
/* tlsExtType */
4295
static const byte tlsFeatureOid[] = {43, 6, 1, 5, 5, 7, 1, 24};
4296
/* certNameType */
4297
static const byte dnsSRVOid[] = {43, 6, 1, 5, 5, 7, 8, 7};
4298
#endif
4299
4300
#if defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_GEN) || \
4301
    defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
4302
    defined(WOLFSSL_ASN_TEMPLATE)
4303
/* Pilot attribute types (0.9.2342.19200300.100.1.*) */
4304
static const byte uidOid[] = {9, 146, 38, 137, 147, 242, 44, 100, 1, 1}; /* user id */
4305
#endif
4306
4307
#if defined(WOLFSSL_CERT_GEN) || \
4308
    defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
4309
    defined(WOLFSSL_ASN_TEMPLATE)
4310
static const byte dcOid[] = {9, 146, 38, 137, 147, 242, 44, 100, 1, 25}; /* domain component */
4311
#endif
4312
4313
4314
/* Looks up the ID/type of an OID.
4315
 *
4316
 * When known returns the OID as a byte array and its length.
4317
 * ID-type are unique.
4318
 *
4319
 * Use oidIgnoreType to autofail.
4320
 *
4321
 * @param [in]  id     OID id.
4322
 * @param [in]  type   Type of OID (enum Oid_Types).
4323
 * @param [out] oidSz  Length of OID byte array returned.
4324
 * @return  Array of bytes for the OID.
4325
 * @return  NULL when ID/type not recognized.
4326
 */
4327
const byte* OidFromId(word32 id, word32 type, word32* oidSz)
4328
0
{
4329
0
    const byte* oid = NULL;
4330
4331
0
    *oidSz = 0;
4332
4333
0
    switch (type) {
4334
4335
0
        case oidHashType:
4336
0
            switch (id) {
4337
0
            #ifdef WOLFSSL_MD2
4338
0
                case MD2h:
4339
0
                    oid = hashMd2hOid;
4340
0
                    *oidSz = sizeof(hashMd2hOid);
4341
0
                    break;
4342
0
            #endif
4343
0
            #ifndef NO_MD5
4344
0
                case MD5h:
4345
0
                    oid = hashMd5hOid;
4346
0
                    *oidSz = sizeof(hashMd5hOid);
4347
0
                    break;
4348
0
            #endif
4349
0
            #ifndef NO_SHA
4350
0
                case SHAh:
4351
0
                    oid = hashSha1hOid;
4352
0
                    *oidSz = sizeof(hashSha1hOid);
4353
0
                    break;
4354
0
            #endif
4355
0
            #ifdef WOLFSSL_SHA224
4356
0
                case SHA224h:
4357
0
                    oid = hashSha224hOid;
4358
0
                    *oidSz = sizeof(hashSha224hOid);
4359
0
                    break;
4360
0
            #endif
4361
0
            #ifndef NO_SHA256
4362
0
                case SHA256h:
4363
0
                    oid = hashSha256hOid;
4364
0
                    *oidSz = sizeof(hashSha256hOid);
4365
0
                    break;
4366
0
            #endif
4367
0
            #ifdef WOLFSSL_SHA384
4368
0
                case SHA384h:
4369
0
                    oid = hashSha384hOid;
4370
0
                    *oidSz = sizeof(hashSha384hOid);
4371
0
                    break;
4372
0
            #endif
4373
0
            #ifdef WOLFSSL_SHA512
4374
0
                #ifndef WOLFSSL_NOSHA512_224
4375
0
                case SHA512_224h:
4376
0
                    oid = hashSha512_224hOid;
4377
0
                    *oidSz = sizeof(hashSha512_224hOid);
4378
0
                    break;
4379
0
                #endif
4380
0
                #ifndef WOLFSSL_NOSHA512_256
4381
0
                case SHA512_256h:
4382
0
                    oid = hashSha512_256hOid;
4383
0
                    *oidSz = sizeof(hashSha512_256hOid);
4384
0
                    break;
4385
0
                #endif
4386
0
                case SHA512h:
4387
0
                    oid = hashSha512hOid;
4388
0
                    *oidSz = sizeof(hashSha512hOid);
4389
0
                    break;
4390
0
            #endif
4391
0
            #ifdef WOLFSSL_SHA3
4392
0
            #ifndef WOLFSSL_NOSHA3_224
4393
0
                case SHA3_224h:
4394
0
                    oid = hashSha3_224hOid;
4395
0
                    *oidSz = sizeof(hashSha3_224hOid);
4396
0
                    break;
4397
0
            #endif /* WOLFSSL_NOSHA3_224 */
4398
0
            #ifndef WOLFSSL_NOSHA3_256
4399
0
                case SHA3_256h:
4400
0
                    oid = hashSha3_256hOid;
4401
0
                    *oidSz = sizeof(hashSha3_256hOid);
4402
0
                    break;
4403
0
            #endif /* WOLFSSL_NOSHA3_256 */
4404
0
            #ifndef WOLFSSL_NOSHA3_384
4405
0
                case SHA3_384h:
4406
0
                    oid = hashSha3_384hOid;
4407
0
                    *oidSz = sizeof(hashSha3_384hOid);
4408
0
                    break;
4409
0
            #endif /* WOLFSSL_NOSHA3_384 */
4410
0
            #ifndef WOLFSSL_NOSHA3_512
4411
0
                case SHA3_512h:
4412
0
                    oid = hashSha3_512hOid;
4413
0
                    *oidSz = sizeof(hashSha3_512hOid);
4414
0
                    break;
4415
0
            #endif /* WOLFSSL_NOSHA3_512 */
4416
0
            #endif /* WOLFSSL_SHA3 */
4417
0
                default:
4418
0
                    break;
4419
0
            }
4420
0
            break;
4421
4422
0
        case oidSigType:
4423
0
            switch (id) {
4424
                #if !defined(NO_DSA) && !defined(NO_SHA)
4425
                case CTC_SHAwDSA:
4426
                    oid = sigSha1wDsaOid;
4427
                    *oidSz = sizeof(sigSha1wDsaOid);
4428
                    break;
4429
                case CTC_SHA256wDSA:
4430
                    oid = sigSha256wDsaOid;
4431
                    *oidSz = sizeof(sigSha256wDsaOid);
4432
                    break;
4433
                #endif /* NO_DSA */
4434
0
                #ifndef NO_RSA
4435
0
                #ifdef WOLFSSL_MD2
4436
0
                case CTC_MD2wRSA:
4437
0
                    oid = sigMd2wRsaOid;
4438
0
                    *oidSz = sizeof(sigMd2wRsaOid);
4439
0
                    break;
4440
0
                #endif
4441
0
                #ifndef NO_MD5
4442
0
                case CTC_MD5wRSA:
4443
0
                    oid = sigMd5wRsaOid;
4444
0
                    *oidSz = sizeof(sigMd5wRsaOid);
4445
0
                    break;
4446
0
                #endif
4447
0
                #ifndef NO_SHA
4448
0
                case CTC_SHAwRSA:
4449
0
                    oid = sigSha1wRsaOid;
4450
0
                    *oidSz = sizeof(sigSha1wRsaOid);
4451
0
                    break;
4452
0
                #endif
4453
0
                #ifdef WOLFSSL_SHA224
4454
0
                case CTC_SHA224wRSA:
4455
0
                    oid = sigSha224wRsaOid;
4456
0
                    *oidSz = sizeof(sigSha224wRsaOid);
4457
0
                    break;
4458
0
                #endif
4459
0
                #ifndef NO_SHA256
4460
0
                case CTC_SHA256wRSA:
4461
0
                    oid = sigSha256wRsaOid;
4462
0
                    *oidSz = sizeof(sigSha256wRsaOid);
4463
0
                    break;
4464
0
                #endif
4465
0
                #ifdef WOLFSSL_SHA384
4466
0
                case CTC_SHA384wRSA:
4467
0
                    oid = sigSha384wRsaOid;
4468
0
                    *oidSz = sizeof(sigSha384wRsaOid);
4469
0
                    break;
4470
0
                #endif
4471
0
                #ifdef WOLFSSL_SHA512
4472
0
                case CTC_SHA512wRSA:
4473
0
                    oid = sigSha512wRsaOid;
4474
0
                    *oidSz = sizeof(sigSha512wRsaOid);
4475
0
                    break;
4476
0
                #endif /* WOLFSSL_SHA512 */
4477
0
                #ifdef WOLFSSL_SHA3
4478
0
                #ifndef WOLFSSL_NOSHA3_224
4479
0
                case CTC_SHA3_224wRSA:
4480
0
                    oid = sigSha3_224wRsaOid;
4481
0
                    *oidSz = sizeof(sigSha3_224wRsaOid);
4482
0
                    break;
4483
0
                #endif
4484
0
                #ifndef WOLFSSL_NOSHA3_256
4485
0
                case CTC_SHA3_256wRSA:
4486
0
                    oid = sigSha3_256wRsaOid;
4487
0
                    *oidSz = sizeof(sigSha3_256wRsaOid);
4488
0
                    break;
4489
0
                #endif
4490
0
                #ifndef WOLFSSL_NOSHA3_384
4491
0
                case CTC_SHA3_384wRSA:
4492
0
                    oid = sigSha3_384wRsaOid;
4493
0
                    *oidSz = sizeof(sigSha3_384wRsaOid);
4494
0
                    break;
4495
0
                #endif
4496
0
                #ifndef WOLFSSL_NOSHA3_512
4497
0
                case CTC_SHA3_512wRSA:
4498
0
                    oid = sigSha3_512wRsaOid;
4499
0
                    *oidSz = sizeof(sigSha3_512wRsaOid);
4500
0
                    break;
4501
0
                #endif
4502
0
                #endif
4503
0
                #ifdef WC_RSA_PSS
4504
0
                case CTC_RSASSAPSS:
4505
0
                    oid = sigRsaSsaPssOid;
4506
0
                    *oidSz = sizeof(sigRsaSsaPssOid);
4507
0
                    break;
4508
0
                #endif
4509
0
                #endif /* NO_RSA */
4510
0
                #ifdef HAVE_ECC
4511
0
                #ifndef NO_SHA
4512
0
                case CTC_SHAwECDSA:
4513
0
                    oid = sigSha1wEcdsaOid;
4514
0
                    *oidSz = sizeof(sigSha1wEcdsaOid);
4515
0
                    break;
4516
0
                #endif
4517
0
                #ifdef WOLFSSL_SHA224
4518
0
                case CTC_SHA224wECDSA:
4519
0
                    oid = sigSha224wEcdsaOid;
4520
0
                    *oidSz = sizeof(sigSha224wEcdsaOid);
4521
0
                    break;
4522
0
                #endif
4523
0
                #ifndef NO_SHA256
4524
0
                case CTC_SHA256wECDSA:
4525
0
                    oid = sigSha256wEcdsaOid;
4526
0
                    *oidSz = sizeof(sigSha256wEcdsaOid);
4527
0
                    break;
4528
0
                #endif
4529
0
                #ifdef WOLFSSL_SHA384
4530
0
                case CTC_SHA384wECDSA:
4531
0
                    oid = sigSha384wEcdsaOid;
4532
0
                    *oidSz = sizeof(sigSha384wEcdsaOid);
4533
0
                    break;
4534
0
                #endif
4535
0
                #ifdef WOLFSSL_SHA512
4536
0
                case CTC_SHA512wECDSA:
4537
0
                    oid = sigSha512wEcdsaOid;
4538
0
                    *oidSz = sizeof(sigSha512wEcdsaOid);
4539
0
                    break;
4540
0
                #endif
4541
0
                #ifdef WOLFSSL_SHA3
4542
0
                #ifndef WOLFSSL_NOSHA3_224
4543
0
                case CTC_SHA3_224wECDSA:
4544
0
                    oid = sigSha3_224wEcdsaOid;
4545
0
                    *oidSz = sizeof(sigSha3_224wEcdsaOid);
4546
0
                    break;
4547
0
                #endif
4548
0
                #ifndef WOLFSSL_NOSHA3_256
4549
0
                case CTC_SHA3_256wECDSA:
4550
0
                    oid = sigSha3_256wEcdsaOid;
4551
0
                    *oidSz = sizeof(sigSha3_256wEcdsaOid);
4552
0
                    break;
4553
0
                #endif
4554
0
                #ifndef WOLFSSL_NOSHA3_384
4555
0
                case CTC_SHA3_384wECDSA:
4556
0
                    oid = sigSha3_384wEcdsaOid;
4557
0
                    *oidSz = sizeof(sigSha3_384wEcdsaOid);
4558
0
                    break;
4559
0
                #endif
4560
0
                #ifndef WOLFSSL_NOSHA3_512
4561
0
                case CTC_SHA3_512wECDSA:
4562
0
                    oid = sigSha3_512wEcdsaOid;
4563
0
                    *oidSz = sizeof(sigSha3_512wEcdsaOid);
4564
0
                    break;
4565
0
                #endif
4566
0
                #endif
4567
0
                #endif /* HAVE_ECC */
4568
0
                #ifdef HAVE_ED25519
4569
0
                case CTC_ED25519:
4570
0
                    oid = sigEd25519Oid;
4571
0
                    *oidSz = sizeof(sigEd25519Oid);
4572
0
                    break;
4573
0
                #endif
4574
0
                #ifdef HAVE_ED448
4575
0
                case CTC_ED448:
4576
0
                    oid = sigEd448Oid;
4577
0
                    *oidSz = sizeof(sigEd448Oid);
4578
0
                    break;
4579
0
                #endif
4580
                #ifdef HAVE_PQC
4581
                #ifdef HAVE_FALCON
4582
                case CTC_FALCON_LEVEL1:
4583
                    oid = sigFalcon_Level1Oid;
4584
                    *oidSz = sizeof(sigFalcon_Level1Oid);
4585
                    break;
4586
                case CTC_FALCON_LEVEL5:
4587
                    oid = sigFalcon_Level5Oid;
4588
                    *oidSz = sizeof(sigFalcon_Level5Oid);
4589
                    break;
4590
                #endif /* HAVE_FALCON */
4591
                #ifdef HAVE_DILITHIUM
4592
                case CTC_DILITHIUM_LEVEL2:
4593
                    oid = sigDilithium_Level2Oid;
4594
                    *oidSz = sizeof(sigDilithium_Level2Oid);
4595
                    break;
4596
                case CTC_DILITHIUM_LEVEL3:
4597
                    oid = sigDilithium_Level3Oid;
4598
                    *oidSz = sizeof(sigDilithium_Level3Oid);
4599
                    break;
4600
                case CTC_DILITHIUM_LEVEL5:
4601
                    oid = sigDilithium_Level5Oid;
4602
                    *oidSz = sizeof(sigDilithium_Level5Oid);
4603
                    break;
4604
                case CTC_DILITHIUM_AES_LEVEL2:
4605
                    oid = sigDilithiumAes_Level2Oid;
4606
                    *oidSz = sizeof(sigDilithiumAes_Level2Oid);
4607
                    break;
4608
                case CTC_DILITHIUM_AES_LEVEL3:
4609
                    oid = sigDilithiumAes_Level3Oid;
4610
                    *oidSz = sizeof(sigDilithiumAes_Level3Oid);
4611
                    break;
4612
                case CTC_DILITHIUM_AES_LEVEL5:
4613
                    oid = sigDilithiumAes_Level5Oid;
4614
                    *oidSz = sizeof(sigDilithiumAes_Level5Oid);
4615
                    break;
4616
                #endif /* HAVE_DILITHIUM */
4617
                #endif /* HAVE_PQC */
4618
0
                default:
4619
0
                    break;
4620
0
            }
4621
0
            break;
4622
4623
0
        case oidKeyType:
4624
0
            switch (id) {
4625
                #ifndef NO_DSA
4626
                case DSAk:
4627
                    oid = keyDsaOid;
4628
                    *oidSz = sizeof(keyDsaOid);
4629
                    break;
4630
                #endif /* NO_DSA */
4631
0
            #ifndef NO_RSA
4632
0
                case RSAk:
4633
0
                    oid = keyRsaOid;
4634
0
                    *oidSz = sizeof(keyRsaOid);
4635
0
                    break;
4636
0
                #ifdef WC_RSA_PSS
4637
0
                case RSAPSSk:
4638
0
                    oid = keyRsaPssOid;
4639
0
                    *oidSz = sizeof(keyRsaPssOid);
4640
0
                    break;
4641
0
                #endif
4642
0
            #endif /* NO_RSA */
4643
0
                #ifdef HAVE_ECC
4644
0
                case ECDSAk:
4645
0
                    oid = keyEcdsaOid;
4646
0
                    *oidSz = sizeof(keyEcdsaOid);
4647
0
                    break;
4648
0
                #endif /* HAVE_ECC */
4649
0
                #ifdef HAVE_ED25519
4650
0
                case ED25519k:
4651
0
                    oid = keyEd25519Oid;
4652
0
                    *oidSz = sizeof(keyEd25519Oid);
4653
0
                    break;
4654
0
                #endif /* HAVE_ED25519 */
4655
0
                #ifdef HAVE_CURVE25519
4656
0
                case X25519k:
4657
0
                    oid = keyCurve25519Oid;
4658
0
                    *oidSz = sizeof(keyCurve25519Oid);
4659
0
                    break;
4660
0
                #endif /* HAVE_CURVE25519 */
4661
0
                #ifdef HAVE_ED448
4662
0
                case ED448k:
4663
0
                    oid = keyEd448Oid;
4664
0
                    *oidSz = sizeof(keyEd448Oid);
4665
0
                    break;
4666
0
                #endif /* HAVE_ED448 */
4667
0
                #ifdef HAVE_CURVE448
4668
0
                case X448k:
4669
0
                    oid = keyCurve448Oid;
4670
0
                    *oidSz = sizeof(keyCurve448Oid);
4671
0
                    break;
4672
0
                #endif /* HAVE_CURVE448 */
4673
0
                #ifndef NO_DH
4674
0
                case DHk:
4675
0
                    oid = keyDhOid;
4676
0
                    *oidSz = sizeof(keyDhOid);
4677
0
                    break;
4678
0
                #endif /* !NO_DH */
4679
                #ifdef HAVE_PQC
4680
                #ifdef HAVE_FALCON
4681
                case FALCON_LEVEL1k:
4682
                    oid = keyFalcon_Level1Oid;
4683
                    *oidSz = sizeof(keyFalcon_Level1Oid);
4684
                    break;
4685
                case FALCON_LEVEL5k:
4686
                    oid = keyFalcon_Level5Oid;
4687
                    *oidSz = sizeof(keyFalcon_Level5Oid);
4688
                    break;
4689
                #endif /* HAVE_FALCON */
4690
                #ifdef HAVE_DILITHIUM
4691
                case DILITHIUM_LEVEL2k:
4692
                    oid = keyDilithium_Level2Oid;
4693
                    *oidSz = sizeof(keyDilithium_Level2Oid);
4694
                    break;
4695
                case DILITHIUM_LEVEL3k:
4696
                    oid = keyDilithium_Level3Oid;
4697
                    *oidSz = sizeof(keyDilithium_Level3Oid);
4698
                    break;
4699
                case DILITHIUM_LEVEL5k:
4700
                    oid = keyDilithium_Level5Oid;
4701
                    *oidSz = sizeof(keyDilithium_Level5Oid);
4702
                    break;
4703
                case DILITHIUM_AES_LEVEL2k:
4704
                    oid = keyDilithiumAes_Level2Oid;
4705
                    *oidSz = sizeof(keyDilithiumAes_Level2Oid);
4706
                    break;
4707
                case DILITHIUM_AES_LEVEL3k:
4708
                    oid = keyDilithiumAes_Level3Oid;
4709
                    *oidSz = sizeof(keyDilithiumAes_Level3Oid);
4710
                    break;
4711
                case DILITHIUM_AES_LEVEL5k:
4712
                    oid = keyDilithiumAes_Level5Oid;
4713
                    *oidSz = sizeof(keyDilithiumAes_Level5Oid);
4714
                    break;
4715
                #endif /* HAVE_DILITHIUM */
4716
                #endif /* HAVE_PQC */
4717
0
                default:
4718
0
                    break;
4719
0
            }
4720
0
            break;
4721
4722
0
        #ifdef HAVE_ECC
4723
0
        case oidCurveType:
4724
0
            if (wc_ecc_get_oid(id, &oid, oidSz) < 0) {
4725
0
                WOLFSSL_MSG("ECC OID not found");
4726
0
            }
4727
0
            break;
4728
0
        #endif /* HAVE_ECC */
4729
4730
0
        case oidBlkType:
4731
0
            switch (id) {
4732
0
    #ifdef HAVE_AES_CBC
4733
0
        #ifdef WOLFSSL_AES_128
4734
0
                case AES128CBCb:
4735
0
                    oid = blkAes128CbcOid;
4736
0
                    *oidSz = sizeof(blkAes128CbcOid);
4737
0
                    break;
4738
0
        #endif
4739
0
        #ifdef WOLFSSL_AES_192
4740
0
                case AES192CBCb:
4741
0
                    oid = blkAes192CbcOid;
4742
0
                    *oidSz = sizeof(blkAes192CbcOid);
4743
0
                    break;
4744
0
        #endif
4745
0
        #ifdef WOLFSSL_AES_256
4746
0
                case AES256CBCb:
4747
0
                    oid = blkAes256CbcOid;
4748
0
                    *oidSz = sizeof(blkAes256CbcOid);
4749
0
                    break;
4750
0
        #endif
4751
0
    #endif /* HAVE_AES_CBC */
4752
0
    #ifdef HAVE_AESGCM
4753
0
        #ifdef WOLFSSL_AES_128
4754
0
                case AES128GCMb:
4755
0
                    oid = blkAes128GcmOid;
4756
0
                    *oidSz = sizeof(blkAes128GcmOid);
4757
0
                    break;
4758
0
        #endif
4759
0
        #ifdef WOLFSSL_AES_192
4760
0
                case AES192GCMb:
4761
0
                    oid = blkAes192GcmOid;
4762
0
                    *oidSz = sizeof(blkAes192GcmOid);
4763
0
                    break;
4764
0
        #endif
4765
0
        #ifdef WOLFSSL_AES_256
4766
0
                case AES256GCMb:
4767
0
                    oid = blkAes256GcmOid;
4768
0
                    *oidSz = sizeof(blkAes256GcmOid);
4769
0
                    break;
4770
0
        #endif
4771
0
    #endif /* HAVE_AESGCM */
4772
0
    #ifdef HAVE_AESCCM
4773
0
        #ifdef WOLFSSL_AES_128
4774
0
                case AES128CCMb:
4775
0
                    oid = blkAes128CcmOid;
4776
0
                    *oidSz = sizeof(blkAes128CcmOid);
4777
0
                    break;
4778
0
        #endif
4779
0
        #ifdef WOLFSSL_AES_192
4780
0
                case AES192CCMb:
4781
0
                    oid = blkAes192CcmOid;
4782
0
                    *oidSz = sizeof(blkAes192CcmOid);
4783
0
                    break;
4784
0
        #endif
4785
0
        #ifdef WOLFSSL_AES_256
4786
0
                case AES256CCMb:
4787
0
                    oid = blkAes256CcmOid;
4788
0
                    *oidSz = sizeof(blkAes256CcmOid);
4789
0
                    break;
4790
0
        #endif
4791
0
    #endif /* HAVE_AESCCM */
4792
0
    #ifndef NO_DES3
4793
0
                case DESb:
4794
0
                    oid = blkDesCbcOid;
4795
0
                    *oidSz = sizeof(blkDesCbcOid);
4796
0
                    break;
4797
0
                case DES3b:
4798
0
                    oid = blkDes3CbcOid;
4799
0
                    *oidSz = sizeof(blkDes3CbcOid);
4800
0
                    break;
4801
0
    #endif /* !NO_DES3 */
4802
0
                default:
4803
0
                    break;
4804
0
            }
4805
0
            break;
4806
4807
        #ifdef HAVE_OCSP
4808
        case oidOcspType:
4809
            switch (id) {
4810
                case OCSP_BASIC_OID:
4811
                    oid = ocspBasicOid;
4812
                    *oidSz = sizeof(ocspBasicOid);
4813
                    break;
4814
                case OCSP_NONCE_OID:
4815
                    oid = ocspNonceOid;
4816
                    *oidSz = sizeof(ocspNonceOid);
4817
                    break;
4818
                default:
4819
                    break;
4820
            }
4821
            break;
4822
        #endif /* HAVE_OCSP */
4823
4824
0
        case oidCertExtType:
4825
0
            switch (id) {
4826
0
                case BASIC_CA_OID:
4827
0
                    oid = extBasicCaOid;
4828
0
                    *oidSz = sizeof(extBasicCaOid);
4829
0
                    break;
4830
0
                case ALT_NAMES_OID:
4831
0
                    oid = extAltNamesOid;
4832
0
                    *oidSz = sizeof(extAltNamesOid);
4833
0
                    break;
4834
0
                case CRL_DIST_OID:
4835
0
                    oid = extCrlDistOid;
4836
0
                    *oidSz = sizeof(extCrlDistOid);
4837
0
                    break;
4838
0
                case AUTH_INFO_OID:
4839
0
                    oid = extAuthInfoOid;
4840
0
                    *oidSz = sizeof(extAuthInfoOid);
4841
0
                    break;
4842
0
                case AUTH_KEY_OID:
4843
0
                    oid = extAuthKeyOid;
4844
0
                    *oidSz = sizeof(extAuthKeyOid);
4845
0
                    break;
4846
0
                case SUBJ_KEY_OID:
4847
0
                    oid = extSubjKeyOid;
4848
0
                    *oidSz = sizeof(extSubjKeyOid);
4849
0
                    break;
4850
0
                case CERT_POLICY_OID:
4851
0
                    oid = extCertPolicyOid;
4852
0
                    *oidSz = sizeof(extCertPolicyOid);
4853
0
                    break;
4854
0
                case KEY_USAGE_OID:
4855
0
                    oid = extKeyUsageOid;
4856
0
                    *oidSz = sizeof(extKeyUsageOid);
4857
0
                    break;
4858
0
                case INHIBIT_ANY_OID:
4859
0
                    oid = extInhibitAnyOid;
4860
0
                    *oidSz = sizeof(extInhibitAnyOid);
4861
0
                    break;
4862
0
                case EXT_KEY_USAGE_OID:
4863
0
                    oid = extExtKeyUsageOid;
4864
0
                    *oidSz = sizeof(extExtKeyUsageOid);
4865
0
                    break;
4866
0
            #ifndef IGNORE_NAME_CONSTRAINTS
4867
0
                case NAME_CONS_OID:
4868
0
                    oid = extNameConsOid;
4869
0
                    *oidSz = sizeof(extNameConsOid);
4870
0
                    break;
4871
0
            #endif
4872
            #ifdef HAVE_OCSP
4873
                case OCSP_NOCHECK_OID:
4874
                    oid = ocspNoCheckOid;
4875
                    *oidSz = sizeof(ocspNoCheckOid);
4876
                    break;
4877
            #endif
4878
            #ifdef WOLFSSL_SUBJ_DIR_ATTR
4879
                case SUBJ_DIR_ATTR_OID:
4880
                    oid = extSubjDirAttrOid;
4881
                    *oidSz = sizeof(extSubjDirAttrOid);
4882
                    break;
4883
            #endif
4884
            #ifdef WOLFSSL_SUBJ_INFO_ACC
4885
                case SUBJ_INFO_ACC_OID:
4886
                    oid = extSubjInfoAccessOid;
4887
                    *oidSz = sizeof(extSubjInfoAccessOid);
4888
                    break;
4889
            #endif
4890
0
                default:
4891
0
                    break;
4892
0
            }
4893
0
            break;
4894
4895
0
        case oidCrlExtType:
4896
            #ifdef HAVE_CRL
4897
            switch (id) {
4898
                case AUTH_KEY_OID:
4899
                    oid = extAuthKeyOid;
4900
                    *oidSz = sizeof(extAuthKeyOid);
4901
                    break;
4902
                case CRL_NUMBER_OID:
4903
                    oid = extCrlNumberOid;
4904
                    *oidSz = sizeof(extCrlNumberOid);
4905
                    break;
4906
                default:
4907
                    break;
4908
            }
4909
            #endif
4910
0
            break;
4911
4912
0
        case oidCertAuthInfoType:
4913
0
            switch (id) {
4914
0
                case AIA_OCSP_OID:
4915
0
                    oid = extAuthInfoOcspOid;
4916
0
                    *oidSz = sizeof(extAuthInfoOcspOid);
4917
0
                    break;
4918
0
                case AIA_CA_ISSUER_OID:
4919
0
                    oid = extAuthInfoCaIssuerOid;
4920
0
                    *oidSz = sizeof(extAuthInfoCaIssuerOid);
4921
0
                    break;
4922
                #ifdef WOLFSSL_SUBJ_INFO_ACC
4923
                case AIA_CA_REPO_OID:
4924
                    oid = extAuthInfoCaRespOid;
4925
                    *oidSz = sizeof(extAuthInfoCaRespOid);
4926
                    break;
4927
                #endif /* WOLFSSL_SUBJ_INFO_ACC */
4928
0
                default:
4929
0
                    break;
4930
0
            }
4931
0
            break;
4932
4933
0
        case oidCertPolicyType:
4934
0
            switch (id) {
4935
0
                case CP_ANY_OID:
4936
0
                    oid = extCertPolicyAnyOid;
4937
0
                    *oidSz = sizeof(extCertPolicyAnyOid);
4938
0
                    break;
4939
                #if defined(WOLFSSL_FPKI)
4940
                case CP_FPKI_COMMON_AUTH_OID:
4941
                    oid = extCertPolicyFpkiCommonAuthOid;
4942
                    *oidSz = sizeof(extCertPolicyFpkiCommonAuthOid);
4943
                    break;
4944
                case CP_FPKI_PIV_AUTH_OID:
4945
                    oid = extCertPolicyFpkiPivAuthOid;
4946
                    *oidSz = sizeof(extCertPolicyFpkiPivAuthOid);
4947
                    break;
4948
                case CP_FPKI_PIV_AUTH_HW_OID: /* collision with AES256CBCb */
4949
                    oid = extCertPolicyFpkiPivAuthHwOid;
4950
                    *oidSz = sizeof(extCertPolicyFpkiPivAuthHwOid);
4951
                    break;
4952
                case CP_FPKI_PIVI_AUTH_OID:
4953
                    oid = extCertPolicyFpkiPiviAuthOid;
4954
                    *oidSz = sizeof(extCertPolicyFpkiPiviAuthOid);
4955
                    break;
4956
                #endif /* WOLFSSL_FPKI */
4957
0
                default:
4958
0
                    break;
4959
0
            }
4960
0
            break;
4961
4962
0
        case oidCertAltNameType:
4963
0
            switch (id) {
4964
0
                case HW_NAME_OID:
4965
0
                    oid = extAltNamesHwNameOid;
4966
0
                    *oidSz = sizeof(extAltNamesHwNameOid);
4967
0
                    break;
4968
0
                default:
4969
0
                    break;
4970
0
            }
4971
0
            break;
4972
4973
0
        case oidCertKeyUseType:
4974
0
            switch (id) {
4975
0
                case EKU_ANY_OID:
4976
0
                    oid = extExtKeyUsageAnyOid;
4977
0
                    *oidSz = sizeof(extExtKeyUsageAnyOid);
4978
0
                    break;
4979
0
                case EKU_SERVER_AUTH_OID:
4980
0
                    oid = extExtKeyUsageServerAuthOid;
4981
0
                    *oidSz = sizeof(extExtKeyUsageServerAuthOid);
4982
0
                    break;
4983
0
                case EKU_CLIENT_AUTH_OID:
4984
0
                    oid = extExtKeyUsageClientAuthOid;
4985
0
                    *oidSz = sizeof(extExtKeyUsageClientAuthOid);
4986
0
                    break;
4987
0
                case EKU_CODESIGNING_OID:
4988
0
                    oid = extExtKeyUsageCodeSigningOid;
4989
0
                    *oidSz = sizeof(extExtKeyUsageCodeSigningOid);
4990
0
                    break;
4991
0
                case EKU_EMAILPROTECT_OID:
4992
0
                    oid = extExtKeyUsageEmailProtectOid;
4993
0
                    *oidSz = sizeof(extExtKeyUsageEmailProtectOid);
4994
0
                    break;
4995
0
                case EKU_TIMESTAMP_OID:
4996
0
                    oid = extExtKeyUsageTimestampOid;
4997
0
                    *oidSz = sizeof(extExtKeyUsageTimestampOid);
4998
0
                    break;
4999
0
                case EKU_OCSP_SIGN_OID:
5000
0
                    oid = extExtKeyUsageOcspSignOid;
5001
0
                    *oidSz = sizeof(extExtKeyUsageOcspSignOid);
5002
0
                    break;
5003
                #ifdef WOLFSSL_WOLFSSH
5004
                case EKU_SSH_CLIENT_AUTH_OID:
5005
                    oid = extExtKeyUsageSshClientAuthOid;
5006
                    *oidSz = sizeof(extExtKeyUsageSshClientAuthOid);
5007
                    break;
5008
                case EKU_SSH_MSCL_OID:
5009
                    oid = extExtKeyUsageSshMSCLOid;
5010
                    *oidSz = sizeof(extExtKeyUsageSshMSCLOid);
5011
                    break;
5012
                case EKU_SSH_KP_CLIENT_AUTH_OID:
5013
                    oid = extExtKeyUsageSshKpClientAuthOid;
5014
                    *oidSz = sizeof(extExtKeyUsageSshKpClientAuthOid);
5015
                    break;
5016
                #endif /* WOLFSSL_WOLFSSH */
5017
0
                default:
5018
0
                    break;
5019
0
            }
5020
0
            break;
5021
5022
0
        case oidKdfType:
5023
0
            switch (id) {
5024
0
                case PBKDF2_OID:
5025
0
                    oid = pbkdf2Oid;
5026
0
                    *oidSz = sizeof(pbkdf2Oid);
5027
0
                    break;
5028
0
                default:
5029
0
                    break;
5030
0
            }
5031
0
            break;
5032
5033
0
        case oidPBEType:
5034
0
            switch (id) {
5035
0
        #if !defined(NO_SHA) && !defined(NO_RC4)
5036
0
                case PBE_SHA1_RC4_128_SUM:
5037
0
                case PBE_SHA1_RC4_128:
5038
0
                    oid = pbeSha1RC4128;
5039
0
                    *oidSz = sizeof(pbeSha1RC4128);
5040
0
                    break;
5041
0
        #endif
5042
0
        #if !defined(NO_MD5) && !defined(NO_DES3)
5043
0
                case PBE_MD5_DES_SUM:
5044
0
                case PBE_MD5_DES:
5045
0
                    oid = pbeMd5Des;
5046
0
                    *oidSz = sizeof(pbeMd5Des);
5047
0
                    break;
5048
5049
0
        #endif
5050
0
        #if !defined(NO_SHA) && !defined(NO_DES3)
5051
0
                case PBE_SHA1_DES_SUM:
5052
0
                case PBE_SHA1_DES:
5053
0
                    oid = pbeSha1Des;
5054
0
                    *oidSz = sizeof(pbeSha1Des);
5055
0
                    break;
5056
5057
0
        #endif
5058
0
        #if !defined(NO_SHA) && !defined(NO_DES3)
5059
0
                case PBE_SHA1_DES3_SUM:
5060
0
                case PBE_SHA1_DES3:
5061
0
                    oid = pbeSha1Des3;
5062
0
                    *oidSz = sizeof(pbeSha1Des3);
5063
0
                    break;
5064
0
        #endif
5065
0
                case PBES2_SUM:
5066
0
                case PBES2:
5067
0
                    oid = pbes2;
5068
0
                    *oidSz = sizeof(pbes2);
5069
0
                    break;
5070
0
                default:
5071
0
                    break;
5072
0
            }
5073
0
            break;
5074
5075
0
        case oidKeyWrapType:
5076
0
            switch (id) {
5077
0
            #ifdef WOLFSSL_AES_128
5078
0
                case AES128_WRAP:
5079
0
                    oid = wrapAes128Oid;
5080
0
                    *oidSz = sizeof(wrapAes128Oid);
5081
0
                    break;
5082
0
            #endif
5083
0
            #ifdef WOLFSSL_AES_192
5084
0
                case AES192_WRAP:
5085
0
                    oid = wrapAes192Oid;
5086
0
                    *oidSz = sizeof(wrapAes192Oid);
5087
0
                    break;
5088
0
            #endif
5089
0
            #ifdef WOLFSSL_AES_256
5090
0
                case AES256_WRAP:
5091
0
                    oid = wrapAes256Oid;
5092
0
                    *oidSz = sizeof(wrapAes256Oid);
5093
0
                    break;
5094
0
            #endif
5095
            #ifdef HAVE_PKCS7
5096
                case PWRI_KEK_WRAP:
5097
                    oid = wrapPwriKekOid;
5098
                    *oidSz = sizeof(wrapPwriKekOid);
5099
                    break;
5100
            #endif
5101
0
                default:
5102
0
                    break;
5103
0
            }
5104
0
            break;
5105
5106
0
        case oidCmsKeyAgreeType:
5107
0
            switch (id) {
5108
0
            #ifndef NO_SHA
5109
0
                case dhSinglePass_stdDH_sha1kdf_scheme:
5110
0
                    oid = dhSinglePass_stdDH_sha1kdf_Oid;
5111
0
                    *oidSz = sizeof(dhSinglePass_stdDH_sha1kdf_Oid);
5112
0
                    break;
5113
0
            #endif
5114
0
            #ifdef WOLFSSL_SHA224
5115
0
                case dhSinglePass_stdDH_sha224kdf_scheme:
5116
0
                    oid = dhSinglePass_stdDH_sha224kdf_Oid;
5117
0
                    *oidSz = sizeof(dhSinglePass_stdDH_sha224kdf_Oid);
5118
0
                    break;
5119
0
            #endif
5120
0
            #ifndef NO_SHA256
5121
0
                case dhSinglePass_stdDH_sha256kdf_scheme:
5122
0
                    oid = dhSinglePass_stdDH_sha256kdf_Oid;
5123
0
                    *oidSz = sizeof(dhSinglePass_stdDH_sha256kdf_Oid);
5124
0
                    break;
5125
0
            #endif
5126
0
            #ifdef WOLFSSL_SHA384
5127
0
                case dhSinglePass_stdDH_sha384kdf_scheme:
5128
0
                    oid = dhSinglePass_stdDH_sha384kdf_Oid;
5129
0
                    *oidSz = sizeof(dhSinglePass_stdDH_sha384kdf_Oid);
5130
0
                    break;
5131
0
            #endif
5132
0
            #ifdef WOLFSSL_SHA512
5133
0
                case dhSinglePass_stdDH_sha512kdf_scheme:
5134
0
                    oid = dhSinglePass_stdDH_sha512kdf_Oid;
5135
0
                    *oidSz = sizeof(dhSinglePass_stdDH_sha512kdf_Oid);
5136
0
                    break;
5137
0
            #endif
5138
0
                default:
5139
0
                    break;
5140
0
            }
5141
0
            break;
5142
5143
0
#ifndef NO_HMAC
5144
0
        case oidHmacType:
5145
0
            switch (id) {
5146
0
        #ifdef WOLFSSL_SHA224
5147
0
                case HMAC_SHA224_OID:
5148
0
                    oid = hmacSha224Oid;
5149
0
                    *oidSz = sizeof(hmacSha224Oid);
5150
0
                    break;
5151
0
        #endif
5152
0
        #ifndef NO_SHA256
5153
0
                case HMAC_SHA256_OID:
5154
0
                    oid = hmacSha256Oid;
5155
0
                    *oidSz = sizeof(hmacSha256Oid);
5156
0
                    break;
5157
0
        #endif
5158
0
        #ifdef WOLFSSL_SHA384
5159
0
                case HMAC_SHA384_OID:
5160
0
                    oid = hmacSha384Oid;
5161
0
                    *oidSz = sizeof(hmacSha384Oid);
5162
0
                    break;
5163
0
        #endif
5164
0
        #ifdef WOLFSSL_SHA512
5165
0
                case HMAC_SHA512_OID:
5166
0
                    oid = hmacSha512Oid;
5167
0
                    *oidSz = sizeof(hmacSha512Oid);
5168
0
                    break;
5169
0
        #endif
5170
0
                default:
5171
0
                    break;
5172
0
            }
5173
0
            break;
5174
0
#endif /* !NO_HMAC */
5175
5176
#ifdef HAVE_LIBZ
5177
        case oidCompressType:
5178
            switch (id) {
5179
                case ZLIBc:
5180
                    oid = zlibCompress;
5181
                    *oidSz = sizeof(zlibCompress);
5182
                    break;
5183
                default:
5184
                    break;
5185
            }
5186
            break;
5187
#endif /* HAVE_LIBZ */
5188
#ifdef WOLFSSL_APACHE_HTTPD
5189
        case oidCertNameType:
5190
            switch (id) {
5191
                 case NID_id_on_dnsSRV:
5192
                    oid = dnsSRVOid;
5193
                    *oidSz = sizeof(dnsSRVOid);
5194
                    break;
5195
                default:
5196
                    break;
5197
            }
5198
            break;
5199
        case oidTlsExtType:
5200
            switch (id) {
5201
                case TLS_FEATURE_OID:
5202
                    oid = tlsFeatureOid;
5203
                    *oidSz = sizeof(tlsFeatureOid);
5204
                    break;
5205
                default:
5206
                    break;
5207
            }
5208
            break;
5209
#endif /* WOLFSSL_APACHE_HTTPD */
5210
#ifdef WOLFSSL_CERT_REQ
5211
        case oidCsrAttrType:
5212
            switch (id) {
5213
                case GIVEN_NAME_OID:
5214
                    oid = attrGivenName;
5215
                    *oidSz = sizeof(attrGivenName);
5216
                    break;
5217
                case SURNAME_OID:
5218
                    oid = attrSurname;
5219
                    *oidSz = sizeof(attrSurname);
5220
                    break;
5221
                case INITIALS_OID:
5222
                    oid = attrInitals;
5223
                    *oidSz = sizeof(attrInitals);
5224
                    break;
5225
                case DNQUALIFIER_OID:
5226
                    oid = attrDnQualifier;
5227
                    *oidSz = sizeof(attrDnQualifier);
5228
                    break;
5229
                case UNSTRUCTURED_NAME_OID:
5230
                    oid = attrUnstructuredNameOid;
5231
                    *oidSz = sizeof(attrUnstructuredNameOid);
5232
                    break;
5233
                case PKCS9_CONTENT_TYPE_OID:
5234
                    oid = attrPkcs9ContentTypeOid;
5235
                    *oidSz = sizeof(attrPkcs9ContentTypeOid);
5236
                    break;
5237
                case CHALLENGE_PASSWORD_OID:
5238
                    oid = attrChallengePasswordOid;
5239
                    *oidSz = sizeof(attrChallengePasswordOid);
5240
                    break;
5241
                case SERIAL_NUMBER_OID:
5242
                    oid = attrSerialNumberOid;
5243
                    *oidSz = sizeof(attrSerialNumberOid);
5244
                    break;
5245
                case USER_ID_OID:
5246
                    oid = uidOid;
5247
                    *oidSz = sizeof(uidOid);
5248
                    break;
5249
                case EXTENSION_REQUEST_OID:
5250
                    oid = attrExtensionRequestOid;
5251
                    *oidSz = sizeof(attrExtensionRequestOid);
5252
                    break;
5253
                default:
5254
                    break;
5255
            }
5256
            break;
5257
#endif
5258
#ifdef WOLFSSL_SUBJ_DIR_ATTR
5259
        case oidSubjDirAttrType:
5260
            switch (id) {
5261
                case SDA_DOB_OID:
5262
                    oid = extSubjDirAttrDobOid;
5263
                    *oidSz = sizeof(extSubjDirAttrDobOid);
5264
                    break;
5265
                case SDA_POB_OID:
5266
                    oid = extSubjDirAttrPobOid;
5267
                    *oidSz = sizeof(extSubjDirAttrPobOid);
5268
                    break;
5269
                case SDA_GENDER_OID:
5270
                    oid = extSubjDirAttrGenderOid;
5271
                    *oidSz = sizeof(extSubjDirAttrGenderOid);
5272
                    break;
5273
                case SDA_COC_OID:
5274
                    oid = extSubjDirAttrCocOid;
5275
                    *oidSz = sizeof(extSubjDirAttrCocOid);
5276
                    break;
5277
                case SDA_COR_OID:
5278
                    oid = extSubjDirAttrCorOid;
5279
                    *oidSz = sizeof(extSubjDirAttrCorOid);
5280
                    break;
5281
                default:
5282
                    break;
5283
            }
5284
            break;
5285
#endif /* WOLFSSL_SUBJ_DIR_ATTR */
5286
0
        case oidIgnoreType:
5287
0
        default:
5288
0
            break;
5289
0
    }
5290
5291
0
    return oid;
5292
0
}
5293
5294
#ifdef HAVE_ECC
5295
5296
/* Check the OID id is for a known elliptic curve.
5297
 *
5298
 * @param [in]  oid  OID id.
5299
 * @return  ECC set id on success.
5300
 * @return  ECC_CURVE_OID_E when OID id is 0 or not supported.
5301
 */
5302
static int CheckCurve(word32 oid)
5303
0
{
5304
0
    int ret;
5305
0
    word32 oidSz;
5306
5307
    /* Lookup OID id. */
5308
0
    ret = wc_ecc_get_oid(oid, NULL, &oidSz);
5309
    /* Check for error or zero length OID size (can't get OID for encoding). */
5310
0
    if ((ret < 0) || (oidSz == 0)) {
5311
0
        WOLFSSL_MSG("CheckCurve not found");
5312
0
        WOLFSSL_ERROR_VERBOSE(ECC_CURVE_OID_E);
5313
0
        ret = ECC_CURVE_OID_E;
5314
0
    }
5315
5316
    /* Return ECC set id or error code. */
5317
0
    return ret;
5318
0
}
5319
5320
#endif
5321
5322
#ifdef HAVE_OID_ENCODING
5323
/* Encode dotted form of OID into byte array version.
5324
 *
5325
 * @param [in]      in     Dotted form of OID.
5326
 * @param [in]      inSz   Count of numbers in dotted form.
5327
 * @param [in]      out    Buffer to hold OID.
5328
 * @param [in, out] outSz  On in, size of buffer.
5329
 *                         On out, number of bytes in buffer.
5330
 * @return  0 on success
5331
 * @return  BAD_FUNC_ARG when in or outSz is NULL.
5332
 * @return  BUFFER_E when buffer too small.
5333
 */
5334
int EncodeObjectId(const word16* in, word32 inSz, byte* out, word32* outSz)
5335
{
5336
    int i, x, len;
5337
    word32 d, t;
5338
5339
    /* check args */
5340
    if (in == NULL || outSz == NULL) {
5341
        return BAD_FUNC_ARG;
5342
    }
5343
5344
    /* compute length of encoded OID */
5345
    d = (in[0] * 40) + in[1];
5346
    len = 0;
5347
    for (i = 1; i < (int)inSz; i++) {
5348
        x = 0;
5349
        t = d;
5350
        while (t) {
5351
            x++;
5352
            t >>= 1;
5353
        }
5354
        len += (x / 7) + ((x % 7) ? 1 : 0) + (d == 0 ? 1 : 0);
5355
5356
        if (i < (int)inSz - 1) {
5357
            d = in[i + 1];
5358
        }
5359
    }
5360
5361
    if (out) {
5362
        /* verify length */
5363
        if ((int)*outSz < len) {
5364
            return BUFFER_E; /* buffer provided is not large enough */
5365
        }
5366
5367
        /* calc first byte */
5368
        d = (in[0] * 40) + in[1];
5369
5370
        /* encode bytes */
5371
        x = 0;
5372
        for (i = 1; i < (int)inSz; i++) {
5373
            if (d) {
5374
                int y = x, z;
5375
                byte mask = 0;
5376
                while (d) {
5377
                    out[x++] = (byte)((d & 0x7F) | mask);
5378
                    d     >>= 7;
5379
                    mask  |= 0x80;  /* upper bit is set on all but the last byte */
5380
                }
5381
                /* now swap bytes y...x-1 */
5382
                z = x - 1;
5383
                while (y < z) {
5384
                    mask = out[y];
5385
                    out[y] = out[z];
5386
                    out[z] = mask;
5387
                    ++y;
5388
                    --z;
5389
                }
5390
            }
5391
            else {
5392
              out[x++] = 0x00; /* zero value */
5393
            }
5394
5395
            /* next word */
5396
            if (i < (int)inSz - 1) {
5397
                d = in[i + 1];
5398
            }
5399
        }
5400
    }
5401
5402
    /* return length */
5403
    *outSz = len;
5404
5405
    return 0;
5406
}
5407
#endif /* HAVE_OID_ENCODING */
5408
5409
#ifdef HAVE_OID_DECODING
5410
/* Encode dotted form of OID into byte array version.
5411
 *
5412
 * @param [in]      in     Byte array containing OID.
5413
 * @param [in]      inSz   Size of OID in bytes.
5414
 * @param [in]      out    Array to hold dotted form of OID.
5415
 * @param [in, out] outSz  On in, number of elements in array.
5416
 *                         On out, count of numbers in dotted form.
5417
 * @return  0 on success
5418
 * @return  BAD_FUNC_ARG when in or outSz is NULL.
5419
 * @return  BUFFER_E when dotted form buffer too small.
5420
 */
5421
int DecodeObjectId(const byte* in, word32 inSz, word16* out, word32* outSz)
5422
{
5423
    int x = 0, y = 0;
5424
    word32 t = 0;
5425
5426
    /* check args */
5427
    if (in == NULL || outSz == NULL) {
5428
        return BAD_FUNC_ARG;
5429
    }
5430
5431
    /* decode bytes */
5432
    while (inSz--) {
5433
        t = (t << 7) | (in[x] & 0x7F);
5434
        if (!(in[x] & 0x80)) {
5435
            if (y >= (int)*outSz) {
5436
                return BUFFER_E;
5437
            }
5438
            if (y == 0) {
5439
                out[0] = (t / 40);
5440
                out[1] = (t % 40);
5441
                y = 2;
5442
            }
5443
            else {
5444
                out[y++] = t;
5445
            }
5446
            t = 0; /* reset tmp */
5447
        }
5448
        x++;
5449
    }
5450
5451
    /* return length */
5452
    *outSz = y;
5453
5454
    return 0;
5455
}
5456
#endif /* HAVE_OID_DECODING */
5457
5458
/* Decode the header of a BER/DER encoded OBJECT ID.
5459
 *
5460
 * @param [in]      input     Buffer holding DER/BER encoded data.
5461
 * @param [in, out] inOutIdx  On in, starting index of header.
5462
 *                            On out, end of parsed header.
5463
 * @param [out]     len       Number of bytes in the ASN.1 data.
5464
 * @param [in]      maxIdx    Length of data in buffer.
5465
 * @return  0 on success.
5466
 * @return  BUFFER_E when there is not enough data to parse.
5467
 * @return  ASN_PARSE_E when the tag is not a OBJECT ID or length is invalid.
5468
 */
5469
int GetASNObjectId(const byte* input, word32* inOutIdx, int* len, word32 maxIdx)
5470
0
{
5471
0
    int ret = GetASNHeader(input, ASN_OBJECT_ID, inOutIdx, len, maxIdx);
5472
0
    if (ret > 0) {
5473
        /* Only return 0 on success. */
5474
0
        ret = 0;
5475
0
    }
5476
0
    return ret;
5477
0
}
5478
5479
/* Set the DER/BER encoding of the ASN.1 OBJECT ID header.
5480
 *
5481
 * When output is NULL, calculate the header length only.
5482
 *
5483
 * @param [in]  len        Length of OBJECT ID data in bytes.
5484
 * @param [out] output     Buffer to write into.
5485
 * @return  Number of bytes added to the buffer.
5486
 */
5487
int SetObjectId(int len, byte* output)
5488
0
{
5489
0
    int idx = 0;
5490
5491
0
    if (output) {
5492
        /* Write out tag. */
5493
0
        output[idx] = ASN_OBJECT_ID;
5494
0
    }
5495
    /* Skip tag. */
5496
0
    idx += ASN_TAG_SZ;
5497
    /* Encode length - passing NULL for output will not encode. */
5498
0
    idx += SetLength(len, output ? output + idx : NULL);
5499
5500
    /* Return index after header. */
5501
0
    return idx;
5502
0
}
5503
5504
#ifdef ASN_DUMP_OID
5505
/* Dump the OID information.
5506
 *
5507
 * Decode the OID too if function available.
5508
 *
5509
 * @param [in] oidData  OID data from buffer.
5510
 * @param [in] oidSz    Size of OID data in buffer.
5511
 * @param [in] oid      OID id.
5512
 * @param [in] oidType  Type of OID.
5513
 * @return  0 on success.
5514
 * @return  BUFFER_E when not enough bytes for proper decode.
5515
 *          (HAVE_OID_DECODING)
5516
 */
5517
static int DumpOID(const byte* oidData, word32 oidSz, word32 oid,
5518
                   word32 oidType)
5519
{
5520
    int    ret = 0;
5521
    word32 i;
5522
5523
    /* support for dumping OID information */
5524
    printf("OID (Type %d, Sz %d, Sum %d): ", oidType, oidSz, oid);
5525
    /* Dump bytes in decimal. */
5526
    for (i = 0; i < oidSz; i++) {
5527
        printf("%d, ", oidData[i]);
5528
    }
5529
    printf("\n");
5530
    /* Dump bytes in hexadecimal. */
5531
    for (i = 0; i < oidSz; i++) {
5532
        printf("%02x, ", oidData[i]);
5533
    }
5534
    printf("\n");
5535
5536
    #ifdef HAVE_OID_DECODING
5537
    {
5538
        word16 decOid[MAX_OID_SZ];
5539
        word32 decOidSz = sizeof(decOid);
5540
        /* Decode the OID into dotted form. */
5541
        ret = DecodeObjectId(oidData, oidSz, decOid, &decOidSz);
5542
        if (ret == 0) {
5543
            printf("  Decoded (Sz %d): ", decOidSz);
5544
            for (i=0; i<decOidSz; i++) {
5545
                printf("%d.", decOid[i]);
5546
            }
5547
            printf("\n");
5548
        }
5549
        else {
5550
            printf("DecodeObjectId failed: %d\n", ret);
5551
        }
5552
    }
5553
    #endif /* HAVE_OID_DECODING */
5554
5555
    return ret;
5556
}
5557
#endif /* ASN_DUMP_OID */
5558
5559
/* Get the OID data and verify it is of the type specified when compiled in.
5560
 *
5561
 * @param [in]      input     Buffer holding OID.
5562
 * @param [in, out] inOutIdx  On in, starting index of OID.
5563
 *                            On out, end of parsed OID.
5564
 * @param [out]     oid       OID id.
5565
 * @param [in]      oidType   Expected type of OID. Define NO_VERIFY_OID to
5566
 *                            not compile in check.
5567
 * @param [in]      length    Length of OID data in buffer.
5568
 * @return  0 on success.
5569
 * @return  ASN_UNKNOWN_OID_E when OID is not recognized.
5570
 * @return  BUFFER_E when not enough bytes for proper decode. (ASN_DUMP_OID and
5571
 *          HAVE_OID_DECODING)
5572
 */
5573
static int GetOID(const byte* input, word32* inOutIdx, word32* oid,
5574
                  word32 oidType, int length)
5575
0
{
5576
0
    int    ret = 0;
5577
0
    word32 idx = *inOutIdx;
5578
#ifdef HAVE_PQC
5579
    int found_collision = 0;
5580
#endif /* HAVE_PQC */
5581
0
#ifndef NO_VERIFY_OID
5582
0
    word32 actualOidSz;
5583
0
    const byte* actualOid;
5584
0
    const byte* checkOid = NULL;
5585
0
    word32 checkOidSz;
5586
0
#endif /* NO_VERIFY_OID */
5587
5588
0
    (void)oidType;
5589
0
    *oid = 0;
5590
5591
0
#ifndef NO_VERIFY_OID
5592
    /* Keep references to OID data and length for check. */
5593
0
    actualOid = &input[idx];
5594
0
    actualOidSz = (word32)length;
5595
0
#endif /* NO_VERIFY_OID */
5596
5597
#ifdef HAVE_PQC
5598
    /* Since we are summing it up, there could be collisions...and indeed there
5599
     * are:
5600
     *
5601
     * DILITHIUM_LEVEL5
5602
     *     1.3.6.1.4.1.2.267.7.6.7
5603
     *     {43, 6, 1, 4, 1, 2, 130, 11, 7, 8, 7}
5604
     *     -> 220
5605
     * DILITHIUM_AES_LEVEL3
5606
     *     1.3.6.1.4.1.2.267.11.4.5
5607
     *     {43, 6, 1, 4, 1, 2, 130, 11, 11, 6, 5}
5608
     *     -> 220
5609
     *
5610
     * As a small hack, we're going to look for the special case of
5611
     * DILITHIUM_AES_LEVEL3k and if we find it, instead of *oid being set to 220
5612
     * we will set it to 221. This hack will hopefully disappear when new
5613
     * standardized OIDs appear. Note that DILITHIUM_AES_LEVEL3k is defined to
5614
     * be 221.
5615
     */
5616
    if (memcmp(sigDilithiumAes_Level3Oid, &input[idx],
5617
        sizeof(sigDilithiumAes_Level3Oid)) == 0) {
5618
        found_collision = 1;
5619
    }
5620
#endif /* HAVE_PQC */
5621
5622
    /* Sum it up for now. */
5623
0
    while (length--) {
5624
        /* odd HC08 compiler behavior here when input[idx++] */
5625
0
        *oid += (word32)input[idx];
5626
0
        idx++;
5627
0
    }
5628
5629
#ifdef HAVE_PQC
5630
    if (found_collision) {
5631
        *oid = DILITHIUM_AES_LEVEL3k;
5632
    }
5633
#endif /* HAVE_PQC */
5634
5635
    /* Return the index after the OID data. */
5636
0
    *inOutIdx = idx;
5637
5638
0
#ifndef NO_VERIFY_OID
5639
    /* 'Ignore' type means we don't care which OID it is. */
5640
0
    if (oidType != oidIgnoreType) {
5641
        /* Get the OID data for the id-type. */
5642
0
        checkOid = OidFromId(*oid, oidType, &checkOidSz);
5643
5644
    #if defined(WOLFSSL_FPKI)
5645
        /* Handle OID sum collision of
5646
            AES256CBCb (454) 2.16.840.1.101.3.4.1.42
5647
            CP_FPKI_PIV_AUTH_HW_OID (454) 2.16.840.1.101.3.2.1.3.41
5648
        */
5649
        #if defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
5650
        if ((actualOidSz == (word32)sizeof(blkAes256CbcOid)) &&
5651
                (XMEMCMP(actualOid, blkAes256CbcOid,
5652
                 sizeof(blkAes256CbcOid)) == 0)) {
5653
5654
            checkOid   = blkAes256CbcOid;
5655
            checkOidSz = sizeof(blkAes256CbcOid);
5656
        }
5657
        #endif /* HAVE_AES_CBC */
5658
    #endif /* WOLFSSL_FPKI */
5659
5660
    #ifdef ASN_DUMP_OID
5661
        /* Dump out the data for debug. */
5662
        ret = DumpOID(actualOid, actualOidSz, *oid, oidType);
5663
    #endif
5664
5665
        /* TODO: Want to fail when checkOid is NULL.
5666
         * Can't as too many situations where unknown OID is to be
5667
         * supported. Extra parameter for must not be NULL?
5668
         */
5669
        /* Check that the OID data matches what we found for the OID id. */
5670
0
        if ((ret == 0) && (checkOid != NULL) && ((checkOidSz != actualOidSz) ||
5671
0
                (XMEMCMP(actualOid, checkOid, checkOidSz) != 0))) {
5672
0
            WOLFSSL_MSG("OID Check Failed");
5673
0
            WOLFSSL_ERROR_VERBOSE(ASN_UNKNOWN_OID_E);
5674
0
            ret = ASN_UNKNOWN_OID_E;
5675
0
        }
5676
0
    }
5677
0
#endif /* NO_VERIFY_OID */
5678
5679
0
    return ret;
5680
0
}
5681
5682
#ifdef WOLFSSL_ASN_TEMPLATE
5683
/* ASN.1 template for an OBJECT_ID. */
5684
static const ASNItem objectIdASN[] = {
5685
/* OID */ { 0, ASN_OBJECT_ID, 0, 0, 0 }
5686
};
5687
enum {
5688
    OBJECTIDASN_IDX_OID = 0
5689
};
5690
5691
/* Number of items in ASN.1 template for an OBJECT_ID. */
5692
#define objectIdASN_Length (sizeof(objectIdASN) / sizeof(ASNItem))
5693
#endif
5694
5695
/* Get the OID id/sum from the BER encoded OBJECT_ID.
5696
 *
5697
 * @param [in]      input     Buffer holding BER encoded data.
5698
 * @param [in, out] inOutIdx  On in, start of OBJECT_ID.
5699
 *                            On out, start of ASN.1 item after OBJECT_ID.
5700
 * @param [out]     oid       Id of OID in OBJECT_ID data.
5701
 * @param [in]      oidType   Type of OID to expect.
5702
 * @param [in]      maxIdx    Maximum index of data in buffer.
5703
 * @return  0 on success.
5704
 * @return  ASN_PARSE_E when encoding is invalid.
5705
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
5706
 */
5707
int GetObjectId(const byte* input, word32* inOutIdx, word32* oid,
5708
                                  word32 oidType, word32 maxIdx)
5709
0
{
5710
0
#ifndef WOLFSSL_ASN_TEMPLATE
5711
0
    int ret, length;
5712
5713
0
    WOLFSSL_ENTER("GetObjectId()");
5714
5715
0
    ret = GetASNObjectId(input, inOutIdx, &length, maxIdx);
5716
0
    if (ret != 0)
5717
0
        return ret;
5718
5719
0
    return GetOID(input, inOutIdx, oid, oidType, length);
5720
#else
5721
    ASNGetData dataASN[objectIdASN_Length];
5722
    int ret;
5723
5724
    WOLFSSL_ENTER("GetObjectId()");
5725
5726
    /* Clear dynamic data and set OID type expected. */
5727
    XMEMSET(dataASN, 0, sizeof(dataASN));
5728
    GetASN_OID(&dataASN[OBJECTIDASN_IDX_OID], oidType);
5729
    /* Decode OBJECT_ID. */
5730
    ret = GetASN_Items(objectIdASN, dataASN, objectIdASN_Length, 0, input,
5731
                       inOutIdx, maxIdx);
5732
    if (ret == 0) {
5733
        /* Return the id/sum. */
5734
        *oid = dataASN[OBJECTIDASN_IDX_OID].data.oid.sum;
5735
    }
5736
5737
    return ret;
5738
#endif /* WOLFSSL_ASN_TEMPLATE */
5739
0
}
5740
5741
#ifndef WOLFSSL_ASN_TEMPLATE
5742
static int SkipObjectId(const byte* input, word32* inOutIdx, word32 maxIdx)
5743
0
{
5744
0
    word32 idx = *inOutIdx;
5745
0
    int    length;
5746
0
    int ret;
5747
5748
0
    ret = GetASNObjectId(input, &idx, &length, maxIdx);
5749
0
    if (ret != 0)
5750
0
        return ret;
5751
5752
0
    idx += length;
5753
0
    *inOutIdx = idx;
5754
5755
0
    return 0;
5756
0
}
5757
#endif
5758
5759
#ifdef WOLFSSL_ASN_TEMPLATE
5760
/* ASN.1 template for an algorithm identifier. */
5761
static const ASNItem algoIdASN[] = {
5762
/*  SEQ  */    { 0, ASN_SEQUENCE, 1, 1, 0 },
5763
/*  OID  */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
5764
/*  NULL */        { 1, ASN_TAG_NULL, 0, 0, 1 },
5765
};
5766
enum {
5767
    ALGOIDASN_IDX_SEQ = 0,
5768
    ALGOIDASN_IDX_OID,
5769
    ALGOIDASN_IDX_NULL
5770
};
5771
5772
/* Number of items in ASN.1 template for an algorithm identifier. */
5773
#define algoIdASN_Length (sizeof(algoIdASN) / sizeof(ASNItem))
5774
#endif
5775
5776
/* Get the OID id/sum from the BER encoding of an algorithm identifier.
5777
 *
5778
 * NULL tag is skipped if present.
5779
 *
5780
 * @param [in]      input     Buffer holding BER encoded data.
5781
 * @param [in, out] inOutIdx  On in, start of algorithm identifier.
5782
 *                            On out, start of ASN.1 item after algorithm id.
5783
 * @param [out]     oid       Id of OID in algorithm identifier data.
5784
 * @param [in]      oidType   Type of OID to expect.
5785
 * @param [in]      maxIdx    Maximum index of data in buffer.
5786
 * @return  0 on success.
5787
 * @return  ASN_PARSE_E when encoding is invalid.
5788
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
5789
 */
5790
int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid,
5791
                     word32 oidType, word32 maxIdx)
5792
0
{
5793
0
#ifndef WOLFSSL_ASN_TEMPLATE
5794
0
    int    length;
5795
0
    word32 idx = *inOutIdx;
5796
0
    int    ret;
5797
0
    *oid = 0;
5798
5799
0
    WOLFSSL_ENTER("GetAlgoId");
5800
5801
0
    if (GetSequence(input, &idx, &length, maxIdx) < 0)
5802
0
        return ASN_PARSE_E;
5803
5804
0
    if (GetObjectId(input, &idx, oid, oidType, maxIdx) < 0)
5805
0
        return ASN_OBJECT_ID_E;
5806
5807
    /* could have NULL tag and 0 terminator, but may not */
5808
0
    if (idx < maxIdx) {
5809
0
        word32 localIdx = idx; /*use localIdx to not advance when checking tag*/
5810
0
        byte   tag;
5811
5812
0
        if (GetASNTag(input, &localIdx, &tag, maxIdx) == 0) {
5813
0
            if (tag == ASN_TAG_NULL) {
5814
0
                ret = GetASNNull(input, &idx, maxIdx);
5815
0
                if (ret != 0)
5816
0
                    return ret;
5817
0
            }
5818
0
        }
5819
0
    }
5820
5821
0
    *inOutIdx = idx;
5822
5823
0
    return 0;
5824
#else
5825
    DECL_ASNGETDATA(dataASN, algoIdASN_Length);
5826
    int ret = 0;
5827
5828
    WOLFSSL_ENTER("GetAlgoId");
5829
5830
    CALLOC_ASNGETDATA(dataASN, algoIdASN_Length, ret, NULL);
5831
    if (ret == 0) {
5832
        /* Set OID type expected. */
5833
        GetASN_OID(&dataASN[ALGOIDASN_IDX_OID], oidType);
5834
        /* Decode the algorithm identifier. */
5835
        ret = GetASN_Items(algoIdASN, dataASN, algoIdASN_Length, 0, input,
5836
            inOutIdx, maxIdx);
5837
    }
5838
    if (ret == 0) {
5839
        /* Return the OID id/sum. */
5840
        *oid = dataASN[ALGOIDASN_IDX_OID].data.oid.sum;
5841
    }
5842
5843
    FREE_ASNGETDATA(dataASN, NULL);
5844
    return ret;
5845
#endif /* WOLFSSL_ASN_TEMPLATE */
5846
0
}
5847
5848
#ifndef NO_RSA
5849
5850
#ifdef WC_RSA_PSS
5851
/* RFC 8017 - PKCS #1 has RSA PSS parameter ASN definition. */
5852
5853
/* Convert a hash OID to a hash type.
5854
 *
5855
 * @param  [in]   oid   Hash OID.
5856
 * @param  [out]  type  Hash type.
5857
 * @return  0 on success.
5858
 * @return  ASN_PARSE_E when hash OID not supported for RSA PSS.
5859
 */
5860
static int RsaPssHashOidToType(word32 oid, enum wc_HashType* type)
5861
0
{
5862
0
    int ret = 0;
5863
5864
0
    switch (oid) {
5865
    /* SHA-1 is missing as it is the default is not allowed to appear. */
5866
0
#ifdef WOLFSSL_SHA224
5867
0
    case SHA224h:
5868
0
        *type = WC_HASH_TYPE_SHA224;
5869
0
        break;
5870
0
#endif
5871
0
#ifndef NO_SHA256
5872
0
    case SHA256h:
5873
0
        *type = WC_HASH_TYPE_SHA256;
5874
0
        break;
5875
0
#endif
5876
0
#ifdef WOLFSSL_SHA384
5877
0
    case SHA384h:
5878
0
        *type = WC_HASH_TYPE_SHA384;
5879
0
        break;
5880
0
#endif
5881
0
#ifdef WOLFSSL_SHA512
5882
0
    case SHA512h:
5883
0
        *type = WC_HASH_TYPE_SHA512;
5884
0
        break;
5885
    /* TODO: SHA512_224h */
5886
    /* TODO: SHA512_256h */
5887
0
#endif
5888
0
    default:
5889
0
        ret = ASN_PARSE_E;
5890
0
        break;
5891
0
    }
5892
5893
0
    return ret;
5894
0
}
5895
5896
/* Convert a hash OID to a MGF1 type.
5897
 *
5898
 * @param  [in]   oid   Hash OID.
5899
 * @param  [out]  mgf   MGF type.
5900
 * @return  0 on success.
5901
 * @return  ASN_PARSE_E when hash OID not supported for RSA PSS.
5902
 */
5903
static int RsaPssHashOidToMgf1(word32 oid, int* mgf)
5904
0
{
5905
0
    int ret = 0;
5906
5907
0
    switch (oid) {
5908
    /* SHA-1 is missing as it is the default is not allowed to appear. */
5909
0
#ifdef WOLFSSL_SHA224
5910
0
    case SHA224h:
5911
0
        *mgf = WC_MGF1SHA224;
5912
0
        break;
5913
0
#endif
5914
0
#ifndef NO_SHA256
5915
0
    case SHA256h:
5916
0
        *mgf = WC_MGF1SHA256;
5917
0
        break;
5918
0
#endif
5919
0
#ifdef WOLFSSL_SHA384
5920
0
    case SHA384h:
5921
0
        *mgf = WC_MGF1SHA384;
5922
0
        break;
5923
0
#endif
5924
0
#ifdef WOLFSSL_SHA512
5925
0
    case SHA512h:
5926
0
        *mgf = WC_MGF1SHA512;
5927
0
        break;
5928
    /* TODO: SHA512_224h */
5929
    /* TODO: SHA512_256h */
5930
0
#endif
5931
0
    default:
5932
0
        ret = ASN_PARSE_E;
5933
0
        break;
5934
0
    }
5935
5936
0
    return ret;
5937
0
}
5938
5939
/* Convert a hash OID to a fake signature OID.
5940
 *
5941
 * @param  [in]   oid     Hash OID.
5942
 * @param  [out]  sigOid  Signature OID to pass wto HashForSignature().
5943
 * @return  0 on success.
5944
 * @return  ASN_PARSE_E when hash OID not supported for RSA PSS.
5945
 */
5946
static int RsaPssHashOidToSigOid(word32 oid, word32* sigOid)
5947
0
{
5948
0
    int ret = 0;
5949
5950
0
    switch (oid) {
5951
0
#ifndef NO_SHA
5952
0
    case WC_HASH_TYPE_SHA:
5953
0
        *sigOid = CTC_SHAwRSA;
5954
0
        break;
5955
0
#endif
5956
0
#ifdef WOLFSSL_SHA224
5957
0
    case WC_HASH_TYPE_SHA224:
5958
0
        *sigOid = CTC_SHA224wRSA;
5959
0
        break;
5960
0
#endif
5961
0
#ifndef NO_SHA256
5962
0
    case WC_HASH_TYPE_SHA256:
5963
0
        *sigOid = CTC_SHA256wRSA;
5964
0
        break;
5965
0
#endif
5966
0
#ifdef WOLFSSL_SHA384
5967
0
    case WC_HASH_TYPE_SHA384:
5968
0
        *sigOid = CTC_SHA384wRSA;
5969
0
        break;
5970
0
#endif
5971
0
#ifdef WOLFSSL_SHA512
5972
0
    case WC_HASH_TYPE_SHA512:
5973
0
        *sigOid = CTC_SHA512wRSA;
5974
0
        break;
5975
0
#endif
5976
    /* TODO: SHA512_224h */
5977
    /* TODO: SHA512_256h */
5978
    /* Not supported by HashForSignature() */
5979
0
    default:
5980
0
        ret = ASN_PARSE_E;
5981
0
        break;
5982
0
    }
5983
5984
0
    return ret;
5985
0
}
5986
5987
#ifdef WOLFSSL_ASN_TEMPLATE
5988
/* ASN tag for hashAlgorigthm. */
5989
#define ASN_TAG_RSA_PSS_HASH        (ASN_CONTEXT_SPECIFIC | 0)
5990
/* ASN tag for maskGenAlgorithm. */
5991
#define ASN_TAG_RSA_PSS_MGF         (ASN_CONTEXT_SPECIFIC | 1)
5992
/* ASN tag for saltLength. */
5993
#define ASN_TAG_RSA_PSS_SALTLEN     (ASN_CONTEXT_SPECIFIC | 2)
5994
/* ASN tag for trailerField. */
5995
#define ASN_TAG_RSA_PSS_TRAILER     (ASN_CONTEXT_SPECIFIC | 3)
5996
5997
/* ASN.1 template for RSA PSS parameters. */
5998
static const ASNItem rsaPssParamsASN[] = {
5999
/*  SEQ         */  { 0, ASN_SEQUENCE, 1, 1, 0 },
6000
/*  HASH        */      { 1, ASN_TAG_RSA_PSS_HASH, 1, 1, 1 },
6001
/*  HASHSEQ     */          { 2, ASN_SEQUENCE, 1, 1, 0 },
6002
/*  HASHOID     */              { 3, ASN_OBJECT_ID, 0, 0, 0 },
6003
/*  HASHNULL    */              { 3, ASN_TAG_NULL, 0, 0, 1 },
6004
/*  MGF         */      { 1, ASN_TAG_RSA_PSS_MGF, 1, 1, 1 },
6005
/*  MGFSEQ      */          { 2, ASN_SEQUENCE, 1, 1, 0 },
6006
/*  MGFOID      */              { 3, ASN_OBJECT_ID, 0, 0, 0 },
6007
/*  MGFPARAM    */              { 3, ASN_SEQUENCE, 1, 1, 0 },
6008
/*  MGFHOID     */                  { 4, ASN_OBJECT_ID, 0, 0, 0 },
6009
/*  MGFHNULL    */                  { 4, ASN_TAG_NULL, 0, 0, 1 },
6010
/*  SALTLEN     */      { 1, ASN_TAG_RSA_PSS_SALTLEN, 1, 1, 1 },
6011
/*  SALTLENINT  */          { 2, ASN_INTEGER, 0, 0, 0 },
6012
/*  TRAILER     */      { 1, ASN_TAG_RSA_PSS_TRAILER, 1, 1, 1 },
6013
/*  TRAILERINT  */          { 2, ASN_INTEGER, 0, 0, 0 },
6014
};
6015
enum {
6016
    RSAPSSPARAMSASN_IDX_SEQ = 0,
6017
    RSAPSSPARAMSASN_IDX_HASH,
6018
    RSAPSSPARAMSASN_IDX_HASHSEQ,
6019
    RSAPSSPARAMSASN_IDX_HASHOID,
6020
    RSAPSSPARAMSASN_IDX_HASHNULL,
6021
    RSAPSSPARAMSASN_IDX_MGF,
6022
    RSAPSSPARAMSASN_IDX_MGFSEQ,
6023
    RSAPSSPARAMSASN_IDX_MGFOID,
6024
    RSAPSSPARAMSASN_IDX_MGFPARAM,
6025
    RSAPSSPARAMSASN_IDX_MGFHOID,
6026
    RSAPSSPARAMSASN_IDX_MGFHNULL,
6027
    RSAPSSPARAMSASN_IDX_SALTLEN,
6028
    RSAPSSPARAMSASN_IDX_SALTLENINT,
6029
    RSAPSSPARAMSASN_IDX_TRAILER,
6030
    RSAPSSPARAMSASN_IDX_TRAILERINT,
6031
};
6032
6033
/* Number of items in ASN.1 template for an algorithm identifier. */
6034
#define rsaPssParamsASN_Length (sizeof(rsaPssParamsASN) / sizeof(ASNItem))
6035
#else
6036
/* ASN tag for hashAlgorigthm. */
6037
0
#define ASN_TAG_RSA_PSS_HASH        (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)
6038
/* ASN tag for maskGenAlgorithm. */
6039
0
#define ASN_TAG_RSA_PSS_MGF         (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)
6040
/* ASN tag for saltLength. */
6041
0
#define ASN_TAG_RSA_PSS_SALTLEN     (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)
6042
/* ASN tag for trailerField. */
6043
0
#define ASN_TAG_RSA_PSS_TRAILER     (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 3)
6044
#endif
6045
6046
/* Decode the RSA PSS parameters.
6047
 *
6048
 * @param  [in]   params   Buffer holding BER encoded RSA PSS parameters.
6049
 * @param  [in]   sz       Size of data in buffer in bytes.
6050
 * @param  [out]  hash     Hash algorithm to use on message.
6051
 * @param  [out]  mgf      MGF algorithm to use with PSS padding.
6052
 * @param  [out]  saltLen  Length of salt in PSS padding.
6053
 * @return  ASN_PARSE_E when the decoding fails.
6054
 * @return  0 on success.
6055
 */
6056
static int DecodeRsaPssParams(const byte* params, word32 sz,
6057
    enum wc_HashType* hash, int* mgf, int* saltLen)
6058
0
{
6059
0
#ifndef WOLFSSL_ASN_TEMPLATE
6060
0
    int ret = 0;
6061
0
    word32 idx = 0;
6062
0
    int len = 0;
6063
0
    word32 oid;
6064
0
    byte tag;
6065
0
    int length;
6066
6067
0
    if (GetSequence_ex(params, &idx, &len, sz, 1) < 0) {
6068
0
        ret = ASN_PARSE_E;
6069
0
    }
6070
0
    if (ret == 0) {
6071
0
        if ((idx < sz) && (params[idx] == ASN_TAG_RSA_PSS_HASH)) {
6072
            /* Hash algorithm to use on message. */
6073
0
            if (GetHeader(params, &tag, &idx, &length, sz, 0) < 0) {
6074
0
                ret = ASN_PARSE_E;
6075
0
            }
6076
0
            if (ret == 0) {
6077
0
                if (GetAlgoId(params, &idx, &oid, oidHashType, sz) < 0) {
6078
0
                    ret = ASN_PARSE_E;
6079
0
                }
6080
0
            }
6081
0
            if (ret == 0) {
6082
0
                ret = RsaPssHashOidToType(oid, hash);
6083
0
            }
6084
0
        }
6085
0
        else {
6086
            /* Default hash algorithm. */
6087
0
            *hash = WC_HASH_TYPE_SHA;
6088
0
        }
6089
0
    }
6090
0
    if (ret == 0) {
6091
0
        if ((idx < sz) && (params[idx] == ASN_TAG_RSA_PSS_MGF)) {
6092
            /* MGF and hash algorithm to use with padding. */
6093
0
            if (GetHeader(params, &tag, &idx, &length, sz, 0) < 0) {
6094
0
                ret = ASN_PARSE_E;
6095
0
            }
6096
0
            if (ret == 0) {
6097
0
                if (GetAlgoId(params, &idx, &oid, oidIgnoreType, sz) < 0) {
6098
0
                    ret = ASN_PARSE_E;
6099
0
                }
6100
0
            }
6101
0
            if ((ret == 0) && (oid != MGF1_OID)) {
6102
0
                ret = ASN_PARSE_E;
6103
0
            }
6104
0
            if (ret == 0) {
6105
0
                ret = GetAlgoId(params, &idx, &oid, oidHashType, sz);
6106
0
                if (ret == 0) {
6107
0
                    ret = RsaPssHashOidToMgf1(oid, mgf);
6108
0
                }
6109
0
            }
6110
0
        }
6111
0
        else {
6112
            /* Default MGF/Hash algorithm. */
6113
0
            *mgf = WC_MGF1SHA1;
6114
0
        }
6115
0
    }
6116
0
    if (ret == 0) {
6117
0
        if ((idx < sz) && (params[idx] == ASN_TAG_RSA_PSS_SALTLEN)) {
6118
            /* Salt length to use with padding. */
6119
0
            if (GetHeader(params, &tag, &idx, &length, sz, 0) < 0) {
6120
0
                ret = ASN_PARSE_E;
6121
0
            }
6122
0
            if (ret == 0) {
6123
0
                ret = GetInteger16Bit(params, &idx, sz);
6124
0
                if (ret >= 0) {
6125
0
                    *saltLen = ret;
6126
0
                    ret = 0;
6127
0
                }
6128
0
            }
6129
0
        }
6130
0
        else {
6131
            /* Default salt length. */
6132
0
            *saltLen = 20;
6133
0
        }
6134
0
    }
6135
0
    if (ret == 0) {
6136
0
        if ((idx < sz) && (params[idx] == ASN_TAG_RSA_PSS_TRAILER)) {
6137
            /* Unused - trialerField. */
6138
0
            if (GetHeader(params, &tag, &idx, &length, sz, 0) < 0) {
6139
0
                ret = ASN_PARSE_E;
6140
0
            }
6141
0
            if (ret == 0) {
6142
0
                ret = GetInteger16Bit(params, &idx, sz);
6143
0
                if (ret > 0) {
6144
0
                    ret = 0;
6145
0
                }
6146
0
            }
6147
0
        }
6148
0
    }
6149
0
    if ((ret == 0) && (idx != sz)) {
6150
0
        ret = ASN_PARSE_E;
6151
0
    }
6152
6153
0
    return ret;
6154
#else
6155
    DECL_ASNGETDATA(dataASN, rsaPssParamsASN_Length);
6156
    int ret = 0;
6157
    word16 sLen = 20;
6158
6159
    CALLOC_ASNGETDATA(dataASN, rsaPssParamsASN_Length, ret, NULL);
6160
    if (ret == 0) {
6161
        word32 inOutIdx = 0;
6162
        /* Default values. */
6163
        *hash = WC_HASH_TYPE_SHA;
6164
        *mgf = WC_MGF1SHA1;
6165
6166
        /* Set OID type expected. */
6167
        GetASN_OID(&dataASN[RSAPSSPARAMSASN_IDX_HASHOID], oidHashType);
6168
        GetASN_OID(&dataASN[RSAPSSPARAMSASN_IDX_MGFHOID], oidHashType);
6169
        /* Place the salt length into 16-bit var sLen. */
6170
        GetASN_Int16Bit(&dataASN[RSAPSSPARAMSASN_IDX_SALTLENINT], &sLen);
6171
        /* Decode the algorithm identifier. */
6172
        ret = GetASN_Items(rsaPssParamsASN, dataASN, rsaPssParamsASN_Length, 1,
6173
            params, &inOutIdx, sz);
6174
    }
6175
    if ((ret == 0) && (dataASN[RSAPSSPARAMSASN_IDX_HASHOID].tag != 0)) {
6176
        word32 oid = dataASN[RSAPSSPARAMSASN_IDX_HASHOID].data.oid.sum;
6177
        ret = RsaPssHashOidToType(oid, hash);
6178
    }
6179
    if ((ret == 0) && (dataASN[RSAPSSPARAMSASN_IDX_MGFHOID].tag != 0)) {
6180
        word32 oid = dataASN[RSAPSSPARAMSASN_IDX_MGFHOID].data.oid.sum;
6181
        ret = RsaPssHashOidToMgf1(oid, mgf);
6182
    }
6183
    if (ret == 0) {
6184
        *saltLen = sLen;
6185
    }
6186
6187
    FREE_ASNGETDATA(dataASN, NULL);
6188
    return ret;
6189
#endif /* WOLFSSL_ASN_TEMPLATE */
6190
0
}
6191
#endif /* WC_RSA_PSS */
6192
6193
#ifndef HAVE_USER_RSA
6194
#if defined(WOLFSSL_ASN_TEMPLATE) || (!defined(NO_CERTS) && \
6195
    (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || \
6196
     defined(WOLFSSL_KCAPI_RSA)))
6197
/* Byte offset of numbers in RSA key. */
6198
size_t rsaIntOffset[] = {
6199
    OFFSETOF(RsaKey, n),
6200
    OFFSETOF(RsaKey, e),
6201
#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) || defined(WOLFSSL_KEY_GEN)
6202
    OFFSETOF(RsaKey, d),
6203
    OFFSETOF(RsaKey, p),
6204
    OFFSETOF(RsaKey, q),
6205
    OFFSETOF(RsaKey, dP),
6206
    OFFSETOF(RsaKey, dQ),
6207
    OFFSETOF(RsaKey, u)
6208
#endif
6209
};
6210
6211
/* Get a number from the RSA key based on an index.
6212
 *
6213
 * Order: { n, e, d, p, q, dP, dQ, u }
6214
 *
6215
 * Caller must ensure index is not invalid!
6216
 *
6217
 * @param [in] key  RSA key object.
6218
 * @param [in] idx  Index of number.
6219
 * @return  A pointer to an mp_int when valid index.
6220
 * @return  NULL when invalid index.
6221
 */
6222
static mp_int* GetRsaInt(RsaKey* key, byte idx)
6223
0
{
6224
    /* Cast key to byte array to and use offset to get to mp_int field. */
6225
0
    return (mp_int*)(((byte*)key) + rsaIntOffset[idx]);
6226
0
}
6227
#endif
6228
6229
#ifdef WOLFSSL_ASN_TEMPLATE
6230
/* ASN.1 template for an RSA private key.
6231
 * PKCS #1: RFC 8017, A.1.2 - RSAPrivateKey
6232
 */
6233
static const ASNItem rsaKeyASN[] = {
6234
/*  SEQ */    { 0, ASN_SEQUENCE, 1, 1, 0 },
6235
/*  VER */        { 1, ASN_INTEGER, 0, 0, 0 },
6236
                /* Integers need to be in this specific order
6237
                 * as asn code depends on this. */
6238
/*  N   */        { 1, ASN_INTEGER, 0, 0, 0 },
6239
/*  E   */        { 1, ASN_INTEGER, 0, 0, 0 },
6240
#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) || defined(WOLFSSL_KEY_GEN)
6241
/*  D   */        { 1, ASN_INTEGER, 0, 0, 0 },
6242
/*  P   */        { 1, ASN_INTEGER, 0, 0, 0 },
6243
/*  Q   */        { 1, ASN_INTEGER, 0, 0, 0 },
6244
/*  DP  */        { 1, ASN_INTEGER, 0, 0, 0 },
6245
/*  DQ  */        { 1, ASN_INTEGER, 0, 0, 0 },
6246
/*  U   */        { 1, ASN_INTEGER, 0, 0, 0 },
6247
                /* otherPrimeInfos  OtherPrimeInfos OPTIONAL
6248
                 * v2 - multiprime */
6249
#endif
6250
};
6251
enum {
6252
    RSAKEYASN_IDX_SEQ = 0,
6253
    RSAKEYASN_IDX_VER,
6254
    /* Integers need to be in this specific order
6255
     * as asn code depends on this. */
6256
    RSAKEYASN_IDX_N,
6257
    RSAKEYASN_IDX_E,
6258
#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) || defined(WOLFSSL_KEY_GEN)
6259
    RSAKEYASN_IDX_D,
6260
    RSAKEYASN_IDX_P,
6261
    RSAKEYASN_IDX_Q,
6262
    RSAKEYASN_IDX_DP,
6263
    RSAKEYASN_IDX_DQ,
6264
    RSAKEYASN_IDX_U,
6265
#endif
6266
};
6267
6268
/* Number of items in ASN.1 template for an RSA private key. */
6269
#define rsaKeyASN_Length (sizeof(rsaKeyASN) / sizeof(ASNItem))
6270
#endif
6271
6272
/* Decode RSA private key.
6273
 *
6274
 * PKCS #1: RFC 8017, A.1.2 - RSAPrivateKey
6275
 *
6276
 * Compiling with WOLFSSL_RSA_PUBLIC_ONLY will result in only the public fields
6277
 * being extracted.
6278
 *
6279
 * @param [in]      input     Buffer holding BER encoded data.
6280
 * @param [in, out] inOutIdx  On in, start of RSA private key.
6281
 *                            On out, start of ASN.1 item after RSA private key.
6282
 * @param [in, out] key       RSA key object.
6283
 * @param [in]      inSz      Number of bytes in buffer.
6284
 * @return  0 on success.
6285
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
6286
 *          is invalid.
6287
 * @return  BUFFER_E when data in buffer is too small.
6288
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
6289
 *          non-zero length.
6290
 * @return  MP_INIT_E when the unable to initialize an mp_int.
6291
 * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
6292
 */
6293
int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
6294
                        word32 inSz)
6295
0
{
6296
0
#ifndef WOLFSSL_ASN_TEMPLATE
6297
0
    int version, length;
6298
0
    word32 algId = 0;
6299
6300
0
    if (inOutIdx == NULL || input == NULL || key == NULL) {
6301
0
        return BAD_FUNC_ARG;
6302
0
    }
6303
6304
    /* if has pkcs8 header skip it */
6305
0
    if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) {
6306
        /* ignore error, did not have pkcs8 header */
6307
0
    }
6308
6309
0
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
6310
0
        return ASN_PARSE_E;
6311
6312
0
    if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
6313
0
        return ASN_PARSE_E;
6314
6315
0
    key->type = RSA_PRIVATE;
6316
6317
#ifdef WOLFSSL_CHECK_MEM_ZERO
6318
    mp_memzero_add("Decode RSA key d", &key->d);
6319
    mp_memzero_add("Decode RSA key p", &key->p);
6320
    mp_memzero_add("Decode RSA key q", &key->q);
6321
#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || \
6322
    !defined(RSA_LOW_MEM)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
6323
    mp_memzero_add("Decode RSA key dP", &key->dP);
6324
    mp_memzero_add("Decode RSA key dQ", &key->dQ);
6325
    mp_memzero_add("Decode RSA key u", &key->u);
6326
#endif
6327
#endif
6328
6329
0
    if (GetInt(&key->n,  input, inOutIdx, inSz) < 0 ||
6330
0
        GetInt(&key->e,  input, inOutIdx, inSz) < 0 ||
6331
0
#ifndef WOLFSSL_RSA_PUBLIC_ONLY
6332
0
        GetInt(&key->d,  input, inOutIdx, inSz) < 0 ||
6333
0
        GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
6334
0
        GetInt(&key->q,  input, inOutIdx, inSz) < 0
6335
#else
6336
        SkipInt(input, inOutIdx, inSz) < 0 ||
6337
        SkipInt(input, inOutIdx, inSz) < 0 ||
6338
        SkipInt(input, inOutIdx, inSz) < 0
6339
#endif
6340
0
       ) {
6341
0
            return ASN_RSA_KEY_E;
6342
0
       }
6343
0
#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)) \
6344
0
    && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
6345
0
    if (GetInt(&key->dP, input, inOutIdx, inSz) < 0 ||
6346
0
        GetInt(&key->dQ, input, inOutIdx, inSz) < 0 ||
6347
0
        GetInt(&key->u,  input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;
6348
#else
6349
    if (SkipInt(input, inOutIdx, inSz) < 0 ||
6350
        SkipInt(input, inOutIdx, inSz) < 0 ||
6351
        SkipInt(input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;
6352
#endif
6353
6354
#if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_CRYPTOCELL)
6355
    if (wc_InitRsaHw(key) != 0) {
6356
        return BAD_STATE_E;
6357
    }
6358
#endif
6359
6360
0
    return 0;
6361
#else
6362
    DECL_ASNGETDATA(dataASN, rsaKeyASN_Length);
6363
    int        ret = 0;
6364
    int        i;
6365
    byte       version = (byte)-1;
6366
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
6367
    word32 algId = 0;
6368
#endif
6369
6370
    /* Check validity of parameters. */
6371
    if (inOutIdx == NULL || input == NULL || key == NULL) {
6372
        ret = BAD_FUNC_ARG;
6373
    }
6374
6375
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
6376
    if (ret == 0) {
6377
        /* if has pkcs8 header skip it */
6378
        if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) {
6379
            /* ignore error, did not have pkcs8 header */
6380
        }
6381
    }
6382
#endif
6383
6384
    CALLOC_ASNGETDATA(dataASN, rsaKeyASN_Length, ret, key->heap);
6385
6386
    if (ret == 0) {
6387
        /* Register variable to hold version field. */
6388
        GetASN_Int8Bit(&dataASN[RSAKEYASN_IDX_VER], &version);
6389
        /* Setup data to store INTEGER data in mp_int's in RSA object. */
6390
    #if defined(WOLFSSL_RSA_PUBLIC_ONLY)
6391
        /* Extract all public fields. */
6392
        for (i = 0; i < RSA_PUB_INTS; i++) {
6393
            GetASN_MP(&dataASN[(byte)RSAKEYASN_IDX_N + i], GetRsaInt(key, i));
6394
        }
6395
        /* Not extracting all data from BER encoding. */
6396
        #define RSA_ASN_COMPLETE    0
6397
    #else
6398
        /* Extract all private fields. */
6399
        for (i = 0; i < RSA_INTS; i++) {
6400
            GetASN_MP(&dataASN[(byte)RSAKEYASN_IDX_N + i], GetRsaInt(key, i));
6401
        }
6402
        /* Extracting all data from BER encoding. */
6403
        #define RSA_ASN_COMPLETE    1
6404
    #endif
6405
        /* Parse BER encoding for RSA private key. */
6406
        ret = GetASN_Items(rsaKeyASN, dataASN, rsaKeyASN_Length,
6407
            RSA_ASN_COMPLETE, input, inOutIdx, inSz);
6408
    }
6409
    /* Check version: 0 - two prime, 1 - multi-prime
6410
     * Multi-prime has optional sequence after coefficient for extra primes.
6411
     * If extra primes, parsing will fail as not all the buffer was used.
6412
     */
6413
    if ((ret == 0) && (version > PKCS1v1)) {
6414
        ret = ASN_PARSE_E;
6415
    }
6416
    if (ret == 0) {
6417
    #if !defined(WOLFSSL_RSA_PUBLIC_ONLY)
6418
        /* RSA key object has all private key values. */
6419
        key->type = RSA_PRIVATE;
6420
    #else
6421
        /* RSA key object has all public key values. */
6422
        key->type = RSA_PUBLIC;
6423
    #endif
6424
6425
    #ifdef WOLFSSL_XILINX_CRYPT
6426
        if (wc_InitRsaHw(key) != 0)
6427
            ret = BAD_STATE_E;
6428
    #endif
6429
    }
6430
6431
    FREE_ASNGETDATA(dataASN, key->heap);
6432
    return ret;
6433
#endif /* WOLFSSL_ASN_TEMPLATE */
6434
0
}
6435
#endif /* HAVE_USER_RSA */
6436
#endif /* NO_RSA */
6437
6438
#ifdef WOLFSSL_ASN_TEMPLATE
6439
/* ASN.1 template for a PKCS #8 key.
6440
 * Ignoring optional attributes and public key.
6441
 * PKCS #8: RFC 5958, 2 - PrivateKeyInfo
6442
 */
6443
static const ASNItem pkcs8KeyASN[] = {
6444
/*  SEQ                 */    { 0, ASN_SEQUENCE, 1, 1, 0 },
6445
/*  VER                 */        { 1, ASN_INTEGER, 0, 0, 0 },
6446
/*  PKEY_ALGO_SEQ       */        { 1, ASN_SEQUENCE, 1, 1, 0 },
6447
/*  PKEY_ALGO_OID_KEY   */            { 2, ASN_OBJECT_ID, 0, 0, 0 },
6448
/*  PKEY_ALGO_OID_CURVE */            { 2, ASN_OBJECT_ID, 0, 0, 1 },
6449
/*  PKEY_ALGO_NULL      */            { 2, ASN_TAG_NULL, 0, 0, 1 },
6450
#ifdef WC_RSA_PSS
6451
/*  PKEY_ALGO_PARAM_SEQ */            { 2, ASN_SEQUENCE, 1, 0, 1 },
6452
#endif
6453
/*  PKEY_DATA           */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
6454
                /* attributes            [0] Attributes OPTIONAL */
6455
                /* [[2: publicKey        [1] PublicKey OPTIONAL ]] */
6456
};
6457
enum {
6458
    PKCS8KEYASN_IDX_SEQ = 0,
6459
    PKCS8KEYASN_IDX_VER,
6460
    PKCS8KEYASN_IDX_PKEY_ALGO_SEQ,
6461
    PKCS8KEYASN_IDX_PKEY_ALGO_OID_KEY,
6462
    PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE,
6463
    PKCS8KEYASN_IDX_PKEY_ALGO_NULL,
6464
#ifdef WC_RSA_PSS
6465
    PKCS8KEYASN_IDX_PKEY_ALGO_PARAM_SEQ,
6466
#endif
6467
    PKCS8KEYASN_IDX_PKEY_DATA,
6468
};
6469
6470
/* Number of items in ASN.1 template for a PKCS #8 key. */
6471
#define pkcs8KeyASN_Length (sizeof(pkcs8KeyASN) / sizeof(ASNItem))
6472
#endif
6473
6474
/* Remove PKCS #8 header around an RSA, ECDSA, Ed25519, or Ed448.
6475
 *
6476
 * @param [in]       input     Buffer holding BER data.
6477
 * @param [in, out]  inOutIdx  On in, start of PKCS #8 encoding.
6478
 *                             On out, start of encoded key.
6479
 * @param [in]       sz        Size of data in buffer.
6480
 * @param [out]      algId     Key's algorithm id from PKCS #8 header.
6481
 * @return  Length of key data on success.
6482
 * @return  BAD_FUNC_ARG when input or inOutIdx is NULL.
6483
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
6484
 *          is invalid.
6485
 * @return  BUFFER_E when data in buffer is too small.
6486
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
6487
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
6488
 *          non-zero length.
6489
 */
6490
int ToTraditionalInline_ex(const byte* input, word32* inOutIdx, word32 sz,
6491
                           word32* algId)
6492
0
{
6493
0
#ifndef WOLFSSL_ASN_TEMPLATE
6494
0
    word32 idx;
6495
0
    int    version, length;
6496
0
    int    ret;
6497
0
    byte   tag;
6498
6499
0
    if (input == NULL || inOutIdx == NULL)
6500
0
        return BAD_FUNC_ARG;
6501
6502
0
    idx = *inOutIdx;
6503
6504
0
    if (GetSequence(input, &idx, &length, sz) < 0)
6505
0
        return ASN_PARSE_E;
6506
6507
0
    if (GetMyVersion(input, &idx, &version, sz) < 0)
6508
0
        return ASN_PARSE_E;
6509
6510
0
    if (GetAlgoId(input, &idx, algId, oidKeyType, sz) < 0)
6511
0
        return ASN_PARSE_E;
6512
6513
0
    if (GetASNTag(input, &idx, &tag, sz) < 0)
6514
0
        return ASN_PARSE_E;
6515
0
    idx = idx - 1; /* reset idx after finding tag */
6516
6517
0
#if defined(WC_RSA_PSS) && !defined(NO_RSA)
6518
0
    if (*algId == RSAPSSk && tag == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
6519
0
        word32 seqIdx = idx;
6520
0
        int seqLen;
6521
        /* Not set when -1. */
6522
0
        enum wc_HashType hash = WC_HASH_TYPE_NONE;
6523
0
        int mgf = -1;
6524
0
        int saltLen = 0;
6525
6526
0
        if (GetSequence(input, &idx, &seqLen, sz) < 0) {
6527
0
            return ASN_PARSE_E;
6528
0
        }
6529
        /* Get the private key parameters. */
6530
0
        ret = DecodeRsaPssParams(input + seqIdx,
6531
0
            seqLen + idx - seqIdx, &hash, &mgf, &saltLen);
6532
0
        if (ret != 0) {
6533
0
            return ASN_PARSE_E;
6534
0
        }
6535
        /* TODO: store parameters so that usage can be checked. */
6536
0
        idx += seqLen;
6537
0
    }
6538
0
#endif /* WC_RSA_PSS && !NO_RSA */
6539
6540
0
    if (tag == ASN_OBJECT_ID) {
6541
0
        if (SkipObjectId(input, &idx, sz) < 0)
6542
0
            return ASN_PARSE_E;
6543
0
    }
6544
6545
0
    ret = GetOctetString(input, &idx, &length, sz);
6546
0
    if (ret < 0) {
6547
0
        if (ret == BUFFER_E)
6548
0
            return ASN_PARSE_E;
6549
        /* Some private keys don't expect an octet string */
6550
0
        WOLFSSL_MSG("Couldn't find Octet string");
6551
0
    }
6552
6553
0
    *inOutIdx = idx;
6554
6555
0
    return length;
6556
#else
6557
    DECL_ASNGETDATA(dataASN, pkcs8KeyASN_Length);
6558
    int ret = 0;
6559
    word32 oid = 9;
6560
    byte version;
6561
    word32 idx;
6562
6563
    /* Check validity of parameters. */
6564
    if (input == NULL || inOutIdx == NULL) {
6565
        return BAD_FUNC_ARG;
6566
    }
6567
6568
    idx = *inOutIdx;
6569
6570
    CALLOC_ASNGETDATA(dataASN, pkcs8KeyASN_Length, ret, NULL);
6571
6572
    if (ret == 0) {
6573
        /* Get version, check key type and curve type. */
6574
        GetASN_Int8Bit(&dataASN[PKCS8KEYASN_IDX_VER], &version);
6575
        GetASN_OID(&dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_KEY], oidKeyType);
6576
        GetASN_OID(&dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE], oidCurveType);
6577
        /* Parse data. */
6578
        ret = GetASN_Items(pkcs8KeyASN, dataASN, pkcs8KeyASN_Length, 1, input,
6579
                           &idx, sz);
6580
    }
6581
6582
    if (ret == 0) {
6583
        /* Key type OID. */
6584
        oid = dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_KEY].data.oid.sum;
6585
6586
        /* Version 1 includes an optional public key.
6587
         * If public key is included then the parsing will fail as it did not
6588
         * use all the data.
6589
         */
6590
        if (version > PKCS8v1) {
6591
            ret = ASN_PARSE_E;
6592
        }
6593
    }
6594
    if (ret == 0) {
6595
        switch (oid) {
6596
    #ifndef NO_RSA
6597
            case RSAk:
6598
                /* Must have NULL item but not OBJECT_ID item. */
6599
                if ((dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag == 0) ||
6600
                    (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE].tag != 0)) {
6601
                    ret = ASN_PARSE_E;
6602
                }
6603
                break;
6604
        #ifdef WC_RSA_PSS
6605
            case RSAPSSk:
6606
                /* Must not have NULL item. */
6607
                if (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag != 0) {
6608
                    ret = ASN_PARSE_E;
6609
                }
6610
                if (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_PARAM_SEQ].tag != 0) {
6611
                    enum wc_HashType hash;
6612
                    int mgf;
6613
                    int saltLen;
6614
                    const byte* params = GetASNItem_Addr(
6615
                        dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_PARAM_SEQ], input);
6616
                    word32 paramsSz = GetASNItem_Length(
6617
                        dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_PARAM_SEQ], input);
6618
6619
                    /* Validate the private key parameters. */
6620
                    ret = DecodeRsaPssParams(params, paramsSz, &hash, &mgf,
6621
                        &saltLen);
6622
                    if (ret != 0) {
6623
                        return ASN_PARSE_E;
6624
                    }
6625
                    /* TODO: store parameters so that usage can be checked. */
6626
                }
6627
                break;
6628
        #endif
6629
    #endif
6630
        #ifdef HAVE_ECC
6631
            case ECDSAk:
6632
                /* Must not have NULL item. */
6633
                if (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag != 0) {
6634
                    ret = ASN_PARSE_E;
6635
                }
6636
                break;
6637
        #endif
6638
        #ifdef HAVE_ED25519
6639
            case ED25519k:
6640
                /* Neither NULL item nor OBJECT_ID item allowed. */
6641
                if ((dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag != 0) ||
6642
                    (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE].tag != 0)) {
6643
                    ret = ASN_PARSE_E;
6644
                }
6645
                break;
6646
        #endif
6647
        #ifdef HAVE_CURVE25519
6648
            case X25519k:
6649
                /* Neither NULL item nor OBJECT_ID item allowed. */
6650
                if ((dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag != 0) ||
6651
                    (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE].tag != 0)) {
6652
                    ret = ASN_PARSE_E;
6653
                }
6654
                break;
6655
        #endif
6656
        #ifdef HAVE_ED448
6657
            case ED448k:
6658
                /* Neither NULL item nor OBJECT_ID item allowed. */
6659
                if ((dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag != 0) ||
6660
                    (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE].tag != 0)) {
6661
                    ret = ASN_PARSE_E;
6662
                }
6663
                break;
6664
        #endif
6665
        #ifdef HAVE_CURVE448
6666
            case X448k:
6667
                /* Neither NULL item nor OBJECT_ID item allowed. */
6668
                if ((dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag != 0) ||
6669
                    (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE].tag != 0)) {
6670
                    ret = ASN_PARSE_E;
6671
                }
6672
                break;
6673
        #endif
6674
            /* DSAk not supported. */
6675
            /* Falcon and Dilithium not supported. */
6676
            /* Ignore OID lookup failures. */
6677
            default:
6678
                break;
6679
        }
6680
    }
6681
    if (ret == 0) {
6682
        /* Return algorithm id of internal key. */
6683
        *algId = oid;
6684
        /* Return index to start of internal key. */
6685
        *inOutIdx = GetASNItem_DataIdx(dataASN[PKCS8KEYASN_IDX_PKEY_DATA], input);
6686
        /* Return value is length of internal key. */
6687
        ret = dataASN[PKCS8KEYASN_IDX_PKEY_DATA].data.ref.length;
6688
    }
6689
6690
    FREE_ASNGETDATA(dataASN, NULL);
6691
    return ret;
6692
#endif
6693
0
}
6694
6695
/* TODO: test case  */
6696
int ToTraditionalInline(const byte* input, word32* inOutIdx, word32 sz)
6697
0
{
6698
0
    word32 oid;
6699
6700
0
    return ToTraditionalInline_ex(input, inOutIdx, sz, &oid);
6701
0
}
6702
6703
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
6704
6705
/* Remove PKCS8 header, move beginning of traditional to beginning of input */
6706
int ToTraditional_ex(byte* input, word32 sz, word32* algId)
6707
0
{
6708
0
    word32 inOutIdx = 0;
6709
0
    int    length;
6710
6711
0
    if (input == NULL)
6712
0
        return BAD_FUNC_ARG;
6713
6714
0
    length = ToTraditionalInline_ex(input, &inOutIdx, sz, algId);
6715
0
    if (length < 0)
6716
0
        return length;
6717
6718
0
    if (length + inOutIdx > sz)
6719
0
        return BUFFER_E;
6720
6721
0
    XMEMMOVE(input, input + inOutIdx, length);
6722
6723
0
    return length;
6724
0
}
6725
6726
int ToTraditional(byte* input, word32 sz)
6727
0
{
6728
0
    word32 oid;
6729
6730
0
    return ToTraditional_ex(input, sz, &oid);
6731
0
}
6732
6733
#endif /* HAVE_PKCS8 || HAVE_PKCS12 */
6734
6735
#if defined(HAVE_PKCS8) && !defined(NO_CERTS)
6736
6737
int wc_GetPkcs8TraditionalOffset(byte* input, word32* inOutIdx, word32 sz)
6738
0
{
6739
0
    int length;
6740
0
    word32 algId;
6741
6742
0
    if (input == NULL || inOutIdx == NULL || (*inOutIdx > sz))
6743
0
        return BAD_FUNC_ARG;
6744
6745
0
    length = ToTraditionalInline_ex(input, inOutIdx, sz, &algId);
6746
6747
0
    return length;
6748
0
}
6749
6750
int wc_CreatePKCS8Key(byte* out, word32* outSz, byte* key, word32 keySz,
6751
        int algoID, const byte* curveOID, word32 oidSz)
6752
0
{
6753
0
#ifndef WOLFSSL_ASN_TEMPLATE
6754
0
    word32 keyIdx = 0;
6755
0
    word32 tmpSz  = 0;
6756
0
    word32 sz;
6757
0
    word32 tmpAlgId = 0;
6758
6759
    /* If out is NULL then return the max size needed
6760
     * + 2 for ASN_OBJECT_ID and ASN_OCTET_STRING tags */
6761
0
    if (out == NULL && outSz != NULL) {
6762
0
        *outSz = keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ
6763
0
                 + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 2;
6764
6765
0
        if (curveOID != NULL)
6766
0
            *outSz += oidSz + MAX_LENGTH_SZ + 1;
6767
6768
0
        WOLFSSL_MSG("Checking size of PKCS8");
6769
6770
0
        return LENGTH_ONLY_E;
6771
0
    }
6772
6773
0
    WOLFSSL_ENTER("wc_CreatePKCS8Key()");
6774
6775
0
    if (key == NULL || out == NULL || outSz == NULL) {
6776
0
        return BAD_FUNC_ARG;
6777
0
    }
6778
6779
    /* check the buffer has enough room for largest possible size */
6780
0
    if (curveOID != NULL) {
6781
0
        if (*outSz < (keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ
6782
0
               + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 3 + oidSz + MAX_LENGTH_SZ))
6783
0
            return BUFFER_E;
6784
0
    }
6785
0
    else {
6786
0
        oidSz = 0; /* with no curveOID oid size must be 0 */
6787
0
        if (*outSz < (keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ
6788
0
                  + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 2))
6789
0
            return BUFFER_E;
6790
0
    }
6791
6792
    /* sanity check: make sure the key doesn't already have a PKCS 8 header */
6793
0
    if (ToTraditionalInline_ex(key, &keyIdx, keySz, &tmpAlgId) >= 0) {
6794
0
        (void)tmpAlgId;
6795
0
        return ASN_PARSE_E;
6796
0
    }
6797
6798
    /* PrivateKeyInfo ::= SEQUENCE */
6799
0
    keyIdx = MAX_SEQ_SZ; /* save room for sequence */
6800
6801
    /*  version Version
6802
     *  no header information just INTEGER */
6803
0
    sz = SetMyVersion(PKCS8v0, out + keyIdx, 0);
6804
0
    tmpSz += sz; keyIdx += sz;
6805
    /*  privateKeyAlgorithm PrivateKeyAlgorithmIdentifier */
6806
0
    sz = 0; /* set sz to 0 and get privateKey oid buffer size needed */
6807
0
    if (curveOID != NULL && oidSz > 0) {
6808
0
        byte buf[MAX_LENGTH_SZ];
6809
0
        sz = SetLength(oidSz, buf);
6810
0
        sz += 1; /* plus one for ASN object id */
6811
0
    }
6812
0
    sz = SetAlgoID(algoID, out + keyIdx, oidKeyType, oidSz + sz);
6813
0
    tmpSz += sz; keyIdx += sz;
6814
6815
    /*  privateKey          PrivateKey *
6816
     * pkcs8 ecc uses slightly different format. Places curve oid in
6817
     * buffer */
6818
0
    if (curveOID != NULL && oidSz > 0) {
6819
0
        sz = SetObjectId(oidSz, out + keyIdx);
6820
0
        keyIdx += sz; tmpSz += sz;
6821
0
        XMEMCPY(out + keyIdx, curveOID, oidSz);
6822
0
        keyIdx += oidSz; tmpSz += oidSz;
6823
0
    }
6824
6825
0
    sz = SetOctetString(keySz, out + keyIdx);
6826
0
    keyIdx += sz; tmpSz += sz;
6827
0
    XMEMCPY(out + keyIdx, key, keySz);
6828
0
    tmpSz += keySz;
6829
6830
    /*  attributes          optional
6831
     * No attributes currently added */
6832
6833
    /* rewind and add sequence */
6834
0
    sz = SetSequence(tmpSz, out);
6835
0
    XMEMMOVE(out + sz, out + MAX_SEQ_SZ, tmpSz);
6836
6837
0
    *outSz = tmpSz + sz;
6838
0
    return tmpSz + sz;
6839
#else
6840
    DECL_ASNSETDATA(dataASN, pkcs8KeyASN_Length);
6841
    int sz;
6842
    int ret = 0;
6843
    word32 keyIdx = 0;
6844
    word32 tmpAlgId = 0;
6845
6846
    WOLFSSL_ENTER("wc_CreatePKCS8Key()");
6847
6848
    /* Check validity of parameters. */
6849
    if (out == NULL && outSz != NULL) {
6850
    }
6851
    else if (key == NULL || out == NULL || outSz == NULL) {
6852
        ret = BAD_FUNC_ARG;
6853
    }
6854
6855
    /* Sanity check: make sure key doesn't have PKCS #8 header. */
6856
    if (ToTraditionalInline_ex(key, &keyIdx, keySz, &tmpAlgId) >= 0) {
6857
        (void)tmpAlgId;
6858
        ret = ASN_PARSE_E;
6859
    }
6860
6861
    CALLOC_ASNSETDATA(dataASN, pkcs8KeyASN_Length, ret, NULL);
6862
6863
    if (ret == 0) {
6864
        /* Only support default PKCS #8 format - v0. */
6865
        SetASN_Int8Bit(&dataASN[PKCS8KEYASN_IDX_VER], PKCS8v0);
6866
        /* Set key OID that corresponds to key data. */
6867
        SetASN_OID(&dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_KEY], algoID, oidKeyType);
6868
        if (curveOID != NULL && oidSz > 0) {
6869
            /* ECC key and curveOID set to write. */
6870
            SetASN_Buffer(&dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE], curveOID, oidSz);
6871
        }
6872
        else {
6873
            /* EC curve OID to encode. */
6874
            dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE].noOut = 1;
6875
        }
6876
        /* Only RSA keys have NULL tagged item after OID. */
6877
        dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].noOut = (algoID != RSAk);
6878
    #ifdef WC_RSA_PSS
6879
        dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_PARAM_SEQ].noOut = 1;
6880
    #endif
6881
        /* Set key data to encode. */
6882
        SetASN_Buffer(&dataASN[PKCS8KEYASN_IDX_PKEY_DATA], key, keySz);
6883
6884
        /* Get the size of the DER encoding. */
6885
        ret = SizeASN_Items(pkcs8KeyASN, dataASN, pkcs8KeyASN_Length, &sz);
6886
    }
6887
    if (ret == 0) {
6888
        /* Always return the calculated size. */
6889
        *outSz = sz;
6890
    }
6891
    /* Check for buffer to encoded into. */
6892
    if ((ret == 0) && (out == NULL)) {
6893
        WOLFSSL_MSG("Checking size of PKCS8");
6894
        ret = LENGTH_ONLY_E;
6895
    }
6896
    if (ret == 0) {
6897
        /*  Encode PKCS #8 key into buffer. */
6898
        SetASN_Items(pkcs8KeyASN, dataASN, pkcs8KeyASN_Length, out);
6899
        ret = sz;
6900
    }
6901
6902
    FREE_ASNSETDATA(dataASN, NULL);
6903
    return ret;
6904
#endif /* WOLFSSL_ASN_TEMPLATE */
6905
0
}
6906
6907
#endif /* HAVE_PKCS8 && !NO_CERTS */
6908
6909
#if defined(HAVE_PKCS12) || !defined(NO_CHECK_PRIVATE_KEY)
6910
/* check that the private key is a pair for the public key
6911
 * return 1 (true) on match
6912
 * return 0 or negative value on failure/error
6913
 *
6914
 * privKey   : buffer holding DER format private key
6915
 * privKeySz : size of private key buffer
6916
 * pubKey    : buffer holding DER format public key
6917
 * pubKeySz  : size of public key buffer
6918
 * ks        : type of key */
6919
int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz,
6920
                       const byte* pubKey, word32 pubKeySz, enum Key_Sum ks)
6921
0
{
6922
0
    int ret;
6923
0
    (void)privKeySz;
6924
0
    (void)pubKeySz;
6925
0
    (void)ks;
6926
6927
0
    if (privKey == NULL || pubKey == NULL) {
6928
0
        return BAD_FUNC_ARG;
6929
0
    }
6930
6931
0
    #if !defined(NO_RSA) && !defined(NO_ASN_CRYPT)
6932
    /* test if RSA key */
6933
0
    if (ks == RSAk
6934
0
    #ifdef WC_RSA_PSS
6935
0
        || ks == RSAPSSk
6936
0
    #endif
6937
0
        ) {
6938
0
    #ifdef WOLFSSL_SMALL_STACK
6939
0
        RsaKey* a;
6940
0
        RsaKey* b = NULL;
6941
    #else
6942
        RsaKey a[1], b[1];
6943
    #endif
6944
0
        word32 keyIdx = 0;
6945
6946
0
    #ifdef WOLFSSL_SMALL_STACK
6947
0
        a = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
6948
0
        if (a == NULL)
6949
0
            return MEMORY_E;
6950
0
        b = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
6951
0
        if (b == NULL) {
6952
0
            XFREE(a, NULL, DYNAMIC_TYPE_RSA);
6953
0
            return MEMORY_E;
6954
0
        }
6955
0
    #endif
6956
6957
0
        if ((ret = wc_InitRsaKey(a, NULL)) < 0) {
6958
0
    #ifdef WOLFSSL_SMALL_STACK
6959
0
            XFREE(b, NULL, DYNAMIC_TYPE_RSA);
6960
0
            XFREE(a, NULL, DYNAMIC_TYPE_RSA);
6961
0
    #endif
6962
0
            return ret;
6963
0
        }
6964
0
        if ((ret = wc_InitRsaKey(b, NULL)) < 0) {
6965
0
            wc_FreeRsaKey(a);
6966
0
    #ifdef WOLFSSL_SMALL_STACK
6967
0
            XFREE(b, NULL, DYNAMIC_TYPE_RSA);
6968
0
            XFREE(a, NULL, DYNAMIC_TYPE_RSA);
6969
0
    #endif
6970
0
            return ret;
6971
0
        }
6972
0
        if ((ret = wc_RsaPrivateKeyDecode(privKey, &keyIdx, a, privKeySz)) == 0) {
6973
0
            WOLFSSL_MSG("Checking RSA key pair");
6974
0
            keyIdx = 0; /* reset to 0 for parsing public key */
6975
6976
0
            if ((ret = wc_RsaPublicKeyDecode(pubKey, &keyIdx, b,
6977
0
                    pubKeySz)) == 0) {
6978
                /* limit for user RSA crypto because of RsaKey
6979
                 * dereference. */
6980
            #if defined(HAVE_USER_RSA)
6981
                WOLFSSL_MSG("Cannot verify RSA pair with user RSA");
6982
                ret = 1; /* return first RSA cert as match */
6983
            #else
6984
                /* both keys extracted successfully now check n and e
6985
                 * values are the same. This is dereferencing RsaKey */
6986
0
                if (mp_cmp(&(a->n), &(b->n)) != MP_EQ ||
6987
0
                    mp_cmp(&(a->e), &(b->e)) != MP_EQ) {
6988
0
                    ret = MP_CMP_E;
6989
0
                    WOLFSSL_ERROR_VERBOSE(ret);
6990
0
                }
6991
0
                else
6992
0
                    ret = 1;
6993
0
            #endif
6994
0
            }
6995
0
            else {
6996
0
                WOLFSSL_ERROR_VERBOSE(ret);
6997
0
            }
6998
0
        }
6999
0
        wc_FreeRsaKey(b);
7000
0
        wc_FreeRsaKey(a);
7001
0
    #ifdef WOLFSSL_SMALL_STACK
7002
0
        XFREE(b, NULL, DYNAMIC_TYPE_RSA);
7003
0
        XFREE(a, NULL, DYNAMIC_TYPE_RSA);
7004
0
    #endif
7005
0
    }
7006
0
    else
7007
0
    #endif /* !NO_RSA && !NO_ASN_CRYPT */
7008
7009
0
    #if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT)
7010
0
    if (ks == ECDSAk) {
7011
0
    #ifdef WOLFSSL_SMALL_STACK
7012
0
        ecc_key* key_pair;
7013
0
        byte*    privDer;
7014
    #else
7015
        ecc_key  key_pair[1];
7016
        byte     privDer[MAX_ECC_BYTES];
7017
    #endif
7018
0
        word32   privSz = MAX_ECC_BYTES;
7019
0
        word32   keyIdx = 0;
7020
7021
0
    #ifdef WOLFSSL_SMALL_STACK
7022
0
        key_pair = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
7023
0
        if (key_pair == NULL)
7024
0
            return MEMORY_E;
7025
0
        privDer = (byte*)XMALLOC(MAX_ECC_BYTES, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7026
0
        if (privDer == NULL) {
7027
0
            XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
7028
0
            return MEMORY_E;
7029
0
        }
7030
0
    #endif
7031
7032
0
        if ((ret = wc_ecc_init(key_pair)) < 0) {
7033
0
    #ifdef WOLFSSL_SMALL_STACK
7034
0
            XFREE(privDer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7035
0
            XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
7036
0
    #endif
7037
0
            return ret;
7038
0
        }
7039
7040
0
        if ((ret = wc_EccPrivateKeyDecode(privKey, &keyIdx, key_pair,
7041
0
                privKeySz)) == 0) {
7042
0
            WOLFSSL_MSG("Checking ECC key pair");
7043
7044
0
            if ((ret = wc_ecc_export_private_only(key_pair, privDer, &privSz))
7045
0
                                                                         == 0) {
7046
            #ifdef WOLFSSL_CHECK_MEM_ZERO
7047
                wc_MemZero_Add("wc_CheckPrivateKey privDer", privDer, privSz);
7048
            #endif
7049
0
                wc_ecc_free(key_pair);
7050
0
                ret = wc_ecc_init(key_pair);
7051
0
                if (ret == 0) {
7052
0
                    ret = wc_ecc_import_private_key(privDer,
7053
0
                                            privSz, pubKey,
7054
0
                                            pubKeySz, key_pair);
7055
0
                }
7056
7057
                /* public and private extracted successfully now check if is
7058
                 * a pair and also do sanity checks on key. wc_ecc_check_key
7059
                 * checks that private * base generator equals pubkey */
7060
0
                if (ret == 0) {
7061
0
                    if ((ret = wc_ecc_check_key(key_pair)) == 0) {
7062
0
                        ret = 1;
7063
0
                    }
7064
0
                    else {
7065
0
                        WOLFSSL_ERROR_VERBOSE(ret);
7066
0
                    }
7067
0
                }
7068
0
                ForceZero(privDer, privSz);
7069
0
            }
7070
0
        }
7071
0
        else {
7072
0
            WOLFSSL_ERROR_VERBOSE(ret);
7073
0
        }
7074
0
        wc_ecc_free(key_pair);
7075
0
    #ifdef WOLFSSL_SMALL_STACK
7076
0
        XFREE(privDer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7077
0
        XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
7078
    #elif defined(WOLFSSL_CHECK_MEM_ZERO)
7079
        wc_MemZero_Check(privDer, MAX_ECC_BYTES);
7080
    #endif
7081
0
    }
7082
0
    else
7083
0
    #endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT && !NO_ASN_CRYPT */
7084
7085
0
    #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) && !defined(NO_ASN_CRYPT)
7086
0
    if (ks == ED25519k) {
7087
0
    #ifdef WOLFSSL_SMALL_STACK
7088
0
        ed25519_key* key_pair;
7089
    #else
7090
        ed25519_key  key_pair[1];
7091
    #endif
7092
0
        word32       keyIdx = 0;
7093
7094
0
    #ifdef WOLFSSL_SMALL_STACK
7095
0
        key_pair = (ed25519_key*)XMALLOC(sizeof(ed25519_key), NULL,
7096
0
                                                          DYNAMIC_TYPE_ED25519);
7097
0
        if (key_pair == NULL)
7098
0
            return MEMORY_E;
7099
0
    #endif
7100
7101
0
        if ((ret = wc_ed25519_init(key_pair)) < 0) {
7102
0
    #ifdef WOLFSSL_SMALL_STACK
7103
0
            XFREE(key_pair, NULL, DYNAMIC_TYPE_ED25519);
7104
0
    #endif
7105
0
            return ret;
7106
0
        }
7107
0
        if ((ret = wc_Ed25519PrivateKeyDecode(privKey, &keyIdx, key_pair,
7108
0
                privKeySz)) == 0) {
7109
0
            WOLFSSL_MSG("Checking ED25519 key pair");
7110
0
            keyIdx = 0;
7111
0
            if ((ret = wc_ed25519_import_public(pubKey, pubKeySz,
7112
0
                    key_pair)) == 0) {
7113
                /* public and private extracted successfully no check if is
7114
                 * a pair and also do sanity checks on key. wc_ecc_check_key
7115
                 * checks that private * base generator equals pubkey */
7116
0
                if ((ret = wc_ed25519_check_key(key_pair)) == 0) {
7117
0
                    ret = 1;
7118
0
                }
7119
0
                else {
7120
0
                    WOLFSSL_ERROR_VERBOSE(ret);
7121
0
                }
7122
0
            }
7123
0
        }
7124
0
        else {
7125
0
            WOLFSSL_ERROR_VERBOSE(ret);
7126
0
        }
7127
0
        wc_ed25519_free(key_pair);
7128
0
    #ifdef WOLFSSL_SMALL_STACK
7129
0
        XFREE(key_pair, NULL, DYNAMIC_TYPE_ED25519);
7130
0
    #endif
7131
0
    }
7132
0
    else
7133
0
    #endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT && !NO_ASN_CRYPT */
7134
7135
0
    #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) && !defined(NO_ASN_CRYPT)
7136
0
    if (ks == ED448k) {
7137
0
    #ifdef WOLFSSL_SMALL_STACK
7138
0
        ed448_key* key_pair = NULL;
7139
    #else
7140
        ed448_key  key_pair[1];
7141
    #endif
7142
0
        word32     keyIdx = 0;
7143
7144
0
    #ifdef WOLFSSL_SMALL_STACK
7145
0
        key_pair = (ed448_key*)XMALLOC(sizeof(ed448_key), NULL,
7146
0
                                                            DYNAMIC_TYPE_ED448);
7147
0
        if (key_pair == NULL)
7148
0
            return MEMORY_E;
7149
0
    #endif
7150
7151
0
        if ((ret = wc_ed448_init(key_pair)) < 0) {
7152
0
    #ifdef WOLFSSL_SMALL_STACK
7153
0
            XFREE(key_pair, NULL, DYNAMIC_TYPE_ED448);
7154
0
    #endif
7155
0
            return ret;
7156
0
        }
7157
0
        if ((ret = wc_Ed448PrivateKeyDecode(privKey, &keyIdx, key_pair,
7158
0
                privKeySz)) == 0) {
7159
0
            WOLFSSL_MSG("Checking ED448 key pair");
7160
0
            keyIdx = 0;
7161
0
            if ((ret = wc_ed448_import_public(pubKey, pubKeySz,
7162
0
                    key_pair)) == 0) {
7163
                /* public and private extracted successfully no check if is
7164
                 * a pair and also do sanity checks on key. wc_ecc_check_key
7165
                 * checks that private * base generator equals pubkey */
7166
0
                if ((ret = wc_ed448_check_key(key_pair)) == 0) {
7167
0
                    ret = 1;
7168
0
                }
7169
0
                else {
7170
0
                    WOLFSSL_ERROR_VERBOSE(ret);
7171
0
                }
7172
0
            }
7173
0
        }
7174
0
        else {
7175
0
            WOLFSSL_ERROR_VERBOSE(ret);
7176
0
        }
7177
0
        wc_ed448_free(key_pair);
7178
0
    #ifdef WOLFSSL_SMALL_STACK
7179
0
        XFREE(key_pair, NULL, DYNAMIC_TYPE_ED448);
7180
0
    #endif
7181
0
    }
7182
0
    else
7183
0
    #endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT && !NO_ASN_CRYPT */
7184
    #if defined(HAVE_PQC)
7185
    #if defined(HAVE_FALCON)
7186
    if ((ks == FALCON_LEVEL1k) || (ks == FALCON_LEVEL5k)) {
7187
    #ifdef WOLFSSL_SMALL_STACK
7188
        falcon_key* key_pair = NULL;
7189
    #else
7190
        falcon_key  key_pair[1];
7191
    #endif
7192
        word32     keyIdx = 0;
7193
7194
    #ifdef WOLFSSL_SMALL_STACK
7195
        key_pair = (falcon_key*)XMALLOC(sizeof(falcon_key), NULL,
7196
                                        DYNAMIC_TYPE_FALCON);
7197
        if (key_pair == NULL)
7198
            return MEMORY_E;
7199
    #endif
7200
        ret = wc_falcon_init(key_pair);
7201
        if (ret  < 0) {
7202
    #ifdef WOLFSSL_SMALL_STACK
7203
            XFREE(key_pair, NULL, DYNAMIC_TYPE_FALCON);
7204
    #endif
7205
            return ret;
7206
        }
7207
7208
        if (ks == FALCON_LEVEL1k) {
7209
            ret = wc_falcon_set_level(key_pair, 1);
7210
        }
7211
        else if (ks == FALCON_LEVEL5k) {
7212
            ret = wc_falcon_set_level(key_pair, 5);
7213
        }
7214
7215
        if (ret  < 0) {
7216
    #ifdef WOLFSSL_SMALL_STACK
7217
            XFREE(key_pair, NULL, DYNAMIC_TYPE_FALCON);
7218
    #endif
7219
            return ret;
7220
        }
7221
        if ((ret = wc_Falcon_PrivateKeyDecode(privKey, &keyIdx, key_pair,
7222
                                             privKeySz)) == 0) {
7223
            WOLFSSL_MSG("Checking Falcon_ key pair");
7224
            keyIdx = 0;
7225
            if ((ret = wc_falcon_import_public(pubKey, pubKeySz,
7226
                                               key_pair)) == 0) {
7227
                /* Public and private extracted successfully. Sanity check. */
7228
                if ((ret = wc_falcon_check_key(key_pair)) == 0) {
7229
                    ret = 1;
7230
                }
7231
                else {
7232
                    WOLFSSL_ERROR_VERBOSE(ret);
7233
                }
7234
            }
7235
        }
7236
        else {
7237
            WOLFSSL_ERROR_VERBOSE(ret);
7238
        }
7239
        wc_falcon_free(key_pair);
7240
    #ifdef WOLFSSL_SMALL_STACK
7241
        XFREE(key_pair, NULL, DYNAMIC_TYPE_FALCON);
7242
    #endif
7243
    }
7244
    else
7245
    #endif /* HAVE_FALCON */
7246
    #if defined(HAVE_DILITHIUM)
7247
    if ((ks == DILITHIUM_LEVEL2k) ||
7248
        (ks == DILITHIUM_LEVEL3k) ||
7249
        (ks == DILITHIUM_LEVEL5k) ||
7250
        (ks == DILITHIUM_AES_LEVEL2k) ||
7251
        (ks == DILITHIUM_AES_LEVEL3k) ||
7252
        (ks == DILITHIUM_AES_LEVEL5k)) {
7253
    #ifdef WOLFSSL_SMALL_STACK
7254
        dilithium_key* key_pair = NULL;
7255
    #else
7256
        dilithium_key  key_pair[1];
7257
    #endif
7258
        word32     keyIdx = 0;
7259
7260
    #ifdef WOLFSSL_SMALL_STACK
7261
        key_pair = (dilithium_key*)XMALLOC(sizeof(dilithium_key), NULL,
7262
                                        DYNAMIC_TYPE_DILITHIUM);
7263
        if (key_pair == NULL)
7264
            return MEMORY_E;
7265
    #endif
7266
        ret = wc_dilithium_init(key_pair);
7267
        if (ret  < 0) {
7268
    #ifdef WOLFSSL_SMALL_STACK
7269
            XFREE(key_pair, NULL, DYNAMIC_TYPE_DILITHIUM);
7270
    #endif
7271
            return ret;
7272
        }
7273
7274
        if (ks == DILITHIUM_LEVEL2k) {
7275
            ret = wc_dilithium_set_level_and_sym(key_pair, 2, SHAKE_VARIANT);
7276
        }
7277
        else if (ks == DILITHIUM_LEVEL3k) {
7278
            ret = wc_dilithium_set_level_and_sym(key_pair, 3, SHAKE_VARIANT);
7279
        }
7280
        else if (ks == DILITHIUM_LEVEL5k) {
7281
            ret = wc_dilithium_set_level_and_sym(key_pair, 5, SHAKE_VARIANT);
7282
        }
7283
        else if (ks == DILITHIUM_AES_LEVEL2k) {
7284
            ret = wc_dilithium_set_level_and_sym(key_pair, 2, AES_VARIANT);
7285
        }
7286
        else if (ks == DILITHIUM_AES_LEVEL3k) {
7287
            ret = wc_dilithium_set_level_and_sym(key_pair, 3, AES_VARIANT);
7288
        }
7289
        else if (ks == DILITHIUM_AES_LEVEL5k) {
7290
            ret = wc_dilithium_set_level_and_sym(key_pair, 5, AES_VARIANT);
7291
        }
7292
7293
        if (ret  < 0) {
7294
    #ifdef WOLFSSL_SMALL_STACK
7295
            XFREE(key_pair, NULL, DYNAMIC_TYPE_DILITHIUM);
7296
    #endif
7297
            return ret;
7298
        }
7299
        if ((ret = wc_Dilithium_PrivateKeyDecode(privKey, &keyIdx, key_pair,
7300
                                             privKeySz)) == 0) {
7301
            WOLFSSL_MSG("Checking Dilithium_ key pair");
7302
            keyIdx = 0;
7303
            if ((ret = wc_dilithium_import_public(pubKey, pubKeySz,
7304
                                               key_pair)) == 0) {
7305
                /* Public and private extracted successfully. Sanity check. */
7306
                if ((ret = wc_dilithium_check_key(key_pair)) == 0)
7307
                    ret = 1;
7308
            }
7309
        }
7310
        wc_dilithium_free(key_pair);
7311
    #ifdef WOLFSSL_SMALL_STACK
7312
        XFREE(key_pair, NULL, DYNAMIC_TYPE_DILITHIUM);
7313
    #endif
7314
    }
7315
    else
7316
    #endif /* HAVE_DILITHIUM */
7317
    #endif /* HAVE_PQC */
7318
0
    {
7319
0
        ret = 0;
7320
0
    }
7321
0
    (void)ks;
7322
7323
0
    return ret;
7324
0
}
7325
7326
/* check that the private key is a pair for the public key in certificate
7327
 * return 1 (true) on match
7328
 * return 0 or negative value on failure/error
7329
 *
7330
 * key   : buffer holding DER format key
7331
 * keySz : size of key buffer
7332
 * der   : a initialized and parsed DecodedCert holding a certificate */
7333
int wc_CheckPrivateKeyCert(const byte* key, word32 keySz, DecodedCert* der)
7334
0
{
7335
0
    if (key == NULL || der == NULL) {
7336
0
        return BAD_FUNC_ARG;
7337
0
    }
7338
7339
0
    return wc_CheckPrivateKey(key, keySz, der->publicKey,
7340
0
            der->pubKeySize, (enum Key_Sum) der->keyOID);
7341
0
}
7342
7343
#endif /* HAVE_PKCS12 || !NO_CHECK_PRIVATE_KEY */
7344
7345
#ifndef NO_PWDBASED
7346
7347
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
7348
/* Check the PBE algorithm is supported and return wolfSSL id, version and block
7349
 * size of encryption algorithm.
7350
 *
7351
 * When PBES2, version is PKCS5v2, CheckAlgoV2() must be called to get id and
7352
 * blockSz based on encryption algorithm.
7353
 *
7354
 * @param [in]  first    First byte of OID to use in check.
7355
 * @param [in]  second   Second byte of OID to use in check.
7356
 * @param [out] id       wolfSSL id for PBE algorithm.
7357
 * @param [out] version  Version of PBE OID:
7358
 *                       PKCS12v1 (PBE), PKCS5 (PBES1), PKCS5v2 (PBES2).
7359
 * @param [out] blockSz  Block size of encryption algorithm.
7360
 * @return  0 on success.
7361
 * @return  ALGO_ID_E when OID not supported.
7362
 * @return  ASN_INPUT_E when first byte is invalid.
7363
 */
7364
static int CheckAlgo(int first, int second, int* id, int* version, int* blockSz)
7365
0
{
7366
0
    int ret = 0;
7367
7368
0
    (void)id;
7369
0
    (void)blockSz;
7370
7371
0
    *version = -1;
7372
7373
    /* pkcs-12 1 = pkcs-12PbeIds */
7374
0
    if (first == 1) {
7375
        /* PKCS #12: Appendix C */
7376
0
        switch (second) {
7377
0
#if !defined(NO_SHA)
7378
0
    #ifndef NO_RC4
7379
0
        case PBE_SHA1_RC4_128:
7380
0
            *id = PBE_SHA1_RC4_128;
7381
0
            *version = PKCS12v1;
7382
0
            if (blockSz != NULL) {
7383
0
                *blockSz = 1;
7384
0
            }
7385
0
            break;
7386
0
    #endif
7387
0
    #ifndef NO_DES3
7388
0
        case PBE_SHA1_DES3:
7389
0
            *id = PBE_SHA1_DES3;
7390
0
            *version = PKCS12v1;
7391
0
            if (blockSz != NULL) {
7392
0
                *blockSz = DES_BLOCK_SIZE;
7393
0
            }
7394
0
            break;
7395
0
    #endif
7396
    #ifdef WC_RC2
7397
        case PBE_SHA1_40RC2_CBC:
7398
            *id = PBE_SHA1_40RC2_CBC;
7399
            *version = PKCS12v1;
7400
            if (blockSz != NULL) {
7401
                *blockSz = RC2_BLOCK_SIZE;
7402
            }
7403
            break;
7404
    #endif
7405
0
#endif /* !NO_SHA */
7406
0
        default:
7407
0
            ret = ALGO_ID_E;
7408
0
            break;
7409
0
        }
7410
0
    }
7411
0
    else if (first != PKCS5) {
7412
        /* Bad OID. */
7413
0
        ret = ASN_INPUT_E;
7414
0
    }
7415
    /* PKCS #5 PBES2: Appendix A.4
7416
     * pkcs-5 13 = id-PBES2 */
7417
0
    else if (second == PBES2) {
7418
0
        *version = PKCS5v2;
7419
        /* Id and block size come from CheckAlgoV2() */
7420
0
    }
7421
0
    else  {
7422
        /* PKCS #5 PBES1: Appendix A.3 */
7423
        /* see RFC 2898 for ids */
7424
0
        switch (second) {
7425
0
    #ifndef NO_DES3
7426
0
        #ifndef NO_MD5
7427
0
        case PBES1_MD5_DES:
7428
0
            *id = PBE_MD5_DES;
7429
0
            *version = PKCS5;
7430
0
            if (blockSz != NULL) {
7431
0
                *blockSz = DES_BLOCK_SIZE;
7432
0
            }
7433
0
            break;
7434
0
        #endif
7435
0
        #ifndef NO_SHA
7436
0
        case PBES1_SHA1_DES:
7437
0
            *id = PBE_SHA1_DES;
7438
0
            *version = PKCS5;
7439
0
            if (blockSz != NULL) {
7440
0
                *blockSz = DES_BLOCK_SIZE;
7441
0
            }
7442
0
            break;
7443
0
        #endif
7444
0
    #endif /* !NO_DES3 */
7445
0
        default:
7446
0
            ret = ALGO_ID_E;
7447
0
            break;
7448
0
        }
7449
0
    }
7450
7451
    /* Return error code. */
7452
0
    return ret;
7453
0
}
7454
7455
#endif /* HAVE_PKCS8 || HAVE_PKCS12 */
7456
7457
#ifdef HAVE_PKCS8
7458
7459
/* Check the encryption algorithm with PBES2 is supported and return block size
7460
 * and wolfSSL id for the PBE.
7461
 *
7462
 * @param [in]  oid      Encryption algorithm OID id.
7463
 * @param [out] id       wolfSSL id for PBE algorithm.
7464
 * @param [out] version  Version of PBE OID:
7465
 *                       PKCS12v1 (PBE), PKCS5 (PBES1), PKCS5v2 (PBES2).
7466
 * @return  0 on success.
7467
 * @return  ALGO_ID_E when encryption algorithm is not supported with PBES2.
7468
 */
7469
static int CheckAlgoV2(int oid, int* id, int* blockSz)
7470
0
{
7471
0
    int ret = 0;
7472
7473
0
    (void)id;
7474
0
    (void)blockSz;
7475
7476
0
    switch (oid) {
7477
0
#if !defined(NO_DES3) && !defined(NO_SHA)
7478
0
    case DESb:
7479
0
        *id = PBE_SHA1_DES;
7480
0
        if (blockSz != NULL) {
7481
0
            *blockSz = DES_BLOCK_SIZE;
7482
0
        }
7483
0
        break;
7484
0
    case DES3b:
7485
0
        *id = PBE_SHA1_DES3;
7486
0
        if (blockSz != NULL) {
7487
0
            *blockSz = DES_BLOCK_SIZE;
7488
0
        }
7489
0
        break;
7490
0
#endif
7491
0
#ifdef WOLFSSL_AES_256
7492
0
    case AES256CBCb:
7493
0
        *id = PBE_AES256_CBC;
7494
0
        if (blockSz != NULL) {
7495
0
            *blockSz = AES_BLOCK_SIZE;
7496
0
        }
7497
0
        break;
7498
0
#endif
7499
0
#ifdef WOLFSSL_AES_128
7500
0
    case AES128CBCb:
7501
0
        *id = PBE_AES128_CBC;
7502
0
        if (blockSz != NULL) {
7503
0
            *blockSz = AES_BLOCK_SIZE;
7504
0
        }
7505
0
        break;
7506
0
#endif
7507
0
    default:
7508
0
        WOLFSSL_MSG("No PKCS v2 algo found");
7509
0
        ret = ALGO_ID_E;
7510
0
        break;
7511
0
    }
7512
7513
    /* Return error code. */
7514
0
    return ret;
7515
0
}
7516
7517
#endif /* HAVE_PKCS8 */
7518
7519
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
7520
7521
int wc_GetKeyOID(byte* key, word32 keySz, const byte** curveOID, word32* oidSz,
7522
        int* algoID, void* heap)
7523
0
{
7524
0
    word32 tmpIdx = 0;
7525
7526
0
    if (key == NULL || algoID == NULL)
7527
0
        return BAD_FUNC_ARG;
7528
7529
0
    *algoID = 0;
7530
7531
0
    #if !defined(NO_RSA) && !defined(NO_ASN_CRYPT)
7532
0
    {
7533
0
        RsaKey *rsa = (RsaKey *)XMALLOC(sizeof *rsa, heap, DYNAMIC_TYPE_TMP_BUFFER);
7534
0
        if (rsa == NULL)
7535
0
            return MEMORY_E;
7536
7537
0
        wc_InitRsaKey(rsa, heap);
7538
0
        if (wc_RsaPrivateKeyDecode(key, &tmpIdx, rsa, keySz) == 0) {
7539
0
            *algoID = RSAk;
7540
0
        }
7541
0
        else {
7542
0
            WOLFSSL_MSG("Not RSA DER key");
7543
0
        }
7544
0
        wc_FreeRsaKey(rsa);
7545
0
        XFREE(rsa, heap, DYNAMIC_TYPE_TMP_BUFFER);
7546
0
    }
7547
0
    #endif /* !NO_RSA && !NO_ASN_CRYPT */
7548
0
    #if defined(HAVE_ECC) && !defined(NO_ASN_CRYPT)
7549
0
    if (*algoID == 0) {
7550
0
        ecc_key *ecc = (ecc_key *)XMALLOC(sizeof *ecc, heap, DYNAMIC_TYPE_TMP_BUFFER);
7551
0
        if (ecc == NULL)
7552
0
            return MEMORY_E;
7553
7554
0
        tmpIdx = 0;
7555
0
        wc_ecc_init_ex(ecc, heap, INVALID_DEVID);
7556
0
        if (wc_EccPrivateKeyDecode(key, &tmpIdx, ecc, keySz) == 0) {
7557
0
            *algoID = ECDSAk;
7558
7559
            /* now find oid */
7560
0
            if (wc_ecc_get_oid(ecc->dp->oidSum, curveOID, oidSz) < 0) {
7561
0
                WOLFSSL_MSG("Error getting ECC curve OID");
7562
0
                wc_ecc_free(ecc);
7563
0
                XFREE(ecc, heap, DYNAMIC_TYPE_TMP_BUFFER);
7564
0
                return BAD_FUNC_ARG;
7565
0
            }
7566
0
        }
7567
0
        else {
7568
0
            WOLFSSL_MSG("Not ECC DER key either");
7569
0
        }
7570
0
        wc_ecc_free(ecc);
7571
0
        XFREE(ecc, heap, DYNAMIC_TYPE_TMP_BUFFER);
7572
0
    }
7573
0
#endif /* HAVE_ECC && !NO_ASN_CRYPT */
7574
0
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) && !defined(NO_ASN_CRYPT)
7575
0
    if (*algoID == 0) {
7576
0
        ed25519_key *ed25519 = (ed25519_key *)XMALLOC(sizeof *ed25519, heap,
7577
0
            DYNAMIC_TYPE_TMP_BUFFER);
7578
0
        if (ed25519 == NULL)
7579
0
            return MEMORY_E;
7580
7581
0
        tmpIdx = 0;
7582
0
        if (wc_ed25519_init_ex(ed25519, heap, INVALID_DEVID) == 0) {
7583
0
            if (wc_Ed25519PrivateKeyDecode(key, &tmpIdx, ed25519, keySz) == 0) {
7584
0
                *algoID = ED25519k;
7585
0
            }
7586
0
            else {
7587
0
                WOLFSSL_MSG("Not ED25519 DER key");
7588
0
            }
7589
0
            wc_ed25519_free(ed25519);
7590
0
        }
7591
0
        else {
7592
0
            WOLFSSL_MSG("GetKeyOID wc_ed25519_init failed");
7593
0
        }
7594
0
        XFREE(ed25519, heap, DYNAMIC_TYPE_TMP_BUFFER);
7595
0
    }
7596
0
#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT && !NO_ASN_CRYPT */
7597
0
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) && !defined(NO_ASN_CRYPT)
7598
0
    if (*algoID == 0) {
7599
0
        ed448_key *ed448 = (ed448_key *)XMALLOC(sizeof *ed448, heap,
7600
0
            DYNAMIC_TYPE_TMP_BUFFER);
7601
0
        if (ed448 == NULL)
7602
0
            return MEMORY_E;
7603
7604
0
        tmpIdx = 0;
7605
0
        if (wc_ed448_init(ed448) == 0) {
7606
0
            if (wc_Ed448PrivateKeyDecode(key, &tmpIdx, ed448, keySz) == 0) {
7607
0
                *algoID = ED448k;
7608
0
            }
7609
0
            else {
7610
0
                WOLFSSL_MSG("Not ED448 DER key");
7611
0
            }
7612
0
            wc_ed448_free(ed448);
7613
0
        }
7614
0
        else {
7615
0
            WOLFSSL_MSG("GetKeyOID wc_ed448_init failed");
7616
0
        }
7617
0
        XFREE(ed448, heap, DYNAMIC_TYPE_TMP_BUFFER);
7618
0
    }
7619
0
#endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT && !NO_ASN_CRYPT */
7620
#if defined(HAVE_PQC)
7621
#if defined(HAVE_FALCON)
7622
    if (*algoID == 0) {
7623
        falcon_key *falcon = (falcon_key *)XMALLOC(sizeof(*falcon), heap,
7624
            DYNAMIC_TYPE_TMP_BUFFER);
7625
        if (falcon == NULL)
7626
            return MEMORY_E;
7627
7628
        if (wc_falcon_init(falcon) != 0) {
7629
            tmpIdx = 0;
7630
            if (wc_falcon_set_level(falcon, 1) == 0) {
7631
                if (wc_Falcon_PrivateKeyDecode(key, &tmpIdx, falcon, keySz)
7632
                    == 0) {
7633
                    *algoID = FALCON_LEVEL1k;
7634
                }
7635
                else {
7636
                    WOLFSSL_MSG("Not Falcon Level 1 DER key");
7637
                }
7638
            }
7639
            else if (wc_falcon_set_level(falcon, 5) == 0) {
7640
                if (wc_Falcon_PrivateKeyDecode(key, &tmpIdx, falcon, keySz)
7641
                    == 0) {
7642
                    *algoID = FALCON_LEVEL5k;
7643
                }
7644
                else {
7645
                    WOLFSSL_MSG("Not Falcon Level 5 DER key");
7646
                }
7647
            }
7648
            else {
7649
                WOLFSSL_MSG("GetKeyOID falcon initialization failed");
7650
            }
7651
            wc_falcon_free(falcon);
7652
        }
7653
        XFREE(falcon, heap, DYNAMIC_TYPE_TMP_BUFFER);
7654
    }
7655
#endif /* HAVE_FALCON */
7656
#if defined(HAVE_DILITHIUM)
7657
    if (*algoID == 0) {
7658
        dilithium_key *dilithium = (dilithium_key *)XMALLOC(sizeof(*dilithium),
7659
             heap, DYNAMIC_TYPE_TMP_BUFFER);
7660
        if (dilithium == NULL)
7661
            return MEMORY_E;
7662
7663
        if (wc_dilithium_init(dilithium) != 0) {
7664
            tmpIdx = 0;
7665
            if (wc_dilithium_set_level_and_sym(dilithium, 2, SHAKE_VARIANT)
7666
                == 0) {
7667
                if (wc_Dilithium_PrivateKeyDecode(key, &tmpIdx, dilithium,
7668
                    keySz) == 0) {
7669
                    *algoID = DILITHIUM_LEVEL2k;
7670
                }
7671
                else {
7672
                    WOLFSSL_MSG("Not Dilithium Level 2 DER key");
7673
                }
7674
            }
7675
            else if (wc_dilithium_set_level_and_sym(dilithium, 3, SHAKE_VARIANT)
7676
                == 0) {
7677
                if (wc_Dilithium_PrivateKeyDecode(key, &tmpIdx, dilithium,
7678
                    keySz) == 0) {
7679
                    *algoID = DILITHIUM_LEVEL3k;
7680
                }
7681
                else {
7682
                    WOLFSSL_MSG("Not Dilithium Level 3 DER key");
7683
                }
7684
            }
7685
            else if (wc_dilithium_set_level_and_sym(dilithium, 5, SHAKE_VARIANT)
7686
                == 0) {
7687
                if (wc_Dilithium_PrivateKeyDecode(key, &tmpIdx, dilithium,
7688
                    keySz) == 0) {
7689
                    *algoID = DILITHIUM_LEVEL5k;
7690
                }
7691
                else {
7692
                    WOLFSSL_MSG("Not Dilithium Level 5 DER key");
7693
                }
7694
            }
7695
            else if (wc_dilithium_set_level_and_sym(dilithium, 2, AES_VARIANT)
7696
                == 0) {
7697
                if (wc_Dilithium_PrivateKeyDecode(key, &tmpIdx, dilithium,
7698
                    keySz) == 0) {
7699
                    *algoID = DILITHIUM_AES_LEVEL2k;
7700
                }
7701
                else {
7702
                    WOLFSSL_MSG("Not Dilithium AES Level 2 DER key");
7703
                }
7704
            }
7705
            else if (wc_dilithium_set_level_and_sym(dilithium, 3, AES_VARIANT)
7706
                == 0) {
7707
                if (wc_Dilithium_PrivateKeyDecode(key, &tmpIdx, dilithium,
7708
                    keySz) == 0) {
7709
                    *algoID = DILITHIUM_AES_LEVEL3k;
7710
                }
7711
                else {
7712
                    WOLFSSL_MSG("Not Dilithium AES Level 3 DER key");
7713
                }
7714
            }
7715
            else if (wc_dilithium_set_level_and_sym(dilithium, 5, AES_VARIANT)
7716
                == 0) {
7717
                if (wc_Dilithium_PrivateKeyDecode(key, &tmpIdx, dilithium,
7718
                    keySz) == 0) {
7719
                    *algoID = DILITHIUM_AES_LEVEL5k;
7720
                }
7721
                else {
7722
                    WOLFSSL_MSG("Not Dilithium AES Level 5 DER key");
7723
                }
7724
            }
7725
            else {
7726
                WOLFSSL_MSG("GetKeyOID dilithium initialization failed");
7727
            }
7728
            wc_dilithium_free(dilithium);
7729
        }
7730
        XFREE(dilithium, heap, DYNAMIC_TYPE_TMP_BUFFER);
7731
    }
7732
#endif /* HAVE_DILITHIUM */
7733
#endif /* HAVE_PQC */
7734
7735
    /* if flag is not set then this is not a key that we understand. */
7736
0
    if (*algoID == 0) {
7737
0
        WOLFSSL_MSG("Bad key DER or compile options");
7738
0
        return BAD_FUNC_ARG;
7739
0
    }
7740
7741
0
    (void)tmpIdx;
7742
0
    (void)curveOID;
7743
0
    (void)oidSz;
7744
0
    (void)keySz;
7745
0
    (void)heap;
7746
7747
0
    return 1;
7748
0
}
7749
7750
#endif /* HAVE_PKCS8 || HAVE_PKCS12 */
7751
7752
#ifdef WOLFSSL_ASN_TEMPLATE
7753
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
7754
/* ASN.1 template for PBES2 parameters.
7755
 * PKCS #5: RFC 8018, A.4 - PBES2-params without outer SEQUENCE
7756
 *                    A.2 - PBKDF2-params
7757
 *                    B.2 - Encryption schemes
7758
 *                    C   - AlgorithmIdentifier
7759
 */
7760
static const ASNItem pbes2ParamsASN[] = {
7761
/* KDF_SEQ                */ { 0, ASN_SEQUENCE, 1, 1, 0 },
7762
               /* PBKDF2 */
7763
/* KDF_OID                */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
7764
/* PBKDF2_PARAMS_SEQ      */     { 1, ASN_SEQUENCE, 1, 1, 0 },
7765
                   /* Salt */
7766
/* PBKDF2_PARAMS_SALT     */         { 2, ASN_OCTET_STRING, 0, 0, 0 },
7767
                   /* Iteration count */
7768
/* PBKDF2_PARAMS_ITER     */         { 2, ASN_INTEGER, 0, 0, 0 },
7769
                   /* Key length */
7770
/* PBKDF2_PARAMS_KEYLEN   */         { 2, ASN_INTEGER, 0, 0, 1 },
7771
                   /* PRF - default is HMAC-SHA1 */
7772
/* PBKDF2_PARAMS_PRF      */         { 2, ASN_SEQUENCE, 1, 1, 1 },
7773
/* PBKDF2_PARAMS_PRF_OID  */             { 3, ASN_OBJECT_ID, 0, 0, 0 },
7774
/* PBKDF2_PARAMS_PRF_NULL */             { 3, ASN_TAG_NULL, 0, 0, 1 },
7775
/* ENCS_SEQ               */ { 0, ASN_SEQUENCE, 1, 1, 0 },
7776
                   /* Encryption algorithm */
7777
/* ENCS_OID               */   { 1, ASN_OBJECT_ID, 0, 0, 0 },
7778
                   /* IV for CBC */
7779
/* ENCS_PARAMS            */   { 1, ASN_OCTET_STRING, 0, 0, 0 },
7780
};
7781
enum {
7782
    PBES2PARAMSASN_IDX_KDF_SEQ = 0,
7783
    PBES2PARAMSASN_IDX_KDF_OID,
7784
    PBES2PARAMSASN_IDX_PBKDF2_PARAMS_SEQ,
7785
    PBES2PARAMSASN_IDX_PBKDF2_PARAMS_SALT,
7786
    PBES2PARAMSASN_IDX_PBKDF2_PARAMS_ITER,
7787
    PBES2PARAMSASN_IDX_PBKDF2_PARAMS_KEYLEN,
7788
    PBES2PARAMSASN_IDX_PBKDF2_PARAMS_PRF,
7789
    PBES2PARAMSASN_IDX_PBKDF2_PARAMS_PRF_OID,
7790
    PBES2PARAMSASN_IDX_PBKDF2_PARAMS_PRF_NULL,
7791
    PBES2PARAMSASN_IDX_ENCS_SEQ,
7792
    PBES2PARAMSASN_IDX_ENCS_OID,
7793
    PBES2PARAMSASN_IDX_ENCS_PARAMS,
7794
};
7795
7796
/* Number of items in ASN.1 template for PBES2 parameters. */
7797
#define pbes2ParamsASN_Length (sizeof(pbes2ParamsASN) / sizeof(ASNItem))
7798
7799
/* ASN.1 template for PBES1 parameters.
7800
 * PKCS #5: RFC 8018, A.3. - PBEParameter without outer SEQUENCE
7801
 */
7802
static const ASNItem pbes1ParamsASN[] = {
7803
            /* Salt */
7804
/* SALT */    { 0, ASN_OCTET_STRING, 0, 0, 0 },
7805
            /* Iteration count */
7806
/* ITER */    { 0, ASN_INTEGER, 0, 0, 0 },
7807
};
7808
enum {
7809
    PBES1PARAMSASN_IDX_SALT = 0,
7810
    PBES1PARAMSASN_IDX_ITER,
7811
};
7812
7813
/* Number of items in ASN.1 template for PBES1 parameters. */
7814
#define pbes1ParamsASN_Length (sizeof(pbes1ParamsASN) / sizeof(ASNItem))
7815
#endif /* HAVE_PKCS8 || HAVE_PKCS12 */
7816
#endif /* WOLFSSL_ASN_TEMPLATE */
7817
7818
#ifdef HAVE_PKCS8
7819
7820
/*
7821
 * Equivalent to calling TraditionalEnc with the same parameters but with
7822
 * encAlgId set to 0. This function must be kept alive because it's sometimes
7823
 * part of the API (WOLFSSL_ASN_API).
7824
 */
7825
int UnTraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz,
7826
        const char* password, int passwordSz, int vPKCS, int vAlgo,
7827
        byte* salt, word32 saltSz, int itt, WC_RNG* rng, void* heap)
7828
0
{
7829
0
    return TraditionalEnc(key, keySz, out, outSz, password, passwordSz,
7830
0
                vPKCS, vAlgo, 0, salt, saltSz, itt, rng, heap);
7831
0
}
7832
7833
static int GetAlgoV2(int encAlgId, const byte** oid, int *len, int* id,
7834
                     int *blkSz)
7835
0
{
7836
0
    int ret = 0;
7837
7838
0
    switch (encAlgId) {
7839
0
#if !defined(NO_DES3) && !defined(NO_SHA)
7840
0
    case DESb:
7841
0
        *len = sizeof(blkDesCbcOid);
7842
0
        *oid = blkDesCbcOid;
7843
0
        *id = PBE_SHA1_DES;
7844
0
        *blkSz = 8;
7845
0
        break;
7846
0
    case DES3b:
7847
0
        *len = sizeof(blkDes3CbcOid);
7848
0
        *oid = blkDes3CbcOid;
7849
0
        *id = PBE_SHA1_DES3;
7850
0
        *blkSz = 8;
7851
0
        break;
7852
0
#endif
7853
0
#if defined(WOLFSSL_AES_256) && defined(HAVE_AES_CBC)
7854
0
    case AES256CBCb:
7855
0
        *len = sizeof(blkAes256CbcOid);
7856
0
        *oid = blkAes256CbcOid;
7857
0
        *id = PBE_AES256_CBC;
7858
0
        *blkSz = 16;
7859
0
        break;
7860
0
#endif
7861
0
    default:
7862
0
        (void)len;
7863
0
        (void)oid;
7864
0
        (void)id;
7865
0
        (void)blkSz;
7866
0
        ret = ALGO_ID_E;
7867
0
    }
7868
7869
0
    return ret;
7870
0
}
7871
7872
int wc_EncryptPKCS8Key(byte* key, word32 keySz, byte* out, word32* outSz,
7873
        const char* password, int passwordSz, int vPKCS, int pbeOid,
7874
        int encAlgId, byte* salt, word32 saltSz, int itt, WC_RNG* rng,
7875
        void* heap)
7876
0
{
7877
0
#ifdef WOLFSSL_SMALL_STACK
7878
0
    byte* saltTmp = NULL;
7879
#else
7880
    byte saltTmp[MAX_SALT_SIZE];
7881
#endif
7882
0
    int genSalt = 0;
7883
0
    int ret = 0;
7884
0
    int version = 0;
7885
0
    int pbeId = 0;
7886
0
    int blockSz = 0;
7887
0
    const byte* encOid = NULL;
7888
0
    int encOidSz = 0;
7889
0
    word32 padSz = 0;
7890
0
    word32 innerLen = 0;
7891
0
    word32 outerLen = 0;
7892
0
    const byte* pbeOidBuf = NULL;
7893
0
    word32 pbeOidBufSz = 0;
7894
0
    word32 pbeLen = 0;
7895
0
    word32 kdfLen = 0;
7896
0
    word32 encLen = 0;
7897
0
    byte cbcIv[MAX_IV_SIZE];
7898
0
    word32 idx = 0;
7899
0
    word32 encIdx = 0;
7900
7901
0
    (void)heap;
7902
7903
0
    WOLFSSL_ENTER("wc_EncryptPKCS8Key");
7904
7905
0
    if (key == NULL || outSz == NULL || password == NULL) {
7906
0
        ret = BAD_FUNC_ARG;
7907
0
    }
7908
7909
0
    if (ret == 0) {
7910
0
        ret = CheckAlgo(vPKCS, pbeOid, &pbeId, &version, &blockSz);
7911
0
    }
7912
0
    if (ret == 0 && (salt == NULL || saltSz == 0)) {
7913
0
        genSalt = 1;
7914
0
        saltSz = 8;
7915
0
    }
7916
0
    if (ret == 0 && version == PKCS5v2) {
7917
0
        ret = GetAlgoV2(encAlgId, &encOid, &encOidSz, &pbeId, &blockSz);
7918
0
    }
7919
0
    if (ret == 0) {
7920
0
        padSz = (blockSz - (keySz & (blockSz - 1))) & (blockSz - 1);
7921
        /* inner = OCT salt INT itt */
7922
0
        innerLen = 2 + saltSz + 2 + (itt < 256 ? 1 : 2);
7923
7924
0
        if (version != PKCS5v2) {
7925
0
            pbeOidBuf = OidFromId(pbeId, oidPBEType, &pbeOidBufSz);
7926
            /* pbe = OBJ pbse1 SEQ [ inner ] */
7927
0
            pbeLen = 2 + pbeOidBufSz + 2 + innerLen;
7928
0
        }
7929
0
        else {
7930
0
            pbeOidBuf = pbes2;
7931
0
            pbeOidBufSz = sizeof(pbes2);
7932
            /* kdf = OBJ pbkdf2 [ SEQ innerLen ] */
7933
0
            kdfLen = 2 + sizeof(pbkdf2Oid) + 2 + innerLen;
7934
            /* enc = OBJ enc_alg OCT iv */
7935
0
            encLen = 2 + encOidSz + 2 + blockSz;
7936
            /* pbe = OBJ pbse2 SEQ [ SEQ [ kdf ] SEQ [ enc ] ] */
7937
0
            pbeLen = 2 + sizeof(pbes2) + 2 + 2 + kdfLen + 2 + encLen;
7938
7939
0
            ret = wc_RNG_GenerateBlock(rng, cbcIv, blockSz);
7940
0
        }
7941
0
    }
7942
0
    if (ret == 0) {
7943
        /* outerLen = length of PBE encoding + octet string data */
7944
        /* Plus 2 for tag and length for pbe */
7945
0
        outerLen = 2 + pbeLen;
7946
        /* Octet string tag, length */
7947
0
        outerLen += 1 + SetLength(keySz + padSz, NULL);
7948
        /* Octet string bytes */
7949
0
        outerLen += keySz + padSz;
7950
0
        if (out == NULL) {
7951
            /* Sequence tag, length */
7952
0
            *outSz = 1 + SetLength(outerLen, NULL) + outerLen;
7953
0
            return LENGTH_ONLY_E;
7954
0
        }
7955
0
        SetOctetString(keySz + padSz, out);
7956
7957
0
        idx += SetSequence(outerLen, out + idx);
7958
7959
0
        encIdx = idx + outerLen - keySz - padSz;
7960
        /* Put Encrypted content in place. */
7961
0
        XMEMCPY(out + encIdx, key, keySz);
7962
0
        if (padSz > 0) {
7963
0
            XMEMSET(out + encIdx + keySz, padSz, padSz);
7964
0
            keySz += padSz;
7965
0
        }
7966
7967
0
        if (genSalt == 1) {
7968
0
        #ifdef WOLFSSL_SMALL_STACK
7969
0
            saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
7970
0
            if (saltTmp == NULL) {
7971
0
                ret = MEMORY_E;
7972
0
            }
7973
0
            else
7974
0
        #endif
7975
0
            {
7976
0
                salt = saltTmp;
7977
0
                if ((ret = wc_RNG_GenerateBlock(rng, saltTmp, saltSz)) != 0) {
7978
0
                    WOLFSSL_MSG("Error generating random salt");
7979
0
                }
7980
0
            }
7981
0
        }
7982
0
    }
7983
0
    if (ret == 0) {
7984
0
        ret = wc_CryptKey(password, passwordSz, salt, saltSz, itt, pbeId,
7985
0
                  out + encIdx, keySz, version, cbcIv, 1, 0);
7986
0
    }
7987
0
    if (ret == 0) {
7988
0
        if (version != PKCS5v2) {
7989
            /* PBE algorithm */
7990
0
            idx += SetSequence(pbeLen, out + idx);
7991
0
            idx += SetObjectId(pbeOidBufSz, out + idx);
7992
0
            XMEMCPY(out + idx, pbeOidBuf, pbeOidBufSz);
7993
0
            idx += pbeOidBufSz;
7994
0
        }
7995
0
        else {
7996
            /* PBES2 algorithm identifier */
7997
0
            idx += SetSequence(pbeLen, out + idx);
7998
0
            idx += SetObjectId(pbeOidBufSz, out + idx);
7999
0
            XMEMCPY(out + idx, pbeOidBuf, pbeOidBufSz);
8000
0
            idx += pbeOidBufSz;
8001
            /* PBES2 Parameters: SEQ [ kdf ] SEQ [ enc ] */
8002
0
            idx += SetSequence(2 + kdfLen + 2 + encLen, out + idx);
8003
            /* KDF Algorithm Identifier */
8004
0
            idx += SetSequence(kdfLen, out + idx);
8005
0
            idx += SetObjectId(sizeof(pbkdf2Oid), out + idx);
8006
0
            XMEMCPY(out + idx, pbkdf2Oid, sizeof(pbkdf2Oid));
8007
0
            idx += sizeof(pbkdf2Oid);
8008
0
        }
8009
0
        idx += SetSequence(innerLen, out + idx);
8010
0
        idx += SetOctetString(saltSz, out + idx);
8011
0
        XMEMCPY(out + idx, salt, saltSz); idx += saltSz;
8012
0
        ret = SetShortInt(out, &idx, itt, *outSz);
8013
0
        if (ret > 0)
8014
0
            ret = 0;
8015
0
    }
8016
0
    if (ret == 0) {
8017
0
        if (version == PKCS5v2) {
8018
            /* Encryption Algorithm Identifier */
8019
0
            idx += SetSequence(encLen, out + idx);
8020
0
            idx += SetObjectId(encOidSz, out + idx);
8021
0
            XMEMCPY(out + idx, encOid, encOidSz);
8022
0
            idx += encOidSz;
8023
            /* Encryption Algorithm Parameter: CBC IV */
8024
0
            idx += SetOctetString(blockSz, out + idx);
8025
0
            XMEMCPY(out + idx, cbcIv, blockSz);
8026
0
            idx += blockSz;
8027
0
        }
8028
0
        idx += SetOctetString(keySz, out + idx);
8029
        /* Default PRF - no need to write out OID */
8030
0
        idx += keySz;
8031
8032
0
        ret = idx;
8033
0
    }
8034
8035
0
#ifdef WOLFSSL_SMALL_STACK
8036
0
    if (saltTmp != NULL) {
8037
0
        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
8038
0
    }
8039
0
#endif
8040
8041
0
    WOLFSSL_LEAVE("wc_EncryptPKCS8Key", ret);
8042
8043
0
    return ret;
8044
0
}
8045
8046
int wc_DecryptPKCS8Key(byte* input, word32 sz, const char* password,
8047
        int passwordSz)
8048
0
{
8049
0
    int ret;
8050
0
    int length;
8051
0
    word32 inOutIdx = 0;
8052
8053
0
    if (input == NULL || password == NULL) {
8054
0
        return BAD_FUNC_ARG;
8055
0
    }
8056
8057
0
    if (GetSequence(input, &inOutIdx, &length, sz) < 0) {
8058
0
        ret = ASN_PARSE_E;
8059
0
    }
8060
0
    else {
8061
0
        ret = DecryptContent(input + inOutIdx, sz - inOutIdx, password,
8062
0
                passwordSz);
8063
0
        if (ret > 0) {
8064
0
            XMEMMOVE(input, input + inOutIdx, ret);
8065
0
        }
8066
0
    }
8067
8068
0
    if (ret > 0) {
8069
        /* DecryptContent will decrypt the data, but it will leave any padding
8070
         * bytes intact. This code calculates the length without the padding
8071
         * and we return that to the user. */
8072
0
        inOutIdx = 0;
8073
0
        if (GetSequence(input, &inOutIdx, &length, ret) < 0) {
8074
0
            ret = ASN_PARSE_E;
8075
0
        }
8076
0
        else {
8077
0
            ret = inOutIdx + length;
8078
0
        }
8079
0
    }
8080
8081
0
    return ret;
8082
0
}
8083
8084
/* Takes an unencrypted, traditional DER-encoded key and converts it to a PKCS#8
8085
 * encrypted key. If out is not NULL, it will hold the encrypted key. If it's
8086
 * NULL, LENGTH_ONLY_E will be returned and outSz will have the required out
8087
 * buffer size. */
8088
int TraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz,
8089
        const char* password, int passwordSz, int vPKCS, int vAlgo,
8090
        int encAlgId, byte* salt, word32 saltSz, int itt, WC_RNG* rng,
8091
        void* heap)
8092
0
{
8093
0
    int ret = 0;
8094
0
    byte *pkcs8Key = NULL;
8095
0
    word32 pkcs8KeySz = 0;
8096
0
    int algId = 0;
8097
0
    const byte* curveOid = NULL;
8098
0
    word32 curveOidSz = 0;
8099
8100
0
    if (ret == 0) {
8101
        /* check key type and get OID if ECC */
8102
0
        ret = wc_GetKeyOID(key, keySz, &curveOid, &curveOidSz, &algId, heap);
8103
0
        if (ret == 1)
8104
0
            ret = 0;
8105
0
    }
8106
0
    if (ret == 0) {
8107
0
        ret = wc_CreatePKCS8Key(NULL, &pkcs8KeySz, key, keySz, algId, curveOid,
8108
0
                                                                    curveOidSz);
8109
0
        if (ret == LENGTH_ONLY_E)
8110
0
            ret = 0;
8111
0
    }
8112
0
    if (ret == 0) {
8113
0
        pkcs8Key = (byte*)XMALLOC(pkcs8KeySz, heap, DYNAMIC_TYPE_TMP_BUFFER);
8114
0
        if (pkcs8Key == NULL)
8115
0
            ret = MEMORY_E;
8116
0
    }
8117
0
    if (ret == 0) {
8118
0
        ret = wc_CreatePKCS8Key(pkcs8Key, &pkcs8KeySz, key, keySz, algId,
8119
0
            curveOid, curveOidSz);
8120
0
        if (ret >= 0) {
8121
0
            pkcs8KeySz = ret;
8122
0
            ret = 0;
8123
0
        }
8124
0
    }
8125
#ifdef WOLFSSL_CHECK_MEM_ZERO
8126
    if (ret == 0) {
8127
        wc_MemZero_Add("TraditionalEnc pkcs8Key", pkcs8Key, pkcs8KeySz);
8128
    }
8129
#endif
8130
0
    if (ret == 0) {
8131
0
        ret = wc_EncryptPKCS8Key(pkcs8Key, pkcs8KeySz, out, outSz, password,
8132
0
            passwordSz, vPKCS, vAlgo, encAlgId, salt, saltSz, itt, rng, heap);
8133
0
    }
8134
8135
0
    if (pkcs8Key != NULL) {
8136
0
        ForceZero(pkcs8Key, pkcs8KeySz);
8137
0
        XFREE(pkcs8Key, heap, DYNAMIC_TYPE_TMP_BUFFER);
8138
0
    }
8139
8140
0
    (void)rng;
8141
8142
0
    return ret;
8143
0
}
8144
8145
/* Same as TraditionalEnc, but in the public API. */
8146
int wc_CreateEncryptedPKCS8Key(byte* key, word32 keySz, byte* out,
8147
        word32* outSz, const char* password, int passwordSz, int vPKCS,
8148
        int pbeOid, int encAlgId, byte* salt, word32 saltSz, int itt,
8149
        WC_RNG* rng, void* heap)
8150
0
{
8151
0
    return TraditionalEnc(key, keySz, out, outSz, password, passwordSz, vPKCS,
8152
0
        pbeOid, encAlgId, salt, saltSz, itt, rng, heap);
8153
0
}
8154
8155
8156
#ifdef WOLFSSL_ASN_TEMPLATE
8157
/* ASN.1 template for PKCS #8/#7 encrypted key for decrypting
8158
 * PKCS #8: RFC 5958, 3 - EncryptedPrivateKeyInfo without outer SEQUENCE
8159
 * PKCS #7: RFC 2315, 10.1 - EncryptedContentInfo without outer SEQUENCE
8160
 */
8161
static const ASNItem pkcs8DecASN[] = {
8162
/* ENCALGO_SEQ    */ { 1, ASN_SEQUENCE, 1, 1, 0 },
8163
/* ENCALGO_OID    */     { 2, ASN_OBJECT_ID, 0, 0, 0 },
8164
/* ENCALGO_PARAMS */     { 2, ASN_SEQUENCE, 1, 0, 0 },
8165
            /* PKCS #7 */
8166
/* ENCCONTENT     */ { 1, ASN_CONTEXT_SPECIFIC | ASN_ENC_CONTENT,
8167
                                       0, 0, 2 },
8168
            /* PKCS #8 */
8169
/* ENCDATA        */ { 1, ASN_OCTET_STRING, 0, 0, 2 },
8170
};
8171
enum {
8172
    PKCS8DECASN_IDX_ENCALGO_SEQ = 0,
8173
    PKCS8DECASN_IDX_ENCALGO_OID,
8174
    PKCS8DECASN_IDX_ENCALGO_PARAMS,
8175
    PKCS8DECASN_IDX_ENCCONTENT,
8176
    PKCS8DECASN_IDX_ENCDATA,
8177
};
8178
8179
/* Number of items in ASN.1 template for PKCS #8/#7 encrypted key. */
8180
#define pkcs8DecASN_Length (sizeof(pkcs8DecASN) / sizeof(ASNItem))
8181
#endif
8182
8183
/* Decrypt data using PBE algorithm.
8184
 *
8185
 * PKCS #8: RFC 5958, 3 - EncryptedPrivateKeyInfo without outer SEQUENCE
8186
 * PKCS #7: RFC 2315, 10.1 - EncryptedContentInfo without outer SEQUENCE
8187
 *
8188
 * Note: input buffer is overwritten with decrypted data!
8189
 *
8190
 * Salt is in KDF parameters and IV is PBE parameters when needed.
8191
 *
8192
 * @param [in] input       Data to decrypt and unwrap.
8193
 * @param [in] sz          Size of encrypted data.
8194
 * @param [in] password    Password to derive encryption key with.
8195
 * @param [in] passwordSz  Size of password in bytes.
8196
 * @return  Length of decrypted data on success.
8197
 * @return  MEMORY_E when dynamic memory allocation fails.
8198
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
8199
 *          is invalid.
8200
 * @return  BUFFER_E when data in buffer is too small.
8201
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
8202
 * @return  Other when decryption fails.
8203
 */
8204
int DecryptContent(byte* input, word32 sz, const char* password, int passwordSz)
8205
0
{
8206
0
#ifndef WOLFSSL_ASN_TEMPLATE
8207
0
    word32 inOutIdx = 0, seqEnd, oid, shaOid = 0;
8208
0
    int    ret = 0, first, second, length = 0, version, saltSz, id = 0;
8209
0
    int    iterations = 0, keySz = 0;
8210
0
#ifdef WOLFSSL_SMALL_STACK
8211
0
    byte*  salt = NULL;
8212
0
    byte*  cbcIv = NULL;
8213
#else
8214
    byte   salt[MAX_SALT_SIZE];
8215
    byte   cbcIv[MAX_IV_SIZE];
8216
#endif
8217
0
    byte   tag;
8218
8219
0
    if (passwordSz < 0) {
8220
0
        WOLFSSL_MSG("Bad password size");
8221
0
        return BAD_FUNC_ARG;
8222
0
    }
8223
8224
0
    if (GetAlgoId(input, &inOutIdx, &oid, oidIgnoreType, sz) < 0) {
8225
0
        ERROR_OUT(ASN_PARSE_E, exit_dc);
8226
0
    }
8227
8228
0
    first  = input[inOutIdx - 2];   /* PKCS version always 2nd to last byte */
8229
0
    second = input[inOutIdx - 1];   /* version.algo, algo id last byte */
8230
8231
0
    if (CheckAlgo(first, second, &id, &version, NULL) < 0) {
8232
0
        ERROR_OUT(ASN_INPUT_E, exit_dc); /* Algo ID error */
8233
0
    }
8234
8235
0
    if (version == PKCS5v2) {
8236
0
        if (GetSequence(input, &inOutIdx, &length, sz) < 0) {
8237
0
            ERROR_OUT(ASN_PARSE_E, exit_dc);
8238
0
        }
8239
8240
0
        if (GetAlgoId(input, &inOutIdx, &oid, oidKdfType, sz) < 0) {
8241
0
            ERROR_OUT(ASN_PARSE_E, exit_dc);
8242
0
        }
8243
8244
0
        if (oid != PBKDF2_OID) {
8245
0
            ERROR_OUT(ASN_PARSE_E, exit_dc);
8246
0
        }
8247
0
    }
8248
8249
0
    if (GetSequence(input, &inOutIdx, &length, sz) <= 0) {
8250
0
        ERROR_OUT(ASN_PARSE_E, exit_dc);
8251
0
    }
8252
    /* Find the end of this SEQUENCE so we can check for the OPTIONAL and
8253
     * DEFAULT items. */
8254
0
    seqEnd = inOutIdx + length;
8255
8256
0
    ret = GetOctetString(input, &inOutIdx, &saltSz, sz);
8257
0
    if (ret < 0)
8258
0
        goto exit_dc;
8259
8260
0
    if (saltSz > MAX_SALT_SIZE) {
8261
0
        ERROR_OUT(ASN_PARSE_E, exit_dc);
8262
0
    }
8263
8264
0
#ifdef WOLFSSL_SMALL_STACK
8265
0
    salt = (byte*)XMALLOC(MAX_SALT_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8266
0
    if (salt == NULL) {
8267
0
        ERROR_OUT(MEMORY_E, exit_dc);
8268
0
    }
8269
0
#endif
8270
8271
0
    XMEMCPY(salt, &input[inOutIdx], saltSz);
8272
0
    inOutIdx += saltSz;
8273
8274
0
    if (GetShortInt(input, &inOutIdx, &iterations, sz) < 0) {
8275
0
        ERROR_OUT(ASN_PARSE_E, exit_dc);
8276
0
    }
8277
8278
    /* OPTIONAL key length */
8279
0
    if (seqEnd > inOutIdx) {
8280
0
        word32 localIdx = inOutIdx;
8281
8282
0
        if (GetASNTag(input, &localIdx, &tag, sz) < 0) {
8283
0
            ERROR_OUT(ASN_PARSE_E, exit_dc);
8284
0
        }
8285
8286
0
        if (tag == ASN_INTEGER &&
8287
0
                GetShortInt(input, &inOutIdx, &keySz, sz) < 0) {
8288
0
            ERROR_OUT(ASN_PARSE_E, exit_dc);
8289
0
        }
8290
0
    }
8291
8292
    /* DEFAULT HMAC is SHA-1 */
8293
0
    if (seqEnd > inOutIdx) {
8294
0
        if (GetAlgoId(input, &inOutIdx, &oid, oidHmacType, sz) < 0) {
8295
0
            ERROR_OUT(ASN_PARSE_E, exit_dc);
8296
0
        }
8297
8298
0
        shaOid = oid;
8299
0
    }
8300
8301
0
#ifdef WOLFSSL_SMALL_STACK
8302
0
    cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8303
0
    if (cbcIv == NULL) {
8304
0
        ERROR_OUT(MEMORY_E, exit_dc);
8305
0
    }
8306
0
#endif
8307
8308
0
    if (version == PKCS5v2) {
8309
        /* get encryption algo */
8310
0
        if (GetAlgoId(input, &inOutIdx, &oid, oidBlkType, sz) < 0) {
8311
0
            ERROR_OUT(ASN_PARSE_E, exit_dc);
8312
0
        }
8313
8314
0
        if (CheckAlgoV2(oid, &id, NULL) < 0) {
8315
0
            ERROR_OUT(ASN_PARSE_E, exit_dc); /* PKCS v2 algo id error */
8316
0
        }
8317
8318
0
        if (shaOid == 0)
8319
0
            shaOid = oid;
8320
8321
0
        ret = GetOctetString(input, &inOutIdx, &length, sz);
8322
0
        if (ret < 0)
8323
0
            goto exit_dc;
8324
8325
0
        if (length > MAX_IV_SIZE) {
8326
0
            ERROR_OUT(ASN_PARSE_E, exit_dc);
8327
0
        }
8328
8329
0
        XMEMCPY(cbcIv, &input[inOutIdx], length);
8330
0
        inOutIdx += length;
8331
0
    }
8332
8333
0
    if (GetASNTag(input, &inOutIdx, &tag, sz) < 0) {
8334
0
        ERROR_OUT(ASN_PARSE_E, exit_dc);
8335
0
    }
8336
8337
0
    if (tag != (ASN_CONTEXT_SPECIFIC | 0) && tag != ASN_OCTET_STRING) {
8338
0
        ERROR_OUT(ASN_PARSE_E, exit_dc);
8339
0
    }
8340
8341
0
    if (GetLength(input, &inOutIdx, &length, sz) < 0) {
8342
0
        ERROR_OUT(ASN_PARSE_E, exit_dc);
8343
0
    }
8344
8345
0
    ret = wc_CryptKey(password, passwordSz, salt, saltSz, iterations, id,
8346
0
                   input + inOutIdx, length, version, cbcIv, 0, shaOid);
8347
8348
0
exit_dc:
8349
0
#ifdef WOLFSSL_SMALL_STACK
8350
0
    XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
8351
0
    XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8352
0
#endif
8353
8354
0
    if (ret == 0) {
8355
0
        XMEMMOVE(input, input + inOutIdx, length);
8356
0
        ret = length;
8357
0
    }
8358
8359
0
    return ret;
8360
#else
8361
    /* pbes2ParamsASN longer than pkcs8DecASN_Length/pbes1ParamsASN_Length. */
8362
    DECL_ASNGETDATA(dataASN, pbes2ParamsASN_Length);
8363
    int    ret = 0;
8364
    int    id;
8365
    int    version;
8366
    word32 idx = 0;
8367
    word32 pIdx = 0;
8368
    word32 iterations;
8369
    word32 keySz = 0;
8370
    word32 saltSz;
8371
    word32 shaOid = 0;
8372
    byte*  salt = NULL;
8373
    byte*  key = NULL;
8374
    byte   cbcIv[MAX_IV_SIZE];
8375
    byte*  params;
8376
8377
    WOLFSSL_ENTER("DecryptContent");
8378
8379
    CALLOC_ASNGETDATA(dataASN, pbes2ParamsASN_Length, ret, NULL);
8380
8381
    if (ret == 0) {
8382
        /* Check OID is a PBE Type */
8383
        GetASN_OID(&dataASN[PKCS8DECASN_IDX_ENCALGO_OID], oidPBEType);
8384
        ret = GetASN_Items(pkcs8DecASN, dataASN, pkcs8DecASN_Length, 0, input,
8385
                           &idx, sz);
8386
    }
8387
    if (ret == 0) {
8388
        /* Check the PBE algorithm and get the version and id. */
8389
        idx = dataASN[PKCS8DECASN_IDX_ENCALGO_OID].data.oid.length;
8390
        /* Second last byte: 1 (PKCS #12 PBE Id) or 5 (PKCS #5)
8391
         * Last byte: Alg or PBES2 */
8392
        ret = CheckAlgo(dataASN[PKCS8DECASN_IDX_ENCALGO_OID].data.oid.data[idx - 2],
8393
                  dataASN[PKCS8DECASN_IDX_ENCALGO_OID].data.oid.data[idx - 1],
8394
                  &id, &version, NULL);
8395
    }
8396
    if (ret == 0) {
8397
        /* Get the parameters data. */
8398
        GetASN_GetRef(&dataASN[PKCS8DECASN_IDX_ENCALGO_PARAMS], &params, &sz);
8399
        /* Having a numbered choice means none or both will have errored out. */
8400
        if (dataASN[PKCS8DECASN_IDX_ENCCONTENT].tag != 0)
8401
            GetASN_GetRef(&dataASN[PKCS8DECASN_IDX_ENCCONTENT], &key, &keySz);
8402
        else if (dataASN[PKCS8DECASN_IDX_ENCDATA].tag != 0)
8403
            GetASN_GetRef(&dataASN[PKCS8DECASN_IDX_ENCDATA], &key, &keySz);
8404
        else
8405
            ret = ASN_RSA_KEY_E;
8406
    }
8407
8408
    if (ret == 0) {
8409
        if (version != PKCS5v2) {
8410
            /* Initialize for PBES1 parameters and put iterations in var. */
8411
            XMEMSET(dataASN, 0, sizeof(*dataASN) * pbes1ParamsASN_Length);
8412
            GetASN_Int32Bit(&dataASN[PBES1PARAMSASN_IDX_ITER], &iterations);
8413
            /* Parse the PBES1 parameters. */
8414
            ret = GetASN_Items(pbes1ParamsASN, dataASN, pbes1ParamsASN_Length,
8415
                               0, params, &pIdx, sz);
8416
            if (ret == 0) {
8417
                /* Get the salt data. */
8418
                GetASN_GetRef(&dataASN[PBES1PARAMSASN_IDX_SALT], &salt, &saltSz);
8419
            }
8420
        }
8421
        else {
8422
            word32 ivSz = MAX_IV_SIZE;
8423
8424
            /* Initialize for PBES2 parameters. Put iterations in var; match
8425
             * KDF, HMAC and cipher, and copy CBC into buffer. */
8426
            XMEMSET(dataASN, 0, sizeof(*dataASN) * pbes2ParamsASN_Length);
8427
            GetASN_ExpBuffer(&dataASN[PBES2PARAMSASN_IDX_KDF_OID], pbkdf2Oid, sizeof(pbkdf2Oid));
8428
            GetASN_Int32Bit(&dataASN[PBES2PARAMSASN_IDX_PBKDF2_PARAMS_ITER], &iterations);
8429
            GetASN_OID(&dataASN[PBES2PARAMSASN_IDX_PBKDF2_PARAMS_PRF_OID], oidHmacType);
8430
            GetASN_OID(&dataASN[PBES2PARAMSASN_IDX_ENCS_OID], oidBlkType);
8431
            GetASN_Buffer(&dataASN[PBES2PARAMSASN_IDX_ENCS_PARAMS], cbcIv, &ivSz);
8432
            /* Parse the PBES2 parameters  */
8433
            ret = GetASN_Items(pbes2ParamsASN, dataASN, pbes2ParamsASN_Length,
8434
                               0, params, &pIdx, sz);
8435
            if (ret == 0) {
8436
                /* Get the salt data. */
8437
                GetASN_GetRef(&dataASN[PBES2PARAMSASN_IDX_PBKDF2_PARAMS_SALT], &salt, &saltSz);
8438
                /* Get the digest and encryption algorithm id. */
8439
                shaOid = dataASN[PBES2PARAMSASN_IDX_PBKDF2_PARAMS_PRF_OID].data.oid.sum; /* Default HMAC-SHA1 */
8440
                id     = dataASN[PBES2PARAMSASN_IDX_ENCS_OID].data.oid.sum;
8441
                /* Convert encryption algorithm to a PBE algorithm if needed. */
8442
                CheckAlgoV2(id, &id, NULL);
8443
            }
8444
        }
8445
    }
8446
8447
    if (ret == 0) {
8448
        /* Decrypt the key. */
8449
        ret = wc_CryptKey(password, passwordSz, salt, saltSz, iterations, id,
8450
                          key, keySz, version, cbcIv, 0, shaOid);
8451
    }
8452
    if (ret == 0) {
8453
        /* Copy the decrypted key into the input (inline). */
8454
        XMEMMOVE(input, key, keySz);
8455
        ret = keySz;
8456
    }
8457
8458
    FREE_ASNGETDATA(dataASN, NULL);
8459
    return ret;
8460
#endif
8461
0
}
8462
8463
/* Decrypt data using PBE algorithm and get key from PKCS#8 wrapping.
8464
 *
8465
 * PKCS #8: RFC 5958, 3 - EncryptedPrivateKeyInfo
8466
 * PKCS #7: RFC 2315, 10.1 - EncryptedContentInfo
8467
 *
8468
 * Note: input buffer is overwritten with decrypted key!
8469
 *
8470
 * Salt is in KDF parameters and IV is PBE parameters when needed.
8471
 *
8472
 * @param [in]  input       Data to decrypt and unwrap.
8473
 * @param [in]  sz          Size of encrypted data.
8474
 * @param [in]  password    Password to derive encryption key with.
8475
 * @param [in]  passwordSz  Size of password in bytes.
8476
 * @param [out] algId       Key algorithm from PKCS#8 wrapper.
8477
 * @return  Length of decrypted data on success.
8478
 * @return  MEMORY_E when dynamic memory allocation fails.
8479
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
8480
 *          is invalid.
8481
 * @return  BUFFER_E when data in buffer is too small.
8482
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
8483
 * @return  Other when decryption fails.
8484
 */
8485
int ToTraditionalEnc(byte* input, word32 sz, const char* password,
8486
                     int passwordSz, word32* algId)
8487
0
{
8488
0
    int ret;
8489
8490
0
    ret = wc_DecryptPKCS8Key(input, sz, password, passwordSz);
8491
0
    if (ret > 0) {
8492
0
        ret = ToTraditional_ex(input, ret, algId);
8493
0
    }
8494
8495
0
    return ret;
8496
0
}
8497
8498
#endif /* HAVE_PKCS8 */
8499
8500
#ifdef HAVE_PKCS12
8501
8502
#define PKCS8_MIN_BLOCK_SIZE 8
8503
static int Pkcs8Pad(byte* buf, int sz, int blockSz)
8504
0
{
8505
0
    int i, padSz;
8506
8507
    /* calculate pad size */
8508
0
    padSz = blockSz - (sz & (blockSz - 1));
8509
8510
    /* pad with padSz value */
8511
0
    if (buf) {
8512
0
        for (i = 0; i < padSz; i++) {
8513
0
            buf[sz+i] = (byte)(padSz & 0xFF);
8514
0
        }
8515
0
    }
8516
8517
    /* return adjusted length */
8518
0
    return sz + padSz;
8519
0
}
8520
8521
#ifdef WOLFSSL_ASN_TEMPLATE
8522
/* ASN.1 template for PKCS #8 encrypted key with PBES1 parameters.
8523
 * PKCS #8: RFC 5958, 3 - EncryptedPrivateKeyInfo
8524
 * PKCS #5: RFC 8018, A.3 - PBEParameter
8525
 */
8526
static const ASNItem p8EncPbes1ASN[] = {
8527
/* SEQ                   */ { 0, ASN_SEQUENCE, 1, 1, 0 },
8528
/* ENCALGO_SEQ           */     { 1, ASN_SEQUENCE, 1, 1, 0 },
8529
                    /* PBE algorithm */
8530
/* ENCALGO_OID           */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
8531
/* ENCALGO_PBEPARAM_SEQ  */         { 2, ASN_SEQUENCE, 1, 1, 0 },
8532
                        /* Salt */
8533
/* ENCALGO_PBEPARAM_SALT */             { 3, ASN_OCTET_STRING, 0, 0, 0 },
8534
                        /* Iteration Count */
8535
/* ENCALGO_PBEPARAM_ITER */             { 3, ASN_INTEGER, 0, 0, 0 },
8536
/* ENCDATA               */     { 1, ASN_OCTET_STRING, 0, 0, 0 },
8537
};
8538
enum {
8539
    P8ENCPBES1ASN_IDX_SEQ = 0,
8540
    P8ENCPBES1ASN_IDX_ENCALGO_SEQ,
8541
    P8ENCPBES1ASN_IDX_ENCALGO_OID,
8542
    P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_SEQ,
8543
    P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_SALT,
8544
    P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_ITER,
8545
    P8ENCPBES1ASN_IDX_ENCDATA,
8546
};
8547
8548
#define p8EncPbes1ASN_Length (sizeof(p8EncPbes1ASN) / sizeof(ASNItem))
8549
#endif
8550
8551
/* Wrap a private key in PKCS#8 and encrypt.
8552
 *
8553
 * Used for PKCS#12 and PKCS#7.
8554
 * vPKCS is the version of PKCS to use.
8555
 * vAlgo is the algorithm version to use.
8556
 *
8557
 * When salt is NULL, a random number is generated.
8558
 *
8559
 * data returned is :
8560
 * [ seq - obj [ seq -salt,itt]] , construct with encrypted data
8561
 *
8562
 * @param [in]  input       Data to encrypt.
8563
 * @param [in]  inputSz     Length of data in bytes.
8564
 * @param [out] out         Buffer to write wrapped encrypted data into.
8565
 * @param [out] outSz       Length of encrypted data in bytes.
8566
 * @param [in]  password    Password used to create encryption key.
8567
 * @param [in]  passwordSz  Length of password in bytes.
8568
 * @param [in]  vPKCS       First byte used to determine PBE algorithm.
8569
 * @param [in]  vAlgo       Second byte used to determine PBE algorithm.
8570
 * @param [in]  salt        Salt to use with KDF.
8571
 * @param [in]  saltSz      Length of salt in bytes.
8572
 * @param [in]  itt         Number of iterations to use in KDF.
8573
 * @param [in]  rng         Random number generator to use to generate salt.
8574
 * @param [in]  heap        Dynamic memory allocator hint.
8575
 * @return  The size of encrypted data on success
8576
 * @return  LENGTH_ONLY_E when out is NULL and able to encode.
8577
 * @return  ASN_PARSE_E when the salt size is too large.
8578
 * @return  ASN_VERSION_E when attempting to use a PBES2 algorithm (use
8579
 *          TraditionalEnc).
8580
 * @return  MEMORY_E when dynamic memory allocation fails.
8581
 * @return  Other when encryption or random number generation fails.
8582
 */
8583
int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz,
8584
        const char* password, int passwordSz, int vPKCS, int vAlgo,
8585
        byte* salt, word32 saltSz, int itt, WC_RNG* rng, void* heap)
8586
0
{
8587
0
#ifndef WOLFSSL_ASN_TEMPLATE
8588
0
    word32 sz;
8589
0
    word32 inOutIdx = 0;
8590
0
    word32 tmpIdx   = 0;
8591
0
    word32 totalSz  = 0;
8592
0
    word32 seqSz;
8593
0
    word32 innerSz;
8594
0
    int    ret;
8595
0
    int    version, id, blockSz = 0;
8596
0
#ifdef WOLFSSL_SMALL_STACK
8597
0
    byte*  saltTmp = NULL;
8598
0
    byte*  cbcIv   = NULL;
8599
#else
8600
    byte   saltTmp[MAX_SALT_SIZE];
8601
    byte   cbcIv[MAX_IV_SIZE];
8602
#endif
8603
0
    byte   seq[MAX_SEQ_SZ];
8604
0
    byte   shr[MAX_SHORT_SZ];
8605
0
    word32 maxShr = MAX_SHORT_SZ;
8606
0
    word32 algoSz;
8607
0
    const  byte* algoName;
8608
8609
0
    (void)heap;
8610
8611
0
    WOLFSSL_ENTER("EncryptContent()");
8612
8613
0
    if (CheckAlgo(vPKCS, vAlgo, &id, &version, &blockSz) < 0)
8614
0
        return ASN_INPUT_E;  /* Algo ID error */
8615
8616
0
    if (version == PKCS5v2) {
8617
0
        WOLFSSL_MSG("PKCS#5 version 2 not supported yet");
8618
0
        return BAD_FUNC_ARG;
8619
0
    }
8620
8621
0
    if (saltSz > MAX_SALT_SIZE)
8622
0
        return ASN_PARSE_E;
8623
8624
0
    if (outSz == NULL) {
8625
0
        return BAD_FUNC_ARG;
8626
0
    }
8627
8628
    /* calculate size */
8629
    /* size of constructed string at end */
8630
0
    sz = Pkcs8Pad(NULL, inputSz, blockSz);
8631
0
    totalSz  = ASN_TAG_SZ;
8632
0
    totalSz += SetLength(sz, seq);
8633
0
    totalSz += sz;
8634
8635
    /* size of sequence holding object id and sub sequence of salt and itt */
8636
0
    algoName = OidFromId(id, oidPBEType, &algoSz);
8637
0
    if (algoName == NULL) {
8638
0
        WOLFSSL_MSG("Unknown Algorithm");
8639
0
        return 0;
8640
0
    }
8641
0
    innerSz = SetObjectId(algoSz, seq);
8642
0
    innerSz += algoSz;
8643
8644
    /* get subsequence of salt and itt */
8645
0
    if (salt == NULL || saltSz == 0) {
8646
0
        sz = 8;
8647
0
    }
8648
0
    else {
8649
0
        sz = saltSz;
8650
0
    }
8651
0
    seqSz  = SetOctetString(sz, seq);
8652
0
    seqSz += sz;
8653
8654
0
    tmpIdx = 0;
8655
0
    ret = SetShortInt(shr, &tmpIdx, itt, maxShr);
8656
0
    if (ret >= 0) {
8657
0
        seqSz += ret;
8658
0
    }
8659
0
    else {
8660
0
        return ret;
8661
0
    }
8662
0
    innerSz += seqSz + SetSequence(seqSz, seq);
8663
0
    totalSz += innerSz + SetSequence(innerSz, seq);
8664
8665
0
    if (out == NULL) {
8666
0
        *outSz = totalSz;
8667
0
        return LENGTH_ONLY_E;
8668
0
    }
8669
8670
0
    inOutIdx = 0;
8671
0
    if (totalSz > *outSz)
8672
0
        return BUFFER_E;
8673
8674
0
    inOutIdx += SetSequence(innerSz, out + inOutIdx);
8675
0
    inOutIdx += SetObjectId(algoSz, out + inOutIdx);
8676
0
    XMEMCPY(out + inOutIdx, algoName, algoSz);
8677
0
    inOutIdx += algoSz;
8678
0
    inOutIdx += SetSequence(seqSz, out + inOutIdx);
8679
8680
    /* create random salt if one not provided */
8681
0
    if (salt == NULL || saltSz == 0) {
8682
0
        saltSz = 8;
8683
0
    #ifdef WOLFSSL_SMALL_STACK
8684
0
        saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
8685
0
        if (saltTmp == NULL)
8686
0
            return MEMORY_E;
8687
0
    #endif
8688
0
        salt = saltTmp;
8689
8690
0
        if ((ret = wc_RNG_GenerateBlock(rng, saltTmp, saltSz)) != 0) {
8691
0
            WOLFSSL_MSG("Error generating random salt");
8692
0
        #ifdef WOLFSSL_SMALL_STACK
8693
0
            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
8694
0
        #endif
8695
0
            return ret;
8696
0
        }
8697
0
    }
8698
0
    inOutIdx += SetOctetString(saltSz, out + inOutIdx);
8699
0
    if (saltSz + inOutIdx > *outSz) {
8700
0
    #ifdef WOLFSSL_SMALL_STACK
8701
0
        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
8702
0
    #endif
8703
0
        return BUFFER_E;
8704
0
    }
8705
0
    XMEMCPY(out + inOutIdx, salt, saltSz);
8706
0
    inOutIdx += saltSz;
8707
8708
    /* place iteration setting in buffer */
8709
0
    ret = SetShortInt(out, &inOutIdx, itt, *outSz);
8710
0
    if (ret < 0) {
8711
0
    #ifdef WOLFSSL_SMALL_STACK
8712
0
        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
8713
0
    #endif
8714
0
        return ret;
8715
0
    }
8716
8717
0
    if (inOutIdx + 1 > *outSz) {
8718
0
    #ifdef WOLFSSL_SMALL_STACK
8719
0
        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
8720
0
    #endif
8721
0
        return BUFFER_E;
8722
0
    }
8723
0
    out[inOutIdx++] = ASN_CONTEXT_SPECIFIC | 0;
8724
8725
    /* get pad size and verify buffer room */
8726
0
    sz = Pkcs8Pad(NULL, inputSz, blockSz);
8727
0
    if (sz + inOutIdx > *outSz) {
8728
0
    #ifdef WOLFSSL_SMALL_STACK
8729
0
        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
8730
0
    #endif
8731
0
        return BUFFER_E;
8732
0
    }
8733
0
    inOutIdx += SetLength(sz, out + inOutIdx);
8734
8735
    /* copy input to output buffer and pad end */
8736
0
    XMEMCPY(out + inOutIdx, input, inputSz);
8737
0
    sz = Pkcs8Pad(out + inOutIdx, inputSz, blockSz);
8738
0
#ifdef WOLFSSL_SMALL_STACK
8739
0
    cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
8740
0
    if (cbcIv == NULL) {
8741
0
        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
8742
0
        return MEMORY_E;
8743
0
    }
8744
0
#endif
8745
8746
    /* encrypt */
8747
0
    if ((ret = wc_CryptKey(password, passwordSz, salt, saltSz, itt, id,
8748
0
                   out + inOutIdx, sz, version, cbcIv, 1, 0)) < 0) {
8749
8750
0
    #ifdef WOLFSSL_SMALL_STACK
8751
0
        XFREE(cbcIv,   heap, DYNAMIC_TYPE_TMP_BUFFER);
8752
0
        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
8753
0
    #endif
8754
0
        return ret;  /* encrypt failure */
8755
0
    }
8756
8757
0
#ifdef WOLFSSL_SMALL_STACK
8758
0
    XFREE(cbcIv,   heap, DYNAMIC_TYPE_TMP_BUFFER);
8759
0
    XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
8760
0
#endif
8761
8762
0
    (void)rng;
8763
8764
0
    return inOutIdx + sz;
8765
#else
8766
    DECL_ASNSETDATA(dataASN, p8EncPbes1ASN_Length);
8767
    int ret = 0;
8768
    int sz = 0;
8769
    int version;
8770
    int id;
8771
    int blockSz = 0;
8772
    byte* pkcs8;
8773
    word32 pkcs8Sz;
8774
    byte cbcIv[MAX_IV_SIZE];
8775
8776
    (void)heap;
8777
8778
    WOLFSSL_ENTER("EncryptContent()");
8779
8780
    /* Must have a output size to return or check. */
8781
    if (outSz == NULL) {
8782
        ret = BAD_FUNC_ARG;
8783
    }
8784
    /* Check salt size is valid. */
8785
    if ((ret == 0) && (saltSz > MAX_SALT_SIZE)) {
8786
        ret = ASN_PARSE_E;
8787
    }
8788
    /* Get algorithm parameters for algorithm identifier. */
8789
    if ((ret == 0) && CheckAlgo(vPKCS, vAlgo, &id, &version, &blockSz) < 0) {
8790
        ret = ASN_INPUT_E;
8791
    }
8792
    /* Check PKCS #5 version - only PBSE1 parameters supported. */
8793
    if ((ret == 0) && (version == PKCS5v2)) {
8794
        ret = BAD_FUNC_ARG;
8795
    }
8796
8797
    CALLOC_ASNSETDATA(dataASN, p8EncPbes1ASN_Length, ret, heap);
8798
8799
    if (ret == 0) {
8800
        /* Setup data to go into encoding including PBE algorithm, salt,
8801
         * iteration count, and padded key length. */
8802
        SetASN_OID(&dataASN[P8ENCPBES1ASN_IDX_ENCALGO_OID], id, oidPBEType);
8803
        if (salt == NULL || saltSz == 0) {
8804
            salt = NULL;
8805
            saltSz = PKCS5_SALT_SZ;
8806
            /* Salt generated into encoding below. */
8807
        }
8808
        SetASN_Buffer(&dataASN[P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_SALT],
8809
                salt, saltSz);
8810
        SetASN_Int16Bit(&dataASN[P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_ITER], itt);
8811
        pkcs8Sz = Pkcs8Pad(NULL, inputSz, blockSz);
8812
        SetASN_Buffer(&dataASN[P8ENCPBES1ASN_IDX_ENCDATA], NULL, pkcs8Sz);
8813
8814
        /* Calculate size of encoding. */
8815
        ret = SizeASN_Items(p8EncPbes1ASN + P8ENCPBES1ASN_IDX_ENCALGO_SEQ,
8816
                dataASN + P8ENCPBES1ASN_IDX_ENCALGO_SEQ,
8817
                (int)(p8EncPbes1ASN_Length - P8ENCPBES1ASN_IDX_ENCALGO_SEQ),
8818
                &sz);
8819
    }
8820
    /* Return size when no output buffer. */
8821
    if ((ret == 0) && (out == NULL)) {
8822
        *outSz = sz;
8823
        ret = LENGTH_ONLY_E;
8824
    }
8825
    /* Check output buffer is big enough for encoded data. */
8826
    if ((ret == 0) && (sz > (int)*outSz)) {
8827
        ret = BAD_FUNC_ARG;
8828
    }
8829
    if (ret == 0) {
8830
        /* Encode PKCS#8 key. */
8831
        SetASN_Items(p8EncPbes1ASN + P8ENCPBES1ASN_IDX_ENCALGO_SEQ,
8832
                 dataASN + P8ENCPBES1ASN_IDX_ENCALGO_SEQ,
8833
                 (int)(p8EncPbes1ASN_Length - P8ENCPBES1ASN_IDX_ENCALGO_SEQ),
8834
                 out);
8835
8836
        if (salt == NULL) {
8837
            /* Generate salt into encoding. */
8838
            salt = (byte*)dataASN[P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_SALT].data.buffer.data;
8839
            ret = wc_RNG_GenerateBlock(rng, salt, saltSz);
8840
        }
8841
    }
8842
    if (ret == 0) {
8843
        /* Store PKCS#8 key in output buffer. */
8844
        pkcs8 = (byte*)dataASN[P8ENCPBES1ASN_IDX_ENCDATA].data.buffer.data;
8845
        XMEMCPY(pkcs8, input, inputSz);
8846
        Pkcs8Pad(pkcs8, inputSz, blockSz);
8847
8848
        /* Encrypt PKCS#8 key inline. */
8849
        ret = wc_CryptKey(password, passwordSz, salt, saltSz, itt, id, pkcs8,
8850
                          pkcs8Sz, version, cbcIv, 1, 0);
8851
    }
8852
    if (ret == 0) {
8853
        /* Returning size on success. */
8854
        ret = sz;
8855
    }
8856
8857
    FREE_ASNSETDATA(dataASN, heap);
8858
    return ret;
8859
#endif /* WOLFSSL_ASN_TEMPLATE */
8860
0
}
8861
8862
8863
#endif /* HAVE_PKCS12 */
8864
#endif /* NO_PWDBASED */
8865
8866
#ifndef NO_RSA
8867
8868
#ifndef HAVE_USER_RSA
8869
#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT)
8870
/* This function is to retrieve key position information in a cert.*
8871
 * The information will be used to call TSIP TLS-linked API for    *
8872
 * certificate verification.                                       */
8873
static int RsaPublicKeyDecodeRawIndex(const byte* input, word32* inOutIdx,
8874
                                      word32 inSz, word32* key_n,
8875
                                      word32* key_n_len, word32* key_e,
8876
                                      word32* key_e_len)
8877
{
8878
8879
    int ret = 0;
8880
    int length = 0;
8881
#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
8882
    byte b;
8883
#endif
8884
8885
    if (input == NULL || inOutIdx == NULL)
8886
        return BAD_FUNC_ARG;
8887
8888
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
8889
        return ASN_PARSE_E;
8890
8891
#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
8892
    if ((*inOutIdx + 1) > inSz)
8893
        return BUFFER_E;
8894
8895
    b = input[*inOutIdx];
8896
    if (b != ASN_INTEGER) {
8897
        /* not from decoded cert, will have algo id, skip past */
8898
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
8899
            return ASN_PARSE_E;
8900
8901
        if (SkipObjectId(input, inOutIdx, inSz) < 0)
8902
            return ASN_PARSE_E;
8903
8904
        /* Option NULL ASN.1 tag */
8905
        if (*inOutIdx  >= inSz) {
8906
            return BUFFER_E;
8907
        }
8908
        if (input[*inOutIdx] == ASN_TAG_NULL) {
8909
            ret = GetASNNull(input, inOutIdx, inSz);
8910
            if (ret != 0)
8911
                return ret;
8912
        }
8913
        /* TODO: support RSA PSS */
8914
8915
        /* should have bit tag length and seq next */
8916
        ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);
8917
        if (ret != 0)
8918
            return ret;
8919
8920
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
8921
            return ASN_PARSE_E;
8922
    }
8923
#endif /* OPENSSL_EXTRA */
8924
8925
    /* Get modulus */
8926
    ret = GetASNInt(input, inOutIdx, &length, inSz);
8927
    *key_n += *inOutIdx;
8928
    if (ret < 0) {
8929
        return ASN_RSA_KEY_E;
8930
    }
8931
    if (key_n_len)
8932
        *key_n_len = length;
8933
    *inOutIdx += length;
8934
8935
    /* Get exponent */
8936
    ret = GetASNInt(input, inOutIdx, &length, inSz);
8937
    *key_e += *inOutIdx;
8938
    if (ret < 0) {
8939
        return ASN_RSA_KEY_E;
8940
    }
8941
    if (key_e_len)
8942
        *key_e_len = length;
8943
8944
    return ret;
8945
}
8946
#endif /* WOLFSSL_RENESAS_TSIP */
8947
8948
#ifdef WOLFSSL_ASN_TEMPLATE
8949
/* ASN.1 template for an RSA public key.
8950
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
8951
 * PKCS #1: RFC 8017, A.1.1 - RSAPublicKey
8952
 */
8953
static const ASNItem rsaPublicKeyASN[] = {
8954
/*  SEQ            */ { 0, ASN_SEQUENCE, 1, 1, 0 },
8955
/*  ALGOID_SEQ     */     { 1, ASN_SEQUENCE, 1, 1, 0 },
8956
/*  ALGOID_OID     */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
8957
/*  ALGOID_NULL    */         { 2, ASN_TAG_NULL, 0, 0, 1 },
8958
#ifdef WC_RSA_PSS
8959
/*  ALGOID_P_SEQ   */         { 2, ASN_SEQUENCE, 1, 0, 1 },
8960
#endif
8961
/*  PUBKEY         */     { 1, ASN_BIT_STRING, 0, 1, 0 },
8962
                                                  /* RSAPublicKey */
8963
/*  PUBKEY_RSA_SEQ */         { 2, ASN_SEQUENCE, 1, 1, 0 },
8964
/*  PUBKEY_RSA_N   */             { 3, ASN_INTEGER, 0, 0, 0 },
8965
/*  PUBKEY_RSA_E   */             { 3, ASN_INTEGER, 0, 0, 0 },
8966
};
8967
enum {
8968
    RSAPUBLICKEYASN_IDX_SEQ = 0,
8969
    RSAPUBLICKEYASN_IDX_ALGOID_SEQ,
8970
    RSAPUBLICKEYASN_IDX_ALGOID_OID,
8971
    RSAPUBLICKEYASN_IDX_ALGOID_NULL,
8972
#ifdef WC_RSA_PSS
8973
    RSAPUBLICKEYASN_IDX_ALGOID_P_SEQ,
8974
#endif
8975
    RSAPUBLICKEYASN_IDX_PUBKEY,
8976
    RSAPUBLICKEYASN_IDX_PUBKEY_RSA_SEQ,
8977
    RSAPUBLICKEYASN_IDX_PUBKEY_RSA_N,
8978
    RSAPUBLICKEYASN_IDX_PUBKEY_RSA_E,
8979
};
8980
8981
/* Number of items in ASN.1 template for an RSA public key. */
8982
#define rsaPublicKeyASN_Length (sizeof(rsaPublicKeyASN) / sizeof(ASNItem))
8983
#endif
8984
8985
/* Decode RSA public key.
8986
 *
8987
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
8988
 * PKCS #1: RFC 8017, A.1.1 - RSAPublicKey
8989
 *
8990
 * @param [in]      input     Buffer holding BER encoded data.
8991
 * @param [in, out] inOutIdx  On in, start of RSA public key.
8992
 *                            On out, start of ASN.1 item after RSA public key.
8993
 * @param [in]      inSz      Number of bytes in buffer.
8994
 * @param [out]     n         Pointer to modulus in buffer.
8995
 * @param [out]     nSz       Size of modulus in bytes.
8996
 * @param [out]     e         Pointer to exponent in buffer.
8997
 * @param [out]     eSz       Size of exponent in bytes.
8998
 * @return  0 on success.
8999
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
9000
 *          is invalid.
9001
 * @return  BUFFER_E when data in buffer is too small.
9002
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
9003
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
9004
 *          non-zero length.
9005
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
9006
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
9007
 */
9008
int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx, word32 inSz,
9009
    const byte** n, word32* nSz, const byte** e, word32* eSz)
9010
0
{
9011
0
#ifndef WOLFSSL_ASN_TEMPLATE
9012
0
    int ret = 0;
9013
0
    int length = 0;
9014
0
#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
9015
0
    word32 localIdx;
9016
0
    byte   tag;
9017
0
#endif
9018
9019
0
    if (input == NULL || inOutIdx == NULL)
9020
0
        return BAD_FUNC_ARG;
9021
9022
0
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
9023
0
        return ASN_PARSE_E;
9024
9025
0
#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
9026
0
    localIdx = *inOutIdx;
9027
0
    if (GetASNTag(input, &localIdx, &tag, inSz) < 0)
9028
0
        return BUFFER_E;
9029
9030
0
    if (tag != ASN_INTEGER) {
9031
        /* not from decoded cert, will have algo id, skip past */
9032
0
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
9033
0
            return ASN_PARSE_E;
9034
9035
0
        if (SkipObjectId(input, inOutIdx, inSz) < 0)
9036
0
            return ASN_PARSE_E;
9037
9038
        /* Option NULL ASN.1 tag */
9039
0
        if (*inOutIdx  >= inSz) {
9040
0
            return BUFFER_E;
9041
0
        }
9042
9043
0
        localIdx = *inOutIdx;
9044
0
        if (GetASNTag(input, &localIdx, &tag, inSz) < 0)
9045
0
            return ASN_PARSE_E;
9046
9047
0
        if (tag == ASN_TAG_NULL) {
9048
0
            ret = GetASNNull(input, inOutIdx, inSz);
9049
0
            if (ret != 0)
9050
0
                return ret;
9051
0
        }
9052
0
    #ifdef WC_RSA_PSS
9053
        /* Skip RSA PSS parameters. */
9054
0
        else if (tag == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
9055
0
            if (GetSequence(input, inOutIdx, &length, inSz) < 0)
9056
0
                return ASN_PARSE_E;
9057
0
            *inOutIdx += length;
9058
0
        }
9059
0
    #endif
9060
9061
        /* should have bit tag length and seq next */
9062
0
        ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);
9063
0
        if (ret != 0)
9064
0
            return ret;
9065
9066
0
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
9067
0
            return ASN_PARSE_E;
9068
0
    }
9069
0
#endif /* OPENSSL_EXTRA */
9070
9071
    /* Get modulus */
9072
0
    ret = GetASNInt(input, inOutIdx, &length, inSz);
9073
0
    if (ret < 0) {
9074
0
        return ASN_RSA_KEY_E;
9075
0
    }
9076
0
    if (nSz)
9077
0
        *nSz = length;
9078
0
    if (n)
9079
0
        *n = &input[*inOutIdx];
9080
0
    *inOutIdx += length;
9081
9082
    /* Get exponent */
9083
0
    ret = GetASNInt(input, inOutIdx, &length, inSz);
9084
0
    if (ret < 0) {
9085
0
        return ASN_RSA_KEY_E;
9086
0
    }
9087
0
    if (eSz)
9088
0
        *eSz = length;
9089
0
    if (e)
9090
0
        *e = &input[*inOutIdx];
9091
0
    *inOutIdx += length;
9092
9093
0
    return ret;
9094
#else
9095
    DECL_ASNGETDATA(dataASN, rsaPublicKeyASN_Length);
9096
    int ret = 0;
9097
#ifdef WC_RSA_PSS
9098
    word32 oid = RSAk;
9099
#endif
9100
9101
    /* Check validity of parameters. */
9102
    if (input == NULL || inOutIdx == NULL) {
9103
        ret = BAD_FUNC_ARG;
9104
    }
9105
9106
    CALLOC_ASNGETDATA(dataASN, rsaPublicKeyASN_Length, ret, NULL);
9107
9108
    if (ret == 0) {
9109
        /* Try decoding PKCS #1 public key by ignoring rest of ASN.1. */
9110
        ret = GetASN_Items(&rsaPublicKeyASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_SEQ],
9111
           &dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_SEQ],
9112
           (int)(rsaPublicKeyASN_Length - RSAPUBLICKEYASN_IDX_PUBKEY_RSA_SEQ),
9113
           0, input, inOutIdx, inSz);
9114
        if (ret != 0) {
9115
            /* Didn't work - try whole SubjectKeyInfo instead. */
9116
        #ifdef WC_RSA_PSS
9117
            /* Could be RSA or RSA PSS key. */
9118
            GetASN_OID(&dataASN[RSAPUBLICKEYASN_IDX_ALGOID_OID], oidKeyType);
9119
        #else
9120
            /* Set the OID to expect. */
9121
            GetASN_ExpBuffer(&dataASN[RSAPUBLICKEYASN_IDX_ALGOID_OID],
9122
                    keyRsaOid, sizeof(keyRsaOid));
9123
        #endif
9124
            /* Decode SubjectKeyInfo. */
9125
            ret = GetASN_Items(rsaPublicKeyASN, dataASN,
9126
                               rsaPublicKeyASN_Length, 1, input, inOutIdx,
9127
                               inSz);
9128
        }
9129
    }
9130
#ifdef WC_RSA_PSS
9131
    if ((ret == 0) && (dataASN[RSAPUBLICKEYASN_IDX_ALGOID_OID].tag != 0)) {
9132
        /* Two possible OIDs supported - RSA and RSA PSS. */
9133
        oid = dataASN[RSAPUBLICKEYASN_IDX_ALGOID_OID].data.oid.sum;
9134
        if ((oid != RSAk) && (oid != RSAPSSk)) {
9135
            ret = ASN_PARSE_E;
9136
        }
9137
    }
9138
    if ((ret == 0) && (dataASN[RSAPUBLICKEYASN_IDX_ALGOID_P_SEQ].tag != 0)) {
9139
        /* Can't have NULL and SEQ. */
9140
        if (dataASN[RSAPUBLICKEYASN_IDX_ALGOID_NULL].tag != 0) {
9141
            ret = ASN_PARSE_E;
9142
        }
9143
        /* SEQ present only with RSA PSS. */
9144
        if ((ret == 0) && (oid != RSAPSSk)) {
9145
            ret = ASN_PARSE_E;
9146
        }
9147
        if (ret == 0) {
9148
            enum wc_HashType hash;
9149
            int mgf;
9150
            int saltLen;
9151
            const byte* params = GetASNItem_Addr(
9152
                dataASN[RSAPUBLICKEYASN_IDX_ALGOID_P_SEQ], input);
9153
            word32 paramsSz = GetASNItem_Length(
9154
                dataASN[RSAPUBLICKEYASN_IDX_ALGOID_P_SEQ], input);
9155
9156
            /* Validate the private key parameters. */
9157
            ret = DecodeRsaPssParams(params, paramsSz, &hash, &mgf, &saltLen);
9158
            /* TODO: store parameters so that usage can be checked. */
9159
        }
9160
    }
9161
#endif
9162
    if (ret == 0) {
9163
        /* Return the buffers and lengths asked for. */
9164
        if (n != NULL) {
9165
            *n   = dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_N].data.ref.data;
9166
        }
9167
        if (nSz != NULL) {
9168
            *nSz = dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_N].data.ref.length;
9169
        }
9170
        if (e != NULL) {
9171
            *e   = dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_E].data.ref.data;
9172
        }
9173
        if (eSz != NULL) {
9174
            *eSz = dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_E].data.ref.length;
9175
        }
9176
    }
9177
9178
    FREE_ASNGETDATA(dataASN, NULL);
9179
    return ret;
9180
#endif /* WOLFSSL_ASN_TEMPLATE */
9181
0
}
9182
9183
/* Decode RSA public key.
9184
 *
9185
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
9186
 * PKCS #1: RFC 8017, A.1.1 - RSAPublicKey
9187
 *
9188
 * @param [in]      input     Buffer holding BER encoded data.
9189
 * @param [in, out] inOutIdx  On in, start of RSA public key.
9190
 *                            On out, start of ASN.1 item after RSA public key.
9191
 * @param [in, out] key       RSA key object.
9192
 * @param [in]      inSz      Number of bytes in buffer.
9193
 * @return  0 on success.
9194
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
9195
 *          is invalid.
9196
 * @return  BUFFER_E when data in buffer is too small.
9197
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
9198
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
9199
 *          non-zero length.
9200
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
9201
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
9202
 */
9203
int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
9204
                       word32 inSz)
9205
0
{
9206
0
#ifndef WOLFSSL_ASN_TEMPLATE
9207
0
    int ret;
9208
0
    const byte *n = NULL, *e = NULL;
9209
0
    word32 nSz = 0, eSz = 0;
9210
9211
0
    if (key == NULL)
9212
0
        return BAD_FUNC_ARG;
9213
9214
0
    ret = wc_RsaPublicKeyDecode_ex(input, inOutIdx, inSz, &n, &nSz, &e, &eSz);
9215
0
    if (ret == 0) {
9216
0
        ret = wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz, key);
9217
0
    }
9218
9219
0
    return ret;
9220
#else
9221
    DECL_ASNGETDATA(dataASN, rsaPublicKeyASN_Length);
9222
    int ret = 0;
9223
9224
    /* Check validity of parameters. */
9225
    if ((input == NULL) || (inOutIdx == NULL) || (key == NULL)) {
9226
        ret = BAD_FUNC_ARG;
9227
    }
9228
9229
    CALLOC_ASNGETDATA(dataASN, rsaPublicKeyASN_Length, ret, NULL);
9230
9231
    if (ret == 0) {
9232
        /* Set mp_ints to fill with modulus and exponent data. */
9233
        GetASN_MP(&dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_N], &key->n);
9234
        GetASN_MP(&dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_E], &key->e);
9235
        /* Try decoding PKCS #1 public key by ignoring rest of ASN.1. */
9236
        ret = GetASN_Items(&rsaPublicKeyASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_SEQ],
9237
               &dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_SEQ],
9238
               (int)(rsaPublicKeyASN_Length - RSAPUBLICKEYASN_IDX_PUBKEY_RSA_SEQ),
9239
               0, input, inOutIdx, inSz);
9240
        if (ret != 0) {
9241
            /* Didn't work - try whole SubjectKeyInfo instead. */
9242
            /* Set the OID to expect. */
9243
            GetASN_ExpBuffer(&dataASN[RSAPUBLICKEYASN_IDX_ALGOID_OID],
9244
                    keyRsaOid, sizeof(keyRsaOid));
9245
            /* Decode SubjectKeyInfo. */
9246
            ret = GetASN_Items(rsaPublicKeyASN, dataASN,
9247
                               rsaPublicKeyASN_Length, 1, input, inOutIdx,
9248
                               inSz);
9249
        }
9250
    }
9251
9252
    FREE_ASNGETDATA(dataASN, NULL);
9253
    return ret;
9254
#endif
9255
0
}
9256
9257
/* import RSA public key elements (n, e) into RsaKey structure (key) */
9258
int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e,
9259
                             word32 eSz, RsaKey* key)
9260
0
{
9261
0
    if (n == NULL || e == NULL || key == NULL)
9262
0
        return BAD_FUNC_ARG;
9263
9264
0
    key->type = RSA_PUBLIC;
9265
9266
0
    if (mp_init(&key->n) != MP_OKAY)
9267
0
        return MP_INIT_E;
9268
9269
0
    if (mp_read_unsigned_bin(&key->n, n, nSz) != 0) {
9270
0
        mp_clear(&key->n);
9271
0
        return ASN_GETINT_E;
9272
0
    }
9273
#ifdef HAVE_WOLF_BIGINT
9274
    if ((int)nSz > 0 && wc_bigint_from_unsigned_bin(&key->n.raw, n, nSz) != 0) {
9275
        mp_clear(&key->n);
9276
        return ASN_GETINT_E;
9277
    }
9278
#endif /* HAVE_WOLF_BIGINT */
9279
9280
0
    if (mp_init(&key->e) != MP_OKAY) {
9281
0
        mp_clear(&key->n);
9282
0
        return MP_INIT_E;
9283
0
    }
9284
9285
0
    if (mp_read_unsigned_bin(&key->e, e, eSz) != 0) {
9286
0
        mp_clear(&key->n);
9287
0
        mp_clear(&key->e);
9288
0
        return ASN_GETINT_E;
9289
0
    }
9290
#ifdef HAVE_WOLF_BIGINT
9291
    if ((int)eSz > 0 && wc_bigint_from_unsigned_bin(&key->e.raw, e, eSz) != 0) {
9292
        mp_clear(&key->n);
9293
        mp_clear(&key->e);
9294
        return ASN_GETINT_E;
9295
    }
9296
#endif /* HAVE_WOLF_BIGINT */
9297
9298
#ifdef WOLFSSL_XILINX_CRYPT
9299
    if (wc_InitRsaHw(key) != 0) {
9300
        return BAD_STATE_E;
9301
    }
9302
#endif
9303
9304
0
    return 0;
9305
0
}
9306
#endif /* HAVE_USER_RSA */
9307
#endif /* !NO_RSA */
9308
9309
#ifndef NO_DH
9310
#if defined(WOLFSSL_DH_EXTRA)
9311
/*
9312
 * Decodes DH public key to fill specified DhKey.
9313
 *
9314
 * return 0 on success, negative on failure
9315
 */
9316
int wc_DhPublicKeyDecode(const byte* input, word32* inOutIdx,
9317
                DhKey* key, word32 inSz)
9318
{
9319
    int ret = 0;
9320
    int length;
9321
    word32 oid = 0;
9322
9323
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
9324
        return BAD_FUNC_ARG;
9325
9326
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
9327
        return ASN_PARSE_E;
9328
9329
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
9330
        return ASN_PARSE_E;
9331
9332
    ret = GetObjectId(input, inOutIdx, &oid, oidKeyType, inSz);
9333
    if (oid != DHk || ret < 0)
9334
        return ASN_DH_KEY_E;
9335
9336
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
9337
        return ASN_PARSE_E;
9338
9339
    if (GetInt(&key->p, input, inOutIdx, inSz) < 0)
9340
        return ASN_DH_KEY_E;
9341
9342
    if (GetInt(&key->g, input, inOutIdx, inSz) < 0) {
9343
        mp_clear(&key->p);
9344
        return ASN_DH_KEY_E;
9345
    }
9346
    ret = (CheckBitString(input, inOutIdx, &length, inSz, 0, NULL) == 0);
9347
    if (ret > 0) {
9348
        /* Found Bit String WOLFSSL_DH_EXTRA is required to access DhKey.pub */
9349
        if (GetInt(&key->pub, input, inOutIdx, inSz) < 0) {
9350
            mp_clear(&key->p);
9351
            mp_clear(&key->g);
9352
            return ASN_DH_KEY_E;
9353
        }
9354
    }
9355
    else {
9356
        mp_clear(&key->p);
9357
        mp_clear(&key->g);
9358
        return ASN_DH_KEY_E;
9359
    }
9360
    return 0;
9361
}
9362
#endif /* WOLFSSL_DH_EXTRA */
9363
9364
#ifdef WOLFSSL_ASN_TEMPLATE
9365
/* ASN.1 template for DH key.
9366
 * PKCS #3, 9 - DHParameter.
9367
 * (Also in: RFC 2786, 3)
9368
 */
9369
static const ASNItem dhParamASN[] = {
9370
/* SEQ     */    { 0, ASN_SEQUENCE, 1, 1, 0 },
9371
                /* prime */
9372
/* PRIME   */        { 1, ASN_INTEGER, 0, 0, 0 },
9373
                /* base */
9374
/* BASE    */        { 1, ASN_INTEGER, 0, 0, 0 },
9375
                /* privateValueLength */
9376
/* PRIVLEN */        { 1, ASN_INTEGER, 0, 0, 1 },
9377
};
9378
enum {
9379
    DHPARAMASN_IDX_SEQ = 0,
9380
    DHPARAMASN_IDX_PRIME,
9381
    DHPARAMASN_IDX_BASE,
9382
    DHPARAMASN_IDX_PRIVLEN,
9383
};
9384
9385
/* Number of items in ASN.1 template for DH key. */
9386
#define dhParamASN_Length (sizeof(dhParamASN) / sizeof(ASNItem))
9387
9388
#ifdef WOLFSSL_DH_EXTRA
9389
/* ASN.1 template for DH key wrapped in PKCS #8 or SubjectPublicKeyInfo.
9390
 * PKCS #8: RFC 5208, 5 - PrivateKeyInfo
9391
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
9392
 * RFC 3279, 2.3.3 - DH in SubjectPublicKeyInfo
9393
 */
9394
static const ASNItem dhKeyPkcs8ASN[] = {
9395
/* SEQ                  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
9396
/* VER                  */     { 1, ASN_INTEGER, 0, 0, 1 },
9397
/* PKEYALGO_SEQ         */     { 1, ASN_SEQUENCE, 1, 1, 0 },
9398
/* PKEYALGO_OID         */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
9399
                                                     /* DHParameter */
9400
/* PKEYALGO_PARAM_SEQ   */         { 2, ASN_SEQUENCE, 1, 1, 0 },
9401
                                                         /* p */
9402
/* PKEYALGO_PARAM_P     */             { 3, ASN_INTEGER, 0, 0, 0 },
9403
                                                         /* g */
9404
/* PKEYALGO_PARAM_G     */             { 3, ASN_INTEGER, 0, 0, 0 },
9405
                                                         /* q - factor of p-1 */
9406
/* PKEYALGO_PARAM_Q     */             { 3, ASN_INTEGER, 0, 0, 1 },
9407
                                                         /* j - subgroup factor */
9408
/* PKEYALGO_PARAM_J     */             { 3, ASN_INTEGER, 0, 0, 1 },
9409
                                                         /* ValidationParms */
9410
/* PKEYALGO_PARAM_VALID */             { 3, ASN_SEQUENCE, 0, 0, 1 },
9411
                                                 /* PrivateKey - PKCS #8 */
9412
/* PKEY_STR             */     { 1, ASN_OCTET_STRING, 0, 1, 2 },
9413
/* PKEY_INT             */         { 2, ASN_INTEGER, 0, 0, 0 },
9414
                                                 /* PublicKey - SubjectPublicKeyInfo. */
9415
/* PUBKEY_STR           */     { 1, ASN_BIT_STRING, 0, 1, 2 },
9416
/* PUBKEY_INT           */         { 2, ASN_INTEGER, 0, 0, 0 },
9417
};
9418
enum {
9419
    DHKEYPKCS8ASN_IDX_SEQ = 0,
9420
    DHKEYPKCS8ASN_IDX_VER,
9421
    DHKEYPKCS8ASN_IDX_PKEYALGO_SEQ,
9422
    DHKEYPKCS8ASN_IDX_PKEYALGO_OID,
9423
    DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_SEQ,
9424
    DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_P,
9425
    DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_G,
9426
    DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_Q,
9427
    DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_J,
9428
    DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_VALID,
9429
    DHKEYPKCS8ASN_IDX_PKEY_STR,
9430
    DHKEYPKCS8ASN_IDX_PKEY_INT,
9431
    DHKEYPKCS8ASN_IDX_PUBKEY_STR,
9432
    DHKEYPKCS8ASN_IDX_PUBKEY_INT,
9433
};
9434
9435
#define dhKeyPkcs8ASN_Length (sizeof(dhKeyPkcs8ASN) / sizeof(ASNItem))
9436
#endif
9437
#endif
9438
9439
/* Decodes either PKCS#3 DH parameters or PKCS#8 DH key file (WOLFSSL_DH_EXTRA).
9440
 *
9441
 * See also wc_DhParamsLoad(). Loads directly into buffers rather than key
9442
 * object.
9443
 *
9444
 * @param [in]      input     BER/DER encoded data.
9445
 * @param [in, out] inOutIdx  On in, start of DH key data.
9446
 *                            On out, end of DH key data.
9447
 * @param [in, out] key       DH key object.
9448
 * @param [in]      inSz      Size of data in bytes.
9449
 * @return  0 on success.
9450
 * @return  BAD_FUNC_ARG when input, inOutIDx or key is NULL.
9451
 * @return  MEMORY_E when dynamic memory allocation fails.
9452
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
9453
 *          is invalid.
9454
 * @return  BUFFER_E when data in buffer is too small.
9455
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
9456
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
9457
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
9458
 *          non-zero length.
9459
 * @return  MP_INIT_E when the unable to initialize an mp_int.
9460
 * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
9461
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
9462
 */
9463
int wc_DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32 inSz)
9464
0
{
9465
0
#ifndef WOLFSSL_ASN_TEMPLATE
9466
0
    int ret = 0;
9467
0
    int length;
9468
#ifdef WOLFSSL_DH_EXTRA
9469
    #if !defined(HAVE_FIPS) || \
9470
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
9471
    word32 oid = 0, temp = 0;
9472
    #endif
9473
#endif
9474
9475
0
    WOLFSSL_ENTER("wc_DhKeyDecode");
9476
9477
0
    if (inOutIdx == NULL)
9478
0
        return BAD_FUNC_ARG;
9479
9480
0
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
9481
0
        return ASN_PARSE_E;
9482
9483
#ifdef WOLFSSL_DH_EXTRA
9484
    #if !defined(HAVE_FIPS) || \
9485
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
9486
    temp = *inOutIdx;
9487
    #endif
9488
#endif
9489
    /* Assume input started after 1.2.840.113549.1.3.1 dhKeyAgreement */
9490
0
    if (GetInt(&key->p, input, inOutIdx, inSz) < 0) {
9491
0
        ret = ASN_DH_KEY_E;
9492
0
    }
9493
0
    if (ret == 0 && GetInt(&key->g, input, inOutIdx, inSz) < 0) {
9494
0
        mp_clear(&key->p);
9495
0
        ret = ASN_DH_KEY_E;
9496
0
    }
9497
9498
#ifdef WOLFSSL_DH_EXTRA
9499
    #if !defined(HAVE_FIPS) || \
9500
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
9501
    /* If ASN_DH_KEY_E: Check if input started at beginning of key */
9502
    if (ret == ASN_DH_KEY_E) {
9503
        *inOutIdx = temp;
9504
9505
        /* the version (0) - private only (for public skip) */
9506
        if (GetASNInt(input, inOutIdx, &length, inSz) == 0) {
9507
            *inOutIdx += length;
9508
        }
9509
9510
        /* Size of dhKeyAgreement section */
9511
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
9512
            return ASN_PARSE_E;
9513
9514
        /* Check for dhKeyAgreement */
9515
        ret = GetObjectId(input, inOutIdx, &oid, oidKeyType, inSz);
9516
        if (oid != DHk || ret < 0)
9517
            return ASN_DH_KEY_E;
9518
9519
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
9520
            return ASN_PARSE_E;
9521
9522
        if (GetInt(&key->p, input, inOutIdx, inSz) < 0) {
9523
            return ASN_DH_KEY_E;
9524
        }
9525
        if (ret == 0 && GetInt(&key->g, input, inOutIdx, inSz) < 0) {
9526
            mp_clear(&key->p);
9527
            return ASN_DH_KEY_E;
9528
        }
9529
    }
9530
9531
    temp = *inOutIdx;
9532
    ret = (CheckBitString(input, inOutIdx, &length, inSz, 0, NULL) == 0);
9533
    if (ret > 0) {
9534
        /* Found Bit String */
9535
        if (GetInt(&key->pub, input, inOutIdx, inSz) == 0) {
9536
            WOLFSSL_MSG("Found Public Key");
9537
            ret = 0;
9538
        }
9539
    } else {
9540
        *inOutIdx = temp;
9541
        ret = (GetOctetString(input, inOutIdx, &length, inSz) >= 0);
9542
        if (ret > 0) {
9543
            /* Found Octet String */
9544
            if (GetInt(&key->priv, input, inOutIdx, inSz) == 0) {
9545
                WOLFSSL_MSG("Found Private Key");
9546
9547
                /* Compute public */
9548
                ret = mp_exptmod(&key->g, &key->priv, &key->p, &key->pub);
9549
            }
9550
        } else {
9551
            /* Don't use length from failed CheckBitString/GetOctetString */
9552
            *inOutIdx = temp;
9553
            ret = 0;
9554
        }
9555
    }
9556
    #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
9557
#endif /* WOLFSSL_DH_EXTRA */
9558
9559
0
    WOLFSSL_LEAVE("wc_DhKeyDecode", ret);
9560
9561
0
    return ret;
9562
#else
9563
#ifdef WOLFSSL_DH_EXTRA
9564
    DECL_ASNGETDATA(dataASN, dhKeyPkcs8ASN_Length);
9565
#else
9566
    DECL_ASNGETDATA(dataASN, dhParamASN_Length);
9567
#endif
9568
    int ret = 0;
9569
9570
    /* Check input parameters are valid. */
9571
    if ((input == NULL) || (inOutIdx == NULL) || (key == NULL)) {
9572
        ret = BAD_FUNC_ARG;
9573
    }
9574
9575
#ifdef WOLFSSL_DH_EXTRA
9576
    ALLOC_ASNGETDATA(dataASN, dhKeyPkcs8ASN_Length, ret, key->heap);
9577
#else
9578
    ALLOC_ASNGETDATA(dataASN, dhParamASN_Length, ret, key->heap);
9579
#endif
9580
9581
    if (ret == 0) {
9582
        /* Initialize data and set mp_ints to hold p and g. */
9583
        XMEMSET(dataASN, 0, sizeof(*dataASN) * dhParamASN_Length);
9584
        GetASN_MP(&dataASN[DHPARAMASN_IDX_PRIME], &key->p);
9585
        GetASN_MP(&dataASN[DHPARAMASN_IDX_BASE], &key->g);
9586
        /* Try simple PKCS #3 template. */
9587
        ret = GetASN_Items(dhParamASN, dataASN, dhParamASN_Length, 1, input,
9588
                           inOutIdx, inSz);
9589
#ifdef WOLFSSL_DH_EXTRA
9590
        if (ret != 0) {
9591
            /* Initialize data and set mp_ints to hold p, g, q, priv and pub. */
9592
            XMEMSET(dataASN, 0, sizeof(*dataASN) * dhKeyPkcs8ASN_Length);
9593
            GetASN_ExpBuffer(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_OID],
9594
                    keyDhOid, sizeof(keyDhOid));
9595
            GetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_P], &key->p);
9596
            GetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_G], &key->g);
9597
            GetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_Q], &key->q);
9598
            GetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEY_INT], &key->priv);
9599
            GetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PUBKEY_INT], &key->pub);
9600
            /* Try PKCS #8 wrapped template. */
9601
            ret = GetASN_Items(dhKeyPkcs8ASN, dataASN, dhKeyPkcs8ASN_Length, 1,
9602
                               input, inOutIdx, inSz);
9603
            if (ret == 0) {
9604
                /* VERSION only present in PKCS #8 private key structure */
9605
                if ((dataASN[DHKEYPKCS8ASN_IDX_PKEY_INT].length != 0) &&
9606
                        (dataASN[DHKEYPKCS8ASN_IDX_VER].length == 0)) {
9607
                    ret = ASN_PARSE_E;
9608
                }
9609
                else if ((dataASN[DHKEYPKCS8ASN_IDX_PUBKEY_INT].length != 0) &&
9610
                        (dataASN[DHKEYPKCS8ASN_IDX_VER].length != 0)) {
9611
                    ret = ASN_PARSE_E;
9612
                }
9613
            }
9614
        }
9615
#endif
9616
    }
9617
9618
    FREE_ASNGETDATA(dataASN, key->heap);
9619
    return ret;
9620
#endif /* WOLFSSL_ASN_TEMPLATE */
9621
0
}
9622
9623
#ifdef WOLFSSL_DH_EXTRA
9624
9625
/* Export DH Key (private or public) */
9626
int wc_DhKeyToDer(DhKey* key, byte* output, word32* outSz, int exportPriv)
9627
{
9628
#ifndef WOLFSSL_ASN_TEMPLATE
9629
    int ret, privSz = 0, pubSz = 0, keySz;
9630
    word32 idx, len, total;
9631
9632
    if (key == NULL || outSz == NULL) {
9633
        return BAD_FUNC_ARG;
9634
    }
9635
9636
    /* determine size */
9637
    if (exportPriv) {
9638
        /* octect string: priv */
9639
        privSz = SetASNIntMP(&key->priv, -1, NULL);
9640
        idx = 1 + SetLength(privSz, NULL) + privSz; /* +1 for ASN_OCTET_STRING */
9641
    }
9642
    else {
9643
        /* bit string: public */
9644
        pubSz = SetASNIntMP(&key->pub, -1, NULL);
9645
        idx = SetBitString(pubSz, 0, NULL) + pubSz;
9646
    }
9647
    keySz = idx;
9648
9649
    /* DH Parameters sequence with P and G */
9650
    total = 0;
9651
    ret = wc_DhParamsToDer(key, NULL, &total);
9652
    if (ret != LENGTH_ONLY_E)
9653
        return ret;
9654
    idx += total;
9655
9656
    /* object dhKeyAgreement 1.2.840.113549.1.3.1 */
9657
    idx += SetObjectId(sizeof(keyDhOid), NULL);
9658
    idx += sizeof(keyDhOid);
9659
    len = idx - keySz;
9660
    /* sequence - all but pub/priv */
9661
    idx += SetSequence(len, NULL);
9662
    if (exportPriv) {
9663
        /* version: 0 (ASN_INTEGER, 0x01, 0x00) */
9664
        idx += 3;
9665
    }
9666
    /* sequence */
9667
    total = idx + SetSequence(idx, NULL);
9668
9669
    /* if no output, then just getting size */
9670
    if (output == NULL) {
9671
        *outSz = total;
9672
        return LENGTH_ONLY_E;
9673
    }
9674
9675
    /* make sure output fits in buffer */
9676
    if (total > *outSz) {
9677
        return BUFFER_E;
9678
    }
9679
    total = idx;
9680
9681
    /* sequence */
9682
    idx = SetSequence(total, output);
9683
    if (exportPriv) {
9684
        /* version: 0 */
9685
        idx += SetMyVersion(0, output + idx, 0);
9686
    }
9687
    /* sequence - all but pub/priv */
9688
    idx += SetSequence(len, output + idx);
9689
    /* object dhKeyAgreement 1.2.840.113549.1.3.1 */
9690
    idx += SetObjectId(sizeof(keyDhOid), output + idx);
9691
    XMEMCPY(output + idx, keyDhOid, sizeof(keyDhOid));
9692
    idx += sizeof(keyDhOid);
9693
9694
    /* DH Parameters sequence with P and G */
9695
    total = *outSz - idx;
9696
    ret = wc_DhParamsToDer(key, output + idx, &total);
9697
    if (ret < 0)
9698
        return ret;
9699
    idx += total;
9700
9701
    /* octect string: priv */
9702
    if (exportPriv) {
9703
        idx += SetOctetString(privSz, output + idx);
9704
        idx += SetASNIntMP(&key->priv, -1, output + idx);
9705
    }
9706
    else {
9707
        /* bit string: public */
9708
        idx += SetBitString(pubSz, 0, output + idx);
9709
        idx += SetASNIntMP(&key->pub, -1, output + idx);
9710
    }
9711
    *outSz = idx;
9712
9713
    return idx;
9714
#else
9715
    ASNSetData dataASN[dhKeyPkcs8ASN_Length];
9716
    int ret = 0;
9717
    int sz;
9718
9719
    WOLFSSL_ENTER("wc_DhKeyToDer");
9720
9721
    XMEMSET(dataASN, 0, sizeof(dataASN));
9722
    SetASN_Int8Bit(&dataASN[DHKEYPKCS8ASN_IDX_VER], 0);
9723
    SetASN_OID(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_OID], DHk, oidKeyType);
9724
    /* Set mp_int containing p and g. */
9725
    SetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_P], &key->p);
9726
    SetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_G], &key->g);
9727
    dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_Q].noOut = 1;
9728
    dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_J].noOut = 1;
9729
    dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_VALID].noOut = 1;
9730
9731
    if (exportPriv) {
9732
        SetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEY_INT], &key->priv);
9733
        dataASN[DHKEYPKCS8ASN_IDX_PUBKEY_STR].noOut = 1;
9734
        dataASN[DHKEYPKCS8ASN_IDX_PUBKEY_INT].noOut = 1;
9735
    }
9736
    else {
9737
        dataASN[DHKEYPKCS8ASN_IDX_VER].noOut = 1;
9738
        dataASN[DHKEYPKCS8ASN_IDX_PKEY_STR].noOut = 1;
9739
        dataASN[DHKEYPKCS8ASN_IDX_PKEY_INT].noOut = 1;
9740
        SetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PUBKEY_INT], &key->pub);
9741
    }
9742
9743
    /* Calculate the size of the DH parameters. */
9744
    ret = SizeASN_Items(dhKeyPkcs8ASN, dataASN, dhKeyPkcs8ASN_Length, &sz);
9745
    if (output == NULL) {
9746
        *outSz = sz;
9747
        ret = LENGTH_ONLY_E;
9748
    }
9749
    /* Check buffer is big enough for encoding. */
9750
    if ((ret == 0) && ((int)*outSz < sz)) {
9751
        ret = BUFFER_E;
9752
    }
9753
    if (ret == 0) {
9754
        /* Encode the DH parameters into buffer. */
9755
        SetASN_Items(dhKeyPkcs8ASN, dataASN, dhKeyPkcs8ASN_Length, output);
9756
        /* Set the actual encoding size. */
9757
        *outSz = sz;
9758
        /* Return the actual encoding size. */
9759
        ret = sz;
9760
    }
9761
9762
    return ret;
9763
#endif
9764
}
9765
9766
int wc_DhPubKeyToDer(DhKey* key, byte* out, word32* outSz)
9767
{
9768
    return wc_DhKeyToDer(key, out, outSz, 0);
9769
}
9770
int wc_DhPrivKeyToDer(DhKey* key, byte* out, word32* outSz)
9771
{
9772
    return wc_DhKeyToDer(key, out, outSz, 1);
9773
}
9774
9775
9776
/* Convert DH key parameters to DER format, write to output (outSz)
9777
 * If output is NULL then max expected size is set to outSz and LENGTH_ONLY_E is
9778
 * returned.
9779
 *
9780
 * Note : static function due to redefinition complications with DhKey and FIPS
9781
 * version 2 build.
9782
 *
9783
 * return bytes written on success */
9784
int wc_DhParamsToDer(DhKey* key, byte* output, word32* outSz)
9785
{
9786
#ifndef WOLFSSL_ASN_TEMPLATE
9787
    word32 idx, total;
9788
9789
    if (key == NULL || outSz == NULL) {
9790
        return BAD_FUNC_ARG;
9791
    }
9792
9793
    /* determine size */
9794
    /* integer - g */
9795
    idx = SetASNIntMP(&key->g, -1, NULL);
9796
    /* integer - p */
9797
    idx += SetASNIntMP(&key->p, -1, NULL);
9798
    total = idx;
9799
     /* sequence */
9800
    idx += SetSequence(idx, NULL);
9801
9802
    if (output == NULL) {
9803
        *outSz = idx;
9804
        return LENGTH_ONLY_E;
9805
    }
9806
    /* make sure output fits in buffer */
9807
    if (idx > *outSz) {
9808
        return BUFFER_E;
9809
    }
9810
9811
9812
    /* write DH parameters */
9813
    /* sequence - for P and G only */
9814
    idx = SetSequence(total, output);
9815
    /* integer - p */
9816
    idx += SetASNIntMP(&key->p, -1, output + idx);
9817
    /* integer - g */
9818
    idx += SetASNIntMP(&key->g, -1, output + idx);
9819
    *outSz = idx;
9820
9821
    return idx;
9822
#else
9823
    ASNSetData dataASN[dhParamASN_Length];
9824
    int ret = 0;
9825
    int sz = 0;
9826
9827
    WOLFSSL_ENTER("wc_DhParamsToDer");
9828
9829
    if (key == NULL || outSz == NULL) {
9830
        ret = BAD_FUNC_ARG;
9831
    }
9832
9833
    if (ret == 0) {
9834
        XMEMSET(dataASN, 0, sizeof(dataASN));
9835
        /* Set mp_int containing p and g. */
9836
        SetASN_MP(&dataASN[DHPARAMASN_IDX_PRIME], &key->p);
9837
        SetASN_MP(&dataASN[DHPARAMASN_IDX_BASE], &key->g);
9838
        /* privateValueLength not encoded. */
9839
        dataASN[DHPARAMASN_IDX_PRIVLEN].noOut = 1;
9840
9841
        /* Calculate the size of the DH parameters. */
9842
        ret = SizeASN_Items(dhParamASN, dataASN, dhParamASN_Length, &sz);
9843
    }
9844
    if ((ret == 0) && (output == NULL)) {
9845
        *outSz = sz;
9846
        ret = LENGTH_ONLY_E;
9847
    }
9848
    /* Check buffer is big enough for encoding. */
9849
    if ((ret == 0) && ((int)*outSz < sz)) {
9850
        ret = BUFFER_E;
9851
    }
9852
    if (ret == 0) {
9853
        /* Encode the DH parameters into buffer. */
9854
        SetASN_Items(dhParamASN, dataASN, dhParamASN_Length, output);
9855
        /* Set the actual encoding size. */
9856
        *outSz = sz;
9857
        /* Return count of bytes written. */
9858
        ret = sz;
9859
    }
9860
9861
    return ret;
9862
#endif
9863
}
9864
9865
#endif /* WOLFSSL_DH_EXTRA */
9866
9867
/* Decode DH parameters.
9868
 *
9869
 * PKCS #3, 9 - DHParameter.
9870
 * (Also in: RFC 2786, 3)
9871
 *
9872
 * @param [in]      input     Buffer holding BER encoded data.
9873
 * @param [in, out] inOutIdx  On in, start of RSA public key.
9874
 *                            On out, start of ASN.1 item after RSA public key.
9875
 * @param [in]      inSz      Number of bytes in buffer.
9876
 * @param [in, out] p         Buffer to hold prime.
9877
 * @param [out]     pInOutSz  On in, size of buffer to hold prime in bytes.
9878
 *                            On out, size of prime in bytes.
9879
 * @param [in, out] g         Buffer to hold base.
9880
 * @param [out]     gInOutSz  On in, size of buffer to hold base in bytes.
9881
 *                            On out, size of base in bytes.
9882
 * @return  0 on success.
9883
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
9884
 *          is invalid.
9885
 * @return  BUFFER_E when data in buffer is too small.
9886
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set.
9887
 */
9888
int wc_DhParamsLoad(const byte* input, word32 inSz, byte* p, word32* pInOutSz,
9889
                 byte* g, word32* gInOutSz)
9890
0
{
9891
0
#ifndef WOLFSSL_ASN_TEMPLATE
9892
0
    word32 idx = 0;
9893
0
    int    ret;
9894
0
    int    length;
9895
9896
0
    if (GetSequence(input, &idx, &length, inSz) <= 0)
9897
0
        return ASN_PARSE_E;
9898
9899
0
    ret = GetASNInt(input, &idx, &length, inSz);
9900
0
    if (ret != 0)
9901
0
        return ret;
9902
9903
0
    if (length <= (int)*pInOutSz) {
9904
0
        XMEMCPY(p, &input[idx], length);
9905
0
        *pInOutSz = length;
9906
0
    }
9907
0
    else {
9908
0
        return BUFFER_E;
9909
0
    }
9910
0
    idx += length;
9911
9912
0
    ret = GetASNInt(input, &idx, &length, inSz);
9913
0
    if (ret != 0)
9914
0
        return ret;
9915
9916
0
    if (length <= (int)*gInOutSz) {
9917
0
        XMEMCPY(g, &input[idx], length);
9918
0
        *gInOutSz = length;
9919
0
    }
9920
0
    else {
9921
0
        return BUFFER_E;
9922
0
    }
9923
9924
0
    return 0;
9925
#else
9926
    DECL_ASNGETDATA(dataASN, dhParamASN_Length);
9927
    word32 idx = 0;
9928
    int ret = 0;
9929
9930
    /* Make sure pointers are valid before use. */
9931
    if ((input == NULL) || (p == NULL) || (pInOutSz == NULL) || (g == NULL) ||
9932
            (gInOutSz == NULL)) {
9933
        ret = BAD_FUNC_ARG;
9934
    }
9935
9936
    CALLOC_ASNGETDATA(dataASN, dhParamASN_Length, ret, NULL);
9937
9938
    if (ret == 0) {
9939
        /* Set the buffers to copy p and g into. */
9940
        GetASN_Buffer(&dataASN[DHPARAMASN_IDX_PRIME], p, pInOutSz);
9941
        GetASN_Buffer(&dataASN[DHPARAMASN_IDX_BASE], g, gInOutSz);
9942
        /* Decode the DH Parameters. */
9943
        ret = GetASN_Items(dhParamASN, dataASN, dhParamASN_Length, 1, input,
9944
                           &idx, inSz);
9945
    }
9946
9947
    FREE_ASNGETDATA(dataASN, NULL);
9948
    return ret;
9949
#endif /* WOLFSSL_ASN_TEMPLATE */
9950
0
}
9951
#endif /* !NO_DH */
9952
9953
9954
#ifndef NO_DSA
9955
9956
static mp_int* GetDsaInt(DsaKey* key, int idx)
9957
{
9958
    if (idx == 0)
9959
        return &key->p;
9960
    if (idx == 1)
9961
        return &key->q;
9962
    if (idx == 2)
9963
        return &key->g;
9964
    if (idx == 3)
9965
        return &key->y;
9966
    if (idx == 4)
9967
        return &key->x;
9968
9969
    return NULL;
9970
}
9971
9972
#ifdef WOLFSSL_ASN_TEMPLATE
9973
/* ASN.1 template for DSA public and private keys.
9974
 * Public key: seq, p, q, g, y
9975
 * Private key: seq, version, p, q, g, y, x
9976
 * RFC 3279, 2.3.2 - DSA in SubjectPublicKeyInfo
9977
 */
9978
static const ASNItem dsaKeyASN[] = {
9979
/* SEQ */    { 0, ASN_SEQUENCE, 1, 1, 0 },
9980
/* VER */        { 1, ASN_INTEGER, 0, 0, 0 },
9981
/* P   */        { 1, ASN_INTEGER, 0, 0, 0 },
9982
/* Q   */        { 1, ASN_INTEGER, 0, 0, 0 },
9983
/* G   */        { 1, ASN_INTEGER, 0, 0, 0 },
9984
/* Y   */        { 1, ASN_INTEGER, 0, 0, 0 },
9985
/* X   */        { 1, ASN_INTEGER, 0, 0, 0 },
9986
};
9987
enum {
9988
    DSAKEYASN_IDX_SEQ = 0,
9989
    DSAKEYASN_IDX_VER,
9990
    DSAKEYASN_IDX_P,
9991
    DSAKEYASN_IDX_Q,
9992
    DSAKEYASN_IDX_G,
9993
    DSAKEYASN_IDX_Y,
9994
    DSAKEYASN_IDX_X,
9995
};
9996
9997
/* Number of items in ASN.1 template for DSA private key. */
9998
#define dsaKeyASN_Length (sizeof(dsaKeyASN) / sizeof(ASNItem))
9999
/* Number of items in ASN.1 template for DSA public key. */
10000
#define dsaPublicKeyASN_Length ((sizeof(dsaKeyASN) / sizeof(ASNItem)) - 2)
10001
10002
/* ASN.1 template for PublicKeyInfo with DSA.
10003
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
10004
 * RFC 3279, 2.3.2 - DSA in SubjectPublicKeyInfo
10005
 */
10006
static const ASNItem dsaPubKeyASN[] = {
10007
/* SEQ             */ { 0, ASN_SEQUENCE, 1, 1, 0 },
10008
/* ALGOID_SEQ      */     { 1, ASN_SEQUENCE, 1, 1, 0 },
10009
/* ALGOID_OID      */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
10010
/* ALGOID_PARAMS   */         { 2, ASN_SEQUENCE, 1, 1, 0 },
10011
                                                   /* p */
10012
/* ALGOID_PARAMS_P */             { 3, ASN_INTEGER, 0, 0, 0 },
10013
                                                   /* q */
10014
/* ALGOID_PARAMS_Q */             { 3, ASN_INTEGER, 0, 0, 0 },
10015
                                                   /* g */
10016
/* ALGOID_PARAMS_G */             { 3, ASN_INTEGER, 0, 0, 0 },
10017
/* PUBKEY_STR      */     { 1, ASN_BIT_STRING, 0, 1, 1 },
10018
                                               /* y */
10019
/* PUBKEY_Y        */         { 2, ASN_INTEGER, 0, 0, 0 },
10020
};
10021
enum {
10022
    DSAPUBKEYASN_IDX_SEQ = 0,
10023
    DSAPUBKEYASN_IDX_ALGOID_SEQ,
10024
    DSAPUBKEYASN_IDX_ALGOID_OID,
10025
    DSAPUBKEYASN_IDX_ALGOID_PARAMS,
10026
    DSAPUBKEYASN_IDX_ALGOID_PARAMS_P,
10027
    DSAPUBKEYASN_IDX_ALGOID_PARAMS_Q,
10028
    DSAPUBKEYASN_IDX_ALGOID_PARAMS_G,
10029
    DSAPUBKEYASN_IDX_PUBKEY_STR,
10030
    DSAPUBKEYASN_IDX_PUBKEY_Y,
10031
};
10032
10033
/* Number of items in ASN.1 template for PublicKeyInfo with DSA. */
10034
#define dsaPubKeyASN_Length (sizeof(dsaPubKeyASN) / sizeof(ASNItem))
10035
#endif /* WOLFSSL_ASN_TEMPLATE */
10036
10037
/* Decode DSA public key.
10038
 *
10039
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
10040
 * RFC 3279, 2.3.2 - DSA in SubjectPublicKeyInfo
10041
 *
10042
 * @param [in]      input     Buffer holding BER encoded data.
10043
 * @param [in, out] inOutIdx  On in, start of DSA public key.
10044
 *                            On out, start of ASN.1 item after DSA public key.
10045
 * @param [in, out] key       DSA key object.
10046
 * @param [in]      inSz      Number of bytes in buffer.
10047
 * @return  0 on success.
10048
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
10049
 *          is invalid.
10050
 * @return  BUFFER_E when data in buffer is too small.
10051
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
10052
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
10053
 *          non-zero length.
10054
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
10055
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
10056
 */
10057
int wc_DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
10058
                          word32 inSz)
10059
{
10060
#ifndef WOLFSSL_ASN_TEMPLATE
10061
    int    length;
10062
    int    ret = 0;
10063
    word32 oid;
10064
    word32 maxIdx;
10065
10066
    if (input == NULL || inOutIdx == NULL || key == NULL)
10067
        return BAD_FUNC_ARG;
10068
10069
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
10070
        return ASN_PARSE_E;
10071
10072
    maxIdx = (word32)(*inOutIdx + length);
10073
    if (GetInt(&key->p,  input, inOutIdx, maxIdx) < 0 ||
10074
        GetInt(&key->q,  input, inOutIdx, maxIdx) < 0 ||
10075
        GetInt(&key->g,  input, inOutIdx, maxIdx) < 0 ||
10076
        GetInt(&key->y,  input, inOutIdx, maxIdx) < 0 )
10077
        ret = ASN_DH_KEY_E;
10078
10079
    if (ret != 0) {
10080
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
10081
            return ASN_PARSE_E;
10082
10083
        ret = GetObjectId(input, inOutIdx, &oid, oidIgnoreType, inSz);
10084
        if (ret != 0)
10085
            return ret;
10086
10087
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
10088
            return ASN_PARSE_E;
10089
10090
        if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
10091
            GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
10092
            GetInt(&key->g,  input, inOutIdx, inSz) < 0)
10093
            return ASN_DH_KEY_E;
10094
10095
        if (CheckBitString(input, inOutIdx, &length, inSz, 0, NULL) < 0)
10096
            return ASN_PARSE_E;
10097
10098
        if (GetInt(&key->y,  input, inOutIdx, inSz) < 0 )
10099
            return ASN_DH_KEY_E;
10100
10101
        ret = 0;
10102
    }
10103
10104
    key->type = DSA_PUBLIC;
10105
    return ret;
10106
#else
10107
    /* dsaPubKeyASN is longer than dsaPublicKeyASN. */
10108
    DECL_ASNGETDATA(dataASN, dsaPubKeyASN_Length);
10109
    int ret = 0;
10110
    int i;
10111
10112
    /* Validated parameters. */
10113
    if ((input == NULL) || (inOutIdx == NULL) || (key == NULL)) {
10114
        ret = BAD_FUNC_ARG;
10115
    }
10116
10117
    ALLOC_ASNGETDATA(dataASN, dsaPubKeyASN_Length, ret, key->heap);
10118
10119
    if (ret == 0) {
10120
        /* Clear dynamic data items. */
10121
        XMEMSET(dataASN, 0, sizeof(ASNGetData) * dsaPublicKeyASN_Length);
10122
        /* seq
10123
         *   p, q, g, y
10124
         * Start DSA ints from DSAKEYASN_IDX_VER instead of DSAKEYASN_IDX_P */
10125
        for (i = 0; i < DSA_INTS - 1; i++)
10126
            GetASN_MP(&dataASN[(int)DSAKEYASN_IDX_VER + i], GetDsaInt(key, i));
10127
        /* Parse as simple form. */
10128
        ret = GetASN_Items(dsaKeyASN, dataASN, dsaPublicKeyASN_Length, 1, input,
10129
                           inOutIdx, inSz);
10130
        if (ret != 0) {
10131
            /* Clear dynamic data items. */
10132
            XMEMSET(dataASN, 0, sizeof(ASNGetData) * dsaPubKeyASN_Length);
10133
            /* Set DSA OID to expect. */
10134
            GetASN_ExpBuffer(&dataASN[DSAPUBKEYASN_IDX_ALGOID_OID],
10135
                    keyDsaOid, sizeof(keyDsaOid));
10136
            /* p, q, g */
10137
            for (i = 0; i < DSA_INTS - 2; i++)
10138
                GetASN_MP(&dataASN[(int)DSAPUBKEYASN_IDX_ALGOID_PARAMS_P + i],
10139
                        GetDsaInt(key, i));
10140
            /* y */
10141
            GetASN_MP(&dataASN[DSAPUBKEYASN_IDX_PUBKEY_Y], GetDsaInt(key, i));
10142
            /* Parse as SubjectPublicKeyInfo. */
10143
            ret = GetASN_Items(dsaPubKeyASN, dataASN, dsaPubKeyASN_Length, 1,
10144
                input, inOutIdx, inSz);
10145
        }
10146
    }
10147
10148
    if (ret == 0) {
10149
        /* Data parsed - set type of key parsed. */
10150
        key->type = DSA_PUBLIC;
10151
    }
10152
10153
    FREE_ASNGETDATA(dataASN, key->heap);
10154
    return ret;
10155
#endif
10156
}
10157
10158
int wc_DsaParamsDecode(const byte* input, word32* inOutIdx, DsaKey* key,
10159
                        word32 inSz)
10160
{
10161
    int    length;
10162
    word32 maxIdx;
10163
10164
    if (input == NULL || inOutIdx == NULL || key == NULL)
10165
        return BAD_FUNC_ARG;
10166
10167
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
10168
        return ASN_PARSE_E;
10169
10170
    maxIdx = (word32)(*inOutIdx + length);
10171
    if (GetInt(&key->p, input, inOutIdx, maxIdx) < 0 ||
10172
        GetInt(&key->q, input, inOutIdx, maxIdx) < 0 ||
10173
        GetInt(&key->g, input, inOutIdx, maxIdx) < 0)
10174
        return ASN_DH_KEY_E;
10175
10176
    return 0;
10177
}
10178
10179
10180
#ifdef WOLFSSL_ASN_TEMPLATE
10181
/* ASN.1 template for a DSA key holding private key in an OCTET_STRING. */
10182
static const ASNItem dsaKeyOctASN[] = {
10183
/*  SEQ      */ { 0, ASN_SEQUENCE, 1, 1, 0 },
10184
                /* p */
10185
/*  P        */     { 1, ASN_INTEGER, 0, 0, 0 },
10186
                /* q */
10187
/*  Q        */     { 1, ASN_INTEGER, 0, 0, 0 },
10188
                /* g */
10189
/*  G        */     { 1, ASN_INTEGER, 0, 0, 0 },
10190
                /* Private key */
10191
/*  PKEY_STR */     { 1, ASN_OCTET_STRING, 0, 1, 0 },
10192
                    /* x */
10193
/*  X        */         { 2, ASN_INTEGER, 0, 0, 0 },
10194
};
10195
enum {
10196
    DSAKEYOCTASN_IDX_SEQ = 0,
10197
    DSAKEYOCTASN_IDX_P,
10198
    DSAKEYOCTASN_IDX_Q,
10199
    DSAKEYOCTASN_IDX_G,
10200
    DSAKEYOCTASN_IDX_PKEY_STR,
10201
    DSAKEYOCTASN_IDX_X,
10202
};
10203
10204
/* Number of items in ASN.1 template for a DSA key (OCTET_STRING version). */
10205
#define dsaKeyOctASN_Length (sizeof(dsaKeyOctASN) / sizeof(ASNItem))
10206
#endif
10207
10208
/* Decode DSA private key.
10209
 *
10210
 * @param [in]      input     Buffer holding BER encoded data.
10211
 * @param [in, out] inOutIdx  On in, start of DSA public key.
10212
 *                            On out, start of ASN.1 item after DSA public key.
10213
 * @param [in, out] key       DSA key object.
10214
 * @param [in]      inSz      Number of bytes in buffer.
10215
 * @return  0 on success.
10216
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
10217
 *          is invalid.
10218
 * @return  BUFFER_E when data in buffer is too small.
10219
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
10220
 *          non-zero length.
10221
 */
10222
int wc_DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
10223
                           word32 inSz)
10224
{
10225
#ifndef WOLFSSL_ASN_TEMPLATE
10226
    int length, version, ret = 0, temp = 0;
10227
    word32 algId = 0;
10228
10229
    /* Sanity checks on input */
10230
    if (input == NULL || inOutIdx == NULL || key == NULL) {
10231
        return BAD_FUNC_ARG;
10232
    }
10233
10234
    /* if has pkcs8 header skip it */
10235
    if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) {
10236
        /* ignore error, did not have pkcs8 header */
10237
    }
10238
10239
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
10240
        return ASN_PARSE_E;
10241
10242
    temp = (int)*inOutIdx;
10243
10244
    /* Default case expects a certificate with OctetString but no version ID */
10245
    ret = GetInt(&key->p, input, inOutIdx, inSz);
10246
    if (ret < 0) {
10247
        mp_clear(&key->p);
10248
        ret = ASN_PARSE_E;
10249
    }
10250
    else {
10251
        ret = GetInt(&key->q, input, inOutIdx, inSz);
10252
        if (ret < 0) {
10253
            mp_clear(&key->p);
10254
            mp_clear(&key->q);
10255
            ret = ASN_PARSE_E;
10256
        }
10257
        else {
10258
            ret = GetInt(&key->g, input, inOutIdx, inSz);
10259
            if (ret < 0) {
10260
                mp_clear(&key->p);
10261
                mp_clear(&key->q);
10262
                mp_clear(&key->g);
10263
                ret = ASN_PARSE_E;
10264
            }
10265
            else {
10266
                ret = GetOctetString(input, inOutIdx, &length, inSz);
10267
                if (ret < 0) {
10268
                    mp_clear(&key->p);
10269
                    mp_clear(&key->q);
10270
                    mp_clear(&key->g);
10271
                    ret = ASN_PARSE_E;
10272
                }
10273
                else {
10274
                    ret = GetInt(&key->y, input, inOutIdx, inSz);
10275
                    if (ret < 0) {
10276
                        mp_clear(&key->p);
10277
                        mp_clear(&key->q);
10278
                        mp_clear(&key->g);
10279
                        mp_clear(&key->y);
10280
                        ret = ASN_PARSE_E;
10281
                    }
10282
                }
10283
            }
10284
        }
10285
    }
10286
    /* An alternate pass if default certificate fails parsing */
10287
    if (ret == ASN_PARSE_E) {
10288
        *inOutIdx = temp;
10289
        if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
10290
            return ASN_PARSE_E;
10291
10292
        if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
10293
            GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
10294
            GetInt(&key->g,  input, inOutIdx, inSz) < 0 ||
10295
            GetInt(&key->y,  input, inOutIdx, inSz) < 0 ||
10296
            GetInt(&key->x,  input, inOutIdx, inSz) < 0 )
10297
            return ASN_DH_KEY_E;
10298
    }
10299
10300
    key->type = DSA_PRIVATE;
10301
    return 0;
10302
#else
10303
    /* dsaKeyASN is longer than dsaKeyOctASN. */
10304
    DECL_ASNGETDATA(dataASN, dsaKeyASN_Length);
10305
    int ret = 0;
10306
    int i;
10307
    byte version = 0;
10308
10309
    /* Sanity checks on input */
10310
    if ((input == NULL) || (inOutIdx == NULL) || (key == NULL)) {
10311
        ret = BAD_FUNC_ARG;
10312
    }
10313
10314
    CALLOC_ASNGETDATA(dataASN, dsaKeyASN_Length, ret, key->heap);
10315
10316
    if (ret == 0) {
10317
        /* Try dsaKeyOctASN */
10318
        /* Initialize key data and set mp_ints for params */
10319
        for (i = 0; i < DSA_INTS - 2; i++) {
10320
            GetASN_MP(&dataASN[(int)DSAKEYOCTASN_IDX_P + i], GetDsaInt(key, i));
10321
        }
10322
        /* and priv */
10323
        GetASN_MP(&dataASN[DSAKEYOCTASN_IDX_X], GetDsaInt(key, i));
10324
        /* Try simple form. */
10325
        ret = GetASN_Items(dsaKeyOctASN, dataASN, dsaKeyOctASN_Length, 1, input,
10326
                           inOutIdx, inSz);
10327
10328
        if (ret != 0) {
10329
            /* Try dsaKeyASN */
10330
            XMEMSET(dataASN, 0, sizeof(*dataASN) * dsaKeyASN_Length);
10331
            GetASN_Int8Bit(&dataASN[DSAKEYASN_IDX_VER], &version);
10332
            for (i = 0; i < DSA_INTS; i++) {
10333
                GetASN_MP(&dataASN[(int)DSAKEYASN_IDX_P + i], GetDsaInt(key, i));
10334
            }
10335
10336
            /* Try simple OCTET_STRING form. */
10337
            ret = GetASN_Items(dsaKeyASN, dataASN, dsaKeyASN_Length, 1, input,
10338
                               inOutIdx, inSz);
10339
        }
10340
    }
10341
10342
    if (ret == 0) {
10343
        /* Set the contents to be a private key. */
10344
        key->type = DSA_PRIVATE;
10345
    }
10346
10347
    FREE_ASNGETDATA(dataASN, key->heap);
10348
    return ret;
10349
#endif
10350
}
10351
10352
#ifndef WOLFSSL_ASN_TEMPLATE
10353
/* Release Tmp DSA resources */
10354
static WC_INLINE void FreeTmpDsas(byte** tmps, void* heap, int ints)
10355
{
10356
    int i;
10357
10358
    for (i = 0; i < ints; i++)
10359
        XFREE(tmps[i], heap, DYNAMIC_TYPE_DSA);
10360
10361
    (void)heap;
10362
}
10363
#endif /* !WOLFSSL_ASN_TEMPLATE */
10364
10365
#if !defined(HAVE_SELFTEST) && (defined(WOLFSSL_KEY_GEN) || \
10366
        defined(WOLFSSL_CERT_GEN))
10367
/* Encode a DSA public key into buffer.
10368
 *
10369
 * @param [out] output       Buffer to hold encoded data.
10370
 * @param [in]  key          DSA key object.
10371
 * @param [out] outLen       Length of buffer.
10372
 * @param [out] with_header  Whether to encode in SubjectPublicKeyInfo block.
10373
 * @return  Size of encoded data in bytes on success.
10374
 * @return  BAD_FUNC_ARG when output or key is NULL, or buffer size is less
10375
 *          than a minimal size (5 bytes), or buffer size is smaller than
10376
 *          encoding size.
10377
 * @return  MEMORY_E when dynamic memory allocation fails.
10378
 */
10379
int wc_SetDsaPublicKey(byte* output, DsaKey* key, int outLen, int with_header)
10380
{
10381
#ifndef WOLFSSL_ASN_TEMPLATE
10382
    /* p, g, q = DSA params, y = public exponent */
10383
#ifdef WOLFSSL_SMALL_STACK
10384
    byte* p = NULL;
10385
    byte* g = NULL;
10386
    byte* q = NULL;
10387
    byte* y = NULL;
10388
#else
10389
    byte p[MAX_DSA_INT_SZ];
10390
    byte g[MAX_DSA_INT_SZ];
10391
    byte q[MAX_DSA_INT_SZ];
10392
    byte y[MAX_DSA_INT_SZ];
10393
#endif
10394
    byte innerSeq[MAX_SEQ_SZ];
10395
    byte outerSeq[MAX_SEQ_SZ];
10396
    byte bitString[1 + MAX_LENGTH_SZ + 1];
10397
    int  idx, pSz, gSz, qSz, ySz, innerSeqSz, outerSeqSz, bitStringSz = 0;
10398
10399
    WOLFSSL_ENTER("wc_SetDsaPublicKey");
10400
10401
    if (output == NULL || key == NULL || outLen < MAX_SEQ_SZ) {
10402
        return BAD_FUNC_ARG;
10403
    }
10404
10405
    /* p */
10406
#ifdef WOLFSSL_SMALL_STACK
10407
    p = (byte*)XMALLOC(MAX_DSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10408
    if (p == NULL)
10409
        return MEMORY_E;
10410
#endif
10411
    if ((pSz = SetASNIntMP(&key->p, MAX_DSA_INT_SZ, p)) < 0) {
10412
        WOLFSSL_MSG("SetASNIntMP Error with p");
10413
#ifdef WOLFSSL_SMALL_STACK
10414
        XFREE(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10415
#endif
10416
        return pSz;
10417
    }
10418
10419
    /* q */
10420
#ifdef WOLFSSL_SMALL_STACK
10421
    q = (byte*)XMALLOC(MAX_DSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10422
    if (q == NULL)
10423
        return MEMORY_E;
10424
#endif
10425
    if ((qSz = SetASNIntMP(&key->q, MAX_DSA_INT_SZ, q)) < 0) {
10426
        WOLFSSL_MSG("SetASNIntMP Error with q");
10427
#ifdef WOLFSSL_SMALL_STACK
10428
        XFREE(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10429
        XFREE(q, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10430
#endif
10431
        return qSz;
10432
    }
10433
10434
    /* g */
10435
#ifdef WOLFSSL_SMALL_STACK
10436
    g = (byte*)XMALLOC(MAX_DSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10437
    if (g == NULL)
10438
        return MEMORY_E;
10439
#endif
10440
    if ((gSz = SetASNIntMP(&key->g, MAX_DSA_INT_SZ, g)) < 0) {
10441
        WOLFSSL_MSG("SetASNIntMP Error with g");
10442
#ifdef WOLFSSL_SMALL_STACK
10443
        XFREE(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10444
        XFREE(q, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10445
        XFREE(g, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10446
#endif
10447
        return gSz;
10448
    }
10449
10450
    /* y */
10451
#ifdef WOLFSSL_SMALL_STACK
10452
    y = (byte*)XMALLOC(MAX_DSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10453
    if (y == NULL)
10454
        return MEMORY_E;
10455
#endif
10456
    if ((ySz = SetASNIntMP(&key->y, MAX_DSA_INT_SZ, y)) < 0) {
10457
        WOLFSSL_MSG("SetASNIntMP Error with y");
10458
#ifdef WOLFSSL_SMALL_STACK
10459
        XFREE(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10460
        XFREE(q, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10461
        XFREE(g, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10462
        XFREE(y, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10463
#endif
10464
        return ySz;
10465
    }
10466
10467
    if (with_header) {
10468
        int algoSz;
10469
#ifdef WOLFSSL_SMALL_STACK
10470
        byte* algo = NULL;
10471
10472
        algo = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10473
        if (algo == NULL) {
10474
            XFREE(p,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10475
            XFREE(q,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10476
            XFREE(g,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10477
            XFREE(y,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10478
            return MEMORY_E;
10479
        }
10480
#else
10481
        byte algo[MAX_ALGO_SZ];
10482
#endif
10483
        innerSeqSz  = SetSequence(pSz + qSz + gSz, innerSeq);
10484
        algoSz = SetAlgoID(DSAk, algo, oidKeyType, 0);
10485
        bitStringSz  = SetBitString(ySz, 0, bitString);
10486
        outerSeqSz = SetSequence(algoSz + innerSeqSz + pSz + qSz + gSz,
10487
                                                                      outerSeq);
10488
10489
        idx = SetSequence(algoSz + innerSeqSz + pSz + qSz + gSz + bitStringSz +
10490
                                                      ySz + outerSeqSz, output);
10491
10492
        /* check output size */
10493
        if ((idx + algoSz + bitStringSz + innerSeqSz + pSz + qSz + gSz + ySz) >
10494
                                                                       outLen) {
10495
            #ifdef WOLFSSL_SMALL_STACK
10496
                XFREE(p,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10497
                XFREE(q,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10498
                XFREE(g,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10499
                XFREE(y,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10500
                XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10501
            #endif
10502
            WOLFSSL_MSG("Error, output size smaller than outlen");
10503
            return BUFFER_E;
10504
        }
10505
10506
        /* outerSeq */
10507
        XMEMCPY(output + idx, outerSeq, outerSeqSz);
10508
        idx += outerSeqSz;
10509
        /* algo */
10510
        XMEMCPY(output + idx, algo, algoSz);
10511
        idx += algoSz;
10512
#ifdef WOLFSSL_SMALL_STACK
10513
        XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10514
#endif
10515
    } else {
10516
        innerSeqSz  = SetSequence(pSz + qSz + gSz + ySz, innerSeq);
10517
10518
        /* check output size */
10519
        if ((innerSeqSz + pSz + qSz + gSz + ySz) > outLen) {
10520
    #ifdef WOLFSSL_SMALL_STACK
10521
            XFREE(p,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10522
            XFREE(q,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10523
            XFREE(g,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10524
            XFREE(y,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10525
    #endif
10526
            WOLFSSL_MSG("Error, output size smaller than outlen");
10527
            return BUFFER_E;
10528
        }
10529
10530
        idx = 0;
10531
    }
10532
10533
    /* innerSeq */
10534
    XMEMCPY(output + idx, innerSeq, innerSeqSz);
10535
    idx += innerSeqSz;
10536
    /* p */
10537
    XMEMCPY(output + idx, p, pSz);
10538
    idx += pSz;
10539
    /* q */
10540
    XMEMCPY(output + idx, q, qSz);
10541
    idx += qSz;
10542
    /* g */
10543
    XMEMCPY(output + idx, g, gSz);
10544
    idx += gSz;
10545
    /* bit string */
10546
    if (bitStringSz > 0) {
10547
        XMEMCPY(output + idx, bitString, bitStringSz);
10548
        idx += bitStringSz;
10549
    }
10550
    /* y */
10551
    XMEMCPY(output + idx, y, ySz);
10552
    idx += ySz;
10553
10554
#ifdef WOLFSSL_SMALL_STACK
10555
    XFREE(p,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10556
    XFREE(q,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10557
    XFREE(g,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10558
    XFREE(y,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10559
#endif
10560
    return idx;
10561
#else
10562
    DECL_ASNSETDATA(dataASN, dsaPubKeyASN_Length);
10563
    int ret = 0;
10564
    int i;
10565
    int sz = 0;
10566
    const ASNItem *data = NULL;
10567
    int count = 0;
10568
10569
    WOLFSSL_ENTER("wc_SetDsaPublicKey");
10570
10571
    if ((output == NULL) || (key == NULL) || (outLen < MAX_SEQ_SZ)) {
10572
        ret = BAD_FUNC_ARG;
10573
    }
10574
10575
    CALLOC_ASNSETDATA(dataASN, dsaPubKeyASN_Length, ret, key->heap);
10576
10577
    if (ret == 0) {
10578
        if (with_header) {
10579
            /* Using dsaPubKeyASN */
10580
            data = dsaPubKeyASN;
10581
            count = dsaPubKeyASN_Length;
10582
            /* Set the algorithm OID to write out. */
10583
            SetASN_OID(&dataASN[DSAPUBKEYASN_IDX_ALGOID_OID], DSAk, oidKeyType);
10584
            /* Set the mp_ints to encode - parameters and public value. */
10585
            for (i = 0; i < DSA_INTS - 2; i++) {
10586
                SetASN_MP(&dataASN[(int)DSAPUBKEYASN_IDX_ALGOID_PARAMS_P + i],
10587
                        GetDsaInt(key, i));
10588
            }
10589
            SetASN_MP(&dataASN[DSAPUBKEYASN_IDX_PUBKEY_Y], GetDsaInt(key, i));
10590
        }
10591
        else {
10592
            /* Using dsaKeyASN */
10593
            data = dsaKeyASN;
10594
            count = dsaPublicKeyASN_Length;
10595
            /* Set the mp_ints to encode - parameters and public value. */
10596
            for (i = 0; i < DSA_INTS - 1; i++) {
10597
                /* Move all DSA ints up one slot (ignore VERSION so now
10598
                 * it means P) */
10599
                SetASN_MP(&dataASN[(int)DSAKEYASN_IDX_VER + i],
10600
                        GetDsaInt(key, i));
10601
            }
10602
        }
10603
        ret = SizeASN_Items(data, dataASN, count, &sz);
10604
    }
10605
    /* Check buffer is big enough for encoding. */
10606
    if ((ret == 0) && (sz > (int)outLen)) {
10607
        ret = BAD_FUNC_ARG;
10608
    }
10609
    /* Encode the DSA public key into output buffer. */
10610
    if (ret == 0) {
10611
        ret = SetASN_Items(data, dataASN, count, output);
10612
    }
10613
10614
    FREE_ASNSETDATA(dataASN, key->heap);
10615
    return ret;
10616
#endif /* WOLFSSL_ASN_TEMPLATE */
10617
}
10618
10619
/* Encode a DSA public key into buffer.
10620
 *
10621
 * @param [out] output       Buffer to hold encoded data.
10622
 * @param [in]  key          DSA key object.
10623
 * @param [out] outLen       Length of buffer.
10624
 * @param [out] with_header  Whether to encode in SubjectPublicKeyInfo block.
10625
 * @return  Size of encoded data in bytes on success.
10626
 * @return  BAD_FUNC_ARG when output or key is NULL, or buffer size is less
10627
 *          than a minimal size (5 bytes), or buffer size is smaller than
10628
 *          encoding size.
10629
 * @return  MEMORY_E when dynamic memory allocation fails.
10630
 */
10631
int wc_DsaKeyToPublicDer(DsaKey* key, byte* output, word32 inLen)
10632
{
10633
    return wc_SetDsaPublicKey(output, key, inLen, 1);
10634
}
10635
#endif /* !HAVE_SELFTEST && (WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN) */
10636
10637
static int DsaKeyIntsToDer(DsaKey* key, byte* output, word32* inLen,
10638
                           int ints, int includeVersion)
10639
{
10640
#ifndef WOLFSSL_ASN_TEMPLATE
10641
    word32 seqSz = 0, verSz = 0, rawLen, intTotalLen = 0;
10642
    word32 sizes[DSA_INTS];
10643
    int    i, j, outLen, ret = 0, mpSz;
10644
10645
    byte  seq[MAX_SEQ_SZ];
10646
    byte  ver[MAX_VERSION_SZ];
10647
    byte* tmps[DSA_INTS];
10648
10649
    if (ints > DSA_INTS || inLen == NULL)
10650
        return BAD_FUNC_ARG;
10651
10652
    XMEMSET(sizes, 0, sizeof(sizes));
10653
    for (i = 0; i < ints; i++)
10654
        tmps[i] = NULL;
10655
10656
    /* write all big ints from key to DER tmps */
10657
    for (i = 0; i < ints; i++) {
10658
        mp_int* keyInt = GetDsaInt(key, i);
10659
10660
        rawLen = mp_unsigned_bin_size(keyInt) + 1;
10661
        tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
10662
                                                              DYNAMIC_TYPE_DSA);
10663
        if (tmps[i] == NULL) {
10664
            ret = MEMORY_E;
10665
            break;
10666
        }
10667
10668
        mpSz = SetASNIntMP(keyInt, -1, tmps[i]);
10669
        if (mpSz < 0) {
10670
            ret = mpSz;
10671
            break;
10672
        }
10673
        intTotalLen += (sizes[i] = mpSz);
10674
    }
10675
10676
    if (ret != 0) {
10677
        FreeTmpDsas(tmps, key->heap, ints);
10678
        return ret;
10679
    }
10680
10681
    /* make headers */
10682
    if (includeVersion)
10683
        verSz = SetMyVersion(0, ver, FALSE);
10684
    seqSz = SetSequence(verSz + intTotalLen, seq);
10685
10686
    outLen = seqSz + verSz + intTotalLen;
10687
    *inLen = outLen;
10688
    if (output == NULL) {
10689
        FreeTmpDsas(tmps, key->heap, ints);
10690
        return LENGTH_ONLY_E;
10691
    }
10692
    if (outLen > (int)*inLen) {
10693
        FreeTmpDsas(tmps, key->heap, ints);
10694
        return BAD_FUNC_ARG;
10695
    }
10696
10697
    /* write to output */
10698
    XMEMCPY(output, seq, seqSz);
10699
    j = seqSz;
10700
    if (includeVersion) {
10701
        XMEMCPY(output + j, ver, verSz);
10702
        j += verSz;
10703
    }
10704
10705
    for (i = 0; i < ints; i++) {
10706
        XMEMCPY(output + j, tmps[i], sizes[i]);
10707
        j += sizes[i];
10708
    }
10709
    FreeTmpDsas(tmps, key->heap, ints);
10710
10711
    return outLen;
10712
#else
10713
    DECL_ASNSETDATA(dataASN, dsaKeyASN_Length);
10714
    int ret = 0;
10715
    int i;
10716
    int sz = 0;
10717
10718
    (void)ints;
10719
10720
    if ((key == NULL) || (inLen == NULL)) {
10721
        ret = BAD_FUNC_ARG;
10722
    }
10723
    if ((ret == 0) && (ints > DSA_INTS)) {
10724
        ret = BAD_FUNC_ARG;
10725
    }
10726
10727
    CALLOC_ASNSETDATA(dataASN, dsaKeyASN_Length, ret, key->heap);
10728
10729
    if (ret == 0) {
10730
        if (includeVersion) {
10731
            /* Set the version. */
10732
            SetASN_Int8Bit(&dataASN[DSAKEYASN_IDX_VER], 0);
10733
        }
10734
        else {
10735
            dataASN[DSAKEYASN_IDX_VER].noOut = 1;
10736
        }
10737
        dataASN[DSAKEYASN_IDX_Y].noOut = mp_iszero(&key->y);
10738
        dataASN[DSAKEYASN_IDX_X].noOut = mp_iszero(&key->x);
10739
        /* Set the mp_ints to encode - params, public and private value. */
10740
        for (i = 0; i < DSA_INTS; i++) {
10741
            if (i < ints)
10742
                SetASN_MP(&dataASN[(int)DSAKEYASN_IDX_P + i], GetDsaInt(key, i));
10743
            else
10744
                dataASN[(int)DSAKEYASN_IDX_P + i].noOut = 1;
10745
        }
10746
        /* Calculate size of the encoding. */
10747
        ret = SizeASN_Items(dsaKeyASN, dataASN, dsaKeyASN_Length, &sz);
10748
    }
10749
    if ((ret == 0) && (output == NULL)) {
10750
        *inLen = sz;
10751
        ret = LENGTH_ONLY_E;
10752
    }
10753
    /* Check buffer is big enough for encoding. */
10754
    if ((ret == 0) && (sz > (int)*inLen)) {
10755
        ret = BAD_FUNC_ARG;
10756
    }
10757
    if (ret == 0) {
10758
        /* Encode the DSA private key into output buffer. */
10759
        SetASN_Items(dsaKeyASN, dataASN, dsaKeyASN_Length, output);
10760
        /* Return the size of the encoding. */
10761
        ret = sz;
10762
    }
10763
10764
    FREE_ASNSETDATA(dataASN, key->heap);
10765
    return ret;
10766
#endif /* WOLFSSL_ASN_TEMPLATE */
10767
}
10768
10769
/* Encode a DSA private key into buffer.
10770
 *
10771
 * @param [in]  key          DSA key object.
10772
 * @param [out] output       Buffer to hold encoded data.
10773
 * @param [out] inLen        Length of buffer.
10774
 * @return  Size of encoded data in bytes on success.
10775
 * @return  BAD_FUNC_ARG when key or output is NULL, or key is not a private key
10776
 *          or, buffer size is smaller than encoding size.
10777
 * @return  MEMORY_E when dynamic memory allocation fails.
10778
 */
10779
int wc_DsaKeyToDer(DsaKey* key, byte* output, word32 inLen)
10780
{
10781
    if (!key || !output)
10782
        return BAD_FUNC_ARG;
10783
10784
    if (key->type != DSA_PRIVATE)
10785
        return BAD_FUNC_ARG;
10786
10787
    return DsaKeyIntsToDer(key, output, &inLen, DSA_INTS, 1);
10788
}
10789
10790
/* Convert DsaKey parameters to DER format, write to output (inLen),
10791
   return bytes written. Version is excluded to be compatible with
10792
   OpenSSL d2i_DSAparams */
10793
int wc_DsaKeyToParamsDer(DsaKey* key, byte* output, word32 inLen)
10794
{
10795
    if (!key || !output)
10796
        return BAD_FUNC_ARG;
10797
10798
    return DsaKeyIntsToDer(key, output, &inLen, DSA_PARAM_INTS, 0);
10799
}
10800
10801
/* This version of the function allows output to be NULL. In that case, the
10802
   DsaKeyIntsToDer will return LENGTH_ONLY_E and the required output buffer
10803
   size will be pointed to by inLen. */
10804
int wc_DsaKeyToParamsDer_ex(DsaKey* key, byte* output, word32* inLen)
10805
{
10806
    if (!key || !inLen)
10807
        return BAD_FUNC_ARG;
10808
10809
    return DsaKeyIntsToDer(key, output, inLen, DSA_PARAM_INTS, 0);
10810
}
10811
10812
#endif /* NO_DSA */
10813
10814
/* Initialize decoded certificate object with buffer of DER encoding.
10815
 *
10816
 * @param [in, out] cert    Decoded certificate object.
10817
 * @param [in]      source  Buffer containing DER encoded certificate.
10818
 * @param [in]      inSz    Size of DER data in buffer in bytes.
10819
 * @param [in]      heap    Dynamic memory hint.
10820
 */
10821
void InitDecodedCert(DecodedCert* cert,
10822
                     const byte* source, word32 inSz, void* heap)
10823
0
{
10824
0
    if (cert != NULL) {
10825
0
        XMEMSET(cert, 0, sizeof(DecodedCert));
10826
10827
0
        cert->subjectCNEnc    = CTC_UTF8;
10828
0
        cert->issuer[0]       = '\0';
10829
0
        cert->subject[0]      = '\0';
10830
0
        cert->source          = source;  /* don't own */
10831
0
        cert->maxIdx          = inSz;    /* can't go over this index */
10832
0
        cert->heap            = heap;
10833
0
        cert->maxPathLen      = WOLFSSL_MAX_PATH_LEN;
10834
    #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
10835
        #ifdef WOLFSSL_CERT_NAME_ALL
10836
        cert->subjectNEnc     = CTC_UTF8;
10837
        cert->subjectIEnc     = CTC_UTF8;
10838
        cert->subjectDNQEnc   = CTC_UTF8;
10839
        cert->subjectGNEnc    = CTC_UTF8;
10840
        #endif
10841
        cert->subjectSNEnc    = CTC_UTF8;
10842
        cert->subjectCEnc     = CTC_PRINTABLE;
10843
        cert->subjectLEnc     = CTC_UTF8;
10844
        cert->subjectSTEnc    = CTC_UTF8;
10845
        cert->subjectOEnc     = CTC_UTF8;
10846
        cert->subjectOUEnc    = CTC_UTF8;
10847
    #ifdef WOLFSSL_HAVE_ISSUER_NAMES
10848
        cert->issuerSNEnc    = CTC_UTF8;
10849
        cert->issuerCEnc     = CTC_PRINTABLE;
10850
        cert->issuerLEnc     = CTC_UTF8;
10851
        cert->issuerSTEnc    = CTC_UTF8;
10852
        cert->issuerOEnc     = CTC_UTF8;
10853
        cert->issuerOUEnc    = CTC_UTF8;
10854
    #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
10855
    #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
10856
10857
0
    #ifndef NO_CERTS
10858
0
        InitSignatureCtx(&cert->sigCtx, heap, INVALID_DEVID);
10859
0
    #endif
10860
0
    }
10861
0
}
10862
10863
void wc_InitDecodedCert(DecodedCert* cert, const byte* source, word32 inSz,
10864
                        void* heap)
10865
0
{
10866
0
    InitDecodedCert(cert, source, inSz, heap);
10867
0
}
10868
10869
/* Free the alternative names object.
10870
 *
10871
 * Frees each linked list items and its name.
10872
 *
10873
 * @param [in, out] altNames  Alternative names.
10874
 * @param [in]      heap      Dynamic memory hint.
10875
 */
10876
void FreeAltNames(DNS_entry* altNames, void* heap)
10877
0
{
10878
0
    (void)heap;
10879
10880
0
    while (altNames) {
10881
0
        DNS_entry* tmp = altNames->next;
10882
10883
0
        XFREE(altNames->name, heap, DYNAMIC_TYPE_ALTNAME);
10884
    #if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
10885
        XFREE(altNames->ipString, heap, DYNAMIC_TYPE_ALTNAME);
10886
    #endif
10887
0
        XFREE(altNames,       heap, DYNAMIC_TYPE_ALTNAME);
10888
0
        altNames = tmp;
10889
0
    }
10890
0
}
10891
10892
/* malloc and initialize a new alt name structure */
10893
DNS_entry* AltNameNew(void* heap)
10894
0
{
10895
0
    DNS_entry* ret;
10896
0
    ret = (DNS_entry*)XMALLOC(sizeof(DNS_entry), heap, DYNAMIC_TYPE_ALTNAME);
10897
0
    if (ret != NULL) {
10898
0
        XMEMSET(ret, 0, sizeof(DNS_entry));
10899
0
    }
10900
0
    (void)heap;
10901
0
    return ret;
10902
0
}
10903
10904
10905
#ifndef IGNORE_NAME_CONSTRAINTS
10906
10907
/* Free the subtree names object.
10908
 *
10909
 * Frees each linked list items and its name.
10910
 *
10911
 * @param [in, out] names  Subtree names.
10912
 * @param [in]      heap   Dynamic memory hint.
10913
 */
10914
void FreeNameSubtrees(Base_entry* names, void* heap)
10915
0
{
10916
0
    (void)heap;
10917
10918
0
    while (names) {
10919
0
        Base_entry* tmp = names->next;
10920
10921
0
        XFREE(names->name, heap, DYNAMIC_TYPE_ALTNAME);
10922
0
        XFREE(names,       heap, DYNAMIC_TYPE_ALTNAME);
10923
0
        names = tmp;
10924
0
    }
10925
0
}
10926
10927
#endif /* IGNORE_NAME_CONSTRAINTS */
10928
10929
/* Free the decoded cert object's dynamic data.
10930
 *
10931
 * @param [in, out] cert  Decoded certificate object.
10932
 */
10933
void FreeDecodedCert(DecodedCert* cert)
10934
0
{
10935
0
    if (cert == NULL)
10936
0
        return;
10937
0
    if (cert->subjectCNStored == 1) {
10938
0
        XFREE(cert->subjectCN, cert->heap, DYNAMIC_TYPE_SUBJECT_CN);
10939
0
    }
10940
0
    if (cert->pubKeyStored == 1) {
10941
0
        XFREE((void*)cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
10942
0
    }
10943
0
    if (cert->weOwnAltNames && cert->altNames)
10944
0
        FreeAltNames(cert->altNames, cert->heap);
10945
0
#ifndef IGNORE_NAME_CONSTRAINTS
10946
0
    if (cert->altEmailNames)
10947
0
        FreeAltNames(cert->altEmailNames, cert->heap);
10948
0
    if (cert->altDirNames)
10949
0
        FreeAltNames(cert->altDirNames, cert->heap);
10950
0
    if (cert->permittedNames)
10951
0
        FreeNameSubtrees(cert->permittedNames, cert->heap);
10952
0
    if (cert->excludedNames)
10953
0
        FreeNameSubtrees(cert->excludedNames, cert->heap);
10954
0
#endif /* IGNORE_NAME_CONSTRAINTS */
10955
#ifdef WOLFSSL_SEP
10956
    XFREE(cert->deviceType, cert->heap, DYNAMIC_TYPE_X509_EXT);
10957
    XFREE(cert->hwType, cert->heap, DYNAMIC_TYPE_X509_EXT);
10958
    XFREE(cert->hwSerialNum, cert->heap, DYNAMIC_TYPE_X509_EXT);
10959
#endif /* WOLFSSL_SEP */
10960
#ifdef WOLFSSL_X509_NAME_AVAILABLE
10961
    if (cert->issuerName != NULL)
10962
        wolfSSL_X509_NAME_free((WOLFSSL_X509_NAME*)cert->issuerName);
10963
    if (cert->subjectName != NULL)
10964
        wolfSSL_X509_NAME_free((WOLFSSL_X509_NAME*)cert->subjectName);
10965
#endif /* WOLFSSL_X509_NAME_AVAILABLE */
10966
#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT)
10967
    if (cert->sce_tsip_encRsaKeyIdx != NULL)
10968
        XFREE(cert->sce_tsip_encRsaKeyIdx, cert->heap, DYNAMIC_TYPE_RSA);
10969
#endif
10970
0
#ifndef NO_CERTS
10971
0
    FreeSignatureCtx(&cert->sigCtx);
10972
0
#endif
10973
0
}
10974
10975
void wc_FreeDecodedCert(DecodedCert* cert)
10976
0
{
10977
0
    FreeDecodedCert(cert);
10978
0
}
10979
10980
#ifndef WOLFSSL_ASN_TEMPLATE
10981
static int GetCertHeader(DecodedCert* cert)
10982
0
{
10983
0
    int ret = 0, len;
10984
10985
0
    if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
10986
0
        return ASN_PARSE_E;
10987
10988
    /* Reset the max index for the size indicated in the outer wrapper. */
10989
0
    cert->maxIdx = len + cert->srcIdx;
10990
0
    cert->certBegin = cert->srcIdx;
10991
10992
0
    if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
10993
0
        return ASN_PARSE_E;
10994
10995
0
    cert->sigIndex = len + cert->srcIdx;
10996
0
    if (cert->sigIndex > cert->maxIdx)
10997
0
        return ASN_PARSE_E;
10998
10999
0
    if (GetExplicitVersion(cert->source, &cert->srcIdx, &cert->version,
11000
0
                                                            cert->sigIndex) < 0)
11001
0
        return ASN_PARSE_E;
11002
11003
0
    if (wc_GetSerialNumber(cert->source, &cert->srcIdx, cert->serial,
11004
0
                                           &cert->serialSz, cert->sigIndex) < 0)
11005
0
        return ASN_PARSE_E;
11006
11007
0
    return ret;
11008
0
}
11009
#endif
11010
11011
#if defined(HAVE_ED25519) || defined(HAVE_ED448) || defined(HAVE_PQC)
11012
/* Store the key data under the BIT_STRING in dynamicly allocated data.
11013
 *
11014
 * @param [in, out] cert    Certificate object.
11015
 * @param [in]      source  Buffer containing encoded key.
11016
 * @param [in, out] srcIdx  On in, start of key data.
11017
 *                          On out, start of element after key data.
11018
 * @param [in]      maxIdx  Maximum index of certificate data.
11019
 */
11020
static int StoreKey(DecodedCert* cert, const byte* source, word32* srcIdx,
11021
                    word32 maxIdx)
11022
0
{
11023
0
    int ret;
11024
0
    int length;
11025
0
    byte* publicKey;
11026
11027
0
    ret = CheckBitString(source, srcIdx, &length, maxIdx, 1, NULL);
11028
0
    if (ret == 0) {
11029
    #ifdef HAVE_OCSP
11030
        ret = CalcHashId(source + *srcIdx, length, cert->subjectKeyHash);
11031
    }
11032
    if (ret == 0) {
11033
    #endif
11034
0
        publicKey = (byte*)XMALLOC(length, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
11035
0
        if (publicKey == NULL) {
11036
0
            ret = MEMORY_E;
11037
0
        }
11038
0
        else {
11039
0
            XMEMCPY(publicKey, &source[*srcIdx], length);
11040
0
            cert->publicKey = publicKey;
11041
0
            cert->pubKeyStored = 1;
11042
0
            cert->pubKeySize   = length;
11043
11044
0
            *srcIdx += length;
11045
0
        }
11046
0
    }
11047
11048
0
    return ret;
11049
0
}
11050
#endif /* HAVE_ED25519 || HAVE_ED448 */
11051
11052
#if !defined(NO_RSA)
11053
#ifdef WOLFSSL_ASN_TEMPLATE
11054
/* ASN.1 template for header before RSA key in certificate. */
11055
static const ASNItem rsaCertKeyASN[] = {
11056
/* STR */ { 0, ASN_BIT_STRING, 0, 1, 0 },
11057
/* SEQ */     { 1, ASN_SEQUENCE, 1, 0, 0 },
11058
};
11059
enum {
11060
    RSACERTKEYASN_IDX_STR = 0,
11061
    RSACERTKEYASN_IDX_SEQ,
11062
};
11063
11064
/* Number of items in ASN.1 template for header before RSA key in cert. */
11065
#define rsaCertKeyASN_Length (sizeof(rsaCertKeyASN) / sizeof(ASNItem))
11066
#endif
11067
11068
/* Store RSA key pointer and length in certificate object.
11069
 *
11070
 * @param [in, out] cert    Certificate object.
11071
 * @param [in]      source  Buffer containing encoded key.
11072
 * @param [in, out] srcIdx  On in, start of RSA key data.
11073
 *                          On out, start of element after RSA key data.
11074
 * @param [in]      maxIdx  Maximum index of key data.
11075
 * @return  0 on success.
11076
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
11077
 *          is invalid.
11078
 * @return  BUFFER_E when data in buffer is too small.
11079
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
11080
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
11081
 *          non-zero length.
11082
 */
11083
static int StoreRsaKey(DecodedCert* cert, const byte* source, word32* srcIdx,
11084
                       word32 maxIdx)
11085
0
{
11086
0
#ifndef WOLFSSL_ASN_TEMPLATE
11087
0
    int    length;
11088
0
    int    pubLen;
11089
0
    word32 pubIdx;
11090
11091
0
    if (CheckBitString(source, srcIdx, &pubLen, maxIdx, 1, NULL) != 0)
11092
0
        return ASN_PARSE_E;
11093
0
    pubIdx = *srcIdx;
11094
11095
0
    if (GetSequence(source, srcIdx, &length, pubIdx + pubLen) < 0)
11096
0
        return ASN_PARSE_E;
11097
11098
#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT)
11099
    cert->sigCtx.CertAtt.pubkey_n_start =
11100
            cert->sigCtx.CertAtt.pubkey_e_start = pubIdx;
11101
#endif
11102
0
    cert->pubKeySize = pubLen;
11103
0
    cert->publicKey = source + pubIdx;
11104
0
    *srcIdx += length;
11105
11106
#ifdef HAVE_OCSP
11107
    return CalcHashId(cert->publicKey, cert->pubKeySize, cert->subjectKeyHash);
11108
#else
11109
0
    return 0;
11110
0
#endif
11111
#else
11112
    ASNGetData dataASN[rsaCertKeyASN_Length];
11113
    int ret;
11114
11115
    /* No dynamic data. */
11116
    XMEMSET(dataASN, 0, sizeof(dataASN));
11117
    /* Decode the header before the key data. */
11118
    ret = GetASN_Items(rsaCertKeyASN, dataASN, rsaCertKeyASN_Length, 1, source,
11119
                       srcIdx, maxIdx);
11120
    if (ret == 0) {
11121
        /* Store the pointer and length in certificate object starting at
11122
         * SEQUENCE. */
11123
        GetASN_GetConstRef(&dataASN[RSACERTKEYASN_IDX_STR],
11124
                &cert->publicKey, &cert->pubKeySize);
11125
11126
    #if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT)
11127
        /* Start of SEQUENCE. */
11128
        cert->sigCtx.CertAtt.pubkey_n_start =
11129
            cert->sigCtx.CertAtt.pubkey_e_start = dataASN[RSACERTKEYASN_IDX_SEQ].offset;
11130
    #endif
11131
    #ifdef HAVE_OCSP
11132
        /* Calculate the hash of the public key for OCSP. */
11133
        ret = CalcHashId(cert->publicKey, cert->pubKeySize,
11134
                         cert->subjectKeyHash);
11135
    #endif
11136
    }
11137
11138
    return ret;
11139
#endif /* WOLFSSL_ASN_TEMPLATE */
11140
0
}
11141
#endif /* !NO_RSA */
11142
11143
#ifdef HAVE_ECC
11144
11145
#ifdef WOLFSSL_ASN_TEMPLATE
11146
/* ASN.1 template for header before ECC key in certificate. */
11147
static const ASNItem eccCertKeyASN[] = {
11148
/* OID        */     { 1, ASN_OBJECT_ID, 0, 0, 2 },
11149
                            /* Algo parameters */
11150
/* PARAMS     */     { 1, ASN_SEQUENCE, 1, 0, 2 },
11151
                            /* Subject public key */
11152
/* SUBJPUBKEY */ { 0, ASN_BIT_STRING, 0, 0, 0 },
11153
};
11154
enum {
11155
    ECCCERTKEYASN_IDX_OID = 0,
11156
    ECCCERTKEYASN_IDX_PARAMS,
11157
    ECCCERTKEYASN_IDX_SUBJPUBKEY,
11158
};
11159
11160
/* Number of items in ASN.1 template for header before ECC key in cert. */
11161
#define eccCertKeyASN_Length (sizeof(eccCertKeyASN) / sizeof(ASNItem))
11162
#endif /* WOLFSSL_ASN_TEMPLATE */
11163
11164
/* Store public ECC key in certificate object.
11165
 *
11166
 * Parse parameters and store public key data.
11167
 *
11168
 * @param [in, out] cert       Certificate object.
11169
 * @param [in]      source     Buffer containing encoded key.
11170
 * @param [in, out] srcIdx     On in, start of ECC key data.
11171
 *                             On out, start of element after ECC key data.
11172
 * @param [in]      maxIdx     Maximum index of key data.
11173
 * @param [in]      pubKey     Buffer holding encoded public key.
11174
 * @param [in]      pubKeyLen  Length of encoded public key in bytes.
11175
 * @return  0 on success.
11176
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
11177
 *          is invalid.
11178
 * @return  BUFFER_E when data in buffer is too small.
11179
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
11180
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
11181
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
11182
 *          non-zero length.
11183
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
11184
 */
11185
static int StoreEccKey(DecodedCert* cert, const byte* source, word32* srcIdx,
11186
                       word32 maxIdx, const byte* pubKey, word32 pubKeyLen)
11187
0
{
11188
0
#ifndef WOLFSSL_ASN_TEMPLATE
11189
0
    int ret;
11190
0
    word32 localIdx;
11191
0
    byte* publicKey;
11192
0
    byte  tag;
11193
0
    int length;
11194
11195
0
    localIdx = *srcIdx;
11196
0
    if (GetASNTag(source, &localIdx, &tag, maxIdx) < 0)
11197
0
        return ASN_PARSE_E;
11198
11199
0
    if (tag != (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
11200
0
        if (GetObjectId(source, srcIdx, &cert->pkCurveOID, oidCurveType,
11201
0
                                                                    maxIdx) < 0)
11202
0
            return ASN_PARSE_E;
11203
11204
0
        if ((ret = CheckCurve(cert->pkCurveOID)) < 0)
11205
0
            return ECC_CURVE_OID_E;
11206
11207
    #if defined(WOLFSSL_RENESAS_SCEPROTECT) || defined(WOLFSSL_RENESAS_TSIP_TLS)
11208
        cert->sigCtx.CertAtt.curve_id = ret;
11209
    #else
11210
0
        (void)ret;
11211
0
    #endif
11212
        /* key header */
11213
0
        ret = CheckBitString(source, srcIdx, &length, maxIdx, 1, NULL);
11214
0
        if (ret != 0)
11215
0
            return ret;
11216
    #if defined(WOLFSSL_RENESAS_SCEPROTECT) || defined(WOLFSSL_RENESAS_TSIP_TLS)
11217
        cert->sigCtx.CertAtt.pubkey_n_start =
11218
                cert->sigCtx.CertAtt.pubkey_e_start = (*srcIdx + 1);
11219
        cert->sigCtx.CertAtt.pubkey_n_len = ((length - 1) >> 1);
11220
        cert->sigCtx.CertAtt.pubkey_e_start +=
11221
                cert->sigCtx.CertAtt.pubkey_n_len;
11222
        cert->sigCtx.CertAtt.pubkey_e_len   =
11223
                cert->sigCtx.CertAtt.pubkey_n_len;
11224
    #endif
11225
    #ifdef HAVE_OCSP
11226
        ret = CalcHashId(source + *srcIdx, length, cert->subjectKeyHash);
11227
        if (ret != 0)
11228
            return ret;
11229
    #endif
11230
0
        *srcIdx += length;
11231
0
    }
11232
11233
0
    publicKey = (byte*)XMALLOC(pubKeyLen, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
11234
0
    if (publicKey == NULL)
11235
0
        return MEMORY_E;
11236
0
    XMEMCPY(publicKey, pubKey, pubKeyLen);
11237
0
    cert->publicKey = publicKey;
11238
0
    cert->pubKeyStored = 1;
11239
0
    cert->pubKeySize   = pubKeyLen;
11240
11241
0
    return 0;
11242
#else
11243
    int ret = 0;
11244
    DECL_ASNGETDATA(dataASN, eccCertKeyASN_Length);
11245
    byte* publicKey;
11246
11247
    /* Clear dynamic data and check OID is a curve. */
11248
    CALLOC_ASNGETDATA(dataASN, eccCertKeyASN_Length, ret, cert->heap);
11249
    if (ret == 0) {
11250
        GetASN_OID(&dataASN[ECCCERTKEYASN_IDX_OID], oidCurveType);
11251
        /* Parse ECC public key header. */
11252
        ret = GetASN_Items(eccCertKeyASN, dataASN, eccCertKeyASN_Length, 1,
11253
                source, srcIdx, maxIdx);
11254
    }
11255
    if (ret == 0) {
11256
        if (dataASN[ECCCERTKEYASN_IDX_OID].tag != 0) {
11257
            /* Store curve OID. */
11258
            cert->pkCurveOID = dataASN[ECCCERTKEYASN_IDX_OID].data.oid.sum;
11259
        }
11260
        /* Ignore explicit parameters. */
11261
11262
    #ifdef HAVE_OCSP
11263
        /* Calculate the hash of the subject public key for OCSP. */
11264
        ret = CalcHashId(dataASN[ECCCERTKEYASN_IDX_SUBJPUBKEY].data.ref.data,
11265
                         dataASN[ECCCERTKEYASN_IDX_SUBJPUBKEY].data.ref.length,
11266
                         cert->subjectKeyHash);
11267
    }
11268
    if (ret == 0) {
11269
    #endif
11270
        /* Store public key data length. */
11271
        cert->pubKeySize = pubKeyLen;
11272
        /* Must allocated space for key.
11273
         * Don't memcpy into constant pointer so use temp. */
11274
        publicKey = (byte*)XMALLOC(cert->pubKeySize, cert->heap,
11275
                                   DYNAMIC_TYPE_PUBLIC_KEY);
11276
        if (publicKey == NULL) {
11277
            ret = MEMORY_E;
11278
        }
11279
        else {
11280
            /* Copy in whole public key and store pointer. */
11281
            XMEMCPY(publicKey, pubKey, cert->pubKeySize);
11282
            cert->publicKey = publicKey;
11283
            /* Indicate publicKey needs to be freed. */
11284
            cert->pubKeyStored = 1;
11285
        }
11286
    }
11287
    FREE_ASNGETDATA(dataASN, cert->heap);
11288
11289
    return ret;
11290
#endif /* WOLFSSL_ASN_TEMPLATE */
11291
0
}
11292
#endif /* HAVE_ECC */
11293
11294
#if !defined(NO_DSA)
11295
#ifdef WOLFSSL_ASN_TEMPLATE
11296
/* ASN.1 template for DSA key in certificate.
11297
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
11298
 * RFC 3279, 2.3.2 - DSA in SubjectPublicKeyInfo
11299
 */
11300
static const ASNItem dsaCertKeyASN[] = {
11301
/*  0 */        { 1, ASN_SEQUENCE, 1, 1, 0 },
11302
/*  1 */            { 2, ASN_INTEGER, 0, 0, 0 },
11303
/*  2 */            { 2, ASN_INTEGER, 0, 0, 0 },
11304
/*  3 */            { 2, ASN_INTEGER, 0, 0, 0 },
11305
/*  4 */    { 0, ASN_BIT_STRING, 0, 1, 0 },
11306
/*  5 */        { 1, ASN_INTEGER, 0, 0, 0 },
11307
};
11308
11309
/* Number of items in ASN.1 template for DSA key in certificate. */
11310
#define dsaCertKeyASN_Length (sizeof(dsaCertKeyASN) / sizeof(ASNItem))
11311
#endif /* WOLFSSL_ASN_TEMPLATE */
11312
11313
/* Parse DSA parameters to ensure valid.
11314
 *
11315
 * @param [in]      source  Buffer containing encoded key.
11316
 * @param [in, out] srcIdx  On in, start of DSA key data.
11317
 *                          On out, start of element after DSA key data.
11318
 * @param [in]      maxIdx  Maximum index of key data.
11319
 * @param [in]      heap    Dynamic memory hint.
11320
 * @return  0 on success.
11321
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
11322
 *          is invalid.
11323
 * @return  BUFFER_E when data in buffer is too small.
11324
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
11325
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
11326
 *          non-zero length.
11327
 */
11328
static int ParseDsaKey(const byte* source, word32* srcIdx, word32 maxIdx,
11329
                       void* heap)
11330
{
11331
#ifndef WOLFSSL_ASN_TEMPLATE
11332
    int ret;
11333
    int length;
11334
11335
    (void)heap;
11336
11337
    ret = GetSequence(source, srcIdx, &length, maxIdx);
11338
    if (ret < 0)
11339
        return ret;
11340
11341
    ret = SkipInt(source, srcIdx, maxIdx);
11342
    if (ret != 0)
11343
        return ret;
11344
    ret = SkipInt(source, srcIdx, maxIdx);
11345
    if (ret != 0)
11346
        return ret;
11347
    ret = SkipInt(source, srcIdx, maxIdx);
11348
    if (ret != 0)
11349
        return ret;
11350
11351
    ret = CheckBitString(source, srcIdx, &length, maxIdx, 1, NULL);
11352
    if (ret != 0)
11353
        return ret;
11354
11355
    ret = GetASNInt(source, srcIdx, &length, maxIdx);
11356
    if (ret != 0)
11357
        return ASN_PARSE_E;
11358
11359
    *srcIdx += length;
11360
11361
    return 0;
11362
#else
11363
    DECL_ASNGETDATA(dataASN, dsaCertKeyASN_Length);
11364
    int ret = 0;
11365
11366
    (void)heap;
11367
11368
    CALLOC_ASNGETDATA(dataASN, dsaCertKeyASN_Length, ret, heap);
11369
    if (ret == 0) {
11370
        /* Parse the DSA key data to ensure valid. */
11371
        ret = GetASN_Items(dsaCertKeyASN, dataASN, dsaCertKeyASN_Length, 1,
11372
                           source, srcIdx, maxIdx);
11373
    }
11374
11375
    FREE_ASNGETDATA(dataASN, heap);
11376
    return ret;
11377
#endif /* WOLFSSL_ASN_TEMPLATE */
11378
}
11379
#endif /* !NO_DSA */
11380
11381
/* Decode the SubjectPublicKeyInfo block in a certificate.
11382
 *
11383
 * Stores the public key in fields of the certificate object.
11384
 * Validates the BER/DER items and does not store in a key object.
11385
 *
11386
 * @param [in, out] cert      Decoded certificate oject.
11387
 * @param [in]      source    BER/DER encoded SubjectPublicKeyInfo block.
11388
 * @param [in, out] inOutIdx  On in, start of public key.
11389
 *                            On out, start of ASN.1 item after public key.
11390
 * @param [in]      maxIdx    Maximum index of key data.
11391
 * @return  0 on success.
11392
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
11393
 *          is invalid.
11394
 * @return  BUFFER_E when data in buffer is too small.
11395
 */
11396
static int GetCertKey(DecodedCert* cert, const byte* source, word32* inOutIdx,
11397
                      word32 maxIdx)
11398
0
{
11399
0
    word32 srcIdx = *inOutIdx;
11400
0
#if defined(HAVE_ECC) || !defined(NO_DSA)
11401
0
    int pubLen;
11402
0
#endif
11403
0
#if defined(HAVE_ECC) || !defined(NO_DSA)
11404
0
    int pubIdx = srcIdx;
11405
0
#endif
11406
0
    int ret = 0;
11407
0
    int length;
11408
11409
0
#ifndef WOLFSSL_ASN_TEMPLATE
11410
0
    if (GetSequence(source, &srcIdx, &length, maxIdx) < 0)
11411
#else
11412
    /* Get SEQUENCE and expect all data to be accounted for. */
11413
    if (GetASN_Sequence(source, &srcIdx, &length, maxIdx, 1) != 0)
11414
#endif
11415
0
    {
11416
0
        return ASN_PARSE_E;
11417
0
    }
11418
11419
0
#if defined(HAVE_ECC) || !defined(NO_DSA)
11420
0
    pubLen = srcIdx - pubIdx + length;
11421
0
#endif
11422
0
    maxIdx = srcIdx + length;
11423
11424
    /* Decode the algorithm identifier for the key. */
11425
0
    if (GetAlgoId(source, &srcIdx, &cert->keyOID, oidKeyType, maxIdx) < 0) {
11426
0
        return ASN_PARSE_E;
11427
0
    }
11428
11429
0
    (void)length;
11430
11431
    /* Parse each type of public key. */
11432
0
    switch (cert->keyOID) {
11433
0
#ifndef NO_RSA
11434
0
    #ifdef WC_RSA_PSS
11435
0
        case RSAPSSk:
11436
0
            if (srcIdx != maxIdx &&
11437
0
                          source[srcIdx] == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
11438
0
                word32 seqIdx = srcIdx;
11439
0
                int seqLen;
11440
                /* Not set when -1. */
11441
0
                enum wc_HashType hash = WC_HASH_TYPE_NONE;
11442
0
                int mgf = -1;
11443
0
                int saltLen = 0;
11444
                /* Defaults for sig algorithm parameters. */
11445
0
                enum wc_HashType sigHash = WC_HASH_TYPE_SHA;
11446
0
                int sigMgf = WC_MGF1SHA1;
11447
0
                int sigSaltLen = 20;
11448
11449
0
                if (GetSequence(source, &srcIdx, &seqLen, maxIdx) < 0) {
11450
0
                    return ASN_PARSE_E;
11451
0
                }
11452
                /* Get the pubic key parameters. */
11453
0
                ret = DecodeRsaPssParams(source + seqIdx,
11454
0
                    seqLen + srcIdx - seqIdx, &hash, &mgf, &saltLen);
11455
0
                if (ret != 0) {
11456
0
                    return ASN_PARSE_E;
11457
0
                }
11458
                /* Get the signature parameters. */
11459
0
                ret = DecodeRsaPssParams(source + cert->sigParamsIndex,
11460
0
                    cert->sigParamsLength, &sigHash, &sigMgf, &sigSaltLen);
11461
0
                if (ret != 0) {
11462
0
                    return ASN_PARSE_E;
11463
0
                }
11464
                /* Validated signature params match public key params. */
11465
0
                if (hash != WC_HASH_TYPE_NONE && hash != sigHash) {
11466
0
                    WOLFSSL_MSG("RSA PSS: hash not matching signature hash");
11467
0
                    return ASN_PARSE_E;
11468
0
                }
11469
0
                if (mgf != -1 && mgf != sigMgf) {
11470
0
                    WOLFSSL_MSG("RSA PSS: MGF not matching signature MGF");
11471
0
                    return ASN_PARSE_E;
11472
0
                }
11473
0
                if (saltLen > sigSaltLen) {
11474
0
                    WOLFSSL_MSG("RSA PSS: sig salt length too small");
11475
0
                    return ASN_PARSE_E;
11476
0
                }
11477
0
                srcIdx += seqLen;
11478
0
            }
11479
0
            FALL_THROUGH;
11480
0
    #endif /* WC_RSA_PSS */
11481
0
        case RSAk:
11482
0
            ret = StoreRsaKey(cert, source, &srcIdx, maxIdx);
11483
0
            break;
11484
0
#endif /* NO_RSA */
11485
0
    #ifdef HAVE_ECC
11486
0
        case ECDSAk:
11487
0
            ret = StoreEccKey(cert, source, &srcIdx, maxIdx, source + pubIdx,
11488
0
                              pubLen);
11489
0
            break;
11490
0
    #endif /* HAVE_ECC */
11491
0
    #ifdef HAVE_ED25519
11492
0
        case ED25519k:
11493
0
            cert->pkCurveOID = ED25519k;
11494
0
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
11495
0
            break;
11496
0
    #endif /* HAVE_ED25519 */
11497
0
    #ifdef HAVE_ED448
11498
0
        case ED448k:
11499
0
            cert->pkCurveOID = ED448k;
11500
0
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
11501
0
            break;
11502
0
    #endif /* HAVE_ED448 */
11503
    #ifdef HAVE_PQC
11504
    #ifdef HAVE_FALCON
11505
        case FALCON_LEVEL1k:
11506
            cert->pkCurveOID = FALCON_LEVEL1k;
11507
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
11508
            break;
11509
        case FALCON_LEVEL5k:
11510
            cert->pkCurveOID = FALCON_LEVEL5k;
11511
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
11512
            break;
11513
    #endif /* HAVE_FALCON */
11514
    #ifdef HAVE_DILITHIUM
11515
        case DILITHIUM_LEVEL2k:
11516
            cert->pkCurveOID = DILITHIUM_LEVEL2k;
11517
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
11518
            break;
11519
        case DILITHIUM_LEVEL3k:
11520
            cert->pkCurveOID = DILITHIUM_LEVEL3k;
11521
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
11522
            break;
11523
        case DILITHIUM_LEVEL5k:
11524
            cert->pkCurveOID = DILITHIUM_LEVEL5k;
11525
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
11526
            break;
11527
        case DILITHIUM_AES_LEVEL2k:
11528
            cert->pkCurveOID = DILITHIUM_AES_LEVEL2k;
11529
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
11530
            break;
11531
        case DILITHIUM_AES_LEVEL3k:
11532
            cert->pkCurveOID = DILITHIUM_AES_LEVEL3k;
11533
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
11534
            break;
11535
        case DILITHIUM_AES_LEVEL5k:
11536
            cert->pkCurveOID = DILITHIUM_AES_LEVEL5k;
11537
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
11538
            break;
11539
    #endif /* HAVE_DILITHIUM */
11540
    #endif /* HAVE_PQC */
11541
    #ifndef NO_DSA
11542
        case DSAk:
11543
            cert->publicKey = source + pubIdx;
11544
            cert->pubKeySize = pubLen;
11545
            ret = ParseDsaKey(source, &srcIdx, maxIdx, cert->heap);
11546
            break;
11547
    #endif /* NO_DSA */
11548
0
        default:
11549
0
            WOLFSSL_MSG("Unknown or not compiled in key OID");
11550
0
            WOLFSSL_ERROR_VERBOSE(ASN_UNKNOWN_OID_E);
11551
0
            ret = ASN_UNKNOWN_OID_E;
11552
0
    }
11553
11554
    /* Return index after public key. */
11555
0
    *inOutIdx = srcIdx;
11556
11557
    /* Return error code. */
11558
0
    return ret;
11559
0
}
11560
11561
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
11562
#if defined(HAVE_ECC)
11563
/* Converts ECC curve enum values in ecc_curve_id to the associated OpenSSL NID
11564
 * value.
11565
 *
11566
 * @param [in] n  ECC curve id.
11567
 * @return  ECC curve NID (OpenSSL compatable value).
11568
 */
11569
WOLFSSL_API int EccEnumToNID(int n)
11570
{
11571
    WOLFSSL_ENTER("EccEnumToNID()");
11572
11573
    switch(n) {
11574
        case ECC_SECP192R1:
11575
            return NID_X9_62_prime192v1;
11576
        case ECC_PRIME192V2:
11577
            return NID_X9_62_prime192v2;
11578
        case ECC_PRIME192V3:
11579
            return NID_X9_62_prime192v3;
11580
        case ECC_PRIME239V1:
11581
            return NID_X9_62_prime239v1;
11582
        case ECC_PRIME239V2:
11583
            return NID_X9_62_prime239v2;
11584
        case ECC_PRIME239V3:
11585
            return NID_X9_62_prime239v3;
11586
        case ECC_SECP256R1:
11587
            return NID_X9_62_prime256v1;
11588
        case ECC_SECP112R1:
11589
            return NID_secp112r1;
11590
        case ECC_SECP112R2:
11591
            return NID_secp112r2;
11592
        case ECC_SECP128R1:
11593
            return NID_secp128r1;
11594
        case ECC_SECP128R2:
11595
            return NID_secp128r2;
11596
        case ECC_SECP160R1:
11597
            return NID_secp160r1;
11598
        case ECC_SECP160R2:
11599
            return NID_secp160r2;
11600
        case ECC_SECP224R1:
11601
            return NID_secp224r1;
11602
        case ECC_SECP384R1:
11603
            return NID_secp384r1;
11604
        case ECC_SECP521R1:
11605
            return NID_secp521r1;
11606
        case ECC_SECP160K1:
11607
            return NID_secp160k1;
11608
        case ECC_SECP192K1:
11609
            return NID_secp192k1;
11610
        case ECC_SECP224K1:
11611
            return NID_secp224k1;
11612
        case ECC_SECP256K1:
11613
            return NID_secp256k1;
11614
        case ECC_BRAINPOOLP160R1:
11615
            return NID_brainpoolP160r1;
11616
        case ECC_BRAINPOOLP192R1:
11617
            return NID_brainpoolP192r1;
11618
        case ECC_BRAINPOOLP224R1:
11619
            return NID_brainpoolP224r1;
11620
        case ECC_BRAINPOOLP256R1:
11621
            return NID_brainpoolP256r1;
11622
        case ECC_BRAINPOOLP320R1:
11623
            return NID_brainpoolP320r1;
11624
        case ECC_BRAINPOOLP384R1:
11625
            return NID_brainpoolP384r1;
11626
        case ECC_BRAINPOOLP512R1:
11627
            return NID_brainpoolP512r1;
11628
        default:
11629
            WOLFSSL_MSG("NID not found");
11630
            return -1;
11631
    }
11632
}
11633
#endif /* HAVE_ECC */
11634
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
11635
11636
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \
11637
    && !defined(WOLFCRYPT_ONLY)
11638
/* Convert shortname to NID.
11639
 *
11640
 * For OpenSSL compatability.
11641
 *
11642
 * @param [in] sn  Short name of OID.
11643
 * @return  NID corresponding to shortname on success.
11644
 * @return  NID_undef when not recognized.
11645
 */
11646
int wc_OBJ_sn2nid(const char *sn)
11647
{
11648
    const struct {
11649
        const char *sn;
11650
        int  nid;
11651
    } sn2nid[] = {
11652
        {WOLFSSL_COMMON_NAME, NID_commonName},
11653
        {WOLFSSL_COUNTRY_NAME, NID_countryName},
11654
        {WOLFSSL_LOCALITY_NAME, NID_localityName},
11655
        {WOLFSSL_STATE_NAME, NID_stateOrProvinceName},
11656
        {WOLFSSL_ORG_NAME, NID_organizationName},
11657
        {WOLFSSL_ORGUNIT_NAME, NID_organizationalUnitName},
11658
    #ifdef WOLFSSL_CERT_NAME_ALL
11659
        {WOLFSSL_NAME, NID_name},
11660
        {WOLFSSL_INITIALS, NID_initials},
11661
        {WOLFSSL_GIVEN_NAME, NID_givenName},
11662
        {WOLFSSL_DNQUALIFIER, NID_dnQualifier},
11663
    #endif
11664
        {WOLFSSL_EMAIL_ADDR, NID_emailAddress},
11665
        {"SHA1", NID_sha1},
11666
        {NULL, -1}};
11667
    int i;
11668
#ifdef HAVE_ECC
11669
    char curveName[ECC_MAXNAME + 1];
11670
    int eccEnum;
11671
#endif
11672
    WOLFSSL_ENTER("OBJ_sn2nid");
11673
    for(i=0; sn2nid[i].sn != NULL; i++) {
11674
        if (XSTRCMP(sn, sn2nid[i].sn) == 0) {
11675
            return sn2nid[i].nid;
11676
        }
11677
    }
11678
#ifdef HAVE_ECC
11679
11680
    if (XSTRLEN(sn) > ECC_MAXNAME)
11681
        return NID_undef;
11682
11683
    /* Nginx uses this OpenSSL string. */
11684
    if (XSTRCMP(sn, "prime256v1") == 0)
11685
        sn = "SECP256R1";
11686
    /* OpenSSL allows lowercase curve names */
11687
    for (i = 0; i < (int)(sizeof(curveName) - 1) && *sn; i++) {
11688
        curveName[i] = (char)XTOUPPER((unsigned char) *sn++);
11689
    }
11690
    curveName[i] = '\0';
11691
    /* find based on name and return NID */
11692
    for (i = 0;
11693
#ifndef WOLFSSL_ECC_CURVE_STATIC
11694
         ecc_sets[i].size != 0 && ecc_sets[i].name != NULL;
11695
#else
11696
         ecc_sets[i].size != 0;
11697
#endif
11698
         i++) {
11699
        if (XSTRCMP(curveName, ecc_sets[i].name) == 0) {
11700
            eccEnum = ecc_sets[i].id;
11701
            /* Convert enum value in ecc_curve_id to OpenSSL NID */
11702
            return EccEnumToNID(eccEnum);
11703
        }
11704
    }
11705
#endif /* HAVE_ECC */
11706
11707
    return NID_undef;
11708
}
11709
#endif
11710
11711
/* Calculate hash of the id using the SHA-1 or SHA-256.
11712
 *
11713
 * @param [in]  data  Data to hash.
11714
 * @param [in]  len   Length of data to hash.
11715
 * @param [out] hash  Buffer to hold hash.
11716
 * @return  0 on success.
11717
 * @return  MEMORY_E when dynamic memory allocation fails.
11718
 */
11719
int CalcHashId(const byte* data, word32 len, byte* hash)
11720
0
{
11721
0
    int ret;
11722
11723
#if defined(NO_SHA) && !defined(NO_SHA256)
11724
    ret = wc_Sha256Hash(data, len, hash);
11725
#elif !defined(NO_SHA)
11726
0
    ret = wc_ShaHash(data, len, hash);
11727
#else
11728
    ret = NOT_COMPILED_IN;
11729
    (void)data;
11730
    (void)len;
11731
    (void)hash;
11732
#endif
11733
11734
0
    return ret;
11735
0
}
11736
11737
#ifndef NO_CERTS
11738
/* Get the hash of the id using the SHA-1 or SHA-256.
11739
 *
11740
 * If the id is not the length of the hash, then hash it.
11741
 *
11742
 * @param [in]  id    Id to get hash for.
11743
 * @param [in]  len   Length of id in bytes.
11744
 * @param [out] hash  Buffer to hold hash.
11745
 * @return  0 on success.
11746
 * @return  MEMORY_E when dynamic memory allocation fails.
11747
 */
11748
static int GetHashId(const byte* id, int length, byte* hash)
11749
0
{
11750
0
    int ret;
11751
11752
0
    if (length == KEYID_SIZE) {
11753
0
        XMEMCPY(hash, id, length);
11754
0
        ret = 0;
11755
0
    }
11756
0
    else {
11757
0
        ret = CalcHashId(id, length, hash);
11758
0
    }
11759
11760
0
    return ret;
11761
0
}
11762
#endif /* !NO_CERTS */
11763
11764
#ifdef WOLFSSL_ASN_TEMPLATE
11765
/* Id for email address. */
11766
#define ASN_EMAIL     0x100
11767
/* Id for domain component. */
11768
#define ASN_DC        0x102
11769
/* Id for jurisdiction country. */
11770
#define ASN_JURIS_C   0x203
11771
/* Id for jurisdiction state. */
11772
#define ASN_JURIS_ST  0x203
11773
11774
/* Set the string for a name component into the subject name. */
11775
#define SetCertNameSubject(cert, id, val) \
11776
    *((char**)(((byte *)(cert)) + certNameSubject[(id) - 3].data)) = (val)
11777
/* Set the string length for a name component into the subject name. */
11778
#define SetCertNameSubjectLen(cert, id, val) \
11779
    *((int*)(((byte *)(cert)) + certNameSubject[(id) - 3].len)) = (val)
11780
/* Set the encoding for a name component into the subject name. */
11781
#define SetCertNameSubjectEnc(cert, id, val) \
11782
    *((byte*)(((byte *)(cert)) + certNameSubject[(id) - 3].enc)) = (val)
11783
11784
/* Get the string of a name component from the subject name. */
11785
#define GetCertNameSubjectStr(id) \
11786
    (certNameSubject[(id) - 3].str)
11787
/* Get the string length of a name component from the subject name. */
11788
#define GetCertNameSubjectStrLen(id) \
11789
    (certNameSubject[(id) - 3].strLen)
11790
/* Get the NID of a name component from the subject name. */
11791
#define GetCertNameSubjectNID(id) \
11792
    (certNameSubject[(id) - 3].nid)
11793
11794
#define ValidCertNameSubject(id) \
11795
    (((id) - 3) >= 0 && ((id) - 3) < certNameSubjectSz && \
11796
            (certNameSubject[(id) - 3].strLen > 0))
11797
11798
/* Mapping of certificate name component to useful information. */
11799
typedef struct CertNameData {
11800
    /* Type string of name component. */
11801
    const char* str;
11802
    /* Length of type string of name component. */
11803
    byte        strLen;
11804
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
11805
    /* Offset of data in subject name component. */
11806
    size_t      data;
11807
    /* Offset of length in subject name component. */
11808
    size_t      len;
11809
    /* Offset of encoding in subject name component. */
11810
    size_t      enc;
11811
#endif
11812
#ifdef WOLFSSL_X509_NAME_AVAILABLE
11813
    /* NID of type for subject name component. */
11814
    int         nid;
11815
#endif
11816
} CertNameData;
11817
11818
/* List of data for common name components. */
11819
static const CertNameData certNameSubject[] = {
11820
    /* Common Name */
11821
    {
11822
        "/CN=", 4,
11823
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
11824
        OFFSETOF(DecodedCert, subjectCN),
11825
        OFFSETOF(DecodedCert, subjectCNLen),
11826
        OFFSETOF(DecodedCert, subjectCNEnc),
11827
#endif
11828
#ifdef WOLFSSL_X509_NAME_AVAILABLE
11829
        NID_commonName
11830
#endif
11831
    },
11832
    /* Surname */
11833
    {
11834
        "/SN=", 4,
11835
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
11836
        OFFSETOF(DecodedCert, subjectSN),
11837
        OFFSETOF(DecodedCert, subjectSNLen),
11838
        OFFSETOF(DecodedCert, subjectSNEnc),
11839
#endif
11840
#ifdef WOLFSSL_X509_NAME_AVAILABLE
11841
        NID_surname
11842
#endif
11843
    },
11844
    /* Serial Number */
11845
    {
11846
        "/serialNumber=", 14,
11847
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
11848
        OFFSETOF(DecodedCert, subjectSND),
11849
        OFFSETOF(DecodedCert, subjectSNDLen),
11850
        OFFSETOF(DecodedCert, subjectSNDEnc),
11851
#endif
11852
#ifdef WOLFSSL_X509_NAME_AVAILABLE
11853
        NID_serialNumber
11854
#endif
11855
    },
11856
    /* Country Name */
11857
    {
11858
        "/C=", 3,
11859
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
11860
        OFFSETOF(DecodedCert, subjectC),
11861
        OFFSETOF(DecodedCert, subjectCLen),
11862
        OFFSETOF(DecodedCert, subjectCEnc),
11863
#endif
11864
#ifdef WOLFSSL_X509_NAME_AVAILABLE
11865
        NID_countryName
11866
#endif
11867
    },
11868
    /* Locality Name */
11869
    {
11870
        "/L=", 3,
11871
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
11872
        OFFSETOF(DecodedCert, subjectL),
11873
        OFFSETOF(DecodedCert, subjectLLen),
11874
        OFFSETOF(DecodedCert, subjectLEnc),
11875
#endif
11876
#ifdef WOLFSSL_X509_NAME_AVAILABLE
11877
        NID_localityName
11878
#endif
11879
    },
11880
    /* State Name */
11881
    {
11882
        "/ST=", 4,
11883
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
11884
        OFFSETOF(DecodedCert, subjectST),
11885
        OFFSETOF(DecodedCert, subjectSTLen),
11886
        OFFSETOF(DecodedCert, subjectSTEnc),
11887
#endif
11888
#ifdef WOLFSSL_X509_NAME_AVAILABLE
11889
        NID_stateOrProvinceName
11890
#endif
11891
    },
11892
    /* Street Address */
11893
    {
11894
        "/street=", 8,
11895
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
11896
        OFFSETOF(DecodedCert, subjectStreet),
11897
        OFFSETOF(DecodedCert, subjectStreetLen),
11898
        OFFSETOF(DecodedCert, subjectStreetEnc),
11899
#endif
11900
#ifdef WOLFSSL_X509_NAME_AVAILABLE
11901
        NID_streetAddress
11902
#endif
11903
    },
11904
    /* Organization Name */
11905
    {
11906
        "/O=", 3,
11907
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
11908
        OFFSETOF(DecodedCert, subjectO),
11909
        OFFSETOF(DecodedCert, subjectOLen),
11910
        OFFSETOF(DecodedCert, subjectOEnc),
11911
#endif
11912
#ifdef WOLFSSL_X509_NAME_AVAILABLE
11913
        NID_organizationName
11914
#endif
11915
    },
11916
    /* Organization Unit Name */
11917
    {
11918
        "/OU=", 4,
11919
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
11920
        OFFSETOF(DecodedCert, subjectOU),
11921
        OFFSETOF(DecodedCert, subjectOULen),
11922
        OFFSETOF(DecodedCert, subjectOUEnc),
11923
#endif
11924
#ifdef WOLFSSL_X509_NAME_AVAILABLE
11925
        NID_organizationalUnitName
11926
#endif
11927
    },
11928
    /* Title */
11929
    {
11930
        NULL, 0,
11931
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
11932
        0,
11933
        0,
11934
        0,
11935
#endif
11936
#ifdef WOLFSSL_X509_NAME_AVAILABLE
11937
        0,
11938
#endif
11939
    },
11940
    /* Undefined */
11941
    {
11942
        NULL, 0,
11943
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
11944
        0,
11945
        0,
11946
        0,
11947
#endif
11948
#ifdef WOLFSSL_X509_NAME_AVAILABLE
11949
        0,
11950
#endif
11951
    },
11952
    /* Undefined */
11953
    {
11954
        NULL, 0,
11955
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
11956
        0,
11957
        0,
11958
        0,
11959
#endif
11960
#ifdef WOLFSSL_X509_NAME_AVAILABLE
11961
        0,
11962
#endif
11963
    },
11964
    /* Business Category */
11965
    {
11966
        "/businessCategory=", 18,
11967
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
11968
        OFFSETOF(DecodedCert, subjectBC),
11969
        OFFSETOF(DecodedCert, subjectBCLen),
11970
        OFFSETOF(DecodedCert, subjectBCEnc),
11971
#endif
11972
#ifdef WOLFSSL_X509_NAME_AVAILABLE
11973
        NID_businessCategory
11974
#endif
11975
    },
11976
    /* Undefined */
11977
    {
11978
        NULL, 0,
11979
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
11980
        0,
11981
        0,
11982
        0,
11983
#endif
11984
#ifdef WOLFSSL_X509_NAME_AVAILABLE
11985
        0,
11986
#endif
11987
    },
11988
    /* Postal Code */
11989
    {
11990
        "/postalCode=", 12,
11991
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
11992
        OFFSETOF(DecodedCert, subjectPC),
11993
        OFFSETOF(DecodedCert, subjectPCLen),
11994
        OFFSETOF(DecodedCert, subjectPCEnc),
11995
#endif
11996
#ifdef WOLFSSL_X509_NAME_AVAILABLE
11997
        NID_postalCode
11998
#endif
11999
    },
12000
    /* User Id */
12001
    {
12002
        "/userid=", 8,
12003
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12004
        OFFSETOF(DecodedCert, subjectUID),
12005
        OFFSETOF(DecodedCert, subjectUIDLen),
12006
        OFFSETOF(DecodedCert, subjectUIDEnc),
12007
#endif
12008
#ifdef WOLFSSL_X509_NAME_AVAILABLE
12009
        NID_userId
12010
#endif
12011
    },
12012
#ifdef WOLFSSL_CERT_NAME_ALL
12013
    /* Name, id 41 */
12014
    {
12015
        "/N=", 3,
12016
    #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12017
        OFFSETOF(DecodedCert, subjectN),
12018
        OFFSETOF(DecodedCert, subjectNLen),
12019
        OFFSETOF(DecodedCert, subjectNEnc),
12020
    #endif
12021
    #ifdef WOLFSSL_X509_NAME_AVAILABLE
12022
        NID_name
12023
    #endif
12024
    },
12025
    /* Given Name, id 42 */
12026
    {
12027
        "/GN=", 4,
12028
    #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12029
        OFFSETOF(DecodedCert, subjectGN),
12030
        OFFSETOF(DecodedCert, subjectGNLen),
12031
        OFFSETOF(DecodedCert, subjectGNEnc),
12032
    #endif
12033
    #ifdef WOLFSSL_X509_NAME_AVAILABLE
12034
        NID_givenName
12035
    #endif
12036
    },
12037
    /* initials, id 43 */
12038
    {
12039
        "/initials=", 10,
12040
    #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12041
        OFFSETOF(DecodedCert, subjectI),
12042
        OFFSETOF(DecodedCert, subjectILen),
12043
        OFFSETOF(DecodedCert, subjectIEnc),
12044
    #endif
12045
    #ifdef WOLFSSL_X509_NAME_AVAILABLE
12046
        NID_initials
12047
    #endif
12048
    },
12049
    /* DN Qualifier Name, id 46 */
12050
    {
12051
        "/dnQualifier=", 13,
12052
    #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12053
        OFFSETOF(DecodedCert, subjectDNQ),
12054
        OFFSETOF(DecodedCert, subjectDNQLen),
12055
        OFFSETOF(DecodedCert, subjectDNQEnc),
12056
    #endif
12057
    #ifdef WOLFSSL_X509_NAME_AVAILABLE
12058
        NID_dnQualifier
12059
    #endif
12060
    },
12061
#endif /* WOLFSSL_CERT_NAME_ALL */
12062
};
12063
12064
static const int certNameSubjectSz =
12065
        (int) (sizeof(certNameSubject) / sizeof(CertNameData));
12066
12067
/* ASN.1 template for an RDN.
12068
 * X.509: RFC 5280, 4.1.2.4 - RelativeDistinguishedName
12069
 */
12070
static const ASNItem rdnASN[] = {
12071
/* SET       */ { 1, ASN_SET, 1, 1, 0 },
12072
                           /* AttributeTypeAndValue */
12073
/* ATTR_SEQ  */     { 2, ASN_SEQUENCE, 1, 1, 0 },
12074
                                   /* AttributeType */
12075
/* ATTR_TYPE */         { 3, ASN_OBJECT_ID, 0, 0, 0 },
12076
                           /* AttributeValue: Choice of tags - rdnChoice. */
12077
/* ATTR_VAL  */         { 3, 0, 0, 0, 0 },
12078
};
12079
enum {
12080
    RDNASN_IDX_SET = 0,
12081
    RDNASN_IDX_ATTR_SEQ,
12082
    RDNASN_IDX_ATTR_TYPE,
12083
    RDNASN_IDX_ATTR_VAL,
12084
};
12085
12086
/* Number of items in ASN.1 template for an RDN. */
12087
#define rdnASN_Length (sizeof(rdnASN) / sizeof(ASNItem))
12088
12089
/* Supported types of encodings (tags) for RDN strings.
12090
 * X.509: RFC 5280, 4.1.2.4 - DirectoryString
12091
 * (IA5 String not listed in RFC but required for alternative types)
12092
 */
12093
static const byte rdnChoice[] = {
12094
    ASN_PRINTABLE_STRING, ASN_IA5_STRING, ASN_UTF8STRING, ASN_T61STRING,
12095
    ASN_UNIVERSALSTRING, ASN_BMPSTRING, 0
12096
};
12097
#endif
12098
12099
#if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
12100
/* used to set the human readable string for the IP address with a ASN_IP_TYPE
12101
 * DNS entry
12102
 * return 0 on success
12103
 */
12104
static int GenerateDNSEntryIPString(DNS_entry* entry, void* heap)
12105
{
12106
    int ret = 0;
12107
    int nameSz;
12108
    char tmpName[WOLFSSL_MAX_IPSTR] = {0};
12109
    char* ip;
12110
12111
    if (entry == NULL || entry->type != ASN_IP_TYPE) {
12112
        return BAD_FUNC_ARG;
12113
    }
12114
12115
    if (entry->len != WOLFSSL_IP4_ADDR_LEN &&
12116
            entry->len != WOLFSSL_IP6_ADDR_LEN) {
12117
        WOLFSSL_MSG("Unexpected IP size");
12118
        return BAD_FUNC_ARG;
12119
    }
12120
    ip = entry->name;
12121
12122
    /* store IP addresses as a string */
12123
    if (entry->len == WOLFSSL_IP4_ADDR_LEN) {
12124
        if (XSNPRINTF(tmpName, sizeof(tmpName), "%u.%u.%u.%u", 0xFFU & ip[0],
12125
                      0xFFU & ip[1], 0xFFU & ip[2], 0xFFU & ip[3])
12126
            >= (int)sizeof(tmpName))
12127
        {
12128
            WOLFSSL_MSG("IP buffer overrun");
12129
            return BUFFER_E;
12130
        }
12131
    }
12132
12133
    if (entry->len == WOLFSSL_IP6_ADDR_LEN) {
12134
        int i;
12135
        for (i = 0; i < 8; i++) {
12136
            if (XSNPRINTF(tmpName + i * 5, sizeof(tmpName) - i * 5,
12137
                    "%02X%02X%s", 0xFF & ip[2 * i], 0xFF & ip[2 * i + 1],
12138
                    (i < 7) ? ":" : "")
12139
                >= (int)sizeof(tmpName))
12140
            {
12141
                WOLFSSL_MSG("IPv6 buffer overrun");
12142
                return BUFFER_E;
12143
            }
12144
        }
12145
    }
12146
12147
    nameSz = (int)XSTRLEN(tmpName);
12148
    entry->ipString = (char*)XMALLOC(nameSz + 1, heap, DYNAMIC_TYPE_ALTNAME);
12149
    if (entry->ipString == NULL) {
12150
        ret = MEMORY_E;
12151
    }
12152
12153
    if (ret == 0) {
12154
        XMEMCPY(entry->ipString, tmpName, nameSz);
12155
        entry->ipString[nameSz] = '\0';
12156
    }
12157
12158
    (void)heap;
12159
12160
    return ret;
12161
}
12162
#endif /* OPENSSL_ALL || WOLFSSL_IP_ALT_NAME */
12163
12164
#ifdef WOLFSSL_ASN_TEMPLATE
12165
#if defined(WOLFSSL_CERT_GEN) || \
12166
    (!defined(NO_CERTS) && !defined(IGNORE_NAME_CONSTRAINTS))
12167
12168
/* Adds a DNS entry to a list of DNS entries
12169
 *
12170
 * @param [in, out] lst      Linked list of DNS name entries.
12171
 * @param [in]      entry    Entry to add to the list
12172
 * @return  0 on success.
12173
 */
12174
static int AddDNSEntryToList(DNS_entry** lst, DNS_entry* entry)
12175
{
12176
#if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_ALT_NAMES_NO_REV)
12177
    entry->next = NULL;
12178
    if (*lst == NULL) {
12179
        /* First on list */
12180
        *lst = entry;
12181
    }
12182
    else {
12183
        DNS_entry* temp = *lst;
12184
12185
        /* Find end */
12186
        for (; (temp->next != NULL); temp = temp->next);
12187
12188
        /* Add to end */
12189
        temp->next = entry;
12190
    }
12191
#else
12192
    /* Prepend entry to linked list. */
12193
    entry->next = *lst;
12194
    *lst = entry;
12195
#endif
12196
12197
    return 0;
12198
}
12199
12200
12201
/* Allocate a DNS entry and set the fields.
12202
 *
12203
 * @param [in]      cert     Certificate object.
12204
 * @param [in]      str      DNS name string.
12205
 * @param [in]      strLen   Length of DNS name string.
12206
 * @param [in]      type     Type of DNS name string.
12207
 * @param [in, out] entries  Linked list of DNS name entries.
12208
 * @return  0 on success.
12209
 * @return  MEMORY_E when dynamic memory allocation fails.
12210
 */
12211
static int SetDNSEntry(DecodedCert* cert, const char* str, int strLen,
12212
                       int type, DNS_entry** entries)
12213
{
12214
    DNS_entry* dnsEntry;
12215
    int ret = 0;
12216
12217
    /* Only used for heap. */
12218
    (void)cert;
12219
12220
    /* TODO: consider one malloc. */
12221
    /* Allocate DNS Entry object. */
12222
    dnsEntry = AltNameNew(cert->heap);
12223
    if (dnsEntry == NULL) {
12224
        ret = MEMORY_E;
12225
    }
12226
    if (ret == 0) {
12227
        /* Allocate DNS Entry name - length of string plus 1 for NUL. */
12228
        dnsEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
12229
                                                          DYNAMIC_TYPE_ALTNAME);
12230
        if (dnsEntry->name == NULL) {
12231
            XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
12232
            ret = MEMORY_E;
12233
        }
12234
    }
12235
    if (ret == 0) {
12236
        /* Set tag type, name length, name and NUL terminate name. */
12237
        dnsEntry->type = type;
12238
        dnsEntry->len = strLen;
12239
        XMEMCPY(dnsEntry->name, str, strLen);
12240
        dnsEntry->name[strLen] = '\0';
12241
12242
    #if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
12243
        /* store IP addresses as a string */
12244
        if (type == ASN_IP_TYPE) {
12245
            if ((ret = GenerateDNSEntryIPString(dnsEntry, cert->heap)) != 0) {
12246
                XFREE(dnsEntry->name, cert->heap, DYNAMIC_TYPE_ALTNAME);
12247
                XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
12248
            }
12249
        }
12250
    #endif
12251
    }
12252
12253
    if (ret == 0) {
12254
        ret = AddDNSEntryToList(entries, dnsEntry);
12255
    }
12256
12257
    return ret;
12258
}
12259
#endif
12260
12261
/* Set the details of a subject name component into a certificate.
12262
 *
12263
 * @param [in, out] cert    Certificate object.
12264
 * @param [in]      id      Id of component.
12265
 * @param [in]      str     String for component.
12266
 * @param [in]      strLen  Length of string.
12267
 * @param [in]      tag     BER tag representing encoding of string.
12268
 * @return  0 on success, negative values on failure.
12269
 */
12270
static int SetSubject(DecodedCert* cert, int id, byte* str, word32 strLen,
12271
                      byte tag)
12272
{
12273
    int ret = 0;
12274
12275
    /* Put string and encoding into certificate. */
12276
    if (id == ASN_COMMON_NAME) {
12277
        cert->subjectCN = (char *)str;
12278
        cert->subjectCNLen = strLen;
12279
        cert->subjectCNEnc = tag;
12280
    }
12281
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12282
    else if (id > ASN_COMMON_NAME && id <= ASN_USER_ID) {
12283
        /* Use table and offsets to put data into appropriate fields. */
12284
        SetCertNameSubject(cert, id, (char*)str);
12285
        SetCertNameSubjectLen(cert, id, strLen);
12286
        SetCertNameSubjectEnc(cert, id, tag);
12287
    }
12288
#endif
12289
#if !defined(IGNORE_NAME_CONSTRAINTS) || \
12290
     defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12291
    else if (id == ASN_EMAIL) {
12292
        cert->subjectEmail = (char*)str;
12293
        cert->subjectEmailLen = strLen;
12294
    }
12295
#endif
12296
#ifdef WOLFSSL_CERT_EXT
12297
    /* TODO: consider mapping id to an index and using SetCertNameSubect*(). */
12298
    else if (id == ASN_JURIS_C) {
12299
        cert->subjectJC = (char*)str;
12300
        cert->subjectJCLen = strLen;
12301
        cert->subjectJCEnc = tag;
12302
    }
12303
    else if (id == ASN_JURIS_ST) {
12304
        cert->subjectJS = (char*)str;
12305
        cert->subjectJSLen = strLen;
12306
        cert->subjectJSEnc = tag;
12307
    }
12308
#endif
12309
12310
    return ret;
12311
}
12312
12313
/* Get a RelativeDistinguishedName from the encoding and put in certificate.
12314
 *
12315
 * @param [in, out] cert       Certificate object.
12316
 * @param [in, out] full       Full name string. ([/<type>=<value>]*)
12317
 * @param [in, out] idx        Index int full name to place next component.
12318
 * @param [in, out] nid        NID of component type.
12319
 * @param [in]      isSubject  Whether this data is for a subject name.
12320
 * @param [in]      dataASN    Decoded data of RDN. Expected rdnASN type.
12321
 * @return  0 on success.
12322
 * @return  MEMORY_E when dynamic memory allocation fails.
12323
 * @return  ASN_PARSE_E when type not supported.
12324
 */
12325
static int GetRDN(DecodedCert* cert, char* full, word32* idx, int* nid,
12326
                  int isSubject, ASNGetData* dataASN)
12327
{
12328
    int         ret = 0;
12329
    const char* typeStr = NULL;
12330
    byte        typeStrLen = 0;
12331
    byte*       oid;
12332
    word32      oidSz;
12333
    int         id = 0;
12334
12335
    (void)nid;
12336
12337
    /* Get name type OID from data items. */
12338
    GetASN_OIDData(&dataASN[RDNASN_IDX_ATTR_TYPE], &oid, &oidSz);
12339
12340
    /* v1 name types */
12341
    if ((oidSz == 3) && (oid[0] == 0x55) && (oid[1] == 0x04)) {
12342
        id = oid[2];
12343
        /* Check range of supported ids in table. */
12344
        if (ValidCertNameSubject(id)) {
12345
            /* Get the type string, length and NID from table. */
12346
            typeStr = GetCertNameSubjectStr(id);
12347
            typeStrLen = GetCertNameSubjectStrLen(id);
12348
        #ifdef WOLFSSL_X509_NAME_AVAILABLE
12349
            *nid = GetCertNameSubjectNID(id);
12350
        #endif
12351
        }
12352
    }
12353
    else if (oidSz == sizeof(attrEmailOid) && XMEMCMP(oid, attrEmailOid, oidSz) == 0) {
12354
        /* Set the email id, type string, length and NID. */
12355
        id = ASN_EMAIL;
12356
        typeStr =  WOLFSSL_EMAIL_ADDR;
12357
        typeStrLen = sizeof(WOLFSSL_EMAIL_ADDR) - 1;
12358
    #ifdef WOLFSSL_X509_NAME_AVAILABLE
12359
        *nid = NID_emailAddress;
12360
    #endif
12361
    }
12362
    else if (oidSz == sizeof(uidOid) && XMEMCMP(oid, uidOid, oidSz) == 0) {
12363
        /* Set the user id, type string, length and NID. */
12364
        id = ASN_USER_ID;
12365
        typeStr = WOLFSSL_USER_ID;
12366
        typeStrLen = sizeof(WOLFSSL_USER_ID) - 1;
12367
    #ifdef WOLFSSL_X509_NAME_AVAILABLE
12368
        *nid = NID_userId;
12369
    #endif
12370
    }
12371
    else if (oidSz == sizeof(dcOid) && XMEMCMP(oid, dcOid, oidSz) == 0) {
12372
        /* Set the domain component, type string, length and NID. */
12373
        id = ASN_DC;
12374
        typeStr = WOLFSSL_DOMAIN_COMPONENT;
12375
        typeStrLen = sizeof(WOLFSSL_DOMAIN_COMPONENT) - 1;
12376
    #ifdef WOLFSSL_X509_NAME_AVAILABLE
12377
        *nid = NID_domainComponent;
12378
    #endif
12379
    }
12380
    /* Other OIDs that start with the same values. */
12381
    else if (oidSz == sizeof(dcOid) && XMEMCMP(oid, dcOid, oidSz-1) == 0) {
12382
        WOLFSSL_MSG("Unknown pilot attribute type");
12383
        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
12384
        ret = ASN_PARSE_E;
12385
    }
12386
    else if (oidSz == ASN_JOI_PREFIX_SZ + 1 &&
12387
                         XMEMCMP(oid, ASN_JOI_PREFIX, ASN_JOI_PREFIX_SZ) == 0) {
12388
        /* Set the jurisdiction id. */
12389
        id = 0x200 + oid[ASN_JOI_PREFIX_SZ];
12390
12391
        /* Set the jurisdiction type string, length and NID if known. */
12392
        if (oid[ASN_JOI_PREFIX_SZ] == ASN_JOI_C) {
12393
            typeStr = WOLFSSL_JOI_C;
12394
            typeStrLen = sizeof(WOLFSSL_JOI_C) - 1;
12395
        #ifdef WOLFSSL_X509_NAME_AVAILABLE
12396
            *nid = NID_jurisdictionCountryName;
12397
        #endif /* WOLFSSL_X509_NAME_AVAILABLE */
12398
        }
12399
        else if (oid[ASN_JOI_PREFIX_SZ] == ASN_JOI_ST) {
12400
            typeStr = WOLFSSL_JOI_ST;
12401
            typeStrLen = sizeof(WOLFSSL_JOI_ST) - 1;
12402
        #ifdef WOLFSSL_X509_NAME_AVAILABLE
12403
            *nid = NID_jurisdictionStateOrProvinceName;
12404
        #endif /* WOLFSSL_X509_NAME_AVAILABLE */
12405
        }
12406
        else {
12407
            WOLFSSL_MSG("Unknown Jurisdiction, skipping");
12408
        }
12409
    }
12410
12411
    if ((ret == 0) && (typeStr != NULL)) {
12412
        /* OID type to store for subject name and add to full string. */
12413
        byte*  str;
12414
        word32 strLen;
12415
        byte   tag = dataASN[RDNASN_IDX_ATTR_VAL].tag;
12416
12417
        /* Get the string reference and length. */
12418
        GetASN_GetRef(&dataASN[RDNASN_IDX_ATTR_VAL], &str, &strLen);
12419
12420
        if (isSubject) {
12421
            /* Store subject field components. */
12422
            ret = SetSubject(cert, id, str, strLen, tag);
12423
        }
12424
        if (ret == 0) {
12425
            /* Check there is space for this in the full name string and
12426
             * terminating NUL character. */
12427
            if ((typeStrLen + strLen) < (word32)(WC_ASN_NAME_MAX - *idx))
12428
            {
12429
                /* Add RDN to full string. */
12430
                XMEMCPY(&full[*idx], typeStr, typeStrLen);
12431
                *idx += typeStrLen;
12432
                XMEMCPY(&full[*idx], str, strLen);
12433
                *idx += strLen;
12434
            }
12435
            else {
12436
                WOLFSSL_MSG("ASN Name too big, skipping");
12437
            }
12438
        }
12439
    }
12440
12441
    return ret;
12442
}
12443
#endif /* WOLFSSL_ASN_TEMPLATE */
12444
12445
/* Get a certificate name into the certificate object.
12446
 *
12447
 * @param [in, out] cert      Decoded certificate object.
12448
 * @param [out]     full      Buffer to hold full name as a string.
12449
 * @param [out]     hash      Buffer to hold hash of name.
12450
 * @param [in]      nameType  ISSUER or SUBJECT.
12451
 * @param [in]      input     Buffer holding certificate name.
12452
 * @param [in, out] inOutIdx  On in, start of certificate name.
12453
 *                            On out, start of ASN.1 item after cert name.
12454
 * @param [in]      maxIdx    Index of next item after certificate name.
12455
 * @return  0 on success.
12456
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
12457
 *          is invalid.
12458
 * @return  BUFFER_E when data in buffer is too small.
12459
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
12460
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
12461
 * @return  MEMORY_E when dynamic memory allocation fails.
12462
 */
12463
static int GetCertName(DecodedCert* cert, char* full, byte* hash, int nameType,
12464
                       const byte* input, word32* inOutIdx, word32 maxIdx)
12465
0
{
12466
0
#ifndef WOLFSSL_ASN_TEMPLATE
12467
0
    int    length;  /* length of all distinguished names */
12468
0
    int    dummy;
12469
0
    int    ret;
12470
0
    word32 idx;
12471
0
    word32 srcIdx = *inOutIdx;
12472
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
12473
    !defined(WOLFCRYPT_ONLY)
12474
    WOLFSSL_X509_NAME* dName = NULL;
12475
#endif
12476
12477
0
    WOLFSSL_MSG("Getting Cert Name");
12478
12479
    /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
12480
     * calculated over the entire DER encoding of the Name field, including
12481
     * the tag and length. */
12482
0
    if (CalcHashId(input + *inOutIdx, maxIdx - *inOutIdx, hash) != 0)
12483
0
        return ASN_PARSE_E;
12484
12485
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
12486
    !defined(WOLFCRYPT_ONLY)
12487
    dName = wolfSSL_X509_NAME_new();
12488
    if (dName == NULL) {
12489
        return MEMORY_E;
12490
    }
12491
#endif /* OPENSSL_EXTRA */
12492
12493
0
    if (GetSequence(input, &srcIdx, &length, maxIdx) < 0) {
12494
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
12495
            !defined(WOLFCRYPT_ONLY)
12496
        wolfSSL_X509_NAME_free(dName);
12497
#endif /* OPENSSL_EXTRA */
12498
0
        return ASN_PARSE_E;
12499
0
    }
12500
12501
#if defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT)
12502
    /* store pointer to raw issuer */
12503
    if (nameType == ISSUER) {
12504
        cert->issuerRaw = &input[srcIdx];
12505
        cert->issuerRawLen = length;
12506
    }
12507
#endif
12508
0
#if !defined(IGNORE_NAME_CONSTRAINTS) || defined(WOLFSSL_CERT_EXT)
12509
0
    if (nameType == SUBJECT) {
12510
0
        cert->subjectRaw = &input[srcIdx];
12511
0
        cert->subjectRawLen = length;
12512
0
    }
12513
0
#endif
12514
12515
0
    length += srcIdx;
12516
0
    idx = 0;
12517
12518
0
    while (srcIdx < (word32)length) {
12519
0
        byte        b       = 0;
12520
0
        byte        joint[3];
12521
0
        byte        tooBig  = FALSE;
12522
0
        int         oidSz;
12523
0
        const char* copy    = NULL;
12524
0
        int         copyLen = 0;
12525
0
        int         strLen  = 0;
12526
0
        byte        id      = 0;
12527
    #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \
12528
                && !defined(WOLFCRYPT_ONLY)
12529
         int        nid = NID_undef;
12530
         int        enc;
12531
    #endif /* OPENSSL_EXTRA */
12532
12533
0
        if (GetSet(input, &srcIdx, &dummy, maxIdx) < 0) {
12534
0
            WOLFSSL_MSG("Cert name lacks set header, trying sequence");
12535
0
        }
12536
12537
0
        if (GetSequence(input, &srcIdx, &dummy, maxIdx) <= 0) {
12538
        #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
12539
            !defined(WOLFCRYPT_ONLY)
12540
            wolfSSL_X509_NAME_free(dName);
12541
        #endif /* OPENSSL_EXTRA */
12542
0
            return ASN_PARSE_E;
12543
0
        }
12544
12545
0
        ret = GetASNObjectId(input, &srcIdx, &oidSz, maxIdx);
12546
0
        if (ret != 0) {
12547
        #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
12548
            !defined(WOLFCRYPT_ONLY)
12549
            wolfSSL_X509_NAME_free(dName);
12550
        #endif /* OPENSSL_EXTRA */
12551
0
            return ret;
12552
0
        }
12553
12554
        /* make sure there is room for joint */
12555
0
        if ((srcIdx + sizeof(joint)) > (word32)maxIdx) {
12556
        #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
12557
            !defined(WOLFCRYPT_ONLY)
12558
            wolfSSL_X509_NAME_free(dName);
12559
        #endif /* OPENSSL_EXTRA */
12560
0
            return ASN_PARSE_E;
12561
0
        }
12562
12563
0
        XMEMCPY(joint, &input[srcIdx], sizeof(joint));
12564
12565
        /* v1 name types */
12566
0
        if (joint[0] == 0x55 && joint[1] == 0x04) {
12567
0
            srcIdx += 3;
12568
0
            id = joint[2];
12569
0
            if (GetHeader(input, &b, &srcIdx, &strLen, maxIdx, 1) < 0) {
12570
            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
12571
            !defined(WOLFCRYPT_ONLY)
12572
                wolfSSL_X509_NAME_free(dName);
12573
            #endif /* OPENSSL_EXTRA */
12574
0
                return ASN_PARSE_E;
12575
0
            }
12576
12577
0
            if (id == ASN_COMMON_NAME) {
12578
0
                if (nameType == SUBJECT) {
12579
0
                    cert->subjectCN = (char *)&input[srcIdx];
12580
0
                    cert->subjectCNLen = strLen;
12581
0
                    cert->subjectCNEnc = b;
12582
0
                }
12583
            #if (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)) && \
12584
                defined(WOLFSSL_HAVE_ISSUER_NAMES)
12585
                else if (nameType == ISSUER) {
12586
                    cert->issuerCN = (char*)&input[srcIdx];
12587
                    cert->issuerCNLen = strLen;
12588
                    cert->issuerCNEnc = b;
12589
                }
12590
            #endif
12591
12592
0
                copy = WOLFSSL_COMMON_NAME;
12593
0
                copyLen = sizeof(WOLFSSL_COMMON_NAME) - 1;
12594
            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \
12595
                && !defined(WOLFCRYPT_ONLY)
12596
                nid = NID_commonName;
12597
            #endif /* OPENSSL_EXTRA */
12598
0
            }
12599
        #ifdef WOLFSSL_CERT_NAME_ALL
12600
            else if (id == ASN_NAME) {
12601
                copy = WOLFSSL_NAME;
12602
                copyLen = sizeof(WOLFSSL_NAME) - 1;
12603
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12604
                    if (nameType == SUBJECT) {
12605
                        cert->subjectN = (char*)&input[srcIdx];
12606
                        cert->subjectNLen = strLen;
12607
                        cert->subjectNEnc = b;
12608
                    }
12609
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
12610
                #if (defined(OPENSSL_EXTRA) || \
12611
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
12612
                        && !defined(WOLFCRYPT_ONLY)
12613
                    nid = NID_name;
12614
                #endif /* OPENSSL_EXTRA */
12615
            }
12616
            else if (id == ASN_INITIALS) {
12617
                copy = WOLFSSL_INITIALS;
12618
                copyLen = sizeof(WOLFSSL_INITIALS) - 1;
12619
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12620
                    if (nameType == SUBJECT) {
12621
                        cert->subjectI = (char*)&input[srcIdx];
12622
                        cert->subjectILen = strLen;
12623
                        cert->subjectIEnc = b;
12624
                    }
12625
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
12626
                #if (defined(OPENSSL_EXTRA) || \
12627
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
12628
                        && !defined(WOLFCRYPT_ONLY)
12629
                    nid = NID_initials;
12630
                #endif /* OPENSSL_EXTRA */
12631
            }
12632
            else if (id == ASN_GIVEN_NAME) {
12633
                copy = WOLFSSL_GIVEN_NAME;
12634
                copyLen = sizeof(WOLFSSL_GIVEN_NAME) - 1;
12635
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12636
                    if (nameType == SUBJECT) {
12637
                        cert->subjectGN = (char*)&input[srcIdx];
12638
                        cert->subjectGNLen = strLen;
12639
                        cert->subjectGNEnc = b;
12640
                    }
12641
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
12642
                #if (defined(OPENSSL_EXTRA) || \
12643
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
12644
                        && !defined(WOLFCRYPT_ONLY)
12645
                    nid = NID_givenName;
12646
                #endif /* OPENSSL_EXTRA */
12647
            }
12648
            else if (id == ASN_DNQUALIFIER) {
12649
                copy = WOLFSSL_DNQUALIFIER;
12650
                copyLen = sizeof(WOLFSSL_DNQUALIFIER) - 1;
12651
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12652
                    if (nameType == SUBJECT) {
12653
                        cert->subjectDNQ = (char*)&input[srcIdx];
12654
                        cert->subjectDNQLen = strLen;
12655
                        cert->subjectDNQEnc = b;
12656
                    }
12657
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
12658
                #if (defined(OPENSSL_EXTRA) || \
12659
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
12660
                        && !defined(WOLFCRYPT_ONLY)
12661
                    nid = NID_dnQualifier;
12662
                #endif /* OPENSSL_EXTRA */
12663
            }
12664
        #endif /* WOLFSSL_CERT_NAME_ALL */
12665
0
            else if (id == ASN_SUR_NAME) {
12666
0
                copy = WOLFSSL_SUR_NAME;
12667
0
                copyLen = sizeof(WOLFSSL_SUR_NAME) - 1;
12668
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12669
                    if (nameType == SUBJECT) {
12670
                        cert->subjectSN = (char*)&input[srcIdx];
12671
                        cert->subjectSNLen = strLen;
12672
                        cert->subjectSNEnc = b;
12673
                    }
12674
                #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
12675
                    else if (nameType == ISSUER) {
12676
                        cert->issuerSN = (char*)&input[srcIdx];
12677
                        cert->issuerSNLen = strLen;
12678
                        cert->issuerSNEnc = b;
12679
                    }
12680
                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
12681
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
12682
                #if (defined(OPENSSL_EXTRA) || \
12683
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
12684
                        && !defined(WOLFCRYPT_ONLY)
12685
                    nid = NID_surname;
12686
                #endif /* OPENSSL_EXTRA */
12687
0
            }
12688
0
            else if (id == ASN_COUNTRY_NAME) {
12689
0
                copy = WOLFSSL_COUNTRY_NAME;
12690
0
                copyLen = sizeof(WOLFSSL_COUNTRY_NAME) - 1;
12691
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12692
                    if (nameType == SUBJECT) {
12693
                        cert->subjectC = (char*)&input[srcIdx];
12694
                        cert->subjectCLen = strLen;
12695
                        cert->subjectCEnc = b;
12696
                    }
12697
                #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
12698
                    else if (nameType == ISSUER) {
12699
                        cert->issuerC = (char*)&input[srcIdx];
12700
                        cert->issuerCLen = strLen;
12701
                        cert->issuerCEnc = b;
12702
                    }
12703
                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
12704
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
12705
                #if (defined(OPENSSL_EXTRA) || \
12706
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
12707
                        && !defined(WOLFCRYPT_ONLY)
12708
                    nid = NID_countryName;
12709
                #endif /* OPENSSL_EXTRA */
12710
0
            }
12711
0
            else if (id == ASN_LOCALITY_NAME) {
12712
0
                copy = WOLFSSL_LOCALITY_NAME;
12713
0
                copyLen = sizeof(WOLFSSL_LOCALITY_NAME) - 1;
12714
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12715
                    if (nameType == SUBJECT) {
12716
                        cert->subjectL = (char*)&input[srcIdx];
12717
                        cert->subjectLLen = strLen;
12718
                        cert->subjectLEnc = b;
12719
                    }
12720
                    #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
12721
                    else if (nameType == ISSUER) {
12722
                        cert->issuerL = (char*)&input[srcIdx];
12723
                        cert->issuerLLen = strLen;
12724
                        cert->issuerLEnc = b;
12725
                    }
12726
                    #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
12727
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
12728
                #if (defined(OPENSSL_EXTRA) || \
12729
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
12730
                        && !defined(WOLFCRYPT_ONLY)
12731
                    nid = NID_localityName;
12732
                #endif /* OPENSSL_EXTRA */
12733
0
            }
12734
0
            else if (id == ASN_STATE_NAME) {
12735
0
                copy = WOLFSSL_STATE_NAME;
12736
0
                copyLen = sizeof(WOLFSSL_STATE_NAME) - 1;
12737
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12738
                    if (nameType == SUBJECT) {
12739
                        cert->subjectST = (char*)&input[srcIdx];
12740
                        cert->subjectSTLen = strLen;
12741
                        cert->subjectSTEnc = b;
12742
                    }
12743
                #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
12744
                    else if (nameType == ISSUER) {
12745
                        cert->issuerST = (char*)&input[srcIdx];
12746
                        cert->issuerSTLen = strLen;
12747
                        cert->issuerSTEnc = b;
12748
                    }
12749
                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
12750
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT*/
12751
                #if (defined(OPENSSL_EXTRA) || \
12752
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
12753
                        && !defined(WOLFCRYPT_ONLY)
12754
                    nid = NID_stateOrProvinceName;
12755
                #endif /* OPENSSL_EXTRA */
12756
0
            }
12757
0
            else if (id == ASN_ORG_NAME) {
12758
0
                copy = WOLFSSL_ORG_NAME;
12759
0
                copyLen = sizeof(WOLFSSL_ORG_NAME) - 1;
12760
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12761
                    if (nameType == SUBJECT) {
12762
                        cert->subjectO = (char*)&input[srcIdx];
12763
                        cert->subjectOLen = strLen;
12764
                        cert->subjectOEnc = b;
12765
                    }
12766
                #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
12767
                    else if (nameType == ISSUER) {
12768
                        cert->issuerO = (char*)&input[srcIdx];
12769
                        cert->issuerOLen = strLen;
12770
                        cert->issuerOEnc = b;
12771
                    }
12772
                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
12773
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
12774
                #if (defined(OPENSSL_EXTRA) || \
12775
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
12776
                        && !defined(WOLFCRYPT_ONLY)
12777
                    nid = NID_organizationName;
12778
                #endif /* OPENSSL_EXTRA */
12779
0
            }
12780
0
            else if (id == ASN_ORGUNIT_NAME) {
12781
0
                copy = WOLFSSL_ORGUNIT_NAME;
12782
0
                copyLen = sizeof(WOLFSSL_ORGUNIT_NAME) - 1;
12783
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12784
                    if (nameType == SUBJECT) {
12785
                        cert->subjectOU = (char*)&input[srcIdx];
12786
                        cert->subjectOULen = strLen;
12787
                        cert->subjectOUEnc = b;
12788
                    }
12789
                #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
12790
                    else if (nameType == ISSUER) {
12791
                        cert->issuerOU = (char*)&input[srcIdx];
12792
                        cert->issuerOULen = strLen;
12793
                        cert->issuerOUEnc = b;
12794
                    }
12795
                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
12796
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
12797
                #if (defined(OPENSSL_EXTRA) || \
12798
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
12799
                        && !defined(WOLFCRYPT_ONLY)
12800
                    nid = NID_organizationalUnitName;
12801
                #endif /* OPENSSL_EXTRA */
12802
0
            }
12803
0
            else if (id == ASN_SERIAL_NUMBER) {
12804
0
                copy = WOLFSSL_SERIAL_NUMBER;
12805
0
                copyLen = sizeof(WOLFSSL_SERIAL_NUMBER) - 1;
12806
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12807
                    if (nameType == SUBJECT) {
12808
                        cert->subjectSND = (char*)&input[srcIdx];
12809
                        cert->subjectSNDLen = strLen;
12810
                        cert->subjectSNDEnc = b;
12811
                    }
12812
                #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
12813
                    else if (nameType == ISSUER) {
12814
                        cert->issuerSND = (char*)&input[srcIdx];
12815
                        cert->issuerSNDLen = strLen;
12816
                        cert->issuerSNDEnc = b;
12817
                    }
12818
                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
12819
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
12820
                #if (defined(OPENSSL_EXTRA) || \
12821
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
12822
                        && !defined(WOLFCRYPT_ONLY)
12823
                    nid = NID_serialNumber;
12824
                #endif /* OPENSSL_EXTRA */
12825
0
            }
12826
0
            else if (id == ASN_USER_ID) {
12827
0
                copy = WOLFSSL_USER_ID;
12828
0
                copyLen = sizeof(WOLFSSL_USER_ID) - 1;
12829
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12830
                    if (nameType == SUBJECT) {
12831
                        cert->subjectUID = (char*)&input[srcIdx];
12832
                        cert->subjectUIDLen = strLen;
12833
                        cert->subjectUIDEnc = b;
12834
                    }
12835
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
12836
                #if (defined(OPENSSL_EXTRA) || \
12837
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
12838
                        && !defined(WOLFCRYPT_ONLY)
12839
                    nid = NID_userId;
12840
                #endif /* OPENSSL_EXTRA */
12841
0
            }
12842
        #ifdef WOLFSSL_CERT_EXT
12843
            else if (id == ASN_STREET_ADDR) {
12844
                copy = WOLFSSL_STREET_ADDR_NAME;
12845
                copyLen = sizeof(WOLFSSL_STREET_ADDR_NAME) - 1;
12846
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12847
                    if (nameType == SUBJECT) {
12848
                        cert->subjectStreet = (char*)&input[srcIdx];
12849
                        cert->subjectStreetLen = strLen;
12850
                        cert->subjectStreetEnc = b;
12851
                    }
12852
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
12853
                #if (defined(OPENSSL_EXTRA) || \
12854
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
12855
                        && !defined(WOLFCRYPT_ONLY)
12856
                    nid = NID_streetAddress;
12857
                #endif /* OPENSSL_EXTRA */
12858
            }
12859
            else if (id == ASN_BUS_CAT) {
12860
                copy = WOLFSSL_BUS_CAT;
12861
                copyLen = sizeof(WOLFSSL_BUS_CAT) - 1;
12862
            #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12863
                if (nameType == SUBJECT) {
12864
                    cert->subjectBC = (char*)&input[srcIdx];
12865
                    cert->subjectBCLen = strLen;
12866
                    cert->subjectBCEnc = b;
12867
                }
12868
            #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
12869
            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \
12870
                        && !defined(WOLFCRYPT_ONLY)
12871
                nid = NID_businessCategory;
12872
            #endif /* OPENSSL_EXTRA */
12873
            }
12874
            else if (id == ASN_POSTAL_CODE) {
12875
                copy = WOLFSSL_POSTAL_NAME;
12876
                copyLen = sizeof(WOLFSSL_POSTAL_NAME) - 1;
12877
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12878
                    if (nameType == SUBJECT) {
12879
                        cert->subjectPC = (char*)&input[srcIdx];
12880
                        cert->subjectPCLen = strLen;
12881
                        cert->subjectPCEnc = b;
12882
                    }
12883
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT*/
12884
                #if (defined(OPENSSL_EXTRA) || \
12885
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
12886
                        && !defined(WOLFCRYPT_ONLY)
12887
                    nid = NID_postalCode;
12888
                #endif /* OPENSSL_EXTRA */
12889
            }
12890
        #endif /* WOLFSSL_CERT_EXT */
12891
0
        }
12892
    #ifdef WOLFSSL_CERT_EXT
12893
        else if ((srcIdx + ASN_JOI_PREFIX_SZ + 2 <= (word32)maxIdx) &&
12894
                 (0 == XMEMCMP(&input[srcIdx], ASN_JOI_PREFIX,
12895
                               ASN_JOI_PREFIX_SZ)) &&
12896
                 ((input[srcIdx+ASN_JOI_PREFIX_SZ] == ASN_JOI_C) ||
12897
                  (input[srcIdx+ASN_JOI_PREFIX_SZ] == ASN_JOI_ST)))
12898
        {
12899
            srcIdx += ASN_JOI_PREFIX_SZ;
12900
            id = input[srcIdx++];
12901
            b = input[srcIdx++]; /* encoding */
12902
12903
            if (GetLength(input, &srcIdx, &strLen,
12904
                          maxIdx) < 0) {
12905
            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
12906
            !defined(WOLFCRYPT_ONLY)
12907
                wolfSSL_X509_NAME_free(dName);
12908
            #endif /* OPENSSL_EXTRA */
12909
                return ASN_PARSE_E;
12910
            }
12911
12912
            /* Check for jurisdiction of incorporation country name */
12913
            if (id == ASN_JOI_C) {
12914
                copy = WOLFSSL_JOI_C;
12915
                copyLen = sizeof(WOLFSSL_JOI_C) - 1;
12916
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12917
                    if (nameType == SUBJECT) {
12918
                        cert->subjectJC = (char*)&input[srcIdx];
12919
                        cert->subjectJCLen = strLen;
12920
                        cert->subjectJCEnc = b;
12921
                    }
12922
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
12923
                #if (defined(OPENSSL_EXTRA) || \
12924
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
12925
                        && !defined(WOLFCRYPT_ONLY)
12926
                    nid = NID_jurisdictionCountryName;
12927
                #endif /* OPENSSL_EXTRA */
12928
            }
12929
12930
            /* Check for jurisdiction of incorporation state name */
12931
            else if (id == ASN_JOI_ST) {
12932
                copy = WOLFSSL_JOI_ST;
12933
                copyLen = sizeof(WOLFSSL_JOI_ST) - 1;
12934
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12935
                    if (nameType == SUBJECT) {
12936
                        cert->subjectJS = (char*)&input[srcIdx];
12937
                        cert->subjectJSLen = strLen;
12938
                        cert->subjectJSEnc = b;
12939
                    }
12940
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
12941
                #if (defined(OPENSSL_EXTRA) || \
12942
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
12943
                        && !defined(WOLFCRYPT_ONLY)
12944
                    nid = NID_jurisdictionStateOrProvinceName;
12945
                #endif /* OPENSSL_EXTRA */
12946
            }
12947
12948
            if ((strLen + copyLen) > (int)(WC_ASN_NAME_MAX - idx)) {
12949
                WOLFSSL_MSG("ASN Name too big, skipping");
12950
                tooBig = TRUE;
12951
            }
12952
        }
12953
    #endif /* WOLFSSL_CERT_EXT */
12954
0
        else {
12955
            /* skip */
12956
0
            byte email = FALSE;
12957
0
            byte pilot = FALSE;
12958
12959
0
            if (joint[0] == 0x2a && joint[1] == 0x86) {  /* email id hdr 42.134.* */
12960
0
                id = ASN_EMAIL_NAME;
12961
0
                email = TRUE;
12962
0
            }
12963
12964
0
            if (joint[0] == 0x9  && joint[1] == 0x92) { /* uid id hdr 9.146.* */
12965
                /* last value of OID is the type of pilot attribute */
12966
0
                id    = input[srcIdx + oidSz - 1];
12967
0
                if (id == 0x01)
12968
0
                    id = ASN_USER_ID;
12969
0
                pilot = TRUE;
12970
0
            }
12971
12972
0
            srcIdx += oidSz + 1;
12973
12974
0
            if (GetLength(input, &srcIdx, &strLen, maxIdx) < 0) {
12975
            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
12976
            !defined(WOLFCRYPT_ONLY)
12977
                wolfSSL_X509_NAME_free(dName);
12978
            #endif /* OPENSSL_EXTRA */
12979
0
                return ASN_PARSE_E;
12980
0
            }
12981
12982
0
            if (strLen > (int)(WC_ASN_NAME_MAX - idx)) {
12983
0
                WOLFSSL_MSG("ASN name too big, skipping");
12984
0
                tooBig = TRUE;
12985
0
            }
12986
12987
0
            if (email) {
12988
0
                copyLen = sizeof(WOLFSSL_EMAIL_ADDR) - 1;
12989
0
                if ((copyLen + strLen) > (int)(WC_ASN_NAME_MAX - idx)) {
12990
0
                    WOLFSSL_MSG("ASN name too big, skipping");
12991
0
                    tooBig = TRUE;
12992
0
                }
12993
0
                else {
12994
0
                    copy = WOLFSSL_EMAIL_ADDR;
12995
0
                }
12996
12997
0
                #if !defined(IGNORE_NAME_CONSTRAINTS) || \
12998
0
                     defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12999
0
                    if (nameType == SUBJECT) {
13000
0
                        cert->subjectEmail = (char*)&input[srcIdx];
13001
0
                        cert->subjectEmailLen = strLen;
13002
0
                    }
13003
                #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
13004
                    else if (nameType == ISSUER) {
13005
                        cert->issuerEmail = (char*)&input[srcIdx];
13006
                        cert->issuerEmailLen = strLen;
13007
                    }
13008
                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
13009
0
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
13010
                #if (defined(OPENSSL_EXTRA) || \
13011
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
13012
                        && !defined(WOLFCRYPT_ONLY)
13013
                    nid = NID_emailAddress;
13014
                #endif /* OPENSSL_EXTRA */
13015
0
            }
13016
13017
0
            if (pilot) {
13018
0
                switch (id) {
13019
0
                    case ASN_USER_ID:
13020
0
                        copy = WOLFSSL_USER_ID;
13021
0
                        copyLen = sizeof(WOLFSSL_USER_ID) - 1;
13022
                    #if (defined(OPENSSL_EXTRA) || \
13023
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
13024
                        && !defined(WOLFCRYPT_ONLY)
13025
                        nid = NID_userId;
13026
                    #endif /* OPENSSL_EXTRA */
13027
0
                        break;
13028
13029
0
                    case ASN_DOMAIN_COMPONENT:
13030
0
                        copy = WOLFSSL_DOMAIN_COMPONENT;
13031
0
                        copyLen = sizeof(WOLFSSL_DOMAIN_COMPONENT) - 1;
13032
                    #if (defined(OPENSSL_EXTRA) || \
13033
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
13034
                        && !defined(WOLFCRYPT_ONLY)
13035
                        nid = NID_domainComponent;
13036
                    #endif /* OPENSSL_EXTRA */
13037
0
                        break;
13038
0
                    case ASN_FAVOURITE_DRINK:
13039
0
                        copy = WOLFSSL_FAVOURITE_DRINK;
13040
0
                        copyLen = sizeof(WOLFSSL_FAVOURITE_DRINK) - 1;
13041
                    #if (defined(OPENSSL_EXTRA) || \
13042
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
13043
                        && !defined(WOLFCRYPT_ONLY)
13044
                        nid = NID_favouriteDrink;
13045
                    #endif /* OPENSSL_EXTRA */
13046
0
                        break;
13047
13048
0
                    default:
13049
0
                        WOLFSSL_MSG("Unknown pilot attribute type");
13050
                    #if (defined(OPENSSL_EXTRA) || \
13051
                                defined(OPENSSL_EXTRA_X509_SMALL)) && \
13052
                                !defined(WOLFCRYPT_ONLY)
13053
                        wolfSSL_X509_NAME_free(dName);
13054
                    #endif /* OPENSSL_EXTRA */
13055
0
                        return ASN_PARSE_E;
13056
0
                }
13057
0
            }
13058
0
        }
13059
0
        if ((copyLen + strLen) > (int)(WC_ASN_NAME_MAX - idx))
13060
0
        {
13061
0
            WOLFSSL_MSG("ASN Name too big, skipping");
13062
0
            tooBig = TRUE;
13063
0
        }
13064
0
        if ((copy != NULL) && !tooBig) {
13065
0
            XMEMCPY(&full[idx], copy, copyLen);
13066
0
            idx += copyLen;
13067
0
            XMEMCPY(&full[idx], &input[srcIdx], strLen);
13068
0
            idx += strLen;
13069
0
        }
13070
        #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
13071
            !defined(WOLFCRYPT_ONLY)
13072
        switch (b) {
13073
            case CTC_UTF8:
13074
                enc = MBSTRING_UTF8;
13075
                break;
13076
            case CTC_PRINTABLE:
13077
                enc = V_ASN1_PRINTABLESTRING;
13078
                break;
13079
            default:
13080
                WOLFSSL_MSG("Unknown encoding type, using UTF8 by default");
13081
                enc = MBSTRING_UTF8;
13082
        }
13083
13084
        if (nid != NID_undef) {
13085
            if (wolfSSL_X509_NAME_add_entry_by_NID(dName, nid, enc,
13086
                            &input[srcIdx], strLen, -1, -1) !=
13087
                            WOLFSSL_SUCCESS) {
13088
                wolfSSL_X509_NAME_free(dName);
13089
                return ASN_PARSE_E;
13090
            }
13091
        }
13092
        #endif /* OPENSSL_EXTRA */
13093
0
        srcIdx += strLen;
13094
0
    }
13095
0
    full[idx++] = 0;
13096
13097
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
13098
            !defined(WOLFCRYPT_ONLY)
13099
    if (nameType == ISSUER) {
13100
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY)) && \
13101
    (defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT))
13102
        dName->rawLen = min(cert->issuerRawLen, WC_ASN_NAME_MAX);
13103
        XMEMCPY(dName->raw, cert->issuerRaw, dName->rawLen);
13104
#endif
13105
        cert->issuerName = dName;
13106
    }
13107
    else {
13108
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
13109
        dName->rawLen = min(cert->subjectRawLen, WC_ASN_NAME_MAX);
13110
        XMEMCPY(dName->raw, cert->subjectRaw, dName->rawLen);
13111
#endif
13112
        cert->subjectName = dName;
13113
    }
13114
#endif
13115
13116
0
    *inOutIdx = srcIdx;
13117
13118
0
    return 0;
13119
#else
13120
    DECL_ASNGETDATA(dataASN, rdnASN_Length);
13121
    int    ret = 0;
13122
    word32 idx = 0;
13123
    int    len;
13124
    word32 srcIdx = *inOutIdx;
13125
#ifdef WOLFSSL_X509_NAME_AVAILABLE
13126
    WOLFSSL_X509_NAME* dName = NULL;
13127
#endif /* WOLFSSL_X509_NAME_AVAILABLE */
13128
13129
    WOLFSSL_MSG("Getting Cert Name");
13130
13131
    /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
13132
     * calculated over the entire DER encoding of the Name field, including
13133
     * the tag and length. */
13134
    if (CalcHashId(input + srcIdx, maxIdx - srcIdx, hash) != 0) {
13135
        ret = ASN_PARSE_E;
13136
    }
13137
13138
    CALLOC_ASNGETDATA(dataASN, rdnASN_Length, ret, cert->heap);
13139
13140
#ifdef WOLFSSL_X509_NAME_AVAILABLE
13141
    if (ret == 0) {
13142
        /* Create an X509_NAME to hold data for OpenSSL compatability APIs. */
13143
        dName = wolfSSL_X509_NAME_new();
13144
        if (dName == NULL) {
13145
            ret = MEMORY_E;
13146
        }
13147
    }
13148
#endif /* WOLFSSL_X509_NAME_AVAILABLE */
13149
13150
    if (ret == 0) {
13151
        /* Expecting a SEQUENCE using up all data. */
13152
        ret = GetASN_Sequence(input, &srcIdx, &len, maxIdx, 1);
13153
    }
13154
    if (ret == 0) {
13155
    #if defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT)
13156
        /* Store pointer and length to raw issuer. */
13157
        if (nameType == ISSUER) {
13158
            cert->issuerRaw = &input[srcIdx];
13159
            cert->issuerRawLen = len;
13160
        }
13161
    #endif
13162
    #if !defined(IGNORE_NAME_CONSTRAINTS) || defined(WOLFSSL_CERT_EXT)
13163
        /* Store pointer and length to raw subject. */
13164
        if (nameType == SUBJECT) {
13165
            cert->subjectRaw = &input[srcIdx];
13166
            cert->subjectRawLen = len;
13167
        }
13168
    #endif
13169
13170
        /* Process all RDNs in name. */
13171
        while ((ret == 0) && (srcIdx < maxIdx)) {
13172
            int nid = 0;
13173
13174
            /* Initialize for data and setup RDN choice. */
13175
            GetASN_Choice(&dataASN[RDNASN_IDX_ATTR_VAL], rdnChoice);
13176
            /* Ignore type OID as too many to store in table. */
13177
            GetASN_OID(&dataASN[RDNASN_IDX_ATTR_TYPE], oidIgnoreType);
13178
            /* Parse RDN. */
13179
            ret = GetASN_Items(rdnASN, dataASN, rdnASN_Length, 1, input,
13180
                               &srcIdx, maxIdx);
13181
            if (ret == 0) {
13182
                /* Put RDN data into certificate. */
13183
                ret = GetRDN(cert, full, &idx, &nid, nameType == SUBJECT,
13184
                             dataASN);
13185
            }
13186
        #ifdef WOLFSSL_X509_NAME_AVAILABLE
13187
            /* TODO: push this back up to ssl.c
13188
             * (do parsing for WOLFSSL_X509_NAME on demand) */
13189
            if (ret == 0) {
13190
                int enc;
13191
                byte*  str;
13192
                word32 strLen;
13193
                byte   tag = dataASN[RDNASN_IDX_ATTR_VAL].tag;
13194
13195
                /* Get string reference. */
13196
                GetASN_GetRef(&dataASN[RDNASN_IDX_ATTR_VAL], &str, &strLen);
13197
13198
                /* Convert BER tag to a OpenSSL type. */
13199
                switch (tag) {
13200
                    case CTC_UTF8:
13201
                        enc = MBSTRING_UTF8;
13202
                        break;
13203
                    case CTC_PRINTABLE:
13204
                        enc = V_ASN1_PRINTABLESTRING;
13205
                        break;
13206
                    default:
13207
                        WOLFSSL_MSG("Unknown encoding type, default UTF8");
13208
                        enc = MBSTRING_UTF8;
13209
                }
13210
                if (nid != 0) {
13211
                    /* Add an entry to the X509_NAME. */
13212
                    if (wolfSSL_X509_NAME_add_entry_by_NID(dName, nid, enc, str,
13213
                            strLen, -1, -1) != WOLFSSL_SUCCESS) {
13214
                        ret = ASN_PARSE_E;
13215
                    }
13216
                }
13217
            }
13218
        #endif
13219
        }
13220
    }
13221
    if (ret == 0) {
13222
        /* Terminate string. */
13223
        full[idx] = 0;
13224
        /* Return index into encoding after name. */
13225
        *inOutIdx = srcIdx;
13226
13227
#ifdef WOLFSSL_X509_NAME_AVAILABLE
13228
        /* Store X509_NAME in certificate. */
13229
        if (nameType == ISSUER) {
13230
        #if (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
13231
             defined(HAVE_LIGHTY)) && \
13232
            (defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT))
13233
            dName->rawLen = min(cert->issuerRawLen, WC_ASN_NAME_MAX);
13234
            XMEMCPY(dName->raw, cert->issuerRaw, dName->rawLen);
13235
        #endif
13236
            cert->issuerName = dName;
13237
        }
13238
        else {
13239
        #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
13240
            dName->rawLen = min(cert->subjectRawLen, WC_ASN_NAME_MAX);
13241
            XMEMCPY(dName->raw, cert->subjectRaw, dName->rawLen);
13242
        #endif
13243
            cert->subjectName = dName;
13244
        }
13245
    }
13246
    else {
13247
        /* Dispose of unused X509_NAME. */
13248
        wolfSSL_X509_NAME_free(dName);
13249
#endif
13250
    }
13251
13252
    FREE_ASNGETDATA(dataASN, cert->heap);
13253
    return ret;
13254
#endif /* WOLFSSL_ASN_TEMPLATE */
13255
0
}
13256
13257
#ifdef WOLFSSL_ASN_TEMPLATE
13258
/* ASN.1 template for certificate name. */
13259
static const ASNItem certNameASN[] = {
13260
/* OID  */ { 0, ASN_OBJECT_ID, 0, 0, 1 },
13261
/* NAME */ { 0, ASN_SEQUENCE, 1, 0, 0 },
13262
};
13263
enum {
13264
    CERTNAMEASN_IDX_OID = 0,
13265
    CERTNAMEASN_IDX_NAME,
13266
};
13267
13268
/* Number of items in ASN.1 template for certificate name. */
13269
#define certNameASN_Length (sizeof(certNameASN) / sizeof(ASNItem))
13270
#endif
13271
13272
/* Get a certificate name into the certificate object.
13273
 *
13274
 * Either the issuer or subject name.
13275
 *
13276
 * @param [in, out] cert      Decoded certificate object.
13277
 * @param [in]      nameType  Type of name being decoded: ISSUER or SUBJECT.
13278
 * @param [in]      maxIdx    Index of next item after certificate name.
13279
 * @return  0 on success.
13280
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
13281
 *          is invalid.
13282
 * @return  BUFFER_E when data in buffer is too small.
13283
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
13284
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
13285
 * @return  MEMORY_E when dynamic memory allocation fails.
13286
 */
13287
int GetName(DecodedCert* cert, int nameType, int maxIdx)
13288
0
{
13289
0
#ifndef WOLFSSL_ASN_TEMPLATE
13290
0
    char*  full;
13291
0
    byte*  hash;
13292
0
    int    length;
13293
0
    word32 localIdx;
13294
0
    byte   tag;
13295
13296
0
    WOLFSSL_MSG("Getting Cert Name");
13297
13298
0
    if (nameType == ISSUER) {
13299
0
        full = cert->issuer;
13300
0
        hash = cert->issuerHash;
13301
0
    }
13302
0
    else {
13303
0
        full = cert->subject;
13304
0
        hash = cert->subjectHash;
13305
0
    }
13306
13307
0
    if (cert->srcIdx >= (word32)maxIdx) {
13308
0
        return BUFFER_E;
13309
0
    }
13310
13311
0
    localIdx = cert->srcIdx;
13312
0
    if (GetASNTag(cert->source, &localIdx, &tag, maxIdx) < 0) {
13313
0
        return ASN_PARSE_E;
13314
0
    }
13315
13316
0
    if (tag == ASN_OBJECT_ID) {
13317
0
        WOLFSSL_MSG("Trying optional prefix...");
13318
13319
0
        if (SkipObjectId(cert->source, &cert->srcIdx, maxIdx) < 0)
13320
0
            return ASN_PARSE_E;
13321
0
        WOLFSSL_MSG("Got optional prefix");
13322
0
    }
13323
13324
0
    localIdx = cert->srcIdx;
13325
0
    if (GetASNTag(cert->source, &localIdx, &tag, maxIdx) < 0) {
13326
0
        return ASN_PARSE_E;
13327
0
    }
13328
0
    localIdx = cert->srcIdx + 1;
13329
0
    if (GetLength(cert->source, &localIdx, &length, maxIdx) < 0) {
13330
0
        return ASN_PARSE_E;
13331
0
    }
13332
0
    length += localIdx - cert->srcIdx;
13333
13334
0
    return GetCertName(cert, full, hash, nameType, cert->source, &cert->srcIdx,
13335
0
                       cert->srcIdx + length);
13336
#else
13337
    ASNGetData dataASN[certNameASN_Length];
13338
    word32 idx = cert->srcIdx;
13339
    int    ret = 0;
13340
    char*  full;
13341
    byte*  hash;
13342
13343
    WOLFSSL_MSG("Getting Cert Name");
13344
13345
    XMEMSET(dataASN, 0, sizeof(dataASN));
13346
    /* Initialize for data and don't check optional prefix OID. */
13347
    GetASN_OID(&dataASN[CERTNAMEASN_IDX_OID], oidIgnoreType);
13348
    ret = GetASN_Items(certNameASN, dataASN, certNameASN_Length, 0,
13349
                       cert->source, &idx, maxIdx);
13350
    if (ret == 0) {
13351
        /* Store offset of SEQUENCE that is start of name. */
13352
        cert->srcIdx = dataASN[CERTNAMEASN_IDX_NAME].offset;
13353
13354
        /* Get fields to fill in based on name type. */
13355
        if (nameType == ISSUER) {
13356
            full = cert->issuer;
13357
            hash = cert->issuerHash;
13358
        }
13359
        else {
13360
            full = cert->subject;
13361
            hash = cert->subjectHash;
13362
        }
13363
13364
        /* Parse certificate name. */
13365
        ret = GetCertName(cert, full, hash, nameType, cert->source,
13366
                          &cert->srcIdx, idx);
13367
    }
13368
13369
    return ret;
13370
#endif
13371
0
}
13372
13373
#ifndef NO_ASN_TIME
13374
13375
/* two byte date/time, add to value */
13376
static WC_INLINE int GetTime(int* value, const byte* date, int* idx)
13377
0
{
13378
0
    int i = *idx;
13379
13380
0
    if (date[i] < 0x30 || date[i] > 0x39 || date[i+1] < 0x30 ||
13381
0
                                                             date[i+1] > 0x39) {
13382
0
        return ASN_PARSE_E;
13383
0
    }
13384
13385
0
    *value += btoi(date[i++]) * 10;
13386
0
    *value += btoi(date[i++]);
13387
13388
0
    *idx = i;
13389
13390
0
    return 0;
13391
0
}
13392
13393
#ifdef WOLFSSL_LINUXKM
13394
static WC_INLINE int GetTime_Long(long* value, const byte* date, int* idx)
13395
{
13396
    int i = *idx;
13397
13398
    if (date[i] < 0x30 || date[i] > 0x39 || date[i+1] < 0x30 ||
13399
                                                             date[i+1] > 0x39) {
13400
        return ASN_PARSE_E;
13401
    }
13402
13403
    *value += (long)btoi(date[i++]) * 10;
13404
    *value += (long)btoi(date[i++]);
13405
13406
    *idx = i;
13407
13408
    return 0;
13409
}
13410
#endif
13411
13412
int ExtractDate(const unsigned char* date, unsigned char format,
13413
                                                  struct tm* certTime, int* idx)
13414
0
{
13415
0
    XMEMSET(certTime, 0, sizeof(struct tm));
13416
13417
0
    if (format == ASN_UTC_TIME) {
13418
0
        if (btoi(date[*idx]) >= 5)
13419
0
            certTime->tm_year = 1900;
13420
0
        else
13421
0
            certTime->tm_year = 2000;
13422
0
    }
13423
0
    else  { /* format == GENERALIZED_TIME */
13424
#ifdef WOLFSSL_LINUXKM
13425
        if (GetTime_Long(&certTime->tm_year, date, idx) != 0) return 0;
13426
#else
13427
0
        if (GetTime(&certTime->tm_year, date, idx) != 0) return 0;
13428
0
#endif
13429
0
        certTime->tm_year *= 100;
13430
0
    }
13431
13432
#ifdef AVR
13433
    /* Extract the time from the struct tm and adjust tm_year, tm_mon */
13434
    /* AVR libc stores these as uint8_t instead of int */
13435
    /* AVR time_t also offsets from midnight 1 Jan 2000 */
13436
    int tm_year = certTime->tm_year - 2000;
13437
    int tm_mon  = certTime->tm_mon - 1;
13438
    int tm_mday = certTime->tm_mday;
13439
    int tm_hour = certTime->tm_hour;
13440
    int tm_min  = certTime->tm_min;
13441
    int tm_sec  = certTime->tm_sec;
13442
13443
#ifdef WOLFSSL_LINUXKM
13444
    if (GetTime_Long(&tm_year, date, idx) != 0) return 0;
13445
#else
13446
    if (GetTime(&tm_year, date, idx) != 0) return 0;
13447
#endif
13448
    if (GetTime(&tm_mon , date, idx) != 0) return 0;
13449
    if (GetTime(&tm_mday, date, idx) != 0) return 0;
13450
    if (GetTime(&tm_hour, date, idx) != 0) return 0;
13451
    if (GetTime(&tm_min , date, idx) != 0) return 0;
13452
    if (GetTime(&tm_sec , date, idx) != 0) return 0;
13453
13454
    /* Re-populate certTime with computed values */
13455
    certTime->tm_year = tm_year;
13456
    certTime->tm_mon  = tm_mon;
13457
    certTime->tm_mday = tm_mday;
13458
    certTime->tm_hour = tm_hour;
13459
    certTime->tm_min  = tm_min;
13460
    certTime->tm_sec  = tm_sec;
13461
#else
13462
    /* adjust tm_year, tm_mon */
13463
#ifdef WOLFSSL_LINUXKM
13464
    if (GetTime_Long(&certTime->tm_year, date, idx) != 0) return 0;
13465
#else
13466
0
    if (GetTime(&certTime->tm_year, date, idx) != 0) return 0;
13467
0
#endif
13468
0
    certTime->tm_year -= 1900;
13469
0
    if (GetTime(&certTime->tm_mon , date, idx) != 0) return 0;
13470
0
    certTime->tm_mon  -= 1;
13471
0
    if (GetTime(&certTime->tm_mday, date, idx) != 0) return 0;
13472
0
    if (GetTime(&certTime->tm_hour, date, idx) != 0) return 0;
13473
0
    if (GetTime(&certTime->tm_min , date, idx) != 0) return 0;
13474
0
    if (GetTime(&certTime->tm_sec , date, idx) != 0) return 0;
13475
0
#endif
13476
13477
0
    return 1;
13478
0
}
13479
13480
13481
#if defined(OPENSSL_ALL) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
13482
    defined(OPENSSL_EXTRA) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
13483
int GetTimeString(byte* date, int format, char* buf, int len)
13484
{
13485
    struct tm t;
13486
    int idx = 0;
13487
13488
    if (!ExtractDate(date, (unsigned char)format, &t, &idx)) {
13489
        return 0;
13490
    }
13491
13492
    if (date[idx] != 'Z') {
13493
        WOLFSSL_MSG("UTCtime, not Zulu") ;
13494
        return 0;
13495
    }
13496
13497
    /* place month in buffer */
13498
    buf[0] = '\0';
13499
    switch(t.tm_mon) {
13500
        case 0:  XSTRNCAT(buf, "Jan ", 5); break;
13501
        case 1:  XSTRNCAT(buf, "Feb ", 5); break;
13502
        case 2:  XSTRNCAT(buf, "Mar ", 5); break;
13503
        case 3:  XSTRNCAT(buf, "Apr ", 5); break;
13504
        case 4:  XSTRNCAT(buf, "May ", 5); break;
13505
        case 5:  XSTRNCAT(buf, "Jun ", 5); break;
13506
        case 6:  XSTRNCAT(buf, "Jul ", 5); break;
13507
        case 7:  XSTRNCAT(buf, "Aug ", 5); break;
13508
        case 8:  XSTRNCAT(buf, "Sep ", 5); break;
13509
        case 9:  XSTRNCAT(buf, "Oct ", 5); break;
13510
        case 10: XSTRNCAT(buf, "Nov ", 5); break;
13511
        case 11: XSTRNCAT(buf, "Dec ", 5); break;
13512
        default:
13513
            return 0;
13514
13515
    }
13516
    idx = 4; /* use idx now for char buffer */
13517
13518
    if (XSNPRINTF(buf + idx, len - idx, "%2d %02d:%02d:%02d %d GMT",
13519
              t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, (int)t.tm_year + 1900)
13520
        >= len - idx)
13521
    {
13522
        WOLFSSL_MSG("buffer overrun in GetTimeString");
13523
        return 0;
13524
    }
13525
13526
    return 1;
13527
}
13528
#endif /* OPENSSL_ALL || WOLFSSL_MYSQL_COMPATIBLE || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
13529
13530
13531
#if !defined(NO_ASN_TIME) && !defined(USER_TIME) && \
13532
    !defined(TIME_OVERRIDES) && (defined(OPENSSL_EXTRA) || defined(HAVE_PKCS7))
13533
/* Set current time string, either UTC or GeneralizedTime.
13534
 * (void*) tm should be a pointer to time_t, output is placed in buf.
13535
 *
13536
 * Return time string length placed in buf on success, negative on error */
13537
int GetAsnTimeString(void* currTime, byte* buf, word32 len)
13538
{
13539
    byte* data_ptr  = buf;
13540
    byte  uf_time[ASN_GENERALIZED_TIME_SIZE];
13541
    word32 data_len = 0;
13542
13543
    WOLFSSL_ENTER("GetAsnTimeString");
13544
13545
    if (buf == NULL || len == 0)
13546
        return BAD_FUNC_ARG;
13547
13548
    XMEMSET(uf_time, 0, sizeof(uf_time));
13549
    /* GetFormattedTime returns length with null terminator */
13550
    data_len = GetFormattedTime(currTime, uf_time, len);
13551
    if (data_len <= 0) {
13552
        return ASN_TIME_E;
13553
    }
13554
    /* ensure room to add 2 bytes (ASN type and length) before proceeding */
13555
    else if (len < data_len + 2) {
13556
        return BUFFER_E;
13557
    }
13558
13559
    if (data_len == ASN_UTC_TIME_SIZE-1) {
13560
        /* increment data_len for ASN length byte after adding the data_ptr */
13561
        *data_ptr = (byte)ASN_UTC_TIME; data_ptr++; data_len++;
13562
        /* -1 below excludes null terminator */
13563
        *data_ptr = (byte)ASN_UTC_TIME_SIZE - 1; data_ptr++; data_len++;
13564
        XMEMCPY(data_ptr, (byte *)uf_time, ASN_UTC_TIME_SIZE - 1);
13565
        *data_ptr += ASN_UTC_TIME_SIZE - 1;
13566
    }
13567
    else if (data_len == ASN_GENERALIZED_TIME_SIZE-1) {
13568
        /* increment data_len for ASN length byte after adding the data_ptr */
13569
        *data_ptr = (byte)ASN_GENERALIZED_TIME; data_ptr++; data_len++;
13570
        /* -1 below excludes null terminator */
13571
        *data_ptr = (byte)ASN_GENERALIZED_TIME_SIZE - 1; data_ptr++; data_len++;
13572
        XMEMCPY(data_ptr, (byte*)uf_time, ASN_GENERALIZED_TIME_SIZE - 1);
13573
        *data_ptr += ASN_GENERALIZED_TIME_SIZE - 1;
13574
    }
13575
    else {
13576
        WOLFSSL_MSG("Invalid time size returned");
13577
        return ASN_TIME_E;
13578
    }
13579
    /* append null terminator */
13580
    *data_ptr = 0;
13581
13582
    /* return length without null terminator */
13583
    return data_len;
13584
}
13585
13586
/* return just the time string as either UTC or Generalized Time*/
13587
int GetFormattedTime(void* currTime, byte* buf, word32 len)
13588
{
13589
    struct tm* ts      = NULL;
13590
    struct tm* tmpTime = NULL;
13591
    int year, mon, day, hour, mini, sec;
13592
    int ret;
13593
#if defined(NEED_TMP_TIME)
13594
    struct tm tmpTimeStorage;
13595
    tmpTime = &tmpTimeStorage;
13596
#else
13597
    (void)tmpTime;
13598
#endif
13599
13600
    WOLFSSL_ENTER("GetFormattedTime");
13601
13602
    if (buf == NULL || len == 0)
13603
        return BAD_FUNC_ARG;
13604
13605
    ts = (struct tm *)XGMTIME((time_t*)currTime, tmpTime);
13606
    if (ts == NULL) {
13607
        WOLFSSL_MSG("failed to get time data.");
13608
        return ASN_TIME_E;
13609
    }
13610
13611
    /* Note ASN_UTC_TIME_SIZE and ASN_GENERALIZED_TIME_SIZE include space for
13612
     * the null terminator. ASN encoded values leave off the terminator. */
13613
13614
    if (ts->tm_year >= 50 && ts->tm_year < 150) {
13615
        /* UTC Time */
13616
        if (ts->tm_year >= 50 && ts->tm_year < 100) {
13617
            year = ts->tm_year;
13618
        }
13619
        else if (ts->tm_year >= 100 && ts->tm_year < 150) {
13620
            year = ts->tm_year - 100;
13621
        }
13622
        else {
13623
            WOLFSSL_MSG("unsupported year range");
13624
            return BAD_FUNC_ARG;
13625
        }
13626
        mon  = ts->tm_mon + 1;
13627
        day  = ts->tm_mday;
13628
        hour = ts->tm_hour;
13629
        mini = ts->tm_min;
13630
        sec  = ts->tm_sec;
13631
        #if defined(WOLF_C89)
13632
            if (len < 14) {
13633
                WOLFSSL_MSG("buffer for GetFormattedTime is too short.");
13634
                return BUFFER_E;
13635
            }
13636
            ret = XSPRINTF((char*)buf,
13637
        #else
13638
            ret = XSNPRINTF((char*)buf, len,
13639
        #endif
13640
                        "%02d%02d%02d%02d%02d%02dZ", year, mon, day,
13641
                        hour, mini, sec);
13642
    }
13643
    else {
13644
        /* GeneralizedTime */
13645
        year = ts->tm_year + 1900;
13646
        mon  = ts->tm_mon + 1;
13647
        day  = ts->tm_mday;
13648
        hour = ts->tm_hour;
13649
        mini = ts->tm_min;
13650
        sec  = ts->tm_sec;
13651
        #if defined(WOLF_C89)
13652
            if (len < 16) {
13653
                WOLFSSL_MSG("buffer for GetFormattedTime is too short.");
13654
                return BUFFER_E;
13655
            }
13656
            ret = XSPRINTF((char*)buf,
13657
        #else
13658
            ret = XSNPRINTF((char*)buf, len,
13659
        #endif
13660
                        "%4d%02d%02d%02d%02d%02dZ", year, mon, day,
13661
                        hour, mini, sec);
13662
    }
13663
13664
    return ret;
13665
}
13666
13667
#endif /* !NO_ASN_TIME && !USER_TIME && !TIME_OVERRIDES &&
13668
        * (OPENSSL_EXTRA || HAVE_PKCS7) */
13669
13670
#if defined(USE_WOLF_VALIDDATE)
13671
13672
/* to the second */
13673
int DateGreaterThan(const struct tm* a, const struct tm* b)
13674
0
{
13675
0
    if (a->tm_year > b->tm_year)
13676
0
        return 1;
13677
13678
0
    if (a->tm_year == b->tm_year && a->tm_mon > b->tm_mon)
13679
0
        return 1;
13680
13681
0
    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
13682
0
           a->tm_mday > b->tm_mday)
13683
0
        return 1;
13684
13685
0
    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
13686
0
        a->tm_mday == b->tm_mday && a->tm_hour > b->tm_hour)
13687
0
        return 1;
13688
13689
0
    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
13690
0
        a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
13691
0
        a->tm_min > b->tm_min)
13692
0
        return 1;
13693
13694
0
    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
13695
0
        a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
13696
0
        a->tm_min  == b->tm_min  && a->tm_sec > b->tm_sec)
13697
0
        return 1;
13698
13699
0
    return 0; /* false */
13700
0
}
13701
13702
13703
static WC_INLINE int DateLessThan(const struct tm* a, const struct tm* b)
13704
0
{
13705
0
    return DateGreaterThan(b,a);
13706
0
}
13707
13708
/* like atoi but only use first byte */
13709
/* Make sure before and after dates are valid */
13710
int wc_ValidateDate(const byte* date, byte format, int dateType)
13711
0
{
13712
0
    time_t ltime;
13713
0
    struct tm  certTime;
13714
0
    struct tm* localTime;
13715
0
    struct tm* tmpTime;
13716
0
    int    i = 0;
13717
0
    int    timeDiff = 0 ;
13718
0
    int    diffHH = 0 ; int diffMM = 0 ;
13719
0
    int    diffSign = 0 ;
13720
13721
0
#if defined(NEED_TMP_TIME)
13722
0
    struct tm tmpTimeStorage;
13723
0
    tmpTime = &tmpTimeStorage;
13724
#else
13725
    tmpTime = NULL;
13726
#endif
13727
0
    (void)tmpTime;
13728
13729
0
    ltime = wc_Time(0);
13730
13731
#ifdef WOLFSSL_BEFORE_DATE_CLOCK_SKEW
13732
    if (dateType == BEFORE) {
13733
        WOLFSSL_MSG("Skewing local time for before date check");
13734
        ltime += WOLFSSL_BEFORE_DATE_CLOCK_SKEW;
13735
    }
13736
#endif
13737
13738
#ifdef WOLFSSL_AFTER_DATE_CLOCK_SKEW
13739
    if (dateType == AFTER) {
13740
        WOLFSSL_MSG("Skewing local time for after date check");
13741
        ltime -= WOLFSSL_AFTER_DATE_CLOCK_SKEW;
13742
    }
13743
#endif
13744
13745
0
    if (!ExtractDate(date, format, &certTime, &i)) {
13746
0
        WOLFSSL_MSG("Error extracting the date");
13747
0
        return 0;
13748
0
    }
13749
13750
0
    if ((date[i] == '+') || (date[i] == '-')) {
13751
0
        WOLFSSL_MSG("Using time differential, not Zulu") ;
13752
0
        diffSign = date[i++] == '+' ? 1 : -1 ;
13753
0
        if (GetTime(&diffHH, date, &i) != 0)
13754
0
            return 0;
13755
0
        if (GetTime(&diffMM, date, &i) != 0)
13756
0
            return 0;
13757
0
        timeDiff = diffSign * (diffHH*60 + diffMM) * 60 ;
13758
0
    } else if (date[i] != 'Z') {
13759
0
        WOLFSSL_MSG("UTCtime, neither Zulu or time differential") ;
13760
0
        return 0;
13761
0
    }
13762
13763
0
    ltime -= (time_t)timeDiff ;
13764
0
    localTime = XGMTIME(&ltime, tmpTime);
13765
13766
0
    if (localTime == NULL) {
13767
0
        WOLFSSL_MSG("XGMTIME failed");
13768
0
        return 0;
13769
0
    }
13770
13771
0
    if (dateType == BEFORE) {
13772
0
        if (DateLessThan(localTime, &certTime)) {
13773
0
            WOLFSSL_MSG("Date BEFORE check failed");
13774
0
            return 0;
13775
0
        }
13776
0
    }
13777
0
    else {  /* dateType == AFTER */
13778
0
        if (DateGreaterThan(localTime, &certTime)) {
13779
0
            WOLFSSL_MSG("Date AFTER check failed");
13780
0
            return 0;
13781
0
        }
13782
0
    }
13783
13784
0
    return 1;
13785
0
}
13786
#endif /* USE_WOLF_VALIDDATE */
13787
13788
int wc_GetTime(void* timePtr, word32 timeSize)
13789
0
{
13790
0
    time_t* ltime = (time_t*)timePtr;
13791
13792
0
    if (timePtr == NULL) {
13793
0
        return BAD_FUNC_ARG;
13794
0
    }
13795
13796
0
    if ((word32)sizeof(time_t) > timeSize) {
13797
0
        return BUFFER_E;
13798
0
    }
13799
13800
0
    *ltime = wc_Time(0);
13801
13802
0
    return 0;
13803
0
}
13804
13805
#ifdef TIME_OVERRIDES
13806
    #ifndef HAVE_TIME_T_TYPE
13807
        typedef long time_t;
13808
    #endif
13809
    extern time_t XTIME(time_t* t);
13810
#endif
13811
13812
static wc_time_cb timeFunc = NULL;
13813
13814
int wc_SetTimeCb(wc_time_cb f)
13815
0
{
13816
0
    timeFunc = f;
13817
0
    return 0;
13818
0
}
13819
13820
time_t wc_Time(time_t* t)
13821
0
{
13822
0
    if (timeFunc != NULL) {
13823
0
        return timeFunc(t);
13824
0
    }
13825
0
    return XTIME(t);
13826
0
}
13827
13828
#endif /* !NO_ASN_TIME */
13829
13830
13831
#ifdef WOLFSSL_ASN_TEMPLATE
13832
/* TODO: use a CHOICE instead of two items? */
13833
/* ASN.1 template for a date - either UTC or Generalized Time. */
13834
static const ASNItem dateASN[] = {
13835
/* UTC */ { 0, ASN_UTC_TIME, 0, 0, 2 },
13836
/* GT  */ { 0, ASN_GENERALIZED_TIME, 0, 0, 2 },
13837
};
13838
enum {
13839
    DATEASN_IDX_UTC = 0,
13840
    DATEASN_IDX_GT,
13841
};
13842
13843
/* Number of items in ASN.1 template for a date. */
13844
#define dateASN_Length (sizeof(dateASN) / sizeof(ASNItem))
13845
#endif /* WOLFSSL_ASN_TEMPLATE */
13846
13847
/* Get date buffer, format and length. Returns 0=success or error */
13848
/* Decode a DateInfo - choice of UTC TIME or GENERALIZED TIME.
13849
 *
13850
 * @param [in]      source   Buffer containing encoded date.
13851
 * @param [in, out] idx      On in, the index of the date.
13852
 *                           On out, index after date.
13853
 * @param [out]     pDate    Pointer into buffer of data bytes.
13854
 * @param [out]     pFormat  Format of date - BER/DER tag.
13855
 * @param [out]     pLength  Length of date bytes.
13856
 * @param [in]      maxIdx   Index of next item after date.
13857
 * @return  0 on success.
13858
 * @return  BAD_FUNC_ARG when source or idx is NULL.
13859
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
13860
 *          is invalid.
13861
 * @return  BUFFER_E when data in buffer is too small.
13862
 */
13863
static int GetDateInfo(const byte* source, word32* idx, const byte** pDate,
13864
                        byte* pFormat, int* pLength, word32 maxIdx)
13865
0
{
13866
0
#ifndef WOLFSSL_ASN_TEMPLATE
13867
0
    int length;
13868
0
    byte format;
13869
13870
0
    if (source == NULL || idx == NULL)
13871
0
        return BAD_FUNC_ARG;
13872
13873
    /* get ASN format header */
13874
0
    if (*idx+1 > maxIdx)
13875
0
        return BUFFER_E;
13876
0
    format = source[*idx];
13877
0
    *idx += 1;
13878
0
    if (format != ASN_UTC_TIME && format != ASN_GENERALIZED_TIME) {
13879
0
        WOLFSSL_ERROR_VERBOSE(ASN_TIME_E);
13880
0
        return ASN_TIME_E;
13881
0
    }
13882
13883
    /* get length */
13884
0
    if (GetLength(source, idx, &length, maxIdx) < 0)
13885
0
        return ASN_PARSE_E;
13886
0
    if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
13887
0
        return ASN_DATE_SZ_E;
13888
13889
    /* return format, date and length */
13890
0
    if (pFormat)
13891
0
        *pFormat = format;
13892
0
    if (pDate)
13893
0
        *pDate = &source[*idx];
13894
0
    if (pLength)
13895
0
        *pLength = length;
13896
13897
0
    *idx += length;
13898
13899
0
    return 0;
13900
#else
13901
    ASNGetData dataASN[dateASN_Length];
13902
    int i;
13903
    int ret = 0;
13904
13905
    if ((source == NULL) || (idx == NULL)) {
13906
        ret = BAD_FUNC_ARG;
13907
    }
13908
    if (ret == 0) {
13909
        /* Initialize data. */
13910
        XMEMSET(dataASN, 0, sizeof(dataASN));
13911
        /* Parse date. */
13912
        ret = GetASN_Items(dateASN, dataASN, dateASN_Length, 0, source, idx,
13913
                           maxIdx);
13914
    }
13915
    if (ret == 0) {
13916
        /* Determine which tag was seen. */
13917
        i = (dataASN[DATEASN_IDX_UTC].tag != 0) ? DATEASN_IDX_UTC
13918
                                                : DATEASN_IDX_GT;
13919
        /* Return data from seen item. */
13920
        if (pFormat != NULL) {
13921
            *pFormat = dataASN[i].tag;
13922
        }
13923
        if (pDate != NULL) {
13924
            *pDate = dataASN[i].data.ref.data;
13925
        }
13926
        if (pLength != NULL) {
13927
            *pLength = dataASN[i].data.ref.length;
13928
        }
13929
    }
13930
13931
    return ret;
13932
#endif
13933
0
}
13934
13935
#ifndef WOLFSSL_ASN_TEMPLATE
13936
static int GetDate(DecodedCert* cert, int dateType, int verify, int maxIdx)
13937
0
{
13938
0
    int    ret, length;
13939
0
    const byte *datePtr = NULL;
13940
0
    byte   date[MAX_DATE_SIZE];
13941
0
    byte   format;
13942
0
    word32 startIdx = 0;
13943
13944
0
    if (dateType == BEFORE)
13945
0
        cert->beforeDate = &cert->source[cert->srcIdx];
13946
0
    else
13947
0
        cert->afterDate = &cert->source[cert->srcIdx];
13948
0
    startIdx = cert->srcIdx;
13949
13950
0
    ret = GetDateInfo(cert->source, &cert->srcIdx, &datePtr, &format,
13951
0
                      &length, maxIdx);
13952
0
    if (ret < 0)
13953
0
        return ret;
13954
13955
0
    XMEMSET(date, 0, MAX_DATE_SIZE);
13956
0
    XMEMCPY(date, datePtr, length);
13957
13958
0
    if (dateType == BEFORE)
13959
0
        cert->beforeDateLen = cert->srcIdx - startIdx;
13960
0
    else
13961
0
        cert->afterDateLen  = cert->srcIdx - startIdx;
13962
13963
0
#ifndef NO_ASN_TIME
13964
0
    if (verify != NO_VERIFY && verify != VERIFY_SKIP_DATE &&
13965
0
            !XVALIDATE_DATE(date, format, dateType)) {
13966
0
        if (dateType == BEFORE) {
13967
0
            WOLFSSL_ERROR_VERBOSE(ASN_BEFORE_DATE_E);
13968
0
            return ASN_BEFORE_DATE_E;
13969
0
        }
13970
0
        else {
13971
0
            WOLFSSL_ERROR_VERBOSE(ASN_AFTER_DATE_E);
13972
0
            return ASN_AFTER_DATE_E;
13973
0
        }
13974
0
    }
13975
#else
13976
    (void)verify;
13977
#endif
13978
13979
0
    return 0;
13980
0
}
13981
13982
static int GetValidity(DecodedCert* cert, int verify, int maxIdx)
13983
0
{
13984
0
    int length;
13985
0
    int badDate = 0;
13986
13987
0
    if (GetSequence(cert->source, &cert->srcIdx, &length, maxIdx) < 0)
13988
0
        return ASN_PARSE_E;
13989
13990
0
    maxIdx = cert->srcIdx + length;
13991
13992
0
    if (GetDate(cert, BEFORE, verify, maxIdx) < 0)
13993
0
        badDate = ASN_BEFORE_DATE_E; /* continue parsing */
13994
13995
0
    if (GetDate(cert, AFTER, verify, maxIdx) < 0)
13996
0
        return ASN_AFTER_DATE_E;
13997
13998
0
    if (badDate != 0)
13999
0
        return badDate;
14000
14001
0
    return 0;
14002
0
}
14003
#endif /* !WOLFSSL_ASN_TEMPLATE */
14004
14005
14006
int wc_GetDateInfo(const byte* certDate, int certDateSz, const byte** date,
14007
    byte* format, int* length)
14008
0
{
14009
0
    int ret;
14010
0
    word32 idx = 0;
14011
14012
0
    ret = GetDateInfo(certDate, &idx, date, format, length, certDateSz);
14013
14014
0
    return ret;
14015
0
}
14016
14017
#ifndef NO_ASN_TIME
14018
int wc_GetDateAsCalendarTime(const byte* date, int length, byte format,
14019
    struct tm* timearg)
14020
0
{
14021
0
    int idx = 0;
14022
0
    (void)length;
14023
0
    if (!ExtractDate(date, format, timearg, &idx))
14024
0
        return ASN_TIME_E;
14025
0
    return 0;
14026
0
}
14027
14028
#if defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_ALT_NAMES)
14029
int wc_GetCertDates(Cert* cert, struct tm* before, struct tm* after)
14030
{
14031
    int ret = 0;
14032
    const byte* date;
14033
    byte format;
14034
    int length;
14035
14036
    if (cert == NULL)
14037
        return BAD_FUNC_ARG;
14038
14039
    if (before && cert->beforeDateSz > 0) {
14040
        ret = wc_GetDateInfo(cert->beforeDate, cert->beforeDateSz, &date,
14041
                             &format, &length);
14042
        if (ret == 0)
14043
            ret = wc_GetDateAsCalendarTime(date, length, format, before);
14044
    }
14045
    if (after && cert->afterDateSz > 0) {
14046
        ret = wc_GetDateInfo(cert->afterDate, cert->afterDateSz, &date,
14047
                             &format, &length);
14048
        if (ret == 0)
14049
            ret = wc_GetDateAsCalendarTime(date, length, format, after);
14050
    }
14051
14052
    return ret;
14053
}
14054
#endif /* WOLFSSL_CERT_GEN && WOLFSSL_ALT_NAMES */
14055
#endif /* !NO_ASN_TIME */
14056
14057
#ifndef WOLFSSL_ASN_TEMPLATE
14058
static int GetSigAlg(DecodedCert* cert, word32* sigOid, word32 maxIdx)
14059
0
{
14060
0
    int length;
14061
0
    word32 endSeqIdx;
14062
14063
0
    if (GetSequence(cert->source, &cert->srcIdx, &length, maxIdx) < 0)
14064
0
        return ASN_PARSE_E;
14065
0
    endSeqIdx = cert->srcIdx + length;
14066
14067
0
    if (GetObjectId(cert->source, &cert->srcIdx, sigOid, oidSigType,
14068
0
                    maxIdx) < 0) {
14069
0
        return ASN_OBJECT_ID_E;
14070
0
    }
14071
14072
0
    if (cert->srcIdx != endSeqIdx) {
14073
0
#ifdef WC_RSA_PSS
14074
0
        if (*sigOid == CTC_RSASSAPSS) {
14075
0
            cert->sigParamsIndex = cert->srcIdx;
14076
0
            cert->sigParamsLength = endSeqIdx - cert->srcIdx;
14077
0
        }
14078
0
        else
14079
0
#endif
14080
        /* Only allowed a ASN NULL header with zero length. */
14081
0
        if  (endSeqIdx - cert->srcIdx != 2)
14082
0
            return ASN_PARSE_E;
14083
0
        else {
14084
0
            byte tag;
14085
0
            if (GetASNTag(cert->source, &cert->srcIdx, &tag, endSeqIdx) != 0)
14086
0
                return ASN_PARSE_E;
14087
0
            if (tag != ASN_TAG_NULL)
14088
0
                return ASN_PARSE_E;
14089
0
        }
14090
0
    }
14091
14092
0
    cert->srcIdx = endSeqIdx;
14093
14094
0
    return 0;
14095
0
}
14096
#endif
14097
14098
#ifdef WOLFSSL_ASN_TEMPLATE
14099
/* TODO: move code around to not require this. */
14100
static int DecodeCertInternal(DecodedCert* cert, int verify, int* criticalExt,
14101
                              int* badDateRet, int stopAtPubKey,
14102
                              int stopAfterPubKey);
14103
#endif
14104
14105
/* Parse the certificate up to the X.509 public key.
14106
 *
14107
 * If cert data is invalid then badDate get set to error value.
14108
 *
14109
 * @param [in, out] cert     Decoded certificate object.
14110
 * @param [in]      verify   Whether to verify dates.
14111
 * @param [out]     badDate  Error code when verify dates.
14112
 * @return  0 on success.
14113
 * @return  BAD_FUNC_ARG when cert or badDate is NULL.
14114
 * @return  ASN_TIME_E when date BER tag is nor UTC or GENERALIZED time.
14115
 * @return  ASN_DATE_SZ_E when time data is not supported.
14116
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
14117
 *          is invalid.
14118
 * @return  BUFFER_E when data in buffer is too small.
14119
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
14120
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set.
14121
 */
14122
int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate)
14123
0
{
14124
0
#ifndef WOLFSSL_ASN_TEMPLATE
14125
0
    int ret;
14126
14127
0
    if (cert == NULL || badDate == NULL)
14128
0
        return BAD_FUNC_ARG;
14129
14130
0
    *badDate = 0;
14131
0
    if ( (ret = GetCertHeader(cert)) < 0)
14132
0
        return ret;
14133
14134
0
    WOLFSSL_MSG("Got Cert Header");
14135
14136
#ifdef WOLFSSL_CERT_REQ
14137
    if (!cert->isCSR) {
14138
#endif
14139
        /* Using the sigIndex as the upper bound because that's where the
14140
         * actual certificate data ends. */
14141
0
        if ((ret = GetSigAlg(cert, &cert->signatureOID, cert->sigIndex)) < 0)
14142
0
            return ret;
14143
14144
0
        WOLFSSL_MSG("Got Algo ID");
14145
14146
0
        if ( (ret = GetName(cert, ISSUER, cert->sigIndex)) < 0)
14147
0
            return ret;
14148
14149
0
        if ( (ret = GetValidity(cert, verify, cert->sigIndex)) < 0)
14150
0
            *badDate = ret;
14151
#ifdef WOLFSSL_CERT_REQ
14152
    }
14153
#endif
14154
14155
0
    if ( (ret = GetName(cert, SUBJECT, cert->sigIndex)) < 0)
14156
0
        return ret;
14157
14158
0
    WOLFSSL_MSG("Got Subject Name");
14159
0
    return ret;
14160
#else
14161
    /* Use common decode routine and stop at public key. */
14162
    int ret;
14163
14164
    *badDate = 0;
14165
14166
    ret = DecodeCertInternal(cert, verify, NULL, badDate, 1, 0);
14167
    if (ret >= 0) {
14168
        /* Store current index: public key. */
14169
        cert->srcIdx = ret;
14170
    }
14171
    return ret;
14172
#endif /* WOLFSSL_ASN_TEMPLATE */
14173
0
}
14174
14175
/* Parse the certificate up to and including X.509 public key.
14176
 *
14177
 * @param [in, out] cert     Decoded certificate object.
14178
 * @param [in]      verify   Whether to verify dates.
14179
 * @return  0 on success.
14180
 * @return  ASN_TIME_E when date BER tag is nor UTC or GENERALIZED time.
14181
 * @return  ASN_DATE_SZ_E when time data is not supported.
14182
 * @return  ASN_BEFORE_DATE_E when BEFORE date is invalid.
14183
 * @return  ASN_AFTER_DATE_E when AFTER date is invalid.
14184
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
14185
 *          is invalid.
14186
 * @return  BUFFER_E when data in buffer is too small.
14187
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
14188
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
14189
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set.
14190
 */
14191
int DecodeToKey(DecodedCert* cert, int verify)
14192
0
{
14193
0
#ifndef WOLFSSL_ASN_TEMPLATE
14194
0
    int badDate = 0;
14195
0
    int ret;
14196
14197
0
    if ( (ret = wc_GetPubX509(cert, verify, &badDate)) < 0)
14198
0
        return ret;
14199
14200
    /* Determine if self signed */
14201
#ifdef WOLFSSL_CERT_REQ
14202
    if (cert->isCSR)
14203
        cert->selfSigned = 1;
14204
    else
14205
#endif
14206
0
    {
14207
0
        cert->selfSigned = XMEMCMP(cert->issuerHash,
14208
0
                                   cert->subjectHash,
14209
0
                                   KEYID_SIZE) == 0 ? 1 : 0;
14210
0
    }
14211
14212
0
    ret = GetCertKey(cert, cert->source, &cert->srcIdx, cert->maxIdx);
14213
0
    if (ret != 0)
14214
0
        return ret;
14215
14216
0
    WOLFSSL_MSG("Got Key");
14217
14218
0
    if (badDate != 0)
14219
0
        return badDate;
14220
14221
0
    return ret;
14222
#else
14223
    int ret;
14224
    int badDate = 0;
14225
14226
    /* Call internal version and stop after public key. */
14227
    ret = DecodeCertInternal(cert, verify, NULL, &badDate, 0, 1);
14228
    /* Always return date errors. */
14229
    if (ret == 0) {
14230
        ret = badDate;
14231
    }
14232
    return ret;
14233
#endif /* WOLFSSL_ASN_TEMPLATE */
14234
0
}
14235
14236
#if !defined(NO_CERTS) && !defined(WOLFSSL_ASN_TEMPLATE)
14237
static int GetSignature(DecodedCert* cert)
14238
0
{
14239
0
    int length;
14240
0
    int ret;
14241
14242
0
    ret = CheckBitString(cert->source, &cert->srcIdx, &length, cert->maxIdx, 1,
14243
0
                         NULL);
14244
0
    if (ret != 0)
14245
0
        return ret;
14246
14247
0
    cert->sigLength = length;
14248
0
    cert->signature = &cert->source[cert->srcIdx];
14249
0
    cert->srcIdx += cert->sigLength;
14250
14251
0
    if (cert->srcIdx != cert->maxIdx)
14252
0
        return ASN_PARSE_E;
14253
14254
0
    return 0;
14255
0
}
14256
#endif /* !NO_CERTS && !WOLFSSL_ASN_TEMPLATE */
14257
14258
#ifndef WOLFSSL_ASN_TEMPLATE
14259
static word32 SetOctetString8Bit(word32 len, byte* output)
14260
0
{
14261
0
    output[0] = ASN_OCTET_STRING;
14262
0
    output[1] = (byte)len;
14263
0
    return 2;
14264
0
}
14265
static word32 SetDigest(const byte* digest, word32 digSz, byte* output)
14266
0
{
14267
0
    word32 idx = SetOctetString8Bit(digSz, output);
14268
0
    XMEMCPY(&output[idx], digest, digSz);
14269
14270
0
    return idx + digSz;
14271
0
}
14272
#endif
14273
14274
14275
/* Encode a length for DER.
14276
 *
14277
 * @param [in]  length  Value to encode.
14278
 * @param [out] output  Buffer to encode into.
14279
 * @return  Number of bytes encoded.
14280
 */
14281
word32 SetLength(word32 length, byte* output)
14282
7.64k
{
14283
    /* Start encoding at start of buffer. */
14284
7.64k
    word32 i = 0;
14285
14286
7.64k
    if (length < ASN_LONG_LENGTH) {
14287
        /* Only one byte needed to encode. */
14288
6.81k
        if (output) {
14289
            /* Write out length value. */
14290
6.81k
            output[i] = (byte)length;
14291
6.81k
        }
14292
        /* Skip over length. */
14293
6.81k
        i++;
14294
6.81k
    }
14295
829
    else {
14296
        /* Calculate the number of bytes required to encode value. */
14297
829
        byte j = (byte)BytePrecision(length);
14298
14299
829
        if (output) {
14300
            /* Encode count byte. */
14301
829
            output[i] = j | ASN_LONG_LENGTH;
14302
829
        }
14303
        /* Skip over count byte. */
14304
829
        i++;
14305
14306
        /* Encode value as a big-endian byte array. */
14307
1.65k
        for (; j > 0; --j) {
14308
829
            if (output) {
14309
                /* Encode next most-significant byte. */
14310
829
                output[i] = (byte)(length >> ((j - 1) * WOLFSSL_BIT_SIZE));
14311
829
            }
14312
            /* Skip over byte. */
14313
829
            i++;
14314
829
        }
14315
829
    }
14316
14317
    /* Return number of bytes in encoded length. */
14318
7.64k
    return i;
14319
7.64k
}
14320
14321
/* Encode a DER header - type/tag and length.
14322
 *
14323
 * @param [in]  tag     DER tag of ASN.1 item.
14324
 * @param [in]  len     Length of data in ASN.1 item.
14325
 * @param [out] output  Buffer to encode into.
14326
 * @return  Number of bytes encoded.
14327
 */
14328
static word32 SetHeader(byte tag, word32 len, byte* output)
14329
2.54k
{
14330
2.54k
    if (output) {
14331
        /* Encode tag first. */
14332
2.54k
        output[0] = tag;
14333
2.54k
    }
14334
    /* Encode the length. */
14335
2.54k
    return SetLength(len, output ? output + ASN_TAG_SZ : NULL) + ASN_TAG_SZ;
14336
2.54k
}
14337
14338
/* Encode a SEQUENCE header in DER.
14339
 *
14340
 * @param [in]  len     Length of data in SEQUENCE.
14341
 * @param [out] output  Buffer to encode into.
14342
 * @return  Number of bytes encoded.
14343
 */
14344
word32 SetSequence(word32 len, byte* output)
14345
2.54k
{
14346
2.54k
    return SetHeader(ASN_SEQUENCE | ASN_CONSTRUCTED, len, output);
14347
2.54k
}
14348
14349
/* Encode an OCTET STRING header in DER.
14350
 *
14351
 * @param [in]  len     Length of data in OCTET STRING.
14352
 * @param [out] output  Buffer to encode into.
14353
 * @return  Number of bytes encoded.
14354
 */
14355
word32 SetOctetString(word32 len, byte* output)
14356
0
{
14357
0
    return SetHeader(ASN_OCTET_STRING, len, output);
14358
0
}
14359
14360
/* Encode a SET header in DER.
14361
 *
14362
 * @param [in]  len     Length of data in SET.
14363
 * @param [out] output  Buffer to encode into.
14364
 * @return  Number of bytes encoded.
14365
 */
14366
word32 SetSet(word32 len, byte* output)
14367
0
{
14368
0
    return SetHeader(ASN_SET | ASN_CONSTRUCTED, len, output);
14369
0
}
14370
14371
/* Encode an implicit context specific header in DER.
14372
 *
14373
 * Implicit means that it is constructed only if the included ASN.1 item is.
14374
 *
14375
 * @param [in]  tag     Tag for the implicit ASN.1 item.
14376
 * @param [in]  number  Context specific number.
14377
 * @param [in]  len     Length of data in SET.
14378
 * @param [out] output  Buffer to encode into.
14379
 * @return  Number of bytes encoded.
14380
 */
14381
word32 SetImplicit(byte tag, byte number, word32 len, byte* output)
14382
0
{
14383
0
    tag = ((tag == ASN_SEQUENCE || tag == ASN_SET) ? ASN_CONSTRUCTED : 0)
14384
0
                    | ASN_CONTEXT_SPECIFIC | number;
14385
0
    return SetHeader(tag, len, output);
14386
0
}
14387
14388
/* Encode an explicit context specific header in DER.
14389
 *
14390
 * Explicit means that there will be an ASN.1 item underneath.
14391
 *
14392
 * @param [in]  number  Context specific number.
14393
 * @param [in]  len     Length of data in SET.
14394
 * @param [out] output  Buffer to encode into.
14395
 * @return  Number of bytes encoded.
14396
 */
14397
word32 SetExplicit(byte number, word32 len, byte* output)
14398
0
{
14399
0
    return SetHeader(ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | number, len,
14400
0
                     output);
14401
0
}
14402
14403
14404
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
14405
14406
static int SetCurve(ecc_key* key, byte* output, size_t outSz)
14407
0
{
14408
#ifdef HAVE_OID_ENCODING
14409
    int ret;
14410
#endif
14411
0
    int idx;
14412
0
    word32 oidSz = 0;
14413
14414
    /* validate key */
14415
0
    if (key == NULL || key->dp == NULL) {
14416
0
        return BAD_FUNC_ARG;
14417
0
    }
14418
14419
#ifdef HAVE_OID_ENCODING
14420
    ret = EncodeObjectId(key->dp->oid, key->dp->oidSz, NULL, &oidSz);
14421
    if (ret != 0) {
14422
        return ret;
14423
    }
14424
#else
14425
0
    oidSz = key->dp->oidSz;
14426
0
#endif
14427
14428
0
    idx = SetObjectId(oidSz, output);
14429
14430
    /* length only */
14431
0
    if (output == NULL) {
14432
0
        return idx + oidSz;
14433
0
    }
14434
14435
    /* verify output buffer has room */
14436
0
    if (oidSz > outSz)
14437
0
        return BUFFER_E;
14438
14439
#ifdef HAVE_OID_ENCODING
14440
    ret = EncodeObjectId(key->dp->oid, key->dp->oidSz, output+idx, &oidSz);
14441
    if (ret != 0) {
14442
        return ret;
14443
    }
14444
#else
14445
0
    XMEMCPY(output+idx, key->dp->oid, oidSz);
14446
0
#endif
14447
0
    idx += oidSz;
14448
14449
0
    return idx;
14450
0
}
14451
14452
#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */
14453
14454
14455
#ifdef HAVE_ECC
14456
/* Determines whether the signature algorithm is using ECDSA.
14457
 *
14458
 * @param [in] algoOID  Signature algorithm identifier.
14459
 * @return  1 when algorithm is using ECDSA.
14460
 * @return  0 otherwise.
14461
 */
14462
static WC_INLINE int IsSigAlgoECDSA(int algoOID)
14463
0
{
14464
    /* ECDSA sigAlgo must not have ASN1 NULL parameters */
14465
0
    if (algoOID == CTC_SHAwECDSA || algoOID == CTC_SHA256wECDSA ||
14466
0
        algoOID == CTC_SHA384wECDSA || algoOID == CTC_SHA512wECDSA) {
14467
0
        return 1;
14468
0
    }
14469
14470
0
    return 0;
14471
0
}
14472
#endif
14473
14474
/* Determines if OID is for an EC signing algorithm including ECDSA and EdDSA
14475
 * and post-quantum algorithms.
14476
 *
14477
 * @param [in] algoOID  Algorithm OID.
14478
 * @return  1 when is EC signing algorithm.
14479
 * @return  0 otherwise.
14480
 */
14481
static WC_INLINE int IsSigAlgoECC(int algoOID)
14482
0
{
14483
0
    (void)algoOID;
14484
14485
0
    return (0
14486
0
        #ifdef HAVE_ECC
14487
0
              || IsSigAlgoECDSA(algoOID)
14488
0
        #endif
14489
0
        #ifdef HAVE_ED25519
14490
0
              || (algoOID == ED25519k)
14491
0
        #endif
14492
0
        #ifdef HAVE_CURVE25519
14493
0
              || (algoOID == X25519k)
14494
0
        #endif
14495
0
        #ifdef HAVE_ED448
14496
0
              || (algoOID == ED448k)
14497
0
        #endif
14498
0
        #ifdef HAVE_CURVE448
14499
0
              || (algoOID == X448k)
14500
0
        #endif
14501
        #ifdef HAVE_PQC
14502
        #ifdef HAVE_FACON
14503
              || (algoOID == FALCON_LEVEL1k)
14504
              || (algoOID == FALCON_LEVEL5k)
14505
        #endif
14506
        #ifdef HAVE_DILITHIUM
14507
              || (algoOID == DILITHIUM_LEVEL2k)
14508
              || (algoOID == DILITHIUM_LEVEL3k)
14509
              || (algoOID == DILITHIUM_LEVEL5k)
14510
              || (algoOID == DILITHIUM_AES_LEVEL2k)
14511
              || (algoOID == DILITHIUM_AES_LEVEL3k)
14512
              || (algoOID == DILITHIUM_AES_LEVEL5k)
14513
        #endif
14514
        #endif /* HAVE_PQC */
14515
0
    );
14516
0
}
14517
14518
/* Encode an algorithm identifier.
14519
 *
14520
 * [algoOID, type] is unique.
14521
 *
14522
 * @param [in]  algoOID   Algorithm identifier.
14523
 * @param [out] output    Buffer to hold encoding.
14524
 * @param [in]  type      Type of OID being encoded.
14525
 * @param [in]  curveSz   Add extra space for curve data.
14526
 * @return  Encoded data size on success.
14527
 * @return  0 when dynamic memory allocation fails.
14528
 */
14529
word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz)
14530
0
{
14531
0
#ifndef WOLFSSL_ASN_TEMPLATE
14532
0
    word32 tagSz, idSz, seqSz, algoSz = 0;
14533
0
    const  byte* algoName = 0;
14534
0
    byte   ID_Length[1 + MAX_LENGTH_SZ];
14535
0
    byte   seqArray[MAX_SEQ_SZ + 1];  /* add object_id to end */
14536
0
    int    length = 0;
14537
14538
0
    tagSz = (type == oidHashType ||
14539
0
             (type == oidSigType && !IsSigAlgoECC(algoOID)) ||
14540
0
             (type == oidKeyType && algoOID == RSAk)) ? 2 : 0;
14541
14542
0
    algoName = OidFromId(algoOID, type, &algoSz);
14543
0
    if (algoName == NULL) {
14544
0
        WOLFSSL_MSG("Unknown Algorithm");
14545
0
        return 0;
14546
0
    }
14547
14548
0
    idSz  = SetObjectId(algoSz, ID_Length);
14549
0
    seqSz = SetSequence(idSz + algoSz + tagSz + curveSz, seqArray);
14550
14551
    /* Copy only algo to output for DSA keys */
14552
0
    if (algoOID == DSAk && output) {
14553
0
        XMEMCPY(output, ID_Length, idSz);
14554
0
        XMEMCPY(output + idSz, algoName, algoSz);
14555
0
        if (tagSz == 2)
14556
0
            SetASNNull(&output[seqSz + idSz + algoSz]);
14557
0
    }
14558
0
    else if (output) {
14559
0
        XMEMCPY(output, seqArray, seqSz);
14560
0
        XMEMCPY(output + seqSz, ID_Length, idSz);
14561
0
        XMEMCPY(output + seqSz + idSz, algoName, algoSz);
14562
0
        if (tagSz == 2)
14563
0
            SetASNNull(&output[seqSz + idSz + algoSz]);
14564
0
    }
14565
14566
0
    if (algoOID == DSAk)
14567
0
        length = idSz + algoSz + tagSz;
14568
0
    else
14569
0
        length = seqSz + idSz + algoSz + tagSz;
14570
14571
0
    return length;
14572
#else
14573
    DECL_ASNSETDATA(dataASN, algoIdASN_Length);
14574
    int sz;
14575
    int ret = 0;
14576
    int o = 0;
14577
14578
    CALLOC_ASNSETDATA(dataASN, algoIdASN_Length, ret, NULL);
14579
14580
    /* Set the OID and OID type to encode. */
14581
    SetASN_OID(&dataASN[ALGOIDASN_IDX_OID], algoOID, type);
14582
    /* Hashes, signatures not ECC and keys not RSA put put NULL tag. */
14583
    if (!(type == oidHashType ||
14584
             (type == oidSigType && !IsSigAlgoECC(algoOID)) ||
14585
             (type == oidKeyType && algoOID == RSAk))) {
14586
        /* Don't put out NULL DER item. */
14587
        dataASN[ALGOIDASN_IDX_NULL].noOut = 1;
14588
    }
14589
    if (algoOID == DSAk) {
14590
        /* Don't include SEQUENCE for DSA keys. */
14591
        o = 1;
14592
    }
14593
    else if (curveSz > 0) {
14594
        /* Don't put out NULL DER item. */
14595
        dataASN[ALGOIDASN_IDX_NULL].noOut = 0;
14596
        /* Include space for extra data of length curveSz.
14597
         * Subtract 1 for sequence and 1 for length encoding. */
14598
        SetASN_Buffer(&dataASN[ALGOIDASN_IDX_NULL], NULL, curveSz - 2);
14599
    }
14600
14601
    /* Calculate size of encoding. */
14602
    ret = SizeASN_Items(algoIdASN + o, dataASN + o, algoIdASN_Length - o, &sz);
14603
    if (ret == 0 && output != NULL) {
14604
        /* Encode into buffer. */
14605
        SetASN_Items(algoIdASN + o, dataASN + o, algoIdASN_Length - o, output);
14606
        if (curveSz > 0) {
14607
            /* Return size excluding curve data. */
14608
            sz = dataASN[o].offset - dataASN[ALGOIDASN_IDX_NULL].offset;
14609
        }
14610
    }
14611
14612
    if (ret == 0) {
14613
        /* Return encoded size. */
14614
        ret = sz;
14615
    }
14616
    else {
14617
        /* Unsigned return type so 0 indicates error. */
14618
        ret = 0;
14619
    }
14620
14621
    FREE_ASNSETDATA(dataASN, NULL);
14622
    return ret;
14623
#endif /* WOLFSSL_ASN_TEMPLATE */
14624
0
}
14625
14626
#ifdef WOLFSSL_ASN_TEMPLATE
14627
/* Always encode PKCS#1 v1.5 RSA signature and compare to encoded data. */
14628
/* ASN.1 template for DigestInfo for a PKCS#1 v1.5 RSA signature.
14629
 * PKCS#1 v2.2: RFC 8017, A.2.4 - DigestInfo
14630
 */
14631
static const ASNItem digestInfoASN[] = {
14632
/* SEQ          */ { 0, ASN_SEQUENCE, 1, 1, 0 },
14633
                                         /* digestAlgorithm */
14634
/* DIGALGO_SEQ  */     { 1, ASN_SEQUENCE, 1, 1, 0 },
14635
/* DIGALGO_OID  */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
14636
/* DIGALGO_NULL */         { 2, ASN_TAG_NULL, 0, 0, 0 },
14637
                                         /* digest */
14638
/* DIGEST       */     { 1, ASN_OCTET_STRING, 0, 0, 0 }
14639
};
14640
enum {
14641
    DIGESTINFOASN_IDX_SEQ = 0,
14642
    DIGESTINFOASN_IDX_DIGALGO_SEQ,
14643
    DIGESTINFOASN_IDX_DIGALGO_OID,
14644
    DIGESTINFOASN_IDX_DIGALGO_NULL,
14645
    DIGESTINFOASN_IDX_DIGEST,
14646
};
14647
14648
/* Number of items in ASN.1 template for DigestInfo for RSA. */
14649
#define digestInfoASN_Length (sizeof(digestInfoASN) / sizeof(ASNItem))
14650
#endif
14651
14652
/* Encode signature.
14653
 *
14654
 * @param [out] out     Buffer to hold encoding.
14655
 * @param [in]  digest  Buffer holding digest.
14656
 * @param [in]  digSz   Length of digest in bytes.
14657
 * @return  Encoded data size on success.
14658
 * @return  0 when dynamic memory allocation fails.
14659
 */
14660
word32 wc_EncodeSignature(byte* out, const byte* digest, word32 digSz,
14661
                          int hashOID)
14662
0
{
14663
0
#ifndef WOLFSSL_ASN_TEMPLATE
14664
0
    byte digArray[MAX_ENCODED_DIG_SZ];
14665
0
    byte algoArray[MAX_ALGO_SZ];
14666
0
    byte seqArray[MAX_SEQ_SZ];
14667
0
    word32 encDigSz, algoSz, seqSz;
14668
14669
0
    encDigSz = SetDigest(digest, digSz, digArray);
14670
0
    algoSz   = SetAlgoID(hashOID, algoArray, oidHashType, 0);
14671
0
    seqSz    = SetSequence(encDigSz + algoSz, seqArray);
14672
14673
0
    XMEMCPY(out, seqArray, seqSz);
14674
0
    XMEMCPY(out + seqSz, algoArray, algoSz);
14675
0
    XMEMCPY(out + seqSz + algoSz, digArray, encDigSz);
14676
14677
0
    return encDigSz + algoSz + seqSz;
14678
#else
14679
    DECL_ASNSETDATA(dataASN, digestInfoASN_Length);
14680
    int ret = 0;
14681
    int sz;
14682
14683
    CALLOC_ASNSETDATA(dataASN, digestInfoASN_Length, ret, NULL);
14684
14685
    if (ret == 0) {
14686
        /* Set hash OID and type. */
14687
        SetASN_OID(&dataASN[DIGESTINFOASN_IDX_DIGALGO_OID], hashOID, oidHashType);
14688
        /* Set digest. */
14689
        SetASN_Buffer(&dataASN[DIGESTINFOASN_IDX_DIGEST], digest, digSz);
14690
14691
        /* Calculate size of encoding. */
14692
        ret = SizeASN_Items(digestInfoASN, dataASN, digestInfoASN_Length, &sz);
14693
    }
14694
    if (ret == 0) {
14695
        /* Encode PKCS#1 v1.5 RSA signature. */
14696
        SetASN_Items(digestInfoASN, dataASN, digestInfoASN_Length, out);
14697
        ret = sz;
14698
    }
14699
    else {
14700
        /* Unsigned return type so 0 indicates error. */
14701
        ret = 0;
14702
    }
14703
14704
    FREE_ASNSETDATA(dataASN, NULL);
14705
    return ret;
14706
#endif
14707
0
}
14708
14709
14710
#ifndef NO_CERTS
14711
14712
int wc_GetCTC_HashOID(int type)
14713
0
{
14714
0
    int ret;
14715
0
    enum wc_HashType hType;
14716
14717
0
    hType = wc_HashTypeConvert(type);
14718
0
    ret = wc_HashGetOID(hType);
14719
0
    if (ret < 0) {
14720
0
        ret = 0; /* backwards compatibility */
14721
0
    }
14722
14723
0
    return ret;
14724
0
}
14725
14726
/* Initialize a signature context object.
14727
 *
14728
 * Object used for signing and verifying a certificate signature.
14729
 *
14730
 * @param [in, out] sigCtx  Signature context object.
14731
 * @param [in]      heap    Dynamic memory hint.
14732
 * @param [in]      devId   Hardware device identifier.
14733
 */
14734
void InitSignatureCtx(SignatureCtx* sigCtx, void* heap, int devId)
14735
0
{
14736
0
    if (sigCtx) {
14737
0
        XMEMSET(sigCtx, 0, sizeof(SignatureCtx));
14738
0
        sigCtx->devId = devId;
14739
0
        sigCtx->heap = heap;
14740
0
    }
14741
0
}
14742
14743
/* Free dynamic data in a signature context object.
14744
 *
14745
 * @param [in, out] sigCtx  Signature context object.
14746
 */
14747
void FreeSignatureCtx(SignatureCtx* sigCtx)
14748
0
{
14749
0
    if (sigCtx == NULL)
14750
0
        return;
14751
14752
0
    if (sigCtx->digest) {
14753
0
        XFREE(sigCtx->digest, sigCtx->heap, DYNAMIC_TYPE_DIGEST);
14754
0
        sigCtx->digest = NULL;
14755
0
    }
14756
0
#if !(defined(NO_RSA) && defined(NO_DSA))
14757
0
    if (sigCtx->sigCpy) {
14758
0
        XFREE(sigCtx->sigCpy, sigCtx->heap, DYNAMIC_TYPE_SIGNATURE);
14759
0
        sigCtx->sigCpy = NULL;
14760
0
    }
14761
0
#endif
14762
0
#ifndef NO_ASN_CRYPT
14763
0
    if (sigCtx->key.ptr) {
14764
0
        switch (sigCtx->keyOID) {
14765
0
        #ifndef NO_RSA
14766
0
            #ifdef WC_RSA_PSS
14767
0
            case RSAPSSk:
14768
0
            #endif
14769
0
            case RSAk:
14770
0
                wc_FreeRsaKey(sigCtx->key.rsa);
14771
0
                XFREE(sigCtx->key.rsa, sigCtx->heap, DYNAMIC_TYPE_RSA);
14772
0
                sigCtx->key.rsa = NULL;
14773
0
                break;
14774
0
        #endif /* !NO_RSA */
14775
        #ifndef NO_DSA
14776
            case DSAk:
14777
                wc_FreeDsaKey(sigCtx->key.dsa);
14778
                XFREE(sigCtx->key.dsa, sigCtx->heap, DYNAMIC_TYPE_DSA);
14779
                sigCtx->key.dsa = NULL;
14780
                break;
14781
        #endif
14782
0
        #ifdef HAVE_ECC
14783
0
            case ECDSAk:
14784
0
                wc_ecc_free(sigCtx->key.ecc);
14785
0
                XFREE(sigCtx->key.ecc, sigCtx->heap, DYNAMIC_TYPE_ECC);
14786
0
                sigCtx->key.ecc = NULL;
14787
0
                break;
14788
0
        #endif /* HAVE_ECC */
14789
0
        #ifdef HAVE_ED25519
14790
0
            case ED25519k:
14791
0
                wc_ed25519_free(sigCtx->key.ed25519);
14792
0
                XFREE(sigCtx->key.ed25519, sigCtx->heap, DYNAMIC_TYPE_ED25519);
14793
0
                sigCtx->key.ed25519 = NULL;
14794
0
                break;
14795
0
        #endif /* HAVE_ED25519 */
14796
0
        #ifdef HAVE_ED448
14797
0
            case ED448k:
14798
0
                wc_ed448_free(sigCtx->key.ed448);
14799
0
                XFREE(sigCtx->key.ed448, sigCtx->heap, DYNAMIC_TYPE_ED448);
14800
0
                sigCtx->key.ed448 = NULL;
14801
0
                break;
14802
0
        #endif /* HAVE_ED448 */
14803
        #if defined(HAVE_PQC)
14804
        #if defined(HAVE_FALCON)
14805
            case FALCON_LEVEL1k:
14806
            case FALCON_LEVEL5k:
14807
                wc_falcon_free(sigCtx->key.falcon);
14808
                XFREE(sigCtx->key.falcon, sigCtx->heap,
14809
                      DYNAMIC_TYPE_FALCON);
14810
                sigCtx->key.falcon = NULL;
14811
                break;
14812
        #endif /* HAVE_FALCON */
14813
        #if defined(HAVE_DILITHIUM)
14814
            case DILITHIUM_LEVEL2k:
14815
            case DILITHIUM_LEVEL3k:
14816
            case DILITHIUM_LEVEL5k:
14817
            case DILITHIUM_AES_LEVEL2k:
14818
            case DILITHIUM_AES_LEVEL3k:
14819
            case DILITHIUM_AES_LEVEL5k:
14820
                wc_dilithium_free(sigCtx->key.dilithium);
14821
                XFREE(sigCtx->key.dilithium, sigCtx->heap,
14822
                      DYNAMIC_TYPE_DILITHIUM);
14823
                sigCtx->key.dilithium = NULL;
14824
                break;
14825
        #endif /* HAVE_DILITHIUM */
14826
        #endif /* HAVE_PQC  */
14827
0
            default:
14828
0
                break;
14829
0
        } /* switch (keyOID) */
14830
0
        sigCtx->key.ptr = NULL;
14831
0
    }
14832
0
#endif
14833
14834
    /* reset state, we are done */
14835
0
    sigCtx->state = SIG_STATE_BEGIN;
14836
0
}
14837
14838
#ifndef NO_ASN_CRYPT
14839
static int HashForSignature(const byte* buf, word32 bufSz, word32 sigOID,
14840
                            byte* digest, int* typeH, int* digestSz, int verify)
14841
0
{
14842
0
    int ret = 0;
14843
14844
0
    switch (sigOID) {
14845
0
    #if defined(WOLFSSL_MD2)
14846
0
        case CTC_MD2wRSA:
14847
0
            if (!verify) {
14848
0
                ret = HASH_TYPE_E;
14849
0
                WOLFSSL_MSG("MD2 not supported for signing");
14850
0
            }
14851
0
            else if ((ret = wc_Md2Hash(buf, bufSz, digest)) == 0) {
14852
0
                *typeH    = MD2h;
14853
0
                *digestSz = MD2_DIGEST_SIZE;
14854
0
            }
14855
0
        break;
14856
0
    #endif
14857
0
    #ifndef NO_MD5
14858
0
        case CTC_MD5wRSA:
14859
0
            if ((ret = wc_Md5Hash(buf, bufSz, digest)) == 0) {
14860
0
                *typeH    = MD5h;
14861
0
                *digestSz = WC_MD5_DIGEST_SIZE;
14862
0
            }
14863
0
            break;
14864
0
    #endif
14865
0
    #ifndef NO_SHA
14866
0
        case CTC_SHAwRSA:
14867
0
        case CTC_SHAwDSA:
14868
0
        case CTC_SHAwECDSA:
14869
0
            if ((ret = wc_ShaHash(buf, bufSz, digest)) == 0) {
14870
0
                *typeH    = SHAh;
14871
0
                *digestSz = WC_SHA_DIGEST_SIZE;
14872
0
            }
14873
0
            break;
14874
0
    #endif
14875
0
    #ifdef WOLFSSL_SHA224
14876
0
        case CTC_SHA224wRSA:
14877
0
        case CTC_SHA224wECDSA:
14878
0
            if ((ret = wc_Sha224Hash(buf, bufSz, digest)) == 0) {
14879
0
                *typeH    = SHA224h;
14880
0
                *digestSz = WC_SHA224_DIGEST_SIZE;
14881
0
            }
14882
0
            break;
14883
0
    #endif
14884
0
    #ifndef NO_SHA256
14885
0
        case CTC_SHA256wRSA:
14886
0
        case CTC_SHA256wECDSA:
14887
0
        case CTC_SHA256wDSA:
14888
0
            if ((ret = wc_Sha256Hash(buf, bufSz, digest)) == 0) {
14889
0
                *typeH    = SHA256h;
14890
0
                *digestSz = WC_SHA256_DIGEST_SIZE;
14891
0
            }
14892
0
            break;
14893
0
    #endif
14894
0
    #ifdef WOLFSSL_SHA384
14895
0
        case CTC_SHA384wRSA:
14896
0
        case CTC_SHA384wECDSA:
14897
0
            if ((ret = wc_Sha384Hash(buf, bufSz, digest)) == 0) {
14898
0
                *typeH    = SHA384h;
14899
0
                *digestSz = WC_SHA384_DIGEST_SIZE;
14900
0
            }
14901
0
            break;
14902
0
    #endif
14903
0
    #ifdef WOLFSSL_SHA512
14904
0
        case CTC_SHA512wRSA:
14905
0
        case CTC_SHA512wECDSA:
14906
0
            if ((ret = wc_Sha512Hash(buf, bufSz, digest)) == 0) {
14907
0
                *typeH    = SHA512h;
14908
0
                *digestSz = WC_SHA512_DIGEST_SIZE;
14909
0
            }
14910
0
            break;
14911
0
    #endif
14912
0
    #ifdef WOLFSSL_SHA3
14913
0
    #ifndef WOLFSSL_NOSHA3_224
14914
0
        case CTC_SHA3_224wRSA:
14915
0
        case CTC_SHA3_224wECDSA:
14916
0
            if ((ret = wc_Sha3_224Hash(buf, bufSz, digest)) == 0) {
14917
0
                *typeH    = SHA3_224h;
14918
0
                *digestSz = WC_SHA3_224_DIGEST_SIZE;
14919
0
            }
14920
0
            break;
14921
0
    #endif
14922
0
    #ifndef WOLFSSL_NOSHA3_256
14923
0
        case CTC_SHA3_256wRSA:
14924
0
        case CTC_SHA3_256wECDSA:
14925
0
            if ((ret = wc_Sha3_256Hash(buf, bufSz, digest)) == 0) {
14926
0
                *typeH    = SHA3_256h;
14927
0
                *digestSz = WC_SHA3_256_DIGEST_SIZE;
14928
0
            }
14929
0
            break;
14930
0
    #endif
14931
0
    #ifndef WOLFSSL_NOSHA3_384
14932
0
        case CTC_SHA3_384wRSA:
14933
0
        case CTC_SHA3_384wECDSA:
14934
0
            if ((ret = wc_Sha3_384Hash(buf, bufSz, digest)) == 0) {
14935
0
                *typeH    = SHA3_384h;
14936
0
                *digestSz = WC_SHA3_384_DIGEST_SIZE;
14937
0
            }
14938
0
            break;
14939
0
    #endif
14940
0
    #ifndef WOLFSSL_NOSHA3_512
14941
0
        case CTC_SHA3_512wRSA:
14942
0
        case CTC_SHA3_512wECDSA:
14943
0
            if ((ret = wc_Sha3_512Hash(buf, bufSz, digest)) == 0) {
14944
0
                *typeH    = SHA3_512h;
14945
0
                *digestSz = WC_SHA3_512_DIGEST_SIZE;
14946
0
            }
14947
0
            break;
14948
0
    #endif
14949
0
    #endif
14950
0
    #ifdef HAVE_ED25519
14951
0
        case CTC_ED25519:
14952
            /* Hashes done in signing operation.
14953
             * Two dependent hashes with prefixes performed.
14954
             */
14955
0
            break;
14956
0
    #endif
14957
0
    #ifdef HAVE_ED448
14958
0
        case CTC_ED448:
14959
            /* Hashes done in signing operation.
14960
             * Two dependent hashes with prefixes performed.
14961
             */
14962
0
            break;
14963
0
    #endif
14964
    #ifdef HAVE_PQC
14965
    #ifdef HAVE_FALCON
14966
        case CTC_FALCON_LEVEL1:
14967
        case CTC_FALCON_LEVEL5:
14968
            /* Hashes done in signing operation. */
14969
            break;
14970
    #endif
14971
    #ifdef HAVE_DILITHIUM
14972
        case CTC_DILITHIUM_LEVEL2:
14973
        case CTC_DILITHIUM_LEVEL3:
14974
        case CTC_DILITHIUM_LEVEL5:
14975
        case CTC_DILITHIUM_AES_LEVEL2:
14976
        case CTC_DILITHIUM_AES_LEVEL3:
14977
        case CTC_DILITHIUM_AES_LEVEL5:
14978
            /* Hashes done in signing operation. */
14979
            break;
14980
    #endif
14981
    #endif /* HAVE_PQC */
14982
14983
0
        default:
14984
0
            ret = HASH_TYPE_E;
14985
0
            WOLFSSL_MSG("Hash for Signature has unsupported type");
14986
0
    }
14987
14988
0
    (void)buf;
14989
0
    (void)bufSz;
14990
0
    (void)sigOID;
14991
0
    (void)digest;
14992
0
    (void)digestSz;
14993
0
    (void)typeH;
14994
0
    (void)verify;
14995
14996
0
    return ret;
14997
0
}
14998
#endif /* !NO_ASN_CRYPT */
14999
15000
/* Return codes: 0=Success, Negative (see error-crypt.h), ASN_SIG_CONFIRM_E */
15001
static int ConfirmSignature(SignatureCtx* sigCtx,
15002
    const byte* buf, word32 bufSz,
15003
    const byte* key, word32 keySz, word32 keyOID,
15004
    const byte* sig, word32 sigSz, word32 sigOID,
15005
    const byte* sigParams, word32 sigParamsSz,
15006
    byte* rsaKeyIdx)
15007
0
{
15008
0
    int ret = 0;
15009
15010
0
    if (sigCtx == NULL || buf == NULL || bufSz == 0 || key == NULL ||
15011
0
        keySz == 0 || sig == NULL || sigSz == 0) {
15012
0
        return BAD_FUNC_ARG;
15013
0
    }
15014
15015
0
    (void)key;
15016
0
    (void)keySz;
15017
0
    (void)sig;
15018
0
    (void)sigSz;
15019
0
    (void)sigParams;
15020
0
    (void)sigParamsSz;
15021
15022
0
    WOLFSSL_ENTER("ConfirmSignature");
15023
15024
0
#if !defined(WOLFSSL_RENESAS_TSIP_TLS) && !defined(WOLFSSL_RENESAS_SCEPROTECT)
15025
0
    (void)rsaKeyIdx;
15026
#else
15027
    CertAttribute* certatt = NULL;
15028
15029
    #if !defined(NO_RSA) || defined(HAVE_ECC)
15030
    certatt = (CertAttribute*)&sigCtx->CertAtt;
15031
    #endif
15032
    if(certatt) {
15033
        certatt->keyIndex = rsaKeyIdx;
15034
        certatt->cert = buf;
15035
        certatt->certSz = bufSz;
15036
    }
15037
#endif
15038
15039
0
#ifndef NO_ASN_CRYPT
15040
0
    switch (sigCtx->state) {
15041
0
        case SIG_STATE_BEGIN:
15042
0
        {
15043
0
            sigCtx->keyOID = keyOID; /* must set early for cleanup */
15044
15045
0
            sigCtx->digest = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, sigCtx->heap,
15046
0
                                                    DYNAMIC_TYPE_DIGEST);
15047
0
            if (sigCtx->digest == NULL) {
15048
0
                ERROR_OUT(MEMORY_E, exit_cs);
15049
0
            }
15050
15051
0
        #if !defined(NO_RSA) && defined(WC_RSA_PSS)
15052
            /* RSA PSS Defaults */
15053
0
            sigCtx->hash = WC_HASH_TYPE_SHA;
15054
0
            sigCtx->mgf = WC_MGF1SHA1;
15055
0
            sigCtx->saltLen = 20;
15056
0
        #endif
15057
15058
0
            sigCtx->state = SIG_STATE_HASH;
15059
0
        } /* SIG_STATE_BEGIN */
15060
0
        FALL_THROUGH;
15061
15062
0
        case SIG_STATE_HASH:
15063
0
        {
15064
0
        #if !defined(NO_RSA) && defined(WC_RSA_PSS)
15065
0
            if (keyOID == RSAPSSk) {
15066
0
                word32 fakeSigOID = 0;
15067
0
                ret = DecodeRsaPssParams(sigParams, sigParamsSz, &sigCtx->hash,
15068
0
                    &sigCtx->mgf, &sigCtx->saltLen);
15069
0
                if (ret != 0) {
15070
0
                    goto exit_cs;
15071
0
                }
15072
0
                ret = RsaPssHashOidToSigOid(sigCtx->hash, &fakeSigOID);
15073
0
                if (ret != 0) {
15074
0
                    goto exit_cs;
15075
0
                }
15076
                /* Decode parameters. */
15077
0
                ret = HashForSignature(buf, bufSz, fakeSigOID, sigCtx->digest,
15078
0
                    &sigCtx->typeH, &sigCtx->digestSz, 1);
15079
0
                if (ret != 0) {
15080
0
                    goto exit_cs;
15081
0
                }
15082
0
            }
15083
0
            else
15084
0
        #endif
15085
0
            {
15086
0
                ret = HashForSignature(buf, bufSz, sigOID, sigCtx->digest,
15087
0
                                       &sigCtx->typeH, &sigCtx->digestSz, 1);
15088
0
                if (ret != 0) {
15089
0
                    goto exit_cs;
15090
0
                }
15091
0
            }
15092
15093
0
            sigCtx->state = SIG_STATE_KEY;
15094
0
        } /* SIG_STATE_HASH */
15095
0
        FALL_THROUGH;
15096
15097
0
        case SIG_STATE_KEY:
15098
0
        {
15099
0
            switch (keyOID) {
15100
0
            #ifndef NO_RSA
15101
0
                #ifdef WC_RSA_PSS
15102
0
                case RSAPSSk:
15103
0
                #endif
15104
0
                case RSAk:
15105
0
                {
15106
0
                    word32 idx = 0;
15107
15108
0
                    sigCtx->key.rsa = (RsaKey*)XMALLOC(sizeof(RsaKey),
15109
0
                                                sigCtx->heap, DYNAMIC_TYPE_RSA);
15110
0
                    sigCtx->sigCpy = (byte*)XMALLOC(sigSz, sigCtx->heap,
15111
0
                                                        DYNAMIC_TYPE_SIGNATURE);
15112
0
                    if (sigCtx->key.rsa == NULL || sigCtx->sigCpy == NULL) {
15113
0
                        ERROR_OUT(MEMORY_E, exit_cs);
15114
0
                    }
15115
0
                    if ((ret = wc_InitRsaKey_ex(sigCtx->key.rsa, sigCtx->heap,
15116
0
                                                        sigCtx->devId)) != 0) {
15117
0
                        goto exit_cs;
15118
0
                    }
15119
0
                    if (sigSz > MAX_ENCODED_SIG_SZ) {
15120
0
                        WOLFSSL_MSG("Verify Signature is too big");
15121
0
                        ERROR_OUT(BUFFER_E, exit_cs);
15122
0
                    }
15123
0
                    if ((ret = wc_RsaPublicKeyDecode(key, &idx, sigCtx->key.rsa,
15124
0
                                                                 keySz)) != 0) {
15125
0
                        WOLFSSL_MSG("ASN Key decode error RSA");
15126
0
                        WOLFSSL_ERROR_VERBOSE(ret);
15127
0
                        goto exit_cs;
15128
0
                    }
15129
0
                    XMEMCPY(sigCtx->sigCpy, sig, sigSz);
15130
0
                    sigCtx->out = NULL;
15131
15132
                #ifdef WOLFSSL_ASYNC_CRYPT
15133
                    sigCtx->asyncDev = &sigCtx->key.rsa->asyncDev;
15134
                #endif
15135
0
                    break;
15136
0
                }
15137
0
            #endif /* !NO_RSA */
15138
            #if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
15139
                case DSAk:
15140
                {
15141
                    word32 idx = 0;
15142
15143
                    if (sigSz < DSA_MIN_SIG_SIZE) {
15144
                        WOLFSSL_MSG("Verify Signature is too small");
15145
                        ERROR_OUT(BUFFER_E, exit_cs);
15146
                    }
15147
                    sigCtx->key.dsa = (DsaKey*)XMALLOC(sizeof(DsaKey),
15148
                                                sigCtx->heap, DYNAMIC_TYPE_DSA);
15149
                    sigCtx->sigCpy = (byte*)XMALLOC(sigSz,
15150
                                         sigCtx->heap, DYNAMIC_TYPE_SIGNATURE);
15151
                    if (sigCtx->key.dsa == NULL || sigCtx->sigCpy == NULL) {
15152
                        ERROR_OUT(MEMORY_E, exit_cs);
15153
                    }
15154
                    if ((ret = wc_InitDsaKey_h(sigCtx->key.dsa, sigCtx->heap)) != 0) {
15155
                        WOLFSSL_MSG("wc_InitDsaKey_h error");
15156
                        goto exit_cs;
15157
                    }
15158
                    if ((ret = wc_DsaPublicKeyDecode(key, &idx, sigCtx->key.dsa,
15159
                                                                 keySz)) != 0) {
15160
                        WOLFSSL_MSG("ASN Key decode error DSA");
15161
                        WOLFSSL_ERROR_VERBOSE(ret);
15162
                        goto exit_cs;
15163
                    }
15164
                    if (sigSz != DSA_160_SIG_SIZE &&
15165
                            sigSz != DSA_256_SIG_SIZE) {
15166
                        /* Try to parse it as the contents of a bitstring */
15167
                    #ifdef WOLFSSL_SMALL_STACK
15168
                        mp_int* r;
15169
                        mp_int* s;
15170
                    #else
15171
                        mp_int r[1];
15172
                        mp_int s[1];
15173
                    #endif
15174
                        int rSz;
15175
                        int sSz;
15176
15177
                    #ifdef WOLFSSL_SMALL_STACK
15178
                        r = (mp_int*)XMALLOC(sizeof(*r), sigCtx->heap,
15179
                                                       DYNAMIC_TYPE_TMP_BUFFER);
15180
                        if (r == NULL) {
15181
                            ERROR_OUT(MEMORY_E, exit_cs);
15182
                        }
15183
                        s = (mp_int*)XMALLOC(sizeof(*s), sigCtx->heap,
15184
                                                       DYNAMIC_TYPE_TMP_BUFFER);
15185
                        if (s == NULL) {
15186
                            XFREE(r, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
15187
                            ERROR_OUT(MEMORY_E, exit_cs);
15188
                        }
15189
                    #endif
15190
                        mp_init(r);
15191
                        mp_init(s);
15192
15193
                        idx = 0;
15194
                        if (DecodeECC_DSA_Sig(sig + idx, sigSz - idx, r, s)
15195
                                              != 0) {
15196
                            WOLFSSL_MSG("DSA Sig is in unrecognized or "
15197
                                        "incorrect format");
15198
                            mp_free(r);
15199
                            mp_free(s);
15200
                    #ifdef WOLFSSL_SMALL_STACK
15201
                            XFREE(r, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
15202
                            XFREE(s, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
15203
                    #endif
15204
                            ERROR_OUT(ASN_SIG_CONFIRM_E, exit_cs);
15205
                        }
15206
                        rSz = mp_unsigned_bin_size(r);
15207
                        sSz = mp_unsigned_bin_size(s);
15208
                        if (rSz + sSz > (int)sigSz) {
15209
                            WOLFSSL_MSG("DSA Sig is in unrecognized or "
15210
                                        "incorrect format");
15211
                            mp_free(r);
15212
                            mp_free(s);
15213
                    #ifdef WOLFSSL_SMALL_STACK
15214
                            XFREE(r, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
15215
                            XFREE(s, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
15216
                    #endif
15217
                            ERROR_OUT(ASN_SIG_CONFIRM_E, exit_cs);
15218
                        }
15219
                        if (mp_to_unsigned_bin(r, sigCtx->sigCpy) != MP_OKAY ||
15220
                                mp_to_unsigned_bin(s,
15221
                                        sigCtx->sigCpy + rSz) != MP_OKAY) {
15222
                            WOLFSSL_MSG("DSA Sig is in unrecognized or "
15223
                                        "incorrect format");
15224
                            mp_free(r);
15225
                            mp_free(s);
15226
                    #ifdef WOLFSSL_SMALL_STACK
15227
                            XFREE(r, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
15228
                            XFREE(s, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
15229
                    #endif
15230
                            ERROR_OUT(ASN_SIG_CONFIRM_E, exit_cs);
15231
                        }
15232
                        mp_free(r);
15233
                        mp_free(s);
15234
                    #ifdef WOLFSSL_SMALL_STACK
15235
                        XFREE(r, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
15236
                        XFREE(s, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
15237
                    #endif
15238
                    }
15239
                    else {
15240
                        XMEMCPY(sigCtx->sigCpy, sig, sigSz);
15241
                    }
15242
                    break;
15243
                }
15244
            #endif /* !NO_DSA && !HAVE_SELFTEST */
15245
0
            #ifdef HAVE_ECC
15246
0
                case ECDSAk:
15247
0
                {
15248
0
                    word32 idx = 0;
15249
15250
0
                    sigCtx->verify = 0;
15251
0
                    sigCtx->key.ecc = (ecc_key*)XMALLOC(sizeof(ecc_key),
15252
0
                                                sigCtx->heap, DYNAMIC_TYPE_ECC);
15253
0
                    if (sigCtx->key.ecc == NULL) {
15254
0
                        ERROR_OUT(MEMORY_E, exit_cs);
15255
0
                    }
15256
0
                    if ((ret = wc_ecc_init_ex(sigCtx->key.ecc, sigCtx->heap,
15257
0
                                                          sigCtx->devId)) < 0) {
15258
0
                        goto exit_cs;
15259
0
                    }
15260
0
                    ret = wc_EccPublicKeyDecode(key, &idx, sigCtx->key.ecc,
15261
0
                                                                         keySz);
15262
0
                    if (ret < 0) {
15263
0
                        WOLFSSL_MSG("ASN Key import error ECC");
15264
0
                        WOLFSSL_ERROR_VERBOSE(ret);
15265
0
                        goto exit_cs;
15266
0
                    }
15267
                #ifdef WOLFSSL_ASYNC_CRYPT
15268
                    sigCtx->asyncDev = &sigCtx->key.ecc->asyncDev;
15269
                #endif
15270
0
                    break;
15271
0
                }
15272
0
            #endif /* HAVE_ECC */
15273
0
            #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
15274
0
                case ED25519k:
15275
0
                {
15276
0
                    sigCtx->verify = 0;
15277
0
                    sigCtx->key.ed25519 = (ed25519_key*)XMALLOC(
15278
0
                                              sizeof(ed25519_key), sigCtx->heap,
15279
0
                                              DYNAMIC_TYPE_ED25519);
15280
0
                    if (sigCtx->key.ed25519 == NULL) {
15281
0
                        ERROR_OUT(MEMORY_E, exit_cs);
15282
0
                    }
15283
0
                    if ((ret = wc_ed25519_init_ex(sigCtx->key.ed25519,
15284
0
                                            sigCtx->heap, sigCtx->devId)) < 0) {
15285
0
                        goto exit_cs;
15286
0
                    }
15287
0
                    if ((ret = wc_ed25519_import_public(key, keySz,
15288
0
                                                    sigCtx->key.ed25519)) < 0) {
15289
0
                        WOLFSSL_MSG("ASN Key import error ED25519");
15290
0
                        WOLFSSL_ERROR_VERBOSE(ret);
15291
0
                        goto exit_cs;
15292
0
                    }
15293
                #ifdef WOLFSSL_ASYNC_CRYPT
15294
                    sigCtx->asyncDev = &sigCtx->key.ed25519->asyncDev;
15295
                #endif
15296
0
                    break;
15297
0
                }
15298
0
            #endif
15299
0
            #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)
15300
0
                case ED448k:
15301
0
                {
15302
0
                    sigCtx->verify = 0;
15303
0
                    sigCtx->key.ed448 = (ed448_key*)XMALLOC(
15304
0
                                                sizeof(ed448_key), sigCtx->heap,
15305
0
                                                DYNAMIC_TYPE_ED448);
15306
0
                    if (sigCtx->key.ed448 == NULL) {
15307
0
                        ERROR_OUT(MEMORY_E, exit_cs);
15308
0
                    }
15309
0
                    if ((ret = wc_ed448_init(sigCtx->key.ed448)) < 0) {
15310
0
                        goto exit_cs;
15311
0
                    }
15312
0
                    if ((ret = wc_ed448_import_public(key, keySz,
15313
0
                                                      sigCtx->key.ed448)) < 0) {
15314
0
                        WOLFSSL_MSG("ASN Key import error ED448");
15315
0
                        WOLFSSL_ERROR_VERBOSE(ret);
15316
0
                        goto exit_cs;
15317
0
                    }
15318
                #ifdef WOLFSSL_ASYNC_CRYPT
15319
                    sigCtx->asyncDev = &sigCtx->key.ed448->asyncDev;
15320
                #endif
15321
0
                    break;
15322
0
                }
15323
0
            #endif
15324
            #if defined(HAVE_PQC)
15325
            #if defined(HAVE_FALCON)
15326
                case FALCON_LEVEL1k:
15327
                {
15328
                    sigCtx->verify = 0;
15329
                    sigCtx->key.falcon =
15330
                        (falcon_key*)XMALLOC(sizeof(falcon_key),
15331
                                             sigCtx->heap,
15332
                                             DYNAMIC_TYPE_FALCON);
15333
                    if (sigCtx->key.falcon == NULL) {
15334
                        ERROR_OUT(MEMORY_E, exit_cs);
15335
                    }
15336
                    if ((ret = wc_falcon_init(sigCtx->key.falcon)) < 0) {
15337
                        goto exit_cs;
15338
                    }
15339
                    if ((ret = wc_falcon_set_level(sigCtx->key.falcon, 1))
15340
                        < 0) {
15341
                        goto exit_cs;
15342
                    }
15343
                    if ((ret = wc_falcon_import_public(key, keySz,
15344
                        sigCtx->key.falcon)) < 0) {
15345
                        WOLFSSL_MSG("ASN Key import error Falcon Level 1");
15346
                        WOLFSSL_ERROR_VERBOSE(ret);
15347
                        goto exit_cs;
15348
                    }
15349
                    break;
15350
                }
15351
                case FALCON_LEVEL5k:
15352
                {
15353
                    sigCtx->verify = 0;
15354
                    sigCtx->key.falcon =
15355
                        (falcon_key*)XMALLOC(sizeof(falcon_key),
15356
                                             sigCtx->heap,
15357
                                             DYNAMIC_TYPE_FALCON);
15358
                    if (sigCtx->key.falcon == NULL) {
15359
                        ERROR_OUT(MEMORY_E, exit_cs);
15360
                    }
15361
                    if ((ret = wc_falcon_init(sigCtx->key.falcon)) < 0) {
15362
                        goto exit_cs;
15363
                    }
15364
                    if ((ret = wc_falcon_set_level(sigCtx->key.falcon, 5))
15365
                        < 0) {
15366
                        goto exit_cs;
15367
                    }
15368
                    if ((ret = wc_falcon_import_public(key, keySz,
15369
                        sigCtx->key.falcon)) < 0) {
15370
                        WOLFSSL_MSG("ASN Key import error Falcon Level 5");
15371
                        WOLFSSL_ERROR_VERBOSE(ret);
15372
                        goto exit_cs;
15373
                    }
15374
                    break;
15375
                }
15376
            #endif /* HAVE_FALCON */
15377
            #if defined(HAVE_DILITHIUM)
15378
                case DILITHIUM_LEVEL2k:
15379
                {
15380
                    sigCtx->verify = 0;
15381
                    sigCtx->key.dilithium =
15382
                        (dilithium_key*)XMALLOC(sizeof(dilithium_key),
15383
                                             sigCtx->heap,
15384
                                             DYNAMIC_TYPE_DILITHIUM);
15385
                    if (sigCtx->key.dilithium == NULL) {
15386
                        ERROR_OUT(MEMORY_E, exit_cs);
15387
                    }
15388
                    if ((ret = wc_dilithium_init(sigCtx->key.dilithium)) < 0) {
15389
                        goto exit_cs;
15390
                    }
15391
                    if ((ret = wc_dilithium_set_level_and_sym(
15392
                                   sigCtx->key.dilithium, 2, SHAKE_VARIANT))
15393
                        < 0) {
15394
                        goto exit_cs;
15395
                    }
15396
                    if ((ret = wc_dilithium_import_public(key, keySz,
15397
                        sigCtx->key.dilithium)) < 0) {
15398
                        WOLFSSL_MSG("ASN Key import error Dilithium Level 2");
15399
                        goto exit_cs;
15400
                    }
15401
                    break;
15402
                }
15403
                case DILITHIUM_LEVEL3k:
15404
                {
15405
                    sigCtx->verify = 0;
15406
                    sigCtx->key.dilithium =
15407
                        (dilithium_key*)XMALLOC(sizeof(dilithium_key),
15408
                                             sigCtx->heap,
15409
                                             DYNAMIC_TYPE_DILITHIUM);
15410
                    if (sigCtx->key.dilithium == NULL) {
15411
                        ERROR_OUT(MEMORY_E, exit_cs);
15412
                    }
15413
                    if ((ret = wc_dilithium_init(sigCtx->key.dilithium)) < 0) {
15414
                        goto exit_cs;
15415
                    }
15416
                    if ((ret = wc_dilithium_set_level_and_sym(
15417
                                   sigCtx->key.dilithium, 3, SHAKE_VARIANT))
15418
                        < 0) {
15419
                        goto exit_cs;
15420
                    }
15421
                    if ((ret = wc_dilithium_import_public(key, keySz,
15422
                        sigCtx->key.dilithium)) < 0) {
15423
                        WOLFSSL_MSG("ASN Key import error Dilithium Level 5");
15424
                        goto exit_cs;
15425
                    }
15426
                    break;
15427
                }
15428
                case DILITHIUM_LEVEL5k:
15429
                {
15430
                    sigCtx->verify = 0;
15431
                    sigCtx->key.dilithium =
15432
                        (dilithium_key*)XMALLOC(sizeof(dilithium_key),
15433
                                             sigCtx->heap,
15434
                                             DYNAMIC_TYPE_DILITHIUM);
15435
                    if (sigCtx->key.dilithium == NULL) {
15436
                        ERROR_OUT(MEMORY_E, exit_cs);
15437
                    }
15438
                    if ((ret = wc_dilithium_init(sigCtx->key.dilithium)) < 0) {
15439
                        goto exit_cs;
15440
                    }
15441
                    if ((ret = wc_dilithium_set_level_and_sym(
15442
                                   sigCtx->key.dilithium, 5, SHAKE_VARIANT))
15443
                        < 0) {
15444
                        goto exit_cs;
15445
                    }
15446
                    if ((ret = wc_dilithium_import_public(key, keySz,
15447
                        sigCtx->key.dilithium)) < 0) {
15448
                        WOLFSSL_MSG("ASN Key import error Dilithium Level 5");
15449
                        goto exit_cs;
15450
                    }
15451
                    break;
15452
                }
15453
                case DILITHIUM_AES_LEVEL2k:
15454
                {
15455
                    sigCtx->verify = 0;
15456
                    sigCtx->key.dilithium =
15457
                        (dilithium_key*)XMALLOC(sizeof(dilithium_key),
15458
                                             sigCtx->heap,
15459
                                             DYNAMIC_TYPE_DILITHIUM);
15460
                    if (sigCtx->key.dilithium == NULL) {
15461
                        ERROR_OUT(MEMORY_E, exit_cs);
15462
                    }
15463
                    if ((ret = wc_dilithium_init(sigCtx->key.dilithium)) < 0) {
15464
                        goto exit_cs;
15465
                    }
15466
                    if ((ret = wc_dilithium_set_level_and_sym(
15467
                                   sigCtx->key.dilithium, 2, AES_VARIANT))
15468
                        < 0) {
15469
                        goto exit_cs;
15470
                    }
15471
                    if ((ret = wc_dilithium_import_public(key, keySz,
15472
                        sigCtx->key.dilithium)) < 0) {
15473
                        WOLFSSL_MSG("ASN Key import error Dilithium Level 2");
15474
                        goto exit_cs;
15475
                    }
15476
                    break;
15477
                }
15478
                case DILITHIUM_AES_LEVEL3k:
15479
                {
15480
                    sigCtx->verify = 0;
15481
                    sigCtx->key.dilithium =
15482
                        (dilithium_key*)XMALLOC(sizeof(dilithium_key),
15483
                                             sigCtx->heap,
15484
                                             DYNAMIC_TYPE_DILITHIUM);
15485
                    if (sigCtx->key.dilithium == NULL) {
15486
                        ERROR_OUT(MEMORY_E, exit_cs);
15487
                    }
15488
                    if ((ret = wc_dilithium_init(sigCtx->key.dilithium)) < 0) {
15489
                        goto exit_cs;
15490
                    }
15491
                    if ((ret = wc_dilithium_set_level_and_sym(
15492
                                   sigCtx->key.dilithium, 3, AES_VARIANT))
15493
                        < 0) {
15494
                        goto exit_cs;
15495
                    }
15496
                    if ((ret = wc_dilithium_import_public(key, keySz,
15497
                        sigCtx->key.dilithium)) < 0) {
15498
                        WOLFSSL_MSG("ASN Key import error Dilithium Level 5");
15499
                        goto exit_cs;
15500
                    }
15501
                    break;
15502
                }
15503
                case DILITHIUM_AES_LEVEL5k:
15504
                {
15505
                    sigCtx->verify = 0;
15506
                    sigCtx->key.dilithium =
15507
                        (dilithium_key*)XMALLOC(sizeof(dilithium_key),
15508
                                             sigCtx->heap,
15509
                                             DYNAMIC_TYPE_DILITHIUM);
15510
                    if (sigCtx->key.dilithium == NULL) {
15511
                        ERROR_OUT(MEMORY_E, exit_cs);
15512
                    }
15513
                    if ((ret = wc_dilithium_init(sigCtx->key.dilithium)) < 0) {
15514
                        goto exit_cs;
15515
                    }
15516
                    if ((ret = wc_dilithium_set_level_and_sym(
15517
                                   sigCtx->key.dilithium, 5, AES_VARIANT))
15518
                        < 0) {
15519
                        goto exit_cs;
15520
                    }
15521
                    if ((ret = wc_dilithium_import_public(key, keySz,
15522
                        sigCtx->key.dilithium)) < 0) {
15523
                        WOLFSSL_MSG("ASN Key import error Dilithium Level 5");
15524
                        goto exit_cs;
15525
                    }
15526
                    break;
15527
                }
15528
            #endif /* HAVE_DILITHIUM */
15529
            #endif /* HAVE_PQC */
15530
0
                default:
15531
0
                    WOLFSSL_MSG("Verify Key type unknown");
15532
0
                    ret = ASN_UNKNOWN_OID_E;
15533
0
                    WOLFSSL_ERROR_VERBOSE(ret);
15534
0
                    break;
15535
0
            } /* switch (keyOID) */
15536
15537
0
            if (ret != 0) {
15538
0
                goto exit_cs;
15539
0
            }
15540
15541
0
            sigCtx->state = SIG_STATE_DO;
15542
15543
        #ifdef WOLFSSL_ASYNC_CRYPT
15544
            if (sigCtx->devId != INVALID_DEVID && sigCtx->asyncDev && sigCtx->asyncCtx) {
15545
                /* make sure event is initialized */
15546
                WOLF_EVENT* event = &sigCtx->asyncDev->event;
15547
                ret = wolfAsync_EventInit(event, WOLF_EVENT_TYPE_ASYNC_WOLFSSL,
15548
                    sigCtx->asyncCtx, WC_ASYNC_FLAG_CALL_AGAIN);
15549
            }
15550
        #endif
15551
0
        } /* SIG_STATE_KEY */
15552
0
        FALL_THROUGH;
15553
15554
0
        case SIG_STATE_DO:
15555
0
        {
15556
0
            switch (keyOID) {
15557
0
            #ifndef NO_RSA
15558
0
                #ifdef WC_RSA_PSS
15559
0
                case RSAPSSk:
15560
                    /* TODO: pkCbRsaPss - RSA PSS callback. */
15561
0
                    ret = wc_RsaPSS_VerifyInline_ex(sigCtx->sigCpy, sigSz,
15562
0
                        &sigCtx->out, sigCtx->hash, sigCtx->mgf,
15563
0
                        sigCtx->saltLen, sigCtx->key.rsa);
15564
0
                    break;
15565
0
                #endif
15566
0
                case RSAk:
15567
0
                {
15568
                #if defined(HAVE_PK_CALLBACKS)
15569
                    if (sigCtx->pkCbRsa) {
15570
                        ret = sigCtx->pkCbRsa(
15571
                                sigCtx->sigCpy, sigSz, &sigCtx->out,
15572
                                key, keySz,
15573
                                sigCtx->pkCtxRsa);
15574
                    }
15575
                #if !defined(WOLFSSL_RENESAS_SCEPROTECT) && \
15576
                    !defined(WOLFSSL_RENESAS_TSIP_TLS)
15577
                    else
15578
                #else
15579
                    if (!sigCtx->pkCbRsa || ret == CRYPTOCB_UNAVAILABLE)
15580
                #endif /* WOLFSSL_RENESAS_SCEPROTECT */
15581
                #endif /* HAVE_PK_CALLBACKS */
15582
0
                    {
15583
0
                        ret = wc_RsaSSL_VerifyInline(sigCtx->sigCpy, sigSz,
15584
0
                                                 &sigCtx->out, sigCtx->key.rsa);
15585
0
                    }
15586
0
                    break;
15587
0
                }
15588
0
            #endif /* !NO_RSA */
15589
            #if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
15590
                case DSAk:
15591
                {
15592
                    ret = wc_DsaVerify(sigCtx->digest, sigCtx->sigCpy,
15593
                            sigCtx->key.dsa, &sigCtx->verify);
15594
                    break;
15595
                }
15596
            #endif /* !NO_DSA && !HAVE_SELFTEST */
15597
0
            #if defined(HAVE_ECC)
15598
0
                case ECDSAk:
15599
0
                {
15600
                #if defined(HAVE_PK_CALLBACKS)
15601
                    if (sigCtx->pkCbEcc) {
15602
                        ret = sigCtx->pkCbEcc(
15603
                                sig, sigSz,
15604
                                sigCtx->digest, sigCtx->digestSz,
15605
                                key, keySz, &sigCtx->verify,
15606
                                sigCtx->pkCtxEcc);
15607
                    }
15608
                #if !defined(WOLFSSL_RENESAS_SCEPROTECT) && \
15609
                    !defined(WOLFSSL_RENESAS_TSIP_TLS)
15610
                    else
15611
                #else
15612
                    if (!sigCtx->pkCbEcc || ret == CRYPTOCB_UNAVAILABLE)
15613
                #endif /* WOLFSSL_RENESAS_SCEPROTECT */
15614
                #endif /* HAVE_PK_CALLBACKS */
15615
0
                    {
15616
0
                        ret = wc_ecc_verify_hash(sig, sigSz, sigCtx->digest,
15617
0
                                            sigCtx->digestSz, &sigCtx->verify,
15618
0
                                            sigCtx->key.ecc);
15619
0
                    }
15620
0
                    break;
15621
0
                }
15622
0
            #endif /* HAVE_ECC */
15623
0
            #if defined(HAVE_ED25519) && defined(HAVE_ED25519_VERIFY)
15624
0
                case ED25519k:
15625
0
                {
15626
0
                    ret = wc_ed25519_verify_msg(sig, sigSz, buf, bufSz,
15627
0
                                          &sigCtx->verify, sigCtx->key.ed25519);
15628
0
                    break;
15629
0
                }
15630
0
            #endif
15631
0
            #if defined(HAVE_ED448) && defined(HAVE_ED448_VERIFY)
15632
0
                case ED448k:
15633
0
                {
15634
0
                    ret = wc_ed448_verify_msg(sig, sigSz, buf, bufSz,
15635
0
                                             &sigCtx->verify, sigCtx->key.ed448,
15636
0
                                             NULL, 0);
15637
0
                    break;
15638
0
                }
15639
0
            #endif
15640
            #if defined(HAVE_PQC)
15641
            #if defined(HAVE_FALCON)
15642
                case FALCON_LEVEL1k:
15643
                case FALCON_LEVEL5k:
15644
                {
15645
                    ret = wc_falcon_verify_msg(sig, sigSz, buf, bufSz,
15646
                                               &sigCtx->verify,
15647
                                               sigCtx->key.falcon);
15648
                    break;
15649
                }
15650
            #endif /* HAVE_FALCON */
15651
            #if defined(HAVE_DILITHIUM)
15652
                case DILITHIUM_LEVEL2k:
15653
                case DILITHIUM_LEVEL3k:
15654
                case DILITHIUM_LEVEL5k:
15655
                case DILITHIUM_AES_LEVEL2k:
15656
                case DILITHIUM_AES_LEVEL3k:
15657
                case DILITHIUM_AES_LEVEL5k:
15658
                {
15659
                    ret = wc_dilithium_verify_msg(sig, sigSz, buf, bufSz,
15660
                                               &sigCtx->verify,
15661
                                               sigCtx->key.dilithium);
15662
                    break;
15663
                }
15664
            #endif /* HAVE_DILITHIUM */
15665
            #endif /* HAVE_PQC */
15666
0
                default:
15667
0
                    break;
15668
0
            }  /* switch (keyOID) */
15669
15670
        #ifdef WOLFSSL_ASYNC_CRYPT
15671
            if (ret == WC_PENDING_E) {
15672
                goto exit_cs;
15673
            }
15674
        #endif
15675
15676
0
            if (ret < 0) {
15677
                /* treat all errors as ASN_SIG_CONFIRM_E */
15678
0
                ret = ASN_SIG_CONFIRM_E;
15679
0
                WOLFSSL_ERROR_VERBOSE(ret);
15680
0
                goto exit_cs;
15681
0
            }
15682
15683
0
            sigCtx->state = SIG_STATE_CHECK;
15684
0
        } /* SIG_STATE_DO */
15685
0
        FALL_THROUGH;
15686
15687
0
        case SIG_STATE_CHECK:
15688
0
        {
15689
0
            switch (keyOID) {
15690
0
            #ifndef NO_RSA
15691
0
                #ifdef WC_RSA_PSS
15692
0
                case RSAPSSk:
15693
                #if (defined(HAVE_SELFTEST) && \
15694
                     (!defined(HAVE_SELFTEST_VERSION) || \
15695
                      (HAVE_SELFTEST_VERSION < 2))) || \
15696
                    (defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \
15697
                     (HAVE_FIPS_VERSION < 2))
15698
                    ret = wc_RsaPSS_CheckPadding_ex(sigCtx->digest,
15699
                        sigCtx->digestSz, sigCtx->out, ret, sigCtx->hash,
15700
                        sigCtx->saltLen);
15701
                #elif (defined(HAVE_SELFTEST) && \
15702
                       (HAVE_SELFTEST_VERSION == 2)) || \
15703
                      (defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \
15704
                       (HAVE_FIPS_VERSION == 2))
15705
                    ret = wc_RsaPSS_CheckPadding_ex(sigCtx->digest,
15706
                        sigCtx->digestSz, sigCtx->out, ret, sigCtx->hash,
15707
                        sigCtx->saltLen, 0);
15708
                #else
15709
0
                    ret = wc_RsaPSS_CheckPadding_ex2(sigCtx->digest,
15710
0
                        sigCtx->digestSz, sigCtx->out, ret, sigCtx->hash,
15711
0
                        sigCtx->saltLen, wc_RsaEncryptSize(sigCtx->key.rsa) * 8,
15712
0
                        sigCtx->heap);
15713
0
                #endif
15714
0
                    break;
15715
0
                #endif
15716
0
                case RSAk:
15717
0
                {
15718
0
                    int encodedSigSz, verifySz;
15719
                #if defined(WOLFSSL_RENESAS_TSIP_TLS) || \
15720
                                            defined(WOLFSSL_RENESAS_SCEPROTECT)
15721
                    if (sigCtx->CertAtt.verifyByTSIP_SCE == 1) break;
15722
                #endif
15723
0
                #ifdef WOLFSSL_SMALL_STACK
15724
0
                    byte* encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ,
15725
0
                                        sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
15726
0
                    if (encodedSig == NULL) {
15727
0
                        ERROR_OUT(MEMORY_E, exit_cs);
15728
0
                    }
15729
                #else
15730
                    byte encodedSig[MAX_ENCODED_SIG_SZ];
15731
                #endif
15732
15733
0
                    verifySz = ret;
15734
15735
                    /* make sure we're right justified */
15736
0
                    encodedSigSz = wc_EncodeSignature(encodedSig,
15737
0
                            sigCtx->digest, sigCtx->digestSz, sigCtx->typeH);
15738
0
                    if (encodedSigSz == verifySz && sigCtx->out != NULL &&
15739
0
                        XMEMCMP(sigCtx->out, encodedSig, encodedSigSz) == 0) {
15740
0
                        ret = 0;
15741
0
                    }
15742
0
                    else {
15743
0
                        WOLFSSL_MSG("RSA SSL verify match encode error");
15744
0
                        ret = ASN_SIG_CONFIRM_E;
15745
0
                        WOLFSSL_ERROR_VERBOSE(ret);
15746
0
                    }
15747
15748
0
                #ifdef WOLFSSL_SMALL_STACK
15749
0
                    XFREE(encodedSig, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
15750
0
                #endif
15751
0
                    break;
15752
0
                }
15753
0
            #endif /* NO_RSA */
15754
            #if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
15755
                case DSAk:
15756
                {
15757
                    if (sigCtx->verify == 1) {
15758
                        ret = 0;
15759
                    }
15760
                    else {
15761
                        WOLFSSL_MSG("DSA Verify didn't match");
15762
                        ret = ASN_SIG_CONFIRM_E;
15763
                        WOLFSSL_ERROR_VERBOSE(ret);
15764
                    }
15765
                    break;
15766
                }
15767
            #endif /* !NO_DSA && !HAVE_SELFTEST */
15768
0
            #ifdef HAVE_ECC
15769
0
                case ECDSAk:
15770
0
                {
15771
0
                    if (sigCtx->verify == 1) {
15772
0
                        ret = 0;
15773
0
                    }
15774
0
                    else {
15775
0
                        WOLFSSL_MSG("ECC Verify didn't match");
15776
0
                        ret = ASN_SIG_CONFIRM_E;
15777
0
                        WOLFSSL_ERROR_VERBOSE(ret);
15778
0
                    }
15779
0
                    break;
15780
0
                }
15781
0
            #endif /* HAVE_ECC */
15782
0
            #ifdef HAVE_ED25519
15783
0
                case ED25519k:
15784
0
                {
15785
0
                    if (sigCtx->verify == 1) {
15786
0
                        ret = 0;
15787
0
                    }
15788
0
                    else {
15789
0
                        WOLFSSL_MSG("ED25519 Verify didn't match");
15790
0
                        ret = ASN_SIG_CONFIRM_E;
15791
0
                        WOLFSSL_ERROR_VERBOSE(ret);
15792
0
                    }
15793
0
                    break;
15794
0
                }
15795
0
            #endif /* HAVE_ED25519 */
15796
0
            #ifdef HAVE_ED448
15797
0
                case ED448k:
15798
0
                {
15799
0
                    if (sigCtx->verify == 1) {
15800
0
                        ret = 0;
15801
0
                    }
15802
0
                    else {
15803
0
                        WOLFSSL_MSG("ED448 Verify didn't match");
15804
0
                        ret = ASN_SIG_CONFIRM_E;
15805
0
                        WOLFSSL_ERROR_VERBOSE(ret);
15806
0
                    }
15807
0
                    break;
15808
0
                }
15809
0
            #endif /* HAVE_ED448 */
15810
            #ifdef HAVE_PQC
15811
            #ifdef HAVE_FALCON
15812
                case FALCON_LEVEL1k:
15813
                {
15814
                    if (sigCtx->verify == 1) {
15815
                        ret = 0;
15816
                    }
15817
                    else {
15818
                        WOLFSSL_MSG("FALCON_LEVEL1 Verify didn't match");
15819
                        ret = ASN_SIG_CONFIRM_E;
15820
                        WOLFSSL_ERROR_VERBOSE(ret);
15821
                    }
15822
                    break;
15823
                }
15824
                case FALCON_LEVEL5k:
15825
                {
15826
                    if (sigCtx->verify == 1) {
15827
                        ret = 0;
15828
                    }
15829
                    else {
15830
                        WOLFSSL_MSG("FALCON_LEVEL5 Verify didn't match");
15831
                        ret = ASN_SIG_CONFIRM_E;
15832
                        WOLFSSL_ERROR_VERBOSE(ret);
15833
                    }
15834
                    break;
15835
                }
15836
            #endif /* HAVE_FALCON */
15837
            #ifdef HAVE_DILITHIUM
15838
                case DILITHIUM_LEVEL2k:
15839
                {
15840
                    if (sigCtx->verify == 1) {
15841
                        ret = 0;
15842
                    }
15843
                    else {
15844
                        WOLFSSL_MSG("DILITHIUM_LEVEL2 Verify didn't match");
15845
                        ret = ASN_SIG_CONFIRM_E;
15846
                    }
15847
                    break;
15848
                }
15849
                case DILITHIUM_LEVEL3k:
15850
                {
15851
                    if (sigCtx->verify == 1) {
15852
                        ret = 0;
15853
                    }
15854
                    else {
15855
                        WOLFSSL_MSG("DILITHIUM_LEVEL3 Verify didn't match");
15856
                        ret = ASN_SIG_CONFIRM_E;
15857
                    }
15858
                    break;
15859
                }
15860
                case DILITHIUM_LEVEL5k:
15861
                {
15862
                    if (sigCtx->verify == 1) {
15863
                        ret = 0;
15864
                    }
15865
                    else {
15866
                        WOLFSSL_MSG("DILITHIUM_LEVEL5 Verify didn't match");
15867
                        ret = ASN_SIG_CONFIRM_E;
15868
                    }
15869
                    break;
15870
                }
15871
                case DILITHIUM_AES_LEVEL2k:
15872
                {
15873
                    if (sigCtx->verify == 1) {
15874
                        ret = 0;
15875
                    }
15876
                    else {
15877
                        WOLFSSL_MSG("DILITHIUM_AES_LEVEL2 Verify didn't match");
15878
                        ret = ASN_SIG_CONFIRM_E;
15879
                    }
15880
                    break;
15881
                }
15882
                case DILITHIUM_AES_LEVEL3k:
15883
                {
15884
                    if (sigCtx->verify == 1) {
15885
                        ret = 0;
15886
                    }
15887
                    else {
15888
                        WOLFSSL_MSG("DILITHIUM_AES_LEVEL3 Verify didn't match");
15889
                        ret = ASN_SIG_CONFIRM_E;
15890
                    }
15891
                    break;
15892
                }
15893
                case DILITHIUM_AES_LEVEL5k:
15894
                {
15895
                    if (sigCtx->verify == 1) {
15896
                        ret = 0;
15897
                    }
15898
                    else {
15899
                        WOLFSSL_MSG("DILITHIUM_AES_LEVEL5 Verify didn't match");
15900
                        ret = ASN_SIG_CONFIRM_E;
15901
                    }
15902
                    break;
15903
                }
15904
            #endif /* HAVE_DILITHIUM */
15905
            #endif /* HAVE_PQC */
15906
0
                default:
15907
0
                    break;
15908
0
            }  /* switch (keyOID) */
15909
15910
0
            break;
15911
0
        } /* SIG_STATE_CHECK */
15912
15913
0
        default:
15914
0
            break;
15915
0
    } /* switch (sigCtx->state) */
15916
15917
0
exit_cs:
15918
15919
0
#endif /* !NO_ASN_CRYPT */
15920
15921
0
    (void)keyOID;
15922
0
    (void)sigOID;
15923
15924
0
    WOLFSSL_LEAVE("ConfirmSignature", ret);
15925
15926
#ifdef WOLFSSL_ASYNC_CRYPT
15927
    if (ret == WC_PENDING_E)
15928
        return ret;
15929
#endif
15930
15931
0
    FreeSignatureCtx(sigCtx);
15932
15933
0
    return ret;
15934
0
}
15935
15936
15937
#ifndef IGNORE_NAME_CONSTRAINTS
15938
15939
static int MatchBaseName(int type, const char* name, int nameSz,
15940
                         const char* base, int baseSz)
15941
0
{
15942
0
    if (base == NULL || baseSz <= 0 || name == NULL || nameSz <= 0 ||
15943
0
            name[0] == '.' || nameSz < baseSz ||
15944
0
            (type != ASN_RFC822_TYPE && type != ASN_DNS_TYPE &&
15945
0
             type != ASN_DIR_TYPE)) {
15946
0
        return 0;
15947
0
    }
15948
15949
0
    if (type == ASN_DIR_TYPE)
15950
0
        return XMEMCMP(name, base, baseSz) == 0;
15951
15952
    /* If an email type, handle special cases where the base is only
15953
     * a domain, or is an email address itself. */
15954
0
    if (type == ASN_RFC822_TYPE) {
15955
0
        const char* p = NULL;
15956
0
        int count = 0;
15957
15958
0
        if (base[0] != '.') {
15959
0
            p = base;
15960
0
            count = 0;
15961
15962
            /* find the '@' in the base */
15963
0
            while (*p != '@' && count < baseSz) {
15964
0
                count++;
15965
0
                p++;
15966
0
            }
15967
15968
            /* No '@' in base, reset p to NULL */
15969
0
            if (count >= baseSz)
15970
0
                p = NULL;
15971
0
        }
15972
15973
0
        if (p == NULL) {
15974
            /* Base isn't an email address, it is a domain name,
15975
             * wind the name forward one character past its '@'. */
15976
0
            p = name;
15977
0
            count = 0;
15978
0
            while (*p != '@' && count < baseSz) {
15979
0
                count++;
15980
0
                p++;
15981
0
            }
15982
15983
0
            if (count < baseSz && *p == '@') {
15984
0
                name = p + 1;
15985
0
                nameSz -= count + 1;
15986
0
            }
15987
0
        }
15988
0
    }
15989
15990
    /* RFC 5280 section 4.2.1.10
15991
     * "...Any DNS name that can be constructed by simply adding zero or more
15992
     *  labels to the left-hand side of the name satisfies the name constraint."
15993
     * i.e www.host.example.com works for host.example.com name constraint and
15994
     * host1.example.com does not. */
15995
0
    if (type == ASN_DNS_TYPE || (type == ASN_RFC822_TYPE && base[0] == '.')) {
15996
0
        int szAdjust = nameSz - baseSz;
15997
0
        name += szAdjust;
15998
0
        nameSz -= szAdjust;
15999
0
    }
16000
16001
0
    while (nameSz > 0) {
16002
0
        if (XTOLOWER((unsigned char)*name++) !=
16003
0
                                               XTOLOWER((unsigned char)*base++))
16004
0
            return 0;
16005
0
        nameSz--;
16006
0
    }
16007
16008
0
    return 1;
16009
0
}
16010
16011
16012
/* Search through the list to find if the name is permitted.
16013
 * name     The DNS name to search for
16014
 * dnsList  The list to search through
16015
 * nameType Type of DNS name to currently searching
16016
 * return 1 if found in list or if not needed
16017
 * return 0 if not found in the list but is needed
16018
 */
16019
static int PermittedListOk(DNS_entry* name, Base_entry* dnsList, byte nameType)
16020
0
{
16021
0
    Base_entry* current = dnsList;
16022
0
    int match = 0;
16023
0
    int need  = 0;
16024
0
    int ret   = 1; /* is ok unless needed and no match found */
16025
16026
0
    while (current != NULL) {
16027
0
        if (current->type == nameType) {
16028
0
            need = 1; /* restriction on permitted names is set for this type */
16029
0
            if (name->len >= current->nameSz &&
16030
0
                MatchBaseName(nameType, name->name, name->len,
16031
0
                              current->name, current->nameSz)) {
16032
0
                match = 1; /* found the current name in the permitted list*/
16033
0
                break;
16034
0
            }
16035
0
        }
16036
0
        current = current->next;
16037
0
    }
16038
16039
    /* check if permitted name restriction was set and no matching name found */
16040
0
    if (need && !match)
16041
0
        ret = 0;
16042
16043
0
    return ret;
16044
0
}
16045
16046
16047
/* Search through the list to find if the name is excluded.
16048
 * name     The DNS name to search for
16049
 * dnsList  The list to search through
16050
 * nameType Type of DNS name to currently searching
16051
 * return 1 if found in list and 0 if not found in the list
16052
 */
16053
static int IsInExcludedList(DNS_entry* name, Base_entry* dnsList, byte nameType)
16054
0
{
16055
0
    int ret = 0; /* default of not found in the list */
16056
0
    Base_entry* current = dnsList;
16057
16058
0
    while (current != NULL) {
16059
0
        if (current->type == nameType) {
16060
0
            if (name->len >= current->nameSz &&
16061
0
                MatchBaseName(nameType, name->name, name->len,
16062
0
                              current->name, current->nameSz)) {
16063
0
                ret = 1;
16064
0
                break;
16065
0
            }
16066
0
        }
16067
0
        current = current->next;
16068
0
    }
16069
16070
0
    return ret;
16071
0
}
16072
16073
16074
static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
16075
0
{
16076
0
    const byte nameTypes[] = {ASN_RFC822_TYPE, ASN_DNS_TYPE, ASN_DIR_TYPE};
16077
0
    int i;
16078
16079
0
    if (signer == NULL || cert == NULL)
16080
0
        return 0;
16081
16082
0
    if (signer->excludedNames == NULL && signer->permittedNames == NULL)
16083
0
        return 1;
16084
16085
0
    for (i=0; i < (int)sizeof(nameTypes); i++) {
16086
0
        byte nameType = nameTypes[i];
16087
0
        DNS_entry* name = NULL;
16088
0
        DNS_entry  subjectDnsName; /* temporary node used for subject name */
16089
16090
0
        XMEMSET(&subjectDnsName, 0, sizeof(DNS_entry));
16091
0
        switch (nameType) {
16092
0
            case ASN_DNS_TYPE:
16093
                /* Should it also consider CN in subject? It could use
16094
                 * subjectDnsName too */
16095
0
                name = cert->altNames;
16096
0
                break;
16097
0
            case ASN_RFC822_TYPE:
16098
                /* Shouldn't it validade E= in subject as well? */
16099
0
                name = cert->altEmailNames;
16100
16101
                /* Add subject email for checking. */
16102
0
                if (cert->subjectEmail != NULL) {
16103
                    /* RFC 5280 section 4.2.1.10
16104
                     * "When constraints are imposed on the rfc822Name name
16105
                     * form, but the certificate does not include a subject
16106
                     * alternative name, the rfc822Name constraint MUST be
16107
                     * applied to the attribute of type emailAddress in the
16108
                     * subject distinguished name" */
16109
0
                    subjectDnsName.next = NULL;
16110
0
                    subjectDnsName.type = ASN_RFC822_TYPE;
16111
0
                    subjectDnsName.len  = cert->subjectEmailLen;
16112
0
                    subjectDnsName.name = (char *)cert->subjectEmail;
16113
0
                }
16114
0
                break;
16115
0
            case ASN_DIR_TYPE:
16116
0
                name = cert->altDirNames;
16117
16118
0
            #ifndef WOLFSSL_NO_ASN_STRICT
16119
                /* RFC 5280 section 4.2.1.10
16120
                    "Restrictions of the form directoryName MUST be
16121
                    applied to the subject field .... and to any names
16122
                    of type directoryName in the subjectAltName
16123
                    extension"
16124
                */
16125
0
                if (cert->subjectRaw != NULL) {
16126
0
                    subjectDnsName.next = NULL;
16127
0
                    subjectDnsName.type = ASN_DIR_TYPE;
16128
0
                    subjectDnsName.len = cert->subjectRawLen;
16129
0
                    subjectDnsName.name = (char *)cert->subjectRaw;
16130
0
                }
16131
0
            #endif
16132
0
                break;
16133
0
            default:
16134
                /* Other types of names are ignored for now.
16135
                 * Shouldn't it be rejected if it there is a altNamesByType[nameType]
16136
                 * and signer->extNameConstraintCrit is set? */
16137
0
                return 0;
16138
0
        }
16139
16140
0
        while (name != NULL) {
16141
0
            if (IsInExcludedList(name, signer->excludedNames, nameType) == 1) {
16142
0
                WOLFSSL_MSG("Excluded name was found!");
16143
0
                return 0;
16144
0
            }
16145
16146
            /* Check against the permitted list */
16147
0
            if (PermittedListOk(name, signer->permittedNames, nameType) != 1) {
16148
0
                WOLFSSL_MSG("Permitted name was not found!");
16149
0
                return 0;
16150
0
            }
16151
16152
0
            name = name->next;
16153
0
        }
16154
16155
        /* handle comparing against subject name too */
16156
0
        if (subjectDnsName.len > 0 && subjectDnsName.name != NULL) {
16157
0
            if (IsInExcludedList(&subjectDnsName, signer->excludedNames,
16158
0
                        nameType) == 1) {
16159
0
                WOLFSSL_MSG("Excluded name was found!");
16160
0
                return 0;
16161
0
            }
16162
16163
            /* Check against the permitted list */
16164
0
            if (PermittedListOk(&subjectDnsName, signer->permittedNames,
16165
0
                        nameType) != 1) {
16166
0
                WOLFSSL_MSG("Permitted name was not found!");
16167
0
                return 0;
16168
0
            }
16169
0
        }
16170
0
    }
16171
16172
0
    return 1;
16173
0
}
16174
16175
#endif /* IGNORE_NAME_CONSTRAINTS */
16176
16177
#ifndef WOLFSSL_ASN_TEMPLATE
16178
static void AddAltName(DecodedCert* cert, DNS_entry* dnsEntry)
16179
0
{
16180
#if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_ALT_NAMES_NO_REV)
16181
    dnsEntry->next = NULL;
16182
    if (cert->altNames == NULL) {
16183
        /* First on list */
16184
        cert->altNames = dnsEntry;
16185
    }
16186
    else {
16187
        DNS_entry* temp = cert->altNames;
16188
16189
        /* Find end */
16190
        for (; (temp->next != NULL); temp = temp->next);
16191
16192
        /* Add to end */
16193
        temp->next = dnsEntry;
16194
    }
16195
#else
16196
0
    dnsEntry->next = cert->altNames;
16197
0
    cert->altNames = dnsEntry;
16198
0
#endif
16199
0
}
16200
#endif
16201
16202
#ifdef WOLFSSL_ASN_TEMPLATE
16203
#if defined(WOLFSSL_SEP) || defined(WOLFSSL_FPKI)
16204
/* ASN.1 template for OtherName of an X.509 certificate.
16205
 * X.509: RFC 5280, 4.2.1.6 - OtherName (without implicit outer SEQUENCE).
16206
 * HW Name: RFC 4108, 5 - Hardware Module Name
16207
 * Only support HW Name where the type is a HW serial number.
16208
 *
16209
 * Other Names handled for FPKI (Federal PKI) use:
16210
 * UPN (Universal Principal Name), a non-standard Other Name
16211
 *  (RFC3280 sec 4.2.1.7). Often used with FIPS 201 smartcard login.
16212
 * FASC-N (Federal Agency Smart Credential Number), defined in the document
16213
 *  fpki-x509-cert-policy-common.pdf. Used for a smart card ID.
16214
 */
16215
static const ASNItem otherNameASN[] = {
16216
/* TYPEID   */ { 0, ASN_OBJECT_ID, 0, 0, 0 },
16217
/* VALUE    */ { 0, ASN_CONTEXT_SPECIFIC | ASN_OTHERNAME_VALUE, 1, 1, 0 },
16218
/* UPN      */     { 1, ASN_UTF8STRING, 0, 0, 2 },
16219
/* FASC-N   */     { 1, ASN_OCTET_STRING, 0, 0, 2 },
16220
/* HWN_SEQ  */     { 1, ASN_SEQUENCE, 1, 0, 2 },
16221
/* HWN_TYPE */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
16222
/* HWN_NUM  */         { 2, ASN_OCTET_STRING, 0, 0, 0 }
16223
};
16224
enum {
16225
    OTHERNAMEASN_IDX_TYPEID = 0,
16226
    OTHERNAMEASN_IDX_VALUE,
16227
    OTHERNAMEASN_IDX_UPN,
16228
    OTHERNAMEASN_IDX_FASCN,
16229
    OTHERNAMEASN_IDX_HWN_SEQ,
16230
    OTHERNAMEASN_IDX_HWN_TYPE,
16231
    OTHERNAMEASN_IDX_HWN_NUM,
16232
};
16233
16234
/* Number of items in ASN.1 template for OtherName of an X.509 certificate. */
16235
#define otherNameASN_Length (sizeof(otherNameASN) / sizeof(ASNItem))
16236
16237
#ifdef WOLFSSL_SEP
16238
static int DecodeSEP(ASNGetData* dataASN, DecodedCert* cert)
16239
{
16240
    int ret = 0;
16241
    word32 oidLen, serialLen;
16242
16243
    oidLen = dataASN[OTHERNAMEASN_IDX_HWN_TYPE].data.oid.length;
16244
    serialLen = dataASN[OTHERNAMEASN_IDX_HWN_NUM].data.ref.length;
16245
16246
    /* Allocate space for HW type OID. */
16247
    cert->hwType = (byte*)XMALLOC(oidLen, cert->heap,
16248
                                  DYNAMIC_TYPE_X509_EXT);
16249
    if (cert->hwType == NULL)
16250
        ret = MEMORY_E;
16251
16252
    if (ret == 0) {
16253
        /* Copy, into cert HW type OID */
16254
        XMEMCPY(cert->hwType,
16255
                dataASN[OTHERNAMEASN_IDX_HWN_TYPE].data.oid.data, oidLen);
16256
        cert->hwTypeSz = oidLen;
16257
        /* TODO: check this is the HW serial number OID - no test data. */
16258
16259
        /* Allocate space for HW serial number. */
16260
        cert->hwSerialNum = (byte*)XMALLOC(serialLen, cert->heap,
16261
                                           DYNAMIC_TYPE_X509_EXT);
16262
        if (cert->hwSerialNum == NULL) {
16263
            WOLFSSL_MSG("\tOut of Memory");
16264
            ret = MEMORY_E;
16265
        }
16266
    }
16267
    if (ret == 0) {
16268
        /* Copy into cert HW serial number. */
16269
        XMEMCPY(cert->hwSerialNum,
16270
                dataASN[OTHERNAMEASN_IDX_HWN_NUM].data.ref.data, serialLen);
16271
        cert->hwSerialNum[serialLen] = '\0';
16272
        cert->hwSerialNumSz = serialLen;
16273
    }
16274
    return ret;
16275
}
16276
#endif /* WOLFSSL_SEP */
16277
16278
#ifdef WOLFSSL_FPKI
16279
static int DecodeOtherHelper(ASNGetData* dataASN, DecodedCert* cert, int oid)
16280
{
16281
    DNS_entry* entry = NULL;
16282
    int ret = 0;
16283
    word32 bufLen   = 0;
16284
    const char* buf = NULL;
16285
16286
    switch (oid) {
16287
        case FASCN_OID:
16288
            bufLen = dataASN[OTHERNAMEASN_IDX_FASCN].data.ref.length;
16289
            buf    = (const char*)dataASN[OTHERNAMEASN_IDX_FASCN].data.ref.data;
16290
            break;
16291
        case UPN_OID:
16292
            bufLen = dataASN[OTHERNAMEASN_IDX_UPN].data.ref.length;
16293
            buf    = (const char*)dataASN[OTHERNAMEASN_IDX_UPN].data.ref.data;
16294
            break;
16295
        default:
16296
            WOLFSSL_ERROR_VERBOSE(ASN_UNKNOWN_OID_E);
16297
            ret = ASN_UNKNOWN_OID_E;
16298
            break;
16299
    }
16300
16301
    if (ret == 0) {
16302
        ret = SetDNSEntry(cert, buf, bufLen, ASN_OTHER_TYPE, &entry);
16303
        if (ret == 0) {
16304
            entry->oidSum = oid;
16305
            AddDNSEntryToList(&cert->altNames, entry);
16306
        }
16307
    }
16308
    return ret;
16309
}
16310
#endif /* WOLFSSL_FPKI */
16311
16312
/* Decode data with OtherName format from after implicit SEQUENCE.
16313
 *
16314
 * @param [in, out] cert      Certificate object.
16315
 * @param [in]      input     Buffer containing encoded OtherName.
16316
 * @param [in, out] inOutIdx  On in, the index of the start of the OtherName.
16317
 *                            On out, index after OtherName.
16318
 * @param [in]      maxIdx    Maximum index of data in buffer.
16319
 * @return  0 on success.
16320
 * @return  MEMORY_E on dynamic memory allocation failure.
16321
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
16322
 *          is invalid.
16323
 * @return  ASN_PARSE_E when OID does is not HW Name.
16324
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
16325
 * @return  BUFFER_E when data in buffer is too small.
16326
 */
16327
static int DecodeOtherName(DecodedCert* cert, const byte* input,
16328
                           word32* inOutIdx, word32 maxIdx)
16329
{
16330
    DECL_ASNGETDATA(dataASN, otherNameASN_Length);
16331
    int ret = 0;
16332
16333
    CALLOC_ASNGETDATA(dataASN, otherNameASN_Length, ret, cert->heap);
16334
16335
    if (ret == 0) {
16336
        /* Check the first OID is a recognized Alt Cert Name type. */
16337
        GetASN_OID(&dataASN[OTHERNAMEASN_IDX_TYPEID], oidCertAltNameType);
16338
        /* Parse OtherName. */
16339
        ret = GetASN_Items(otherNameASN, dataASN, otherNameASN_Length, 1, input,
16340
                           inOutIdx, maxIdx);
16341
    }
16342
    if (ret == 0) {
16343
        /* Ensure expected OID. */
16344
        switch (dataASN[OTHERNAMEASN_IDX_TYPEID].data.oid.sum) {
16345
        #ifdef WOLFSSL_SEP
16346
            case HW_NAME_OID:
16347
                /* Only support HW serial number. */
16348
                GetASN_OID(&dataASN[OTHERNAMEASN_IDX_HWN_TYPE], oidIgnoreType);
16349
                ret = DecodeSEP(dataASN, cert);
16350
                break;
16351
        #endif /* WOLFSSL_SEP */
16352
        #ifdef WOLFSSL_FPKI
16353
            case FASCN_OID:
16354
            case UPN_OID:
16355
                ret = DecodeOtherHelper(dataASN, cert,
16356
                        dataASN[OTHERNAMEASN_IDX_TYPEID].data.oid.sum);
16357
                break;
16358
        #endif /* WOLFSSL_FPKI */
16359
            default:
16360
                WOLFSSL_MSG("\tunsupported OID");
16361
                WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
16362
                ret = ASN_PARSE_E;
16363
        }
16364
    }
16365
16366
    FREE_ASNGETDATA(dataASN, cert->heap);
16367
    return ret;
16368
}
16369
#endif /* WOLFSSL_SEP || WOLFSSL_FPKI */
16370
16371
/* Decode a GeneralName.
16372
 *
16373
 * @param [in]      input     Buffer containing encoded OtherName.
16374
 * @param [in, out] inOutIdx  On in, the index of the start of the OtherName.
16375
 *                            On out, index after OtherName.
16376
 * @param [in]      len       Length of data in buffer.
16377
 * @param [in]      cert      Decoded certificate object.
16378
 * @return  0 on success.
16379
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
16380
 *          is invalid.
16381
 * @return  BUFFER_E when data in buffer is too small.
16382
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
16383
 * @return  MEMORY_E when dynamic memory allocation fails.
16384
 */
16385
static int DecodeGeneralName(const byte* input, word32* inOutIdx, byte tag,
16386
                             int len, DecodedCert* cert)
16387
{
16388
    int ret = 0;
16389
    word32 idx = *inOutIdx;
16390
16391
    /* GeneralName choice: dnsName */
16392
    if (tag == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) {
16393
        ret = SetDNSEntry(cert, (const char*)(input + idx), len, ASN_DNS_TYPE,
16394
                &cert->altNames);
16395
        if (ret == 0) {
16396
            idx += len;
16397
        }
16398
    }
16399
#ifndef IGNORE_NAME_CONSTRAINTS
16400
    /* GeneralName choice: directoryName */
16401
    else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_DIR_TYPE)) {
16402
        int strLen;
16403
        word32 idxDir = idx;
16404
16405
        /* Expecting a SEQUENCE using up all data. */
16406
        if (GetASN_Sequence(input, &idxDir, &strLen, idx + len, 1) < 0) {
16407
            WOLFSSL_MSG("\tfail: seq length");
16408
            return ASN_PARSE_E;
16409
        }
16410
16411
        ret = SetDNSEntry(cert, (const char*)(input + idxDir), strLen,
16412
                ASN_DIR_TYPE, &cert->altDirNames);
16413
        if (ret == 0) {
16414
            idx += len;
16415
        }
16416
    }
16417
    /* GeneralName choice: rfc822Name */
16418
    else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE)) {
16419
        ret = SetDNSEntry(cert, (const char*)(input + idx), len,
16420
                ASN_RFC822_TYPE, &cert->altEmailNames);
16421
        if (ret == 0) {
16422
            idx += len;
16423
        }
16424
    }
16425
    /* GeneralName choice: uniformResourceIdentifier */
16426
    else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_URI_TYPE)) {
16427
        WOLFSSL_MSG("\tPutting URI into list but not using");
16428
16429
    #if !defined(WOLFSSL_NO_ASN_STRICT) && !defined(WOLFSSL_FPKI)
16430
        /* Verify RFC 5280 Sec 4.2.1.6 rule:
16431
            "The name MUST NOT be a relative URI" */
16432
        {
16433
            int i;
16434
16435
            /* skip past scheme (i.e http,ftp,...) finding first ':' char */
16436
            for (i = 0; i < len; i++) {
16437
                if (input[idx + i] == ':') {
16438
                    break;
16439
                }
16440
                if (input[idx + i] == '/') {
16441
                    i = len; /* error, found relative path since '/' was
16442
                              * encountered before ':'. Returning error
16443
                              * value in next if statement. */
16444
                }
16445
            }
16446
16447
            /* test if no ':' char was found and test that the next two
16448
             * chars are "//" to match the pattern "://" */
16449
            if (i >= len - 2 || (input[idx + i + 1] != '/' ||
16450
                                 input[idx + i + 2] != '/')) {
16451
                WOLFSSL_MSG("\tAlt Name must be absolute URI");
16452
                WOLFSSL_ERROR_VERBOSE(ASN_ALT_NAME_E);
16453
                return ASN_ALT_NAME_E;
16454
            }
16455
        }
16456
    #endif
16457
16458
        ret = SetDNSEntry(cert, (const char*)(input + idx), len, ASN_URI_TYPE,
16459
                &cert->altNames);
16460
        if (ret == 0) {
16461
            idx += len;
16462
        }
16463
    }
16464
    #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || \
16465
                                            defined(WOLFSSL_IP_ALT_NAME)
16466
    /* GeneralName choice: iPAddress */
16467
    else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_IP_TYPE)) {
16468
        ret = SetDNSEntry(cert, (const char*)(input + idx), len, ASN_IP_TYPE,
16469
                &cert->altNames);
16470
        if (ret == 0) {
16471
            idx += len;
16472
        }
16473
    }
16474
    #endif /* WOLFSSL_QT || OPENSSL_ALL */
16475
#endif /* IGNORE_NAME_CONSTRAINTS */
16476
#if defined(WOLFSSL_SEP) || defined(WOLFSSL_FPKI)
16477
    /* GeneralName choice: otherName */
16478
    else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE)) {
16479
        /* TODO: test data for code path */
16480
        ret = DecodeOtherName(cert, input, &idx, idx + len);
16481
    }
16482
#endif
16483
    /* GeneralName choice: dNSName, x400Address, ediPartyName,
16484
     *                     registeredID */
16485
    else {
16486
        WOLFSSL_MSG("\tUnsupported name type, skipping");
16487
        idx += len;
16488
    }
16489
16490
    if (ret == 0) {
16491
        /* Return index of next encoded byte. */
16492
        *inOutIdx = idx;
16493
    }
16494
    return ret;
16495
}
16496
16497
/* ASN.1 choices for GeneralName.
16498
 * X.509: RFC 5280, 4.2.1.6 - GeneralName.
16499
 */
16500
static const byte generalNameChoice[] = {
16501
    ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0,
16502
    ASN_CONTEXT_SPECIFIC                   | 1,
16503
    ASN_CONTEXT_SPECIFIC                   | 2,
16504
    ASN_CONTEXT_SPECIFIC                   | 3,
16505
    ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 4,
16506
    ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 5,
16507
    ASN_CONTEXT_SPECIFIC                   | 6,
16508
    ASN_CONTEXT_SPECIFIC                   | 7,
16509
    ASN_CONTEXT_SPECIFIC                   | 8,
16510
    0
16511
};
16512
16513
/* ASN.1 template for GeneralName.
16514
 * X.509: RFC 5280, 4.2.1.6 - GeneralName.
16515
 */
16516
static const ASNItem altNameASN[] = {
16517
    { 0, ASN_CONTEXT_SPECIFIC | 0, 0, 1, 0 }
16518
};
16519
enum {
16520
    ALTNAMEASN_IDX_GN = 0,
16521
};
16522
16523
/* Number of items in ASN.1 template for GeneralName. */
16524
#define altNameASN_Length (sizeof(altNameASN) / sizeof(ASNItem))
16525
#endif /* WOLFSSL_ASN_TEMPLATE */
16526
16527
#if defined(WOLFSSL_SEP) && !defined(WOLFSSL_ASN_TEMPLATE)
16528
/* return 0 on success */
16529
static int DecodeSepHwAltName(DecodedCert* cert, const byte* input,
16530
    word32* idxIn, int sz)
16531
{
16532
    word32 idx = *idxIn;
16533
    int  strLen;
16534
    int  ret;
16535
    byte tag;
16536
16537
    /* Certificates issued with this OID in the subject alt name are for
16538
     * verifying signatures created on a module.
16539
     * RFC 4108 Section 5. */
16540
    if (cert->hwType != NULL) {
16541
        WOLFSSL_MSG("\tAlready seen Hardware Module Name");
16542
        return ASN_PARSE_E;
16543
    }
16544
16545
    if (GetASNTag(input, &idx, &tag, sz) < 0) {
16546
        return ASN_PARSE_E;
16547
    }
16548
16549
    if (tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
16550
        WOLFSSL_MSG("\twrong type");
16551
        return ASN_PARSE_E;
16552
    }
16553
16554
    if (GetLength(input, &idx, &strLen, sz) < 0) {
16555
        WOLFSSL_MSG("\tfail: str len");
16556
        return ASN_PARSE_E;
16557
    }
16558
16559
    if (GetSequence(input, &idx, &strLen, sz) < 0) {
16560
        WOLFSSL_MSG("\tBad Sequence");
16561
        return ASN_PARSE_E;
16562
    }
16563
16564
    ret = GetASNObjectId(input, &idx, &strLen, sz);
16565
    if (ret != 0) {
16566
        WOLFSSL_MSG("\tbad OID");
16567
        return ret;
16568
    }
16569
16570
    cert->hwType = (byte*)XMALLOC(strLen, cert->heap,
16571
                                  DYNAMIC_TYPE_X509_EXT);
16572
    if (cert->hwType == NULL) {
16573
        WOLFSSL_MSG("\tOut of Memory");
16574
        return MEMORY_E;
16575
    }
16576
16577
    XMEMCPY(cert->hwType, &input[idx], strLen);
16578
    cert->hwTypeSz = strLen;
16579
    idx += strLen;
16580
16581
    ret = GetOctetString(input, &idx, &strLen, sz);
16582
    if (ret < 0) {
16583
        XFREE(cert->hwType, cert->heap, DYNAMIC_TYPE_X509_EXT);
16584
        cert->hwType = NULL;
16585
        return ret;
16586
    }
16587
16588
    cert->hwSerialNum = (byte*)XMALLOC(strLen + 1, cert->heap,
16589
                                       DYNAMIC_TYPE_X509_EXT);
16590
    if (cert->hwSerialNum == NULL) {
16591
        WOLFSSL_MSG("\tOut of Memory");
16592
        XFREE(cert->hwType, cert->heap, DYNAMIC_TYPE_X509_EXT);
16593
        cert->hwType = NULL;
16594
        return MEMORY_E;
16595
    }
16596
16597
    XMEMCPY(cert->hwSerialNum, &input[idx], strLen);
16598
    cert->hwSerialNum[strLen] = '\0';
16599
    cert->hwSerialNumSz = strLen;
16600
    idx += strLen;
16601
16602
    *idxIn = idx;
16603
    return 0;
16604
}
16605
#endif /* WOLFSSL_SEP */
16606
16607
#if !defined(WOLFSSL_ASN_TEMPLATE)
16608
/* return 0 on success */
16609
static int DecodeConstructedOtherName(DecodedCert* cert, const byte* input,
16610
        word32* idx, int sz, int oid)
16611
0
{
16612
0
    int ret    = 0;
16613
0
    int strLen = 0;
16614
0
    byte tag;
16615
0
    DNS_entry* dnsEntry = NULL;
16616
16617
0
    if (GetASNTag(input, idx, &tag, sz) < 0) {
16618
0
        ret = ASN_PARSE_E;
16619
0
    }
16620
16621
0
    if (ret == 0 && (tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))) {
16622
0
        ret = ASN_PARSE_E;
16623
0
    }
16624
16625
0
    if (ret == 0 && (GetLength(input, idx, &strLen, sz) < 0)) {
16626
0
        ret = ASN_PARSE_E;
16627
0
    }
16628
16629
0
    if (ret == 0) {
16630
0
        dnsEntry = AltNameNew(cert->heap);
16631
0
        if (dnsEntry == NULL) {
16632
0
            WOLFSSL_MSG("\tOut of Memory");
16633
0
            return MEMORY_E;
16634
0
        }
16635
0
    }
16636
16637
0
    if (ret == 0) {
16638
0
        switch (oid) {
16639
        #ifdef WOLFSSL_FPKI
16640
            case FASCN_OID:
16641
                ret = GetOctetString(input, idx, &strLen, sz);
16642
                if (ret > 0) {
16643
                    ret = 0;
16644
                }
16645
                break;
16646
        #endif /* WOLFSSL_FPKI */
16647
0
            case UPN_OID:
16648
0
                if (GetASNTag(input, idx, &tag, sz) < 0) {
16649
0
                    ret = ASN_PARSE_E;
16650
0
                }
16651
16652
0
                if (ret == 0 &&
16653
0
                        tag != ASN_PRINTABLE_STRING && tag != ASN_UTF8STRING &&
16654
0
                                    tag != ASN_IA5_STRING) {
16655
0
                    WOLFSSL_MSG("Was expecting a string for UPN");
16656
0
                    ret = ASN_PARSE_E;
16657
0
                }
16658
16659
0
                if (ret == 0 && (GetLength(input, idx, &strLen, sz) < 0)) {
16660
0
                    WOLFSSL_MSG("Was expecting a string for UPN");
16661
0
                    ret = ASN_PARSE_E;
16662
0
                }
16663
0
                break;
16664
16665
0
            default:
16666
0
                WOLFSSL_MSG("Unknown constructed other name, skipping");
16667
0
                *idx += strLen;
16668
0
                XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
16669
0
                dnsEntry = NULL;
16670
0
        }
16671
0
    }
16672
16673
0
    if (ret == 0 && dnsEntry != NULL) {
16674
0
        dnsEntry->type = ASN_OTHER_TYPE;
16675
0
        dnsEntry->len = strLen;
16676
0
        dnsEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
16677
0
            DYNAMIC_TYPE_ALTNAME);
16678
    #ifdef WOLFSSL_FPKI
16679
        dnsEntry->oidSum = oid;
16680
    #endif /* WOLFSSL_FPKI */
16681
0
        if (dnsEntry->name == NULL) {
16682
0
            WOLFSSL_MSG("\tOut of Memory");
16683
0
            ret = MEMORY_E;
16684
0
        }
16685
0
        else {
16686
0
            XMEMCPY(dnsEntry->name, &input[*idx], strLen);
16687
0
            dnsEntry->name[strLen] = '\0';
16688
0
            AddAltName(cert, dnsEntry);
16689
0
        }
16690
0
    }
16691
16692
0
    if (ret == 0) {
16693
0
        *idx += strLen;
16694
0
    }
16695
0
    else {
16696
0
        XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
16697
0
    }
16698
16699
0
    return ret;
16700
0
}
16701
#endif
16702
16703
/* Decode subject alternative names extension.
16704
 *
16705
 * RFC 5280 4.2.1.6.  Subject Alternative Name
16706
 *
16707
 * @param [in]      input  Buffer holding encoded data.
16708
 * @param [in]      sz     Size of encoded data in bytes.
16709
 * @param [in, out] cert   Decoded certificate object.
16710
 * @return  0 on success.
16711
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
16712
 *          is invalid.
16713
 * @return  BUFFER_E when data in buffer is too small.
16714
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
16715
 * @return  MEMORY_E when dynamic memory allocation fails.
16716
 */
16717
static int DecodeAltNames(const byte* input, int sz, DecodedCert* cert)
16718
0
{
16719
0
#ifndef WOLFSSL_ASN_TEMPLATE
16720
0
    word32 idx = 0;
16721
0
    int length = 0;
16722
16723
0
    WOLFSSL_ENTER("DecodeAltNames");
16724
16725
0
    if (GetSequence(input, &idx, &length, sz) < 0) {
16726
0
        WOLFSSL_MSG("\tBad Sequence");
16727
0
        return ASN_PARSE_E;
16728
0
    }
16729
16730
0
    if (length == 0) {
16731
        /* RFC 5280 4.2.1.6.  Subject Alternative Name
16732
           If the subjectAltName extension is present, the sequence MUST
16733
           contain at least one entry. */
16734
0
        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
16735
0
        return ASN_PARSE_E;
16736
0
    }
16737
16738
#ifdef OPENSSL_ALL
16739
    cert->extSubjAltNameSrc = input;
16740
    cert->extSubjAltNameSz = sz;
16741
#endif
16742
16743
0
    cert->weOwnAltNames = 1;
16744
16745
0
    while (length > 0) {
16746
0
        byte b = input[idx++];
16747
16748
0
        length--;
16749
16750
        /* Save DNS Type names in the altNames list. */
16751
        /* Save Other Type names in the cert's OidMap */
16752
0
        if (b == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) {
16753
0
            DNS_entry* dnsEntry;
16754
0
            int strLen;
16755
0
            word32 lenStartIdx = idx;
16756
16757
0
            if (GetLength(input, &idx, &strLen, sz) < 0) {
16758
0
                WOLFSSL_MSG("\tfail: str length");
16759
0
                return ASN_PARSE_E;
16760
0
            }
16761
0
            length -= (idx - lenStartIdx);
16762
16763
0
            dnsEntry = AltNameNew(cert->heap);
16764
0
            if (dnsEntry == NULL) {
16765
0
                WOLFSSL_MSG("\tOut of Memory");
16766
0
                return MEMORY_E;
16767
0
            }
16768
16769
0
            dnsEntry->type = ASN_DNS_TYPE;
16770
0
            dnsEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
16771
0
                                         DYNAMIC_TYPE_ALTNAME);
16772
0
            if (dnsEntry->name == NULL) {
16773
0
                WOLFSSL_MSG("\tOut of Memory");
16774
0
                XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
16775
0
                return MEMORY_E;
16776
0
            }
16777
0
            dnsEntry->len = strLen;
16778
0
            XMEMCPY(dnsEntry->name, &input[idx], strLen);
16779
0
            dnsEntry->name[strLen] = '\0';
16780
16781
0
            AddAltName(cert, dnsEntry);
16782
16783
0
            length -= strLen;
16784
0
            idx    += strLen;
16785
0
        }
16786
0
    #ifndef IGNORE_NAME_CONSTRAINTS
16787
0
        else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_DIR_TYPE)) {
16788
0
            DNS_entry* dirEntry;
16789
0
            int strLen;
16790
0
            word32 lenStartIdx = idx;
16791
16792
0
            if (GetLength(input, &idx, &strLen, sz) < 0) {
16793
0
                WOLFSSL_MSG("\tfail: str length");
16794
0
                return ASN_PARSE_E;
16795
0
            }
16796
16797
0
            if (GetSequence(input, &idx, &strLen, sz) < 0) {
16798
0
                WOLFSSL_MSG("\tfail: seq length");
16799
0
                return ASN_PARSE_E;
16800
0
            }
16801
0
            length -= (idx - lenStartIdx);
16802
16803
0
            dirEntry = AltNameNew(cert->heap);
16804
0
            if (dirEntry == NULL) {
16805
0
                WOLFSSL_MSG("\tOut of Memory");
16806
0
                return MEMORY_E;
16807
0
            }
16808
16809
0
            dirEntry->type = ASN_DIR_TYPE;
16810
0
            dirEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
16811
0
                                         DYNAMIC_TYPE_ALTNAME);
16812
0
            if (dirEntry->name == NULL) {
16813
0
                WOLFSSL_MSG("\tOut of Memory");
16814
0
                XFREE(dirEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
16815
0
                return MEMORY_E;
16816
0
            }
16817
0
            dirEntry->len = strLen;
16818
0
            XMEMCPY(dirEntry->name, &input[idx], strLen);
16819
0
            dirEntry->name[strLen] = '\0';
16820
0
            dirEntry->next = cert->altDirNames;
16821
0
            cert->altDirNames = dirEntry;
16822
16823
0
            length -= strLen;
16824
0
            idx    += strLen;
16825
0
        }
16826
0
        else if (b == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE)) {
16827
0
            DNS_entry* emailEntry;
16828
0
            int strLen;
16829
0
            word32 lenStartIdx = idx;
16830
16831
0
            if (GetLength(input, &idx, &strLen, sz) < 0) {
16832
0
                WOLFSSL_MSG("\tfail: str length");
16833
0
                return ASN_PARSE_E;
16834
0
            }
16835
0
            length -= (idx - lenStartIdx);
16836
16837
0
            emailEntry = AltNameNew(cert->heap);
16838
0
            if (emailEntry == NULL) {
16839
0
                WOLFSSL_MSG("\tOut of Memory");
16840
0
                return MEMORY_E;
16841
0
            }
16842
16843
0
            emailEntry->type = ASN_RFC822_TYPE;
16844
0
            emailEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
16845
0
                                         DYNAMIC_TYPE_ALTNAME);
16846
0
            if (emailEntry->name == NULL) {
16847
0
                WOLFSSL_MSG("\tOut of Memory");
16848
0
                XFREE(emailEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
16849
0
                return MEMORY_E;
16850
0
            }
16851
0
            emailEntry->len = strLen;
16852
0
            XMEMCPY(emailEntry->name, &input[idx], strLen);
16853
0
            emailEntry->name[strLen] = '\0';
16854
16855
0
            emailEntry->next = cert->altEmailNames;
16856
0
            cert->altEmailNames = emailEntry;
16857
16858
0
            length -= strLen;
16859
0
            idx    += strLen;
16860
0
        }
16861
0
        else if (b == (ASN_CONTEXT_SPECIFIC | ASN_URI_TYPE)) {
16862
0
            DNS_entry* uriEntry;
16863
0
            int strLen;
16864
0
            word32 lenStartIdx = idx;
16865
16866
0
            WOLFSSL_MSG("\tPutting URI into list but not using");
16867
0
            if (GetLength(input, &idx, &strLen, sz) < 0) {
16868
0
                WOLFSSL_MSG("\tfail: str length");
16869
0
                return ASN_PARSE_E;
16870
0
            }
16871
0
            length -= (idx - lenStartIdx);
16872
16873
            /* check that strLen at index is not past input buffer */
16874
0
            if (strLen + (int)idx > sz) {
16875
0
                return BUFFER_E;
16876
0
            }
16877
16878
0
        #if !defined(WOLFSSL_NO_ASN_STRICT) && !defined(WOLFSSL_FPKI)
16879
            /* Verify RFC 5280 Sec 4.2.1.6 rule:
16880
                "The name MUST NOT be a relative URI" */
16881
16882
0
            {
16883
0
                int i;
16884
16885
                /* skip past scheme (i.e http,ftp,...) finding first ':' char */
16886
0
                for (i = 0; i < strLen; i++) {
16887
0
                    if (input[idx + i] == ':') {
16888
0
                        break;
16889
0
                    }
16890
0
                    if (input[idx + i] == '/') {
16891
0
                        WOLFSSL_MSG("\tAlt Name must be absolute URI");
16892
0
                        WOLFSSL_ERROR_VERBOSE(ASN_ALT_NAME_E);
16893
0
                        return ASN_ALT_NAME_E;
16894
0
                    }
16895
0
                }
16896
16897
                /* test if no ':' char was found and test that the next two
16898
                 * chars are "//" to match the pattern "://" */
16899
0
                if (i >= strLen - 2 || (input[idx + i + 1] != '/' ||
16900
0
                                        input[idx + i + 2] != '/')) {
16901
0
                    WOLFSSL_MSG("\tAlt Name must be absolute URI");
16902
0
                    WOLFSSL_ERROR_VERBOSE(ASN_ALT_NAME_E);
16903
0
                    return ASN_ALT_NAME_E;
16904
0
                }
16905
0
            }
16906
0
        #endif
16907
16908
0
            uriEntry = AltNameNew(cert->heap);
16909
0
            if (uriEntry == NULL) {
16910
0
                WOLFSSL_MSG("\tOut of Memory");
16911
0
                return MEMORY_E;
16912
0
            }
16913
16914
0
            uriEntry->type = ASN_URI_TYPE;
16915
0
            uriEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
16916
0
                                         DYNAMIC_TYPE_ALTNAME);
16917
0
            if (uriEntry->name == NULL) {
16918
0
                WOLFSSL_MSG("\tOut of Memory");
16919
0
                XFREE(uriEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
16920
0
                return MEMORY_E;
16921
0
            }
16922
0
            uriEntry->len = strLen;
16923
0
            XMEMCPY(uriEntry->name, &input[idx], strLen);
16924
0
            uriEntry->name[strLen] = '\0';
16925
16926
0
            AddAltName(cert, uriEntry);
16927
16928
0
            length -= strLen;
16929
0
            idx    += strLen;
16930
0
        }
16931
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
16932
        else if (b == (ASN_CONTEXT_SPECIFIC | ASN_IP_TYPE)) {
16933
            DNS_entry* ipAddr;
16934
            int strLen;
16935
            word32 lenStartIdx = idx;
16936
            WOLFSSL_MSG("Decoding Subject Alt. Name: IP Address");
16937
16938
            if (GetLength(input, &idx, &strLen, sz) < 0) {
16939
                WOLFSSL_MSG("\tfail: str length");
16940
                return ASN_PARSE_E;
16941
            }
16942
            length -= (idx - lenStartIdx);
16943
            /* check that strLen at index is not past input buffer */
16944
            if (strLen + (int)idx > sz) {
16945
                return BUFFER_E;
16946
            }
16947
16948
            ipAddr = AltNameNew(cert->heap);
16949
            if (ipAddr == NULL) {
16950
                WOLFSSL_MSG("\tOut of Memory");
16951
                return MEMORY_E;
16952
            }
16953
16954
            ipAddr->type = ASN_IP_TYPE;
16955
            ipAddr->name = (char*)XMALLOC(strLen + 1, cert->heap,
16956
                                         DYNAMIC_TYPE_ALTNAME);
16957
            if (ipAddr->name == NULL) {
16958
                WOLFSSL_MSG("\tOut of Memory");
16959
                XFREE(ipAddr, cert->heap, DYNAMIC_TYPE_ALTNAME);
16960
                return MEMORY_E;
16961
            }
16962
            ipAddr->len = strLen;
16963
            XMEMCPY(ipAddr->name, &input[idx], strLen);
16964
            ipAddr->name[strLen] = '\0';
16965
16966
        #if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
16967
            if (GenerateDNSEntryIPString(ipAddr, cert->heap) != 0) {
16968
                WOLFSSL_MSG("\tOut of Memory for IP string");
16969
                XFREE(ipAddr->name, cert->heap, DYNAMIC_TYPE_ALTNAME);
16970
                XFREE(ipAddr, cert->heap, DYNAMIC_TYPE_ALTNAME);
16971
                return MEMORY_E;
16972
            }
16973
        #endif /* OPENSSL_ALL || WOLFSSL_IP_ALT_NAME */
16974
            AddAltName(cert, ipAddr);
16975
16976
            length -= strLen;
16977
            idx    += strLen;
16978
        }
16979
#endif /* WOLFSSL_QT || OPENSSL_ALL */
16980
0
#endif /* IGNORE_NAME_CONSTRAINTS */
16981
0
        else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE))
16982
0
        {
16983
0
            int strLen;
16984
0
            word32 lenStartIdx = idx;
16985
0
            word32 oid = 0;
16986
0
            int    ret;
16987
16988
0
            if (GetLength(input, &idx, &strLen, sz) < 0) {
16989
0
                WOLFSSL_MSG("\tfail: other name length");
16990
0
                return ASN_PARSE_E;
16991
0
            }
16992
            /* Consume the rest of this sequence. */
16993
0
            length -= (strLen + idx - lenStartIdx);
16994
16995
0
            if (GetObjectId(input, &idx, &oid, oidCertAltNameType, sz) < 0) {
16996
0
                WOLFSSL_MSG("\tbad OID");
16997
0
                return ASN_PARSE_E;
16998
0
            }
16999
17000
            /* handle parsing other type alt names */
17001
0
            switch (oid) {
17002
            #ifdef WOLFSSL_SEP
17003
                case HW_NAME_OID:
17004
                    ret = DecodeSepHwAltName(cert, input, &idx, sz);
17005
                    if (ret != 0)
17006
                        return ret;
17007
                    break;
17008
            #endif /* WOLFSSL_SEP */
17009
            #ifdef WOLFSSL_FPKI
17010
                case FASCN_OID:
17011
                case UPN_OID:
17012
                    ret = DecodeConstructedOtherName(cert, input, &idx, sz,
17013
                            oid);
17014
                    if (ret != 0)
17015
                        return ret;
17016
                    break;
17017
            #endif /* WOLFSSL_FPKI */
17018
17019
0
                default:
17020
0
                    WOLFSSL_MSG("\tUnsupported other name type, skipping");
17021
0
                    if (GetLength(input, &idx, &strLen, sz) < 0) {
17022
                        /* check to skip constructed other names too */
17023
0
                        if (DecodeConstructedOtherName(cert, input, &idx, sz,
17024
0
                                    oid) != 0) {
17025
0
                            WOLFSSL_MSG("\tfail: unsupported other name length");
17026
0
                            return ASN_PARSE_E;
17027
0
                        }
17028
0
                        else {
17029
                            /* idx will have been advanced to end of alt name */
17030
0
                            length -= (idx - lenStartIdx);
17031
0
                        }
17032
0
                    }
17033
0
                    else {
17034
0
                        length -= (strLen + idx - lenStartIdx);
17035
0
                        idx += strLen;
17036
0
                    }
17037
0
            }
17038
0
            (void)ret;
17039
0
        }
17040
0
        else {
17041
0
            int strLen;
17042
0
            word32 lenStartIdx = idx;
17043
17044
0
            WOLFSSL_MSG("\tUnsupported name type, skipping");
17045
17046
0
            if (GetLength(input, &idx, &strLen, sz) < 0) {
17047
0
                WOLFSSL_MSG("\tfail: unsupported name length");
17048
0
                return ASN_PARSE_E;
17049
0
            }
17050
0
            length -= (strLen + idx - lenStartIdx);
17051
0
            idx += strLen;
17052
0
        }
17053
0
    }
17054
17055
0
    return 0;
17056
#else
17057
    word32 idx = 0;
17058
    int length = 0;
17059
    int ret = 0;
17060
17061
    WOLFSSL_ENTER("DecodeAltNames");
17062
17063
    /* Get SEQUENCE and expect all data to be accounted for. */
17064
    if (GetASN_Sequence(input, &idx, &length, sz, 1) != 0) {
17065
        WOLFSSL_MSG("\tBad Sequence");
17066
        ret = ASN_PARSE_E;
17067
    }
17068
17069
    if ((ret == 0) && (length == 0)) {
17070
        /* RFC 5280 4.2.1.6.  Subject Alternative Name
17071
           If the subjectAltName extension is present, the sequence MUST
17072
           contain at least one entry. */
17073
        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
17074
        ret = ASN_PARSE_E;
17075
    }
17076
    if (ret == 0) {
17077
    #ifdef OPENSSL_ALL
17078
        cert->extSubjAltNameSrc = input;
17079
        cert->extSubjAltNameSz = sz;
17080
    #endif
17081
17082
        cert->weOwnAltNames = 1;
17083
17084
        if (length + (int)idx != sz) {
17085
            ret = ASN_PARSE_E;
17086
        }
17087
    }
17088
17089
    while ((ret == 0) && ((int)idx < sz)) {
17090
        ASNGetData dataASN[altNameASN_Length];
17091
17092
        /* Clear dynamic data items. */
17093
        XMEMSET(dataASN, 0, sizeof(dataASN));
17094
        /* Parse GeneralName with the choices supported. */
17095
        GetASN_Choice(&dataASN[ALTNAMEASN_IDX_GN], generalNameChoice);
17096
        /* Decode a GeneralName choice. */
17097
        ret = GetASN_Items(altNameASN, dataASN, altNameASN_Length, 0, input,
17098
                           &idx, sz);
17099
        if (ret == 0) {
17100
            ret = DecodeGeneralName(input, &idx, dataASN[ALTNAMEASN_IDX_GN].tag,
17101
                dataASN[ALTNAMEASN_IDX_GN].length, cert);
17102
        }
17103
    }
17104
17105
    return ret;
17106
#endif
17107
0
}
17108
17109
#ifdef WOLFSSL_ASN_TEMPLATE
17110
/* ASN.1 template for BasicContraints.
17111
 * X.509: RFC 5280, 4.2.1.9 - BasicConstraints.
17112
 */
17113
static const ASNItem basicConsASN[] = {
17114
/* SEQ  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
17115
/* CA   */     { 1, ASN_BOOLEAN, 0, 0, 1 },
17116
/* PLEN */     { 1, ASN_INTEGER, 0, 0, 1 }
17117
};
17118
enum {
17119
    BASICCONSASN_IDX_SEQ = 0,
17120
    BASICCONSASN_IDX_CA,
17121
    BASICCONSASN_IDX_PLEN,
17122
};
17123
17124
/* Number of items in ASN.1 template for BasicContraints. */
17125
#define basicConsASN_Length (sizeof(basicConsASN) / sizeof(ASNItem))
17126
#endif
17127
17128
/* Decode basic constraints extension in a certificate.
17129
 *
17130
 * X.509: RFC 5280, 4.2.1.9 - BasicConstraints.
17131
 *
17132
 * @param [in]      input  Buffer holding data.
17133
 * @param [in]      sz     Size of data in buffer.
17134
 * @param [in, out] cert   Certificate object.
17135
 * @return  0 on success.
17136
 * @return  MEMORY_E on dynamic memory allocation failure.
17137
 * @return  ASN_PARSE_E when CA boolean is present and false (default is false).
17138
 * @return  ASN_PARSE_E when CA boolean is not present unless
17139
 *          WOLFSSL_X509_BASICCONS_INT is defined. Only a CA extension.
17140
 * @return  ASN_PARSE_E when path length more than 7 bits.
17141
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
17142
 *          is invalid.
17143
 * @return  BUFFER_E when data in buffer is too small.
17144
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
17145
 *          non-zero length.
17146
 */
17147
static int DecodeBasicCaConstraint(const byte* input, int sz, DecodedCert* cert)
17148
0
{
17149
0
#ifndef WOLFSSL_ASN_TEMPLATE
17150
0
    word32 idx = 0;
17151
0
    int length = 0;
17152
0
    int ret;
17153
17154
0
    WOLFSSL_ENTER("DecodeBasicCaConstraint");
17155
17156
0
    if (GetSequence(input, &idx, &length, sz) < 0) {
17157
0
        WOLFSSL_MSG("\tfail: bad SEQUENCE");
17158
0
        return ASN_PARSE_E;
17159
0
    }
17160
17161
0
    if (length == 0)
17162
0
        return 0;
17163
17164
    /* If the basic ca constraint is false, this extension may be named, but
17165
     * left empty. So, if the length is 0, just return. */
17166
17167
0
    ret = GetBoolean(input, &idx, sz);
17168
17169
    /* Removed logic for WOLFSSL_X509_BASICCONS_INT which was mistreating the
17170
     * pathlen value as if it were the CA Boolean value 7/2/2021 - KH.
17171
     * When CA Boolean not asserted use the default value "False" */
17172
0
    if (ret < 0) {
17173
0
        WOLFSSL_MSG("\tfail: constraint not valid BOOLEAN, set default FALSE");
17174
0
        ret = 0;
17175
0
    }
17176
17177
0
    cert->isCA = (byte)ret;
17178
17179
    /* If there isn't any more data, return. */
17180
0
    if (idx >= (word32)sz) {
17181
0
        return 0;
17182
0
    }
17183
17184
0
    ret = GetInteger7Bit(input, &idx, sz);
17185
0
    if (ret < 0)
17186
0
        return ret;
17187
0
    cert->pathLength = (byte)ret;
17188
0
    cert->pathLengthSet = 1;
17189
17190
0
    return 0;
17191
#else
17192
    DECL_ASNGETDATA(dataASN, basicConsASN_Length);
17193
    int ret = 0;
17194
    word32 idx = 0;
17195
    byte isCA = 0;
17196
17197
    WOLFSSL_ENTER("DecodeBasicCaConstraints");
17198
17199
    CALLOC_ASNGETDATA(dataASN, basicConsASN_Length, ret, cert->heap);
17200
17201
    if (ret == 0) {
17202
        /* Get the CA boolean and path length when present. */
17203
        GetASN_Boolean(&dataASN[BASICCONSASN_IDX_CA], &isCA);
17204
        GetASN_Int8Bit(&dataASN[BASICCONSASN_IDX_PLEN], &cert->pathLength);
17205
17206
        ret = GetASN_Items(basicConsASN, dataASN, basicConsASN_Length, 1, input,
17207
                           &idx, sz);
17208
    }
17209
17210
    /* Empty SEQUENCE is OK - nothing to store. */
17211
    if ((ret == 0) && (dataASN[BASICCONSASN_IDX_SEQ].length != 0)) {
17212
        /* Bad encoding when CA Boolean is false
17213
         * (default when not present). */
17214
        if ((dataASN[BASICCONSASN_IDX_CA].length != 0) && (!isCA)) {
17215
            WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
17216
            ret = ASN_PARSE_E;
17217
        }
17218
        /* Path length must be a 7-bit value. */
17219
        if ((ret == 0) && (cert->pathLength >= (1 << 7))) {
17220
            WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
17221
            ret = ASN_PARSE_E;
17222
        }
17223
        /* Store CA boolean and whether a path length was seen. */
17224
        if (ret == 0) {
17225
            /* isCA in certificate is a 1 bit of a byte. */
17226
            cert->isCA = isCA;
17227
            cert->pathLengthSet = (dataASN[BASICCONSASN_IDX_PLEN].length > 0);
17228
        }
17229
    }
17230
17231
    FREE_ASNGETDATA(dataASN, cert->heap);
17232
    return ret;
17233
#endif
17234
0
}
17235
17236
17237
static int DecodePolicyConstraints(const byte* input, int sz, DecodedCert* cert)
17238
0
{
17239
0
    word32 idx = 0;
17240
0
    int length = 0;
17241
0
    int skipLength = 0;
17242
0
    int ret;
17243
0
    byte tag;
17244
17245
0
    WOLFSSL_ENTER("DecodePolicyConstraints");
17246
17247
0
    if (GetSequence(input, &idx, &length, sz) < 0) {
17248
0
        WOLFSSL_MSG("\tfail: bad SEQUENCE");
17249
0
        return ASN_PARSE_E;
17250
0
    }
17251
17252
0
    if (length == 0)
17253
0
        return ASN_PARSE_E;
17254
17255
0
    if (GetASNTag(input, &idx, &tag, sz) < 0) {
17256
0
        WOLFSSL_MSG("\tfail: bad TAG");
17257
0
        return ASN_PARSE_E;
17258
0
    }
17259
17260
0
    if (tag == (ASN_CONTEXT_SPECIFIC | 0)) {
17261
        /* requireExplicitPolicy */
17262
0
        cert->extPolicyConstRxpSet = 1;
17263
0
    }
17264
0
    else if (tag == (ASN_CONTEXT_SPECIFIC | 1)) {
17265
        /* inhibitPolicyMapping */
17266
0
        cert->extPolicyConstIpmSet = 1;
17267
0
    }
17268
0
    else {
17269
0
        WOLFSSL_MSG("\tfail: invalid TAG");
17270
0
        return ASN_PARSE_E;
17271
0
    }
17272
17273
0
    ret = GetLength(input, &idx, &skipLength, sz);
17274
0
    if (ret < 0) {
17275
0
        WOLFSSL_MSG("\tfail: invalid length");
17276
0
        return ret;
17277
0
    }
17278
0
    if (skipLength > 1) {
17279
0
        WOLFSSL_MSG("\tfail: skip value too big");
17280
0
        return BUFFER_E;
17281
0
    }
17282
0
    if (idx >= (word32)sz) {
17283
0
        WOLFSSL_MSG("\tfail: no policy const skip to read");
17284
0
        return BUFFER_E;
17285
0
    }
17286
0
    cert->policyConstSkip = input[idx];
17287
17288
0
    return 0;
17289
0
}
17290
17291
17292
/* Context-Specific value for: DistributionPoint.distributionPoint
17293
 * From RFC5280 SS4.2.1.13, Distribution Point */
17294
0
#define DISTRIBUTION_POINT  (ASN_CONTEXT_SPECIFIC | 0)
17295
/* Context-Specific value for: DistributionPoint.DistributionPointName.fullName
17296
 *  From RFC3280 SS4.2.1.13, Distribution Point Name */
17297
0
#define CRLDP_FULL_NAME     (ASN_CONTEXT_SPECIFIC | 0)
17298
/* Context-Specific value for choice: GeneralName.uniformResourceIdentifier
17299
 * From RFC3280 SS4.2.1.7, GeneralName */
17300
0
#define GENERALNAME_URI     (ASN_CONTEXT_SPECIFIC | 6)
17301
17302
#ifdef WOLFSSL_ASN_TEMPLATE
17303
/* ASN.1 template for CRL distribution points.
17304
 * X.509: RFC 5280, 4.2.1.13 - CRL Distribution Points.
17305
 */
17306
static const ASNItem crlDistASN[] = {
17307
/* SEQ                */ { 0, ASN_SEQUENCE, 1, 1, 0 },
17308
/* DP_SEQ             */     { 1, ASN_SEQUENCE, 1, 1, 0 },
17309
                                                /* Distribution point name */
17310
/* DP_DISTPOINT       */         { 2, DISTRIBUTION_POINT, 1, 1, 1 },
17311
                                                    /* fullName */
17312
/* DP_DISTPOINT_FN    */             { 3, CRLDP_FULL_NAME, 1, 1, 2 },
17313
/* DP_DISTPOINT_FN_GN */                 { 4, GENERALNAME_URI, 0, 0, 0 },
17314
                                                    /* nameRelativeToCRLIssuer */
17315
/* DP_DISTPOINT_RN    */             { 3, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 2 },
17316
                                                /* reasons: IMPLICIT BIT STRING */
17317
/* DP_REASONS         */         { 2, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 1 },
17318
                                                /* cRLIssuer */
17319
/* DP_CRLISSUER       */         { 2, ASN_CONTEXT_SPECIFIC | 2, 1, 0, 1 },
17320
};
17321
enum {
17322
    CRLDISTASN_IDX_SEQ = 0,
17323
    CRLDISTASN_IDX_DP_SEQ,
17324
    CRLDISTASN_IDX_DP_DISTPOINT,
17325
    CRLDISTASN_IDX_DP_DISTPOINT_FN,
17326
    CRLDISTASN_IDX_DP_DISTPOINT_FN_GN,
17327
    CRLDISTASN_IDX_DP_DISTPOINT_RN, /* Relative name */
17328
    CRLDISTASN_IDX_DP_REASONS,
17329
    CRLDISTASN_IDX_DP_CRLISSUER,
17330
};
17331
17332
/* Number of items in ASN.1 template for CRL distribution points. */
17333
#define crlDistASN_Length (sizeof(crlDistASN) / sizeof(ASNItem))
17334
#endif
17335
17336
/* Decode CRL distribution point extension in a certificate.
17337
 *
17338
 * X.509: RFC 5280, 4.2.1.13 - CRL Distribution Points.
17339
 *
17340
 * @param [in]      input  Buffer holding data.
17341
 * @param [in]      sz     Size of data in buffer.
17342
 * @param [in, out] cert   Certificate object.
17343
 * @return  0 on success.
17344
 * @return  MEMORY_E on dynamic memory allocation failure.
17345
 * @return  ASN_PARSE_E when invalid bits of reason are set.
17346
 * @return  ASN_PARSE_E when BITSTRING value is more than 2 bytes.
17347
 * @return  ASN_PARSE_E when unused bits of BITSTRING is invalid.
17348
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
17349
 *          is invalid.
17350
 * @return  BUFFER_E when data in buffer is too small.
17351
 */
17352
static int DecodeCrlDist(const byte* input, int sz, DecodedCert* cert)
17353
0
{
17354
0
#ifndef WOLFSSL_ASN_TEMPLATE
17355
0
    word32 idx = 0, localIdx;
17356
0
    int length = 0;
17357
0
    byte tag   = 0;
17358
17359
0
    WOLFSSL_ENTER("DecodeCrlDist");
17360
17361
0
    cert->extCrlInfoRaw = input;
17362
0
    cert->extCrlInfoRawSz = sz;
17363
17364
    /* Unwrap the list of Distribution Points*/
17365
0
    if (GetSequence(input, &idx, &length, sz) < 0)
17366
0
        return ASN_PARSE_E;
17367
17368
    /* Unwrap a single Distribution Point */
17369
0
    if (GetSequence(input, &idx, &length, sz) < 0)
17370
0
        return ASN_PARSE_E;
17371
17372
    /* The Distribution Point has three explicit optional members
17373
     *  First check for a DistributionPointName
17374
     */
17375
0
    localIdx = idx;
17376
0
    if (GetASNTag(input, &localIdx, &tag, sz) == 0 &&
17377
0
            tag == (ASN_CONSTRUCTED | DISTRIBUTION_POINT))
17378
0
    {
17379
0
        idx++;
17380
0
        if (GetLength(input, &idx, &length, sz) < 0)
17381
0
            return ASN_PARSE_E;
17382
17383
0
        localIdx = idx;
17384
0
        if (GetASNTag(input, &localIdx, &tag, sz) == 0 &&
17385
0
                tag == (ASN_CONSTRUCTED | CRLDP_FULL_NAME))
17386
0
        {
17387
0
            idx++;
17388
0
            if (GetLength(input, &idx, &length, sz) < 0)
17389
0
                return ASN_PARSE_E;
17390
17391
0
            localIdx = idx;
17392
0
            if (GetASNTag(input, &localIdx, &tag, sz) == 0 &&
17393
0
                    tag == GENERALNAME_URI)
17394
0
            {
17395
0
                idx++;
17396
0
                if (GetLength(input, &idx, &length, sz) < 0)
17397
0
                    return ASN_PARSE_E;
17398
17399
0
                cert->extCrlInfoSz = length;
17400
0
                cert->extCrlInfo = input + idx;
17401
0
                idx += length;
17402
0
            }
17403
0
            else
17404
                /* This isn't a URI, skip it. */
17405
0
                idx += length;
17406
0
        }
17407
0
        else {
17408
            /* This isn't a FULLNAME, skip it. */
17409
0
            idx += length;
17410
0
        }
17411
0
    }
17412
17413
    /* Check for reasonFlags */
17414
0
    localIdx = idx;
17415
0
    if (idx < (word32)sz &&
17416
0
        GetASNTag(input, &localIdx, &tag, sz) == 0 &&
17417
0
        tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
17418
0
    {
17419
0
        idx++;
17420
0
        if (GetLength(input, &idx, &length, sz) < 0)
17421
0
            return ASN_PARSE_E;
17422
0
        idx += length;
17423
0
    }
17424
17425
    /* Check for cRLIssuer */
17426
0
    localIdx = idx;
17427
0
    if (idx < (word32)sz &&
17428
0
        GetASNTag(input, &localIdx, &tag, sz) == 0 &&
17429
0
        tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2))
17430
0
    {
17431
0
        idx++;
17432
0
        if (GetLength(input, &idx, &length, sz) < 0)
17433
0
            return ASN_PARSE_E;
17434
0
        idx += length;
17435
0
    }
17436
17437
0
    if (idx < (word32)sz)
17438
0
    {
17439
0
        WOLFSSL_MSG("\tThere are more CRL Distribution Point records, "
17440
0
                   "but we only use the first one.");
17441
0
    }
17442
17443
0
    return 0;
17444
#else
17445
    DECL_ASNGETDATA(dataASN, crlDistASN_Length);
17446
    word32 idx = 0;
17447
    int ret = 0;
17448
#ifdef CRLDP_VALIDATE_DATA
17449
    word16 reason;
17450
#endif
17451
17452
    WOLFSSL_ENTER("DecodeCrlDist");
17453
17454
    CALLOC_ASNGETDATA(dataASN, crlDistASN_Length, ret, cert->heap);
17455
17456
    cert->extCrlInfoRaw = input;
17457
    cert->extCrlInfoRawSz = sz;
17458
17459
    if  (ret == 0) {
17460
        /* Get the GeneralName choice */
17461
        GetASN_Choice(&dataASN[CRLDISTASN_IDX_DP_DISTPOINT_FN_GN], generalNameChoice);
17462
        /* Parse CRL distribtion point. */
17463
        ret = GetASN_Items(crlDistASN, dataASN, crlDistASN_Length, 0, input,
17464
                           &idx, sz);
17465
    }
17466
    if (ret == 0) {
17467
        /* If the choice was a URI, store it in certificate. */
17468
        if (dataASN[CRLDISTASN_IDX_DP_DISTPOINT_FN_GN].tag == GENERALNAME_URI) {
17469
            word32 sz32;
17470
            GetASN_GetConstRef(&dataASN[CRLDISTASN_IDX_DP_DISTPOINT_FN_GN],
17471
                    &cert->extCrlInfo, &sz32);
17472
            cert->extCrlInfoSz = sz32;
17473
        }
17474
17475
    #ifdef CRLDP_VALIDATE_DATA
17476
        if (dataASN[CRLDISTASN_IDX_DP_REASONS].data.ref.data != NULL) {
17477
             /* TODO: test case */
17478
             /* Validate ReasonFlags. */
17479
             ret = GetASN_BitString_Int16Bit(&dataASN[CRLDISTASN_IDX_DP_REASONS],
17480
                     &reason);
17481
             /* First bit (LSB) unused and eight other bits defined. */
17482
             if ((ret == 0) && ((reason >> 9) || (reason & 0x01))) {
17483
                WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
17484
                ret = ASN_PARSE_E;
17485
             }
17486
        }
17487
    #endif
17488
    }
17489
17490
    /* Only parsing the first one. */
17491
    if (ret == 0 && idx < (word32)sz) {
17492
        WOLFSSL_MSG("\tThere are more CRL Distribution Point records, "
17493
                    "but we only use the first one.");
17494
    }
17495
    /* TODO: validate other points. */
17496
17497
    FREE_ASNGETDATA(dataASN, cert->heap);
17498
    return ret;
17499
#endif /* WOLFSSL_ASN_TEMPLATE */
17500
0
}
17501
17502
#ifdef WOLFSSL_ASN_TEMPLATE
17503
/* ASN.1 template for the access description.
17504
 * X.509: RFC 5280, 4.2.2.1 - Authority Information Access.
17505
 */
17506
static const ASNItem accessDescASN[] = {
17507
/* SEQ  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
17508
                                 /* accessMethod */
17509
/* METH */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
17510
                                 /* accessLocation: GeneralName */
17511
/* LOC  */     { 1, ASN_CONTEXT_SPECIFIC | 0, 0, 0, 0 },
17512
};
17513
enum {
17514
    ACCESSDESCASN_IDX_SEQ = 0,
17515
    ACCESSDESCASN_IDX_METH,
17516
    ACCESSDESCASN_IDX_LOC,
17517
};
17518
17519
/* Number of items in ASN.1 template for the access description. */
17520
#define accessDescASN_Length (sizeof(accessDescASN) / sizeof(ASNItem))
17521
#endif
17522
17523
/* Decode authority information access extension in a certificate.
17524
 *
17525
 * X.509: RFC 5280, 4.2.2.1 - Authority Information Access.
17526
 *
17527
 * @param [in]      input  Buffer holding data.
17528
 * @param [in]      sz     Size of data in buffer.
17529
 * @param [in, out] cert   Certificate object.
17530
 * @return  0 on success.
17531
 * @return  MEMORY_E on dynamic memory allocation failure.
17532
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
17533
 *          is invalid.
17534
 * @return  BUFFER_E when data in buffer is too small.
17535
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
17536
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
17537
 */
17538
static int DecodeAuthInfo(const byte* input, int sz, DecodedCert* cert)
17539
0
{
17540
0
#ifndef WOLFSSL_ASN_TEMPLATE
17541
0
    word32 idx = 0;
17542
0
    int length = 0;
17543
0
    int count  = 0;
17544
0
    byte b = 0;
17545
0
    word32 oid;
17546
17547
0
    WOLFSSL_ENTER("DecodeAuthInfo");
17548
17549
    /* Unwrap the list of AIAs */
17550
0
    if (GetSequence(input, &idx, &length, sz) < 0)
17551
0
        return ASN_PARSE_E;
17552
17553
0
    while ((idx < (word32)sz) && (count < MAX_AIA_SZ)) {
17554
        /* Unwrap a single AIA */
17555
0
        if (GetSequence(input, &idx, &length, sz) < 0)
17556
0
            return ASN_PARSE_E;
17557
17558
0
        oid = 0;
17559
0
        if (GetObjectId(input, &idx, &oid, oidCertAuthInfoType, sz) < 0) {
17560
0
            return ASN_PARSE_E;
17561
0
        }
17562
17563
        /* Only supporting URIs right now. */
17564
0
        if (GetASNTag(input, &idx, &b, sz) < 0)
17565
0
            return ASN_PARSE_E;
17566
17567
0
        if (GetLength(input, &idx, &length, sz) < 0)
17568
0
            return ASN_PARSE_E;
17569
17570
        /* Set ocsp entry */
17571
0
        if (b == GENERALNAME_URI && oid == AIA_OCSP_OID)
17572
0
        {
17573
0
            cert->extAuthInfoSz = length;
17574
0
            cert->extAuthInfo = input + idx;
17575
        #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
17576
            count++;
17577
        #else
17578
0
            break;
17579
0
        #endif
17580
0
        }
17581
        #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
17582
        /* Set CaIssuers entry */
17583
        else if ((b == GENERALNAME_URI) && oid == AIA_CA_ISSUER_OID)
17584
        {
17585
            cert->extAuthInfoCaIssuerSz = length;
17586
            cert->extAuthInfoCaIssuer = input + idx;
17587
            count++;
17588
        }
17589
        #endif
17590
0
        idx += length;
17591
0
    }
17592
17593
0
    return 0;
17594
#else
17595
    word32 idx = 0;
17596
    int length = 0;
17597
    int count  = 0;
17598
    int ret    = 0;
17599
17600
    WOLFSSL_ENTER("DecodeAuthInfo");
17601
17602
    /* Unwrap the list of AIAs */
17603
    if (GetASN_Sequence(input, &idx, &length, sz, 1) < 0) {
17604
        ret = ASN_PARSE_E;
17605
    }
17606
17607
    while ((ret == 0) && (idx < (word32)sz) && (count < MAX_AIA_SZ)) {
17608
        ASNGetData dataASN[accessDescASN_Length];
17609
        word32 sz32;
17610
17611
        /* Clear dynamic data and retrieve OID and name. */
17612
        XMEMSET(dataASN, 0, sizeof(dataASN));
17613
        GetASN_OID(&dataASN[ACCESSDESCASN_IDX_METH], oidCertAuthInfoType);
17614
        GetASN_Choice(&dataASN[ACCESSDESCASN_IDX_LOC], generalNameChoice);
17615
        /* Parse AccessDescription. */
17616
        ret = GetASN_Items(accessDescASN, dataASN, accessDescASN_Length, 0,
17617
                           input, &idx, sz);
17618
        if (ret == 0) {
17619
            /* Check we have OCSP and URI. */
17620
            if ((dataASN[ACCESSDESCASN_IDX_METH].data.oid.sum == AIA_OCSP_OID) &&
17621
                    (dataASN[ACCESSDESCASN_IDX_LOC].tag == GENERALNAME_URI)) {
17622
                /* Store URI for OCSP lookup. */
17623
                GetASN_GetConstRef(&dataASN[ACCESSDESCASN_IDX_LOC],
17624
                        &cert->extAuthInfo, &sz32);
17625
                cert->extAuthInfoSz = sz32;
17626
                count++;
17627
            #if !defined(OPENSSL_ALL) || !defined(WOLFSSL_QT)
17628
                break;
17629
            #endif
17630
            }
17631
            #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
17632
            /* Check we have CA Issuer and URI. */
17633
            else if ((dataASN[ACCESSDESCASN_IDX_METH].data.oid.sum ==
17634
                        AIA_CA_ISSUER_OID) &&
17635
                    (dataASN[ACCESSDESCASN_IDX_LOC].tag == GENERALNAME_URI)) {
17636
                /* Set CaIssuers entry */
17637
                GetASN_GetConstRef(&dataASN[ACCESSDESCASN_IDX_LOC],
17638
                        &cert->extAuthInfoCaIssuer, &sz32);
17639
                cert->extAuthInfoCaIssuerSz = sz32;
17640
                count++;
17641
            }
17642
            #endif
17643
            /* Otherwise skip. */
17644
        }
17645
    }
17646
17647
    return ret;
17648
#endif
17649
0
}
17650
17651
17652
#ifdef WOLFSSL_ASN_TEMPLATE
17653
/* ASN.1 template for AuthorityKeyIdentifier.
17654
 * X.509: RFC 5280, 4.2.1.1 - Authority Key Identifier.
17655
 */
17656
static const ASNItem authKeyIdASN[] = {
17657
/* SEQ    */    { 0, ASN_SEQUENCE, 1, 1, 0 },
17658
                                     /* keyIdentifier */
17659
/* KEYID  */        { 1, ASN_CONTEXT_SPECIFIC | ASN_AUTHKEYID_KEYID, 0, 0, 1 },
17660
                                     /* authorityCertIssuer */
17661
/* ISSUER */        { 1, ASN_CONTEXT_SPECIFIC | ASN_AUTHKEYID_ISSUER, 1, 0, 1 },
17662
                                     /* authorityCertSerialNumber */
17663
/* SERIAL */        { 1, ASN_CONTEXT_SPECIFIC | ASN_AUTHKEYID_SERIAL, 0, 0, 1 },
17664
};
17665
enum {
17666
    AUTHKEYIDASN_IDX_SEQ = 0,
17667
    AUTHKEYIDASN_IDX_KEYID,
17668
    AUTHKEYIDASN_IDX_ISSUER,
17669
    AUTHKEYIDASN_IDX_SERIAL,
17670
};
17671
17672
/* Number of items in ASN.1 template for AuthorityKeyIdentifier. */
17673
#define authKeyIdASN_Length (sizeof(authKeyIdASN) / sizeof(ASNItem))
17674
#endif
17675
17676
/* Decode authority information access extension in a certificate.
17677
 *
17678
 * X.509: RFC 5280, 4.2.2.1 - Authority Information Access.
17679
 *
17680
 * @param [in]      input  Buffer holding data.
17681
 * @param [in]      sz     Size of data in buffer.
17682
 * @param [in, out] cert   Certificate object.
17683
 * @return  0 on success.
17684
 * @return  MEMORY_E on dynamic memory allocation failure.
17685
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
17686
 *          is invalid.
17687
 * @return  BUFFER_E when data in buffer is too small.
17688
 */
17689
static int DecodeAuthKeyId(const byte* input, int sz, DecodedCert* cert)
17690
0
{
17691
0
#ifndef WOLFSSL_ASN_TEMPLATE
17692
0
    word32 idx = 0;
17693
0
    int length = 0;
17694
0
    byte tag;
17695
17696
0
    WOLFSSL_ENTER("DecodeAuthKeyId");
17697
17698
0
    if (GetSequence(input, &idx, &length, sz) < 0) {
17699
0
        WOLFSSL_MSG("\tfail: should be a SEQUENCE");
17700
0
        return ASN_PARSE_E;
17701
0
    }
17702
17703
0
    if (GetASNTag(input, &idx, &tag, sz) < 0) {
17704
0
        return ASN_PARSE_E;
17705
0
    }
17706
17707
0
    if (tag != (ASN_CONTEXT_SPECIFIC | 0)) {
17708
0
        WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available");
17709
0
        cert->extAuthKeyIdSet = 0;
17710
0
        return 0;
17711
0
    }
17712
17713
0
    if (GetLength(input, &idx, &length, sz) <= 0) {
17714
0
        WOLFSSL_MSG("\tfail: extension data length");
17715
0
        return ASN_PARSE_E;
17716
0
    }
17717
17718
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
17719
#ifdef WOLFSSL_AKID_NAME
17720
    cert->extRawAuthKeyIdSrc = input;
17721
    cert->extRawAuthKeyIdSz = sz;
17722
#endif
17723
    cert->extAuthKeyIdSrc = &input[idx];
17724
    cert->extAuthKeyIdSz = length;
17725
#endif /* OPENSSL_EXTRA */
17726
17727
0
    return GetHashId(input + idx, length, cert->extAuthKeyId);
17728
#else
17729
    DECL_ASNGETDATA(dataASN, authKeyIdASN_Length);
17730
    int ret = 0;
17731
    word32 idx = 0;
17732
17733
    WOLFSSL_ENTER("DecodeAuthKeyId");
17734
17735
    CALLOC_ASNGETDATA(dataASN, authKeyIdASN_Length, ret, cert->heap);
17736
17737
    if (ret == 0) {
17738
        /* Parse an authority key identifier. */
17739
        ret = GetASN_Items(authKeyIdASN, dataASN, authKeyIdASN_Length, 1, input,
17740
                           &idx, sz);
17741
    }
17742
    if (ret == 0) {
17743
        /* Key id is optional. */
17744
        if (dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data == NULL) {
17745
            WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available");
17746
        }
17747
        else {
17748
#ifdef OPENSSL_EXTRA
17749
            /* Store the authority key id. */
17750
#ifdef WOLFSSL_AKID_NAME
17751
            cert->extRawAuthKeyIdSrc = input;
17752
            cert->extRawAuthKeyIdSz = sz;
17753
#endif
17754
            GetASN_GetConstRef(&dataASN[AUTHKEYIDASN_IDX_KEYID], &cert->extAuthKeyIdSrc,
17755
                               &cert->extAuthKeyIdSz);
17756
#endif /* OPENSSL_EXTRA */
17757
17758
            /* Get the hash or hash of the hash if wrong size. */
17759
            ret = GetHashId(dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data,
17760
                        dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.length,
17761
                        cert->extAuthKeyId);
17762
        }
17763
    }
17764
17765
    FREE_ASNGETDATA(dataASN, cert->heap);
17766
    return ret;
17767
#endif /* WOLFSSL_ASN_TEMPLATE */
17768
0
}
17769
17770
/* Decode subject key id extension in a certificate.
17771
 *
17772
 * X.509: RFC 5280, 4.2.2.1 - Authority Information Access.
17773
 *
17774
 * @param [in]      input  Buffer holding data.
17775
 * @param [in]      sz     Size of data in buffer.
17776
 * @param [in, out] cert   Certificate object.
17777
 * @return  0 on success.
17778
 * @return  ASN_PARSE_E when the OCTET_STRING tag is not found or length is
17779
 *          invalid.
17780
 * @return  MEMORY_E on dynamic memory allocation failure.
17781
 */
17782
static int DecodeSubjKeyId(const byte* input, int sz, DecodedCert* cert)
17783
0
{
17784
0
    word32 idx = 0;
17785
0
    int length = 0;
17786
0
    int ret = 0;
17787
17788
0
    WOLFSSL_ENTER("DecodeSubjKeyId");
17789
17790
0
    if (sz <= 0) {
17791
0
        ret = ASN_PARSE_E;
17792
0
    }
17793
0
    if (ret == 0) {
17794
0
        ret = GetOctetString(input, &idx, &length, sz);
17795
0
    }
17796
0
    if (ret > 0) {
17797
    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
17798
        cert->extSubjKeyIdSrc = &input[idx];
17799
        cert->extSubjKeyIdSz = length;
17800
    #endif /* OPENSSL_EXTRA */
17801
17802
        /* Get the hash or hash of the hash if wrong size. */
17803
0
        ret = GetHashId(input + idx, length, cert->extSubjKeyId);
17804
0
    }
17805
17806
0
    return ret;
17807
0
}
17808
17809
#ifdef WOLFSSL_ASN_TEMPLATE
17810
/* ASN.1 template for KeyUsage.
17811
 * X.509: RFC 5280, 4.2.1.3 - Key Usage.
17812
 */
17813
static const ASNItem keyUsageASN[] = {
17814
/* STR */ { 0, ASN_BIT_STRING, 0, 0, 0 },
17815
};
17816
enum {
17817
    KEYUSAGEASN_IDX_STR = 0,
17818
};
17819
17820
/* Number of items in ASN.1 template for KeyUsage. */
17821
#define keyUsageASN_Length (sizeof(keyUsageASN) / sizeof(ASNItem))
17822
#endif
17823
17824
/* Decode key usage extension in a certificate.
17825
 *
17826
 * X.509: RFC 5280, 4.2.2.1 - Authority Information Access.
17827
 *
17828
 * @param [in]      input  Buffer holding data.
17829
 * @param [in]      sz     Size of data in buffer.
17830
 * @param [in, out] cert   Certificate object.
17831
 * @return  0 on success.
17832
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
17833
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
17834
 *          is invalid.
17835
 * @return  MEMORY_E on dynamic memory allocation failure.
17836
 */
17837
static int DecodeKeyUsage(const byte* input, int sz, DecodedCert* cert)
17838
0
{
17839
0
#ifndef WOLFSSL_ASN_TEMPLATE
17840
0
    word32 idx = 0;
17841
0
    int length;
17842
0
    int ret;
17843
0
    WOLFSSL_ENTER("DecodeKeyUsage");
17844
17845
0
    ret = CheckBitString(input, &idx, &length, sz, 0, NULL);
17846
0
    if (ret != 0)
17847
0
        return ret;
17848
17849
0
    if (length == 0 || length > 2)
17850
0
        return ASN_PARSE_E;
17851
17852
0
    cert->extKeyUsage = (word16)(input[idx]);
17853
0
    if (length == 2)
17854
0
        cert->extKeyUsage |= (word16)(input[idx+1] << 8);
17855
17856
0
    return 0;
17857
#else
17858
    ASNGetData dataASN[keyUsageASN_Length];
17859
    word32 idx = 0;
17860
    WOLFSSL_ENTER("DecodeKeyUsage");
17861
17862
    /* Clear dynamic data and set where to store extended key usage. */
17863
    XMEMSET(dataASN, 0, sizeof(dataASN));
17864
    GetASN_Int16Bit(&dataASN[KEYUSAGEASN_IDX_STR], &cert->extKeyUsage);
17865
    /* Parse key usage. */
17866
    return GetASN_Items(keyUsageASN, dataASN, keyUsageASN_Length, 0, input,
17867
                        &idx, sz);
17868
#endif /* WOLFSSL_ASN_TEMPLATE */
17869
0
}
17870
17871
#ifdef WOLFSSL_ASN_TEMPLATE
17872
/* ASN.1 template for KeyPurposeId.
17873
 * X.509: RFC 5280, 4.2.1.12 - Extended Key Usage.
17874
 */
17875
static const ASNItem keyPurposeIdASN[] = {
17876
/* OID */ { 0, ASN_OBJECT_ID, 0, 0, 0 },
17877
};
17878
enum {
17879
    KEYPURPOSEIDASN_IDX_OID = 0,
17880
};
17881
17882
/* Number of items in ASN.1 template for KeyPurposeId. */
17883
#define keyPurposeIdASN_Length (sizeof(keyPurposeIdASN) / sizeof(ASNItem))
17884
#endif
17885
17886
/* Decode extended key usage extension in a certificate.
17887
 *
17888
 * X.509: RFC 5280, 4.2.1.12 - Extended Key Usage.
17889
 *
17890
 * @param [in]      input  Buffer holding data.
17891
 * @param [in]      sz     Size of data in buffer.
17892
 * @param [in, out] cert   Certificate object.
17893
 * @return  0 on success.
17894
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
17895
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
17896
 *          is invalid.
17897
 * @return  MEMORY_E on dynamic memory allocation failure.
17898
 */
17899
static int DecodeExtKeyUsage(const byte* input, int sz, DecodedCert* cert)
17900
0
{
17901
0
#ifndef WOLFSSL_ASN_TEMPLATE
17902
0
    word32 idx = 0, oid;
17903
0
    int length, ret;
17904
17905
0
    WOLFSSL_ENTER("DecodeExtKeyUsage");
17906
17907
0
    if (GetSequence(input, &idx, &length, sz) < 0) {
17908
0
        WOLFSSL_MSG("\tfail: should be a SEQUENCE");
17909
0
        return ASN_PARSE_E;
17910
0
    }
17911
17912
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
17913
    cert->extExtKeyUsageSrc = input + idx;
17914
    cert->extExtKeyUsageSz = length;
17915
#endif
17916
17917
0
    while (idx < (word32)sz) {
17918
0
        ret = GetObjectId(input, &idx, &oid, oidCertKeyUseType, sz);
17919
0
        if (ret == ASN_UNKNOWN_OID_E)
17920
0
            continue;
17921
0
        else if (ret < 0)
17922
0
            return ret;
17923
17924
0
        switch (oid) {
17925
0
            case EKU_ANY_OID:
17926
0
                cert->extExtKeyUsage |= EXTKEYUSE_ANY;
17927
0
                break;
17928
0
            case EKU_SERVER_AUTH_OID:
17929
0
                cert->extExtKeyUsage |= EXTKEYUSE_SERVER_AUTH;
17930
0
                break;
17931
0
            case EKU_CLIENT_AUTH_OID:
17932
0
                cert->extExtKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
17933
0
                break;
17934
0
            case EKU_CODESIGNING_OID:
17935
0
                cert->extExtKeyUsage |= EXTKEYUSE_CODESIGN;
17936
0
                break;
17937
0
            case EKU_EMAILPROTECT_OID:
17938
0
                cert->extExtKeyUsage |= EXTKEYUSE_EMAILPROT;
17939
0
                break;
17940
0
            case EKU_TIMESTAMP_OID:
17941
0
                cert->extExtKeyUsage |= EXTKEYUSE_TIMESTAMP;
17942
0
                break;
17943
0
            case EKU_OCSP_SIGN_OID:
17944
0
                cert->extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN;
17945
0
                break;
17946
            #ifdef WOLFSSL_WOLFSSH
17947
            case EKU_SSH_CLIENT_AUTH_OID:
17948
                cert->extExtKeyUsageSsh |= EXTKEYUSE_SSH_CLIENT_AUTH;
17949
                break;
17950
            case EKU_SSH_MSCL_OID:
17951
                cert->extExtKeyUsageSsh |= EXTKEYUSE_SSH_MSCL;
17952
                break;
17953
            case EKU_SSH_KP_CLIENT_AUTH_OID:
17954
                cert->extExtKeyUsageSsh |= EXTKEYUSE_SSH_KP_CLIENT_AUTH;
17955
                break;
17956
            #endif /* WOLFSSL_WOLFSSH */
17957
0
            default:
17958
0
                break;
17959
0
        }
17960
17961
    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
17962
        cert->extExtKeyUsageCount++;
17963
    #endif
17964
0
    }
17965
17966
0
    return 0;
17967
#else
17968
    word32 idx = 0;
17969
    int length;
17970
    int ret = 0;
17971
17972
    WOLFSSL_ENTER("DecodeExtKeyUsage");
17973
17974
    /* Strip SEQUENCE OF and expect to account for all the data. */
17975
    if (GetASN_Sequence(input, &idx, &length, sz, 1) < 0) {
17976
        WOLFSSL_MSG("\tfail: should be a SEQUENCE");
17977
        ret = ASN_PARSE_E;
17978
    }
17979
17980
    if (ret == 0) {
17981
    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
17982
        /* Keep reference for WOLFSSL_X509. */
17983
        cert->extExtKeyUsageSrc = input + idx;
17984
        cert->extExtKeyUsageSz = length;
17985
    #endif
17986
    }
17987
17988
    /* Check all OIDs. */
17989
    while ((ret == 0) && (idx < (word32)sz)) {
17990
        ASNGetData dataASN[keyPurposeIdASN_Length];
17991
17992
        /* Clear dynamic data items and set OID type expected. */
17993
        XMEMSET(dataASN, 0, sizeof(dataASN));
17994
        GetASN_OID(&dataASN[KEYPURPOSEIDASN_IDX_OID], oidIgnoreType);
17995
        /* Decode KeyPurposeId. */
17996
        ret = GetASN_Items(keyPurposeIdASN, dataASN, keyPurposeIdASN_Length, 0,
17997
                           input, &idx, sz);
17998
        /* Skip unknown OIDs. */
17999
        if (ret == ASN_UNKNOWN_OID_E) {
18000
            ret = 0;
18001
        }
18002
        else if (ret == 0) {
18003
            /* Store the bit for the OID. */
18004
            switch (dataASN[KEYPURPOSEIDASN_IDX_OID].data.oid.sum) {
18005
                case EKU_ANY_OID:
18006
                    cert->extExtKeyUsage |= EXTKEYUSE_ANY;
18007
                    break;
18008
                case EKU_SERVER_AUTH_OID:
18009
                    cert->extExtKeyUsage |= EXTKEYUSE_SERVER_AUTH;
18010
                    break;
18011
                case EKU_CLIENT_AUTH_OID:
18012
                    cert->extExtKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
18013
                    break;
18014
                case EKU_CODESIGNING_OID:
18015
                    cert->extExtKeyUsage |= EXTKEYUSE_CODESIGN;
18016
                    break;
18017
                case EKU_EMAILPROTECT_OID:
18018
                    cert->extExtKeyUsage |= EXTKEYUSE_EMAILPROT;
18019
                    break;
18020
                case EKU_TIMESTAMP_OID:
18021
                    cert->extExtKeyUsage |= EXTKEYUSE_TIMESTAMP;
18022
                    break;
18023
                case EKU_OCSP_SIGN_OID:
18024
                    cert->extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN;
18025
                    break;
18026
            }
18027
18028
        #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
18029
            /* Keep count for WOLFSSL_X509. */
18030
            cert->extExtKeyUsageCount++;
18031
        #endif
18032
        }
18033
    }
18034
18035
    return ret;
18036
#endif /* WOLFSSL_ASN_TEMPLATE */
18037
0
}
18038
18039
#ifndef IGNORE_NETSCAPE_CERT_TYPE
18040
18041
static int DecodeNsCertType(const byte* input, int sz, DecodedCert* cert)
18042
0
{
18043
0
    word32 idx = 0;
18044
0
    int len = 0;
18045
18046
0
    WOLFSSL_ENTER("DecodeNsCertType");
18047
18048
0
    if (CheckBitString(input, &idx, &len, (word32)sz, 0, NULL) < 0)
18049
0
        return ASN_PARSE_E;
18050
18051
    /* Don't need to worry about unused bits as CheckBitString makes sure
18052
     * they're zero. */
18053
0
    if (idx < (word32)sz)
18054
0
        cert->nsCertType = input[idx];
18055
0
    else
18056
0
        return ASN_PARSE_E;
18057
18058
0
    return 0;
18059
0
}
18060
#endif
18061
18062
18063
#ifndef IGNORE_NAME_CONSTRAINTS
18064
#ifdef WOLFSSL_ASN_TEMPLATE
18065
/* ASN.1 template for GeneralSubtree.
18066
 * X.509: RFC 5280, 4.2.1.10 - Name Constraints.
18067
 */
18068
static const ASNItem subTreeASN[] = {
18069
/* SEQ  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
18070
                              /* base     GeneralName */
18071
/* BASE */     { 1, ASN_CONTEXT_SPECIFIC | 0, 0, 0, 0 },
18072
                              /* minimum  BaseDistance DEFAULT 0*/
18073
/* MIN  */     { 1, ASN_CONTEXT_SPECIFIC | ASN_SUBTREE_MIN, 0, 0, 1 },
18074
                              /* maximum  BaseDistance OPTIONAL  */
18075
/* MAX  */     { 1, ASN_CONTEXT_SPECIFIC | ASN_SUBTREE_MAX, 0, 0, 1 },
18076
};
18077
enum {
18078
    SUBTREEASN_IDX_SEQ = 0,
18079
    SUBTREEASN_IDX_BASE,
18080
    SUBTREEASN_IDX_MIN,
18081
    SUBTREEASN_IDX_MAX,
18082
};
18083
18084
/* Number of items in ASN.1 template for GeneralSubtree. */
18085
#define subTreeASN_Length (sizeof(subTreeASN) / sizeof(ASNItem))
18086
#endif
18087
18088
#ifdef WOLFSSL_ASN_TEMPLATE
18089
/* Decode the Subtree's GeneralName.
18090
 *
18091
 * @param [in]      input  Buffer holding data.
18092
 * @param [in]      sz     Size of data in buffer.
18093
 * @param [in]      tag    BER tag on GeneralName.
18094
 * @param [in, out] head   Linked list of subtree names.
18095
 * @param [in]      heap   Dynamic memory hint.
18096
 * @return  0 on success.
18097
 * @return  MEMORY_E when dynamic memory allocation fails.
18098
 * @return  ASN_PARSE_E when SEQUENCE is not found as expected.
18099
 */
18100
static int DecodeSubtreeGeneralName(const byte* input, int sz, byte tag,
18101
                                    Base_entry** head, void* heap)
18102
{
18103
    Base_entry* entry;
18104
    word32 nameIdx = 0;
18105
    word32 len = sz;
18106
    int strLen;
18107
    int ret = 0;
18108
18109
    (void)heap;
18110
18111
    /* if constructed has leading sequence */
18112
    if ((tag & ASN_CONSTRUCTED) == ASN_CONSTRUCTED) {
18113
        ret = GetASN_Sequence(input, &nameIdx, &strLen, sz, 0);
18114
        if (ret < 0) {
18115
            ret = ASN_PARSE_E;
18116
        }
18117
        else {
18118
            len = strLen;
18119
            ret = 0;
18120
        }
18121
    }
18122
    if (ret == 0) {
18123
        /* TODO: consider one malloc. */
18124
        /* Allocate Base Entry object. */
18125
        entry = (Base_entry*)XMALLOC(sizeof(Base_entry), heap,
18126
                                     DYNAMIC_TYPE_ALTNAME);
18127
        if (entry == NULL) {
18128
            ret = MEMORY_E;
18129
        }
18130
    }
18131
    if (ret == 0) {
18132
        /* Allocate name. */
18133
        entry->name = (char*)XMALLOC(len + 1, heap, DYNAMIC_TYPE_ALTNAME);
18134
        if (entry->name == NULL) {
18135
            XFREE(entry, heap, DYNAMIC_TYPE_ALTNAME);
18136
            ret = MEMORY_E;
18137
        }
18138
    }
18139
    if (ret == 0) {
18140
        /* Store name, size and tag in object. */
18141
        XMEMCPY(entry->name, &input[nameIdx], len);
18142
        entry->name[len] = '\0';
18143
        entry->nameSz = len;
18144
        entry->type = tag & ASN_TYPE_MASK;
18145
18146
        /* Put entry at front of linked list. */
18147
        entry->next = *head;
18148
        *head = entry;
18149
    }
18150
18151
    return ret;
18152
}
18153
#endif
18154
18155
/* Decode a subtree of a name contraint in a certificate.
18156
 *
18157
 * X.509: RFC 5280, 4.2.1.10 - Name Contraints.
18158
 *
18159
 * @param [in]      input  Buffer holding data.
18160
 * @param [in]      sz     Size of data in buffer.
18161
 * @param [in, out] head   Linked list of subtree names.
18162
 * @param [in]      heap   Dynamic memory hint.
18163
 * @return  0 on success.
18164
 * @return  MEMORY_E when dynamic memory allocation fails.
18165
 * @return  ASN_PARSE_E when SEQUENCE is not found as expected.
18166
 */
18167
static int DecodeSubtree(const byte* input, int sz, Base_entry** head,
18168
                         void* heap)
18169
0
{
18170
0
#ifndef WOLFSSL_ASN_TEMPLATE
18171
0
    word32 idx = 0;
18172
0
    int ret = 0;
18173
18174
0
    (void)heap;
18175
18176
0
    while (idx < (word32)sz) {
18177
0
        int seqLength, strLength;
18178
0
        word32 nameIdx;
18179
0
        byte b, bType;
18180
18181
0
        if (GetSequence(input, &idx, &seqLength, sz) < 0) {
18182
0
            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
18183
0
            return ASN_PARSE_E;
18184
0
        }
18185
18186
0
        if (idx >= (word32)sz) {
18187
0
            WOLFSSL_MSG("\tfail: expecting tag");
18188
0
            return ASN_PARSE_E;
18189
0
        }
18190
18191
0
        nameIdx = idx;
18192
0
        b = input[nameIdx++];
18193
18194
0
        if (GetLength(input, &nameIdx, &strLength, sz) <= 0) {
18195
0
            WOLFSSL_MSG("\tinvalid length");
18196
0
            return ASN_PARSE_E;
18197
0
        }
18198
18199
        /* Get type, LSB 4-bits */
18200
0
        bType = (b & ASN_TYPE_MASK);
18201
18202
0
        if (bType == ASN_DNS_TYPE || bType == ASN_RFC822_TYPE ||
18203
0
                                                        bType == ASN_DIR_TYPE) {
18204
0
            Base_entry* entry;
18205
18206
            /* if constructed has leading sequence */
18207
0
            if (b & ASN_CONSTRUCTED) {
18208
0
                if (GetSequence(input, &nameIdx, &strLength, sz) < 0) {
18209
0
                    WOLFSSL_MSG("\tfail: constructed be a SEQUENCE");
18210
0
                    return ASN_PARSE_E;
18211
0
                }
18212
0
            }
18213
18214
0
            entry = (Base_entry*)XMALLOC(sizeof(Base_entry), heap,
18215
0
                                                          DYNAMIC_TYPE_ALTNAME);
18216
0
            if (entry == NULL) {
18217
0
                WOLFSSL_MSG("allocate error");
18218
0
                return MEMORY_E;
18219
0
            }
18220
18221
0
            entry->name = (char*)XMALLOC(strLength+1, heap, DYNAMIC_TYPE_ALTNAME);
18222
0
            if (entry->name == NULL) {
18223
0
                WOLFSSL_MSG("allocate error");
18224
0
                XFREE(entry, heap, DYNAMIC_TYPE_ALTNAME);
18225
0
                return MEMORY_E;
18226
0
            }
18227
18228
0
            XMEMCPY(entry->name, &input[nameIdx], strLength);
18229
0
            entry->name[strLength] = '\0';
18230
0
            entry->nameSz = strLength;
18231
0
            entry->type = bType;
18232
18233
0
            entry->next = *head;
18234
0
            *head = entry;
18235
0
        }
18236
18237
0
        idx += seqLength;
18238
0
    }
18239
18240
0
    return ret;
18241
#else
18242
    DECL_ASNGETDATA(dataASN, subTreeASN_Length);
18243
    word32 idx = 0;
18244
    int ret = 0;
18245
18246
    (void)heap;
18247
18248
    ALLOC_ASNGETDATA(dataASN, subTreeASN_Length, ret, heap);
18249
18250
    /* Process all subtrees. */
18251
    while ((ret == 0) && (idx < (word32)sz)) {
18252
        byte minVal = 0;
18253
        byte maxVal = 0;
18254
18255
        /* Clear dynamic data and set choice for GeneralName and location to
18256
         * store minimum and maximum.
18257
         */
18258
        XMEMSET(dataASN, 0, sizeof(*dataASN) * subTreeASN_Length);
18259
        GetASN_Choice(&dataASN[SUBTREEASN_IDX_BASE], generalNameChoice);
18260
        GetASN_Int8Bit(&dataASN[SUBTREEASN_IDX_MIN], &minVal);
18261
        GetASN_Int8Bit(&dataASN[SUBTREEASN_IDX_MAX], &maxVal);
18262
        /* Parse GeneralSubtree. */
18263
        ret = GetASN_Items(subTreeASN, dataASN, subTreeASN_Length, 0, input,
18264
                           &idx, sz);
18265
        if (ret == 0) {
18266
            byte t = dataASN[SUBTREEASN_IDX_BASE].tag;
18267
18268
            /* Check GeneralName tag is one of the types we can handle. */
18269
            if (t == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE) ||
18270
                t == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE) ||
18271
                t == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_DIR_TYPE)) {
18272
                /* Parse the general name and store a new entry. */
18273
                ret = DecodeSubtreeGeneralName(input +
18274
                    GetASNItem_DataIdx(dataASN[SUBTREEASN_IDX_BASE], input),
18275
                    dataASN[SUBTREEASN_IDX_BASE].length, t, head, heap);
18276
            }
18277
            /* Skip entry. */
18278
        }
18279
    }
18280
18281
    FREE_ASNGETDATA(dataASN, heap);
18282
    return ret;
18283
#endif
18284
0
}
18285
18286
#ifdef WOLFSSL_ASN_TEMPLATE
18287
/* ASN.1 template for NameConstraints.
18288
 * X.509: RFC 5280, 4.2.1.10 - Name Contraints.
18289
 */
18290
static const ASNItem nameConstraintsASN[] = {
18291
/* SEQ     */ { 0, ASN_SEQUENCE, 1, 1, 0 },
18292
                                         /* permittedSubtrees */
18293
/* PERMIT  */     { 1, ASN_CONTEXT_SPECIFIC | 0, 1, 0, 1 },
18294
                                         /* excludededSubtrees */
18295
/* EXCLUDE */     { 1, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 1 },
18296
};
18297
enum {
18298
    NAMECONSTRAINTSASN_IDX_SEQ = 0,
18299
    NAMECONSTRAINTSASN_IDX_PERMIT,
18300
    NAMECONSTRAINTSASN_IDX_EXCLUDE,
18301
};
18302
18303
/* Number of items in ASN.1 template for NameConstraints. */
18304
#define nameConstraintsASN_Length (sizeof(nameConstraintsASN) / sizeof(ASNItem))
18305
#endif
18306
18307
/* Decode name constraints extension in a certificate.
18308
 *
18309
 * X.509: RFC 5280, 4.2.1.10 - Name Constraints.
18310
 *
18311
 * @param [in]      input  Buffer holding data.
18312
 * @param [in]      sz     Size of data in buffer.
18313
 * @param [in, out] cert   Certificate object.
18314
 * @return  0 on success.
18315
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
18316
 *          is invalid.
18317
 * @return  MEMORY_E on dynamic memory allocation failure.
18318
 */
18319
static int DecodeNameConstraints(const byte* input, int sz, DecodedCert* cert)
18320
0
{
18321
0
#ifndef WOLFSSL_ASN_TEMPLATE
18322
0
    word32 idx = 0;
18323
0
    int length = 0;
18324
18325
0
    WOLFSSL_ENTER("DecodeNameConstraints");
18326
18327
0
    if (GetSequence(input, &idx, &length, sz) < 0) {
18328
0
        WOLFSSL_MSG("\tfail: should be a SEQUENCE");
18329
0
        return ASN_PARSE_E;
18330
0
    }
18331
18332
0
    while (idx < (word32)sz) {
18333
0
        byte b = input[idx++];
18334
0
        Base_entry** subtree = NULL;
18335
18336
0
        if (GetLength(input, &idx, &length, sz) <= 0) {
18337
0
            WOLFSSL_MSG("\tinvalid length");
18338
0
            return ASN_PARSE_E;
18339
0
        }
18340
18341
0
        if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0))
18342
0
            subtree = &cert->permittedNames;
18343
0
        else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1))
18344
0
            subtree = &cert->excludedNames;
18345
0
        else {
18346
0
            WOLFSSL_MSG("\tinvalid subtree");
18347
0
            return ASN_PARSE_E;
18348
0
        }
18349
18350
0
        if (DecodeSubtree(input + idx, length, subtree, cert->heap) < 0) {
18351
0
            WOLFSSL_MSG("\terror parsing subtree");
18352
0
            return ASN_PARSE_E;
18353
0
        }
18354
18355
0
        idx += length;
18356
0
    }
18357
18358
0
    return 0;
18359
#else
18360
    DECL_ASNGETDATA(dataASN, nameConstraintsASN_Length);
18361
    word32 idx = 0;
18362
    int    ret = 0;
18363
18364
    CALLOC_ASNGETDATA(dataASN, nameConstraintsASN_Length, ret, cert->heap);
18365
18366
    if (ret == 0) {
18367
        /* Parse NameConstraints. */
18368
        ret = GetASN_Items(nameConstraintsASN, dataASN,
18369
                           nameConstraintsASN_Length, 1, input, &idx, sz);
18370
    }
18371
    if (ret == 0) {
18372
        /* If there was a permittedSubtrees then parse it. */
18373
        if (dataASN[NAMECONSTRAINTSASN_IDX_PERMIT].data.ref.data != NULL) {
18374
            ret = DecodeSubtree(
18375
                    dataASN[NAMECONSTRAINTSASN_IDX_PERMIT].data.ref.data,
18376
                    dataASN[NAMECONSTRAINTSASN_IDX_PERMIT].data.ref.length,
18377
                    &cert->permittedNames, cert->heap);
18378
        }
18379
    }
18380
    if (ret == 0) {
18381
        /* If there was a excludedSubtrees then parse it. */
18382
        if (dataASN[NAMECONSTRAINTSASN_IDX_EXCLUDE].data.ref.data != NULL) {
18383
            ret = DecodeSubtree(
18384
                    dataASN[NAMECONSTRAINTSASN_IDX_EXCLUDE].data.ref.data,
18385
                    dataASN[NAMECONSTRAINTSASN_IDX_EXCLUDE].data.ref.length,
18386
                    &cert->excludedNames, cert->heap);
18387
        }
18388
    }
18389
18390
    FREE_ASNGETDATA(dataASN, cert->heap);
18391
18392
    return ret;
18393
#endif /* WOLFSSL_ASN_TEMPLATE */
18394
0
}
18395
#endif /* IGNORE_NAME_CONSTRAINTS */
18396
18397
#if (defined(WOLFSSL_CERT_EXT) && !defined(WOLFSSL_SEP)) || \
18398
    defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
18399
18400
/* Decode ITU-T X.690 OID format to a string representation
18401
 * return string length */
18402
int DecodePolicyOID(char *out, word32 outSz, const byte *in, word32 inSz)
18403
{
18404
    word32 val, inIdx = 0, outIdx = 0;
18405
    int w = 0;
18406
18407
    if (out == NULL || in == NULL || outSz < 4 || inSz < 2)
18408
        return BAD_FUNC_ARG;
18409
18410
    /* The first byte expands into b/40 dot b%40. */
18411
    val = in[inIdx++];
18412
18413
    w = XSNPRINTF(out, outSz, "%u.%u", val / 40, val % 40);
18414
    if (w < 0) {
18415
        w = BUFFER_E;
18416
        goto exit;
18417
    }
18418
    outIdx += w;
18419
    val = 0;
18420
18421
    while (inIdx < inSz && outIdx < outSz) {
18422
        /* extract the next OID digit from in to val */
18423
        /* first bit is used to set if value is coded on 1 or multiple bytes */
18424
        if (in[inIdx] & 0x80) {
18425
            val += in[inIdx] & 0x7F;
18426
            val *= 128;
18427
        }
18428
        else {
18429
            /* write val as text into out */
18430
            val += in[inIdx];
18431
            w = XSNPRINTF(out + outIdx, outSz - outIdx, ".%u", val);
18432
            if (w < 0 || (word32)w > outSz - outIdx) {
18433
                w = BUFFER_E;
18434
                goto exit;
18435
            }
18436
            outIdx += w;
18437
            val = 0;
18438
        }
18439
        inIdx++;
18440
    }
18441
    if (outIdx == outSz)
18442
        outIdx--;
18443
    out[outIdx] = 0;
18444
18445
    w = (int)outIdx;
18446
18447
exit:
18448
    return w;
18449
}
18450
#endif /* WOLFSSL_CERT_EXT && !WOLFSSL_SEP */
18451
18452
#if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_QT)
18453
    #ifdef WOLFSSL_ASN_TEMPLATE
18454
    /* ASN.1 template for PolicyInformation.
18455
     * X.509: RFC 5280, 4.2.1.4 - Certificate Policies.
18456
     */
18457
    static const ASNItem policyInfoASN[] = {
18458
    /* SEQ   */ { 0, ASN_SEQUENCE, 1, 1, 0 },
18459
                                      /* policyIdentifier */
18460
    /* ID    */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
18461
                                      /* policyQualifiers */
18462
    /* QUALI */     { 1, ASN_SEQUENCE, 1, 0, 1 },
18463
    };
18464
    enum {
18465
        POLICYINFOASN_IDX_SEQ = 0,
18466
        POLICYINFOASN_IDX_ID,
18467
        POLICYINFOASN_IDX_QUALI,
18468
    };
18469
18470
    /* Number of items in ASN.1 template for PolicyInformation. */
18471
    #define policyInfoASN_Length (sizeof(policyInfoASN) / sizeof(ASNItem))
18472
    #endif
18473
18474
    /* Reference: https://tools.ietf.org/html/rfc5280#section-4.2.1.4 */
18475
    static int DecodeCertPolicy(const byte* input, int sz, DecodedCert* cert)
18476
    {
18477
    #ifndef WOLFSSL_ASN_TEMPLATE
18478
        word32 idx = 0;
18479
        word32 oldIdx;
18480
        int policy_length = 0;
18481
        int ret;
18482
        int total_length = 0;
18483
    #if !defined(WOLFSSL_SEP) && defined(WOLFSSL_CERT_EXT) && \
18484
        !defined(WOLFSSL_DUP_CERTPOL)
18485
        int i;
18486
    #endif
18487
18488
        WOLFSSL_ENTER("DecodeCertPolicy");
18489
18490
    #if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT)
18491
        /* Check if cert is null before dereferencing below */
18492
        if (cert == NULL)
18493
            return BAD_FUNC_ARG;
18494
    #else
18495
        (void)cert;
18496
    #endif
18497
18498
    #if defined(WOLFSSL_CERT_EXT)
18499
         cert->extCertPoliciesNb = 0;
18500
    #endif
18501
18502
        if (GetSequence(input, &idx, &total_length, sz) < 0) {
18503
            WOLFSSL_MSG("\tGet CertPolicy total seq failed");
18504
            return ASN_PARSE_E;
18505
        }
18506
18507
        /* Validate total length */
18508
        if (total_length > (sz - (int)idx)) {
18509
            WOLFSSL_MSG("\tCertPolicy length mismatch");
18510
            return ASN_PARSE_E;
18511
        }
18512
18513
        /* Unwrap certificatePolicies */
18514
        do {
18515
            int length = 0;
18516
18517
            if (GetSequence(input, &idx, &policy_length, sz) < 0) {
18518
                WOLFSSL_MSG("\tGet CertPolicy seq failed");
18519
                return ASN_PARSE_E;
18520
            }
18521
18522
            oldIdx = idx;
18523
            ret = GetASNObjectId(input, &idx, &length, sz);
18524
            if (ret != 0)
18525
                return ret;
18526
            policy_length -= idx - oldIdx;
18527
18528
            if (length > 0) {
18529
                /* Verify length won't overrun buffer */
18530
                if (length > (sz - (int)idx)) {
18531
                    WOLFSSL_MSG("\tCertPolicy length exceeds input buffer");
18532
                    return ASN_PARSE_E;
18533
                }
18534
18535
        #if defined(WOLFSSL_SEP)
18536
                cert->deviceType = (byte*)XMALLOC(length, cert->heap,
18537
                                                         DYNAMIC_TYPE_X509_EXT);
18538
                if (cert->deviceType == NULL) {
18539
                    WOLFSSL_MSG("\tCouldn't alloc memory for deviceType");
18540
                    return MEMORY_E;
18541
                }
18542
                cert->deviceTypeSz = length;
18543
                XMEMCPY(cert->deviceType, input + idx, length);
18544
                break;
18545
        #elif defined(WOLFSSL_CERT_EXT)
18546
                /* decode cert policy */
18547
                if (DecodePolicyOID(cert->extCertPolicies[
18548
                                       cert->extCertPoliciesNb], MAX_CERTPOL_SZ,
18549
                                       input + idx, length) <= 0) {
18550
                    WOLFSSL_MSG("\tCouldn't decode CertPolicy");
18551
                    WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
18552
                    return ASN_PARSE_E;
18553
                }
18554
            #ifndef WOLFSSL_DUP_CERTPOL
18555
                /* From RFC 5280 section 4.2.1.3 "A certificate policy OID MUST
18556
                 * NOT appear more than once in a certificate policies
18557
                 * extension". This is a sanity check for duplicates.
18558
                 * extCertPolicies should only have OID values, additional
18559
                 * qualifiers need to be stored in a separate array. */
18560
                for (i = 0; i < cert->extCertPoliciesNb; i++) {
18561
                    if (XMEMCMP(cert->extCertPolicies[i],
18562
                            cert->extCertPolicies[cert->extCertPoliciesNb],
18563
                            MAX_CERTPOL_SZ) == 0) {
18564
                            WOLFSSL_MSG("Duplicate policy OIDs not allowed");
18565
                            WOLFSSL_MSG("Use WOLFSSL_DUP_CERTPOL if wanted");
18566
                            WOLFSSL_ERROR_VERBOSE(CERTPOLICIES_E);
18567
                            return CERTPOLICIES_E;
18568
                    }
18569
                }
18570
            #endif /* !WOLFSSL_DUP_CERTPOL */
18571
                cert->extCertPoliciesNb++;
18572
        #else
18573
                WOLFSSL_LEAVE("DecodeCertPolicy : unsupported mode", 0);
18574
                return 0;
18575
        #endif
18576
            }
18577
            idx += policy_length;
18578
        } while((int)idx < total_length
18579
    #if defined(WOLFSSL_CERT_EXT)
18580
            && cert->extCertPoliciesNb < MAX_CERTPOL_NB
18581
    #endif
18582
        );
18583
18584
        WOLFSSL_LEAVE("DecodeCertPolicy", 0);
18585
        return 0;
18586
    #else /* WOLFSSL_ASN_TEMPLATE */
18587
        word32 idx = 0;
18588
        int ret = 0;
18589
        int total_length = 0;
18590
    #if !defined(WOLFSSL_SEP) && defined(WOLFSSL_CERT_EXT) && \
18591
        !defined(WOLFSSL_DUP_CERTPOL)
18592
        int i;
18593
    #endif
18594
18595
        WOLFSSL_ENTER("DecodeCertPolicy");
18596
        #if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT)
18597
        /* Check if cert is null before dereferencing below */
18598
        if (cert == NULL)
18599
            ret = BAD_FUNC_ARG;
18600
        #endif
18601
18602
        if (ret == 0) {
18603
        #if defined(WOLFSSL_CERT_EXT)
18604
             cert->extCertPoliciesNb = 0;
18605
        #endif
18606
18607
            /* Strip SEQUENCE OF and check using all data. */
18608
            if (GetASN_Sequence(input, &idx, &total_length, sz, 1) < 0) {
18609
                ret = ASN_PARSE_E;
18610
            }
18611
        }
18612
18613
        /* Unwrap certificatePolicies */
18614
        while ((ret == 0) && ((int)idx < total_length)
18615
        #if defined(WOLFSSL_CERT_EXT)
18616
            && (cert->extCertPoliciesNb < MAX_CERTPOL_NB)
18617
        #endif
18618
               ) {
18619
            ASNGetData dataASN[policyInfoASN_Length];
18620
            byte* data;
18621
            word32 length = 0;
18622
18623
            /* Clear dynamic data and check OID is a cert policy type. */
18624
            XMEMSET(dataASN, 0, sizeof(dataASN));
18625
            GetASN_OID(&dataASN[POLICYINFOASN_IDX_ID], oidCertPolicyType);
18626
            ret = GetASN_Items(policyInfoASN, dataASN, policyInfoASN_Length, 1,
18627
                               input, &idx, sz);
18628
            if (ret == 0) {
18629
                /* Get the OID. */
18630
                GetASN_OIDData(&dataASN[POLICYINFOASN_IDX_ID], &data, &length);
18631
                if (length == 0) {
18632
                    ret = ASN_PARSE_E;
18633
                }
18634
            }
18635
            #if defined(WOLFSSL_SEP)
18636
            /* Store OID in device type. */
18637
            if (ret == 0) {
18638
                cert->deviceType = (byte*)XMALLOC(length, cert->heap,
18639
                                                  DYNAMIC_TYPE_X509_EXT);
18640
                if (cert->deviceType == NULL) {
18641
                    WOLFSSL_MSG("\tCouldn't alloc memory for deviceType");
18642
                    ret = MEMORY_E;
18643
                }
18644
            }
18645
            if (ret == 0) {
18646
                /* Store device type data and length. */
18647
                cert->deviceTypeSz = length;
18648
                XMEMCPY(cert->deviceType, data, length);
18649
                break;
18650
            }
18651
            #elif defined(WOLFSSL_CERT_EXT)
18652
            if (ret == 0) {
18653
                /* Decode cert policy. */
18654
                if (DecodePolicyOID(
18655
                                 cert->extCertPolicies[cert->extCertPoliciesNb],
18656
                                 MAX_CERTPOL_SZ, data, length) <= 0) {
18657
                    WOLFSSL_MSG("\tCouldn't decode CertPolicy");
18658
                    WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
18659
                    ret = ASN_PARSE_E;
18660
                }
18661
            }
18662
            #ifndef WOLFSSL_DUP_CERTPOL
18663
            /* From RFC 5280 section 4.2.1.3 "A certificate policy OID MUST
18664
             * NOT appear more than once in a certificate policies
18665
             * extension". This is a sanity check for duplicates.
18666
             * extCertPolicies should only have OID values, additional
18667
             * qualifiers need to be stored in a seperate array. */
18668
            for (i = 0; (ret == 0) && (i < cert->extCertPoliciesNb); i++) {
18669
                if (XMEMCMP(cert->extCertPolicies[i],
18670
                            cert->extCertPolicies[cert->extCertPoliciesNb],
18671
                            MAX_CERTPOL_SZ) == 0) {
18672
                    WOLFSSL_MSG("Duplicate policy OIDs not allowed");
18673
                    WOLFSSL_MSG("Use WOLFSSL_DUP_CERTPOL if wanted");
18674
                    WOLFSSL_ERROR_VERBOSE(CERTPOLICIES_E);
18675
                    ret = CERTPOLICIES_E;
18676
                }
18677
            }
18678
            #endif /* !defined(WOLFSSL_DUP_CERTPOL) */
18679
            if (ret == 0) {
18680
                /* Keep count of policies seen. */
18681
                cert->extCertPoliciesNb++;
18682
            }
18683
            #else
18684
                (void)data;
18685
                WOLFSSL_LEAVE("DecodeCertPolicy : unsupported mode", 0);
18686
                break;
18687
            #endif
18688
        }
18689
18690
        WOLFSSL_LEAVE("DecodeCertPolicy", 0);
18691
        return ret;
18692
    #endif /* WOLFSSL_ASN_TEMPLATE */
18693
    }
18694
#endif /* WOLFSSL_SEP */
18695
18696
#ifdef WOLFSSL_SUBJ_DIR_ATTR
18697
#ifdef WOLFSSL_ASN_TEMPLATE
18698
/* ASN.1 template for subject dir attribute.
18699
 * X.509: RFC 5280, 4.2.1.8 - Subject Directory Attributes.
18700
 */
18701
static const ASNItem subjDirAttrASN[] = {
18702
/* SEQ  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
18703
/* SEQ  */     { 1, ASN_SEQUENCE, 1, 1, 0 },
18704
/* OID  */          { 2, ASN_OBJECT_ID, 0, 0, 0 },
18705
/* PLEN */          { 2, ASN_SET, 1, 1, 0 },
18706
/* BIT_STR */       { 2, ASN_PRINTABLE_STRING, 0, 0, 0 }
18707
};
18708
enum {
18709
    SUBJDIRATTRASN_IDX_SEQ = 0,
18710
    SUBJDIRATTRASN_IDX_SEQ2,
18711
    SUBJDIRATTRASN_IDX_OID,
18712
    SUBJDIRATTRASN_IDX_SET,
18713
    SUBJDIRATTRASN_IDX_STRING,
18714
};
18715
18716
/* Number of items in ASN.1 template for BasicContraints. */
18717
#define subjDirAttrASN_Length (sizeof(subjDirAttrASN) / sizeof(ASNItem))
18718
#endif
18719
/* Decode subject directory attributes extension in a certificate.
18720
 *
18721
 * X.509: RFC 5280, 4.2.1.8 - Subject Directory Attributes.
18722
 *
18723
 * @param [in]      input  Buffer holding data.
18724
 * @param [in]      sz     Size of data in buffer.
18725
 * @param [in, out] cert   Certificate object.
18726
 * @return  0 on success.
18727
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
18728
 *          is invalid.
18729
 */
18730
static int DecodeSubjDirAttr(const byte* input, int sz, DecodedCert* cert)
18731
{
18732
#ifndef WOLFSSL_ASN_TEMPLATE
18733
    word32 idx = 0;
18734
    int length = 0;
18735
    int ret = 0;
18736
18737
    WOLFSSL_ENTER("DecodeSubjDirAttr");
18738
18739
#ifdef OPENSSL_ALL
18740
    cert->extSubjDirAttrSrc = input;
18741
    cert->extSubjDirAttrSz = sz;
18742
#endif /* OPENSSL_ALL */
18743
18744
    /* Unwrap the list of Attributes */
18745
    if (GetSequence(input, &idx, &length, sz) < 0)
18746
        return ASN_PARSE_E;
18747
18748
    if (length == 0) {
18749
        /* RFC 5280 4.2.1.8.  Subject Directory Attributes
18750
           If the subjectDirectoryAttributes extension is present, the
18751
           sequence MUST contain at least one entry. */
18752
        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
18753
        return ASN_PARSE_E;
18754
    }
18755
18756
    /* length is the length of the list contents */
18757
    while (idx < (word32)sz) {
18758
        word32 oid;
18759
18760
        if (GetSequence(input, &idx, &length, sz) < 0)
18761
            return ASN_PARSE_E;
18762
18763
        if (GetObjectId(input, &idx, &oid, oidSubjDirAttrType, sz) < 0)
18764
            return ASN_PARSE_E;
18765
18766
        if (GetSet(input, &idx, &length, sz) < 0)
18767
            return ASN_PARSE_E;
18768
18769
        /* There may be more than one countryOfCitizenship, but save the
18770
         * first one for now. */
18771
        if (oid == SDA_COC_OID) {
18772
            byte tag;
18773
18774
            if (GetHeader(input, &tag, &idx, &length, sz, 1) < 0)
18775
                return ASN_PARSE_E;
18776
18777
            if (length != COUNTRY_CODE_LEN)
18778
                return ASN_PARSE_E;
18779
18780
            if (tag == ASN_PRINTABLE_STRING) {
18781
                XMEMCPY(cert->countryOfCitizenship,
18782
                        input + idx, COUNTRY_CODE_LEN);
18783
                cert->countryOfCitizenship[COUNTRY_CODE_LEN] = 0;
18784
            }
18785
        }
18786
        idx += length;
18787
    }
18788
18789
    return ret;
18790
#else
18791
    DECL_ASNGETDATA(dataASN, subjDirAttrASN_Length);
18792
    int ret = 0;
18793
    word32 idx = 0;
18794
18795
    WOLFSSL_ENTER("DecodeSubjDirAttr");
18796
18797
    CALLOC_ASNGETDATA(dataASN, subjDirAttrASN_Length, ret, cert->heap);
18798
18799
    if (ret == 0) {
18800
        ret = GetASN_Items(subjDirAttrASN, dataASN, subjDirAttrASN_Length, 1,
18801
            input, &idx, sz);
18802
    }
18803
18804
    /* There may be more than one countryOfCitizenship, but save the
18805
     * first one for now. */
18806
    if (dataASN[SUBJDIRATTRASN_IDX_OID].data.oid.sum == SDA_COC_OID) {
18807
        word32 cuLen;
18808
18809
        cuLen = dataASN[SUBJDIRATTRASN_IDX_STRING].data.ref.length;
18810
        if (cuLen != COUNTRY_CODE_LEN)
18811
            return ASN_PARSE_E;
18812
18813
        XMEMCPY(cert->countryOfCitizenship,
18814
            dataASN[SUBJDIRATTRASN_IDX_STRING].data.ref.data, cuLen);
18815
        cert->countryOfCitizenship[COUNTRY_CODE_LEN] = 0;
18816
    }
18817
    FREE_ASNGETDATA(dataASN, cert->heap);
18818
    return ret;
18819
#endif /* WOLFSSL_ASN_TEMPLATE */
18820
}
18821
#endif /* WOLFSSL_SUBJ_DIR_ATTR */
18822
18823
#ifdef WOLFSSL_SUBJ_INFO_ACC
18824
/* Decode subject infomation access extension in a certificate.
18825
 *
18826
 * X.509: RFC 5280, 4.2.2.2 - Subject Information Access.
18827
 *
18828
 * @param [in]      input  Buffer holding data.
18829
 * @param [in]      sz     Size of data in buffer.
18830
 * @param [in, out] cert   Certificate object.
18831
 * @return  0 on success.
18832
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
18833
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
18834
 *          is invalid.
18835
 * @return  MEMORY_E on dynamic memory allocation failure.
18836
 */
18837
static int DecodeSubjInfoAcc(const byte* input, int sz, DecodedCert* cert)
18838
{
18839
    word32 idx = 0;
18840
    int length = 0;
18841
    int ret = 0;
18842
18843
    WOLFSSL_ENTER("DecodeSubjInfoAcc");
18844
18845
#ifdef OPENSSL_ALL
18846
    cert->extSubjAltNameSrc = input;
18847
    cert->extSubjAltNameSz = sz;
18848
#endif /* OPENSSL_ALL */
18849
18850
    /* Unwrap SubjectInfoAccessSyntax, the list of AccessDescriptions */
18851
    if (GetSequence(input, &idx, &length, sz) < 0)
18852
        return ASN_PARSE_E;
18853
18854
    if (length == 0) {
18855
        /* RFC 5280 4.2.2.2.  Subject Information Access
18856
           If the subjectInformationAccess extension is present, the
18857
           sequence MUST contain at least one entry. */
18858
        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
18859
        return ASN_PARSE_E;
18860
    }
18861
18862
    /* Per fpkx-x509-cert-profile-common... section 5.3.
18863
     * [The] subjectInfoAccess extension must contain at least one
18864
     * instance of the id-ad-caRepository access method containing a
18865
     * publicly accessible HTTP URI which returns as certs-only
18866
     * CMS.
18867
     */
18868
18869
    while (idx < (word32)sz) {
18870
        word32 oid = 0;
18871
        byte b;
18872
18873
        /* Unwrap an AccessDescription */
18874
        if (GetSequence(input, &idx, &length, sz) < 0)
18875
            return ASN_PARSE_E;
18876
18877
        /* Get the accessMethod */
18878
        if (GetObjectId(input, &idx, &oid, oidCertAuthInfoType, sz) < 0)
18879
            return ASN_PARSE_E;
18880
18881
        /* Only supporting URIs right now. */
18882
        if (GetASNTag(input, &idx, &b, sz) < 0)
18883
            return ASN_PARSE_E;
18884
18885
        if (GetLength(input, &idx, &length, sz) < 0)
18886
            return ASN_PARSE_E;
18887
18888
        /* Set ocsp entry */
18889
        if (b == GENERALNAME_URI && oid == AIA_OCSP_OID) {
18890
            cert->extSubjInfoAccCaRepoSz = length;
18891
            cert->extSubjInfoAccCaRepo = input + idx;
18892
            break;
18893
        }
18894
        idx += length;
18895
    }
18896
18897
    if (cert->extSubjInfoAccCaRepo == NULL ||
18898
            cert->extSubjInfoAccCaRepoSz == 0) {
18899
        WOLFSSL_MSG("SubjectInfoAccess missing an URL.");
18900
        ret = ASN_PARSE_E;
18901
    }
18902
18903
    WOLFSSL_LEAVE("DecodeSubjInfoAcc", ret);
18904
    return ret;
18905
}
18906
#endif /* WOLFSSL_SUBJ_INFO_ACC */
18907
18908
/* Macro to check if bit is set, if not sets and return success.
18909
    Otherwise returns failure */
18910
/* Macro required here because bit-field operation */
18911
#ifndef WOLFSSL_NO_ASN_STRICT
18912
    #define VERIFY_AND_SET_OID(bit) \
18913
0
        if ((bit) == 0) \
18914
0
            (bit) = 1; \
18915
0
        else \
18916
0
            return ASN_OBJECT_ID_E;
18917
#else
18918
    /* With no strict defined, the verify is skipped */
18919
#define VERIFY_AND_SET_OID(bit) bit = 1;
18920
#endif
18921
18922
/* Parse extension type specific data based on OID sum.
18923
 *
18924
 * Supported extensions:
18925
 *   Basic Constraints - BASIC_CA_OID
18926
 *   CRL Distribution Points - CRL_DIST_OID
18927
 *   Authority Information Access - AUTH_INFO_OID
18928
 *   Subject Alternative Name - ALT_NAMES_OID
18929
 *   Authority Key Identifier - AUTH_KEY_OID
18930
 *   Subject Key Identifier - SUBJ_KEY_OID
18931
 *   Certificate Policies - CERT_POLICY_OID (conditional parsing)
18932
 *   Key Usage - KEY_USAGE_OID
18933
 *   Extended Key Usage - EXT_KEY_USAGE_OID
18934
 *   Name Constraints - NAME_CONS_OID
18935
 *   Inhibit anyPolicy - INHIBIT_ANY_OID
18936
 *   Netscape Certificate Type - NETSCAPE_CT_OID (able to be excluded)
18937
 *   OCSP no check - OCSP_NOCHECK_OID (when compiling OCSP)
18938
 *   Subject Directory Attributes - SUBJ_DIR_ATTR_OID
18939
 *   Subject Information Access - SUBJ_INFO_ACC_OID
18940
 * Unsupported extensions from RFC 5280:
18941
 *   4.2.1.5 - Policy mappings
18942
 *   4.2.1.7 - Issuer Alternative Name
18943
 *   4.2.1.11 - Policy Constraints
18944
 *   4.2.1.15 - Freshest CRL
18945
 *
18946
 * @param [in]      input     Buffer containing extension type specific data.
18947
 * @param [in]      length    Length of data.
18948
 * @param [in]      oid       OID sum for extension.
18949
 * @param [in]      critical  Whether extension is critical.
18950
 * @param [in, out] cert      Certificate object.
18951
 * @return  0 on success.
18952
 * @return  ASN_PARSE_E when BER encoding is invalid.
18953
 * @return  MEMORY_E on dynamic memory allocation failure.
18954
 * @return  Other negative values on error.
18955
 */
18956
static int DecodeExtensionType(const byte* input, int length, word32 oid,
18957
                               byte critical, DecodedCert* cert,
18958
                               int *isUnknownExt)
18959
0
{
18960
0
    int ret = 0;
18961
0
    word32 idx = 0;
18962
18963
0
    if (isUnknownExt != NULL)
18964
0
        *isUnknownExt = 0;
18965
18966
0
    switch (oid) {
18967
        /* Basic Constraints. */
18968
0
        case BASIC_CA_OID:
18969
0
            VERIFY_AND_SET_OID(cert->extBasicConstSet);
18970
0
            cert->extBasicConstCrit = critical;
18971
0
            if (DecodeBasicCaConstraint(input, length, cert) < 0) {
18972
0
                ret = ASN_PARSE_E;
18973
0
            }
18974
0
            break;
18975
18976
        /* CRL Distribution point. */
18977
0
        case CRL_DIST_OID:
18978
0
            VERIFY_AND_SET_OID(cert->extCRLdistSet);
18979
0
            cert->extCRLdistCrit = critical;
18980
0
            if (DecodeCrlDist(input, length, cert) < 0) {
18981
0
                ret = ASN_PARSE_E;
18982
0
            }
18983
0
            break;
18984
18985
        /* Authority information access. */
18986
0
        case AUTH_INFO_OID:
18987
0
            VERIFY_AND_SET_OID(cert->extAuthInfoSet);
18988
0
            cert->extAuthInfoCrit = critical;
18989
0
            if (DecodeAuthInfo(input, length, cert) < 0) {
18990
0
                ret = ASN_PARSE_E;
18991
0
            }
18992
0
            break;
18993
18994
        /* Subject alternative name. */
18995
0
        case ALT_NAMES_OID:
18996
0
            VERIFY_AND_SET_OID(cert->extSubjAltNameSet);
18997
0
            cert->extSubjAltNameCrit = critical;
18998
0
            ret = DecodeAltNames(input, length, cert);
18999
0
            break;
19000
19001
        /* Authority Key Identifier. */
19002
0
        case AUTH_KEY_OID:
19003
0
            VERIFY_AND_SET_OID(cert->extAuthKeyIdSet);
19004
0
            cert->extAuthKeyIdCrit = critical;
19005
0
            #ifndef WOLFSSL_ALLOW_CRIT_SKID
19006
                /* This check is added due to RFC 5280 section 4.2.1.1
19007
                 * stating that conforming CA's must mark this extension
19008
                 * as non-critical. When parsing extensions check that
19009
                 * certificate was made in compliance with this. */
19010
0
                if (critical) {
19011
0
                    WOLFSSL_MSG("Critical Auth Key ID is not allowed");
19012
0
                    WOLFSSL_MSG("Use macro WOLFSSL_ALLOW_CRIT_SKID if wanted");
19013
0
                    ret = ASN_CRIT_EXT_E;
19014
0
                }
19015
0
            #endif
19016
0
            if ((ret == 0) && (DecodeAuthKeyId(input, length, cert) < 0)) {
19017
0
                ret = ASN_PARSE_E;
19018
0
            }
19019
0
            break;
19020
19021
        /* Subject Key Identifier. */
19022
0
        case SUBJ_KEY_OID:
19023
0
            VERIFY_AND_SET_OID(cert->extSubjKeyIdSet);
19024
0
            cert->extSubjKeyIdCrit = critical;
19025
0
            #ifndef WOLFSSL_ALLOW_CRIT_SKID
19026
                /* This check is added due to RFC 5280 section 4.2.1.2
19027
                 * stating that conforming CA's must mark this extension
19028
                 * as non-critical. When parsing extensions check that
19029
                 * certificate was made in compliance with this. */
19030
0
                if (critical) {
19031
0
                    WOLFSSL_MSG("Critical Subject Key ID is not allowed");
19032
0
                    WOLFSSL_MSG("Use macro WOLFSSL_ALLOW_CRIT_SKID if wanted");
19033
0
                    ret = ASN_CRIT_EXT_E;
19034
0
                }
19035
0
            #endif
19036
19037
0
            if ((ret == 0) && (DecodeSubjKeyId(input, length, cert) < 0)) {
19038
0
                ret = ASN_PARSE_E;
19039
0
            }
19040
0
            break;
19041
19042
        /* Certificate policies. */
19043
0
        case CERT_POLICY_OID:
19044
            #if defined(WOLFSSL_SEP) || defined(WOLFSSL_QT)
19045
                VERIFY_AND_SET_OID(cert->extCertPolicySet);
19046
                #if defined(OPENSSL_EXTRA) || \
19047
                    defined(OPENSSL_EXTRA_X509_SMALL)
19048
                    cert->extCertPolicyCrit = critical;
19049
                #endif
19050
            #endif
19051
            #if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT) || \
19052
                defined(WOLFSSL_QT)
19053
                if (DecodeCertPolicy(input, length, cert) < 0) {
19054
                    ret = ASN_PARSE_E;
19055
                }
19056
            #else
19057
0
                WOLFSSL_MSG("Certificate Policy extension not supported yet.");
19058
0
            #endif
19059
0
            break;
19060
19061
        /* Key usage. */
19062
0
        case KEY_USAGE_OID:
19063
0
            VERIFY_AND_SET_OID(cert->extKeyUsageSet);
19064
0
            cert->extKeyUsageCrit = critical;
19065
0
            if (DecodeKeyUsage(input, length, cert) < 0) {
19066
0
                ret = ASN_PARSE_E;
19067
0
            }
19068
0
            break;
19069
19070
        /* Extended key usage. */
19071
0
        case EXT_KEY_USAGE_OID:
19072
0
            VERIFY_AND_SET_OID(cert->extExtKeyUsageSet);
19073
0
            cert->extExtKeyUsageCrit = critical;
19074
0
            if (DecodeExtKeyUsage(input, length, cert) < 0) {
19075
0
                ret = ASN_PARSE_E;
19076
0
            }
19077
0
            break;
19078
19079
0
        #ifndef IGNORE_NAME_CONSTRAINTS
19080
        /* Name constraints. */
19081
0
        case NAME_CONS_OID:
19082
0
        #ifndef WOLFSSL_NO_ASN_STRICT
19083
            /* Verify RFC 5280 Sec 4.2.1.10 rule:
19084
                "The name constraints extension,
19085
                which MUST be used only in a CA certificate" */
19086
0
            if (!cert->isCA) {
19087
0
                WOLFSSL_MSG("Name constraints allowed only for CA certs");
19088
0
                WOLFSSL_ERROR_VERBOSE(ASN_NAME_INVALID_E);
19089
0
                ret = ASN_NAME_INVALID_E;
19090
0
            }
19091
0
        #endif
19092
0
            VERIFY_AND_SET_OID(cert->extNameConstraintSet);
19093
0
            cert->extNameConstraintCrit = critical;
19094
0
            if (DecodeNameConstraints(input, length, cert) < 0) {
19095
0
                ret = ASN_PARSE_E;
19096
0
            }
19097
0
            break;
19098
0
        #endif /* IGNORE_NAME_CONSTRAINTS */
19099
19100
        /* Inhibit anyPolicy. */
19101
0
        case INHIBIT_ANY_OID:
19102
0
            VERIFY_AND_SET_OID(cert->inhibitAnyOidSet);
19103
0
            WOLFSSL_MSG("Inhibit anyPolicy extension not supported yet.");
19104
0
            break;
19105
19106
0
   #ifndef IGNORE_NETSCAPE_CERT_TYPE
19107
        /* Netscape's certificate type. */
19108
0
        case NETSCAPE_CT_OID:
19109
0
            if (DecodeNsCertType(input, length, cert) < 0)
19110
0
                ret = ASN_PARSE_E;
19111
0
            break;
19112
0
    #endif
19113
    #ifdef HAVE_OCSP
19114
        /* OCSP no check. */
19115
        case OCSP_NOCHECK_OID:
19116
            VERIFY_AND_SET_OID(cert->ocspNoCheckSet);
19117
            ret = GetASNNull(input, &idx, length);
19118
            if (ret != 0) {
19119
                ret = ASN_PARSE_E;
19120
            }
19121
            break;
19122
    #endif
19123
0
        case POLICY_CONST_OID:
19124
0
            VERIFY_AND_SET_OID(cert->extPolicyConstSet);
19125
0
            cert->extPolicyConstCrit = critical;
19126
0
            if (DecodePolicyConstraints(&input[idx], length, cert) < 0)
19127
0
                return ASN_PARSE_E;
19128
0
            break;
19129
    #ifdef WOLFSSL_SUBJ_DIR_ATTR
19130
        case SUBJ_DIR_ATTR_OID:
19131
            VERIFY_AND_SET_OID(cert->extSubjDirAttrSet);
19132
            if (DecodeSubjDirAttr(&input[idx], length, cert) < 0)
19133
                return ASN_PARSE_E;
19134
            break;
19135
    #endif
19136
    #ifdef WOLFSSL_SUBJ_INFO_ACC
19137
        case SUBJ_INFO_ACC_OID:
19138
            VERIFY_AND_SET_OID(cert->extSubjInfoAccSet);
19139
            if (DecodeSubjInfoAcc(&input[idx], length, cert) < 0)
19140
                return ASN_PARSE_E;
19141
            break;
19142
    #endif
19143
0
        default:
19144
0
            if (isUnknownExt != NULL)
19145
0
                *isUnknownExt = 1;
19146
0
        #ifndef WOLFSSL_NO_ASN_STRICT
19147
            /* While it is a failure to not support critical extensions,
19148
             * still parse the certificate ignoring the unsupported
19149
             * extension to allow caller to accept it with the verify
19150
             * callback. */
19151
0
            if (critical) {
19152
0
                WOLFSSL_ERROR_VERBOSE(ASN_CRIT_EXT_E);
19153
0
                ret = ASN_CRIT_EXT_E;
19154
0
            }
19155
0
        #endif
19156
0
            break;
19157
0
    }
19158
19159
0
    return ret;
19160
0
}
19161
19162
#ifdef WOLFSSL_ASN_TEMPLATE
19163
/* ASN.1 template for extensions.
19164
 * X.509: RFC 5280, 4.1 - Basic Certificate Fields.
19165
 */
19166
static const ASNItem certExtHdrASN[] = {
19167
/* EXTTAG */ { 0, ASN_CONTEXT_SPECIFIC | 3, 1, 1, 0 },
19168
/* EXTSEQ */     { 1, ASN_SEQUENCE, 1, 1, 0 },
19169
};
19170
enum {
19171
    CERTEXTHDRASN_IDX_EXTTAG = 0,
19172
    CERTEXTHDRASN_IDX_EXTSEQ,
19173
};
19174
19175
/* Number of itesm in ASN.1 template for extensions. */
19176
#define certExtHdrASN_Length (sizeof(certExtHdrASN) / sizeof(ASNItem))
19177
19178
/* ASN.1 template for Extension.
19179
 * X.509: RFC 5280, 4.1 - Basic Certificate Fields.
19180
 */
19181
static const ASNItem certExtASN[] = {
19182
/* SEQ  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
19183
                              /* Extension object id */
19184
/* OID  */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
19185
                              /* critical - when true, must be parseable. */
19186
/* CRIT */     { 1, ASN_BOOLEAN, 0, 0, 1 },
19187
                              /* Data for extension - leave index at start of data. */
19188
/* VAL  */     { 1, ASN_OCTET_STRING, 0, 1, 0 },
19189
};
19190
enum {
19191
    CERTEXTASN_IDX_SEQ = 0,
19192
    CERTEXTASN_IDX_OID,
19193
    CERTEXTASN_IDX_CRIT,
19194
    CERTEXTASN_IDX_VAL,
19195
};
19196
19197
/* Number of items in ASN.1 template for Extension. */
19198
#define certExtASN_Length (sizeof(certExtASN) / sizeof(ASNItem))
19199
#endif
19200
19201
#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_ASN_TEMPLATE) \
19202
    && defined(HAVE_OID_DECODING)
19203
int wc_SetUnknownExtCallback(DecodedCert* cert,
19204
                             wc_UnknownExtCallback cb) {
19205
    if (cert == NULL) {
19206
        return BAD_FUNC_ARG;
19207
    }
19208
19209
    cert->unknownExtCallback = cb;
19210
    return 0;
19211
}
19212
#endif
19213
19214
/*
19215
 *  Processing the Certificate Extensions. This does not modify the current
19216
 *  index. It is works starting with the recorded extensions pointer.
19217
 */
19218
static int DecodeCertExtensions(DecodedCert* cert)
19219
0
{
19220
0
#ifndef WOLFSSL_ASN_TEMPLATE
19221
0
    int ret = 0;
19222
0
    word32 idx = 0;
19223
0
    int sz = cert->extensionsSz;
19224
0
    const byte* input = cert->extensions;
19225
0
    int length;
19226
0
    word32 oid;
19227
0
    byte critical = 0;
19228
0
    byte criticalFail = 0;
19229
0
    byte tag = 0;
19230
19231
0
    WOLFSSL_ENTER("DecodeCertExtensions");
19232
19233
0
    if (input == NULL || sz == 0)
19234
0
        return BAD_FUNC_ARG;
19235
19236
#ifdef WOLFSSL_CERT_REQ
19237
    if (!cert->isCSR)
19238
#endif
19239
0
    { /* Not included in CSR */
19240
0
        if (GetASNTag(input, &idx, &tag, sz) < 0) {
19241
0
            return ASN_PARSE_E;
19242
0
        }
19243
19244
0
        if (tag != ASN_EXTENSIONS) {
19245
0
            WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
19246
0
            return ASN_PARSE_E;
19247
0
        }
19248
19249
0
        if (GetLength(input, &idx, &length, sz) < 0) {
19250
0
            WOLFSSL_MSG("\tfail: invalid length");
19251
0
            return ASN_PARSE_E;
19252
0
        }
19253
0
    }
19254
19255
0
    if (GetSequence(input, &idx, &length, sz) < 0) {
19256
0
        WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
19257
0
        return ASN_PARSE_E;
19258
0
    }
19259
19260
0
    while (idx < (word32)sz) {
19261
0
        word32 localIdx;
19262
19263
0
        if (GetSequence(input, &idx, &length, sz) < 0) {
19264
0
            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
19265
0
            return ASN_PARSE_E;
19266
0
        }
19267
19268
0
        oid = 0;
19269
0
        if ((ret = GetObjectId(input, &idx, &oid, oidCertExtType, sz)) < 0) {
19270
0
            WOLFSSL_MSG("\tfail: OBJECT ID");
19271
0
            return ret;
19272
0
        }
19273
19274
        /* check for critical flag */
19275
0
        critical = 0;
19276
0
        if ((idx + 1) > (word32)sz) {
19277
0
            WOLFSSL_MSG("\tfail: malformed buffer");
19278
0
            return BUFFER_E;
19279
0
        }
19280
19281
0
        localIdx = idx;
19282
0
        if (GetASNTag(input, &localIdx, &tag, sz) == 0) {
19283
0
            if (tag == ASN_BOOLEAN) {
19284
0
                ret = GetBoolean(input, &idx, sz);
19285
0
                if (ret < 0) {
19286
0
                    WOLFSSL_MSG("\tfail: critical boolean");
19287
0
                    return ret;
19288
0
                }
19289
19290
0
                critical = (byte)ret;
19291
0
            }
19292
0
        }
19293
19294
        /* process the extension based on the OID */
19295
0
        ret = GetOctetString(input, &idx, &length, sz);
19296
0
        if (ret < 0) {
19297
0
            WOLFSSL_MSG("\tfail: bad OCTET STRING");
19298
0
            return ret;
19299
0
        }
19300
19301
0
        ret = DecodeExtensionType(input + idx, length, oid, critical, cert,
19302
0
                                  NULL);
19303
0
        if (ret == ASN_CRIT_EXT_E) {
19304
0
            ret = 0;
19305
0
            criticalFail = 1;
19306
0
        }
19307
0
        if (ret < 0)
19308
0
            goto end;
19309
0
        idx += length;
19310
0
    }
19311
19312
0
    ret = criticalFail ? ASN_CRIT_EXT_E : 0;
19313
0
end:
19314
0
    return ret;
19315
#else
19316
    DECL_ASNGETDATA(dataASN, certExtASN_Length);
19317
    ASNGetData dataExtsASN[certExtHdrASN_Length];
19318
    int ret = 0;
19319
    const byte* input = cert->extensions;
19320
    int sz = cert->extensionsSz;
19321
    word32 idx = 0;
19322
    int criticalRet = 0;
19323
    int offset = 0;
19324
19325
    WOLFSSL_ENTER("DecodeCertExtensions");
19326
19327
    if (input == NULL || sz == 0)
19328
        ret = BAD_FUNC_ARG;
19329
19330
    ALLOC_ASNGETDATA(dataASN, certExtASN_Length, ret, cert->heap);
19331
19332
#ifdef WOLFSSL_CERT_REQ
19333
    if (cert->isCSR) {
19334
        offset = CERTEXTHDRASN_IDX_EXTSEQ;
19335
    }
19336
#endif
19337
    if (ret == 0) {
19338
        /* Clear dynamic data. */
19339
        XMEMSET(dataExtsASN, 0, sizeof(dataExtsASN));
19340
        /* Parse extensions header. */
19341
        ret = GetASN_Items(certExtHdrASN + offset, dataExtsASN + offset,
19342
                           certExtHdrASN_Length - offset, 0, input, &idx, sz);
19343
    }
19344
    /* Parse each extension. */
19345
    while ((ret == 0) && (idx < (word32)sz)) {
19346
        byte critical = 0;
19347
        int isUnknownExt = 0;
19348
19349
        /* Clear dynamic data. */
19350
        XMEMSET(dataASN, 0, sizeof(*dataASN) * certExtASN_Length);
19351
        /* Ensure OID is an extention type. */
19352
        GetASN_OID(&dataASN[CERTEXTASN_IDX_OID], oidCertExtType);
19353
        /* Set criticality variable. */
19354
        GetASN_Int8Bit(&dataASN[CERTEXTASN_IDX_CRIT], &critical);
19355
        /* Parse extension wrapper. */
19356
        ret = GetASN_Items(certExtASN, dataASN, certExtASN_Length, 0, input,
19357
                           &idx, sz);
19358
        if (ret == 0) {
19359
            word32 oid = dataASN[CERTEXTASN_IDX_OID].data.oid.sum;
19360
            int length = dataASN[CERTEXTASN_IDX_VAL].length;
19361
19362
            /* Decode the extension by type. */
19363
            ret = DecodeExtensionType(input + idx, length, oid, critical, cert,
19364
                                      &isUnknownExt);
19365
#if defined(WOLFSSL_CUSTOM_OID) && defined(HAVE_OID_DECODING)
19366
            if (isUnknownExt && (cert->unknownExtCallback != NULL)) {
19367
                word16 decOid[MAX_OID_SZ];
19368
                word32 decOidSz = sizeof(decOid);
19369
                ret = DecodeObjectId(
19370
                          dataASN[CERTEXTASN_IDX_OID].data.oid.data,
19371
                          dataASN[CERTEXTASN_IDX_OID].data.oid.length,
19372
                          decOid, &decOidSz);
19373
                if (ret != 0) {
19374
                    /* Should never get here as the extension was successfully
19375
                     * decoded earlier. Something might be corrupted. */
19376
                    WOLFSSL_MSG("DecodeObjectId() failed. Corruption?");
19377
                    WOLFSSL_ERROR(ret);
19378
                }
19379
19380
                ret = cert->unknownExtCallback(decOid, decOidSz, critical,
19381
                          dataASN[CERTEXTASN_IDX_VAL].data.buffer.data,
19382
                          dataASN[CERTEXTASN_IDX_VAL].length);
19383
            }
19384
#endif
19385
            (void)isUnknownExt;
19386
19387
            /* Move index on to next extension. */
19388
            idx += length;
19389
        }
19390
        /* Don't fail criticality until all other extensions have been checked.
19391
         */
19392
        if (ret == ASN_CRIT_EXT_E) {
19393
            criticalRet = ASN_CRIT_EXT_E;
19394
            ret = 0;
19395
        }
19396
    }
19397
19398
    if (ret == 0) {
19399
        /* Use criticality return. */
19400
        ret = criticalRet;
19401
    }
19402
19403
    FREE_ASNGETDATA(dataASN, cert->heap);
19404
    return ret;
19405
#endif
19406
0
}
19407
19408
#ifdef WOLFSSL_ASN_TEMPLATE
19409
/* ASN template for an X509 certificate.
19410
 * X.509: RFC 5280, 4.1 - Basic Certificate Fields.
19411
 */
19412
static const ASNItem x509CertASN[] = {
19413
        /* Certificate ::= SEQUENCE */
19414
/* SEQ                           */    { 0, ASN_SEQUENCE, 1, 1, 0 },
19415
                                                   /* tbsCertificate       TBSCertificate */
19416
                                                   /* TBSCertificate ::= SEQUENCE */
19417
/* TBS_SEQ                       */        { 1, ASN_SEQUENCE, 1, 1, 0 },
19418
                                                   /* version         [0]  EXPLICT Version DEFAULT v1 */
19419
/* TBS_VER                       */            { 2, ASN_CONTEXT_SPECIFIC | ASN_X509_CERT_VERSION, 1, 1, 1 },
19420
                                                   /* Version ::= INTEGER { v1(0), v2(1), v3(2) */
19421
/* TBS_VER_INT                   */                { 3, ASN_INTEGER, 0, 0, 0 },
19422
                                                   /* serialNumber         CertificateSerialNumber */
19423
                                                   /* CetificateSerialNumber ::= INTEGER */
19424
/* TBS_SERIAL                    */            { 2, ASN_INTEGER, 0, 0, 0 },
19425
                                                   /* signature            AlgorithmIdentifier */
19426
                                                   /* AlgorithmIdentifier ::= SEQUENCE */
19427
/* TBS_ALGOID_SEQ                */            { 2, ASN_SEQUENCE, 1, 1, 0 },
19428
                                                   /* Algorithm    OBJECT IDENTIFIER */
19429
/* TBS_ALGOID_OID                */                { 3, ASN_OBJECT_ID, 0, 0, 0 },
19430
                                                   /* parameters   ANY defined by algorithm OPTIONAL */
19431
/* TBS_ALGOID_PARAMS_NULL        */                { 3, ASN_TAG_NULL, 0, 0, 2 },
19432
#ifdef WC_RSA_PSS
19433
/* TBS_ALGOID_PARAMS             */                { 3, ASN_SEQUENCE, 1, 0, 2 },
19434
#endif
19435
                                                   /* issuer               Name */
19436
/* TBS_ISSUER_SEQ                */            { 2, ASN_SEQUENCE, 1, 0, 0 },
19437
                                                   /* validity             Validity */
19438
                                                   /* Validity ::= SEQUENCE */
19439
/* TBS_VALIDITY_SEQ              */            { 2, ASN_SEQUENCE, 1, 1, 0 },
19440
                                                   /* notBefore   Time */
19441
                                                   /* Time :: CHOICE { UTCTime, GeneralizedTime } */
19442
/* TBS_VALIDITY_NOTB_UTC         */                { 3, ASN_UTC_TIME, 0, 0, 2 },
19443
/* TBS_VALIDITY_NOTB_GT          */                { 3, ASN_GENERALIZED_TIME, 0, 0, 2 },
19444
                                                   /* notAfter   Time */
19445
                                                   /* Time :: CHOICE { UTCTime, GeneralizedTime } */
19446
/* TBS_VALIDITY_NOTA_UTC         */                { 3, ASN_UTC_TIME, 0, 0, 3 },
19447
/* TBS_VALIDITY_NOTA_GT          */                { 3, ASN_GENERALIZED_TIME, 0, 0, 3 },
19448
                                                   /* subject              Name */
19449
/* TBS_SUBJECT_SEQ               */            { 2, ASN_SEQUENCE, 1, 0, 0 },
19450
                                                   /* subjectPublicKeyInfo SubjectPublicKeyInfo */
19451
/* TBS_SPUBKEYINFO_SEQ           */            { 2, ASN_SEQUENCE, 1, 1, 0 },
19452
                                                   /* algorithm          AlgorithmIdentifier */
19453
                                                   /* AlgorithmIdentifier ::= SEQUENCE */
19454
/* TBS_SPUBKEYINFO_ALGO_SEQ      */                { 3, ASN_SEQUENCE, 1, 1, 0 },
19455
                                                   /* Algorithm    OBJECT IDENTIFIER */
19456
/* TBS_SPUBKEYINFO_ALGO_OID      */                    { 4, ASN_OBJECT_ID, 0, 0, 0 },
19457
                                                   /* parameters   ANY defined by algorithm OPTIONAL */
19458
/* TBS_SPUBKEYINFO_ALGO_NULL     */                    { 4, ASN_TAG_NULL, 0, 0, 2 },
19459
/* TBS_SPUBKEYINFO_ALGO_CURVEID  */                    { 4, ASN_OBJECT_ID, 0, 0, 2 },
19460
#ifdef WC_RSA_PSS
19461
/* TBS_SPUBKEYINFO_ALGO_P_SEQ    */                    { 4, ASN_SEQUENCE, 1, 0, 2 },
19462
#endif
19463
                                                   /* subjectPublicKey   BIT STRING */
19464
/* TBS_SPUBKEYINFO_PUBKEY        */                { 3, ASN_BIT_STRING, 0, 0, 0 },
19465
                                                   /* issuerUniqueID       UniqueIdentfier OPTIONAL */
19466
/* TBS_ISSUERUID                 */            { 2, ASN_CONTEXT_SPECIFIC | 1, 0, 0, 1 },
19467
                                                   /* subjectUniqueID      UniqueIdentfier OPTIONAL */
19468
/* TBS_SUBJECTUID                */            { 2, ASN_CONTEXT_SPECIFIC | 2, 0, 0, 1 },
19469
                                                   /* extensions           Extensions OPTIONAL */
19470
/* TBS_EXT                       */            { 2, ASN_CONTEXT_SPECIFIC | 3, 1, 1, 1 },
19471
/* TBS_EXT_SEQ                   */                { 3, ASN_SEQUENCE, 1, 0, 0 },
19472
                                                   /* signatureAlgorithm   AlgorithmIdentifier */
19473
                                                   /* AlgorithmIdentifier ::= SEQUENCE */
19474
/* SIGALGO_SEQ                   */        { 1, ASN_SEQUENCE, 1, 1, 0 },
19475
                                                   /* Algorithm    OBJECT IDENTIFIER */
19476
/* SIGALGO_OID                   */            { 2, ASN_OBJECT_ID, 0, 0, 0 },
19477
                                                   /* parameters   ANY defined by algorithm OPTIONAL */
19478
/* SIGALGO_PARAMS_NULL           */            { 2, ASN_TAG_NULL, 0, 0, 2 },
19479
#ifdef WC_RSA_PSS
19480
/* SIGALGO_PARAMS                */            { 2, ASN_SEQUENCE, 1, 0, 2 },
19481
#endif
19482
                                                   /* signature            BIT STRING */
19483
/* SIGNATURE                     */        { 1, ASN_BIT_STRING, 0, 0, 0 },
19484
};
19485
enum {
19486
    X509CERTASN_IDX_SEQ = 0,
19487
    X509CERTASN_IDX_TBS_SEQ,
19488
    X509CERTASN_IDX_TBS_VER,
19489
    X509CERTASN_IDX_TBS_VER_INT,
19490
    X509CERTASN_IDX_TBS_SERIAL,
19491
    X509CERTASN_IDX_TBS_ALGOID_SEQ,
19492
    X509CERTASN_IDX_TBS_ALGOID_OID,
19493
    X509CERTASN_IDX_TBS_ALGOID_PARAMS_NULL,
19494
#ifdef WC_RSA_PSS
19495
    X509CERTASN_IDX_TBS_ALGOID_PARAMS,
19496
#endif
19497
    X509CERTASN_IDX_TBS_ISSUER_SEQ,
19498
    X509CERTASN_IDX_TBS_VALIDITY_SEQ,
19499
    X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC,
19500
    X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT,
19501
    X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC,
19502
    X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT,
19503
    X509CERTASN_IDX_TBS_SUBJECT_SEQ,
19504
    X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ,
19505
    X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_SEQ,
19506
    X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_OID,
19507
    X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_NULL,
19508
    X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_CURVEID,
19509
#ifdef WC_RSA_PSS
19510
    X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_P_SEQ,
19511
#endif
19512
    X509CERTASN_IDX_TBS_SPUBKEYINFO_PUBKEY,
19513
    X509CERTASN_IDX_TBS_ISSUERUID,
19514
    X509CERTASN_IDX_TBS_SUBJECTUID,
19515
    X509CERTASN_IDX_TBS_EXT,
19516
    X509CERTASN_IDX_TBS_EXT_SEQ,
19517
    X509CERTASN_IDX_SIGALGO_SEQ,
19518
    X509CERTASN_IDX_SIGALGO_OID,
19519
    X509CERTASN_IDX_SIGALGO_PARAMS_NULL,
19520
#ifdef WC_RSA_PSS
19521
    X509CERTASN_IDX_SIGALGO_PARAMS,
19522
#endif
19523
    X509CERTASN_IDX_SIGNATURE,
19524
};
19525
19526
/* Number of items in ASN template for an X509 certificate. */
19527
#define x509CertASN_Length (sizeof(x509CertASN) / sizeof(ASNItem))
19528
19529
/* Check the data data.
19530
 *
19531
 * @param [in] dataASN   ASN template dynamic data item.
19532
 * @param [in] dataType  BEFORE or AFTER date.
19533
 * @return  0 on success.
19534
 * @return  ASN_TIME_E when BER tag is nor UTC or GENERALIZED time.
19535
 * @return  ASN_DATE_SZ_E when time data is not supported.
19536
 * @return  ASN_BEFORE_DATE_E when BEFORE date is invalid.
19537
 * @return  ASN_AFTER_DATE_E when AFTER date is invalid.
19538
 */
19539
static int CheckDate(ASNGetData *dataASN, int dateType)
19540
{
19541
    int ret = 0;
19542
19543
    /* Check BER tag is valid. */
19544
    if ((dataASN->tag != ASN_UTC_TIME) &&
19545
            (dataASN->tag != ASN_GENERALIZED_TIME)) {
19546
        ret = ASN_TIME_E;
19547
    }
19548
    /* Check date length is valid. */
19549
    if ((ret == 0) && ((dataASN->length > MAX_DATE_SIZE) ||
19550
                       (dataASN->length < MIN_DATE_SIZE))) {
19551
        ret = ASN_DATE_SZ_E;
19552
    }
19553
19554
#ifndef NO_ASN_TIME
19555
    /* Check date is a valid string and BEFORE or AFTER now. */
19556
    if ((ret == 0) &&
19557
            (!XVALIDATE_DATE(dataASN->data.ref.data, dataASN->tag, dateType))) {
19558
        if (dateType == BEFORE) {
19559
            ret = ASN_BEFORE_DATE_E;
19560
        }
19561
        else {
19562
            ret = ASN_AFTER_DATE_E;
19563
        }
19564
    }
19565
#endif
19566
    (void)dateType;
19567
19568
    return ret;
19569
}
19570
19571
/* Decode a certificate. Internal/non-public API.
19572
 *
19573
 * @param [in]  cert             Certificate object.
19574
 * @param [in]  verify           Whether to verify dates before and after now.
19575
 * @param [out] criticalExt      Critical extension return code.
19576
 * @param [out] badDateRet       Bad date return code.
19577
 * @param [in]  stopAtPubKey     Stop parsing before subkectPublicKeyInfo.
19578
 * @param [in]  stopAfterPubKey  Stop parsing after subkectPublicKeyInfo.
19579
 * @return  0 on success.
19580
 * @return  ASN_CRIT_EXT_E when a critical extension was not recognized.
19581
 * @return  ASN_TIME_E when date BER tag is nor UTC or GENERALIZED time.
19582
 * @return  ASN_DATE_SZ_E when time data is not supported.
19583
 * @return  ASN_BEFORE_DATE_E when BEFORE date is invalid.
19584
 * @return  ASN_AFTER_DATE_E when AFTER date is invalid.
19585
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
19586
 *          is invalid.
19587
 * @return  BUFFER_E when data in buffer is too small.
19588
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
19589
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
19590
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
19591
 *          non-zero length.
19592
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
19593
 */
19594
static int DecodeCertInternal(DecodedCert* cert, int verify, int* criticalExt,
19595
                              int* badDateRet, int stopAtPubKey,
19596
                              int stopAfterPubKey)
19597
{
19598
    DECL_ASNGETDATA(dataASN, x509CertASN_Length);
19599
    int ret = 0;
19600
    int badDate = 0;
19601
    int i;
19602
    byte version;
19603
    word32 idx;
19604
    word32 serialSz;
19605
    int done = 0;
19606
19607
    CALLOC_ASNGETDATA(dataASN, x509CertASN_Length, ret, cert->heap);
19608
19609
    if (ret == 0) {
19610
        version = 0;
19611
        serialSz = EXTERNAL_SERIAL_SIZE;
19612
19613
        /* Get the version and put the serial number into the buffer. */
19614
        GetASN_Int8Bit(&dataASN[X509CERTASN_IDX_TBS_VER_INT], &version);
19615
        GetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_SERIAL], cert->serial,
19616
                &serialSz);
19617
        /* Check OID types for signature, algorithm, ECC curve and sigAlg. */
19618
        GetASN_OID(&dataASN[X509CERTASN_IDX_TBS_ALGOID_OID], oidSigType);
19619
        GetASN_OID(&dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_OID],
19620
                oidKeyType);
19621
        GetASN_OID(&dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_CURVEID],
19622
                oidCurveType);
19623
        GetASN_OID(&dataASN[X509CERTASN_IDX_SIGALGO_OID], oidSigType);
19624
        /* Parse the X509 certificate. */
19625
        ret = GetASN_Items(x509CertASN, dataASN, x509CertASN_Length, 1,
19626
                           cert->source, &cert->srcIdx, cert->maxIdx);
19627
    }
19628
    /* Check version is valid/supported - can't be negative. */
19629
    if ((ret == 0) && (version > MAX_X509_VERSION)) {
19630
        WOLFSSL_MSG("Unexpected certificate version");
19631
        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
19632
        ret = ASN_PARSE_E;
19633
    }
19634
    if (ret == 0) {
19635
        /* Set fields extracted from data. */
19636
        cert->version = version;
19637
        cert->serialSz = serialSz;
19638
        cert->signatureOID = dataASN[X509CERTASN_IDX_TBS_ALGOID_OID].data.oid.sum;
19639
        cert->keyOID = dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_OID].data.oid.sum;
19640
        cert->certBegin = dataASN[X509CERTASN_IDX_TBS_SEQ].offset;
19641
19642
        /* No bad date error - don't always care. */
19643
        badDate = 0;
19644
        /* Find the item with the BEFORE date and check it. */
19645
        i = (dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC].tag != 0)
19646
                ? X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC
19647
                : X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT;
19648
        if ((CheckDate(&dataASN[i], BEFORE) < 0) && verify) {
19649
            badDate = ASN_BEFORE_DATE_E;
19650
        }
19651
        /* Store reference to BEFOREdate. */
19652
        cert->beforeDate = GetASNItem_Addr(dataASN[i], cert->source);
19653
        cert->beforeDateLen = GetASNItem_Length(dataASN[i], cert->source);
19654
19655
        /* Find the item with the AFTER date and check it. */
19656
        i = (dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC].tag != 0)
19657
                ? X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC
19658
                : X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT;
19659
        if ((CheckDate(&dataASN[i], AFTER) < 0) && verify) {
19660
            badDate = ASN_AFTER_DATE_E;
19661
        }
19662
        /* Store reference to AFTER date. */
19663
        cert->afterDate = GetASNItem_Addr(dataASN[i], cert->source);
19664
        cert->afterDateLen = GetASNItem_Length(dataASN[i], cert->source);
19665
19666
        /* Get the issuer name and calculate hash. */
19667
        idx = dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ].offset;
19668
        ret = GetCertName(cert, cert->issuer, cert->issuerHash, ISSUER,
19669
                          cert->source, &idx,
19670
                          dataASN[X509CERTASN_IDX_TBS_VALIDITY_SEQ].offset);
19671
    }
19672
    if (ret == 0) {
19673
        /* Get the subject name and calculate hash. */
19674
        idx = dataASN[X509CERTASN_IDX_TBS_SUBJECT_SEQ].offset;
19675
        ret = GetCertName(cert, cert->subject, cert->subjectHash, SUBJECT,
19676
                          cert->source, &idx,
19677
                          dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ].offset);
19678
    }
19679
    if (ret == 0) {
19680
        /* Determine if self signed by comparing issuer and subject hashes. */
19681
    #ifdef WOLFSSL_CERT_REQ
19682
        if (cert->isCSR)
19683
            cert->selfSigned = 1;
19684
        else
19685
    #endif
19686
        {
19687
            cert->selfSigned = XMEMCMP(cert->issuerHash, cert->subjectHash,
19688
                                       KEYID_SIZE) == 0 ? 1 : 0;
19689
        }
19690
19691
        if (stopAtPubKey) {
19692
            /* Return any bad date error through badDateRet and return offset of
19693
             * subjectPublicKeyInfo.
19694
             */
19695
            if (badDateRet != NULL) {
19696
                *badDateRet = badDate;
19697
            }
19698
            ret = dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ].offset;
19699
            done = 1;
19700
        }
19701
    }
19702
19703
    if ((ret == 0) && (!done)) {
19704
        /* Store the signature information. */
19705
        cert->sigIndex = dataASN[X509CERTASN_IDX_SIGALGO_SEQ].offset;
19706
        GetASN_GetConstRef(&dataASN[X509CERTASN_IDX_SIGNATURE],
19707
                &cert->signature, &cert->sigLength);
19708
        /* Make sure 'signature' and 'signatureAlgorithm' are the same. */
19709
        if (dataASN[X509CERTASN_IDX_SIGALGO_OID].data.oid.sum
19710
                != cert->signatureOID) {
19711
            WOLFSSL_ERROR_VERBOSE(ASN_SIG_OID_E);
19712
            ret = ASN_SIG_OID_E;
19713
        }
19714
        /* Parameters not allowed after ECDSA or EdDSA algorithm OID. */
19715
        else if (IsSigAlgoECC(cert->signatureOID)) {
19716
            if ((dataASN[X509CERTASN_IDX_SIGALGO_PARAMS_NULL].tag != 0)
19717
        #ifdef WC_RSA_PSS
19718
                || (dataASN[X509CERTASN_IDX_SIGALGO_PARAMS].tag != 0)
19719
        #endif
19720
                ) {
19721
                WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
19722
                ret = ASN_PARSE_E;
19723
            }
19724
        }
19725
        #ifdef WC_RSA_PSS
19726
        /* Check parameters starting with a SEQUENCE. */
19727
        else if (dataASN[X509CERTASN_IDX_SIGALGO_PARAMS].tag != 0) {
19728
            word32 oid = dataASN[X509CERTASN_IDX_SIGALGO_OID].data.oid.sum;
19729
            word32 sigAlgParamsSz;
19730
19731
            /* Parameters only with RSA PSS. */
19732
            if (oid != CTC_RSASSAPSS) {
19733
                WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
19734
                ret = ASN_PARSE_E;
19735
            }
19736
            if (ret == 0) {
19737
                const byte* tbsParams;
19738
                word32 tbsParamsSz;
19739
                const byte* sigAlgParams;
19740
19741
                /* Check RSA PSS parameters are the same. */
19742
                tbsParams =
19743
                    GetASNItem_Addr(dataASN[X509CERTASN_IDX_TBS_ALGOID_PARAMS],
19744
                        cert->source);
19745
                tbsParamsSz =
19746
                    GetASNItem_Length(dataASN[X509CERTASN_IDX_TBS_ALGOID_PARAMS],
19747
                        cert->source);
19748
                sigAlgParams =
19749
                    GetASNItem_Addr(dataASN[X509CERTASN_IDX_SIGALGO_PARAMS],
19750
                        cert->source);
19751
                sigAlgParamsSz =
19752
                    GetASNItem_Length(dataASN[X509CERTASN_IDX_SIGALGO_PARAMS],
19753
                        cert->source);
19754
                if ((tbsParamsSz != sigAlgParamsSz) ||
19755
                        (XMEMCMP(tbsParams, sigAlgParams, tbsParamsSz) != 0)) {
19756
                    WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
19757
                    ret = ASN_PARSE_E;
19758
                }
19759
            }
19760
            if (ret == 0) {
19761
                /* Store parameters for use in signature verification. */
19762
                cert->sigParamsIndex =
19763
                    dataASN[X509CERTASN_IDX_SIGALGO_PARAMS].offset;
19764
                cert->sigParamsLength = sigAlgParamsSz;
19765
            }
19766
        }
19767
        #endif
19768
    }
19769
    if ((ret == 0) && (!done)) {
19770
        /* Parse the public key. */
19771
        idx = dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ].offset;
19772
        ret = GetCertKey(cert, cert->source, &idx,
19773
                dataASN[X509CERTASN_IDX_TBS_ISSUERUID].offset);
19774
        if ((ret == 0) && stopAfterPubKey) {
19775
            /* Return any bad date error through badDateRed and return offset
19776
             * after subjectPublicKeyInfo.
19777
             */
19778
            if (badDateRet != NULL) {
19779
                *badDateRet = badDate;
19780
            }
19781
            done = 1;
19782
        }
19783
    }
19784
    if ((ret == 0) && (!done) &&
19785
            (dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].data.ref.data != NULL)) {
19786
    #ifndef ALLOW_V1_EXTENSIONS
19787
        /* Certificate extensions were only defined in version 2. */
19788
        if (cert->version < 2) {
19789
            WOLFSSL_MSG("\tv1 and v2 certs not allowed extensions");
19790
            WOLFSSL_ERROR_VERBOSE(ASN_VERSION_E);
19791
            ret = ASN_VERSION_E;
19792
        }
19793
    #endif
19794
        if (ret == 0) {
19795
            /* Save references to extension data. */
19796
            cert->extensions    = GetASNItem_Addr(
19797
                    dataASN[X509CERTASN_IDX_TBS_EXT], cert->source);
19798
            cert->extensionsSz  = GetASNItem_Length(
19799
                    dataASN[X509CERTASN_IDX_TBS_EXT], cert->source);
19800
            cert->extensionsIdx = dataASN[X509CERTASN_IDX_TBS_EXT].offset;
19801
19802
            /* Decode the extension data starting at [3]. */
19803
            ret = DecodeCertExtensions(cert);
19804
            if (criticalExt != NULL) {
19805
                if (ret == ASN_CRIT_EXT_E) {
19806
                    /* Return critical extension not recognized. */
19807
                    *criticalExt = ret;
19808
                    ret = 0;
19809
                }
19810
                else {
19811
                    /* No critical extension error. */
19812
                    *criticalExt = 0;
19813
                }
19814
            }
19815
        }
19816
        if (ret == 0) {
19817
            /* Advance past extensions. */
19818
            cert->srcIdx = dataASN[X509CERTASN_IDX_SIGALGO_SEQ].offset;
19819
        }
19820
    }
19821
19822
    if ((ret == 0) && (!done) && (badDate != 0)) {
19823
        /* Parsed whole certificate fine but return any date errors. */
19824
        ret = badDate;
19825
    }
19826
19827
    FREE_ASNGETDATA(dataASN, cert->heap);
19828
    return ret;
19829
}
19830
19831
/* Decode BER/DER data into certificate object.
19832
 *
19833
 * BER/DER data information held in source, srcIdx and maxIdx fields of
19834
 * certificate object.
19835
 *
19836
 * @param [in] cert         Decoded certificate object.
19837
 * @param [in] verify       Whether to find CA and verify certificate.
19838
 * @param [in] criticalExt  Any error for critical extensions not recognized.
19839
 * @return  0 on success.
19840
 * @return  ASN_CRIT_EXT_E when a critical extension was not recognized.
19841
 * @return  ASN_TIME_E when date BER tag is nor UTC or GENERALIZED time.
19842
 * @return  ASN_DATE_SZ_E when time data is not supported.
19843
 * @return  ASN_BEFORE_DATE_E when BEFORE date is invalid.
19844
 * @return  ASN_AFTER_DATE_E when AFTER date is invalid.
19845
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
19846
 *          is invalid.
19847
 * @return  BUFFER_E when data in buffer is too small.
19848
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
19849
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
19850
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
19851
 *          non-zero length.
19852
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
19853
 */
19854
int DecodeCert(DecodedCert* cert, int verify, int* criticalExt)
19855
{
19856
    return DecodeCertInternal(cert, verify, criticalExt, NULL, 0, 0);
19857
}
19858
19859
#ifdef WOLFSSL_CERT_REQ
19860
/* ASN.1 template for certificate request Attribute.
19861
 * PKCS #10: RFC 2986, 4.1 - CertificationRequestInfo
19862
 */
19863
static const ASNItem reqAttrASN[] = {
19864
/* SEQ  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
19865
                              /* type */
19866
/* TYPE */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
19867
                              /* values */
19868
/* VALS */     { 1, ASN_SET, 1, 0, 0 },
19869
};
19870
enum {
19871
    REQATTRASN_IDX_SEQ = 0,
19872
    REQATTRASN_IDX_TYPE,
19873
    REQATTRASN_IDX_VALS,
19874
};
19875
19876
/* Number of items in ASN.1 template for certificate request Attribute. */
19877
#define reqAttrASN_Length (sizeof(reqAttrASN) / sizeof(ASNItem))
19878
19879
/* ASN.1 template for a string choice. */
19880
static const ASNItem strAttrASN[] = {
19881
    { 0, 0, 0, 0, 0 },
19882
};
19883
enum {
19884
    STRATTRASN_IDX_STR = 0,
19885
};
19886
19887
/* Number of items in ASN.1 template for a string choice. */
19888
#define strAttrASN_Length (sizeof(strAttrASN) / sizeof(ASNItem))
19889
19890
/* ASN.1 choices for types for a string in an attribute. */
19891
static const byte strAttrChoice[] = {
19892
    ASN_PRINTABLE_STRING, ASN_IA5_STRING, ASN_UTF8STRING, 0
19893
};
19894
19895
/* Decode a certificate request attribute's value.
19896
 *
19897
 * @param [in]  cert         Certificate request object.
19898
 * @param [out] criticalExt  Critical extension return code.
19899
 * @param [in]  oid          OID decribing which attribute was found.
19900
 * @param [in]  aIdx         Index into certificate source to start parsing.
19901
 * @param [in]  input        Attribute value data.
19902
 * @param [in]  maxIdx       Maximum index to parse to.
19903
 * @return  0 on success.
19904
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
19905
 *          is invalid.
19906
 */
19907
static int DecodeCertReqAttrValue(DecodedCert* cert, int* criticalExt,
19908
    word32 oid, word32 aIdx, const byte* input, word32 maxIdx)
19909
{
19910
    int ret = 0;
19911
    word32 idx = 0;
19912
    ASNGetData strDataASN[strAttrASN_Length];
19913
19914
    switch (oid) {
19915
        case PKCS9_CONTENT_TYPE_OID:
19916
            /* Clear dynamic data and specify choices acceptable. */
19917
            XMEMSET(strDataASN, 0, sizeof(strDataASN));
19918
            GetASN_Choice(&strDataASN[STRATTRASN_IDX_STR], strAttrChoice);
19919
            /* Parse a string. */
19920
            ret = GetASN_Items(strAttrASN, strDataASN, strAttrASN_Length,
19921
                               1, input, &idx, maxIdx);
19922
            if (ret == 0) {
19923
                /* Store references to password data. */
19924
                cert->contentType =
19925
                        (char*)strDataASN[STRATTRASN_IDX_STR].data.ref.data;
19926
                cert->contentTypeLen =
19927
                        strDataASN[STRATTRASN_IDX_STR].data.ref.length;
19928
            }
19929
            break;
19930
19931
        /* A password by which the entity may request certificate revocation.
19932
         * PKCS#9: RFC 2985, 5.4.1 - Challenge password
19933
         */
19934
        case CHALLENGE_PASSWORD_OID:
19935
            /* Clear dynamic data and specify choices acceptable. */
19936
            XMEMSET(strDataASN, 0, sizeof(strDataASN));
19937
            GetASN_Choice(&strDataASN[STRATTRASN_IDX_STR], strAttrChoice);
19938
            /* Parse a string. */
19939
            ret = GetASN_Items(strAttrASN, strDataASN, strAttrASN_Length,
19940
                               1, input, &idx, maxIdx);
19941
            if (ret == 0) {
19942
                /* Store references to password data. */
19943
                cert->cPwd =
19944
                        (char*)strDataASN[STRATTRASN_IDX_STR].data.ref.data;
19945
                cert->cPwdLen = strDataASN[STRATTRASN_IDX_STR].data.ref.length;
19946
            }
19947
            break;
19948
19949
        /* Requested serial number to issue with.
19950
         * PKCS#9: RFC 2985, 5.2.10 - Serial Number
19951
         * (References: ISO/IEC 9594-6:1997)
19952
         */
19953
        case SERIAL_NUMBER_OID:
19954
            /* Clear dynamic data and specify choices acceptable. */
19955
            XMEMSET(strDataASN, 0, sizeof(strDataASN));
19956
            GetASN_Choice(&strDataASN[STRATTRASN_IDX_STR], strAttrChoice);
19957
            /* Parse a string. */
19958
            ret = GetASN_Items(strAttrASN, strDataASN, strAttrASN_Length,
19959
                               1, input, &idx, maxIdx);
19960
            if (ret == 0) {
19961
                /* Store references to serial number. */
19962
                cert->sNum =
19963
                        (char*)strDataASN[STRATTRASN_IDX_STR].data.ref.data;
19964
                cert->sNumLen = strDataASN[STRATTRASN_IDX_STR].data.ref.length;
19965
                /* Store serial number if small enough. */
19966
                if (cert->sNumLen <= EXTERNAL_SERIAL_SIZE) {
19967
                    XMEMCPY(cert->serial, cert->sNum, cert->sNumLen);
19968
                    cert->serialSz = cert->sNumLen;
19969
                }
19970
            }
19971
            break;
19972
19973
        /* Certificate extensions to be included in generated certificate.
19974
         * PKCS#9: RFC 2985, 5.4.2 - Extension request
19975
         */
19976
        case EXTENSION_REQUEST_OID:
19977
            /* Store references to all extensions. */
19978
            cert->extensions    = input;
19979
            cert->extensionsSz  = maxIdx;
19980
            cert->extensionsIdx = aIdx;
19981
19982
            /* Decode and validate extensions. */
19983
            ret = DecodeCertExtensions(cert);
19984
            if (ret == ASN_CRIT_EXT_E) {
19985
                /* Return critical extension not recognized. */
19986
                *criticalExt = ret;
19987
                ret = 0;
19988
            }
19989
            else {
19990
                /* No critical extension error. */
19991
                *criticalExt = 0;
19992
            }
19993
            break;
19994
19995
        default:
19996
            ret = ASN_PARSE_E;
19997
            break;
19998
    }
19999
20000
    return ret;
20001
}
20002
20003
/* Decode attributes of a BER encoded certificate request.
20004
 *
20005
 * RFC 2986 - PKCS #10: Certification Request Syntax Specification Version 1.7
20006
 *
20007
 * Outer sequence has been removed.
20008
 *
20009
 * @param [in]  cert         Certificate request object.
20010
 * @param [out] criticalExt  Critical extension return code.
20011
 * @param [in]  idx          Index into certificate source to start parsing.
20012
 * @param [in]  maxIdx       Maximum index to parse to.
20013
 * @return  0 on success.
20014
 * @return  ASN_CRIT_EXT_E when a critical extension was not recognized.
20015
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
20016
 *          is invalid.
20017
 * @return  BUFFER_E when data in buffer is too small.
20018
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
20019
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
20020
 *          non-zero length.
20021
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
20022
 */
20023
static int DecodeCertReqAttributes(DecodedCert* cert, int* criticalExt,
20024
                                   word32 idx, word32 maxIdx)
20025
{
20026
    DECL_ASNGETDATA(dataASN, reqAttrASN_Length);
20027
    int ret = 0;
20028
20029
    WOLFSSL_ENTER("DecodeCertReqAttributes");
20030
20031
    ALLOC_ASNGETDATA(dataASN, reqAttrASN_Length, ret, cert->heap);
20032
20033
    /* Parse each attribute until all data used up. */
20034
    while ((ret == 0) && (idx < maxIdx)) {
20035
        /* Clear dynamic data. */
20036
        XMEMSET(dataASN, 0, sizeof(ASNGetData) * reqAttrASN_Length);
20037
        GetASN_OID(&dataASN[REQATTRASN_IDX_TYPE], oidIgnoreType);
20038
20039
        /* Parse an attribute. */
20040
        ret = GetASN_Items(reqAttrASN, dataASN, reqAttrASN_Length, 0,
20041
                           cert->source, &idx, maxIdx);
20042
        /* idx is now at end of attribute data. */
20043
        if (ret == 0) {
20044
            ret = DecodeCertReqAttrValue(cert, criticalExt,
20045
                dataASN[REQATTRASN_IDX_TYPE].data.oid.sum,
20046
                GetASNItem_DataIdx(dataASN[REQATTRASN_IDX_VALS], cert->source),
20047
                dataASN[REQATTRASN_IDX_VALS].data.ref.data,
20048
                dataASN[REQATTRASN_IDX_VALS].data.ref.length);
20049
        }
20050
    }
20051
20052
    FREE_ASNGETDATA(dataASN, cert->heap);
20053
    return ret;
20054
}
20055
20056
/* ASN.1 template for a certificate request.
20057
 * PKCS#10: RFC 2986, 4.1 - CertificationRequestInfo
20058
 * PKCS#10: RFC 2986, 4.2 - CertificationRequest
20059
 */
20060
static const ASNItem certReqASN[] = {
20061
            /* CertificationRequest */
20062
/* SEQ                              */ { 0, ASN_SEQUENCE, 1, 1, 0 },
20063
                                                          /* CertificationRequestInfo */
20064
/* INFO_SEQ                         */     { 1, ASN_SEQUENCE, 1, 1, 0 },
20065
                                                              /* version              INTEGER { v1(0), v2(1), v3(2) */
20066
/* INFO_VER                         */         { 2, ASN_INTEGER, 0, 0, 0 },
20067
                                                              /* subject              Name */
20068
/* INFO_SUBJ_SEQ                    */         { 2, ASN_SEQUENCE, 1, 0, 0 },
20069
                                                              /* subjectPublicKeyInfo SubjectPublicKeyInfo */
20070
/* INFO_SPUBKEYINFO_SEQ             */         { 2, ASN_SEQUENCE, 1, 1, 0 },
20071
                                                                  /* algorithm          AlgorithmIdentifier */
20072
/* INFO_SPUBKEYINFO_ALGOID_SEQ      */             { 3, ASN_SEQUENCE, 1, 1, 0 },
20073
                                                                      /* Algorithm    OBJECT IDENTIFIER */
20074
/* INFO_SPUBKEYINFO_ALGOID_OID      */                 { 4, ASN_OBJECT_ID, 0, 0, 0 },
20075
                                                                      /* parameters   ANY defined by algorithm OPTIONAL */
20076
/* INFO_SPUBKEYINFO_ALGOID_NULL     */                 { 4, ASN_TAG_NULL, 0, 0, 1 },
20077
/* INFO_SPUBKEYINFO_ALGOID_CURVEID  */                 { 4, ASN_OBJECT_ID, 0, 0, 1 },
20078
/* INFO_SPUBKEYINFO_ALGOID_PARAMS   */                 { 4, ASN_SEQUENCE, 1, 0, 1 },
20079
                                                                  /* subjectPublicKey   BIT STRING */
20080
/* INFO_SPUBKEYINFO_PUBKEY          */             { 3, ASN_BIT_STRING, 0, 0, 0 },
20081
                                                              /* attributes       [0] Attributes */
20082
/* INFO_ATTRS                       */         { 2, ASN_CONTEXT_SPECIFIC | 0, 1, 0, 1 },
20083
                                                          /* signatureAlgorithm   AlgorithmIdentifier */
20084
/* INFO_SIGALGO_SEQ                 */     { 1, ASN_SEQUENCE, 1, 1, 0 },
20085
                                                              /* Algorithm    OBJECT IDENTIFIER */
20086
/* INFO_SIGALGO_OID                 */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
20087
                                                              /* parameters   ANY defined by algorithm OPTIONAL */
20088
/* INFO_SIGALGO_NULL                */         { 2, ASN_TAG_NULL, 0, 0, 1 },
20089
                                                          /* signature            BIT STRING */
20090
/* INFO_SIGNATURE                   */     { 1, ASN_BIT_STRING, 0, 0, 0 },
20091
};
20092
enum {
20093
    CERTREQASN_IDX_SEQ = 0,
20094
    CERTREQASN_IDX_INFO_SEQ,
20095
    CERTREQASN_IDX_INFO_VER,
20096
    CERTREQASN_IDX_INFO_SUBJ_SEQ,
20097
    CERTREQASN_IDX_INFO_SPUBKEYINFO_SEQ,
20098
    CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_SEQ,
20099
    CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_OID,
20100
    CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_NULL,
20101
    CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_CURVEID,
20102
    CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_PARAMS,
20103
    CERTREQASN_IDX_INFO_SPUBKEYINFO_PUBKEY,
20104
    CERTREQASN_IDX_INFO_ATTRS,
20105
    CERTREQASN_IDX_INFO_SIGALGO_SEQ,
20106
    CERTREQASN_IDX_INFO_SIGALGO_OID,
20107
    CERTREQASN_IDX_INFO_SIGALGO_NULL,
20108
    CERTREQASN_IDX_INFO_SIGNATURE,
20109
};
20110
20111
/* Number of items in ASN.1 template for a certificate request. */
20112
#define certReqASN_Length (sizeof(certReqASN) / sizeof(ASNItem))
20113
20114
/* Parse BER encoded certificate request.
20115
 *
20116
 * RFC 2986 - PKCS #10: Certification Request Syntax Specification Version 1.7
20117
 *
20118
 * @param [in]  cert         Certificate request object.
20119
 * @param [out] criticalExt  Critical extension return code.
20120
 * @return  0 on success.
20121
 * @return  ASN_CRIT_EXT_E when a critical extension was not recognized.
20122
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
20123
 *          is invalid.
20124
 * @return  BUFFER_E when data in buffer is too small.
20125
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
20126
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
20127
 *          non-zero length.
20128
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
20129
 * @return  MEMORY_E on dynamic memory allocation failure.
20130
 */
20131
static int DecodeCertReq(DecodedCert* cert, int* criticalExt)
20132
{
20133
    DECL_ASNGETDATA(dataASN, certReqASN_Length);
20134
    int ret = 0;
20135
    byte version;
20136
    word32 idx;
20137
20138
    CALLOC_ASNGETDATA(dataASN, certReqASN_Length, ret, cert->heap);
20139
20140
    if (ret == 0) {
20141
        /* Default version is 0. */
20142
        version = 0;
20143
20144
        /* Set version var and OID types to expect. */
20145
        GetASN_Int8Bit(&dataASN[CERTREQASN_IDX_INFO_VER], &version);
20146
        GetASN_OID(&dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_OID],
20147
                oidKeyType);
20148
        GetASN_OID(&dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_CURVEID],
20149
                oidCurveType);
20150
        GetASN_OID(&dataASN[CERTREQASN_IDX_INFO_SIGALGO_OID], oidSigType);
20151
        /* Parse a certificate request. */
20152
        ret = GetASN_Items(certReqASN, dataASN, certReqASN_Length, 1,
20153
                           cert->source, &cert->srcIdx, cert->maxIdx);
20154
    }
20155
    /* Check version is valid/supported - can't be negative. */
20156
    if ((ret == 0) && (version > MAX_X509_VERSION)) {
20157
        WOLFSSL_MSG("Unexpected certificate request version");
20158
        ret = ASN_PARSE_E;
20159
    }
20160
    if (ret == 0) {
20161
        /* Set fields of certificate request. */
20162
        cert->version = version;
20163
        cert->signatureOID =
20164
              dataASN[CERTREQASN_IDX_INFO_SIGALGO_OID].data.oid.sum;
20165
        cert->keyOID =
20166
              dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_OID].data.oid.sum;
20167
        cert->certBegin = dataASN[CERTREQASN_IDX_INFO_SEQ].offset;
20168
20169
        /* Parse the subject name. */
20170
        idx = dataASN[CERTREQASN_IDX_INFO_SUBJ_SEQ].offset;
20171
        ret = GetCertName(cert, cert->subject, cert->subjectHash, SUBJECT,
20172
                          cert->source, &idx,
20173
                          dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_SEQ].offset);
20174
    }
20175
    if (ret == 0) {
20176
        /* Parse the certificate request Attributes. */
20177
        ret = DecodeCertReqAttributes(cert, criticalExt,
20178
                GetASNItem_DataIdx(dataASN[CERTREQASN_IDX_INFO_ATTRS],
20179
                        cert->source),
20180
                dataASN[CERTREQASN_IDX_INFO_SIGALGO_SEQ].offset);
20181
    }
20182
    if (ret == 0) {
20183
        /* Parse the certificate request's key. */
20184
        idx = dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_SEQ].offset;
20185
        ret = GetCertKey(cert, cert->source, &idx,
20186
                dataASN[CERTREQASN_IDX_INFO_ATTRS].offset);
20187
    }
20188
    if (ret == 0) {
20189
        /* Store references to signature. */
20190
        cert->sigIndex = dataASN[CERTREQASN_IDX_INFO_SIGALGO_SEQ].offset;
20191
        GetASN_GetConstRef(&dataASN[CERTREQASN_IDX_INFO_SIGNATURE],
20192
                &cert->signature, &cert->sigLength);
20193
    }
20194
20195
    FREE_ASNGETDATA(dataASN, cert->heap);
20196
    return ret;
20197
}
20198
20199
#endif /* WOLFSSL_CERT_REQ */
20200
20201
#endif
20202
20203
int ParseCert(DecodedCert* cert, int type, int verify, void* cm)
20204
0
{
20205
0
    int   ret;
20206
0
#if !defined(WOLFSSL_NO_MALLOC) || defined(WOLFSSL_DYN_CERT)
20207
0
    char* ptr;
20208
0
#endif
20209
20210
0
    ret = ParseCertRelative(cert, type, verify, cm);
20211
0
    if (ret < 0)
20212
0
        return ret;
20213
20214
0
#if !defined(WOLFSSL_NO_MALLOC) || defined(WOLFSSL_DYN_CERT)
20215
    /* cert->subjectCN not stored as copy of WOLFSSL_NO_MALLOC defind */
20216
0
    if (cert->subjectCNLen > 0) {
20217
0
        ptr = (char*) XMALLOC(cert->subjectCNLen + 1, cert->heap,
20218
0
                              DYNAMIC_TYPE_SUBJECT_CN);
20219
0
        if (ptr == NULL)
20220
0
            return MEMORY_E;
20221
0
        XMEMCPY(ptr, cert->subjectCN, cert->subjectCNLen);
20222
0
        ptr[cert->subjectCNLen] = '\0';
20223
0
        cert->subjectCN = ptr;
20224
0
        cert->subjectCNStored = 1;
20225
0
    }
20226
0
#endif
20227
20228
0
#if !defined(WOLFSSL_NO_MALLOC) || defined(WOLFSSL_DYN_CERT)
20229
    /* cert->publicKey not stored as copy if WOLFSSL_NO_MALLOC defined */
20230
0
    if ((cert->keyOID == RSAk
20231
0
    #ifdef WC_RSA_PSS
20232
0
         || cert->keyOID == RSAPSSk
20233
0
    #endif
20234
0
         ) && cert->publicKey != NULL && cert->pubKeySize > 0) {
20235
0
        ptr = (char*) XMALLOC(cert->pubKeySize, cert->heap,
20236
0
                              DYNAMIC_TYPE_PUBLIC_KEY);
20237
0
        if (ptr == NULL)
20238
0
            return MEMORY_E;
20239
0
        XMEMCPY(ptr, cert->publicKey, cert->pubKeySize);
20240
0
        cert->publicKey = (byte *)ptr;
20241
0
        cert->pubKeyStored = 1;
20242
0
    }
20243
0
#endif
20244
20245
0
    return ret;
20246
0
}
20247
20248
int wc_ParseCert(DecodedCert* cert, int type, int verify, void* cm)
20249
0
{
20250
0
    return ParseCert(cert, type, verify, cm);
20251
0
}
20252
20253
#if !defined(OPENSSL_EXTRA) && !defined(OPENSSL_EXTRA_X509_SMALL) && \
20254
    !defined(GetCA)
20255
/* from SSL proper, for locking can't do find here anymore.
20256
 * brought in from internal.h if built with compat layer.
20257
 * if defined(GetCA), it's a predefined macro and these prototypes
20258
 * would conflict.
20259
 */
20260
#ifdef __cplusplus
20261
    extern "C" {
20262
#endif
20263
    Signer* GetCA(void* signers, byte* hash);
20264
    #ifndef NO_SKID
20265
        Signer* GetCAByName(void* signers, byte* hash);
20266
    #endif
20267
#ifdef __cplusplus
20268
    }
20269
#endif
20270
20271
#endif /* !OPENSSL_EXTRA && !OPENSSL_EXTRA_X509_SMALL && !GetCA */
20272
20273
#if defined(WOLFCRYPT_ONLY)
20274
20275
/* dummy functions, not using wolfSSL so don't need actual ones */
20276
Signer* GetCA(void* signers, byte* hash)
20277
{
20278
    (void)hash;
20279
20280
    return (Signer*)signers;
20281
}
20282
20283
#ifndef NO_SKID
20284
Signer* GetCAByName(void* signers, byte* hash)
20285
{
20286
    (void)hash;
20287
20288
    return (Signer*)signers;
20289
}
20290
#endif /* NO_SKID */
20291
20292
#endif /* WOLFCRYPT_ONLY */
20293
20294
#if defined(WOLFSSL_NO_TRUSTED_CERTS_VERIFY) && !defined(NO_SKID)
20295
static Signer* GetCABySubjectAndPubKey(DecodedCert* cert, void* cm)
20296
{
20297
    Signer* ca = NULL;
20298
    if (cert->extSubjKeyIdSet)
20299
        ca = GetCA(cm, cert->extSubjKeyId);
20300
    if (ca == NULL)
20301
        ca = GetCAByName(cm, cert->subjectHash);
20302
    if (ca) {
20303
        if ((ca->pubKeySize == cert->pubKeySize) &&
20304
               (XMEMCMP(ca->publicKey, cert->publicKey, ca->pubKeySize) == 0)) {
20305
            return ca;
20306
        }
20307
    }
20308
    return NULL;
20309
}
20310
#endif
20311
20312
#if defined(WOLFSSL_SMALL_CERT_VERIFY) || defined(OPENSSL_EXTRA)
20313
#ifdef WOLFSSL_ASN_TEMPLATE
20314
/* Get the Hash of the Authority Key Identifier from the list of extensions.
20315
 *
20316
 * @param [in]  input   Input data.
20317
 * @param [in]  maxIdx  Maximum index for data.
20318
 * @param [out] hash    Hash of AKI.
20319
 * @param [out] set     Whether the hash buffer was set.
20320
 * @param [in]  heap    Dynamic memory allocation hint.
20321
 * @return  0 on success.
20322
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
20323
 *          is invalid.
20324
 * @return  MEMORY_E on dynamic memory allocation failure.
20325
 */
20326
static int GetAKIHash(const byte* input, word32 maxIdx, byte* hash, int* set,
20327
                      void* heap)
20328
{
20329
    /* AKI and Certificate Extenion ASN.1 templates are the same length. */
20330
    DECL_ASNGETDATA(dataASN, certExtASN_Length);
20331
    int ret = 0;
20332
    word32 idx = 0;
20333
    word32 extEndIdx;
20334
    byte* extData;
20335
    word32 extDataSz;
20336
    byte critical;
20337
20338
    ALLOC_ASNGETDATA(dataASN, certExtASN_Length, ret, heap);
20339
    (void)heap;
20340
20341
    extEndIdx = idx + maxIdx;
20342
20343
    /* Step through each extension looking for AKI. */
20344
    while ((ret == 0) && (idx < extEndIdx)) {
20345
        /* Clear dynamic data and check for certificate extension type OIDs. */
20346
        XMEMSET(dataASN, 0, sizeof(*dataASN) * certExtASN_Length);
20347
        GetASN_OID(&dataASN[CERTEXTASN_IDX_OID], oidCertExtType);
20348
        /* Set criticality variable. */
20349
        GetASN_Int8Bit(&dataASN[CERTEXTASN_IDX_CRIT], &critical);
20350
        /* Parse an extension. */
20351
        ret = GetASN_Items(certExtASN, dataASN, certExtASN_Length, 0, input,
20352
                &idx, extEndIdx);
20353
        if (ret == 0) {
20354
            /* Get reference to extension data and move index on past this
20355
             * extension. */
20356
            GetASN_GetRef(&dataASN[CERTEXTASN_IDX_VAL], &extData, &extDataSz);
20357
            idx += extDataSz;
20358
20359
            /* Check whether we have the AKI extension. */
20360
            if (dataASN[CERTEXTASN_IDX_OID].data.oid.sum == AUTH_KEY_OID) {
20361
                /* Clear dynamic data. */
20362
                XMEMSET(dataASN, 0, sizeof(*dataASN) * authKeyIdASN_Length);
20363
                /* Start parsing extension data from the start. */
20364
                idx = 0;
20365
                /* Parse AKI extension data. */
20366
                ret = GetASN_Items(authKeyIdASN, dataASN, authKeyIdASN_Length,
20367
                        1, extData, &idx, extDataSz);
20368
                if ((ret == 0) &&
20369
                        (dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data
20370
                                != NULL)) {
20371
                    /* We parsed successfully and have data. */
20372
                    *set = 1;
20373
                    /* Get the hash or hash of the hash if wrong size. */
20374
                    ret = GetHashId(
20375
                            dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data,
20376
                            dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.length,
20377
                            hash);
20378
                }
20379
                break;
20380
            }
20381
        }
20382
    }
20383
20384
    FREE_ASNGETDATA(dataASN, heap);
20385
    return ret;
20386
}
20387
#endif
20388
20389
/* Only quick step through the certificate to find fields that are then used
20390
 * in certificate signature verification.
20391
 * Must use the signature OID from the signed part of the certificate.
20392
 * Works also on certificate signing requests.
20393
 *
20394
 * This is only for minimizing dynamic memory usage during TLS certificate
20395
 * chain processing.
20396
 * Doesn't support:
20397
 *   OCSP Only: alt lookup using subject and pub key w/o sig check
20398
 */
20399
static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap,
20400
        void* cm, const byte* pubKey, word32 pubKeySz, int pubKeyOID, int req)
20401
{
20402
#ifndef WOLFSSL_ASN_TEMPLATE
20403
#ifndef WOLFSSL_SMALL_STACK
20404
    SignatureCtx  sigCtx[1];
20405
#else
20406
    SignatureCtx* sigCtx;
20407
#endif
20408
    byte          hash[KEYID_SIZE];
20409
    Signer*       ca = NULL;
20410
    word32        idx = 0;
20411
    int           len;
20412
    word32        tbsCertIdx = 0;
20413
    word32        sigIndex   = 0;
20414
    word32        signatureOID = 0;
20415
    word32        oid = 0;
20416
    word32        issuerIdx = 0;
20417
    word32        issuerSz  = 0;
20418
#ifndef NO_SKID
20419
    int           extLen = 0;
20420
    word32        extIdx = 0;
20421
    word32        extEndIdx = 0;
20422
    int           extAuthKeyIdSet = 0;
20423
#endif
20424
    int           ret = 0;
20425
    word32        localIdx;
20426
    byte          tag;
20427
    const byte*   sigParams = NULL;
20428
    word32        sigParamsSz = 0;
20429
20430
20431
    if (cert == NULL) {
20432
        return BAD_FUNC_ARG;
20433
    }
20434
20435
#ifdef WOLFSSL_SMALL_STACK
20436
    sigCtx = (SignatureCtx*)XMALLOC(sizeof(*sigCtx), heap, DYNAMIC_TYPE_SIGNATURE);
20437
    if (sigCtx == NULL)
20438
        return MEMORY_E;
20439
#endif
20440
    InitSignatureCtx(sigCtx, heap, INVALID_DEVID);
20441
20442
    /* Certificate SEQUENCE */
20443
    if (GetSequence(cert, &idx, &len, certSz) < 0)
20444
        ret = ASN_PARSE_E;
20445
    if (ret == 0) {
20446
        tbsCertIdx = idx;
20447
20448
        /* TBSCertificate SEQUENCE */
20449
        if (GetSequence(cert, &idx, &len, certSz) < 0)
20450
            ret = ASN_PARSE_E;
20451
    }
20452
    if (ret == 0) {
20453
        sigIndex = len + idx;
20454
20455
        if ((idx + 1) > certSz)
20456
            ret = BUFFER_E;
20457
    }
20458
    if (ret == 0) {
20459
        /* version - optional */
20460
        localIdx = idx;
20461
        if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) {
20462
            if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
20463
                idx++;
20464
                if (GetLength(cert, &idx, &len, certSz) < 0)
20465
                    ret = ASN_PARSE_E;
20466
                idx += len;
20467
            }
20468
        }
20469
    }
20470
20471
    if (ret == 0) {
20472
        /* serialNumber */
20473
        if (GetASNHeader(cert, ASN_INTEGER, &idx, &len, certSz) < 0)
20474
            ret = ASN_PARSE_E;
20475
    }
20476
    if (ret == 0) {
20477
        idx += len;
20478
20479
        /* signature */
20480
        if (!req) {
20481
            if (GetAlgoId(cert, &idx, &signatureOID, oidSigType, certSz) < 0)
20482
                ret = ASN_PARSE_E;
20483
        #ifdef WC_RSA_PSS
20484
            else if (signatureOID == CTC_RSASSAPSS) {
20485
                int start = idx;
20486
                sigParams = cert + idx;
20487
                if (GetSequence(cert, &idx, &len, certSz) < 0)
20488
                    ret = ASN_PARSE_E;
20489
                if (ret == 0) {
20490
                    idx += len;
20491
                    sigParamsSz = idx - start;
20492
                }
20493
            }
20494
        #endif
20495
        }
20496
    }
20497
20498
    if (ret == 0) {
20499
        issuerIdx = idx;
20500
        /* issuer for cert or subject for csr */
20501
        if (GetSequence(cert, &idx, &len, certSz) < 0)
20502
            ret = ASN_PARSE_E;
20503
    }
20504
    if (ret == 0) {
20505
        issuerSz = len + idx - issuerIdx;
20506
    }
20507
#ifndef NO_SKID
20508
    if (!req && ret == 0) {
20509
        idx += len;
20510
20511
        /* validity */
20512
        if (GetSequence(cert, &idx, &len, certSz) < 0)
20513
            ret = ASN_PARSE_E;
20514
    }
20515
    if (!req && ret == 0) {
20516
        idx += len;
20517
20518
        /* subject */
20519
        if (GetSequence(cert, &idx, &len, certSz) < 0)
20520
            ret = ASN_PARSE_E;
20521
    }
20522
    if (ret == 0) {
20523
        idx += len;
20524
20525
        /* subjectPublicKeyInfo */
20526
        if (GetSequence(cert, &idx, &len, certSz) < 0)
20527
            ret = ASN_PARSE_E;
20528
    }
20529
    if (req && ret == 0) {
20530
        idx += len;
20531
20532
        /* attributes */
20533
        if (GetASNHeader_ex(cert,
20534
                ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED, &idx,
20535
                &len, certSz, 1) < 0)
20536
            ret = ASN_PARSE_E;
20537
    }
20538
    if (!req) {
20539
        if (ret == 0) {
20540
            idx += len;
20541
20542
            if ((idx + 1) > certSz)
20543
                ret = BUFFER_E;
20544
        }
20545
        if (ret == 0) {
20546
            /* issuerUniqueID - optional */
20547
            localIdx = idx;
20548
            if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) {
20549
                if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) {
20550
                    idx++;
20551
                    if (GetLength(cert, &idx, &len, certSz) < 0)
20552
                        ret = ASN_PARSE_E;
20553
                    idx += len;
20554
                }
20555
            }
20556
        }
20557
        if (ret == 0) {
20558
            if ((idx + 1) > certSz)
20559
                ret = BUFFER_E;
20560
        }
20561
        if (ret == 0) {
20562
            /* subjectUniqueID - optional */
20563
            localIdx = idx;
20564
            if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) {
20565
                if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)) {
20566
                    idx++;
20567
                    if (GetLength(cert, &idx, &len, certSz) < 0)
20568
                        ret = ASN_PARSE_E;
20569
                    idx += len;
20570
                }
20571
            }
20572
        }
20573
20574
        if (ret == 0) {
20575
            if ((idx + 1) > certSz)
20576
                ret = BUFFER_E;
20577
        }
20578
        /* extensions - optional */
20579
        localIdx = idx;
20580
        if (ret == 0 && GetASNTag(cert, &localIdx, &tag, certSz) == 0 &&
20581
                tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 3)) {
20582
            idx++;
20583
            if (GetLength(cert, &idx, &extLen, certSz) < 0)
20584
                ret = ASN_PARSE_E;
20585
            if (ret == 0) {
20586
                if (GetSequence(cert, &idx, &extLen, certSz) < 0)
20587
                    ret = ASN_PARSE_E;
20588
            }
20589
            if (ret == 0) {
20590
                extEndIdx = idx + extLen;
20591
20592
                /* Check each extension for the ones we want. */
20593
                while (ret == 0 && idx < extEndIdx) {
20594
                    if (GetSequence(cert, &idx, &len, certSz) < 0)
20595
                        ret = ASN_PARSE_E;
20596
                    if (ret == 0) {
20597
                        extIdx = idx;
20598
                        if (GetObjectId(cert, &extIdx, &oid, oidCertExtType,
20599
                                                                  certSz) < 0) {
20600
                            ret = ASN_PARSE_E;
20601
                        }
20602
20603
                        if (ret == 0) {
20604
                            if ((extIdx + 1) > certSz)
20605
                                ret = BUFFER_E;
20606
                        }
20607
                    }
20608
20609
                    if (ret == 0) {
20610
                        localIdx = extIdx;
20611
                        if (GetASNTag(cert, &localIdx, &tag, certSz) == 0 &&
20612
                                tag == ASN_BOOLEAN) {
20613
                            if (GetBoolean(cert, &extIdx, certSz) < 0)
20614
                                ret = ASN_PARSE_E;
20615
                        }
20616
                    }
20617
                    if (ret == 0) {
20618
                        if (GetOctetString(cert, &extIdx, &extLen, certSz) < 0)
20619
                            ret = ASN_PARSE_E;
20620
                    }
20621
20622
                    if (ret == 0) {
20623
                        switch (oid) {
20624
                        case AUTH_KEY_OID:
20625
                            if (GetSequence(cert, &extIdx, &extLen, certSz) < 0)
20626
                                ret = ASN_PARSE_E;
20627
20628
                            if (ret == 0 && (extIdx + 1) >= certSz)
20629
                                ret = BUFFER_E;
20630
20631
                            if (ret == 0 &&
20632
                                    GetASNTag(cert, &extIdx, &tag, certSz) == 0 &&
20633
                                    tag == (ASN_CONTEXT_SPECIFIC | 0)) {
20634
                                if (GetLength(cert, &extIdx, &extLen, certSz) <= 0)
20635
                                    ret = ASN_PARSE_E;
20636
                                if (ret == 0) {
20637
                                    extAuthKeyIdSet = 1;
20638
                                    /* Get the hash or hash of the hash if wrong
20639
                                     * size. */
20640
                                    ret = GetHashId(cert + extIdx, extLen,
20641
                                                    hash);
20642
                                }
20643
                            }
20644
                            break;
20645
20646
                        default:
20647
                            break;
20648
                        }
20649
                    }
20650
                    idx += len;
20651
                }
20652
            }
20653
        }
20654
    }
20655
    else if (ret == 0) {
20656
        idx += len;
20657
    }
20658
20659
    if (ret == 0 && pubKey == NULL) {
20660
        if (extAuthKeyIdSet)
20661
            ca = GetCA(cm, hash);
20662
        if (ca == NULL) {
20663
            ret = CalcHashId(cert + issuerIdx, issuerSz, hash);
20664
            if (ret == 0)
20665
                ca = GetCAByName(cm, hash);
20666
        }
20667
    }
20668
#else
20669
    if (ret == 0 && pubKey == NULL) {
20670
        ret = CalcHashId(cert + issuerIdx, issuerSz, hash);
20671
        if (ret == 0)
20672
            ca = GetCA(cm, hash);
20673
    }
20674
#endif /* !NO_SKID */
20675
    if (ca == NULL && pubKey == NULL)
20676
        ret = ASN_NO_SIGNER_E;
20677
20678
    if (ret == 0) {
20679
        idx = sigIndex;
20680
        /* signatureAlgorithm */
20681
        if (GetAlgoId(cert, &idx, &oid, oidSigType, certSz) < 0)
20682
            ret = ASN_PARSE_E;
20683
    #ifdef WC_RSA_PSS
20684
        else if (signatureOID == CTC_RSASSAPSS) {
20685
            word32 sz = idx;
20686
            const byte* params = cert + idx;
20687
            if (GetSequence(cert, &idx, &len, certSz) < 0)
20688
                ret = ASN_PARSE_E;
20689
            if (ret == 0) {
20690
                idx += len;
20691
                sz = idx - sz;
20692
20693
                if (req) {
20694
                    if ((sz != sigParamsSz) ||
20695
                                        (XMEMCMP(sigParams, params, sz) != 0)) {
20696
                        ret = ASN_PARSE_E;
20697
                    }
20698
                }
20699
                else {
20700
                    sigParams = params;
20701
                    sigParamsSz = sz;
20702
                }
20703
            }
20704
        }
20705
    #endif
20706
        /* In CSR signature data is not present in body */
20707
        if (req)
20708
            signatureOID = oid;
20709
    }
20710
    if (ret == 0) {
20711
        if (oid != signatureOID)
20712
            ret = ASN_SIG_OID_E;
20713
    }
20714
    if (ret == 0) {
20715
        /* signatureValue */
20716
        if (CheckBitString(cert, &idx, &len, certSz, 1, NULL) < 0)
20717
            ret = ASN_PARSE_E;
20718
    }
20719
20720
    if (ret == 0) {
20721
        if (pubKey != NULL) {
20722
            ret = ConfirmSignature(sigCtx, cert + tbsCertIdx,
20723
                sigIndex - tbsCertIdx, pubKey, pubKeySz, pubKeyOID,
20724
                cert + idx, len, signatureOID, sigParams, sigParamsSz, NULL);
20725
        }
20726
        else {
20727
            ret = ConfirmSignature(sigCtx, cert + tbsCertIdx,
20728
                sigIndex - tbsCertIdx, ca->publicKey, ca->pubKeySize,
20729
                ca->keyOID, cert + idx, len, signatureOID, sigParams,
20730
                sigParamsSz, NULL);
20731
        }
20732
        if (ret != 0) {
20733
            WOLFSSL_ERROR_VERBOSE(ret);
20734
            WOLFSSL_MSG("Confirm signature failed");
20735
        }
20736
    }
20737
20738
    FreeSignatureCtx(sigCtx);
20739
#ifdef WOLFSSL_SMALL_STACK
20740
    if (sigCtx != NULL)
20741
        XFREE(sigCtx, heap, DYNAMIC_TYPE_SIGNATURE);
20742
#endif
20743
    return ret;
20744
#else /* WOLFSSL_ASN_TEMPLATE */
20745
    /* X509 ASN.1 template longer than Certificate Request template. */
20746
    DECL_ASNGETDATA(dataASN, x509CertASN_Length);
20747
#ifndef WOLFSSL_SMALL_STACK
20748
    SignatureCtx  sigCtx[1];
20749
#else
20750
    SignatureCtx* sigCtx = NULL;
20751
#endif
20752
    byte hash[KEYID_SIZE];
20753
    Signer* ca = NULL;
20754
    int ret = 0;
20755
    word32 idx = 0;
20756
#ifndef NO_SKID
20757
    int extAuthKeyIdSet = 0;
20758
#endif
20759
    const byte* tbs = NULL;
20760
    word32 tbsSz = 0;
20761
#ifdef WC_RSA_PSS
20762
    const byte* tbsParams = NULL;
20763
    word32 tbsParamsSz = 0;
20764
#endif
20765
    const byte* sig = NULL;
20766
    word32 sigSz = 0;
20767
    word32 sigOID = 0;
20768
    const byte* sigParams = NULL;
20769
    word32 sigParamsSz = 0;
20770
    const byte* caName = NULL;
20771
    word32 caNameLen = 0;
20772
20773
    (void)req;
20774
    (void)heap;
20775
20776
    if (cert == NULL) {
20777
        ret = BAD_FUNC_ARG;
20778
    }
20779
20780
    ALLOC_ASNGETDATA(dataASN, x509CertASN_Length, ret, heap);
20781
#ifdef WOLFSSL_SMALL_STACK
20782
    if (ret == 0) {
20783
        sigCtx = (SignatureCtx*)XMALLOC(sizeof(*sigCtx), heap,
20784
                                                        DYNAMIC_TYPE_SIGNATURE);
20785
        if (sigCtx == NULL) {
20786
            ret = MEMORY_E;
20787
        }
20788
    }
20789
#endif
20790
20791
    InitSignatureCtx(sigCtx, heap, INVALID_DEVID);
20792
20793
    if ((ret == 0) && (!req)) {
20794
        /* Clear dynamic data for certificate items. */
20795
        XMEMSET(dataASN, 0, sizeof(ASNGetData) * x509CertASN_Length);
20796
        /* Set OID types expected for signature and public key. */
20797
        GetASN_OID(&dataASN[X509CERTASN_IDX_TBS_ALGOID_OID], oidSigType);
20798
        GetASN_OID(&dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_OID],
20799
                oidKeyType);
20800
        GetASN_OID(&dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_CURVEID],
20801
                oidCurveType);
20802
        GetASN_OID(&dataASN[X509CERTASN_IDX_SIGALGO_OID], oidSigType);
20803
        /* Parse certificate. */
20804
        ret = GetASN_Items(x509CertASN, dataASN, x509CertASN_Length, 1, cert,
20805
                           &idx, certSz);
20806
20807
        /* Check signature OIDs match. */
20808
        if ((ret == 0) && dataASN[X509CERTASN_IDX_TBS_ALGOID_OID].data.oid.sum
20809
                != dataASN[X509CERTASN_IDX_SIGALGO_OID].data.oid.sum) {
20810
            ret = ASN_SIG_OID_E;
20811
        }
20812
        /* Store the data for verification in the certificate. */
20813
        if (ret == 0) {
20814
            tbs = GetASNItem_Addr(dataASN[X509CERTASN_IDX_TBS_SEQ], cert);
20815
            tbsSz = GetASNItem_Length(dataASN[X509CERTASN_IDX_TBS_SEQ], cert);
20816
            caName = GetASNItem_Addr(dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ],
20817
                    cert);
20818
            caNameLen = GetASNItem_Length(dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ],
20819
                    cert);
20820
            sigOID = dataASN[X509CERTASN_IDX_SIGALGO_OID].data.oid.sum;
20821
        #ifdef WC_RSA_PSS
20822
            if (dataASN[X509CERTASN_IDX_TBS_ALGOID_PARAMS].tag != 0) {
20823
                tbsParams =
20824
                    GetASNItem_Addr(dataASN[X509CERTASN_IDX_TBS_ALGOID_PARAMS],
20825
                        cert);
20826
                tbsParamsSz =
20827
                    GetASNItem_Length(dataASN[X509CERTASN_IDX_TBS_ALGOID_PARAMS],
20828
                        cert);
20829
            }
20830
            if (dataASN[X509CERTASN_IDX_SIGALGO_PARAMS].tag != 0) {
20831
                sigParams =
20832
                    GetASNItem_Addr(dataASN[X509CERTASN_IDX_SIGALGO_PARAMS],
20833
                        cert);
20834
                sigParamsSz =
20835
                    GetASNItem_Length(dataASN[X509CERTASN_IDX_SIGALGO_PARAMS],
20836
                        cert);
20837
            }
20838
        #endif
20839
            GetASN_GetConstRef(&dataASN[X509CERTASN_IDX_SIGNATURE], &sig, &sigSz);
20840
        #ifdef WC_RSA_PSS
20841
            if (tbsParamsSz != sigParamsSz) {
20842
                ret = ASN_PARSE_E;
20843
            }
20844
            else if ((tbsParamsSz > 0) && (sigOID != CTC_RSASSAPSS)) {
20845
                ret = ASN_PARSE_E;
20846
            }
20847
            else if ((tbsParamsSz > 0) &&
20848
                     (XMEMCMP(tbsParams, sigParams, tbsParamsSz) != 0)) {
20849
                ret = ASN_PARSE_E;
20850
            }
20851
        #endif
20852
        }
20853
    }
20854
    else if (ret == 0) {
20855
#ifndef WOLFSSL_CERT_REQ
20856
        ret = NOT_COMPILED_IN;
20857
#else
20858
        /* Clear dynamic data for certificate request items. */
20859
        XMEMSET(dataASN, 0, sizeof(ASNGetData) * certReqASN_Length);
20860
        /* Set OID types expected for signature and public key. */
20861
        GetASN_OID(&dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_OID],
20862
                oidKeyType);
20863
        GetASN_OID(&dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_CURVEID],
20864
                oidCurveType);
20865
        GetASN_OID(&dataASN[CERTREQASN_IDX_INFO_SIGALGO_OID], oidSigType);
20866
        /* Parse certificate request. */
20867
        ret = GetASN_Items(certReqASN, dataASN, certReqASN_Length, 1, cert,
20868
                           &idx, certSz);
20869
        if (ret == 0) {
20870
            /* Store the data for verification in the certificate. */
20871
            tbs = GetASNItem_Addr(dataASN[CERTREQASN_IDX_INFO_SEQ], cert);
20872
            tbsSz = GetASNItem_Length(dataASN[CERTREQASN_IDX_INFO_SEQ], cert);
20873
            caName = GetASNItem_Addr(
20874
                    dataASN[CERTREQASN_IDX_INFO_SUBJ_SEQ], cert);
20875
            caNameLen = GetASNItem_Length(
20876
                    dataASN[CERTREQASN_IDX_INFO_SUBJ_SEQ], cert);
20877
            sigOID = dataASN[CERTREQASN_IDX_INFO_SIGALGO_OID].data.oid.sum;
20878
        #ifdef WC_RSA_PSS
20879
            sigParams = GetASNItem_Addr(dataASN[X509CERTASN_IDX_SIGALGO_PARAMS],
20880
                cert);
20881
            sigParamsSz =
20882
                GetASNItem_Length(dataASN[X509CERTASN_IDX_SIGALGO_PARAMS],
20883
                    cert);
20884
        #endif
20885
            GetASN_GetConstRef(&dataASN[CERTREQASN_IDX_INFO_SIGNATURE], &sig,
20886
                    &sigSz);
20887
        }
20888
#endif
20889
    }
20890
20891
    /* If no public passed, then find the CA. */
20892
    if ((ret == 0) && (pubKey == NULL)) {
20893
#ifndef NO_SKID
20894
        /* Find the AKI extension in list of extensions and get hash. */
20895
        if ((!req) &&
20896
                (dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].data.ref.data != NULL)) {
20897
            /* TODO: test case */
20898
            ret = GetAKIHash(dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].data.ref.data,
20899
                             dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].data.ref.length,
20900
                             hash, &extAuthKeyIdSet, heap);
20901
        }
20902
20903
        /* Get the CA by hash one was found. */
20904
        if (extAuthKeyIdSet) {
20905
            ca = GetCA(cm, hash);
20906
        }
20907
        if (ca == NULL)
20908
#endif
20909
        {
20910
            /* Try hash of issuer name. */
20911
            ret = CalcHashId(caName, caNameLen, hash);
20912
            if (ret == 0) {
20913
                ca = GetCAByName(cm, hash);
20914
            }
20915
        }
20916
20917
        if (ca != NULL) {
20918
            /* Extract public key information. */
20919
            pubKey = ca->publicKey;
20920
            pubKeySz = ca->pubKeySize;
20921
            pubKeyOID = ca->keyOID;
20922
        }
20923
        else {
20924
            /* No public key to verify with. */
20925
            ret = ASN_NO_SIGNER_E;
20926
        }
20927
    }
20928
20929
    if (ret == 0) {
20930
        /* Check signature. */
20931
        ret = ConfirmSignature(sigCtx, tbs, tbsSz, pubKey, pubKeySz, pubKeyOID,
20932
                sig, sigSz, sigOID, sigParams, sigParamsSz, NULL);
20933
        if (ret != 0) {
20934
            WOLFSSL_MSG("Confirm signature failed");
20935
        }
20936
    }
20937
20938
    FreeSignatureCtx(sigCtx);
20939
#ifdef WOLFSSL_SMALL_STACK
20940
    if (sigCtx != NULL)
20941
        XFREE(sigCtx, heap, DYNAMIC_TYPE_SIGNATURE);
20942
#endif
20943
    FREE_ASNGETDATA(dataASN, heap);
20944
    return ret;
20945
#endif /* WOLFSSL_ASN_TEMPLATE */
20946
}
20947
20948
#ifdef OPENSSL_EXTRA
20949
/* Call CheckCertSignature_ex using a public key buffer for verification
20950
 */
20951
int CheckCertSignaturePubKey(const byte* cert, word32 certSz, void* heap,
20952
        const byte* pubKey, word32 pubKeySz, int pubKeyOID)
20953
{
20954
    return CheckCertSignature_ex(cert, certSz, heap, NULL,
20955
            pubKey, pubKeySz, pubKeyOID, 0);
20956
}
20957
20958
int wc_CheckCertSigPubKey(const byte* cert, word32 certSz, void* heap,
20959
        const byte* pubKey, word32 pubKeySz, int pubKeyOID)
20960
{
20961
        return CheckCertSignaturePubKey(cert, certSz, heap, pubKey, pubKeySz,
20962
                                        pubKeyOID);
20963
}
20964
20965
#ifdef WOLFSSL_CERT_REQ
20966
int CheckCSRSignaturePubKey(const byte* cert, word32 certSz, void* heap,
20967
        const byte* pubKey, word32 pubKeySz, int pubKeyOID)
20968
{
20969
    return CheckCertSignature_ex(cert, certSz, heap, NULL,
20970
            pubKey, pubKeySz, pubKeyOID, 1);
20971
}
20972
#endif /* WOLFSSL_CERT_REQ */
20973
#endif /* OPENSSL_EXTRA */
20974
#ifdef WOLFSSL_SMALL_CERT_VERIFY
20975
/* Call CheckCertSignature_ex using a certificate manager (cm)
20976
 */
20977
int CheckCertSignature(const byte* cert, word32 certSz, void* heap, void* cm)
20978
{
20979
    return CheckCertSignature_ex(cert, certSz, heap, cm, NULL, 0, 0, 0);
20980
}
20981
#endif /* WOLFSSL_SMALL_CERT_VERIFY */
20982
#endif /* WOLFSSL_SMALL_CERT_VERIFY || OPENSSL_EXTRA */
20983
20984
int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
20985
0
{
20986
0
    int    ret = 0;
20987
0
    int    checkPathLen = 0;
20988
0
    int    decrementMaxPathLen = 0;
20989
0
#ifndef WOLFSSL_ASN_TEMPLATE
20990
0
    word32 confirmOID = 0;
20991
#ifdef WOLFSSL_CERT_REQ
20992
    int    len = 0;
20993
#endif
20994
0
#endif
20995
#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT)
20996
    int    idx = 0;
20997
#endif
20998
0
    byte*  sce_tsip_encRsaKeyIdx;
20999
21000
0
    if (cert == NULL) {
21001
0
        return BAD_FUNC_ARG;
21002
0
    }
21003
21004
#ifdef WOLFSSL_CERT_REQ
21005
    if (type == CERTREQ_TYPE)
21006
        cert->isCSR = 1;
21007
#endif
21008
21009
0
    if (cert->sigCtx.state == SIG_STATE_BEGIN) {
21010
0
#ifndef WOLFSSL_ASN_TEMPLATE
21011
0
        cert->badDate = 0;
21012
0
        cert->criticalExt = 0;
21013
0
        if ((ret = DecodeToKey(cert, verify)) < 0) {
21014
0
            if (ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E)
21015
0
                cert->badDate = ret;
21016
0
            else
21017
0
                return ret;
21018
0
        }
21019
21020
0
        WOLFSSL_MSG("Parsed Past Key");
21021
21022
21023
#ifdef WOLFSSL_CERT_REQ
21024
        /* Read attributes */
21025
        if (cert->isCSR) {
21026
            if (GetASNHeader_ex(cert->source,
21027
                    ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED, &cert->srcIdx,
21028
                    &len, cert->maxIdx, 1) < 0) {
21029
                WOLFSSL_MSG("GetASNHeader_ex error");
21030
                return ASN_PARSE_E;
21031
            }
21032
21033
            if (len) {
21034
                word32 attrMaxIdx = cert->srcIdx + len;
21035
                word32 oid;
21036
                byte   tag;
21037
21038
                if (attrMaxIdx > cert->maxIdx) {
21039
                    WOLFSSL_MSG("Attribute length greater than CSR length");
21040
                    return ASN_PARSE_E;
21041
                }
21042
21043
                while (cert->srcIdx < attrMaxIdx) {
21044
                    /* Attributes have the structure:
21045
                     * SEQ -> OID -> SET -> ATTRIBUTE */
21046
                    if (GetSequence(cert->source, &cert->srcIdx, &len,
21047
                            attrMaxIdx) < 0) {
21048
                        WOLFSSL_MSG("attr GetSequence error");
21049
                        return ASN_PARSE_E;
21050
                    }
21051
                    if (GetObjectId(cert->source, &cert->srcIdx, &oid,
21052
                            oidCsrAttrType, attrMaxIdx) < 0) {
21053
                        WOLFSSL_MSG("attr GetObjectId error");
21054
                        return ASN_PARSE_E;
21055
                    }
21056
                    if (GetSet(cert->source, &cert->srcIdx, &len,
21057
                            attrMaxIdx) < 0) {
21058
                        WOLFSSL_MSG("attr GetSet error");
21059
                        return ASN_PARSE_E;
21060
                    }
21061
                    switch (oid) {
21062
                    case PKCS9_CONTENT_TYPE_OID:
21063
                        if (GetHeader(cert->source, &tag,
21064
                                &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
21065
                            WOLFSSL_MSG("attr GetHeader error");
21066
                            return ASN_PARSE_E;
21067
                        }
21068
                        if (tag != ASN_PRINTABLE_STRING && tag != ASN_UTF8STRING &&
21069
                                tag != ASN_IA5_STRING) {
21070
                            WOLFSSL_MSG("Unsupported attribute value format");
21071
                            return ASN_PARSE_E;
21072
                        }
21073
                        cert->contentType = (char*)cert->source + cert->srcIdx;
21074
                        cert->contentTypeLen = len;
21075
                        cert->srcIdx += len;
21076
                        break;
21077
                    case CHALLENGE_PASSWORD_OID:
21078
                        if (GetHeader(cert->source, &tag,
21079
                                &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
21080
                            WOLFSSL_MSG("attr GetHeader error");
21081
                            return ASN_PARSE_E;
21082
                        }
21083
                        if (tag != ASN_PRINTABLE_STRING && tag != ASN_UTF8STRING &&
21084
                                tag != ASN_IA5_STRING) {
21085
                            WOLFSSL_MSG("Unsupported attribute value format");
21086
                            return ASN_PARSE_E;
21087
                        }
21088
                        cert->cPwd = (char*)cert->source + cert->srcIdx;
21089
                        cert->cPwdLen = len;
21090
                        cert->srcIdx += len;
21091
                        break;
21092
                    case SERIAL_NUMBER_OID:
21093
                        if (GetHeader(cert->source, &tag,
21094
                                &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
21095
                            WOLFSSL_MSG("attr GetHeader error");
21096
                            return ASN_PARSE_E;
21097
                        }
21098
                        if (tag != ASN_PRINTABLE_STRING && tag != ASN_UTF8STRING &&
21099
                                tag != ASN_IA5_STRING) {
21100
                            WOLFSSL_MSG("Unsupported attribute value format");
21101
                            return ASN_PARSE_E;
21102
                        }
21103
                        cert->sNum = (char*)cert->source + cert->srcIdx;
21104
                        cert->sNumLen = len;
21105
                        cert->srcIdx += len;
21106
                        if (cert->sNumLen <= EXTERNAL_SERIAL_SIZE) {
21107
                            XMEMCPY(cert->serial, cert->sNum, cert->sNumLen);
21108
                            cert->serialSz = cert->sNumLen;
21109
                        }
21110
                        break;
21111
                    case DNQUALIFIER_OID:
21112
                        if (GetHeader(cert->source, &tag,
21113
                                &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
21114
                            WOLFSSL_MSG("attr GetHeader error");
21115
                            return ASN_PARSE_E;
21116
                        }
21117
                        cert->dnQualifier = (char*)cert->source + cert->srcIdx;
21118
                        cert->dnQualifierLen = len;
21119
                        cert->srcIdx += len;
21120
                        break;
21121
                    case INITIALS_OID:
21122
                        if (GetHeader(cert->source, &tag,
21123
                                &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
21124
                            WOLFSSL_MSG("attr GetHeader error");
21125
                            return ASN_PARSE_E;
21126
                        }
21127
                        cert->initials = (char*)cert->source + cert->srcIdx;
21128
                        cert->initialsLen = len;
21129
                        cert->srcIdx += len;
21130
                        break;
21131
                    case SURNAME_OID:
21132
                        if (GetHeader(cert->source, &tag,
21133
                                &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
21134
                            WOLFSSL_MSG("attr GetHeader error");
21135
                            return ASN_PARSE_E;
21136
                        }
21137
                        cert->surname = (char*)cert->source + cert->srcIdx;
21138
                        cert->surnameLen = len;
21139
                        cert->srcIdx += len;
21140
                        break;
21141
                    case GIVEN_NAME_OID:
21142
                        if (GetHeader(cert->source, &tag,
21143
                                &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
21144
                            WOLFSSL_MSG("attr GetHeader error");
21145
                            return ASN_PARSE_E;
21146
                        }
21147
                        cert->givenName = (char*)cert->source + cert->srcIdx;
21148
                        cert->givenNameLen = len;
21149
                        cert->srcIdx += len;
21150
                        break;
21151
                    case UNSTRUCTURED_NAME_OID:
21152
                        if (GetHeader(cert->source, &tag,
21153
                                &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
21154
                            WOLFSSL_MSG("attr GetHeader error");
21155
                            return ASN_PARSE_E;
21156
                        }
21157
                        cert->unstructuredName =
21158
                            (char*)cert->source + cert->srcIdx;
21159
                        cert->unstructuredNameLen = len;
21160
                        cert->srcIdx += len;
21161
                        break;
21162
                    case EXTENSION_REQUEST_OID:
21163
                        /* save extensions */
21164
                        cert->extensions    = &cert->source[cert->srcIdx];
21165
                        cert->extensionsSz  = len;
21166
                        cert->extensionsIdx = cert->srcIdx; /* for potential later use */
21167
21168
                        if ((ret = DecodeCertExtensions(cert)) < 0) {
21169
                            if (ret == ASN_CRIT_EXT_E) {
21170
                                cert->criticalExt = ret;
21171
                            }
21172
                            else {
21173
                                return ret;
21174
                            }
21175
                        }
21176
                        cert->srcIdx += len;
21177
                        break;
21178
                    default:
21179
                        WOLFSSL_MSG("Unsupported attribute type");
21180
                        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
21181
                        return ASN_PARSE_E;
21182
                    }
21183
                }
21184
            }
21185
        }
21186
#endif
21187
21188
0
        if (cert->srcIdx < cert->sigIndex) {
21189
0
        #ifndef ALLOW_V1_EXTENSIONS
21190
0
            if (cert->version < 2) {
21191
0
                WOLFSSL_MSG("\tv1 and v2 certs not allowed extensions");
21192
0
                WOLFSSL_ERROR_VERBOSE(ASN_VERSION_E);
21193
0
                return ASN_VERSION_E;
21194
0
            }
21195
0
        #endif
21196
21197
            /* save extensions */
21198
0
            cert->extensions    = &cert->source[cert->srcIdx];
21199
0
            cert->extensionsSz  = cert->sigIndex - cert->srcIdx;
21200
0
            cert->extensionsIdx = cert->srcIdx;   /* for potential later use */
21201
21202
0
            if ((ret = DecodeCertExtensions(cert)) < 0) {
21203
0
                if (ret == ASN_CRIT_EXT_E)
21204
0
                    cert->criticalExt = ret;
21205
0
                else
21206
0
                    return ret;
21207
0
            }
21208
21209
        #ifdef HAVE_OCSP
21210
            if (verify == VERIFY_OCSP_CERT) {
21211
                /* trust for the lifetime of the responder's cert*/
21212
                if (cert->ocspNoCheckSet)
21213
                    verify = VERIFY;
21214
                else
21215
                    verify = VERIFY_OCSP;
21216
            }
21217
        #endif
21218
            /* advance past extensions */
21219
0
            cert->srcIdx = cert->sigIndex;
21220
0
        }
21221
21222
0
        if ((ret = GetSigAlg(cert,
21223
#ifdef WOLFSSL_CERT_REQ
21224
                !cert->isCSR ? &confirmOID : &cert->signatureOID,
21225
#else
21226
0
                &confirmOID,
21227
0
#endif
21228
0
                cert->maxIdx)) < 0) {
21229
0
            return ret;
21230
0
        }
21231
21232
0
        if ((ret = GetSignature(cert)) < 0) {
21233
0
            return ret;
21234
0
        }
21235
21236
0
        if (confirmOID != cert->signatureOID
21237
#ifdef WOLFSSL_CERT_REQ
21238
                && !cert->isCSR
21239
#endif
21240
0
                ) {
21241
0
            WOLFSSL_ERROR_VERBOSE(ASN_SIG_OID_E);
21242
0
            return ASN_SIG_OID_E;
21243
0
        }
21244
#else
21245
#ifdef WOLFSSL_CERT_REQ
21246
        if (cert->isCSR) {
21247
            ret = DecodeCertReq(cert, &cert->criticalExt);
21248
            if (ret < 0) {
21249
                return ret;
21250
            }
21251
        }
21252
        else
21253
#endif
21254
        {
21255
            ret = DecodeCert(cert, verify, &cert->criticalExt);
21256
            if (ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E) {
21257
                cert->badDate = ret;
21258
            }
21259
            else if (ret < 0) {
21260
                WOLFSSL_ERROR_VERBOSE(ret);
21261
                return ret;
21262
            }
21263
        }
21264
#endif
21265
21266
0
    #ifndef NO_SKID
21267
0
        if (cert->extSubjKeyIdSet == 0 && cert->publicKey != NULL &&
21268
0
                                                         cert->pubKeySize > 0) {
21269
0
            ret = CalcHashId(cert->publicKey, cert->pubKeySize,
21270
0
                                                            cert->extSubjKeyId);
21271
0
            if (ret != 0) {
21272
0
                WOLFSSL_ERROR_VERBOSE(ret);
21273
0
                return ret;
21274
0
            }
21275
0
        }
21276
0
    #endif /* !NO_SKID */
21277
21278
0
        if (!cert->selfSigned || (verify != NO_VERIFY && type != CA_TYPE &&
21279
0
                                                   type != TRUSTED_PEER_TYPE)) {
21280
0
            cert->ca = NULL;
21281
0
    #ifndef NO_SKID
21282
0
            if (cert->extAuthKeyIdSet) {
21283
0
                cert->ca = GetCA(cm, cert->extAuthKeyId);
21284
0
            }
21285
0
            if (cert->ca == NULL && cert->extSubjKeyIdSet
21286
0
                                 && verify != VERIFY_OCSP) {
21287
0
                cert->ca = GetCA(cm, cert->extSubjKeyId);
21288
0
            }
21289
0
            if (cert->ca != NULL && XMEMCMP(cert->issuerHash,
21290
0
                                  cert->ca->subjectNameHash, KEYID_SIZE) != 0) {
21291
0
                cert->ca = NULL;
21292
0
            }
21293
0
            if (cert->ca == NULL) {
21294
0
                cert->ca = GetCAByName(cm, cert->issuerHash);
21295
                /* If AKID is available then this CA doesn't have the public
21296
                 * key required */
21297
0
                if (cert->ca && cert->extAuthKeyIdSet) {
21298
0
                    WOLFSSL_MSG("CA SKID doesn't match AKID");
21299
0
                    cert->ca = NULL;
21300
0
                }
21301
0
            }
21302
21303
            /* OCSP Only: alt lookup using subject and pub key w/o sig check */
21304
        #ifdef WOLFSSL_NO_TRUSTED_CERTS_VERIFY
21305
            if (cert->ca == NULL && verify == VERIFY_OCSP) {
21306
                cert->ca = GetCABySubjectAndPubKey(cert, cm);
21307
                if (cert->ca) {
21308
                    ret = 0; /* success */
21309
                    goto exit_pcr;
21310
                }
21311
            }
21312
        #endif /* WOLFSSL_NO_TRUSTED_CERTS_VERIFY */
21313
    #else
21314
            cert->ca = GetCA(cm, cert->issuerHash);
21315
    #endif /* !NO_SKID */
21316
21317
0
            if (cert->ca) {
21318
0
                WOLFSSL_MSG("CA found");
21319
0
            }
21320
0
        }
21321
21322
0
        if (cert->selfSigned) {
21323
0
            cert->maxPathLen = WOLFSSL_MAX_PATH_LEN;
21324
0
        } else {
21325
            /* RFC 5280 Section 4.2.1.9:
21326
             *
21327
             * load/receive check
21328
             *
21329
             * 1) Is CA boolean set?
21330
             *      No  - SKIP CHECK
21331
             *      Yes - Check key usage
21332
             * 2) Is Key usage extension present?
21333
             *      No  - goto 3
21334
             *      Yes - check keyCertSign assertion
21335
             *     2.a) Is keyCertSign asserted?
21336
             *          No  - goto 4
21337
             *          Yes - goto 3
21338
             * 3) Is pathLen set?
21339
             *      No  - goto 4
21340
             *      Yes - check pathLen against maxPathLen.
21341
             *      3.a) Is pathLen less than maxPathLen?
21342
             *           No - goto 4
21343
             *           Yes - set maxPathLen to pathLen and EXIT
21344
             * 4) Is maxPathLen > 0?
21345
             *      Yes - Reduce by 1
21346
             *      No  - ERROR
21347
             */
21348
21349
0
            if (cert->ca && cert->pathLengthSet) {
21350
0
                cert->maxPathLen = cert->pathLength;
21351
0
                if (cert->isCA) {
21352
0
                    WOLFSSL_MSG("\tCA boolean set");
21353
0
                    if (cert->extKeyUsageSet) {
21354
0
                        WOLFSSL_MSG("\tExtension Key Usage Set");
21355
0
                        if ((cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) != 0) {
21356
0
                            checkPathLen = 1;
21357
0
                        }
21358
0
                        else {
21359
0
                            decrementMaxPathLen = 1;
21360
0
                        }
21361
0
                    }
21362
0
                    else {
21363
0
                        checkPathLen = 1;
21364
0
                    } /* !cert->ca check */
21365
0
                } /* cert is not a CA (assuming entity cert) */
21366
21367
0
                if (checkPathLen && cert->pathLengthSet) {
21368
0
                    if (cert->pathLength < cert->ca->maxPathLen) {
21369
0
                        WOLFSSL_MSG("\tmaxPathLen status: set to pathLength");
21370
0
                        cert->maxPathLen = cert->pathLength;
21371
0
                    }
21372
0
                    else {
21373
0
                        decrementMaxPathLen = 1;
21374
0
                    }
21375
0
                }
21376
21377
0
                if (decrementMaxPathLen && cert->ca->maxPathLen > 0) {
21378
0
                    WOLFSSL_MSG("\tmaxPathLen status: reduce by 1");
21379
0
                    cert->maxPathLen = cert->ca->maxPathLen - 1;
21380
0
                    if (verify != NO_VERIFY && type != CA_TYPE &&
21381
0
                                                    type != TRUSTED_PEER_TYPE) {
21382
0
                        WOLFSSL_MSG("\tmaxPathLen status: OK");
21383
0
                    }
21384
0
                } else if (decrementMaxPathLen && cert->ca->maxPathLen == 0) {
21385
0
                    cert->maxPathLen = 0;
21386
0
                    if (verify != NO_VERIFY && type != CA_TYPE &&
21387
0
                                                    type != TRUSTED_PEER_TYPE) {
21388
0
                        WOLFSSL_MSG("\tNon-entity cert, maxPathLen is 0");
21389
0
                        WOLFSSL_MSG("\tmaxPathLen status: ERROR");
21390
0
                        WOLFSSL_ERROR_VERBOSE(ASN_PATHLEN_INV_E);
21391
0
                        return ASN_PATHLEN_INV_E;
21392
0
                    }
21393
0
                }
21394
0
            } else if (cert->ca && cert->isCA) {
21395
                /* case where cert->pathLength extension is not set */
21396
0
                if (cert->ca->maxPathLen > 0) {
21397
0
                    cert->maxPathLen = cert->ca->maxPathLen - 1;
21398
0
                } else {
21399
0
                    cert->maxPathLen = 0;
21400
0
                    if (verify != NO_VERIFY && type != CA_TYPE &&
21401
0
                                                    type != TRUSTED_PEER_TYPE) {
21402
0
                        WOLFSSL_MSG("\tNon-entity cert, maxPathLen is 0");
21403
0
                        WOLFSSL_MSG("\tmaxPathLen status: ERROR");
21404
0
                        WOLFSSL_ERROR_VERBOSE(ASN_PATHLEN_INV_E);
21405
0
                        return ASN_PATHLEN_INV_E;
21406
0
                    }
21407
0
                }
21408
0
            }
21409
0
        }
21410
21411
        #ifdef HAVE_OCSP
21412
        if (verify != NO_VERIFY && type != CA_TYPE &&
21413
                                                type != TRUSTED_PEER_TYPE) {
21414
            if (cert->ca) {
21415
                /* Need the CA's public key hash for OCSP */
21416
                XMEMCPY(cert->issuerKeyHash, cert->ca->subjectKeyHash,
21417
                                                                KEYID_SIZE);
21418
            }
21419
        }
21420
        #endif /* HAVE_OCSP */
21421
0
    }
21422
#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT)
21423
    /* prepare for TSIP TLS cert verification API use */
21424
    if (cert->keyOID == RSAk) {
21425
        /* to call TSIP API, it needs keys position info in bytes */
21426
        if ((ret = RsaPublicKeyDecodeRawIndex(cert->publicKey, (word32*)&idx,
21427
                                   cert->pubKeySize,
21428
                                   &cert->sigCtx.CertAtt.pubkey_n_start,
21429
                                   &cert->sigCtx.CertAtt.pubkey_n_len,
21430
                                   &cert->sigCtx.CertAtt.pubkey_e_start,
21431
                                   &cert->sigCtx.CertAtt.pubkey_e_len)) != 0) {
21432
            WOLFSSL_MSG("Decoding index from cert failed.");
21433
            return ret;
21434
        }
21435
        cert->sigCtx.CertAtt.certBegin = cert->certBegin;
21436
    } else if (cert->keyOID == ECDSAk) {
21437
        cert->sigCtx.CertAtt.certBegin = cert->certBegin;
21438
    }
21439
    /* check if we can use TSIP for cert verification */
21440
    /* if the ca is verified as tsip root ca.         */
21441
    /* TSIP can only handle 2048 bits(256 byte) key.  */
21442
    if (cert->ca && Renesas_cmn_checkCA(cert->ca->cm_idx) != 0 &&
21443
        (cert->sigCtx.CertAtt.pubkey_n_len == 256 ||
21444
         cert->sigCtx.CertAtt.curve_id == ECC_SECP256R1)) {
21445
21446
        /* assign memory to encrypted tsip Rsa key index */
21447
        if (!cert->sce_tsip_encRsaKeyIdx)
21448
            cert->sce_tsip_encRsaKeyIdx =
21449
                            (byte*)XMALLOC(TSIP_TLS_ENCPUBKEY_SZ_BY_CERTVRFY,
21450
                             cert->heap, DYNAMIC_TYPE_RSA);
21451
        if (cert->sce_tsip_encRsaKeyIdx == NULL)
21452
                return MEMORY_E;
21453
    }
21454
    else {
21455
        if (cert->ca) {
21456
            /* TSIP isn't usable */
21457
            if (Renesas_cmn_checkCA(cert->ca->cm_idx) == 0)
21458
                WOLFSSL_MSG("SCE-TSIP isn't usable because the ca isn't verified "
21459
                            "by TSIP.");
21460
            else if (cert->sigCtx.CertAtt.pubkey_n_len != 256)
21461
                WOLFSSL_MSG("SCE-TSIP isn't usable because the ca isn't signed by "
21462
                            "RSA 2048.");
21463
            else
21464
                WOLFSSL_MSG("SCE-TSIP isn't usable");
21465
        }
21466
        cert->sce_tsip_encRsaKeyIdx = NULL;
21467
    }
21468
21469
    sce_tsip_encRsaKeyIdx = cert->sce_tsip_encRsaKeyIdx;
21470
21471
#else
21472
0
    sce_tsip_encRsaKeyIdx = NULL;
21473
0
#endif
21474
21475
0
    if (verify != NO_VERIFY && type != CA_TYPE && type != TRUSTED_PEER_TYPE) {
21476
0
        if (cert->ca) {
21477
0
            if (verify == VERIFY || verify == VERIFY_OCSP ||
21478
0
                                                 verify == VERIFY_SKIP_DATE) {
21479
                /* try to confirm/verify signature */
21480
0
                if ((ret = ConfirmSignature(&cert->sigCtx,
21481
0
                        cert->source + cert->certBegin,
21482
0
                        cert->sigIndex - cert->certBegin,
21483
0
                        cert->ca->publicKey, cert->ca->pubKeySize,
21484
0
                        cert->ca->keyOID, cert->signature,
21485
0
                        cert->sigLength, cert->signatureOID,
21486
0
                    #ifdef WC_RSA_PSS
21487
0
                        cert->source + cert->sigParamsIndex,
21488
0
                        cert->sigParamsLength,
21489
                    #else
21490
                        NULL, 0,
21491
                    #endif
21492
0
                        sce_tsip_encRsaKeyIdx)) != 0) {
21493
0
                    if (ret != WC_PENDING_E) {
21494
0
                        WOLFSSL_MSG("Confirm signature failed");
21495
0
                    }
21496
0
                    WOLFSSL_ERROR_VERBOSE(ret);
21497
0
                    return ret;
21498
0
                }
21499
0
            }
21500
0
        #ifndef IGNORE_NAME_CONSTRAINTS
21501
0
            if (verify == VERIFY || verify == VERIFY_OCSP ||
21502
0
                        verify == VERIFY_NAME || verify == VERIFY_SKIP_DATE) {
21503
                /* check that this cert's name is permitted by the signer's
21504
                 * name constraints */
21505
0
                if (!ConfirmNameConstraints(cert->ca, cert)) {
21506
0
                    WOLFSSL_MSG("Confirm name constraint failed");
21507
0
                    WOLFSSL_ERROR_VERBOSE(ASN_NAME_INVALID_E);
21508
0
                    return ASN_NAME_INVALID_E;
21509
0
                }
21510
0
            }
21511
0
        #endif /* IGNORE_NAME_CONSTRAINTS */
21512
0
        }
21513
#ifdef WOLFSSL_CERT_REQ
21514
        else if (type == CERTREQ_TYPE) {
21515
            if ((ret = ConfirmSignature(&cert->sigCtx,
21516
                    cert->source + cert->certBegin,
21517
                    cert->sigIndex - cert->certBegin,
21518
                    cert->publicKey, cert->pubKeySize,
21519
                    cert->keyOID, cert->signature,
21520
                    cert->sigLength, cert->signatureOID,
21521
                #ifdef WC_RSA_PSS
21522
                    cert->source + cert->sigParamsIndex, cert->sigParamsLength,
21523
                #else
21524
                    NULL, 0,
21525
                #endif
21526
                    sce_tsip_encRsaKeyIdx)) != 0) {
21527
                if (ret != WC_PENDING_E) {
21528
                    WOLFSSL_MSG("Confirm signature failed");
21529
                }
21530
                WOLFSSL_ERROR_VERBOSE(ret);
21531
                return ret;
21532
            }
21533
        }
21534
#endif
21535
0
        else {
21536
            /* no signer */
21537
0
            WOLFSSL_MSG("No CA signer to verify with");
21538
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
21539
            /* ret needs to be self-signer error for Qt compat */
21540
            if (cert->selfSigned) {
21541
                WOLFSSL_ERROR_VERBOSE(ASN_SELF_SIGNED_E);
21542
                return ASN_SELF_SIGNED_E;
21543
            }
21544
            else
21545
#endif
21546
0
            {
21547
0
                WOLFSSL_ERROR_VERBOSE(ASN_NO_SIGNER_E);
21548
0
                return ASN_NO_SIGNER_E;
21549
0
            }
21550
0
        }
21551
0
    }
21552
21553
#if defined(WOLFSSL_NO_TRUSTED_CERTS_VERIFY) && !defined(NO_SKID)
21554
exit_pcr:
21555
#endif
21556
21557
0
    if (cert->badDate != 0) {
21558
0
        if (verify != VERIFY_SKIP_DATE) {
21559
0
            return cert->badDate;
21560
0
        }
21561
0
        WOLFSSL_MSG("Date error: Verify option is skipping");
21562
0
    }
21563
21564
0
    if (cert->criticalExt != 0)
21565
0
        return cert->criticalExt;
21566
21567
0
    return ret;
21568
0
}
21569
21570
/* Create and init an new signer */
21571
Signer* MakeSigner(void* heap)
21572
0
{
21573
0
    Signer* signer = (Signer*) XMALLOC(sizeof(Signer), heap,
21574
0
                                       DYNAMIC_TYPE_SIGNER);
21575
0
    if (signer) {
21576
0
        XMEMSET(signer, 0, sizeof(Signer));
21577
0
    }
21578
0
    (void)heap;
21579
21580
0
    return signer;
21581
0
}
21582
21583
21584
/* Free an individual signer.
21585
 *
21586
 * Used by Certificate Manager.
21587
 *
21588
 * @param [in, out] signer  On in, signer object.
21589
 *                          On out, pointer is no longer valid.
21590
 * @param [in]      heap    Dynamic memory hint.
21591
 */
21592
void FreeSigner(Signer* signer, void* heap)
21593
0
{
21594
0
    XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
21595
0
    XFREE((void*)signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
21596
0
#ifndef IGNORE_NAME_CONSTRAINTS
21597
0
    if (signer->permittedNames)
21598
0
        FreeNameSubtrees(signer->permittedNames, heap);
21599
0
    if (signer->excludedNames)
21600
0
        FreeNameSubtrees(signer->excludedNames, heap);
21601
0
#endif
21602
#ifdef WOLFSSL_SIGNER_DER_CERT
21603
    FreeDer(&signer->derCert);
21604
#endif
21605
0
    XFREE(signer, heap, DYNAMIC_TYPE_SIGNER);
21606
0
    (void)signer;
21607
0
    (void)heap;
21608
0
}
21609
21610
21611
/* Free the whole singer table with number of rows.
21612
 *
21613
 * Each table entry is a linked list of signers.
21614
 * Used by Certificate Manager.
21615
 *
21616
 * @param [in, out] table   Array of signer objects.
21617
 * @param [in]      rows    Number of entries in table.
21618
 * @param [in]      heap    Dynamic memory hint.
21619
 */
21620
void FreeSignerTable(Signer** table, int rows, void* heap)
21621
0
{
21622
0
    int i;
21623
21624
0
    for (i = 0; i < rows; i++) {
21625
0
        Signer* signer = table[i];
21626
0
        while (signer) {
21627
0
            Signer* next = signer->next;
21628
0
            FreeSigner(signer, heap);
21629
0
            signer = next;
21630
0
        }
21631
0
        table[i] = NULL;
21632
0
    }
21633
0
}
21634
21635
#ifdef WOLFSSL_TRUST_PEER_CERT
21636
/* Free an individual trusted peer cert.
21637
 *
21638
 * @param [in, out] tp    Trusted peer certificate object.
21639
 * @param [in]      heap  Dynamic memory hint.
21640
 */
21641
void FreeTrustedPeer(TrustedPeerCert* tp, void* heap)
21642
{
21643
    if (tp == NULL) {
21644
        return;
21645
    }
21646
21647
    if (tp->name) {
21648
        XFREE(tp->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
21649
    }
21650
21651
    if (tp->sig) {
21652
        XFREE(tp->sig, heap, DYNAMIC_TYPE_SIGNATURE);
21653
    }
21654
#ifndef IGNORE_NAME_CONSTRAINTS
21655
    if (tp->permittedNames)
21656
        FreeNameSubtrees(tp->permittedNames, heap);
21657
    if (tp->excludedNames)
21658
        FreeNameSubtrees(tp->excludedNames, heap);
21659
#endif
21660
    XFREE(tp, heap, DYNAMIC_TYPE_CERT);
21661
21662
    (void)heap;
21663
}
21664
21665
/* Free the whole Trusted Peer linked list.
21666
 *
21667
 * Each table entry is a linked list of trusted peer certificates.
21668
 * Used by Certificate Manager.
21669
 *
21670
 * @param [in, out] table   Array of trusted peer certificate objects.
21671
 * @param [in]      rows    Number of entries in table.
21672
 * @param [in]      heap    Dynamic memory hint.
21673
 */
21674
void FreeTrustedPeerTable(TrustedPeerCert** table, int rows, void* heap)
21675
{
21676
    int i;
21677
21678
    for (i = 0; i < rows; i++) {
21679
        TrustedPeerCert* tp = table[i];
21680
        while (tp) {
21681
            TrustedPeerCert* next = tp->next;
21682
            FreeTrustedPeer(tp, heap);
21683
            tp = next;
21684
        }
21685
        table[i] = NULL;
21686
    }
21687
}
21688
#endif /* WOLFSSL_TRUST_PEER_CERT */
21689
21690
int SetMyVersion(word32 version, byte* output, int header)
21691
0
{
21692
0
    int i = 0;
21693
21694
0
    if (output == NULL)
21695
0
        return BAD_FUNC_ARG;
21696
21697
0
    if (header) {
21698
0
        output[i++] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED;
21699
0
        output[i++] = 3;
21700
0
    }
21701
0
    output[i++] = ASN_INTEGER;
21702
0
    output[i++] = 0x01;
21703
0
    output[i++] = (byte)version;
21704
21705
0
    return i;
21706
0
}
21707
21708
#if !defined(WOLFSSL_ASN_TEMPLATE) || defined(HAVE_PKCS7)
21709
int SetSerialNumber(const byte* sn, word32 snSz, byte* output,
21710
    word32 outputSz, int maxSnSz)
21711
0
{
21712
0
    int i;
21713
0
    int snSzInt = (int)snSz;
21714
21715
0
    if (sn == NULL || output == NULL || snSzInt < 0)
21716
0
        return BAD_FUNC_ARG;
21717
21718
    /* remove leading zeros */
21719
0
    while (snSzInt > 0 && sn[0] == 0) {
21720
0
        snSzInt--;
21721
0
        sn++;
21722
0
    }
21723
    /* RFC 5280 - 4.1.2.2:
21724
     *   Serial numbers must be a positive value (and not zero) */
21725
0
    if (snSzInt == 0) {
21726
0
        WOLFSSL_ERROR_VERBOSE(BAD_FUNC_ARG);
21727
0
        return BAD_FUNC_ARG;
21728
0
    }
21729
21730
0
    if (sn[0] & 0x80)
21731
0
        maxSnSz--;
21732
    /* truncate if input is too long */
21733
0
    if (snSzInt > maxSnSz)
21734
0
        snSzInt = maxSnSz;
21735
21736
0
    i = SetASNInt(snSzInt, sn[0], NULL);
21737
    /* truncate if input is too long */
21738
0
    if (snSzInt > (int)outputSz - i)
21739
0
        snSzInt = (int)outputSz - i;
21740
    /* sanity check number of bytes to copy */
21741
0
    if (snSzInt <= 0) {
21742
0
        return BUFFER_E;
21743
0
    }
21744
21745
    /* write out ASN.1 Integer */
21746
0
    (void)SetASNInt(snSzInt, sn[0], output);
21747
0
    XMEMCPY(output + i, sn, snSzInt);
21748
21749
    /* compute final length */
21750
0
    i += snSzInt;
21751
21752
0
    return i;
21753
0
}
21754
#endif /* !WOLFSSL_ASN_TEMPLATE */
21755
21756
#endif /* !NO_CERTS */
21757
21758
#ifndef WOLFSSL_ASN_TEMPLATE
21759
int wc_GetSerialNumber(const byte* input, word32* inOutIdx,
21760
    byte* serial, int* serialSz, word32 maxIdx)
21761
0
{
21762
0
    int result = 0;
21763
0
    int ret;
21764
21765
0
    WOLFSSL_ENTER("wc_GetSerialNumber");
21766
21767
0
    if (serial == NULL || input == NULL || serialSz == NULL) {
21768
0
        return BAD_FUNC_ARG;
21769
0
    }
21770
21771
    /* First byte is ASN type */
21772
0
    if ((*inOutIdx+1) > maxIdx) {
21773
0
        WOLFSSL_MSG("Bad idx first");
21774
0
        return BUFFER_E;
21775
0
    }
21776
21777
0
    ret = GetASNInt(input, inOutIdx, serialSz, maxIdx);
21778
0
    if (ret != 0)
21779
0
        return ret;
21780
21781
0
    if (*serialSz > EXTERNAL_SERIAL_SIZE || *serialSz <= 0) {
21782
0
        WOLFSSL_MSG("Serial size bad");
21783
0
        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
21784
0
        return ASN_PARSE_E;
21785
0
    }
21786
21787
    /* return serial */
21788
0
    XMEMCPY(serial, &input[*inOutIdx], (size_t)*serialSz);
21789
0
    *inOutIdx += *serialSz;
21790
21791
0
    return result;
21792
0
}
21793
#endif
21794
21795
#ifndef NO_CERTS
21796
21797
/* TODO: consider moving PEM code out to a different file. */
21798
21799
int AllocDer(DerBuffer** pDer, word32 length, int type, void* heap)
21800
0
{
21801
0
    int ret = BAD_FUNC_ARG;
21802
0
    if (pDer) {
21803
0
        int dynType = 0;
21804
0
        DerBuffer* der;
21805
21806
        /* Determine dynamic type */
21807
0
        switch (type) {
21808
0
            case CA_TYPE:   dynType = DYNAMIC_TYPE_CA;   break;
21809
0
            case CERT_TYPE: dynType = DYNAMIC_TYPE_CERT; break;
21810
0
            case CRL_TYPE:  dynType = DYNAMIC_TYPE_CRL;  break;
21811
0
            case DSA_TYPE:  dynType = DYNAMIC_TYPE_DSA;  break;
21812
0
            case ECC_TYPE:  dynType = DYNAMIC_TYPE_ECC;  break;
21813
0
            case RSA_TYPE:  dynType = DYNAMIC_TYPE_RSA;  break;
21814
0
            default:        dynType = DYNAMIC_TYPE_KEY;  break;
21815
0
        }
21816
21817
        /* Setup new buffer */
21818
0
        *pDer = (DerBuffer*)XMALLOC(sizeof(DerBuffer) + length, heap, dynType);
21819
0
        if (*pDer == NULL) {
21820
0
            return MEMORY_E;
21821
0
        }
21822
0
        XMEMSET(*pDer, 0, sizeof(DerBuffer) + length);
21823
21824
0
        der = *pDer;
21825
0
        der->type = type;
21826
0
        der->dynType = dynType; /* Cache this for FreeDer */
21827
0
        der->heap = heap;
21828
0
        der->buffer = (byte*)der + sizeof(DerBuffer);
21829
0
        der->length = length;
21830
0
        ret = 0; /* Success */
21831
0
    }
21832
0
    return ret;
21833
0
}
21834
21835
void FreeDer(DerBuffer** pDer)
21836
0
{
21837
0
    if (pDer && *pDer)
21838
0
    {
21839
0
        DerBuffer* der = (DerBuffer*)*pDer;
21840
21841
        /* ForceZero private keys */
21842
0
        if (der->type == PRIVATEKEY_TYPE && der->buffer != NULL) {
21843
0
            ForceZero(der->buffer, der->length);
21844
0
        }
21845
0
        der->buffer = NULL;
21846
0
        der->length = 0;
21847
0
        XFREE(der, der->heap, der->dynType);
21848
21849
0
        *pDer = NULL;
21850
0
    }
21851
0
}
21852
21853
int wc_AllocDer(DerBuffer** pDer, word32 length, int type, void* heap)
21854
0
{
21855
0
    return AllocDer(pDer, length, type, heap);
21856
0
}
21857
void wc_FreeDer(DerBuffer** pDer)
21858
0
{
21859
0
    FreeDer(pDer);
21860
0
}
21861
21862
21863
#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
21864
21865
/* Note: If items added make sure MAX_X509_HEADER_SZ is
21866
    updated to reflect maximum length and pem_struct_min_sz
21867
    to reflect minimum size */
21868
wcchar BEGIN_CERT           = "-----BEGIN CERTIFICATE-----";
21869
wcchar END_CERT             = "-----END CERTIFICATE-----";
21870
#ifdef WOLFSSL_CERT_REQ
21871
    wcchar BEGIN_CERT_REQ   = "-----BEGIN CERTIFICATE REQUEST-----";
21872
    wcchar END_CERT_REQ     = "-----END CERTIFICATE REQUEST-----";
21873
#endif
21874
#ifndef NO_DH
21875
    wcchar BEGIN_DH_PARAM   = "-----BEGIN DH PARAMETERS-----";
21876
    wcchar END_DH_PARAM     = "-----END DH PARAMETERS-----";
21877
    wcchar BEGIN_X942_PARAM = "-----BEGIN X9.42 DH PARAMETERS-----";
21878
    wcchar END_X942_PARAM   = "-----END X9.42 DH PARAMETERS-----";
21879
#endif
21880
#ifndef NO_DSA
21881
    wcchar BEGIN_DSA_PARAM  = "-----BEGIN DSA PARAMETERS-----";
21882
    wcchar END_DSA_PARAM    = "-----END DSA PARAMETERS-----";
21883
#endif
21884
wcchar BEGIN_X509_CRL       = "-----BEGIN X509 CRL-----";
21885
wcchar END_X509_CRL         = "-----END X509 CRL-----";
21886
wcchar BEGIN_RSA_PRIV       = "-----BEGIN RSA PRIVATE KEY-----";
21887
wcchar END_RSA_PRIV         = "-----END RSA PRIVATE KEY-----";
21888
wcchar BEGIN_RSA_PUB        = "-----BEGIN RSA PUBLIC KEY-----";
21889
wcchar END_RSA_PUB          = "-----END RSA PUBLIC KEY-----";
21890
wcchar BEGIN_PRIV_KEY       = "-----BEGIN PRIVATE KEY-----";
21891
wcchar END_PRIV_KEY         = "-----END PRIVATE KEY-----";
21892
wcchar BEGIN_ENC_PRIV_KEY   = "-----BEGIN ENCRYPTED PRIVATE KEY-----";
21893
wcchar END_ENC_PRIV_KEY     = "-----END ENCRYPTED PRIVATE KEY-----";
21894
#ifdef HAVE_ECC
21895
    wcchar BEGIN_EC_PRIV    = "-----BEGIN EC PRIVATE KEY-----";
21896
    wcchar END_EC_PRIV      = "-----END EC PRIVATE KEY-----";
21897
#endif
21898
#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \
21899
                                                                !defined(NO_DSA)
21900
    wcchar BEGIN_DSA_PRIV   = "-----BEGIN DSA PRIVATE KEY-----";
21901
    wcchar END_DSA_PRIV     = "-----END DSA PRIVATE KEY-----";
21902
#endif
21903
#ifdef OPENSSL_EXTRA
21904
    const char BEGIN_PRIV_KEY_PREFIX[] = "-----BEGIN";
21905
    const char PRIV_KEY_SUFFIX[] = "PRIVATE KEY-----";
21906
    const char END_PRIV_KEY_PREFIX[]   = "-----END";
21907
#endif
21908
wcchar BEGIN_PUB_KEY        = "-----BEGIN PUBLIC KEY-----";
21909
wcchar END_PUB_KEY          = "-----END PUBLIC KEY-----";
21910
#if defined(HAVE_ED25519) || defined(HAVE_ED448)
21911
    wcchar BEGIN_EDDSA_PRIV = "-----BEGIN EDDSA PRIVATE KEY-----";
21912
    wcchar END_EDDSA_PRIV   = "-----END EDDSA PRIVATE KEY-----";
21913
#endif
21914
#if defined(HAVE_PQC)
21915
#if defined(HAVE_FALCON)
21916
    wcchar BEGIN_FALCON_LEVEL1_PRIV  = "-----BEGIN FALCON_LEVEL1 PRIVATE KEY-----";
21917
    wcchar END_FALCON_LEVEL1_PRIV    = "-----END FALCON_LEVEL1 PRIVATE KEY-----";
21918
    wcchar BEGIN_FALCON_LEVEL5_PRIV = "-----BEGIN FALCON_LEVEL5 PRIVATE KEY-----";
21919
    wcchar END_FALCON_LEVEL5_PRIV   = "-----END FALCON_LEVEL5 PRIVATE KEY-----";
21920
#endif /* HAVE_FALCON */
21921
#if defined(HAVE_DILITHIUM)
21922
    wcchar BEGIN_DILITHIUM_LEVEL2_PRIV = "-----BEGIN DILITHIUM_LEVEL2 PRIVATE KEY-----";
21923
    wcchar END_DILITHIUM_LEVEL2_PRIV   = "-----END DILITHIUM_LEVEL2 PRIVATE KEY-----";
21924
    wcchar BEGIN_DILITHIUM_LEVEL3_PRIV = "-----BEGIN DILITHIUM_LEVEL3 PRIVATE KEY-----";
21925
    wcchar END_DILITHIUM_LEVEL3_PRIV   = "-----END DILITHIUM_LEVEL3 PRIVATE KEY-----";
21926
    wcchar BEGIN_DILITHIUM_LEVEL5_PRIV = "-----BEGIN DILITHIUM_LEVEL5 PRIVATE KEY-----";
21927
    wcchar END_DILITHIUM_LEVEL5_PRIV   = "-----END DILITHIUM_LEVEL5 PRIVATE KEY-----";
21928
21929
    wcchar BEGIN_DILITHIUM_AES_LEVEL2_PRIV = "-----BEGIN DILITHIUM_AES_LEVEL2 PRIVATE KEY-----";
21930
    wcchar END_DILITHIUM_AES_LEVEL2_PRIV   = "-----END DILITHIUM_AES_LEVEL2 PRIVATE KEY-----";
21931
    wcchar BEGIN_DILITHIUM_AES_LEVEL3_PRIV = "-----BEGIN DILITHIUM_AES_LEVEL3 PRIVATE KEY-----";
21932
    wcchar END_DILITHIUM_AES_LEVEL3_PRIV   = "-----END DILITHIUM_AES_LEVEL3 PRIVATE KEY-----";
21933
    wcchar BEGIN_DILITHIUM_AES_LEVEL5_PRIV = "-----BEGIN DILITHIUM_AES_LEVEL5 PRIVATE KEY-----";
21934
    wcchar END_DILITHIUM_AES_LEVEL5_PRIV   = "-----END DILITHIUM_AES_LEVEL5 PRIVATE KEY-----";
21935
#endif /* HAVE_DILITHIUM */
21936
#endif /* HAVE_PQC */
21937
21938
const int pem_struct_min_sz = XSTR_SIZEOF("-----BEGIN X509 CRL-----"
21939
                                             "-----END X509 CRL-----");
21940
21941
static WC_INLINE const char* SkipEndOfLineChars(const char* line,
21942
                                                const char* endOfLine)
21943
0
{
21944
    /* eat end of line characters */
21945
0
    while (line < endOfLine &&
21946
0
              (line[0] == '\r' || line[0] == '\n')) {
21947
0
        line++;
21948
0
    }
21949
0
    return line;
21950
0
}
21951
21952
int wc_PemGetHeaderFooter(int type, const char** header, const char** footer)
21953
0
{
21954
0
    int ret = BAD_FUNC_ARG;
21955
21956
0
    switch (type) {
21957
0
        case CA_TYPE:       /* same as below */
21958
0
        case TRUSTED_PEER_TYPE:
21959
0
        case CERT_TYPE:
21960
0
            if (header) *header = BEGIN_CERT;
21961
0
            if (footer) *footer = END_CERT;
21962
0
            ret = 0;
21963
0
            break;
21964
21965
0
        case CRL_TYPE:
21966
0
            if (header) *header = BEGIN_X509_CRL;
21967
0
            if (footer) *footer = END_X509_CRL;
21968
0
            ret = 0;
21969
0
            break;
21970
0
    #ifndef NO_DH
21971
0
        case DH_PARAM_TYPE:
21972
0
            if (header) *header = BEGIN_DH_PARAM;
21973
0
            if (footer) *footer = END_DH_PARAM;
21974
0
            ret = 0;
21975
0
            break;
21976
0
        case X942_PARAM_TYPE:
21977
0
            if (header) *header = BEGIN_X942_PARAM;
21978
0
            if (footer) *footer = END_X942_PARAM;
21979
0
            ret = 0;
21980
0
            break;
21981
0
    #endif
21982
    #ifndef NO_DSA
21983
        case DSA_PARAM_TYPE:
21984
            if (header) *header = BEGIN_DSA_PARAM;
21985
            if (footer) *footer = END_DSA_PARAM;
21986
            ret = 0;
21987
            break;
21988
    #endif
21989
    #ifdef WOLFSSL_CERT_REQ
21990
        case CERTREQ_TYPE:
21991
            if (header) *header = BEGIN_CERT_REQ;
21992
            if (footer) *footer = END_CERT_REQ;
21993
            ret = 0;
21994
            break;
21995
    #endif
21996
    #ifndef NO_DSA
21997
        case DSA_TYPE:
21998
        case DSA_PRIVATEKEY_TYPE:
21999
            if (header) *header = BEGIN_DSA_PRIV;
22000
            if (footer) *footer = END_DSA_PRIV;
22001
            ret = 0;
22002
            break;
22003
    #endif
22004
0
    #ifdef HAVE_ECC
22005
0
        case ECC_TYPE:
22006
0
        case ECC_PRIVATEKEY_TYPE:
22007
0
            if (header) *header = BEGIN_EC_PRIV;
22008
0
            if (footer) *footer = END_EC_PRIV;
22009
0
            ret = 0;
22010
0
            break;
22011
0
    #endif
22012
0
        case RSA_TYPE:
22013
0
        case PRIVATEKEY_TYPE:
22014
0
            if (header) *header = BEGIN_RSA_PRIV;
22015
0
            if (footer) *footer = END_RSA_PRIV;
22016
0
            ret = 0;
22017
0
            break;
22018
0
    #ifdef HAVE_ED25519
22019
0
        case ED25519_TYPE:
22020
0
    #endif
22021
0
    #ifdef HAVE_ED448
22022
0
        case ED448_TYPE:
22023
0
    #endif
22024
0
    #if defined(HAVE_ED25519) || defined(HAVE_ED448)
22025
0
        case EDDSA_PRIVATEKEY_TYPE:
22026
0
            if (header) *header = BEGIN_EDDSA_PRIV;
22027
0
            if (footer) *footer = END_EDDSA_PRIV;
22028
0
            ret = 0;
22029
0
            break;
22030
0
    #endif
22031
#ifdef HAVE_PQC
22032
#ifdef HAVE_FALCON
22033
        case FALCON_LEVEL1_TYPE:
22034
            if (header) *header = BEGIN_FALCON_LEVEL1_PRIV;
22035
            if (footer) *footer = END_FALCON_LEVEL1_PRIV;
22036
            ret = 0;
22037
            break;
22038
        case FALCON_LEVEL5_TYPE:
22039
            if (header) *header = BEGIN_FALCON_LEVEL5_PRIV;
22040
            if (footer) *footer = END_FALCON_LEVEL5_PRIV;
22041
            ret = 0;
22042
            break;
22043
#endif /* HAVE_FALCON */
22044
#ifdef HAVE_DILITHIUM
22045
        case DILITHIUM_LEVEL2_TYPE:
22046
            if (header) *header = BEGIN_DILITHIUM_LEVEL2_PRIV;
22047
            if (footer) *footer = END_DILITHIUM_LEVEL2_PRIV;
22048
            ret = 0;
22049
            break;
22050
        case DILITHIUM_LEVEL3_TYPE:
22051
            if (header) *header = BEGIN_DILITHIUM_LEVEL3_PRIV;
22052
            if (footer) *footer = END_DILITHIUM_LEVEL3_PRIV;
22053
            ret = 0;
22054
            break;
22055
        case DILITHIUM_LEVEL5_TYPE:
22056
            if (header) *header = BEGIN_DILITHIUM_LEVEL5_PRIV;
22057
            if (footer) *footer = END_DILITHIUM_LEVEL5_PRIV;
22058
            ret = 0;
22059
            break;
22060
        case DILITHIUM_AES_LEVEL2_TYPE:
22061
            if (header) *header = BEGIN_DILITHIUM_AES_LEVEL2_PRIV;
22062
            if (footer) *footer = END_DILITHIUM_AES_LEVEL2_PRIV;
22063
            ret = 0;
22064
            break;
22065
        case DILITHIUM_AES_LEVEL3_TYPE:
22066
            if (header) *header = BEGIN_DILITHIUM_AES_LEVEL3_PRIV;
22067
            if (footer) *footer = END_DILITHIUM_AES_LEVEL3_PRIV;
22068
            ret = 0;
22069
            break;
22070
        case DILITHIUM_AES_LEVEL5_TYPE:
22071
            if (header) *header = BEGIN_DILITHIUM_AES_LEVEL5_PRIV;
22072
            if (footer) *footer = END_DILITHIUM_AES_LEVEL5_PRIV;
22073
            ret = 0;
22074
            break;
22075
#endif /* HAVE_DILITHIUM */
22076
#endif /* HAVE_PQC */
22077
0
        case PUBLICKEY_TYPE:
22078
0
        case ECC_PUBLICKEY_TYPE:
22079
0
            if (header) *header = BEGIN_PUB_KEY;
22080
0
            if (footer) *footer = END_PUB_KEY;
22081
0
            ret = 0;
22082
0
            break;
22083
0
    #ifndef NO_DH
22084
0
        case DH_PRIVATEKEY_TYPE:
22085
0
    #endif
22086
0
        case PKCS8_PRIVATEKEY_TYPE:
22087
0
            if (header) *header = BEGIN_PRIV_KEY;
22088
0
            if (footer) *footer = END_PRIV_KEY;
22089
0
            ret = 0;
22090
0
            break;
22091
0
        case PKCS8_ENC_PRIVATEKEY_TYPE:
22092
0
            if (header) *header = BEGIN_ENC_PRIV_KEY;
22093
0
            if (footer) *footer = END_ENC_PRIV_KEY;
22094
0
            ret = 0;
22095
0
            break;
22096
0
        default:
22097
0
            break;
22098
0
    }
22099
0
    return ret;
22100
0
}
22101
22102
#ifdef WOLFSSL_ENCRYPTED_KEYS
22103
22104
static wcchar kProcTypeHeader = "Proc-Type";
22105
static wcchar kDecInfoHeader = "DEK-Info";
22106
22107
#ifdef WOLFSSL_PEM_TO_DER
22108
#ifndef NO_DES3
22109
    static wcchar kEncTypeDes = "DES-CBC";
22110
    static wcchar kEncTypeDes3 = "DES-EDE3-CBC";
22111
#endif
22112
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)
22113
    static wcchar kEncTypeAesCbc128 = "AES-128-CBC";
22114
#endif
22115
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_192)
22116
    static wcchar kEncTypeAesCbc192 = "AES-192-CBC";
22117
#endif
22118
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
22119
    static wcchar kEncTypeAesCbc256 = "AES-256-CBC";
22120
#endif
22121
22122
int wc_EncryptedInfoGet(EncryptedInfo* info, const char* cipherInfo)
22123
{
22124
    int ret = 0;
22125
22126
    if (info == NULL || cipherInfo == NULL)
22127
        return BAD_FUNC_ARG;
22128
22129
    /* determine cipher information */
22130
#ifndef NO_DES3
22131
    if (XSTRCMP(cipherInfo, kEncTypeDes) == 0) {
22132
        info->cipherType = WC_CIPHER_DES;
22133
        info->keySz = DES_KEY_SIZE;
22134
/* DES_IV_SIZE is incorrectly 16 in FIPS v2. It should be 8, same as the
22135
 * block size. */
22136
#if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION == 2)
22137
        if (info->ivSz == 0) info->ivSz  = DES_BLOCK_SIZE;
22138
#else
22139
        if (info->ivSz == 0) info->ivSz  = DES_IV_SIZE;
22140
#endif
22141
    }
22142
    else if (XSTRCMP(cipherInfo, kEncTypeDes3) == 0) {
22143
        info->cipherType = WC_CIPHER_DES3;
22144
        info->keySz = DES3_KEY_SIZE;
22145
#if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION == 2)
22146
        if (info->ivSz == 0) info->ivSz  = DES_BLOCK_SIZE;
22147
#else
22148
        if (info->ivSz == 0) info->ivSz  = DES_IV_SIZE;
22149
#endif
22150
    }
22151
    else
22152
#endif /* !NO_DES3 */
22153
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)
22154
    if (XSTRCMP(cipherInfo, kEncTypeAesCbc128) == 0) {
22155
        info->cipherType = WC_CIPHER_AES_CBC;
22156
        info->keySz = AES_128_KEY_SIZE;
22157
        if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;
22158
    }
22159
    else
22160
#endif
22161
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_192)
22162
    if (XSTRCMP(cipherInfo, kEncTypeAesCbc192) == 0) {
22163
        info->cipherType = WC_CIPHER_AES_CBC;
22164
        info->keySz = AES_192_KEY_SIZE;
22165
        if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;
22166
    }
22167
    else
22168
#endif
22169
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
22170
    if (XSTRCMP(cipherInfo, kEncTypeAesCbc256) == 0) {
22171
        info->cipherType = WC_CIPHER_AES_CBC;
22172
        info->keySz = AES_256_KEY_SIZE;
22173
        if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;
22174
    }
22175
    else
22176
#endif
22177
    {
22178
        ret = NOT_COMPILED_IN;
22179
    }
22180
    return ret;
22181
}
22182
22183
int wc_EncryptedInfoParse(EncryptedInfo* info, const char** pBuffer,
22184
                          size_t bufSz)
22185
{
22186
    int         err = 0;
22187
    const char* bufferStart;
22188
    const char* bufferEnd;
22189
    char*       line;
22190
    word32      lineSz;
22191
    char*       finish;
22192
    word32      finishSz;
22193
    char*       start = NULL;
22194
    word32      startSz;
22195
    const char* newline = NULL;
22196
22197
    if (info == NULL || pBuffer == NULL || bufSz == 0)
22198
        return BAD_FUNC_ARG;
22199
22200
    bufferStart = *pBuffer;
22201
    bufferEnd = bufferStart + bufSz;
22202
22203
    /* find encrypted info marker */
22204
    line = XSTRNSTR(bufferStart, kProcTypeHeader,
22205
                    min((word32)bufSz, PEM_LINE_LEN));
22206
    if (line != NULL) {
22207
        if (line >= bufferEnd) {
22208
            return BUFFER_E;
22209
        }
22210
22211
        lineSz = (word32)(bufferEnd - line);
22212
22213
        /* find DEC-Info marker */
22214
        start = XSTRNSTR(line, kDecInfoHeader, min(lineSz, PEM_LINE_LEN));
22215
22216
        if (start == NULL)
22217
            return BUFFER_E;
22218
22219
        /* skip dec-info and ": " */
22220
        start += XSTRLEN(kDecInfoHeader);
22221
        if (start >= bufferEnd)
22222
            return BUFFER_E;
22223
22224
        if (start[0] == ':') {
22225
            start++;
22226
            if (start >= bufferEnd)
22227
                return BUFFER_E;
22228
        }
22229
        if (start[0] == ' ')
22230
            start++;
22231
22232
        startSz = (word32)(bufferEnd - start);
22233
        finish = XSTRNSTR(start, ",", min(startSz, PEM_LINE_LEN));
22234
22235
        if ((start != NULL) && (finish != NULL) && (start < finish)) {
22236
            if (finish >= bufferEnd) {
22237
                return BUFFER_E;
22238
            }
22239
22240
            finishSz = (word32)(bufferEnd - finish);
22241
            newline = XSTRNSTR(finish, "\r", min(finishSz, PEM_LINE_LEN));
22242
22243
            /* get cipher name */
22244
            if (NAME_SZ < (finish - start)) /* buffer size of info->name */
22245
                return BUFFER_E;
22246
            if (XMEMCPY(info->name, start, finish - start) == NULL)
22247
                return BUFFER_E;
22248
            info->name[finish - start] = '\0'; /* null term */
22249
22250
            /* populate info */
22251
            err = wc_EncryptedInfoGet(info, info->name);
22252
            if (err != 0)
22253
                return err;
22254
22255
            /* get IV */
22256
            if (finishSz < info->ivSz + 1)
22257
                return BUFFER_E;
22258
22259
            if (newline == NULL) {
22260
                newline = XSTRNSTR(finish, "\n", min(finishSz,
22261
                                                     PEM_LINE_LEN));
22262
            }
22263
            if ((newline != NULL) && (newline > finish)) {
22264
                finish++;
22265
                info->ivSz = (word32)(newline - finish);
22266
                if (info->ivSz > IV_SZ)
22267
                    return BUFFER_E;
22268
                if (XMEMCPY(info->iv, finish, info->ivSz) == NULL)
22269
                    return BUFFER_E;
22270
                info->set = 1;
22271
            }
22272
            else
22273
                return BUFFER_E;
22274
        }
22275
        else
22276
            return BUFFER_E;
22277
22278
        /* eat end of line characters */
22279
        newline = SkipEndOfLineChars(newline, bufferEnd);
22280
22281
        /* return new headerEnd */
22282
22283
        *pBuffer = newline;
22284
    }
22285
22286
    return err;
22287
}
22288
#endif /* WOLFSSL_PEM_TO_DER */
22289
22290
#ifdef WOLFSSL_DER_TO_PEM
22291
static int wc_EncryptedInfoAppend(char* dest, int destSz, char* cipherInfo)
22292
{
22293
    if (cipherInfo != NULL) {
22294
        int cipherInfoStrLen = (int)XSTRLEN((char*)cipherInfo);
22295
22296
        if (cipherInfoStrLen > HEADER_ENCRYPTED_KEY_SIZE - (9+14+10+3))
22297
            cipherInfoStrLen = HEADER_ENCRYPTED_KEY_SIZE - (9+14+10+3);
22298
22299
        if (destSz - (int)XSTRLEN(dest) >= cipherInfoStrLen + (9+14+8+2+2+1)) {
22300
            /* strncat's src length needs to include the NULL */
22301
            XSTRNCAT(dest, kProcTypeHeader, 10);
22302
            XSTRNCAT(dest, ": 4,ENCRYPTED\n", 15);
22303
            XSTRNCAT(dest, kDecInfoHeader, 9);
22304
            XSTRNCAT(dest, ": ", 3);
22305
            XSTRNCAT(dest, cipherInfo, destSz - (int)XSTRLEN(dest) - 1);
22306
            XSTRNCAT(dest, "\n\n", 4);
22307
        }
22308
    }
22309
    return 0;
22310
}
22311
#endif /* WOLFSSL_DER_TO_PEM */
22312
#endif /* WOLFSSL_ENCRYPTED_KEYS */
22313
22314
#ifdef WOLFSSL_DER_TO_PEM
22315
22316
/* Used for compatibility API */
22317
WOLFSSL_ABI
22318
int wc_DerToPem(const byte* der, word32 derSz,
22319
                byte* output, word32 outSz, int type)
22320
0
{
22321
0
    return wc_DerToPemEx(der, derSz, output, outSz, NULL, type);
22322
0
}
22323
22324
/* convert der buffer to pem into output, can't do inplace, der and output
22325
   need to be different */
22326
int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz,
22327
             byte *cipher_info, int type)
22328
0
{
22329
0
    const char* headerStr = NULL;
22330
0
    const char* footerStr = NULL;
22331
0
#ifdef WOLFSSL_SMALL_STACK
22332
0
    char* header = NULL;
22333
0
    char* footer = NULL;
22334
#else
22335
    char header[MAX_X509_HEADER_SZ + HEADER_ENCRYPTED_KEY_SIZE];
22336
    char footer[MAX_X509_HEADER_SZ];
22337
#endif
22338
0
    int headerLen = MAX_X509_HEADER_SZ + HEADER_ENCRYPTED_KEY_SIZE;
22339
0
    int footerLen = MAX_X509_HEADER_SZ;
22340
0
    int i;
22341
0
    int err;
22342
0
    int outLen;   /* return length or error */
22343
22344
0
    (void)cipher_info;
22345
22346
0
    if (der == output)      /* no in place conversion */
22347
0
        return BAD_FUNC_ARG;
22348
22349
0
    err = wc_PemGetHeaderFooter(type, &headerStr, &footerStr);
22350
0
    if (err != 0)
22351
0
        return err;
22352
22353
0
#ifdef WOLFSSL_SMALL_STACK
22354
0
    header = (char*)XMALLOC(headerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22355
0
    if (header == NULL)
22356
0
        return MEMORY_E;
22357
22358
0
    footer = (char*)XMALLOC(footerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22359
0
    if (footer == NULL) {
22360
0
        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22361
0
        return MEMORY_E;
22362
0
    }
22363
0
#endif
22364
22365
    /* build header and footer based on type */
22366
0
    XSTRNCPY(header, headerStr, headerLen - 1);
22367
0
    header[headerLen - 2] = 0;
22368
0
    XSTRNCPY(footer, footerStr, footerLen - 1);
22369
0
    footer[footerLen - 2] = 0;
22370
22371
    /* add new line to end */
22372
0
    XSTRNCAT(header, "\n", 2);
22373
0
    XSTRNCAT(footer, "\n", 2);
22374
22375
#ifdef WOLFSSL_ENCRYPTED_KEYS
22376
    err = wc_EncryptedInfoAppend(header, headerLen, (char*)cipher_info);
22377
    if (err != 0) {
22378
    #ifdef WOLFSSL_SMALL_STACK
22379
        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22380
        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22381
    #endif
22382
        return err;
22383
    }
22384
#endif
22385
22386
0
    headerLen = (int)XSTRLEN(header);
22387
0
    footerLen = (int)XSTRLEN(footer);
22388
22389
    /* if null output and 0 size passed in then return size needed */
22390
0
    if (!output && outSz == 0) {
22391
0
#ifdef WOLFSSL_SMALL_STACK
22392
0
        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22393
0
        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22394
0
#endif
22395
0
        outLen = 0;
22396
0
        if ((err = Base64_Encode(der, derSz, NULL, (word32*)&outLen))
22397
0
                != LENGTH_ONLY_E) {
22398
0
            WOLFSSL_ERROR_VERBOSE(err);
22399
0
            return err;
22400
0
        }
22401
0
        return headerLen + footerLen + outLen;
22402
0
    }
22403
22404
0
    if (!der || !output) {
22405
0
#ifdef WOLFSSL_SMALL_STACK
22406
0
        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22407
0
        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22408
0
#endif
22409
0
        return BAD_FUNC_ARG;
22410
0
    }
22411
22412
    /* don't even try if outSz too short */
22413
0
    if (outSz < headerLen + footerLen + derSz) {
22414
0
#ifdef WOLFSSL_SMALL_STACK
22415
0
        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22416
0
        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22417
0
#endif
22418
0
        return BAD_FUNC_ARG;
22419
0
    }
22420
22421
    /* header */
22422
0
    XMEMCPY(output, header, headerLen);
22423
0
    i = headerLen;
22424
22425
0
#ifdef WOLFSSL_SMALL_STACK
22426
0
    XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22427
0
#endif
22428
22429
    /* body */
22430
0
    outLen = outSz - (headerLen + footerLen);  /* input to Base64_Encode */
22431
0
    if ( (err = Base64_Encode(der, derSz, output + i, (word32*)&outLen)) < 0) {
22432
0
#ifdef WOLFSSL_SMALL_STACK
22433
0
        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22434
0
#endif
22435
0
        WOLFSSL_ERROR_VERBOSE(err);
22436
0
        return err;
22437
0
    }
22438
0
    i += outLen;
22439
22440
    /* footer */
22441
0
    if ( (i + footerLen) > (int)outSz) {
22442
0
#ifdef WOLFSSL_SMALL_STACK
22443
0
        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22444
0
#endif
22445
0
        return BAD_FUNC_ARG;
22446
0
    }
22447
0
    XMEMCPY(output + i, footer, footerLen);
22448
22449
0
#ifdef WOLFSSL_SMALL_STACK
22450
0
    XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
22451
0
#endif
22452
22453
0
    return outLen + headerLen + footerLen;
22454
0
}
22455
22456
#endif /* WOLFSSL_DER_TO_PEM */
22457
22458
#ifdef WOLFSSL_PEM_TO_DER
22459
22460
/* Remove PEM header/footer, convert to ASN1, store any encrypted data
22461
   info->consumed tracks of PEM bytes consumed in case multiple parts */
22462
int PemToDer(const unsigned char* buff, long longSz, int type,
22463
              DerBuffer** pDer, void* heap, EncryptedInfo* info, int* keyFormat)
22464
0
{
22465
0
    const char* header      = NULL;
22466
0
    const char* footer      = NULL;
22467
0
    const char* headerEnd;
22468
0
    const char* footerEnd;
22469
0
    const char* consumedEnd;
22470
0
    const char* bufferEnd   = (const char*)(buff + longSz);
22471
0
    long        neededSz;
22472
0
    int         ret         = 0;
22473
0
    int         sz          = (int)longSz;
22474
0
    int         encrypted_key = 0;
22475
0
    DerBuffer*  der;
22476
0
    word32      algId = 0;
22477
0
    word32      idx;
22478
#if defined(WOLFSSL_ENCRYPTED_KEYS)
22479
    #if ((defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_DES3)) || \
22480
         (!defined(NO_AES) && defined(HAVE_AES_CBC) && \
22481
          defined(HAVE_AES_DECRYPT))) && \
22482
        !defined(NO_WOLFSSL_SKIP_TRAILING_PAD)
22483
        int     padVal = 0;
22484
    #endif
22485
#endif
22486
#ifdef OPENSSL_EXTRA
22487
    char        beginBuf[PEM_LINE_LEN + 1]; /* add 1 for null terminator */
22488
    char        endBuf[PEM_LINE_LEN + 1];   /* add 1 for null terminator */
22489
#endif
22490
22491
0
    WOLFSSL_ENTER("PemToDer");
22492
22493
    /* get PEM header and footer based on type */
22494
0
    ret = wc_PemGetHeaderFooter(type, &header, &footer);
22495
0
    if (ret != 0)
22496
0
        return ret;
22497
22498
    /* map header if not found for type */
22499
0
    for (;;) {
22500
0
        headerEnd = XSTRNSTR((char*)buff, header, sz);
22501
0
        if (headerEnd) {
22502
0
            break;
22503
0
        }
22504
22505
0
        if (type == PRIVATEKEY_TYPE) {
22506
0
            if (header == BEGIN_RSA_PRIV) {
22507
0
                header = BEGIN_PRIV_KEY;
22508
0
                footer = END_PRIV_KEY;
22509
0
            }
22510
0
            else if (header == BEGIN_PRIV_KEY) {
22511
0
                header = BEGIN_ENC_PRIV_KEY;
22512
0
                footer = END_ENC_PRIV_KEY;
22513
0
            }
22514
0
#ifdef HAVE_ECC
22515
0
            else if (header == BEGIN_ENC_PRIV_KEY) {
22516
0
                header = BEGIN_EC_PRIV;
22517
0
                footer = END_EC_PRIV;
22518
0
            }
22519
0
            else if (header == BEGIN_EC_PRIV) {
22520
0
                header = BEGIN_DSA_PRIV;
22521
0
                footer = END_DSA_PRIV;
22522
0
            }
22523
0
#endif
22524
0
#if defined(HAVE_ED25519) || defined(HAVE_ED448)
22525
0
    #ifdef HAVE_ECC
22526
0
            else if (header == BEGIN_DSA_PRIV) {
22527
    #else
22528
            else if (header == BEGIN_ENC_PRIV_KEY) {
22529
    #endif
22530
0
                header = BEGIN_EDDSA_PRIV;
22531
0
                footer = END_EDDSA_PRIV;
22532
0
            }
22533
0
#endif
22534
0
            else {
22535
0
            #ifdef WOLF_PRIVATE_KEY_ID
22536
                /* allow loading a public key for use with crypto or PK callbacks */
22537
0
                type = PUBLICKEY_TYPE;
22538
0
                header = BEGIN_PUB_KEY;
22539
0
                footer = END_PUB_KEY;
22540
            #else
22541
                break;
22542
            #endif
22543
0
            }
22544
0
        }
22545
0
        else if (type == PUBLICKEY_TYPE) {
22546
0
            if (header == BEGIN_PUB_KEY) {
22547
0
                header = BEGIN_RSA_PUB;
22548
0
                footer = END_RSA_PUB;
22549
0
            }
22550
0
            else {
22551
0
                break;
22552
0
            }
22553
0
        }
22554
#ifdef HAVE_CRL
22555
        else if ((type == CRL_TYPE) && (header != BEGIN_X509_CRL)) {
22556
            header =  BEGIN_X509_CRL;
22557
            footer = END_X509_CRL;
22558
        }
22559
#endif
22560
0
        else {
22561
0
            break;
22562
0
        }
22563
0
    }
22564
22565
0
    if (!headerEnd) {
22566
#ifdef OPENSSL_EXTRA
22567
        if (type == PRIVATEKEY_TYPE) {
22568
            const char* beginEnd;
22569
            int endLen;
22570
            /* see if there is a -----BEGIN * PRIVATE KEY----- header */
22571
            headerEnd = XSTRNSTR((char*)buff, PRIV_KEY_SUFFIX, sz);
22572
            if (headerEnd) {
22573
                beginEnd = headerEnd + XSTR_SIZEOF(PRIV_KEY_SUFFIX);
22574
                if (beginEnd >= (char*)buff + sz) {
22575
                    return BUFFER_E;
22576
                }
22577
22578
                /* back up to BEGIN_PRIV_KEY_PREFIX */
22579
                while (headerEnd > (char*)buff &&
22580
                        XSTRNCMP(headerEnd, BEGIN_PRIV_KEY_PREFIX,
22581
                                XSTR_SIZEOF(BEGIN_PRIV_KEY_PREFIX)) != 0 &&
22582
                        *headerEnd != '\n') {
22583
                    headerEnd--;
22584
                }
22585
                if (headerEnd <= (char*)buff ||
22586
                        XSTRNCMP(headerEnd, BEGIN_PRIV_KEY_PREFIX,
22587
                        XSTR_SIZEOF(BEGIN_PRIV_KEY_PREFIX)) != 0 ||
22588
                        beginEnd - headerEnd > PEM_LINE_LEN) {
22589
                    WOLFSSL_MSG("Couldn't find PEM header");
22590
                    WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
22591
                    return ASN_NO_PEM_HEADER;
22592
                }
22593
22594
                /* headerEnd now points to beginning of header */
22595
                XMEMCPY(beginBuf, headerEnd, beginEnd - headerEnd);
22596
                beginBuf[beginEnd - headerEnd] = '\0';
22597
                /* look for matching footer */
22598
                footer = XSTRNSTR(beginEnd,
22599
                                beginBuf + XSTR_SIZEOF(BEGIN_PRIV_KEY_PREFIX),
22600
                                (unsigned int)((char*)buff + sz - beginEnd));
22601
                if (!footer) {
22602
                    WOLFSSL_MSG("Couldn't find PEM footer");
22603
                    WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
22604
                    return ASN_NO_PEM_HEADER;
22605
                }
22606
22607
                footer -= XSTR_SIZEOF(END_PRIV_KEY_PREFIX);
22608
                if (footer > (char*)buff + sz - XSTR_SIZEOF(END_PRIV_KEY_PREFIX)
22609
                        || XSTRNCMP(footer, END_PRIV_KEY_PREFIX,
22610
                            XSTR_SIZEOF(END_PRIV_KEY_PREFIX)) != 0) {
22611
                    WOLFSSL_MSG("Unexpected footer for PEM");
22612
                    return BUFFER_E;
22613
                }
22614
22615
                endLen = (unsigned int)(beginEnd - headerEnd -
22616
                            (XSTR_SIZEOF(BEGIN_PRIV_KEY_PREFIX) -
22617
                                    XSTR_SIZEOF(END_PRIV_KEY_PREFIX)));
22618
                XMEMCPY(endBuf, footer, endLen);
22619
                endBuf[endLen] = '\0';
22620
22621
                header = beginBuf;
22622
                footer = endBuf;
22623
                headerEnd = beginEnd;
22624
            }
22625
        }
22626
22627
        if (!headerEnd) {
22628
            WOLFSSL_MSG("Couldn't find PEM header");
22629
            WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
22630
            return ASN_NO_PEM_HEADER;
22631
        }
22632
#else
22633
0
        WOLFSSL_MSG("Couldn't find PEM header");
22634
0
        return ASN_NO_PEM_HEADER;
22635
0
#endif
22636
0
    } else {
22637
0
        headerEnd += XSTRLEN(header);
22638
0
    }
22639
22640
    /* eat end of line characters */
22641
0
    headerEnd = SkipEndOfLineChars(headerEnd, bufferEnd);
22642
22643
0
    if (keyFormat) {
22644
        /* keyFormat is Key_Sum enum */
22645
0
        if (type == PRIVATEKEY_TYPE) {
22646
0
        #ifndef NO_RSA
22647
0
            if (header == BEGIN_RSA_PRIV)
22648
0
                *keyFormat = RSAk;
22649
0
        #endif
22650
0
        #ifdef HAVE_ECC
22651
0
            if (header == BEGIN_EC_PRIV)
22652
0
                *keyFormat = ECDSAk;
22653
0
        #endif
22654
        #ifndef NO_DSA
22655
            if (header == BEGIN_DSA_PRIV)
22656
                *keyFormat = DSAk;
22657
        #endif
22658
0
        }
22659
0
    #ifdef WOLF_PRIVATE_KEY_ID
22660
0
        else if (type == PUBLICKEY_TYPE) {
22661
0
        #ifndef NO_RSA
22662
0
            if (header == BEGIN_RSA_PUB)
22663
0
                *keyFormat = RSAk;
22664
0
        #endif
22665
0
        }
22666
0
    #endif
22667
0
    }
22668
22669
#ifdef WOLFSSL_ENCRYPTED_KEYS
22670
    if (info) {
22671
        ret = wc_EncryptedInfoParse(info, &headerEnd, bufferEnd - headerEnd);
22672
        if (ret < 0)
22673
            return ret;
22674
        if (info->set)
22675
            encrypted_key = 1;
22676
    }
22677
#endif /* WOLFSSL_ENCRYPTED_KEYS */
22678
22679
    /* find footer */
22680
0
    footerEnd = XSTRNSTR(headerEnd, footer, (unsigned int)((char*)buff +
22681
0
        sz - headerEnd));
22682
0
    if (!footerEnd) {
22683
0
        if (info)
22684
0
            info->consumed = longSz; /* No more certs if no footer */
22685
0
        return BUFFER_E;
22686
0
    }
22687
22688
0
    consumedEnd = footerEnd + XSTRLEN(footer);
22689
22690
0
    if (consumedEnd < bufferEnd) { /* handle no end of line on last line */
22691
        /* eat end of line characters */
22692
0
        consumedEnd = SkipEndOfLineChars(consumedEnd, bufferEnd);
22693
        /* skip possible null term */
22694
0
        if (consumedEnd < bufferEnd && consumedEnd[0] == '\0')
22695
0
            consumedEnd++;
22696
0
    }
22697
22698
0
    if (info)
22699
0
        info->consumed = (long)(consumedEnd - (const char*)buff);
22700
22701
    /* set up der buffer */
22702
0
    neededSz = (long)(footerEnd - headerEnd);
22703
0
    if (neededSz > sz || neededSz <= 0)
22704
0
        return BUFFER_E;
22705
22706
0
    ret = AllocDer(pDer, (word32)neededSz, type, heap);
22707
0
    if (ret < 0) {
22708
0
        return ret;
22709
0
    }
22710
0
    der = *pDer;
22711
22712
0
    if (Base64_Decode((byte*)headerEnd, (word32)neededSz,
22713
0
                      der->buffer, &der->length) < 0) {
22714
0
        WOLFSSL_ERROR(BUFFER_E);
22715
0
        return BUFFER_E;
22716
0
    }
22717
22718
0
    if ((header == BEGIN_PRIV_KEY
22719
#ifdef OPENSSL_EXTRA
22720
         || header == beginBuf
22721
#endif
22722
0
#ifdef HAVE_ECC
22723
0
         || header == BEGIN_EC_PRIV
22724
0
#endif
22725
0
        ) && !encrypted_key)
22726
0
    {
22727
        /* detect pkcs8 key and get alg type */
22728
        /* keep PKCS8 header */
22729
0
        idx = 0;
22730
0
        ret = ToTraditionalInline_ex(der->buffer, &idx, der->length, &algId);
22731
0
        if (ret > 0) {
22732
0
            if (keyFormat)
22733
0
                *keyFormat = algId;
22734
0
        }
22735
0
        else {
22736
            /* ignore failure here and assume key is not pkcs8 wrapped */
22737
0
        }
22738
0
        return 0;
22739
0
    }
22740
22741
#ifdef WOLFSSL_ENCRYPTED_KEYS
22742
    if (encrypted_key || header == BEGIN_ENC_PRIV_KEY) {
22743
        int   passwordSz = NAME_SZ;
22744
    #ifdef WOLFSSL_SMALL_STACK
22745
        char* password = NULL;
22746
    #else
22747
        char  password[NAME_SZ];
22748
    #endif
22749
22750
        if (!info || !info->passwd_cb) {
22751
            WOLFSSL_MSG("No password callback set");
22752
            WOLFSSL_ERROR_VERBOSE(NO_PASSWORD);
22753
            return NO_PASSWORD;
22754
        }
22755
22756
    #ifdef WOLFSSL_SMALL_STACK
22757
        password = (char*)XMALLOC(passwordSz, heap, DYNAMIC_TYPE_STRING);
22758
        if (password == NULL) {
22759
            return MEMORY_E;
22760
        }
22761
    #endif
22762
22763
        /* get password */
22764
        ret = info->passwd_cb(password, passwordSz, PEM_PASS_READ,
22765
            info->passwd_userdata);
22766
        if (ret >= 0) {
22767
            passwordSz = ret;
22768
        #ifdef WOLFSSL_CHECK_MEM_ZERO
22769
            wc_MemZero_Add("PEM password", password, passwordSz);
22770
        #endif
22771
22772
            /* convert and adjust length */
22773
            if (header == BEGIN_ENC_PRIV_KEY) {
22774
            #ifndef NO_PWDBASED
22775
                ret = wc_DecryptPKCS8Key(der->buffer, der->length,
22776
                    password, passwordSz);
22777
                if (ret > 0) {
22778
                    /* update length by decrypted content */
22779
                    der->length = ret;
22780
                    idx = 0;
22781
                    /* detect pkcs8 key and get alg type */
22782
                    /* keep PKCS8 header */
22783
                    ret = ToTraditionalInline_ex(der->buffer, &idx, der->length,
22784
                        &algId);
22785
                    if (ret >= 0) {
22786
                        if (keyFormat)
22787
                            *keyFormat = algId;
22788
                        ret = 0;
22789
                    }
22790
                }
22791
            #else
22792
                WOLFSSL_ERROR_VERBOSE(NOT_COMPILED_IN);
22793
                ret = NOT_COMPILED_IN;
22794
            #endif
22795
            }
22796
            /* decrypt the key */
22797
            else {
22798
                if (passwordSz == 0) {
22799
                    /* The key is encrypted but does not have a password */
22800
                    WOLFSSL_MSG("No password for encrypted key");
22801
                    WOLFSSL_ERROR_VERBOSE(NO_PASSWORD);
22802
                    ret = NO_PASSWORD;
22803
                }
22804
                else {
22805
                    ret = wc_BufferKeyDecrypt(info, der->buffer, der->length,
22806
                        (byte*)password, passwordSz, WC_MD5);
22807
22808
#ifndef NO_WOLFSSL_SKIP_TRAILING_PAD
22809
                #ifndef NO_DES3
22810
                    if (info->cipherType == WC_CIPHER_DES3) {
22811
                        /* Assuming there is padding:
22812
                         *      (der->length > 0 && der->length > DES_BLOCK_SIZE &&
22813
                         *       (der->length % DES_BLOCK_SIZE) != 0)
22814
                         * and assuming the last value signifies the number of
22815
                         * padded bytes IE if last value is 0x08 then there are
22816
                         * 8 bytes of padding:
22817
                         *      padVal = der->buffer[der->length-1];
22818
                         * then strip this padding before proceeding:
22819
                         * der->length -= padVal;
22820
                         */
22821
                        if (der->length > DES_BLOCK_SIZE &&
22822
                            (der->length % DES_BLOCK_SIZE) != 0) {
22823
                            padVal = der->buffer[der->length-1];
22824
                            if (padVal < DES_BLOCK_SIZE) {
22825
                                der->length -= padVal;
22826
                            }
22827
                        }
22828
                    }
22829
                #endif /* !NO_DES3 */
22830
                #if !defined(NO_AES) && defined(HAVE_AES_CBC) && \
22831
                    defined(HAVE_AES_DECRYPT)
22832
                    if (info->cipherType == WC_CIPHER_AES_CBC) {
22833
                        if (der->length > AES_BLOCK_SIZE) {
22834
                            padVal = der->buffer[der->length-1];
22835
                            if (padVal <= AES_BLOCK_SIZE) {
22836
                                der->length -= padVal;
22837
                            }
22838
                        }
22839
                    }
22840
                #endif
22841
#endif /* !NO_WOLFSSL_SKIP_TRAILING_PAD */
22842
                }
22843
            }
22844
#ifdef OPENSSL_EXTRA
22845
            if (ret) {
22846
                PEMerr(0, PEM_R_BAD_DECRYPT);
22847
            }
22848
#endif
22849
            ForceZero(password, passwordSz);
22850
        }
22851
#ifdef OPENSSL_EXTRA
22852
        else {
22853
            PEMerr(0, PEM_R_BAD_PASSWORD_READ);
22854
        }
22855
#endif
22856
22857
    #ifdef WOLFSSL_SMALL_STACK
22858
        XFREE(password, heap, DYNAMIC_TYPE_STRING);
22859
    #elif defined(WOLFSSL_CHECK_MEM_ZERO)
22860
        wc_MemZero_Check(password, NAME_SZ);
22861
    #endif
22862
    }
22863
#endif /* WOLFSSL_ENCRYPTED_KEYS */
22864
22865
0
    return ret;
22866
0
}
22867
22868
int wc_PemToDer(const unsigned char* buff, long longSz, int type,
22869
              DerBuffer** pDer, void* heap, EncryptedInfo* info, int* keyFormat)
22870
0
{
22871
0
    int ret = PemToDer(buff, longSz, type, pDer, heap, info, keyFormat);
22872
0
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
22873
0
    if (ret == 0 && type == PRIVATEKEY_TYPE) {
22874
0
        DerBuffer* der = *pDer;
22875
        /* if a PKCS8 key header exists remove it */
22876
0
        ret = ToTraditional(der->buffer, der->length);
22877
0
        if (ret > 0) {
22878
0
            der->length = ret;
22879
0
        }
22880
0
        ret = 0; /* ignore error removing PKCS8 header */
22881
0
    }
22882
0
#endif
22883
0
    return ret;
22884
0
}
22885
22886
22887
/* our KeyPemToDer password callback, password in userData */
22888
static int KeyPemToDerPassCb(char* passwd, int sz, int rw, void* userdata)
22889
0
{
22890
0
    (void)rw;
22891
22892
0
    if (userdata == NULL)
22893
0
        return 0;
22894
22895
0
    XSTRNCPY(passwd, (char*)userdata, sz);
22896
0
    return min((word32)sz, (word32)XSTRLEN((char*)userdata));
22897
0
}
22898
22899
/* Return bytes written to buff or < 0 for error */
22900
int wc_KeyPemToDer(const unsigned char* pem, int pemSz,
22901
                        unsigned char* buff, int buffSz, const char* pass)
22902
0
{
22903
0
    int ret;
22904
0
    DerBuffer* der = NULL;
22905
0
#ifdef WOLFSSL_SMALL_STACK
22906
0
    EncryptedInfo* info = NULL;
22907
#else
22908
    EncryptedInfo  info[1];
22909
#endif
22910
22911
0
    WOLFSSL_ENTER("wc_KeyPemToDer");
22912
22913
0
    if (pem == NULL || buff == NULL || buffSz <= 0) {
22914
0
        WOLFSSL_MSG("Bad pem der args");
22915
0
        return BAD_FUNC_ARG;
22916
0
    }
22917
22918
0
#ifdef WOLFSSL_SMALL_STACK
22919
0
    info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
22920
0
                                   DYNAMIC_TYPE_ENCRYPTEDINFO);
22921
0
    if (info == NULL)
22922
0
        return MEMORY_E;
22923
0
#endif
22924
22925
0
    XMEMSET(info, 0, sizeof(EncryptedInfo));
22926
0
    info->passwd_cb = KeyPemToDerPassCb;
22927
0
    info->passwd_userdata = (void*)pass;
22928
22929
0
    ret = PemToDer(pem, pemSz, PRIVATEKEY_TYPE, &der, NULL, info, NULL);
22930
22931
0
#ifdef WOLFSSL_SMALL_STACK
22932
0
    XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
22933
0
#endif
22934
22935
0
    if (ret < 0 || der == NULL) {
22936
0
        WOLFSSL_MSG("Bad Pem To Der");
22937
0
    }
22938
0
    else {
22939
0
        if (der->length <= (word32)buffSz) {
22940
0
            XMEMCPY(buff, der->buffer, der->length);
22941
0
            ret = der->length;
22942
0
        }
22943
0
        else {
22944
0
            WOLFSSL_MSG("Bad der length");
22945
0
            ret = BAD_FUNC_ARG;
22946
0
        }
22947
0
    }
22948
22949
0
    FreeDer(&der);
22950
0
    return ret;
22951
0
}
22952
22953
22954
/* Return bytes written to buff or < 0 for error */
22955
int wc_CertPemToDer(const unsigned char* pem, int pemSz,
22956
                        unsigned char* buff, int buffSz, int type)
22957
0
{
22958
0
    int ret;
22959
0
    DerBuffer* der = NULL;
22960
22961
0
    WOLFSSL_ENTER("wc_CertPemToDer");
22962
22963
0
    if (pem == NULL || buff == NULL || buffSz <= 0) {
22964
0
        WOLFSSL_MSG("Bad pem der args");
22965
0
        return BAD_FUNC_ARG;
22966
0
    }
22967
22968
0
    if (type != CERT_TYPE && type != CA_TYPE && type != CERTREQ_TYPE) {
22969
0
        WOLFSSL_MSG("Bad cert type");
22970
0
        return BAD_FUNC_ARG;
22971
0
    }
22972
22973
22974
0
    ret = PemToDer(pem, pemSz, type, &der, NULL, NULL, NULL);
22975
0
    if (ret < 0 || der == NULL) {
22976
0
        WOLFSSL_MSG("Bad Pem To Der");
22977
0
    }
22978
0
    else {
22979
0
        if (der->length <= (word32)buffSz) {
22980
0
            XMEMCPY(buff, der->buffer, der->length);
22981
0
            ret = der->length;
22982
0
        }
22983
0
        else {
22984
0
            WOLFSSL_MSG("Bad der length");
22985
0
            ret = BAD_FUNC_ARG;
22986
0
        }
22987
0
    }
22988
22989
0
    FreeDer(&der);
22990
0
    return ret;
22991
0
}
22992
22993
#endif /* WOLFSSL_PEM_TO_DER */
22994
#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
22995
22996
22997
#ifdef WOLFSSL_PEM_TO_DER
22998
#if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER)
22999
/* Return bytes written to buff or < 0 for error */
23000
int wc_PubKeyPemToDer(const unsigned char* pem, int pemSz,
23001
                           unsigned char* buff, int buffSz)
23002
{
23003
    int ret;
23004
    DerBuffer* der = NULL;
23005
23006
    WOLFSSL_ENTER("wc_PubKeyPemToDer");
23007
23008
    if (pem == NULL || buff == NULL || buffSz <= 0) {
23009
        WOLFSSL_MSG("Bad pem der args");
23010
        return BAD_FUNC_ARG;
23011
    }
23012
23013
    ret = PemToDer(pem, pemSz, PUBLICKEY_TYPE, &der, NULL, NULL, NULL);
23014
    if (ret < 0 || der == NULL) {
23015
        WOLFSSL_MSG("Bad Pem To Der");
23016
    }
23017
    else {
23018
        if (der->length <= (word32)buffSz) {
23019
            XMEMCPY(buff, der->buffer, der->length);
23020
            ret = der->length;
23021
        }
23022
        else {
23023
            WOLFSSL_MSG("Bad der length");
23024
            ret = BAD_FUNC_ARG;
23025
        }
23026
    }
23027
23028
    FreeDer(&der);
23029
    return ret;
23030
}
23031
#endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */
23032
#endif /* WOLFSSL_PEM_TO_DER */
23033
23034
#if !defined(NO_FILESYSTEM) && defined(WOLFSSL_PEM_TO_DER)
23035
23036
#ifdef WOLFSSL_CERT_GEN
23037
int wc_PemCertToDer_ex(const char* fileName, DerBuffer** der)
23038
{
23039
#ifdef WOLFSSL_SMALL_STACK
23040
    byte   staticBuffer[1]; /* force XMALLOC */
23041
#else
23042
    byte   staticBuffer[FILE_BUFFER_SIZE];
23043
#endif
23044
    byte*  fileBuf = staticBuffer;
23045
    int    dynamic = 0;
23046
    int    ret     = 0;
23047
    long   sz      = 0;
23048
    XFILE  file    = NULL;
23049
23050
    WOLFSSL_ENTER("wc_PemCertToDer");
23051
23052
    if (fileName == NULL) {
23053
        ret = BAD_FUNC_ARG;
23054
    }
23055
    else {
23056
        file = XFOPEN(fileName, "rb");
23057
        if (file == XBADFILE) {
23058
            ret = BUFFER_E;
23059
        }
23060
    }
23061
23062
    if (ret == 0) {
23063
        if (XFSEEK(file, 0, XSEEK_END) != 0) {
23064
            ret = BUFFER_E;
23065
        }
23066
        sz = XFTELL(file);
23067
        XREWIND(file);
23068
23069
        if (sz <= 0) {
23070
            ret = BUFFER_E;
23071
        }
23072
        else if (sz > (long)sizeof(staticBuffer)) {
23073
            fileBuf = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
23074
            if (fileBuf == NULL)
23075
                ret = MEMORY_E;
23076
            else
23077
                dynamic = 1;
23078
        }
23079
23080
        if (ret == 0) {
23081
            if ((size_t)XFREAD(fileBuf, 1, sz, file) != (size_t)sz) {
23082
                ret = BUFFER_E;
23083
            }
23084
            else {
23085
                ret = PemToDer(fileBuf, sz, CA_TYPE, der,  0, NULL,NULL);
23086
            }
23087
        }
23088
23089
        XFCLOSE(file);
23090
        if (dynamic)
23091
            XFREE(fileBuf, NULL, DYNAMIC_TYPE_FILE);
23092
    }
23093
23094
    return ret;
23095
}
23096
/* load pem cert from file into der buffer, return der size or error */
23097
int wc_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz)
23098
{
23099
    int ret;
23100
    DerBuffer* converted = NULL;
23101
    ret = wc_PemCertToDer_ex(fileName, &converted);
23102
    if (ret == 0) {
23103
        if (converted->length < (word32)derSz) {
23104
            XMEMCPY(derBuf, converted->buffer, converted->length);
23105
            ret = converted->length;
23106
        }
23107
        else
23108
            ret = BUFFER_E;
23109
23110
        FreeDer(&converted);
23111
    }
23112
    return ret;
23113
}
23114
#endif /* WOLFSSL_CERT_GEN */
23115
23116
#if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER)
23117
/* load pem public key from file into der buffer, return der size or error */
23118
int wc_PemPubKeyToDer_ex(const char* fileName, DerBuffer** der)
23119
{
23120
#ifdef WOLFSSL_SMALL_STACK
23121
    byte   staticBuffer[1]; /* force XMALLOC */
23122
#else
23123
    byte   staticBuffer[FILE_BUFFER_SIZE];
23124
#endif
23125
    byte*  fileBuf = staticBuffer;
23126
    int    dynamic = 0;
23127
    int    ret     = 0;
23128
    long   sz      = 0;
23129
    XFILE  file    = NULL;
23130
23131
    WOLFSSL_ENTER("wc_PemPubKeyToDer");
23132
23133
    if (fileName == NULL) {
23134
        ret = BAD_FUNC_ARG;
23135
    }
23136
    else {
23137
        file = XFOPEN(fileName, "rb");
23138
        if (file == XBADFILE) {
23139
            ret = BUFFER_E;
23140
        }
23141
    }
23142
23143
    if (ret == 0) {
23144
        if (XFSEEK(file, 0, XSEEK_END) != 0) {
23145
            ret = BUFFER_E;
23146
        }
23147
        sz = XFTELL(file);
23148
        XREWIND(file);
23149
23150
        if (sz <= 0) {
23151
            ret = BUFFER_E;
23152
        }
23153
        else if (sz > (long)sizeof(staticBuffer)) {
23154
            fileBuf = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
23155
            if (fileBuf == NULL)
23156
                ret = MEMORY_E;
23157
            else
23158
                dynamic = 1;
23159
        }
23160
        if (ret == 0) {
23161
            if ((size_t)XFREAD(fileBuf, 1, sz, file) != (size_t)sz) {
23162
                ret = BUFFER_E;
23163
            }
23164
            else {
23165
                ret = PemToDer(fileBuf, sz, PUBLICKEY_TYPE, der,
23166
                               0, NULL, NULL);
23167
            }
23168
        }
23169
23170
        XFCLOSE(file);
23171
        if (dynamic) {
23172
            XFREE(fileBuf, NULL, DYNAMIC_TYPE_FILE);
23173
        }
23174
    }
23175
23176
    return ret;
23177
}
23178
/* load pem public key from file into der buffer, return der size or error */
23179
int wc_PemPubKeyToDer(const char* fileName,
23180
                           unsigned char* derBuf, int derSz)
23181
{
23182
    int ret;
23183
    DerBuffer* converted = NULL;
23184
    ret = wc_PemPubKeyToDer_ex(fileName, &converted);
23185
    if (ret == 0) {
23186
        if (converted->length < (word32)derSz) {
23187
            XMEMCPY(derBuf, converted->buffer, converted->length);
23188
            ret = converted->length;
23189
        }
23190
        else
23191
            ret = BUFFER_E;
23192
23193
        FreeDer(&converted);
23194
    }
23195
    return ret;
23196
}
23197
#endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */
23198
23199
#endif /* !NO_FILESYSTEM && WOLFSSL_PEM_TO_DER */
23200
23201
/* Get public key in DER format from a populated DecodedCert struct.
23202
 *
23203
 * Users must call wc_InitDecodedCert() and wc_ParseCert() before calling
23204
 * this API. wc_InitDecodedCert() accepts a DER/ASN.1 encoded certificate.
23205
 * To convert a PEM cert to DER first use wc_CertPemToDer() before calling
23206
 * wc_InitDecodedCert().
23207
 *
23208
 * cert   - populated DecodedCert struct holding X.509 certificate
23209
 * derKey - output buffer to place DER/ASN.1 encoded public key
23210
 * derKeySz [IN/OUT] - size of derKey buffer on input, size of public key
23211
 *                     on return. If derKey is passed in as NULL, derKeySz
23212
 *                     will be set to required buffer size for public key
23213
 *                     and LENGTH_ONLY_E will be returned from function.
23214
 * Returns 0 on success, or negative error code on failure. LENGTH_ONLY_E
23215
 * if derKey is NULL and returning length only.
23216
 */
23217
int wc_GetPubKeyDerFromCert(struct DecodedCert* cert,
23218
                            byte* derKey, word32* derKeySz)
23219
0
{
23220
0
    int ret = 0;
23221
23222
    /* derKey may be NULL to return length only */
23223
0
    if (cert == NULL || derKeySz == NULL ||
23224
0
        (derKey != NULL && *derKeySz == 0)) {
23225
0
        return BAD_FUNC_ARG;
23226
0
    }
23227
23228
0
    if (cert->publicKey == NULL) {
23229
0
        WOLFSSL_MSG("DecodedCert does not contain public key\n");
23230
0
        return BAD_FUNC_ARG;
23231
0
    }
23232
23233
    /* if derKey is NULL, return required output buffer size in derKeySz */
23234
0
    if (derKey == NULL) {
23235
0
        *derKeySz = cert->pubKeySize;
23236
0
        ret = LENGTH_ONLY_E;
23237
0
    }
23238
23239
0
    if (ret == 0) {
23240
0
        if (cert->pubKeySize > *derKeySz) {
23241
0
            WOLFSSL_MSG("Output buffer not large enough for public key DER");
23242
0
            ret = BAD_FUNC_ARG;
23243
0
        }
23244
0
        else {
23245
0
            XMEMCPY(derKey, cert->publicKey, cert->pubKeySize);
23246
0
            *derKeySz = cert->pubKeySize;
23247
0
        }
23248
0
    }
23249
23250
0
    return ret;
23251
0
}
23252
23253
#ifdef WOLFSSL_FPKI
23254
/* Search through list for first matching alt name of the same type
23255
 * If 'current' is null then the search starts at the head of the list
23256
 * otherwise the search starts from the node after 'current' alt name.
23257
 * Returns 0 on success
23258
 */
23259
static DNS_entry* FindAltName(struct DecodedCert* cert, int nameType,
23260
    DNS_entry* current)
23261
{
23262
    DNS_entry* entry;
23263
23264
    if (current == NULL) {
23265
        entry = cert->altNames;
23266
    }
23267
    else {
23268
        entry = current->next;
23269
    }
23270
23271
    /* cycle through alt names to check for needed types */
23272
    while (entry != NULL) {
23273
        if (entry->type == nameType) {
23274
            break;
23275
        }
23276
        entry = entry->next;
23277
    }
23278
23279
    return entry;
23280
}
23281
23282
23283
/* returns 0 on success */
23284
int wc_GetUUIDFromCert(struct DecodedCert* cert, byte* uuid, word32* uuidSz)
23285
{
23286
    int ret = ALT_NAME_E;
23287
    DNS_entry* id = NULL;
23288
23289
    do {
23290
        id = FindAltName(cert, ASN_URI_TYPE, id);
23291
        if (id != NULL) {
23292
            /* check if URI string matches expected format for UUID */
23293
            if (id->len != DEFAULT_UUID_SZ) {
23294
                continue; /* size not right not a UUID URI */
23295
            }
23296
23297
            if (XMEMCMP(id->name, "urn:uuid:", 9) != 0) {
23298
                continue; /* beginning text not right for a UUID URI */
23299
            }
23300
23301
            if (uuid == NULL) {
23302
                *uuidSz = id->len;
23303
                return LENGTH_ONLY_E;
23304
            }
23305
23306
            if ((int)*uuidSz < id->len) {
23307
                return BUFFER_E;
23308
            }
23309
23310
            XMEMCPY(uuid, id->name, id->len);
23311
            ret = 0; /* success */
23312
            break;
23313
        }
23314
    } while (id != NULL);
23315
23316
    return ret;
23317
}
23318
23319
23320
/* reutrns 0 on success */
23321
int wc_GetFASCNFromCert(struct DecodedCert* cert, byte* fascn, word32* fascnSz)
23322
{
23323
    int ret = ALT_NAME_E;
23324
    DNS_entry* id = NULL;
23325
23326
    do {
23327
        id = FindAltName(cert, ASN_OTHER_TYPE, id);
23328
        if (id != NULL && id->oidSum == FASCN_OID) {
23329
            if (fascn == NULL) {
23330
                *fascnSz = id->len;
23331
                return LENGTH_ONLY_E;
23332
            }
23333
23334
            if ((int)*fascnSz < id->len) {
23335
                return BUFFER_E;
23336
            }
23337
23338
            XMEMCPY(fascn, id->name, id->len);
23339
            ret = 0; /* success */
23340
        }
23341
    } while (id != NULL);
23342
23343
    return ret;
23344
}
23345
#endif /* WOLFSSL_FPKI */
23346
23347
#if !defined(NO_RSA) && (defined(WOLFSSL_CERT_GEN) || \
23348
    defined(WOLFSSL_KCAPI_RSA) || \
23349
    ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(HAVE_USER_RSA)))
23350
/* USER RSA ifdef portions used instead of refactor in consideration for
23351
   possible fips build */
23352
/* Encode a public RSA key to output.
23353
 *
23354
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
23355
 * PKCS #1: RFC 8017, A.1.1 - RSAPublicKey
23356
 *
23357
 * Encoded data can either be SubjectPublicKeyInfo (with header) or just the key
23358
 * (RSAPublicKey).
23359
 *
23360
 * @param [out] output       Buffer to put encoded data in.
23361
 * @param [in]  key          RSA key object.
23362
 * @param [in]  outLen       Size of the output buffer in bytes.
23363
 * @param [in]  with_header  Whether to include SubjectPublicKeyInfo around key.
23364
 * @return  Size of encoded data in bytes on success.
23365
 * @return  BAD_FUNC_ARG when output or key is NULL, or outLen is less than
23366
 *          minimum length (5 bytes).
23367
 * @return  MEMORY_E when dynamic memory allocation failed.
23368
 */
23369
static int SetRsaPublicKey(byte* output, RsaKey* key, int outLen,
23370
                           int with_header)
23371
0
{
23372
0
#ifndef WOLFSSL_ASN_TEMPLATE
23373
0
    int  idx, nSz, eSz, seqSz, headSz = 0, bitStringSz = 0, algoSz = 0;
23374
0
    byte seq[MAX_SEQ_SZ];
23375
0
    byte headSeq[MAX_SEQ_SZ];
23376
0
    byte bitString[1 + MAX_LENGTH_SZ + 1];
23377
0
    byte algo[MAX_ALGO_SZ]; /* 20 bytes */
23378
23379
0
    if (key == NULL) {
23380
0
        return BAD_FUNC_ARG;
23381
0
    }
23382
23383
#ifdef HAVE_USER_RSA
23384
    nSz = SetASNIntRSA(key->n, NULL);
23385
#else
23386
0
    nSz = SetASNIntMP(&key->n, MAX_RSA_INT_SZ, NULL);
23387
0
#endif
23388
0
    if (nSz < 0)
23389
0
        return nSz;
23390
23391
#ifdef HAVE_USER_RSA
23392
    eSz = SetASNIntRSA(key->e, NULL);
23393
#else
23394
0
    eSz = SetASNIntMP(&key->e, MAX_RSA_INT_SZ, NULL);
23395
0
#endif
23396
0
    if (eSz < 0)
23397
0
        return eSz;
23398
0
    seqSz = SetSequence(nSz + eSz, seq);
23399
23400
    /* headers */
23401
0
    if (with_header) {
23402
0
        algoSz = SetAlgoID(RSAk, algo, oidKeyType, 0);
23403
0
        bitStringSz = SetBitString(seqSz + nSz + eSz, 0, bitString);
23404
0
        headSz = SetSequence(nSz + eSz + seqSz + bitStringSz + algoSz, headSeq);
23405
0
    }
23406
23407
    /* if getting length only */
23408
0
    if (output == NULL) {
23409
0
        return headSz + algoSz + bitStringSz + seqSz + nSz + eSz;
23410
0
    }
23411
23412
    /* check output size */
23413
0
    if ((headSz + algoSz + bitStringSz + seqSz + nSz + eSz) > outLen) {
23414
0
        return BUFFER_E;
23415
0
    }
23416
23417
    /* write output */
23418
0
    idx = 0;
23419
0
    if (with_header) {
23420
        /* header size */
23421
0
        XMEMCPY(output + idx, headSeq, headSz);
23422
0
        idx += headSz;
23423
        /* algo */
23424
0
        XMEMCPY(output + idx, algo, algoSz);
23425
0
        idx += algoSz;
23426
        /* bit string */
23427
0
        XMEMCPY(output + idx, bitString, bitStringSz);
23428
0
        idx += bitStringSz;
23429
0
    }
23430
23431
    /* seq */
23432
0
    XMEMCPY(output + idx, seq, seqSz);
23433
0
    idx += seqSz;
23434
    /* n */
23435
#ifdef HAVE_USER_RSA
23436
    nSz = SetASNIntRSA(key->n, output + idx);
23437
#else
23438
0
    nSz = SetASNIntMP(&key->n, nSz, output + idx);
23439
0
#endif
23440
0
    idx += nSz;
23441
    /* e */
23442
#ifdef HAVE_USER_RSA
23443
    eSz = SetASNIntRSA(key->e, output + idx);
23444
#else
23445
0
    eSz = SetASNIntMP(&key->e, eSz, output + idx);
23446
0
#endif
23447
0
    idx += eSz;
23448
23449
0
    return idx;
23450
#else
23451
    DECL_ASNSETDATA(dataASN, rsaPublicKeyASN_Length);
23452
    int sz = 0;
23453
    int ret = 0;
23454
    int o = 0;
23455
23456
    /* Check parameter validity. */
23457
    if ((key == NULL) || ((output != NULL) && (outLen < MAX_SEQ_SZ))) {
23458
        ret = BAD_FUNC_ARG;
23459
    }
23460
23461
    CALLOC_ASNSETDATA(dataASN, rsaPublicKeyASN_Length, ret, key->heap);
23462
23463
    if (ret == 0) {
23464
        if (!with_header) {
23465
            /* Start encoding with items after header. */
23466
            o = RSAPUBLICKEYASN_IDX_PUBKEY_RSA_SEQ;
23467
        }
23468
        /* Set OID for RSA key. */
23469
        SetASN_OID(&dataASN[RSAPUBLICKEYASN_IDX_ALGOID_OID], RSAk, oidKeyType);
23470
    #ifdef WC_RSA_PSS
23471
        dataASN[RSAPUBLICKEYASN_IDX_ALGOID_P_SEQ].noOut = 1;
23472
    #endif
23473
        /* Set public key mp_ints. */
23474
    #ifdef HAVE_USER_RSA
23475
        SetASN_MP(&dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_N], key->n);
23476
        SetASN_MP(&dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_E], key->e);
23477
    #else
23478
        SetASN_MP(&dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_N], &key->n);
23479
        SetASN_MP(&dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_E], &key->e);
23480
    #endif
23481
        /* Calculate size of RSA public key. */
23482
        ret = SizeASN_Items(rsaPublicKeyASN + o, dataASN + o,
23483
                            rsaPublicKeyASN_Length - o, &sz);
23484
    }
23485
    /* Check output buffer is big enough for encoding. */
23486
    if ((ret == 0) && (output != NULL) && (sz > outLen)) {
23487
        ret = BUFFER_E;
23488
    }
23489
    if ((ret == 0) && (output != NULL)) {
23490
        /* Encode RSA public key. */
23491
        SetASN_Items(rsaPublicKeyASN + o, dataASN + o,
23492
                     rsaPublicKeyASN_Length - o, output);
23493
    }
23494
    if (ret == 0) {
23495
        /* Return size of encoding. */
23496
        ret = sz;
23497
    }
23498
23499
    FREE_ASNSETDATA(dataASN, key->heap);
23500
    return ret;
23501
#endif /* WOLFSSL_ASN_TEMPLATE */
23502
0
}
23503
23504
/* Calculate size of encoded public RSA key in bytes.
23505
 *
23506
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
23507
 * PKCS #1: RFC 8017, A.1.1 - RSAPublicKey
23508
 *
23509
 * Encoded data can either be SubjectPublicKeyInfo (with header) or just the key
23510
 * (RSAPublicKey).
23511
 *
23512
 * @param [in]  key          RSA key object.
23513
 * @param [in]  with_header  Whether to include SubjectPublicKeyInfo around key.
23514
 * @return  Size of encoded data in bytes on success.
23515
 * @return  BAD_FUNC_ARG when key is NULL.
23516
 * @return  MEMORY_E when dynamic memory allocation failed.
23517
 */
23518
int wc_RsaPublicKeyDerSize(RsaKey* key, int with_header)
23519
0
{
23520
0
    return SetRsaPublicKey(NULL, key, 0, with_header);
23521
0
}
23522
23523
/* Encode public RSA key in DER format.
23524
 *
23525
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
23526
 * PKCS #1: RFC 8017, A.1.1 - RSAPublicKey
23527
 *
23528
 * @param [in]  key     RSA key object.
23529
 * @param [out] output  Buffer to put encoded data in.
23530
 * @param [in]  inLen   Size of buffer in bytes.
23531
 * @return  Size of encoded data in bytes on success.
23532
 * @return  BAD_FUNC_ARG when key or output is NULL.
23533
 * @return  MEMORY_E when dynamic memory allocation failed.
23534
 */
23535
int wc_RsaKeyToPublicDer(RsaKey* key, byte* output, word32 inLen)
23536
0
{
23537
0
    return SetRsaPublicKey(output, key, inLen, 1);
23538
0
}
23539
23540
/* Returns public DER version of the RSA key. If with_header is 0 then only a
23541
 * seq + n + e is returned in ASN.1 DER format */
23542
int wc_RsaKeyToPublicDer_ex(RsaKey* key, byte* output, word32 inLen,
23543
    int with_header)
23544
0
{
23545
0
    return SetRsaPublicKey(output, key, inLen, with_header);
23546
0
}
23547
23548
#endif /* !NO_RSA && (WOLFSSL_CERT_GEN || WOLFSSL_KCAPI_RSA ||
23549
            ((OPENSSL_EXTRA || WOLFSSL_KEY_GEN) && !HAVE_USER_RSA))) */
23550
23551
#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || \
23552
     defined(WOLFSSL_KCAPI_RSA)) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
23553
23554
/* Encode private RSA key in DER format.
23555
 *
23556
 * PKCS #1: RFC 8017, A.1.2 - RSAPrivateKey
23557
 *
23558
 * @param [in]  key     RSA key object.
23559
 * @param [out] output  Buffer to put encoded data in.
23560
 * @param [in]  inLen   Size of buffer in bytes.
23561
 * @return  Size of encoded data in bytes on success.
23562
 * @return  BAD_FUNC_ARG when key is NULL or not a private key.
23563
 * @return  MEMORY_E when dynamic memory allocation failed.
23564
 */
23565
int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)
23566
0
{
23567
0
#ifndef WOLFSSL_ASN_TEMPLATE
23568
0
    int ret = 0, i, j, outLen = 0, mpSz;
23569
0
    word32 seqSz = 0, verSz = 0, rawLen, intTotalLen = 0;
23570
0
    word32 sizes[RSA_INTS];
23571
0
    byte  seq[MAX_SEQ_SZ];
23572
0
    byte  ver[MAX_VERSION_SZ];
23573
0
    byte* tmps[RSA_INTS];
23574
23575
0
    if (key == NULL)
23576
0
        return BAD_FUNC_ARG;
23577
23578
0
    if (key->type != RSA_PRIVATE)
23579
0
        return BAD_FUNC_ARG;
23580
23581
0
    for (i = 0; i < RSA_INTS; i++)
23582
0
        tmps[i] = NULL;
23583
23584
    /* write all big ints from key to DER tmps */
23585
0
    for (i = 0; i < RSA_INTS; i++) {
23586
0
        mp_int* keyInt = GetRsaInt(key, (byte)i);
23587
23588
0
        rawLen = mp_unsigned_bin_size(keyInt) + 1;
23589
0
        if (output != NULL) {
23590
0
            tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
23591
0
                                 DYNAMIC_TYPE_RSA);
23592
0
            if (tmps[i] == NULL) {
23593
0
                ret = MEMORY_E;
23594
0
                break;
23595
0
            }
23596
0
        }
23597
23598
0
        mpSz = SetASNIntMP(keyInt, MAX_RSA_INT_SZ, tmps[i]);
23599
0
        if (mpSz < 0) {
23600
0
            ret = mpSz;
23601
0
            break;
23602
0
        }
23603
0
        intTotalLen += (sizes[i] = mpSz);
23604
0
    }
23605
23606
0
    if (ret == 0) {
23607
        /* make headers */
23608
0
        verSz = SetMyVersion(0, ver, FALSE);
23609
0
        seqSz = SetSequence(verSz + intTotalLen, seq);
23610
23611
0
        outLen = seqSz + verSz + intTotalLen;
23612
0
        if (output != NULL && outLen > (int)inLen)
23613
0
            ret = BUFFER_E;
23614
0
    }
23615
0
    if (ret == 0 && output != NULL) {
23616
        /* write to output */
23617
0
        XMEMCPY(output, seq, seqSz);
23618
0
        j = seqSz;
23619
0
        XMEMCPY(output + j, ver, verSz);
23620
0
        j += verSz;
23621
23622
0
        for (i = 0; i < RSA_INTS; i++) {
23623
0
            XMEMCPY(output + j, tmps[i], sizes[i]);
23624
0
            j += sizes[i];
23625
0
        }
23626
0
    }
23627
23628
0
    for (i = 0; i < RSA_INTS; i++) {
23629
0
        if (tmps[i])
23630
0
            XFREE(tmps[i], key->heap, DYNAMIC_TYPE_RSA);
23631
0
    }
23632
23633
0
    if (ret == 0)
23634
0
        ret = outLen;
23635
0
    return ret;
23636
#else
23637
    DECL_ASNSETDATA(dataASN, rsaKeyASN_Length);
23638
    int i;
23639
    int sz = 0;
23640
    int ret = 0;
23641
23642
    if ((key == NULL) || (key->type != RSA_PRIVATE)) {
23643
        ret = BAD_FUNC_ARG;
23644
    }
23645
23646
    CALLOC_ASNSETDATA(dataASN, rsaKeyASN_Length, ret, key->heap);
23647
23648
    if (ret == 0) {
23649
        /* Set the version. */
23650
        SetASN_Int8Bit(&dataASN[RSAKEYASN_IDX_VER], 0);
23651
        /* Set all the mp_ints in private key. */
23652
        for (i = 0; i < RSA_INTS; i++) {
23653
            SetASN_MP(&dataASN[(byte)RSAKEYASN_IDX_N + i], GetRsaInt(key, i));
23654
        }
23655
23656
        /* Calculate size of RSA private key encoding. */
23657
        ret = SizeASN_Items(rsaKeyASN, dataASN, rsaKeyASN_Length, &sz);
23658
    }
23659
    /* Check output buffer has enough space for encoding. */
23660
    if ((ret == 0) && (output != NULL) && (sz > (int)inLen)) {
23661
        ret = BAD_FUNC_ARG;
23662
    }
23663
    if ((ret == 0) && (output != NULL)) {
23664
        /* Encode RSA private key. */
23665
        SetASN_Items(rsaKeyASN, dataASN, rsaKeyASN_Length, output);
23666
    }
23667
23668
    if (ret == 0) {
23669
        /* Return size of encoding. */
23670
        ret = sz;
23671
    }
23672
23673
    FREE_ASNSETDATA(dataASN, key->heap);
23674
    return ret;
23675
#endif
23676
0
}
23677
23678
#endif /* (WOLFSSL_KEY_GEN || OPENSSL_EXTRA) && !NO_RSA && !HAVE_USER_RSA */
23679
23680
23681
#ifdef WOLFSSL_CERT_GEN
23682
23683
/* Initialize and Set Certificate defaults:
23684
   version    = 3 (0x2)
23685
   serial     = 0
23686
   sigType    = SHA_WITH_RSA
23687
   issuer     = blank
23688
   daysValid  = 500
23689
   selfSigned = 1 (true) use subject as issuer
23690
   subject    = blank
23691
*/
23692
int wc_InitCert_ex(Cert* cert, void* heap, int devId)
23693
{
23694
#ifdef WOLFSSL_MULTI_ATTRIB
23695
    int i = 0;
23696
#endif
23697
    if (cert == NULL) {
23698
        return BAD_FUNC_ARG;
23699
    }
23700
23701
    XMEMSET(cert, 0, sizeof(Cert));
23702
23703
    cert->version    = 2;   /* version 3 is hex 2 */
23704
#ifndef NO_SHA
23705
    cert->sigType    = CTC_SHAwRSA;
23706
#elif !defined(NO_SHA256)
23707
    cert->sigType    = CTC_SHA256wRSA;
23708
#else
23709
    cert->sigType    = 0;
23710
#endif
23711
    cert->daysValid  = 500;
23712
    cert->selfSigned = 1;
23713
    cert->keyType    = RSA_KEY;
23714
23715
    cert->issuer.countryEnc = CTC_PRINTABLE;
23716
    cert->issuer.stateEnc = CTC_UTF8;
23717
    cert->issuer.streetEnc = CTC_UTF8;
23718
    cert->issuer.localityEnc = CTC_UTF8;
23719
    cert->issuer.surEnc = CTC_UTF8;
23720
#ifdef WOLFSSL_CERT_NAME_ALL
23721
    cert->issuer.givenNameEnc = CTC_UTF8;
23722
    cert->issuer.initialsEnc = CTC_UTF8;
23723
    cert->issuer.dnQualifierEnc = CTC_UTF8;
23724
    cert->issuer.dnNameEnc = CTC_UTF8;
23725
#endif
23726
    cert->issuer.orgEnc = CTC_UTF8;
23727
    cert->issuer.unitEnc = CTC_UTF8;
23728
    cert->issuer.commonNameEnc = CTC_UTF8;
23729
    cert->issuer.serialDevEnc = CTC_PRINTABLE;
23730
    cert->issuer.userIdEnc = CTC_UTF8;
23731
    cert->issuer.postalCodeEnc = CTC_UTF8;
23732
#ifdef WOLFSSL_CERT_EXT
23733
    cert->issuer.busCatEnc = CTC_UTF8;
23734
    cert->issuer.joiCEnc = CTC_UTF8;
23735
    cert->issuer.joiStEnc = CTC_UTF8;
23736
#endif
23737
23738
    cert->subject.countryEnc = CTC_PRINTABLE;
23739
    cert->subject.stateEnc = CTC_UTF8;
23740
    cert->subject.streetEnc = CTC_UTF8;
23741
    cert->subject.localityEnc = CTC_UTF8;
23742
    cert->subject.surEnc = CTC_UTF8;
23743
#ifdef WOLFSSL_CERT_NAME_ALL
23744
    cert->subject.givenNameEnc = CTC_UTF8;
23745
    cert->subject.initialsEnc = CTC_UTF8;
23746
    cert->subject.dnQualifierEnc = CTC_UTF8;
23747
    cert->subject.dnNameEnc = CTC_UTF8;
23748
#endif
23749
    cert->subject.orgEnc = CTC_UTF8;
23750
    cert->subject.unitEnc = CTC_UTF8;
23751
    cert->subject.commonNameEnc = CTC_UTF8;
23752
    cert->subject.serialDevEnc = CTC_PRINTABLE;
23753
    cert->subject.userIdEnc = CTC_UTF8;
23754
    cert->subject.postalCodeEnc = CTC_UTF8;
23755
#ifdef WOLFSSL_CERT_EXT
23756
    cert->subject.busCatEnc = CTC_UTF8;
23757
    cert->subject.joiCEnc = CTC_UTF8;
23758
    cert->subject.joiStEnc = CTC_UTF8;
23759
#endif
23760
23761
#ifdef WOLFSSL_MULTI_ATTRIB
23762
    for (i = 0; i < CTC_MAX_ATTRIB; i++) {
23763
        cert->issuer.name[i].type   = CTC_UTF8;
23764
        cert->subject.name[i].type  = CTC_UTF8;
23765
    }
23766
#endif /* WOLFSSL_MULTI_ATTRIB */
23767
23768
    cert->heap = heap;
23769
    (void)devId; /* future */
23770
23771
    return 0;
23772
}
23773
23774
WOLFSSL_ABI
23775
int wc_InitCert(Cert* cert)
23776
{
23777
    return wc_InitCert_ex(cert, NULL, INVALID_DEVID);
23778
}
23779
23780
WOLFSSL_ABI
23781
Cert* wc_CertNew(void* heap)
23782
{
23783
    Cert* certNew;
23784
23785
    certNew = (Cert*)XMALLOC(sizeof(Cert), heap, DYNAMIC_TYPE_CERT);
23786
23787
    if (certNew) {
23788
        if (wc_InitCert_ex(certNew, heap, INVALID_DEVID) != 0) {
23789
            XFREE(certNew, heap, DYNAMIC_TYPE_CERT);
23790
            certNew = NULL;
23791
        }
23792
    }
23793
23794
    return certNew;
23795
}
23796
23797
WOLFSSL_ABI
23798
void  wc_CertFree(Cert* cert)
23799
{
23800
    if (cert) {
23801
         void* heap = cert->heap;
23802
23803
         ForceZero(cert, sizeof(Cert));
23804
         XFREE(cert, heap, DYNAMIC_TYPE_CERT);
23805
         (void)heap;
23806
     }
23807
}
23808
23809
/* DER encoded x509 Certificate */
23810
typedef struct DerCert {
23811
    byte size[MAX_LENGTH_SZ];          /* length encoded */
23812
    byte version[MAX_VERSION_SZ];      /* version encoded */
23813
    byte serial[(int)CTC_SERIAL_SIZE + (int)MAX_LENGTH_SZ]; /* serial number encoded */
23814
    byte sigAlgo[MAX_ALGO_SZ];         /* signature algo encoded */
23815
    byte issuer[WC_ASN_NAME_MAX];         /* issuer  encoded */
23816
    byte subject[WC_ASN_NAME_MAX];        /* subject encoded */
23817
    byte validity[MAX_DATE_SIZE*2 + MAX_SEQ_SZ*2];  /* before and after dates */
23818
    byte publicKey[MAX_PUBLIC_KEY_SZ]; /* rsa public key encoded */
23819
    byte ca[MAX_CA_SZ];                /* basic constraint CA true size */
23820
    byte extensions[MAX_EXTENSIONS_SZ]; /* all extensions */
23821
#ifdef WOLFSSL_CERT_EXT
23822
    byte skid[MAX_KID_SZ];             /* Subject Key Identifier extension */
23823
    byte akid[MAX_KID_SZ
23824
#ifdef WOLFSSL_AKID_NAME
23825
              + sizeof(CertName) + CTC_SERIAL_SIZE
23826
#endif
23827
              ]; /* Authority Key Identifier extension */
23828
    byte keyUsage[MAX_KEYUSAGE_SZ];    /* Key Usage extension */
23829
    byte extKeyUsage[MAX_EXTKEYUSAGE_SZ]; /* Extended Key Usage extension */
23830
#ifndef IGNORE_NETSCAPE_CERT_TYPE
23831
    byte nsCertType[MAX_NSCERTTYPE_SZ]; /* Extended Key Usage extension */
23832
#endif
23833
    byte certPolicies[MAX_CERTPOL_NB*MAX_CERTPOL_SZ]; /* Certificate Policies */
23834
    byte crlInfo[CTC_MAX_CRLINFO_SZ];  /* CRL Distribution Points */
23835
#endif
23836
#ifdef WOLFSSL_CERT_REQ
23837
    byte attrib[MAX_ATTRIB_SZ];        /* Cert req attributes encoded */
23838
    #ifdef WOLFSSL_CUSTOM_OID
23839
    byte extCustom[MAX_ATTRIB_SZ];     /* Encoded user oid and value */
23840
    #endif
23841
#endif
23842
#ifdef WOLFSSL_ALT_NAMES
23843
    byte altNames[CTC_MAX_ALT_SIZE];   /* Alternative Names encoded */
23844
#endif
23845
    int  sizeSz;                       /* encoded size length */
23846
    int  versionSz;                    /* encoded version length */
23847
    int  serialSz;                     /* encoded serial length */
23848
    int  sigAlgoSz;                    /* encoded sig algo length */
23849
    int  issuerSz;                     /* encoded issuer length */
23850
    int  subjectSz;                    /* encoded subject length */
23851
    int  validitySz;                   /* encoded validity length */
23852
    int  publicKeySz;                  /* encoded public key length */
23853
    int  caSz;                         /* encoded CA extension length */
23854
#ifdef WOLFSSL_CERT_EXT
23855
    int  skidSz;                       /* encoded SKID extension length */
23856
    int  akidSz;                       /* encoded SKID extension length */
23857
    int  keyUsageSz;                   /* encoded KeyUsage extension length */
23858
    int  extKeyUsageSz;                /* encoded ExtendedKeyUsage extension length */
23859
#ifndef IGNORE_NETSCAPE_CERT_TYPE
23860
    int  nsCertTypeSz;                 /* encoded Netscape Certifcate Type
23861
                                        * extension length */
23862
#endif
23863
    int  certPoliciesSz;               /* encoded CertPolicies extension length*/
23864
    int  crlInfoSz;                    /* encoded CRL Dist Points length */
23865
#endif
23866
#ifdef WOLFSSL_ALT_NAMES
23867
    int  altNamesSz;                   /* encoded AltNames extension length */
23868
#endif
23869
    int  extensionsSz;                 /* encoded extensions total length */
23870
    int  total;                        /* total encoded lengths */
23871
#ifdef WOLFSSL_CERT_REQ
23872
    int  attribSz;
23873
    #ifdef WOLFSSL_CUSTOM_OID
23874
    int  extCustomSz;
23875
    #endif
23876
#endif
23877
} DerCert;
23878
23879
23880
#ifdef WOLFSSL_CERT_REQ
23881
#ifndef WOLFSSL_ASN_TEMPLATE
23882
23883
/* Write a set header to output */
23884
static word32 SetPrintableString(word32 len, byte* output)
23885
{
23886
    output[0] = ASN_PRINTABLE_STRING;
23887
    return SetLength(len, output + 1) + 1;
23888
}
23889
23890
static word32 SetUTF8String(word32 len, byte* output)
23891
{
23892
    output[0] = ASN_UTF8STRING;
23893
    return SetLength(len, output + 1) + 1;
23894
}
23895
23896
#endif
23897
#endif /* WOLFSSL_CERT_REQ */
23898
23899
23900
#ifndef WOLFSSL_CERT_GEN_CACHE
23901
/* wc_SetCert_Free is only public when WOLFSSL_CERT_GEN_CACHE is not defined */
23902
static
23903
#endif
23904
WOLFSSL_ABI
23905
void wc_SetCert_Free(Cert* cert)
23906
{
23907
    if (cert != NULL) {
23908
        cert->der = NULL;
23909
        if (cert->decodedCert) {
23910
            FreeDecodedCert((DecodedCert*)cert->decodedCert);
23911
23912
            XFREE(cert->decodedCert, cert->heap, DYNAMIC_TYPE_DCERT);
23913
            cert->decodedCert = NULL;
23914
        }
23915
    }
23916
}
23917
23918
static int wc_SetCert_LoadDer(Cert* cert, const byte* der, word32 derSz)
23919
{
23920
    int ret;
23921
23922
    if (cert == NULL) {
23923
        ret = BAD_FUNC_ARG;
23924
    }
23925
    else {
23926
        /* Allocate DecodedCert struct and Zero */
23927
        cert->decodedCert = (void*)XMALLOC(sizeof(DecodedCert), cert->heap,
23928
            DYNAMIC_TYPE_DCERT);
23929
23930
        if (cert->decodedCert == NULL) {
23931
            ret = MEMORY_E;
23932
        }
23933
        else {
23934
            XMEMSET(cert->decodedCert, 0, sizeof(DecodedCert));
23935
23936
            InitDecodedCert((DecodedCert*)cert->decodedCert, der, derSz,
23937
                    cert->heap);
23938
            ret = ParseCertRelative((DecodedCert*)cert->decodedCert,
23939
                    CERT_TYPE, 0, NULL);
23940
            if (ret >= 0) {
23941
                cert->der = (byte*)der;
23942
            }
23943
            else {
23944
                wc_SetCert_Free(cert);
23945
            }
23946
        }
23947
    }
23948
23949
    return ret;
23950
}
23951
23952
#endif /* WOLFSSL_CERT_GEN */
23953
23954
#ifdef HAVE_ECC
23955
#ifdef WOLFSSL_ASN_TEMPLATE
23956
/* ASN.1 template for ECC public key (SubjectPublicKeyInfo).
23957
 * RFC 5480, 2 - Subject Public Key Information Fields
23958
 *           2.1.1 - Unrestricted Algorithm Identifier and Parameters
23959
 * X9.62 ECC point format.
23960
 * See ASN.1 template 'eccSpecifiedASN' for specifiedCurve.
23961
 */
23962
static const ASNItem eccPublicKeyASN[] = {
23963
/* SEQ            */ { 0, ASN_SEQUENCE, 1, 1, 0 },
23964
                                             /* AlgorithmIdentifier */
23965
/* ALGOID_SEQ     */     { 1, ASN_SEQUENCE, 1, 1, 0 },
23966
                                                 /* algorithm */
23967
/* ALGOID_OID     */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
23968
                                                 /* namedCurve */
23969
/* ALGOID_CURVEID */         { 2, ASN_OBJECT_ID, 0, 0, 2 },
23970
                                                 /* specifiedCurve - explicit parameters */
23971
/* ALGOID_PARAMS  */         { 2, ASN_SEQUENCE, 1, 0, 2 },
23972
                                             /* Public Key */
23973
/* PUBKEY         */     { 1, ASN_BIT_STRING, 0, 0, 0 },
23974
};
23975
enum {
23976
    ECCPUBLICKEYASN_IDX_SEQ = 0,
23977
    ECCPUBLICKEYASN_IDX_ALGOID_SEQ,
23978
    ECCPUBLICKEYASN_IDX_ALGOID_OID,
23979
    ECCPUBLICKEYASN_IDX_ALGOID_CURVEID,
23980
    ECCPUBLICKEYASN_IDX_ALGOID_PARAMS,
23981
    ECCPUBLICKEYASN_IDX_PUBKEY,
23982
};
23983
23984
/* Number of items in ASN.1 template for ECC public key. */
23985
#define eccPublicKeyASN_Length (sizeof(eccPublicKeyASN) / sizeof(ASNItem))
23986
#endif /* WOLFSSL_ASN_TEMPLATE */
23987
#endif /* HAVE_ECC */
23988
23989
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
23990
23991
/* Encode public ECC key in DER format.
23992
 *
23993
 * RFC 5480, 2 - Subject Public Key Information Fields
23994
 *           2.1.1 - Unrestricted Algorithm Identifier and Parameters
23995
 * X9.62 ECC point format.
23996
 * SEC 1 Ver. 2.0, C.2 - Syntax for Elliptic Curve Domain Parameters
23997
 *
23998
 * @param [out] output       Buffer to put encoded data in.
23999
 * @param [in]  key          ECC key object.
24000
 * @param [in]  outLen       Size of buffer in bytes.
24001
 * @param [in]  with_header  Whether to use SubjectPublicKeyInfo format.
24002
 * @return  Size of encoded data in bytes on success.
24003
 * @return  BAD_FUNC_ARG when key or key's parameters is NULL.
24004
 * @return  MEMORY_E when dynamic memory allocation failed.
24005
 */
24006
static int SetEccPublicKey(byte* output, ecc_key* key, int outLen,
24007
                           int with_header, int comp)
24008
0
{
24009
0
#ifndef WOLFSSL_ASN_TEMPLATE
24010
0
    int ret, idx = 0, algoSz, curveSz, bitStringSz;
24011
0
    word32 pubSz;
24012
0
    byte bitString[1 + MAX_LENGTH_SZ + 1]; /* 6 */
24013
0
    byte algo[MAX_ALGO_SZ];  /* 20 */
24014
24015
    /* public size */
24016
0
    pubSz = key->dp ? key->dp->size : MAX_ECC_BYTES;
24017
0
    if (comp)
24018
0
        pubSz = 1 + pubSz;
24019
0
    else
24020
0
        pubSz = 1 + 2 * pubSz;
24021
24022
    /* check for buffer overflow */
24023
0
    if (output != NULL && pubSz > (word32)outLen) {
24024
0
        return BUFFER_E;
24025
0
    }
24026
24027
    /* headers */
24028
0
    if (with_header) {
24029
0
        curveSz = SetCurve(key, NULL, 0);
24030
0
        if (curveSz <= 0) {
24031
0
            return curveSz;
24032
0
        }
24033
24034
        /* calculate size */
24035
0
        algoSz  = SetAlgoID(ECDSAk, algo, oidKeyType, curveSz);
24036
0
        bitStringSz = SetBitString(pubSz, 0, bitString);
24037
0
        idx = SetSequence(pubSz + curveSz + bitStringSz + algoSz, NULL);
24038
24039
        /* check for buffer overflow */
24040
0
        if (output != NULL &&
24041
0
                curveSz + algoSz + bitStringSz + idx + pubSz > (word32)outLen) {
24042
0
            return BUFFER_E;
24043
0
        }
24044
24045
0
        idx = SetSequence(pubSz + curveSz + bitStringSz + algoSz, output);
24046
        /* algo */
24047
0
        if (output)
24048
0
            XMEMCPY(output + idx, algo, algoSz);
24049
0
        idx += algoSz;
24050
        /* curve */
24051
0
        if (output)
24052
0
            (void)SetCurve(key, output + idx, curveSz);
24053
0
        idx += curveSz;
24054
        /* bit string */
24055
0
        if (output)
24056
0
            XMEMCPY(output + idx, bitString, bitStringSz);
24057
0
        idx += bitStringSz;
24058
0
    }
24059
24060
    /* pub */
24061
0
    if (output) {
24062
0
        PRIVATE_KEY_UNLOCK();
24063
0
        ret = wc_ecc_export_x963_ex(key, output + idx, &pubSz, comp);
24064
0
        PRIVATE_KEY_LOCK();
24065
0
        if (ret != 0) {
24066
0
            return ret;
24067
0
        }
24068
0
    }
24069
0
    idx += pubSz;
24070
24071
0
    return idx;
24072
#else
24073
    word32 pubSz = 0;
24074
    int sz = 0;
24075
    int ret = 0;
24076
    int curveIdSz = 0;
24077
    byte* curveOid = NULL;
24078
24079
    /* Check key validity. */
24080
    if ((key == NULL) || (key->dp == NULL)) {
24081
        ret = BAD_FUNC_ARG;
24082
    }
24083
24084
    if (ret == 0) {
24085
        /* Calculate the size of the encoded public point. */
24086
        PRIVATE_KEY_UNLOCK();
24087
        ret = wc_ecc_export_x963_ex(key, NULL, &pubSz, comp);
24088
        PRIVATE_KEY_LOCK();
24089
        /* LENGTH_ONLY_E on success. */
24090
        if (ret == LENGTH_ONLY_E) {
24091
            ret = 0;
24092
        }
24093
    }
24094
    if ((ret == 0) && with_header) {
24095
        /* Including SubjectPublicKeyInfo header. */
24096
        DECL_ASNSETDATA(dataASN, eccPublicKeyASN_Length);
24097
24098
        CALLOC_ASNSETDATA(dataASN, eccPublicKeyASN_Length, ret, key->heap);
24099
24100
        /* Get the length of the named curve OID to put into the encoding. */
24101
        curveIdSz = SetCurve(key, NULL, 0);
24102
        if (curveIdSz < 0) {
24103
            ret = curveIdSz;
24104
        }
24105
24106
        if (ret == 0) {
24107
            /* Set the key type OID. */
24108
            SetASN_OID(&dataASN[ECCPUBLICKEYASN_IDX_ALGOID_OID], ECDSAk,
24109
                    oidKeyType);
24110
            /* Set the curve OID. */
24111
            SetASN_ReplaceBuffer(&dataASN[ECCPUBLICKEYASN_IDX_ALGOID_CURVEID],
24112
                NULL, curveIdSz);
24113
            /* Don't try to write out explicit parameters. */
24114
            dataASN[ECCPUBLICKEYASN_IDX_ALGOID_PARAMS].noOut = 1;
24115
            /* Set size of public point to ensure space is made for it. */
24116
            SetASN_Buffer(&dataASN[ECCPUBLICKEYASN_IDX_PUBKEY], NULL, pubSz);
24117
            /* Calculate size of ECC public key. */
24118
            ret = SizeASN_Items(eccPublicKeyASN, dataASN,
24119
                                eccPublicKeyASN_Length, &sz);
24120
        }
24121
24122
        /* Check buffer, if passed in, is big enough for encoded data. */
24123
        if ((ret == 0) && (output != NULL) && (sz > outLen)) {
24124
            ret = BUFFER_E;
24125
        }
24126
        if ((ret == 0) && (output != NULL)) {
24127
            /* Encode ECC public key. */
24128
            SetASN_Items(eccPublicKeyASN, dataASN, eccPublicKeyASN_Length,
24129
                         output);
24130
            /* Skip to where public point is to be encoded. */
24131
            output += sz - pubSz;
24132
            /* Cache the location to place the name curve OID. */
24133
            curveOid = (byte*)
24134
                dataASN[ECCPUBLICKEYASN_IDX_ALGOID_CURVEID].data.buffer.data;
24135
        }
24136
24137
        FREE_ASNSETDATA(dataASN, key->heap);
24138
    }
24139
    else if ((ret == 0) && (output != NULL) && (pubSz > (word32)outLen)) {
24140
        ret = BUFFER_E;
24141
    }
24142
    else {
24143
        /* Total size is the public point size. */
24144
        sz = pubSz;
24145
    }
24146
24147
    if ((ret == 0) && (output != NULL)) {
24148
        /* Put named curve OID data into encoding. */
24149
        curveIdSz = SetCurve(key, curveOid, curveIdSz);
24150
        if (curveIdSz < 0) {
24151
            ret = curveIdSz;
24152
        }
24153
    }
24154
    if ((ret == 0) && (output != NULL)) {
24155
        /* Encode public point. */
24156
        PRIVATE_KEY_UNLOCK();
24157
        ret = wc_ecc_export_x963_ex(key, output, &pubSz, comp);
24158
        PRIVATE_KEY_LOCK();
24159
    }
24160
    if (ret == 0) {
24161
        /* Return the size of the encoding. */
24162
        ret = sz;
24163
    }
24164
24165
    return ret;
24166
#endif
24167
0
}
24168
24169
24170
/* Encode the public part of an ECC key in a DER.
24171
 *
24172
 * Pass NULL for output to get the size of the encoding.
24173
 *
24174
 * @param [in]  key            ECC key object.
24175
 * @param [out] output         Buffer to hold DER encoding.
24176
 * @param [in]  inLen          Size of buffer in bytes.
24177
 * @param [in]  with_AlgCurve  Whether to use SubjectPublicKeyInfo format.
24178
 * @return  Size of encoded data in bytes on success.
24179
 * @return  BAD_FUNC_ARG when key or key's parameters is NULL.
24180
 * @return  MEMORY_E when dynamic memory allocation failed.
24181
 */
24182
WOLFSSL_ABI
24183
int wc_EccPublicKeyToDer(ecc_key* key, byte* output, word32 inLen,
24184
                                                              int with_AlgCurve)
24185
0
{
24186
0
    return SetEccPublicKey(output, key, inLen, with_AlgCurve, 0);
24187
0
}
24188
24189
int wc_EccPublicKeyToDer_ex(ecc_key* key, byte* output, word32 inLen,
24190
                                                    int with_AlgCurve, int comp)
24191
0
{
24192
0
    return SetEccPublicKey(output, key, inLen, with_AlgCurve, comp);
24193
0
}
24194
24195
int wc_EccPublicKeyDerSize(ecc_key* key, int with_AlgCurve)
24196
0
{
24197
0
    return SetEccPublicKey(NULL, key, 0, with_AlgCurve, 0);
24198
0
}
24199
24200
#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */
24201
24202
#ifdef WOLFSSL_ASN_TEMPLATE
24203
#if defined(WC_ENABLE_ASYM_KEY_EXPORT) || defined(WC_ENABLE_ASYM_KEY_IMPORT)
24204
/* ASN.1 template for Ed25519 and Ed448 public key (SubkectPublicKeyInfo).
24205
 * RFC 8410, 4 - Subject Public Key Fields
24206
 */
24207
static const ASNItem edPubKeyASN[] = {
24208
            /* SubjectPublicKeyInfo */
24209
/* SEQ        */ { 0, ASN_SEQUENCE, 1, 1, 0 },
24210
                                     /* AlgorithmIdentifier */
24211
/* ALGOID_SEQ */     { 1, ASN_SEQUENCE, 1, 1, 0 },
24212
                                         /* Ed25519/Ed448 OID */
24213
/* ALGOID_OID */         { 2, ASN_OBJECT_ID, 0, 0, 1 },
24214
                                     /* Public key stream */
24215
/* PUBKEY     */     { 1, ASN_BIT_STRING, 0, 0, 0 },
24216
};
24217
enum {
24218
    EDPUBKEYASN_IDX_SEQ = 0,
24219
    EDPUBKEYASN_IDX_ALGOID_SEQ,
24220
    EDPUBKEYASN_IDX_ALGOID_OID,
24221
    EDPUBKEYASN_IDX_PUBKEY,
24222
};
24223
24224
/* Number of items in ASN.1 template for Ed25519 and Ed448 public key. */
24225
#define edPubKeyASN_Length (sizeof(edPubKeyASN) / sizeof(ASNItem))
24226
#endif /* WC_ENABLE_ASYM_KEY_EXPORT || WC_ENABLE_ASYM_KEY_IMPORT */
24227
#endif /* WOLFSSL_ASN_TEMPLATE */
24228
24229
#ifdef WC_ENABLE_ASYM_KEY_EXPORT
24230
24231
/* Build ASN.1 formatted public key based on RFC 8410
24232
 *
24233
 * Pass NULL for output to get the size of the encoding.
24234
 *
24235
 * @param [in]  pubKey       public key buffer
24236
 * @param [in]  pubKeyLen    public ket buffer length
24237
 * @param [out] output       Buffer to put encoded data in (optional)
24238
 * @param [in]  outLen       Size of buffer in bytes
24239
 * @param [in]  keyType      is "enum Key_Sum" like ED25519k
24240
 * @param [in]  withHeader   Whether to include SubjectPublicKeyInfo around key.
24241
 * @return  Size of encoded data in bytes on success
24242
 * @return  BAD_FUNC_ARG when key is NULL.
24243
 * @return  MEMORY_E when dynamic memory allocation failed.
24244
 */
24245
int SetAsymKeyDerPublic(const byte* pubKey, word32 pubKeyLen,
24246
    byte* output, word32 outLen, int keyType, int withHeader)
24247
0
{
24248
0
    int ret = 0;
24249
0
#ifndef WOLFSSL_ASN_TEMPLATE
24250
0
    word32 idx = 0;
24251
0
    word32 seqDataSz = 0;
24252
0
    word32 sz;
24253
#else
24254
    int sz = 0;
24255
    DECL_ASNSETDATA(dataASN, edPubKeyASN_Length);
24256
#endif
24257
24258
0
    if (pubKey == NULL) {
24259
0
        return BAD_FUNC_ARG;
24260
0
    }
24261
24262
0
#ifndef WOLFSSL_ASN_TEMPLATE
24263
    /* calculate size */
24264
0
    if (withHeader) {
24265
0
        word32 algoSz      = SetAlgoID(keyType, NULL, oidKeyType, 0);
24266
0
        word32 bitStringSz = SetBitString(pubKeyLen, 0, NULL);
24267
24268
0
        seqDataSz = algoSz + bitStringSz + pubKeyLen;
24269
0
        sz = SetSequence(seqDataSz, NULL) + seqDataSz;
24270
0
    }
24271
0
    else {
24272
0
        sz = pubKeyLen;
24273
0
    }
24274
24275
    /* checkout output size */
24276
0
    if (output != NULL && sz > outLen) {
24277
0
        ret = BUFFER_E;
24278
0
    }
24279
24280
    /* headers */
24281
0
    if (ret == 0 && output != NULL && withHeader) {
24282
        /* sequence */
24283
0
        idx = SetSequence(seqDataSz, output);
24284
        /* algo */
24285
0
        idx += SetAlgoID(keyType, output + idx, oidKeyType, 0);
24286
        /* bit string */
24287
0
        idx += SetBitString(pubKeyLen, 0, output + idx);
24288
0
    }
24289
24290
0
    if (ret == 0 && output != NULL) {
24291
        /* pub */
24292
0
        XMEMCPY(output + idx, pubKey, pubKeyLen);
24293
0
        idx += pubKeyLen;
24294
24295
0
        sz = idx;
24296
0
    }
24297
24298
0
    if (ret == 0) {
24299
0
        ret = sz;
24300
0
    }
24301
#else
24302
    if (withHeader) {
24303
        CALLOC_ASNSETDATA(dataASN, edPubKeyASN_Length, ret, NULL);
24304
24305
        if (ret == 0) {
24306
            /* Set the OID. */
24307
            SetASN_OID(&dataASN[EDPUBKEYASN_IDX_ALGOID_OID], keyType,
24308
                    oidKeyType);
24309
            /* Leave space for public point. */
24310
            SetASN_Buffer(&dataASN[EDPUBKEYASN_IDX_PUBKEY], NULL, pubKeyLen);
24311
            /* Calculate size of public key encoding. */
24312
            ret = SizeASN_Items(edPubKeyASN, dataASN, edPubKeyASN_Length, &sz);
24313
        }
24314
        if ((ret == 0) && (output != NULL) && (sz > (int)outLen)) {
24315
            ret = BUFFER_E;
24316
        }
24317
        if ((ret == 0) && (output != NULL)) {
24318
            /* Encode public key. */
24319
            SetASN_Items(edPubKeyASN, dataASN, edPubKeyASN_Length, output);
24320
            /* Set location to encode public point. */
24321
            output = (byte*)dataASN[EDPUBKEYASN_IDX_PUBKEY].data.buffer.data;
24322
        }
24323
24324
        FREE_ASNSETDATA(dataASN, NULL);
24325
    }
24326
    else if ((output != NULL) && (pubKeyLen > outLen)) {
24327
        ret = BUFFER_E;
24328
    }
24329
    else if (ret == 0) {
24330
        sz = pubKeyLen;
24331
    }
24332
24333
    if ((ret == 0) && (output != NULL)) {
24334
        /* Put public key into space provided. */
24335
        XMEMCPY(output, pubKey, pubKeyLen);
24336
    }
24337
    if (ret == 0) {
24338
        ret = sz;
24339
    }
24340
#endif /* WOLFSSL_ASN_TEMPLATE */
24341
0
    return ret;
24342
0
}
24343
#endif /* WC_ENABLE_ASYM_KEY_EXPORT */
24344
24345
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
24346
/* Encode the public part of an Ed25519 key in DER.
24347
 *
24348
 * Pass NULL for output to get the size of the encoding.
24349
 *
24350
 * @param [in]  key       Ed25519 key object.
24351
 * @param [out] output    Buffer to put encoded data in.
24352
 * @param [in]  outLen    Size of buffer in bytes.
24353
 * @param [in]  withAlg   Whether to use SubjectPublicKeyInfo format.
24354
 * @return  Size of encoded data in bytes on success.
24355
 * @return  BAD_FUNC_ARG when key is NULL.
24356
 * @return  MEMORY_E when dynamic memory allocation failed.
24357
 */
24358
int wc_Ed25519PublicKeyToDer(ed25519_key* key, byte* output, word32 inLen,
24359
                             int withAlg)
24360
0
{
24361
0
    int    ret;
24362
0
    byte   pubKey[ED25519_PUB_KEY_SIZE];
24363
0
    word32 pubKeyLen = (word32)sizeof(pubKey);
24364
24365
0
    if (key == NULL) {
24366
0
        return BAD_FUNC_ARG;
24367
0
    }
24368
24369
0
    ret = wc_ed25519_export_public(key, pubKey, &pubKeyLen);
24370
0
    if (ret == 0) {
24371
0
        ret = SetAsymKeyDerPublic(pubKey, pubKeyLen, output, inLen,
24372
0
            ED25519k, withAlg);
24373
0
    }
24374
0
    return ret;
24375
0
}
24376
#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_EXPORT */
24377
24378
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
24379
/* Encode the public part of an Ed448 key in DER.
24380
 *
24381
 * Pass NULL for output to get the size of the encoding.
24382
 *
24383
 * @param [in]  key       Ed448 key object.
24384
 * @param [out] output    Buffer to put encoded data in.
24385
 * @param [in]  outLen    Size of buffer in bytes.
24386
 * @param [in]  withAlg   Whether to use SubjectPublicKeyInfo format.
24387
 * @return  Size of encoded data in bytes on success.
24388
 * @return  BAD_FUNC_ARG when key is NULL.
24389
 * @return  MEMORY_E when dynamic memory allocation failed.
24390
 */
24391
int wc_Ed448PublicKeyToDer(ed448_key* key, byte* output, word32 inLen,
24392
                           int withAlg)
24393
0
{
24394
0
    int    ret;
24395
0
    byte   pubKey[ED448_PUB_KEY_SIZE];
24396
0
    word32 pubKeyLen = (word32)sizeof(pubKey);
24397
24398
0
    if (key == NULL) {
24399
0
        return BAD_FUNC_ARG;
24400
0
    }
24401
24402
0
    ret = wc_ed448_export_public(key, pubKey, &pubKeyLen);
24403
0
    if (ret == 0) {
24404
0
        ret = SetAsymKeyDerPublic(pubKey, pubKeyLen, output, inLen,
24405
0
            ED448k, withAlg);
24406
0
    }
24407
0
    return ret;
24408
0
}
24409
#endif /* HAVE_ED448 && HAVE_ED448_KEY_EXPORT */
24410
#ifdef WOLFSSL_CERT_GEN
24411
24412
#ifndef NO_ASN_TIME
24413
static WC_INLINE byte itob(int number)
24414
{
24415
    return (byte)number + 0x30;
24416
}
24417
24418
24419
/* write time to output, format */
24420
static void SetTime(struct tm* date, byte* output)
24421
{
24422
    int i = 0;
24423
24424
    output[i++] = itob((date->tm_year % 10000) / 1000);
24425
    output[i++] = itob((date->tm_year % 1000)  /  100);
24426
    output[i++] = itob((date->tm_year % 100)   /   10);
24427
    output[i++] = itob( date->tm_year % 10);
24428
24429
    output[i++] = itob(date->tm_mon / 10);
24430
    output[i++] = itob(date->tm_mon % 10);
24431
24432
    output[i++] = itob(date->tm_mday / 10);
24433
    output[i++] = itob(date->tm_mday % 10);
24434
24435
    output[i++] = itob(date->tm_hour / 10);
24436
    output[i++] = itob(date->tm_hour % 10);
24437
24438
    output[i++] = itob(date->tm_min / 10);
24439
    output[i++] = itob(date->tm_min % 10);
24440
24441
    output[i++] = itob(date->tm_sec / 10);
24442
    output[i++] = itob(date->tm_sec % 10);
24443
24444
    output[i] = 'Z';  /* Zulu profile */
24445
}
24446
#endif
24447
24448
#ifndef WOLFSSL_ASN_TEMPLATE
24449
24450
/* Copy Dates from cert, return bytes written */
24451
static int CopyValidity(byte* output, Cert* cert)
24452
{
24453
    int seqSz;
24454
24455
    WOLFSSL_ENTER("CopyValidity");
24456
24457
    /* headers and output */
24458
    seqSz = SetSequence(cert->beforeDateSz + cert->afterDateSz, output);
24459
    if (output) {
24460
        XMEMCPY(output + seqSz, cert->beforeDate, cert->beforeDateSz);
24461
        XMEMCPY(output + seqSz + cert->beforeDateSz, cert->afterDate,
24462
                                                     cert->afterDateSz);
24463
    }
24464
    return seqSz + cert->beforeDateSz + cert->afterDateSz;
24465
}
24466
24467
#endif /* !WOLFSSL_ASN_TEMPLATE */
24468
24469
24470
/* Simple name OID size. */
24471
#define NAME_OID_SZ     3
24472
24473
/* Domain name OIDs. */
24474
static const byte nameOid[][NAME_OID_SZ] = {
24475
    { 0x55, 0x04, ASN_COUNTRY_NAME },
24476
    { 0x55, 0x04, ASN_STATE_NAME },
24477
    { 0x55, 0x04, ASN_STREET_ADDR },
24478
    { 0x55, 0x04, ASN_LOCALITY_NAME },
24479
#ifdef WOLFSSL_CERT_NAME_ALL
24480
    { 0x55, 0x04, ASN_NAME },
24481
    { 0x55, 0x04, ASN_GIVEN_NAME },
24482
    { 0x55, 0x04, ASN_INITIALS },
24483
    { 0x55, 0x04, ASN_DNQUALIFIER },
24484
#endif
24485
    { 0x55, 0x04, ASN_SUR_NAME },
24486
    { 0x55, 0x04, ASN_ORG_NAME },
24487
    { 0x00, 0x00, ASN_DOMAIN_COMPONENT}, /* not actual OID - see dcOid */
24488
                                         /* list all DC values before OUs */
24489
    { 0x55, 0x04, ASN_ORGUNIT_NAME },
24490
    { 0x55, 0x04, ASN_COMMON_NAME },
24491
    { 0x55, 0x04, ASN_SERIAL_NUMBER },
24492
#ifdef WOLFSSL_CERT_EXT
24493
    { 0x55, 0x04, ASN_BUS_CAT },
24494
#endif
24495
    { 0x55, 0x04, ASN_POSTAL_CODE },
24496
    { 0x00, 0x00, ASN_EMAIL_NAME},       /* not actual OID - see attrEmailOid */
24497
    { 0x00, 0x00, ASN_USER_ID},          /* not actual OID - see uidOid */
24498
#ifdef WOLFSSL_CUSTOM_OID
24499
    { 0x00, 0x00, ASN_CUSTOM_NAME} /* OID comes from CertOidField */
24500
#endif
24501
};
24502
#define NAME_ENTRIES (int)(sizeof(nameOid)/NAME_OID_SZ)
24503
24504
24505
/* Get ASN Name from index */
24506
byte GetCertNameId(int idx)
24507
{
24508
    if (idx < NAME_ENTRIES)
24509
        return nameOid[idx][2];
24510
    return 0;
24511
}
24512
24513
/* Get Which Name from index */
24514
const char* GetOneCertName(CertName* name, int idx)
24515
{
24516
    byte type = GetCertNameId(idx);
24517
    switch (type) {
24518
    case ASN_COUNTRY_NAME:
24519
       return name->country;
24520
    case ASN_STATE_NAME:
24521
       return name->state;
24522
    case ASN_STREET_ADDR:
24523
       return name->street;
24524
    case ASN_LOCALITY_NAME:
24525
       return name->locality;
24526
#ifdef WOLFSSL_CERT_NAME_ALL
24527
    case ASN_NAME:
24528
       return name->dnName;
24529
    case ASN_GIVEN_NAME:
24530
       return name->givenName;
24531
    case ASN_INITIALS:
24532
       return name->initials;
24533
    case ASN_DNQUALIFIER:
24534
       return name->dnQualifier;
24535
#endif /* WOLFSSL_CERT_NAME_ALL */
24536
    case ASN_SUR_NAME:
24537
       return name->sur;
24538
    case ASN_ORG_NAME:
24539
       return name->org;
24540
    case ASN_ORGUNIT_NAME:
24541
       return name->unit;
24542
    case ASN_COMMON_NAME:
24543
       return name->commonName;
24544
    case ASN_SERIAL_NUMBER:
24545
       return name->serialDev;
24546
    case ASN_USER_ID:
24547
       return name->userId;
24548
    case ASN_POSTAL_CODE:
24549
       return name->postalCode;
24550
    case ASN_EMAIL_NAME:
24551
       return name->email;
24552
#ifdef WOLFSSL_CERT_EXT
24553
    case ASN_BUS_CAT:
24554
       return name->busCat;
24555
#endif
24556
#ifdef WOLFSSL_CUSTOM_OID
24557
    case ASN_CUSTOM_NAME:
24558
        return (const char*)name->custom.val;
24559
#endif
24560
    default:
24561
       return NULL;
24562
    }
24563
}
24564
24565
24566
/* Get Which Name Encoding from index */
24567
static char GetNameType(CertName* name, int idx)
24568
{
24569
    byte type = GetCertNameId(idx);
24570
    switch (type) {
24571
    case ASN_COUNTRY_NAME:
24572
       return name->countryEnc;
24573
    case ASN_STATE_NAME:
24574
       return name->stateEnc;
24575
    case ASN_STREET_ADDR:
24576
       return name->streetEnc;
24577
    case ASN_LOCALITY_NAME:
24578
       return name->localityEnc;
24579
#ifdef WOLFSSL_CERT_NAME_ALL
24580
    case ASN_NAME:
24581
       return name->dnNameEnc;
24582
    case ASN_GIVEN_NAME:
24583
       return name->givenNameEnc;
24584
    case ASN_INITIALS:
24585
       return name->initialsEnc;
24586
    case ASN_DNQUALIFIER:
24587
       return name->dnQualifierEnc;
24588
#endif /* WOLFSSL_CERT_NAME_ALL */
24589
    case ASN_SUR_NAME:
24590
       return name->surEnc;
24591
    case ASN_ORG_NAME:
24592
       return name->orgEnc;
24593
    case ASN_ORGUNIT_NAME:
24594
       return name->unitEnc;
24595
    case ASN_COMMON_NAME:
24596
       return name->commonNameEnc;
24597
    case ASN_SERIAL_NUMBER:
24598
       return name->serialDevEnc;
24599
    case ASN_USER_ID:
24600
       return name->userIdEnc;
24601
    case ASN_POSTAL_CODE:
24602
       return name->postalCodeEnc;
24603
    case ASN_EMAIL_NAME:
24604
       return 0; /* special */
24605
#ifdef WOLFSSL_CERT_EXT
24606
    case ASN_BUS_CAT:
24607
       return name->busCatEnc;
24608
#endif
24609
#ifdef WOLFSSL_CUSTOM_OID
24610
    case ASN_CUSTOM_NAME:
24611
        return name->custom.enc;
24612
#endif
24613
    default:
24614
       return 0;
24615
    }
24616
}
24617
24618
#ifndef WOLFSSL_ASN_TEMPLATE
24619
/*
24620
 Extensions ::= SEQUENCE OF Extension
24621
24622
 Extension ::= SEQUENCE {
24623
 extnId     OBJECT IDENTIFIER,
24624
 critical   BOOLEAN DEFAULT FALSE,
24625
 extnValue  OCTET STRING }
24626
 */
24627
24628
/* encode all extensions, return total bytes written */
24629
static int SetExtensions(byte* out, word32 outSz, int *IdxInOut,
24630
                         const byte* ext, int extSz)
24631
{
24632
    if (out == NULL || IdxInOut == NULL || ext == NULL)
24633
        return BAD_FUNC_ARG;
24634
24635
    if (outSz < (word32)(*IdxInOut+extSz))
24636
        return BUFFER_E;
24637
24638
    XMEMCPY(&out[*IdxInOut], ext, extSz);  /* extensions */
24639
    *IdxInOut += extSz;
24640
24641
    return *IdxInOut;
24642
}
24643
24644
/* encode extensions header, return total bytes written */
24645
static int SetExtensionsHeader(byte* out, word32 outSz, int extSz)
24646
{
24647
    byte sequence[MAX_SEQ_SZ];
24648
    byte len[MAX_LENGTH_SZ];
24649
    int seqSz, lenSz, idx = 0;
24650
24651
    if (out == NULL)
24652
        return BAD_FUNC_ARG;
24653
24654
    if (outSz < 3)
24655
        return BUFFER_E;
24656
24657
    seqSz = SetSequence(extSz, sequence);
24658
24659
    /* encode extensions length provided */
24660
    lenSz = SetLength(extSz+seqSz, len);
24661
24662
    if (outSz < (word32)(lenSz+seqSz+1))
24663
        return BUFFER_E;
24664
24665
    out[idx++] = ASN_EXTENSIONS; /* extensions id */
24666
    XMEMCPY(&out[idx], len, lenSz);  /* length */
24667
    idx += lenSz;
24668
24669
    XMEMCPY(&out[idx], sequence, seqSz);  /* sequence */
24670
    idx += seqSz;
24671
24672
    return idx;
24673
}
24674
24675
24676
/* encode CA basic constraints true with path length
24677
 * return total bytes written */
24678
static int SetCaWithPathLen(byte* out, word32 outSz, byte pathLen)
24679
{
24680
    /* ASN1->DER sequence for Basic Constraints True and path length */
24681
    const byte caPathLenBasicConstASN1[] = {
24682
        0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x04,
24683
        0x08, 0x30, 0x06, 0x01, 0x01, 0xFF, 0x02, 0x01,
24684
        0x00
24685
    };
24686
24687
    if (out == NULL)
24688
        return BAD_FUNC_ARG;
24689
24690
    if (outSz < sizeof(caPathLenBasicConstASN1))
24691
        return BUFFER_E;
24692
24693
    XMEMCPY(out, caPathLenBasicConstASN1, sizeof(caPathLenBasicConstASN1));
24694
24695
    out[sizeof(caPathLenBasicConstASN1)-1] = pathLen;
24696
24697
    return (int)sizeof(caPathLenBasicConstASN1);
24698
}
24699
24700
24701
/* encode CA basic constraints true
24702
 * return total bytes written */
24703
static int SetCa(byte* out, word32 outSz)
24704
{
24705
    /* ASN1->DER sequence for Basic Constraints True */
24706
    const byte caBasicConstASN1[] = {
24707
        0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,
24708
        0x05, 0x30, 0x03, 0x01, 0x01, 0xff
24709
    };
24710
24711
    if (out == NULL)
24712
        return BAD_FUNC_ARG;
24713
24714
    if (outSz < sizeof(caBasicConstASN1))
24715
        return BUFFER_E;
24716
24717
    XMEMCPY(out, caBasicConstASN1, sizeof(caBasicConstASN1));
24718
24719
    return (int)sizeof(caBasicConstASN1);
24720
}
24721
24722
/* encode basic constraints without CA Boolean
24723
 * return total bytes written */
24724
static int SetBC(byte* out, word32 outSz)
24725
{
24726
    /* ASN1->DER sequence for Basic Constraint without CA Boolean */
24727
 const byte BasicConstASN1[] = {
24728
        0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,
24729
        0x02, 0x30, 0x00
24730
    };
24731
24732
    if (out == NULL)
24733
        return BAD_FUNC_ARG;
24734
24735
    if (outSz < sizeof(BasicConstASN1))
24736
        return BUFFER_E;
24737
24738
    XMEMCPY(out, BasicConstASN1, sizeof(BasicConstASN1));
24739
24740
    return (int)sizeof(BasicConstASN1);
24741
}
24742
#endif
24743
24744
24745
#ifdef WOLFSSL_CERT_EXT
24746
#ifndef WOLFSSL_ASN_TEMPLATE
24747
/* encode OID and associated value, return total bytes written */
24748
static int SetOidValue(byte* out, word32 outSz, const byte *oid, word32 oidSz,
24749
                       byte *in, word32 inSz)
24750
{
24751
    int idx = 0;
24752
24753
    if (out == NULL || oid == NULL || in == NULL)
24754
        return BAD_FUNC_ARG;
24755
24756
    if (outSz < 3)
24757
        return BUFFER_E;
24758
24759
    /* sequence,  + 1 => byte to put value size */
24760
    idx = SetSequence(inSz + oidSz + 1, out);
24761
24762
    if ((idx + inSz + oidSz + 1) > outSz)
24763
        return BUFFER_E;
24764
24765
    XMEMCPY(out+idx, oid, oidSz);
24766
    idx += oidSz;
24767
    out[idx++] = (byte)inSz;
24768
    XMEMCPY(out+idx, in, inSz);
24769
24770
    return (idx+inSz);
24771
}
24772
24773
/* encode Subject Key Identifier, return total bytes written
24774
 * RFC5280 : non-critical */
24775
static int SetSKID(byte* output, word32 outSz, const byte *input, word32 length)
24776
{
24777
    byte skid_len[1 + MAX_LENGTH_SZ];
24778
    byte skid_enc_len[MAX_LENGTH_SZ];
24779
    int idx = 0, skid_lenSz, skid_enc_lenSz;
24780
    const byte skid_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04 };
24781
24782
    if (output == NULL || input == NULL)
24783
        return BAD_FUNC_ARG;
24784
24785
    /* Octet String header */
24786
    skid_lenSz = SetOctetString(length, skid_len);
24787
24788
    /* length of encoded value */
24789
    skid_enc_lenSz = SetLength(length + skid_lenSz, skid_enc_len);
24790
24791
    if (outSz < 3)
24792
        return BUFFER_E;
24793
24794
    idx = SetSequence(length + sizeof(skid_oid) + skid_lenSz + skid_enc_lenSz,
24795
                      output);
24796
24797
    if ((length + sizeof(skid_oid) + skid_lenSz + skid_enc_lenSz) > outSz)
24798
        return BUFFER_E;
24799
24800
    /* put oid */
24801
    XMEMCPY(output+idx, skid_oid, sizeof(skid_oid));
24802
    idx += sizeof(skid_oid);
24803
24804
    /* put encoded len */
24805
    XMEMCPY(output+idx, skid_enc_len, skid_enc_lenSz);
24806
    idx += skid_enc_lenSz;
24807
24808
    /* put octet header */
24809
    XMEMCPY(output+idx, skid_len, skid_lenSz);
24810
    idx += skid_lenSz;
24811
24812
    /* put value */
24813
    XMEMCPY(output+idx, input, length);
24814
    idx += length;
24815
24816
    return idx;
24817
}
24818
24819
/* encode Authority Key Identifier, return total bytes written
24820
 * RFC5280 : non-critical */
24821
static int SetAKID(byte* output, word32 outSz, byte *input, word32 length,
24822
                   byte rawAkid)
24823
{
24824
    int     enc_valSz, inSeqSz;
24825
    byte enc_val_buf[MAX_KID_SZ];
24826
    byte* enc_val;
24827
    const byte akid_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x23 };
24828
    const byte akid_cs[] = { 0x80 };
24829
    word32 idx;
24830
24831
    (void)rawAkid;
24832
24833
    if (output == NULL || input == NULL)
24834
        return BAD_FUNC_ARG;
24835
24836
#ifdef WOLFSSL_AKID_NAME
24837
    if (rawAkid) {
24838
        enc_val = input;
24839
        enc_valSz = length;
24840
    }
24841
    else
24842
#endif
24843
    {
24844
        enc_val = enc_val_buf;
24845
        enc_valSz = length + 3 + sizeof(akid_cs);
24846
        if (enc_valSz > (int)sizeof(enc_val_buf))
24847
            return BAD_FUNC_ARG;
24848
24849
        /* sequence for ContentSpec & value */
24850
        enc_valSz = SetOidValue(enc_val, enc_valSz, akid_cs, sizeof(akid_cs),
24851
                          input, length);
24852
        if (enc_valSz <= 0)
24853
            return enc_valSz;
24854
    }
24855
24856
    /* The size of the extension sequence contents */
24857
    inSeqSz = sizeof(akid_oid) + SetOctetString(enc_valSz, NULL) +
24858
            enc_valSz;
24859
24860
    if (SetSequence(inSeqSz, NULL) + inSeqSz > outSz)
24861
        return BAD_FUNC_ARG;
24862
24863
    /* Write out the sequence header */
24864
    idx = SetSequence(inSeqSz, output);
24865
24866
    /* Write out OID */
24867
    XMEMCPY(output + idx, akid_oid, sizeof(akid_oid));
24868
    idx += sizeof(akid_oid);
24869
24870
    /* Write out AKID */
24871
    idx += SetOctetString(enc_valSz, output + idx);
24872
    XMEMCPY(output + idx, enc_val, enc_valSz);
24873
24874
    return idx + enc_valSz;
24875
}
24876
24877
/* encode Key Usage, return total bytes written
24878
 * RFC5280 : critical */
24879
static int SetKeyUsage(byte* output, word32 outSz, word16 input)
24880
{
24881
    byte ku[5];
24882
    int  idx;
24883
    const byte keyusage_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x0f,
24884
                                         0x01, 0x01, 0xff, 0x04};
24885
    if (output == NULL)
24886
        return BAD_FUNC_ARG;
24887
24888
    idx = SetBitString16Bit(input, ku);
24889
    return SetOidValue(output, outSz, keyusage_oid, sizeof(keyusage_oid),
24890
                       ku, idx);
24891
}
24892
24893
static int SetOjectIdValue(byte* output, word32 outSz, int* idx,
24894
    const byte* oid, word32 oidSz)
24895
{
24896
    /* verify room */
24897
    if (*idx + 2 + oidSz >= outSz)
24898
        return ASN_PARSE_E;
24899
24900
    *idx += SetObjectId(oidSz, &output[*idx]);
24901
    XMEMCPY(&output[*idx], oid, oidSz);
24902
    *idx += oidSz;
24903
24904
    return 0;
24905
}
24906
#endif
24907
24908
#ifdef WOLFSSL_ASN_TEMPLATE
24909
/* ASN.1 template for extended key usage.
24910
 * X.509: RFC 5280, 4.2.12 - Extended Key Usage
24911
 * Dynamic creation of template for encoding.
24912
 */
24913
static const ASNItem ekuASN[] = {
24914
/* SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 },
24915
/* OID */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
24916
};
24917
enum {
24918
    EKUASN_IDX_SEQ = 0,
24919
    EKUASN_IDX_OID,
24920
};
24921
24922
/* OIDs corresponding to extended key usage. */
24923
struct {
24924
    const byte* oid;
24925
    word32 oidSz;
24926
} ekuOid[] = {
24927
    { extExtKeyUsageServerAuthOid,   sizeof(extExtKeyUsageServerAuthOid) },
24928
    { extExtKeyUsageClientAuthOid,   sizeof(extExtKeyUsageClientAuthOid) },
24929
    { extExtKeyUsageCodeSigningOid,  sizeof(extExtKeyUsageCodeSigningOid) },
24930
    { extExtKeyUsageEmailProtectOid, sizeof(extExtKeyUsageEmailProtectOid) },
24931
    { extExtKeyUsageTimestampOid,    sizeof(extExtKeyUsageTimestampOid) },
24932
    { extExtKeyUsageOcspSignOid,     sizeof(extExtKeyUsageOcspSignOid) },
24933
};
24934
24935
#define EKU_OID_LO      1
24936
#define EKU_OID_HI      6
24937
#endif /* WOLFSSL_ASN_TEMPLATE */
24938
24939
/* encode Extended Key Usage (RFC 5280 4.2.1.12), return total bytes written */
24940
static int SetExtKeyUsage(Cert* cert, byte* output, word32 outSz, byte input)
24941
{
24942
#ifndef WOLFSSL_ASN_TEMPLATE
24943
    int idx = 0, oidListSz = 0, totalSz, ret = 0;
24944
    const byte extkeyusage_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x25 };
24945
24946
    if (output == NULL)
24947
        return BAD_FUNC_ARG;
24948
24949
    /* Skip to OID List */
24950
    totalSz = 2 + sizeof(extkeyusage_oid) + 4;
24951
    idx = totalSz;
24952
24953
    /* Build OID List */
24954
    /* If any set, then just use it */
24955
    if (input & EXTKEYUSE_ANY) {
24956
        ret |= SetOjectIdValue(output, outSz, &idx,
24957
            extExtKeyUsageAnyOid, sizeof(extExtKeyUsageAnyOid));
24958
    }
24959
    else {
24960
        if (input & EXTKEYUSE_SERVER_AUTH)
24961
            ret |= SetOjectIdValue(output, outSz, &idx,
24962
                extExtKeyUsageServerAuthOid, sizeof(extExtKeyUsageServerAuthOid));
24963
        if (input & EXTKEYUSE_CLIENT_AUTH)
24964
            ret |= SetOjectIdValue(output, outSz, &idx,
24965
                extExtKeyUsageClientAuthOid, sizeof(extExtKeyUsageClientAuthOid));
24966
        if (input & EXTKEYUSE_CODESIGN)
24967
            ret |= SetOjectIdValue(output, outSz, &idx,
24968
                extExtKeyUsageCodeSigningOid, sizeof(extExtKeyUsageCodeSigningOid));
24969
        if (input & EXTKEYUSE_EMAILPROT)
24970
            ret |= SetOjectIdValue(output, outSz, &idx,
24971
                extExtKeyUsageEmailProtectOid, sizeof(extExtKeyUsageEmailProtectOid));
24972
        if (input & EXTKEYUSE_TIMESTAMP)
24973
            ret |= SetOjectIdValue(output, outSz, &idx,
24974
                extExtKeyUsageTimestampOid, sizeof(extExtKeyUsageTimestampOid));
24975
        if (input & EXTKEYUSE_OCSP_SIGN)
24976
            ret |= SetOjectIdValue(output, outSz, &idx,
24977
                extExtKeyUsageOcspSignOid, sizeof(extExtKeyUsageOcspSignOid));
24978
    #ifdef WOLFSSL_EKU_OID
24979
        /* iterate through OID values */
24980
        if (input & EXTKEYUSE_USER) {
24981
            int i, sz;
24982
            for (i = 0; i < CTC_MAX_EKU_NB; i++) {
24983
                sz = cert->extKeyUsageOIDSz[i];
24984
                if (sz > 0) {
24985
                    ret |= SetOjectIdValue(output, outSz, &idx,
24986
                        cert->extKeyUsageOID[i], sz);
24987
                }
24988
            }
24989
        }
24990
    #endif /* WOLFSSL_EKU_OID */
24991
    }
24992
    if (ret != 0)
24993
        return ASN_PARSE_E;
24994
24995
    /* Calculate Sizes */
24996
    oidListSz = idx - totalSz;
24997
    totalSz = idx - 2; /* exclude first seq/len (2) */
24998
24999
    /* 1. Seq + Total Len (2) */
25000
    idx = SetSequence(totalSz, output);
25001
25002
    /* 2. Object ID (2) */
25003
    XMEMCPY(&output[idx], extkeyusage_oid, sizeof(extkeyusage_oid));
25004
    idx += sizeof(extkeyusage_oid);
25005
25006
    /* 3. Octet String (2) */
25007
    idx += SetOctetString(totalSz - idx, &output[idx]);
25008
25009
    /* 4. Seq + OidListLen (2) */
25010
    idx += SetSequence(oidListSz, &output[idx]);
25011
25012
    /* 5. Oid List (already set in-place above) */
25013
    idx += oidListSz;
25014
25015
    (void)cert;
25016
    return idx;
25017
#else
25018
    /* TODO: consider calculating size of OBJECT_IDs, setting length into
25019
     * SEQUENCE, encode SEQUENCE, encode OBJECT_IDs into buffer.  */
25020
    ASNSetData* dataASN;
25021
    ASNItem* extKuASN = NULL;
25022
    int asnIdx = 1;
25023
    int cnt = 1 + EKU_OID_HI;
25024
    int i;
25025
    int ret = 0;
25026
    int sz = 0;
25027
25028
#ifdef WOLFSSL_EKU_OID
25029
    cnt += CTC_MAX_EKU_NB;
25030
#endif
25031
25032
    /* Allocate memory for dynamic data items. */
25033
    dataASN = (ASNSetData*)XMALLOC(cnt * sizeof(ASNSetData), cert->heap,
25034
                                                       DYNAMIC_TYPE_TMP_BUFFER);
25035
    if (dataASN == NULL) {
25036
        ret = MEMORY_E;
25037
    }
25038
    if (ret == 0) {
25039
        /* Allocate memory for dynamic ASN.1 template. */
25040
        extKuASN = (ASNItem*)XMALLOC(cnt * sizeof(ASNItem), cert->heap,
25041
                                                       DYNAMIC_TYPE_TMP_BUFFER);
25042
        if (extKuASN == NULL) {
25043
            ret = MEMORY_E;
25044
        }
25045
    }
25046
25047
    if (ret == 0) {
25048
        /* Copy Sequence into dynamic ASN.1 template. */
25049
        XMEMCPY(&extKuASN[EKUASN_IDX_SEQ], ekuASN, sizeof(ASNItem));
25050
        /* Clear dynamic data. */
25051
        XMEMSET(dataASN, 0, cnt * sizeof(ASNSetData));
25052
25053
        /* Build up the template and data. */
25054
        /* If 'any' set, then just use it. */
25055
        if ((input & EXTKEYUSE_ANY) == EXTKEYUSE_ANY) {
25056
            /* Set template item. */
25057
            XMEMCPY(&extKuASN[EKUASN_IDX_OID], &ekuASN[EKUASN_IDX_OID],
25058
                    sizeof(ASNItem));
25059
            /* Set data item. */
25060
            SetASN_Buffer(&dataASN[asnIdx], extExtKeyUsageAnyOid,
25061
                sizeof(extExtKeyUsageAnyOid));
25062
            asnIdx++;
25063
        }
25064
        else {
25065
            /* Step through the flagged purposes. */
25066
            for (i = EKU_OID_LO; i <= EKU_OID_HI; i++) {
25067
                if ((input & (1 << i)) != 0) {
25068
                    /* Set template item. */
25069
                    XMEMCPY(&extKuASN[asnIdx], &ekuASN[EKUASN_IDX_OID],
25070
                            sizeof(ASNItem));
25071
                    /* Set data item. */
25072
                    SetASN_Buffer(&dataASN[asnIdx], ekuOid[i - 1].oid,
25073
                        ekuOid[i - 1].oidSz);
25074
                    asnIdx++;
25075
                }
25076
            }
25077
        #ifdef WOLFSSL_EKU_OID
25078
            if (input & EXTKEYUSE_USER) {
25079
                /* Iterate through OID values */
25080
                for (i = 0; i < CTC_MAX_EKU_NB; i++) {
25081
                    sz = cert->extKeyUsageOIDSz[i];
25082
                    if (sz > 0) {
25083
                        /* Set template item. */
25084
                        XMEMCPY(&extKuASN[asnIdx], &ekuASN[EKUASN_IDX_OID],
25085
                                sizeof(ASNItem));
25086
                        /* Set data item. */
25087
                        SetASN_Buffer(&dataASN[asnIdx], cert->extKeyUsageOID[i],
25088
                            sz);
25089
                        asnIdx++;
25090
                    }
25091
                }
25092
            }
25093
        #endif /* WOLFSSL_EKU_OID */
25094
            (void)cert;
25095
        }
25096
25097
        /* Calculate size of encoding. */
25098
        sz = 0;
25099
        ret = SizeASN_Items(extKuASN, dataASN, asnIdx, &sz);
25100
    }
25101
    /* When buffer to write to, ensure it's big enough. */
25102
    if ((ret == 0) && (output != NULL) && (sz > (int)outSz)) {
25103
        ret = BUFFER_E;
25104
    }
25105
    if ((ret == 0) && (output != NULL)) {
25106
        /* Encode extended key usage. */
25107
        SetASN_Items(extKuASN, dataASN, asnIdx, output);
25108
    }
25109
    if (ret == 0) {
25110
        /* Return the encoding size. */
25111
        ret = sz;
25112
    }
25113
25114
    /* Dispose of allocated data. */
25115
    if (extKuASN != NULL) {
25116
        XFREE(extKuASN, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
25117
    }
25118
    if (dataASN != NULL) {
25119
        XFREE(dataASN, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
25120
    }
25121
25122
    return ret;
25123
#endif
25124
}
25125
25126
#ifndef IGNORE_NETSCAPE_CERT_TYPE
25127
#ifndef WOLFSSL_ASN_TEMPLATE
25128
static int SetNsCertType(Cert* cert, byte* output, word32 outSz, byte input)
25129
{
25130
    word32 idx;
25131
    byte unusedBits = 0;
25132
    byte nsCertType = input;
25133
    word32 totalSz;
25134
    word32 bitStrSz;
25135
    const byte nscerttype_oid[] = { 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
25136
                                    0x86, 0xF8, 0x42, 0x01, 0x01 };
25137
25138
    if (cert == NULL || output == NULL ||
25139
            input == 0)
25140
        return BAD_FUNC_ARG;
25141
25142
    totalSz = sizeof(nscerttype_oid);
25143
25144
    /* Get amount of lsb zero's */
25145
    for (;(input & 1) == 0; input >>= 1)
25146
        unusedBits++;
25147
25148
    /* 1 byte of NS Cert Type extension */
25149
    bitStrSz = SetBitString(1, unusedBits, NULL) + 1;
25150
    totalSz += SetOctetString(bitStrSz, NULL) + bitStrSz;
25151
25152
    if (SetSequence(totalSz, NULL) + totalSz > outSz)
25153
        return BAD_FUNC_ARG;
25154
25155
    /* 1. Seq + Total Len */
25156
    idx = SetSequence(totalSz, output);
25157
25158
    /* 2. Object ID */
25159
    XMEMCPY(&output[idx], nscerttype_oid, sizeof(nscerttype_oid));
25160
    idx += sizeof(nscerttype_oid);
25161
25162
    /* 3. Octet String */
25163
    idx += SetOctetString(bitStrSz, &output[idx]);
25164
25165
    /* 4. Bit String */
25166
    idx += SetBitString(1, unusedBits, &output[idx]);
25167
    output[idx++] = nsCertType;
25168
25169
    return idx;
25170
}
25171
#endif
25172
#endif
25173
25174
#ifndef WOLFSSL_ASN_TEMPLATE
25175
static int SetCRLInfo(Cert* cert, byte* output, word32 outSz, byte* input,
25176
                      int inSz)
25177
{
25178
    word32 idx;
25179
    word32 totalSz;
25180
    const byte crlinfo_oid[] = { 0x06, 0x03, 0x55, 0x1D, 0x1F };
25181
25182
    if (cert == NULL || output == NULL ||
25183
            input == 0 || inSz <= 0)
25184
        return BAD_FUNC_ARG;
25185
25186
    totalSz = sizeof(crlinfo_oid) + SetOctetString(inSz, NULL) + inSz;
25187
25188
    if (SetSequence(totalSz, NULL) + totalSz > outSz)
25189
        return BAD_FUNC_ARG;
25190
25191
    /* 1. Seq + Total Len */
25192
    idx = SetSequence(totalSz, output);
25193
25194
    /* 2. Object ID */
25195
    XMEMCPY(&output[idx], crlinfo_oid, sizeof(crlinfo_oid));
25196
    idx += sizeof(crlinfo_oid);
25197
25198
    /* 3. Octet String */
25199
    idx += SetOctetString(inSz, &output[idx]);
25200
25201
    /* 4. CRL Info */
25202
    XMEMCPY(&output[idx], input, inSz);
25203
    idx += inSz;
25204
25205
    return idx;
25206
}
25207
#endif
25208
25209
/* encode Certificate Policies, return total bytes written
25210
 * each input value must be ITU-T X.690 formatted : a.b.c...
25211
 * input must be an array of values with a NULL terminated for the latest
25212
 * RFC5280 : non-critical */
25213
static int SetCertificatePolicies(byte *output,
25214
                                  word32 outputSz,
25215
                                  char input[MAX_CERTPOL_NB][MAX_CERTPOL_SZ],
25216
                                  word16 nb_certpol,
25217
                                  void* heap)
25218
{
25219
#ifndef WOLFSSL_ASN_TEMPLATE
25220
    byte    oid[MAX_OID_SZ];
25221
    byte    der_oid[MAX_CERTPOL_NB][MAX_OID_SZ];
25222
    byte    out[MAX_CERTPOL_SZ];
25223
    word32  oidSz;
25224
    word32  outSz;
25225
    word32  i = 0;
25226
    word32  der_oidSz[MAX_CERTPOL_NB];
25227
    int     ret;
25228
25229
    const byte certpol_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04 };
25230
    const byte oid_oid[] = { 0x06 };
25231
25232
    if (output == NULL || input == NULL || nb_certpol > MAX_CERTPOL_NB)
25233
        return BAD_FUNC_ARG;
25234
25235
    for (i = 0; i < nb_certpol; i++) {
25236
        oidSz = sizeof(oid);
25237
        XMEMSET(oid, 0, oidSz);
25238
25239
        ret = EncodePolicyOID(oid, &oidSz, input[i], heap);
25240
        if (ret != 0)
25241
            return ret;
25242
25243
        /* compute sequence value for the oid */
25244
        ret = SetOidValue(der_oid[i], MAX_OID_SZ, oid_oid,
25245
                          sizeof(oid_oid), oid, oidSz);
25246
        if (ret <= 0)
25247
            return ret;
25248
        else
25249
            der_oidSz[i] = (word32)ret;
25250
    }
25251
25252
    /* concatenate oid, keep two byte for sequence/size of the created value */
25253
    for (i = 0, outSz = 2; i < nb_certpol; i++) {
25254
        XMEMCPY(out+outSz, der_oid[i], der_oidSz[i]);
25255
        outSz += der_oidSz[i];
25256
    }
25257
25258
    /* add sequence */
25259
    ret = SetSequence(outSz-2, out);
25260
    if (ret <= 0)
25261
        return ret;
25262
25263
    /* add Policy OID to compute final value */
25264
    return SetOidValue(output, outputSz, certpol_oid, sizeof(certpol_oid),
25265
                      out, outSz);
25266
#else
25267
    int    i;
25268
    int    ret = 0;
25269
    byte   oid[MAX_OID_SZ];
25270
    word32 oidSz;
25271
    word32 sz = 0;
25272
    int    piSz;
25273
25274
    if ((input == NULL) || (nb_certpol > MAX_CERTPOL_NB)) {
25275
        ret = BAD_FUNC_ARG;
25276
    }
25277
    /* Put in policyIdentifier but not policyQualifiers. */
25278
    for (i = 0; (ret == 0) && (i < nb_certpol); i++) {
25279
        ASNSetData dataASN[policyInfoASN_Length];
25280
25281
        oidSz = sizeof(oid);
25282
        XMEMSET(oid, 0, oidSz);
25283
        dataASN[POLICYINFOASN_IDX_QUALI].noOut = 1;
25284
25285
        ret = EncodePolicyOID(oid, &oidSz, input[i], heap);
25286
        if (ret == 0) {
25287
            XMEMSET(dataASN, 0, sizeof(dataASN));
25288
            SetASN_Buffer(&dataASN[POLICYINFOASN_IDX_ID], oid, oidSz);
25289
            ret = SizeASN_Items(policyInfoASN, dataASN, policyInfoASN_Length,
25290
                                &piSz);
25291
        }
25292
        if ((ret == 0) && (output != NULL) && (sz + piSz > outputSz)) {
25293
            ret = BUFFER_E;
25294
        }
25295
        if (ret == 0) {
25296
            if (output != NULL) {
25297
                SetASN_Items(policyInfoASN, dataASN, policyInfoASN_Length,
25298
                    output);
25299
                output += piSz;
25300
            }
25301
            sz += piSz;
25302
        }
25303
    }
25304
25305
    if (ret == 0) {
25306
        ret = sz;
25307
    }
25308
    return ret;
25309
#endif
25310
}
25311
#endif /* WOLFSSL_CERT_EXT */
25312
25313
25314
#ifdef WOLFSSL_ALT_NAMES
25315
25316
#ifndef WOLFSSL_ASN_TEMPLATE
25317
/* encode Alternative Names, return total bytes written */
25318
static int SetAltNames(byte *output, word32 outSz,
25319
        const byte *input, word32 length, int critical)
25320
{
25321
    byte san_len[1 + MAX_LENGTH_SZ];
25322
    int idx = 0, san_lenSz;
25323
    const byte san_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x11 };
25324
    const byte san_crit[] = { 0x01, 0x01, 0xff };
25325
    word32 seqSz;
25326
25327
    if (output == NULL || input == NULL)
25328
        return BAD_FUNC_ARG;
25329
25330
    if (outSz < length)
25331
        return BUFFER_E;
25332
25333
    /* Octet String header */
25334
    san_lenSz = SetOctetString(length, san_len);
25335
25336
    if (outSz < MAX_SEQ_SZ)
25337
        return BUFFER_E;
25338
25339
    seqSz = length + sizeof(san_oid) + san_lenSz;
25340
    if (critical)
25341
        seqSz += sizeof(san_crit);
25342
    idx = SetSequence(seqSz, output);
25343
25344
    if (seqSz > outSz)
25345
        return BUFFER_E;
25346
25347
    /* put oid */
25348
    XMEMCPY(output+idx, san_oid, sizeof(san_oid));
25349
    idx += sizeof(san_oid);
25350
25351
    if (critical) {
25352
        XMEMCPY(output+idx, san_crit, sizeof(san_crit));
25353
        idx += sizeof(san_crit);
25354
    }
25355
25356
    /* put octet header */
25357
    XMEMCPY(output+idx, san_len, san_lenSz);
25358
    idx += san_lenSz;
25359
25360
    /* put value */
25361
    XMEMCPY(output+idx, input, length);
25362
    idx += length;
25363
25364
    return idx;
25365
}
25366
#endif /* WOLFSSL_ASN_TEMPLATE */
25367
25368
25369
int FlattenAltNames(byte* output, word32 outputSz, const DNS_entry* names)
25370
{
25371
    word32 idx;
25372
    const DNS_entry* curName;
25373
    word32 namesSz = 0;
25374
#ifdef WOLFSSL_ALT_NAMES_NO_REV
25375
    word32 i;
25376
#endif
25377
25378
    if (output == NULL)
25379
        return BAD_FUNC_ARG;
25380
25381
    if (names == NULL)
25382
        return 0;
25383
25384
    curName = names;
25385
    do {
25386
        namesSz += curName->len + 2 +
25387
            ((curName->len < ASN_LONG_LENGTH) ? 0
25388
             : BytePrecision(curName->len));
25389
        curName = curName->next;
25390
    } while (curName != NULL);
25391
25392
    if (outputSz < MAX_SEQ_SZ + namesSz)
25393
        return BUFFER_E;
25394
25395
    idx = SetSequence(namesSz, output);
25396
#ifdef WOLFSSL_ALT_NAMES_NO_REV
25397
    namesSz += idx;
25398
    i = namesSz;
25399
#endif
25400
25401
    curName = names;
25402
    do {
25403
#ifdef WOLFSSL_ALT_NAMES_NO_REV
25404
        word32 len = SetLength(curName->len, NULL);
25405
        idx = i - curName->len - len - 1;
25406
        i = idx;
25407
#endif
25408
        output[idx] = (byte) (ASN_CONTEXT_SPECIFIC | curName->type);
25409
        if (curName->type == ASN_DIR_TYPE) {
25410
            output[idx] |= ASN_CONSTRUCTED;
25411
        }
25412
        idx++;
25413
        idx += SetLength(curName->len, output + idx);
25414
        XMEMCPY(output + idx, curName->name, curName->len);
25415
#ifndef WOLFSSL_ALT_NAMES_NO_REV
25416
        idx += curName->len;
25417
#endif
25418
        curName = curName->next;
25419
    } while (curName != NULL);
25420
25421
#ifdef WOLFSSL_ALT_NAMES_NO_REV
25422
    idx = namesSz;
25423
#endif
25424
    return idx;
25425
}
25426
25427
#endif /* WOLFSSL_ALT_NAMES */
25428
#endif /* WOLFSSL_CERT_GEN */
25429
25430
#if defined(WOLFSSL_CERT_GEN) || defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
25431
/* Simple domain name OID size. */
25432
#define DN_OID_SZ     3
25433
25434
/* Encodes one attribute of the name (issuer/subject)
25435
 *
25436
 * name     structure to hold result of encoding
25437
 * nameStr  value to be encoded
25438
 * nameTag  tag of encoding i.e CTC_UTF8
25439
 * type     id of attribute i.e ASN_COMMON_NAME
25440
 * emailTag tag of email i.e CTC_UTF8
25441
 * returns length on success
25442
 */
25443
static int EncodeName(EncodedName* name, const char* nameStr,
25444
                    byte nameTag, byte type, byte emailTag, CertName* cname)
25445
{
25446
#if !defined(WOLFSSL_ASN_TEMPLATE)
25447
    word32 idx = 0;
25448
    /* bottom up */
25449
    byte firstLen[1 + MAX_LENGTH_SZ];
25450
    byte secondLen[MAX_LENGTH_SZ];
25451
    byte sequence[MAX_SEQ_SZ];
25452
    byte set[MAX_SET_SZ];
25453
25454
    int strLen;
25455
    int thisLen;
25456
    int firstSz, secondSz, seqSz, setSz;
25457
25458
    if (nameStr == NULL) {
25459
        name->used = 0;
25460
        return 0;
25461
    }
25462
25463
    thisLen = strLen = (int)XSTRLEN(nameStr);
25464
#ifdef WOLFSSL_CUSTOM_OID
25465
    if (type == ASN_CUSTOM_NAME) {
25466
        if (cname == NULL || cname->custom.oidSz == 0) {
25467
            name->used = 0;
25468
            return 0;
25469
        }
25470
        thisLen = strLen = cname->custom.valSz;
25471
    }
25472
#else
25473
    (void)cname;
25474
#endif
25475
25476
    if (strLen == 0) { /* no user data for this item */
25477
        name->used = 0;
25478
        return 0;
25479
    }
25480
25481
    /* Restrict country code size */
25482
    if (type == ASN_COUNTRY_NAME && strLen != CTC_COUNTRY_SIZE) {
25483
        WOLFSSL_MSG("Country code size error");
25484
        WOLFSSL_ERROR_VERBOSE(ASN_COUNTRY_SIZE_E);
25485
        return ASN_COUNTRY_SIZE_E;
25486
    }
25487
25488
    secondSz = SetLength(strLen, secondLen);
25489
    thisLen += secondSz;
25490
    switch (type) {
25491
        case ASN_EMAIL_NAME: /* email */
25492
            thisLen += (int)sizeof(attrEmailOid);
25493
            firstSz  = (int)sizeof(attrEmailOid);
25494
            break;
25495
        case ASN_DOMAIN_COMPONENT:
25496
            thisLen += (int)sizeof(dcOid);
25497
            firstSz  = (int)sizeof(dcOid);
25498
            break;
25499
        case ASN_USER_ID:
25500
            thisLen += (int)sizeof(uidOid);
25501
            firstSz  = (int)sizeof(uidOid);
25502
            break;
25503
    #ifdef WOLFSSL_CUSTOM_OID
25504
        case ASN_CUSTOM_NAME:
25505
            thisLen += cname->custom.oidSz;
25506
            firstSz = cname->custom.oidSz;
25507
            break;
25508
    #endif
25509
        default:
25510
            thisLen += DN_OID_SZ;
25511
            firstSz  = DN_OID_SZ;
25512
    }
25513
    thisLen++; /* id  type */
25514
    firstSz  = SetObjectId(firstSz, firstLen);
25515
    thisLen += firstSz;
25516
25517
    seqSz = SetSequence(thisLen, sequence);
25518
    thisLen += seqSz;
25519
    setSz = SetSet(thisLen, set);
25520
    thisLen += setSz;
25521
25522
    if (thisLen > (int)sizeof(name->encoded)) {
25523
        return BUFFER_E;
25524
    }
25525
25526
    /* store it */
25527
    idx = 0;
25528
    /* set */
25529
    XMEMCPY(name->encoded, set, setSz);
25530
    idx += setSz;
25531
    /* seq */
25532
    XMEMCPY(name->encoded + idx, sequence, seqSz);
25533
    idx += seqSz;
25534
    /* asn object id */
25535
    XMEMCPY(name->encoded + idx, firstLen, firstSz);
25536
    idx += firstSz;
25537
    switch (type) {
25538
        case ASN_EMAIL_NAME:
25539
            /* email joint id */
25540
            XMEMCPY(name->encoded + idx, attrEmailOid, sizeof(attrEmailOid));
25541
            idx += (int)sizeof(attrEmailOid);
25542
            name->encoded[idx++] = emailTag;
25543
            break;
25544
        case ASN_DOMAIN_COMPONENT:
25545
            XMEMCPY(name->encoded + idx, dcOid, sizeof(dcOid)-1);
25546
            idx += (int)sizeof(dcOid)-1;
25547
            /* id type */
25548
            name->encoded[idx++] = type;
25549
            /* str type */
25550
            name->encoded[idx++] = nameTag;
25551
            break;
25552
        case ASN_USER_ID:
25553
            XMEMCPY(name->encoded + idx, uidOid, sizeof(uidOid));
25554
            idx += (int)sizeof(uidOid);
25555
            /* str type */
25556
            name->encoded[idx++] = nameTag;
25557
            break;
25558
    #ifdef WOLFSSL_CUSTOM_OID
25559
        case ASN_CUSTOM_NAME:
25560
            XMEMCPY(name->encoded + idx, cname->custom.oid,
25561
                    cname->custom.oidSz);
25562
            idx += cname->custom.oidSz;
25563
            /* str type */
25564
            name->encoded[idx++] = nameTag;
25565
            break;
25566
    #endif
25567
        default:
25568
            name->encoded[idx++] = 0x55;
25569
            name->encoded[idx++] = 0x04;
25570
            /* id type */
25571
            name->encoded[idx++] = type;
25572
            /* str type */
25573
            name->encoded[idx++] = nameTag;
25574
    }
25575
    /* second length */
25576
    XMEMCPY(name->encoded + idx, secondLen, secondSz);
25577
    idx += secondSz;
25578
    /* str value */
25579
    XMEMCPY(name->encoded + idx, nameStr, strLen);
25580
    idx += strLen;
25581
25582
    name->type = type;
25583
    name->totalLen = idx;
25584
    name->used = 1;
25585
25586
    return idx;
25587
#else
25588
    DECL_ASNSETDATA(dataASN, rdnASN_Length);
25589
    ASNItem namesASN[rdnASN_Length];
25590
    byte dnOid[DN_OID_SZ] = { 0x55, 0x04, 0x00 };
25591
    int ret = 0;
25592
    int sz = 0;
25593
    const byte* oid;
25594
    int oidSz;
25595
    word32 nameSz;
25596
25597
    /* Validate input parameters. */
25598
    if ((name == NULL) || (nameStr == NULL)) {
25599
        ret = BAD_FUNC_ARG;
25600
    }
25601
25602
    CALLOC_ASNSETDATA(dataASN, rdnASN_Length, ret, NULL);
25603
    if (ret == 0) {
25604
        nameSz = (word32)XSTRLEN(nameStr);
25605
        /* Copy the RDN encoding template. ASN.1 tag for the name string is set
25606
         * based on type. */
25607
        XMEMCPY(namesASN, rdnASN, sizeof(namesASN));
25608
25609
        /* Set OID and ASN.1 tag for name depending on type. */
25610
        switch (type) {
25611
            case ASN_EMAIL_NAME:
25612
                /* email OID different to standard types. */
25613
                oid = attrEmailOid;
25614
                oidSz = sizeof(attrEmailOid);
25615
                /* Use email specific type/tag. */
25616
                nameTag = emailTag;
25617
                break;
25618
            case ASN_DOMAIN_COMPONENT:
25619
                /* Domain component OID different to standard types. */
25620
                oid = dcOid;
25621
                oidSz = sizeof(dcOid);
25622
                break;
25623
            case ASN_USER_ID:
25624
                /* Domain component OID different to standard types. */
25625
                oid = uidOid;
25626
                oidSz = sizeof(uidOid);
25627
                break;
25628
        #ifdef WOLFSSL_CUSTOM_OID
25629
            case ASN_CUSTOM_NAME:
25630
                nameSz = cname->custom.valSz;
25631
                oid = cname->custom.oid;
25632
                oidSz = cname->custom.oidSz;
25633
                break;
25634
        #endif
25635
            default:
25636
                /* Construct OID using type. */
25637
                dnOid[2] = type;
25638
                oid = dnOid;
25639
                oidSz = DN_OID_SZ;
25640
                break;
25641
        }
25642
25643
        /* Set OID corresponding to the name type. */
25644
        SetASN_Buffer(&dataASN[RDNASN_IDX_ATTR_TYPE], oid, oidSz);
25645
        /* Set name string. */
25646
        SetASN_Buffer(&dataASN[RDNASN_IDX_ATTR_VAL], (const byte *)nameStr, nameSz);
25647
        /* Set the ASN.1 tag for the name string. */
25648
        namesASN[RDNASN_IDX_ATTR_VAL].tag = nameTag;
25649
25650
        /* Calculate size of encoded name and indexes of components. */
25651
        ret = SizeASN_Items(namesASN, dataASN, rdnASN_Length, &sz);
25652
    }
25653
    /* Check if name's buffer is big enough. */
25654
    if ((ret == 0) && (sz > (int)sizeof(name->encoded))) {
25655
        ret = BUFFER_E;
25656
    }
25657
    if (ret == 0) {
25658
        /* Encode name into the buffer. */
25659
        SetASN_Items(namesASN, dataASN, rdnASN_Length, name->encoded);
25660
        /* Cache the type and size, and set that it is used. */
25661
        name->type = type;
25662
        name->totalLen = sz;
25663
        name->used = 1;
25664
25665
        /* Return size of encoding. */
25666
        ret = sz;
25667
    }
25668
    (void)cname;
25669
25670
    FREE_ASNSETDATA(dataASN, NULL);
25671
    return ret;
25672
#endif /* WOLFSSL_ASN_TEMPLATE */
25673
}
25674
25675
/* canonical encoding one attribute of the name (issuer/subject)
25676
 * call EncodeName with CTC_UTF8 for email type
25677
 *
25678
 * name     structure to hold result of encoding
25679
 * nameStr  value to be encoded
25680
 * nameType type of encoding i.e CTC_UTF8
25681
 * type     id of attribute i.e ASN_COMMON_NAME
25682
 *
25683
 * returns length on success
25684
 */
25685
int wc_EncodeNameCanonical(EncodedName* name, const char* nameStr,
25686
                           char nameType, byte type)
25687
{
25688
    return EncodeName(name, nameStr, (byte)nameType, type,
25689
        ASN_UTF8STRING, NULL);
25690
}
25691
#endif /* WOLFSSL_CERT_GEN || OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
25692
25693
#ifdef WOLFSSL_CERT_GEN
25694
/* Encodes one attribute of the name (issuer/subject)
25695
 * call we_EncodeName_ex with 0x16, IA5String for email type
25696
 * name     structure to hold result of encoding
25697
 * nameStr  value to be encoded
25698
 * nameType type of encoding i.e CTC_UTF8
25699
 * type     id of attribute i.e ASN_COMMON_NAME
25700
 *
25701
 * returns length on success
25702
 */
25703
int wc_EncodeName(EncodedName* name, const char* nameStr, char nameType,
25704
                  byte type)
25705
{
25706
    return EncodeName(name, nameStr, (byte)nameType, type,
25707
        ASN_IA5_STRING, NULL);
25708
}
25709
25710
#ifdef WOLFSSL_ASN_TEMPLATE
25711
static void SetRdnItems(ASNItem* namesASN, ASNSetData* dataASN, const byte* oid,
25712
    int oidSz, byte tag, const byte* data, int sz)
25713
{
25714
    XMEMCPY(namesASN, rdnASN, sizeof(rdnASN));
25715
    SetASN_Buffer(&dataASN[RDNASN_IDX_ATTR_TYPE], oid, oidSz);
25716
    namesASN[RDNASN_IDX_ATTR_VAL].tag = tag;
25717
    SetASN_Buffer(&dataASN[RDNASN_IDX_ATTR_VAL], data, sz);
25718
}
25719
25720
#ifdef WOLFSSL_MULTI_ATTRIB
25721
static int FindMultiAttrib(CertName* name, int id, int* idx)
25722
{
25723
    int i;
25724
    for (i = *idx + 1; i < CTC_MAX_ATTRIB; i++) {
25725
        if (name->name[i].sz > 0 && name->name[i].id == id) {
25726
            break;
25727
        }
25728
    }
25729
    if (i == CTC_MAX_ATTRIB) {
25730
        i = -1;
25731
    }
25732
    *idx = i;
25733
    return i >= 0;
25734
}
25735
#endif
25736
25737
/* ASN.1 template for the SEQUENCE around the RDNs.
25738
 * X.509: RFC 5280, 4.1.2.4 - RDNSequence
25739
 */
25740
static const ASNItem nameASN[] = {
25741
    { 0, ASN_SEQUENCE, 1, 1, 0 },
25742
};
25743
enum {
25744
    NAMEASN_IDX_SEQ = 0,
25745
};
25746
25747
/* Number of items in ASN.1 template for the SEQUENCE around the RDNs. */
25748
#define nameASN_Length (sizeof(nameASN) / sizeof(ASNItem))
25749
25750
static int SetNameRdnItems(ASNSetData* dataASN, ASNItem* namesASN,
25751
        int maxIdx, CertName* name)
25752
{
25753
    int         i;
25754
    int         idx;
25755
    int         ret = 0;
25756
    int         nameLen[NAME_ENTRIES];
25757
#ifdef WOLFSSL_MULTI_ATTRIB
25758
    int         j;
25759
#endif
25760
25761
    for (i = 0; i < NAME_ENTRIES; i++) {
25762
        /* Keep name length to identify component is to be encoded. */
25763
        const char* nameStr = GetOneCertName(name, i);
25764
        nameLen[i] = nameStr ? (int)XSTRLEN(nameStr) : 0;
25765
    }
25766
25767
    idx = nameASN_Length;
25768
    for (i = 0; i < NAME_ENTRIES; i++) {
25769
        int type = GetCertNameId(i);
25770
25771
    #ifdef WOLFSSL_MULTI_ATTRIB
25772
        j = -1;
25773
        /* Put DomainComponents before OrgUnitName. */
25774
        while (FindMultiAttrib(name, type, &j)) {
25775
            if (dataASN != NULL && namesASN != NULL) {
25776
                if (idx > maxIdx - (int)rdnASN_Length) {
25777
                    WOLFSSL_MSG("Wanted to write more ASN than allocated");
25778
                    ret = BUFFER_E;
25779
                    break;
25780
                }
25781
                /* Copy data into dynamic vars. */
25782
                SetRdnItems(namesASN + idx, dataASN + idx, dcOid,
25783
                    sizeof(dcOid), name->name[j].type,
25784
                    (byte*)name->name[j].value, name->name[j].sz);
25785
            }
25786
            idx += rdnASN_Length;
25787
        }
25788
        if (ret != 0)
25789
            break;
25790
    #endif
25791
25792
        if (nameLen[i] > 0) {
25793
            if (dataASN != NULL) {
25794
                if (idx > maxIdx - (int)rdnASN_Length) {
25795
                    WOLFSSL_MSG("Wanted to write more ASN than allocated");
25796
                    ret = BUFFER_E;
25797
                    break;
25798
                }
25799
                /* Write out first instance of attribute type. */
25800
                if (type == ASN_EMAIL_NAME) {
25801
                    /* Copy email data into dynamic vars. */
25802
                    SetRdnItems(namesASN + idx, dataASN + idx, attrEmailOid,
25803
                        sizeof(attrEmailOid), ASN_IA5_STRING,
25804
                        (const byte*)GetOneCertName(name, i), nameLen[i]);
25805
                }
25806
                else if (type == ASN_USER_ID) {
25807
                    /* Copy userID data into dynamic vars. */
25808
                    SetRdnItems(namesASN + idx, dataASN + idx, uidOid,
25809
                        sizeof(uidOid), GetNameType(name, i),
25810
                        (const byte*)GetOneCertName(name, i), nameLen[i]);
25811
                }
25812
                else if (type == ASN_CUSTOM_NAME) {
25813
                #ifdef WOLFSSL_CUSTOM_OID
25814
                    SetRdnItems(namesASN + idx, dataASN + idx, name->custom.oid,
25815
                        name->custom.oidSz, name->custom.enc,
25816
                        name->custom.val, name->custom.valSz);
25817
                #endif
25818
                }
25819
                else {
25820
                    /* Copy name data into dynamic vars. */
25821
                    SetRdnItems(namesASN + idx, dataASN + idx, nameOid[i],
25822
                        NAME_OID_SZ, GetNameType(name, i),
25823
                        (const byte*)GetOneCertName(name, i), nameLen[i]);
25824
                }
25825
            }
25826
            idx += rdnASN_Length;
25827
        }
25828
25829
    #ifdef WOLFSSL_MULTI_ATTRIB
25830
        j = -1;
25831
        /* Write all other attributes of this type. */
25832
        while (FindMultiAttrib(name, type, &j)) {
25833
            if (dataASN != NULL && namesASN != NULL) {
25834
                if (idx > maxIdx - (int)rdnASN_Length) {
25835
                    WOLFSSL_MSG("Wanted to write more ASN than allocated");
25836
                    ret = BUFFER_E;
25837
                    break;
25838
                }
25839
                /* Copy data into dynamic vars. */
25840
                SetRdnItems(namesASN + idx, dataASN + idx, nameOid[i],
25841
                    NAME_OID_SZ, name->name[j].type,
25842
                    (byte*)name->name[j].value, name->name[j].sz);
25843
            }
25844
            idx += rdnASN_Length;
25845
        }
25846
        if (ret != 0)
25847
            break;
25848
    #endif
25849
    }
25850
    if (ret == 0)
25851
        ret = idx;
25852
    return ret;
25853
}
25854
#endif
25855
25856
/* encode CertName into output, return total bytes written */
25857
int SetNameEx(byte* output, word32 outputSz, CertName* name, void* heap)
25858
{
25859
#ifndef WOLFSSL_ASN_TEMPLATE
25860
    int ret;
25861
    int totalBytes = 0, i, idx;
25862
#ifdef WOLFSSL_SMALL_STACK
25863
    EncodedName* names = NULL;
25864
#else
25865
    EncodedName  names[NAME_ENTRIES];
25866
#endif
25867
#ifdef WOLFSSL_MULTI_ATTRIB
25868
    EncodedName addNames[CTC_MAX_ATTRIB];
25869
    int j, type;
25870
#endif
25871
25872
    if (output == NULL || name == NULL)
25873
        return BAD_FUNC_ARG;
25874
25875
    if (outputSz < 3)
25876
        return BUFFER_E;
25877
25878
#ifdef WOLFSSL_SMALL_STACK
25879
    names = (EncodedName*)XMALLOC(sizeof(EncodedName) * NAME_ENTRIES, NULL,
25880
                                                       DYNAMIC_TYPE_TMP_BUFFER);
25881
    if (names == NULL)
25882
        return MEMORY_E;
25883
#endif
25884
25885
    for (i = 0; i < NAME_ENTRIES; i++) {
25886
        const char* nameStr = GetOneCertName(name, i);
25887
25888
        ret = EncodeName(&names[i], nameStr, GetNameType(name, i),
25889
                          GetCertNameId(i), ASN_IA5_STRING, name);
25890
        if (ret < 0) {
25891
        #ifdef WOLFSSL_SMALL_STACK
25892
            XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
25893
        #endif
25894
            WOLFSSL_MSG("EncodeName failed");
25895
            return BUFFER_E;
25896
        }
25897
        totalBytes += ret;
25898
    }
25899
#ifdef WOLFSSL_MULTI_ATTRIB
25900
    for (i = 0; i < CTC_MAX_ATTRIB; i++) {
25901
        if (name->name[i].sz > 0) {
25902
            ret = EncodeName(&addNames[i], name->name[i].value,
25903
                        (byte)name->name[i].type, name->name[i].id,
25904
                        ASN_IA5_STRING, NULL);
25905
            if (ret < 0) {
25906
            #ifdef WOLFSSL_SMALL_STACK
25907
                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
25908
            #endif
25909
                WOLFSSL_MSG("EncodeName on multiple attributes failed");
25910
                return BUFFER_E;
25911
            }
25912
            totalBytes += ret;
25913
        }
25914
        else {
25915
            addNames[i].used = 0;
25916
        }
25917
    }
25918
#endif /* WOLFSSL_MULTI_ATTRIB */
25919
25920
    /* header */
25921
    idx = SetSequence(totalBytes, output);
25922
    totalBytes += idx;
25923
    if (totalBytes > WC_ASN_NAME_MAX) {
25924
#ifdef WOLFSSL_SMALL_STACK
25925
        XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
25926
#endif
25927
        WOLFSSL_MSG("Total Bytes is greater than WC_ASN_NAME_MAX");
25928
        return BUFFER_E;
25929
    }
25930
25931
    for (i = 0; i < NAME_ENTRIES; i++) {
25932
    #ifdef WOLFSSL_MULTI_ATTRIB
25933
        type = GetCertNameId(i);
25934
        for (j = 0; j < CTC_MAX_ATTRIB; j++) {
25935
            if (name->name[j].sz > 0 && type == name->name[j].id) {
25936
                if (outputSz < (word32)(idx+addNames[j].totalLen)) {
25937
                #ifdef WOLFSSL_SMALL_STACK
25938
                    XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
25939
                #endif
25940
                    WOLFSSL_MSG("Not enough space left for DC value");
25941
                    return BUFFER_E;
25942
                }
25943
25944
                XMEMCPY(output + idx, addNames[j].encoded,
25945
                        addNames[j].totalLen);
25946
                idx += addNames[j].totalLen;
25947
            }
25948
        }
25949
    #endif /* WOLFSSL_MULTI_ATTRIB */
25950
25951
        if (names[i].used) {
25952
            if (outputSz < (word32)(idx+names[i].totalLen)) {
25953
#ifdef WOLFSSL_SMALL_STACK
25954
                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
25955
#endif
25956
                return BUFFER_E;
25957
            }
25958
25959
            XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
25960
            idx += names[i].totalLen;
25961
        }
25962
    }
25963
25964
#ifdef WOLFSSL_SMALL_STACK
25965
    XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
25966
#endif
25967
    (void)heap;
25968
25969
    return totalBytes;
25970
#else
25971
    /* TODO: consider calculating size of entries, putting length into
25972
     * SEQUENCE, encode SEQUENCE, encode entries into buffer.  */
25973
    ASNSetData* dataASN = NULL; /* Can't use DECL_ASNSETDATA. Always dynamic. */
25974
    ASNItem*    namesASN = NULL;
25975
    int         items = 0;
25976
    int         ret = 0;
25977
    int         sz = 0;
25978
25979
    /* Calculate length of name entries and size for allocating. */
25980
    ret = SetNameRdnItems(NULL, NULL, 0, name);
25981
    if (ret > 0) {
25982
        items = ret;
25983
        ret = 0;
25984
    }
25985
25986
    /* Allocate dynamic data items. */
25987
    dataASN = (ASNSetData*)XMALLOC(items * sizeof(ASNSetData), heap,
25988
                                   DYNAMIC_TYPE_TMP_BUFFER);
25989
    if (dataASN == NULL) {
25990
        ret = MEMORY_E;
25991
    }
25992
    else {
25993
        /* Allocate dynamic ASN.1 template items. */
25994
        namesASN = (ASNItem*)XMALLOC(items * sizeof(ASNItem), heap,
25995
                                     DYNAMIC_TYPE_TMP_BUFFER);
25996
        if (namesASN == NULL) {
25997
            ret = MEMORY_E;
25998
        }
25999
    }
26000
26001
    if (ret == 0) {
26002
        /* Clear the dynamic data. */
26003
        XMEMSET(dataASN, 0, items * sizeof(ASNSetData));
26004
        /* Copy in the outer sequence. */
26005
        XMEMCPY(namesASN, nameASN, sizeof(nameASN));
26006
26007
        ret = SetNameRdnItems(dataASN, namesASN, items, name);
26008
        if (ret == items)
26009
            ret = 0;
26010
        else if (ret > 0) {
26011
            WOLFSSL_MSG("SetNameRdnItems returned different length");
26012
            ret = BUFFER_E;
26013
        }
26014
    }
26015
    if (ret == 0) {
26016
        /* Calculate size of encoding. */
26017
        ret = SizeASN_Items(namesASN, dataASN, items, &sz);
26018
    }
26019
    /* Check buffer size if passed in. */
26020
    if (ret == 0 && output != NULL && sz > (int)outputSz) {
26021
        ret = BUFFER_E;
26022
    }
26023
    if (ret == 0) {
26024
        if (output != NULL) {
26025
            /* Encode Name. */
26026
            ret = SetASN_Items(namesASN, dataASN, items, output);
26027
        }
26028
        else {
26029
            /* Return the encoding size. */
26030
            ret = sz;
26031
        }
26032
    }
26033
26034
    if (namesASN != NULL)
26035
        XFREE(namesASN, heap, DYNAMIC_TYPE_TMP_BUFFER);
26036
    if (dataASN != NULL)
26037
        XFREE(dataASN, heap, DYNAMIC_TYPE_TMP_BUFFER);
26038
    (void)heap;
26039
    return ret;
26040
#endif
26041
}
26042
int SetName(byte* output, word32 outputSz, CertName* name)
26043
{
26044
    return SetNameEx(output, outputSz, name, NULL);
26045
}
26046
26047
#ifdef WOLFSSL_ASN_TEMPLATE
26048
static int EncodePublicKey(int keyType, byte* output, int outLen,
26049
                           RsaKey* rsaKey, ecc_key* eccKey,
26050
                           ed25519_key* ed25519Key, ed448_key* ed448Key,
26051
                           DsaKey* dsaKey)
26052
{
26053
    int ret = 0;
26054
26055
    (void)outLen;
26056
    (void)rsaKey;
26057
    (void)eccKey;
26058
    (void)ed25519Key;
26059
    (void)ed448Key;
26060
    (void)dsaKey;
26061
26062
    switch (keyType) {
26063
    #ifndef NO_RSA
26064
        case RSA_KEY:
26065
            ret = SetRsaPublicKey(output, rsaKey, outLen, 1);
26066
            if (ret <= 0) {
26067
                ret = PUBLIC_KEY_E;
26068
            }
26069
            break;
26070
    #endif
26071
    #ifdef HAVE_ECC
26072
        case ECC_KEY:
26073
            ret = SetEccPublicKey(output, eccKey, outLen, 1, 0);
26074
            if (ret <= 0) {
26075
                ret = PUBLIC_KEY_E;
26076
            }
26077
            break;
26078
    #endif /* HAVE_ECC */
26079
    #ifdef HAVE_ED25519
26080
        case ED25519_KEY:
26081
            ret = wc_Ed25519PublicKeyToDer(ed25519Key, output, outLen, 1);
26082
            if (ret <= 0) {
26083
                ret = PUBLIC_KEY_E;
26084
            }
26085
            break;
26086
    #endif
26087
    #ifdef HAVE_ED448
26088
        case ED448_KEY:
26089
            ret = wc_Ed448PublicKeyToDer(ed448Key, output, outLen, 1);
26090
            if (ret <= 0) {
26091
                ret = PUBLIC_KEY_E;
26092
            }
26093
            break;
26094
    #endif
26095
        default:
26096
            ret = PUBLIC_KEY_E;
26097
            break;
26098
    }
26099
26100
    return ret;
26101
}
26102
26103
/* ASN.1 template for certificate extensions.
26104
 * X.509: RFC 5280, 4.1 - Basic Certificate Fields.
26105
 * All extensions supported for encoding are described.
26106
 */
26107
static const ASNItem static_certExtsASN[] = {
26108
            /* Basic Constraints Extension - 4.2.1.9 */
26109
/* BC_SEQ        */    { 0, ASN_SEQUENCE, 1, 1, 0 },
26110
/* BC_OID        */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
26111
/* BC_STR        */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
26112
/* BC_STR_SEQ    */            { 2, ASN_SEQUENCE, 1, 1, 0 },
26113
                                                   /* cA */
26114
/* BC_CA         */                { 3, ASN_BOOLEAN, 0, 0, 0 },
26115
                                                   /* pathLenConstraint */
26116
/* BC_PATHLEN    */                { 3, ASN_INTEGER, 0, 0, 1 },
26117
                                       /* Subject Alternative Name - 4.2.1.6  */
26118
/* SAN_SEQ       */    { 0, ASN_SEQUENCE, 1, 1, 0 },
26119
/* SAN_OID       */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
26120
/* SAN_CRIT      */        { 1, ASN_BOOLEAN, 0, 0, 0 },
26121
/* SAN_STR       */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
26122
            /* Subject Key Identifier - 4.2.1.2 */
26123
/* SKID_SEQ      */    { 0, ASN_SEQUENCE, 1, 1, 0 },
26124
/* SKID_OID      */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
26125
/* SKID_STR      */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
26126
/* SKID_KEYID    */            { 2, ASN_OCTET_STRING, 0, 0, 0 },
26127
                                       /* Authority Key Identifier - 4.2.1.1 */
26128
/* AKID_SEQ      */    { 0, ASN_SEQUENCE, 1, 1, 0 },
26129
/* AKID_OID      */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
26130
/* AKID_STR      */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
26131
/* AKID_STR_SEQ, */            { 2, ASN_SEQUENCE, 1, 1, 0 },
26132
/* AKID_KEYID    */                { 3, ASN_CONTEXT_SPECIFIC | 0, 0, 0, 0 },
26133
                                       /* Key Usage - 4.2.1.3 */
26134
/* KU_SEQ        */    { 0, ASN_SEQUENCE, 1, 1, 0 },
26135
/* KU_OID        */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
26136
/* KU_CRIT       */        { 1, ASN_BOOLEAN, 0, 0, 0 },
26137
/* KU_STR        */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
26138
/* KU_USAGE      */            { 2, ASN_BIT_STRING, 0, 0, 0 },
26139
                                       /* Extended Key Usage - 4,2,1,12 */
26140
/* EKU_SEQ       */    { 0, ASN_SEQUENCE, 1, 1, 0 },
26141
/* EKU_OID       */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
26142
/* EKU_STR       */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
26143
                                       /* Certificate Policies - 4.2.1.4 */
26144
/* POLICIES_SEQ, */    { 0, ASN_SEQUENCE, 1, 1, 0 },
26145
/* POLICIES_OID, */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
26146
/* POLICIES_STR, */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
26147
/* POLICIES_INFO */            { 2, ASN_SEQUENCE, 1, 0, 0 },
26148
                                       /* Netscape Certificate Type */
26149
/* NSTYPE_SEQ    */    { 0, ASN_SEQUENCE, 1, 1, 0 },
26150
/* NSTYPE_OID    */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
26151
/* NSTYPE_STR    */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
26152
/* NSTYPE_USAGE, */            { 2, ASN_BIT_STRING, 0, 0, 0 },
26153
/* CRLINFO_SEQ   */    { 0, ASN_SEQUENCE, 1, 1, 0 },
26154
/* CRLINFO_OID   */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
26155
/* CRLINFO_STR   */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
26156
/* CUSTOM_SEQ    */    { 0, ASN_SEQUENCE, 1, 1, 0 },
26157
/* CUSTOM_OID    */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
26158
/* CUSTOM_STR    */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
26159
};
26160
enum {
26161
    CERTEXTSASN_IDX_BC_SEQ = 0,
26162
    CERTEXTSASN_IDX_BC_OID,
26163
    CERTEXTSASN_IDX_BC_STR,
26164
    CERTEXTSASN_IDX_BC_STR_SEQ,
26165
    CERTEXTSASN_IDX_BC_CA,
26166
    CERTEXTSASN_IDX_BC_PATHLEN,
26167
    CERTEXTSASN_IDX_SAN_SEQ,
26168
    CERTEXTSASN_IDX_SAN_OID,
26169
    CERTEXTSASN_IDX_SAN_CRIT,
26170
    CERTEXTSASN_IDX_SAN_STR,
26171
    CERTEXTSASN_IDX_SKID_SEQ,
26172
    CERTEXTSASN_IDX_SKID_OID,
26173
    CERTEXTSASN_IDX_SKID_STR,
26174
    CERTEXTSASN_IDX_SKID_KEYID,
26175
    CERTEXTSASN_IDX_AKID_SEQ,
26176
    CERTEXTSASN_IDX_AKID_OID,
26177
    CERTEXTSASN_IDX_AKID_STR,
26178
    CERTEXTSASN_IDX_AKID_STR_SEQ,
26179
    CERTEXTSASN_IDX_AKID_KEYID,
26180
    CERTEXTSASN_IDX_KU_SEQ,
26181
    CERTEXTSASN_IDX_KU_OID,
26182
    CERTEXTSASN_IDX_KU_CRIT,
26183
    CERTEXTSASN_IDX_KU_STR,
26184
    CERTEXTSASN_IDX_KU_USAGE,
26185
    CERTEXTSASN_IDX_EKU_SEQ,
26186
    CERTEXTSASN_IDX_EKU_OID,
26187
    CERTEXTSASN_IDX_EKU_STR,
26188
    CERTEXTSASN_IDX_POLICIES_SEQ,
26189
    CERTEXTSASN_IDX_POLICIES_OID,
26190
    CERTEXTSASN_IDX_POLICIES_STR,
26191
    CERTEXTSASN_IDX_POLICIES_INFO,
26192
    CERTEXTSASN_IDX_NSTYPE_SEQ,
26193
    CERTEXTSASN_IDX_NSTYPE_OID,
26194
    CERTEXTSASN_IDX_NSTYPE_STR,
26195
    CERTEXTSASN_IDX_NSTYPE_USAGE,
26196
    CERTEXTSASN_IDX_CRLINFO_SEQ,
26197
    CERTEXTSASN_IDX_CRLINFO_OID,
26198
    CERTEXTSASN_IDX_CRLINFO_STR,
26199
    CERTEXTSASN_IDX_CUSTOM_SEQ,
26200
    CERTEXTSASN_IDX_CUSTOM_OID,
26201
    CERTEXTSASN_IDX_CUSTOM_STR,
26202
    CERTEXTSASN_IDX_START_CUSTOM,
26203
26204
};
26205
26206
/* Number of items in ASN.1 template for certificate extensions. We multiply
26207
 * by 4 because there are 4 things (seq, OID, crit flag, octet string). */
26208
#define certExtsASN_Length ((sizeof(static_certExtsASN) / sizeof(ASNItem)) \
26209
                            + (NUM_CUSTOM_EXT * 4))
26210
26211
static const ASNItem customExtASN[] = {
26212
/* CUSTOM_SEQ    */    { 0, ASN_SEQUENCE, 1, 1, 0 },
26213
/* CUSTOM_OID    */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
26214
/* CUSTOM_CRIT   */        { 1, ASN_BOOLEAN, 0, 0, 0 },
26215
/* CUSTOM_STR    */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
26216
};
26217
26218
static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz,
26219
                            int forRequest)
26220
{
26221
    DECL_ASNSETDATA(dataASN, certExtsASN_Length);
26222
    int sz;
26223
    int ret = 0;
26224
    int i = 0;
26225
    static const byte bcOID[]   = { 0x55, 0x1d, 0x13 };
26226
#ifdef WOLFSSL_ALT_NAMES
26227
    static const byte sanOID[]  = { 0x55, 0x1d, 0x11 };
26228
#endif
26229
#ifdef WOLFSSL_CERT_EXT
26230
    static const byte skidOID[] = { 0x55, 0x1d, 0x0e };
26231
    static const byte akidOID[] = { 0x55, 0x1d, 0x23 };
26232
    static const byte kuOID[]   = { 0x55, 0x1d, 0x0f };
26233
    static const byte ekuOID[]  = { 0x55, 0x1d, 0x25 };
26234
    static const byte cpOID[]   = { 0x55, 0x1d, 0x20 };
26235
    static const byte nsCertOID[] = { 0x60, 0x86, 0x48, 0x01,
26236
                                      0x86, 0xF8, 0x42, 0x01, 0x01 };
26237
    static const byte crlInfoOID[] = { 0x55, 0x1D, 0x1F };
26238
#endif
26239
26240
#ifdef WOLFSSL_SMALL_STACK
26241
#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_CERT_EXT)
26242
    byte *encodedOids;
26243
#endif
26244
    ASNItem *certExtsASN = (ASNItem *)XMALLOC(certExtsASN_Length *
26245
                                              sizeof(ASNItem), cert->heap,
26246
                                              DYNAMIC_TYPE_TMP_BUFFER);
26247
    if (certExtsASN == NULL) {
26248
        return MEMORY_E;
26249
    }
26250
26251
#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_CERT_EXT)
26252
    encodedOids = (byte *)XMALLOC(NUM_CUSTOM_EXT * MAX_OID_SZ, cert->heap,
26253
                                  DYNAMIC_TYPE_TMP_BUFFER);
26254
    if (encodedOids == NULL) {
26255
        XFREE(certExtsASN, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
26256
        return MEMORY_E;
26257
    }
26258
#endif
26259
#else
26260
    ASNItem certExtsASN[certExtsASN_Length];
26261
#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_CERT_EXT)
26262
    byte encodedOids[NUM_CUSTOM_EXT * MAX_OID_SZ];
26263
#endif
26264
#endif
26265
26266
    /* Clone static_certExtsASN into a certExtsASN and then fill the rest of it
26267
     * with (NUM_CUSTOM_EXT*4) more ASNItems specifying extensions. See comment
26268
     * above definition of certExtsASN_Length. */
26269
    XMEMCPY(certExtsASN, static_certExtsASN, sizeof(static_certExtsASN));
26270
    for (i = sizeof(static_certExtsASN) / sizeof(ASNItem);
26271
         i < (int)certExtsASN_Length; i += 4) {
26272
        XMEMCPY(&certExtsASN[i], customExtASN, sizeof(customExtASN));
26273
    }
26274
26275
    (void)forRequest;
26276
26277
    CALLOC_ASNSETDATA(dataASN, certExtsASN_Length, ret, cert->heap);
26278
26279
    if (ret == 0) {
26280
        if (cert->isCA) {
26281
            /* Set Basic Constraints to be a Certificate Authority. */
26282
            SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_BC_CA], 1);
26283
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_BC_OID], bcOID, sizeof(bcOID));
26284
            if (cert->pathLenSet
26285
            #ifdef WOLFSSL_CERT_EXT
26286
                && ((cert->keyUsage & KEYUSE_KEY_CERT_SIGN) || (!cert->keyUsage))
26287
            #endif
26288
            ) {
26289
                SetASN_Int8Bit(&dataASN[CERTEXTSASN_IDX_BC_PATHLEN],
26290
                        cert->pathLen);
26291
            }
26292
            else {
26293
                dataASN[CERTEXTSASN_IDX_BC_PATHLEN].noOut = 1;
26294
            }
26295
        }
26296
        else if (cert->basicConstSet) {
26297
            /* Set Basic Constraints to be a non Certificate Authority. */
26298
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_BC_OID], bcOID, sizeof(bcOID));
26299
            dataASN[CERTEXTSASN_IDX_BC_CA].noOut = 1;
26300
            dataASN[CERTEXTSASN_IDX_BC_PATHLEN].noOut = 1;
26301
        }
26302
        else {
26303
            /* Don't write out Basic Constraints extension items. */
26304
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_BC_SEQ,
26305
                    CERTEXTSASN_IDX_BC_PATHLEN);
26306
        }
26307
    #ifdef WOLFSSL_ALT_NAMES
26308
        if (!forRequest && cert->altNamesSz > 0) {
26309
            /* Set Subject Alternative Name OID and data. */
26310
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_SAN_OID],
26311
                    sanOID, sizeof(sanOID));
26312
            if (cert->altNamesCrit) {
26313
                SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_SAN_CRIT], 1);
26314
            }
26315
            else {
26316
                dataASN[CERTEXTSASN_IDX_SAN_CRIT].noOut = 1;
26317
            }
26318
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_SAN_STR],
26319
                    cert->altNames, cert->altNamesSz);
26320
        }
26321
        else
26322
    #endif
26323
        {
26324
            /* Don't write out Subject Alternative Name extension items. */
26325
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_SAN_SEQ,
26326
                    CERTEXTSASN_IDX_SAN_STR);
26327
        }
26328
    #ifdef WOLFSSL_CERT_EXT
26329
        if (cert->skidSz > 0) {
26330
            /* Set Subject Key Identifier OID and data. */
26331
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_SKID_OID],
26332
                    skidOID, sizeof(skidOID));
26333
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_SKID_KEYID],
26334
                    cert->skid, cert->skidSz);
26335
        }
26336
        else
26337
    #endif
26338
        {
26339
            /* Don't write out Subject Key Identifier extension items. */
26340
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_SKID_SEQ,
26341
                    CERTEXTSASN_IDX_SKID_KEYID);
26342
        }
26343
    #ifdef WOLFSSL_CERT_EXT
26344
        if (cert->akidSz > 0) {
26345
            /* Set Authority Key Identifier OID and data. */
26346
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_AKID_OID],
26347
                    akidOID, sizeof(akidOID));
26348
        #ifdef WOLFSSL_AKID_NAME
26349
            if (cert->rawAkid) {
26350
                SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_AKID_STR],
26351
                        cert->akid, cert->akidSz);
26352
                /* cert->akid contains the internal ext structure */
26353
                SetASNItem_NoOutBelow(dataASN, certExtsASN,
26354
                        CERTEXTSASN_IDX_AKID_STR, certExtsASN_Length);
26355
            }
26356
            else
26357
        #endif
26358
            {
26359
                SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_AKID_KEYID],
26360
                        cert->akid, cert->akidSz);
26361
            }
26362
        }
26363
        else
26364
    #endif
26365
        {
26366
            /* Don't write out Authority Key Identifier extension items. */
26367
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_AKID_SEQ,
26368
                    CERTEXTSASN_IDX_AKID_KEYID);
26369
        }
26370
    #ifdef WOLFSSL_CERT_EXT
26371
        if (cert->keyUsage != 0) {
26372
            /* Set Key Usage OID, critical and value. */
26373
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_KU_OID],
26374
                    kuOID, sizeof(kuOID));
26375
            SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_KU_CRIT], 1);
26376
            SetASN_Int16Bit(&dataASN[CERTEXTSASN_IDX_KU_USAGE],
26377
                    cert->keyUsage);
26378
        }
26379
        else
26380
    #endif
26381
        {
26382
            /* Don't write out Key Usage extension items. */
26383
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_KU_SEQ,
26384
                    CERTEXTSASN_IDX_KU_USAGE);
26385
        }
26386
    #ifdef WOLFSSL_CERT_EXT
26387
        if (cert->extKeyUsage != 0) {
26388
            /* Calculate size of Extended Key Usage data. */
26389
            sz = SetExtKeyUsage(cert, NULL, 0, cert->extKeyUsage);
26390
            if (sz <= 0) {
26391
                ret = KEYUSAGE_E;
26392
            }
26393
            /* Set Extended Key Usage OID and data. */
26394
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_EKU_OID],
26395
                    ekuOID, sizeof(ekuOID));
26396
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_EKU_STR],
26397
                    NULL, sz);
26398
        }
26399
        else
26400
    #endif
26401
        {
26402
            /* Don't write out Extended Key Usage extension items. */
26403
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_EKU_SEQ,
26404
                    CERTEXTSASN_IDX_EKU_STR);
26405
        }
26406
26407
    #ifdef WOLFSSL_CERT_EXT
26408
        if ((!forRequest) && (cert->certPoliciesNb > 0)) {
26409
            /* Calculate size of certificate policies. */
26410
            sz = SetCertificatePolicies(NULL, 0, cert->certPolicies,
26411
                    cert->certPoliciesNb, cert->heap);
26412
            if (sz > 0) {
26413
                /* Set Certificate Policies OID. */
26414
                SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_POLICIES_OID],
26415
                        cpOID, sizeof(cpOID));
26416
                /* Make space for data. */
26417
                SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_POLICIES_INFO],
26418
                        NULL, sz);
26419
            }
26420
            else {
26421
                ret = CERTPOLICIES_E;
26422
            }
26423
        }
26424
        else
26425
    #endif
26426
        {
26427
            /* Don't write out Certificate Policies extension items. */
26428
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_POLICIES_SEQ,
26429
                    CERTEXTSASN_IDX_POLICIES_INFO);
26430
        }
26431
    #if defined(WOLFSSL_CERT_EXT) && !defined(IGNORE_NETSCAPE_CERT_TYPE)
26432
        /* Netscape Certificate Type */
26433
        if (cert->nsCertType != 0) {
26434
            /* Set Netscape Certificate Type OID and data. */
26435
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_NSTYPE_OID],
26436
                    nsCertOID, sizeof(nsCertOID));
26437
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_NSTYPE_USAGE],
26438
                    &cert->nsCertType, 1);
26439
        }
26440
        else
26441
    #endif
26442
        {
26443
            /* Don't write out Netscape Certificate Type. */
26444
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_NSTYPE_SEQ,
26445
                    CERTEXTSASN_IDX_NSTYPE_USAGE);
26446
        }
26447
    #ifdef WOLFSSL_CERT_EXT
26448
        if (cert->crlInfoSz > 0) {
26449
            /* Set CRL Distribution Points OID and data. */
26450
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_CRLINFO_OID],
26451
                    crlInfoOID, sizeof(crlInfoOID));
26452
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_CRLINFO_STR],
26453
                    cert->crlInfo, cert->crlInfoSz);
26454
        }
26455
        else
26456
    #endif
26457
        {
26458
            /* Don't write out CRL Distribution Points. */
26459
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_CRLINFO_SEQ,
26460
                    CERTEXTSASN_IDX_CRLINFO_STR);
26461
        }
26462
26463
    #if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CUSTOM_OID)
26464
        /* encode a custom oid and value */
26465
        if (cert->extCustom.oidSz > 0) {
26466
            /* Set CRL Distribution Points OID and data. */
26467
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_CUSTOM_OID],
26468
                    cert->extCustom.oid, cert->extCustom.oidSz);
26469
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_CUSTOM_STR],
26470
                    cert->extCustom.val, cert->extCustom.valSz);
26471
        }
26472
        else
26473
    #endif
26474
        {
26475
            /* Don't write out custom OID. */
26476
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_CUSTOM_SEQ,
26477
                    CERTEXTSASN_IDX_CUSTOM_STR);
26478
        }
26479
26480
        i = 0;
26481
    #if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CUSTOM_OID)
26482
        for (; i < cert->customCertExtCount; i++) {
26483
             int idx = CERTEXTSASN_IDX_START_CUSTOM + (i * 4);
26484
             word32 encodedOidSz = MAX_OID_SZ;
26485
             idx++; /* Skip one for for SEQ. */
26486
             /* EncodePolicyOID() will never return error since we parsed this
26487
              * OID when it was set. */
26488
             EncodePolicyOID(&encodedOids[i * MAX_OID_SZ], &encodedOidSz,
26489
                             cert->customCertExt[i].oid, NULL);
26490
             SetASN_Buffer(&dataASN[idx], &encodedOids[i * MAX_OID_SZ],
26491
                           encodedOidSz);
26492
             idx++;
26493
             if (cert->customCertExt[i].crit) {
26494
                 SetASN_Boolean(&dataASN[idx], 1);
26495
             } else {
26496
                 dataASN[idx].noOut = 1;
26497
             }
26498
             idx++;
26499
             SetASN_Buffer(&dataASN[idx], cert->customCertExt[i].val,
26500
                           cert->customCertExt[i].valSz);
26501
        }
26502
    #endif
26503
26504
        while (i < NUM_CUSTOM_EXT) {
26505
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_START_CUSTOM + (i * 4),
26506
                             CERTEXTSASN_IDX_START_CUSTOM + (i * 4) + 3);
26507
            i++;
26508
        }
26509
    }
26510
26511
    if (ret == 0) {
26512
        /* Calculate size of encoded extensions. */
26513
        ret = SizeASN_Items(certExtsASN, dataASN, certExtsASN_Length, &sz);
26514
    }
26515
    if (ret == 0) {
26516
        /* Only SEQUENCE - don't encode extensions. */
26517
        if (sz == 2) {
26518
            sz = 0;
26519
        }
26520
        /* Check buffer is big enough. */
26521
        else if ((output != NULL) && (sz > (int)maxSz)) {
26522
            ret = BUFFER_E;
26523
        }
26524
    }
26525
26526
    if ((ret == 0) && (output != NULL) && (sz > 0)) {
26527
        /* Encode certificate extensions into buffer. */
26528
        SetASN_Items(certExtsASN, dataASN, certExtsASN_Length, output);
26529
26530
    #ifdef WOLFSSL_CERT_EXT
26531
        if (cert->extKeyUsage != 0){
26532
            /* Encode Extended Key Usage into space provided. */
26533
            if (SetExtKeyUsage(cert,
26534
                    (byte*)dataASN[CERTEXTSASN_IDX_EKU_STR].data.buffer.data,
26535
                    dataASN[CERTEXTSASN_IDX_EKU_STR].data.buffer.length,
26536
                    cert->extKeyUsage) <= 0) {
26537
                ret = KEYUSAGE_E;
26538
            }
26539
        }
26540
        if ((!forRequest) && (cert->certPoliciesNb > 0)) {
26541
            /* Encode Certificate Policies into space provided. */
26542
            if (SetCertificatePolicies(
26543
                    (byte*)dataASN[CERTEXTSASN_IDX_POLICIES_INFO].data.buffer.data,
26544
                    dataASN[CERTEXTSASN_IDX_POLICIES_INFO].data.buffer.length,
26545
                    cert->certPolicies, cert->certPoliciesNb, cert->heap) <= 0) {
26546
                ret = CERTPOLICIES_E;
26547
            }
26548
        }
26549
    #endif
26550
    }
26551
    if (ret == 0) {
26552
        /* Return the encoding size. */
26553
        ret = sz;
26554
    }
26555
26556
    FREE_ASNSETDATA(dataASN, cert->heap);
26557
#ifdef WOLFSSL_SMALL_STACK
26558
#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_CERT_EXT)
26559
    XFREE(encodedOids, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
26560
#endif
26561
    XFREE(certExtsASN, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
26562
#endif
26563
26564
    return ret;
26565
}
26566
#endif /* WOLFSSL_ASN_TEMPLATE */
26567
26568
#ifndef WOLFSSL_ASN_TEMPLATE
26569
/* Set Date validity from now until now + daysValid
26570
 * return size in bytes written to output, 0 on error */
26571
/* TODO https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.5
26572
 * "MUST always encode certificate validity dates through the year 2049 as
26573
 *  UTCTime; certificate validity dates in 2050 or later MUST be encoded as
26574
 *  GeneralizedTime." */
26575
static int SetValidity(byte* output, int daysValid)
26576
{
26577
#ifndef NO_ASN_TIME
26578
    byte before[MAX_DATE_SIZE];
26579
    byte  after[MAX_DATE_SIZE];
26580
26581
    int beforeSz;
26582
    int afterSz;
26583
    int seqSz;
26584
26585
    time_t now;
26586
    time_t then;
26587
    struct tm* tmpTime;
26588
    struct tm* expandedTime;
26589
    struct tm localTime;
26590
26591
#if defined(NEED_TMP_TIME)
26592
    /* for use with gmtime_r */
26593
    struct tm tmpTimeStorage;
26594
    tmpTime = &tmpTimeStorage;
26595
#else
26596
    tmpTime = NULL;
26597
#endif
26598
    (void)tmpTime;
26599
26600
    now = wc_Time(0);
26601
26602
    /* before now */
26603
    before[0] = ASN_GENERALIZED_TIME;
26604
    beforeSz = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1;  /* gen tag */
26605
26606
    /* subtract 1 day of seconds for more compliance */
26607
    then = now - 86400;
26608
    expandedTime = XGMTIME(&then, tmpTime);
26609
    if (expandedTime == NULL) {
26610
        WOLFSSL_MSG("XGMTIME failed");
26611
        return 0;   /* error */
26612
    }
26613
    localTime = *expandedTime;
26614
26615
    /* adjust */
26616
    localTime.tm_year += 1900;
26617
    localTime.tm_mon +=    1;
26618
26619
    SetTime(&localTime, before + beforeSz);
26620
    beforeSz += ASN_GEN_TIME_SZ;
26621
26622
    after[0] = ASN_GENERALIZED_TIME;
26623
    afterSz  = SetLength(ASN_GEN_TIME_SZ, after + 1) + 1;  /* gen tag */
26624
26625
    /* add daysValid of seconds */
26626
    then = now + (daysValid * (time_t)86400);
26627
    expandedTime = XGMTIME(&then, tmpTime);
26628
    if (expandedTime == NULL) {
26629
        WOLFSSL_MSG("XGMTIME failed");
26630
        return 0;   /* error */
26631
    }
26632
    localTime = *expandedTime;
26633
26634
    /* adjust */
26635
    localTime.tm_year += 1900;
26636
    localTime.tm_mon  +=    1;
26637
26638
    SetTime(&localTime, after + afterSz);
26639
    afterSz += ASN_GEN_TIME_SZ;
26640
26641
    /* headers and output */
26642
    seqSz = SetSequence(beforeSz + afterSz, output);
26643
    XMEMCPY(output + seqSz, before, beforeSz);
26644
    XMEMCPY(output + seqSz + beforeSz, after, afterSz);
26645
26646
    return seqSz + beforeSz + afterSz;
26647
#else
26648
    (void)output;
26649
    (void)daysValid;
26650
    return NOT_COMPILED_IN;
26651
#endif
26652
}
26653
#else
26654
static int SetValidity(byte* before, byte* after, int daysValid)
26655
{
26656
    int ret = 0;
26657
    time_t now;
26658
    time_t then;
26659
    struct tm* tmpTime;
26660
    struct tm* expandedTime;
26661
    struct tm localTime;
26662
#if defined(NEED_TMP_TIME)
26663
    /* for use with gmtime_r */
26664
    struct tm tmpTimeStorage;
26665
    tmpTime = &tmpTimeStorage;
26666
#else
26667
    tmpTime = NULL;
26668
#endif
26669
    (void)tmpTime;
26670
26671
    now = wc_Time(0);
26672
26673
    /* subtract 1 day of seconds for more compliance */
26674
    then = now - 86400;
26675
    expandedTime = XGMTIME(&then, tmpTime);
26676
    if (expandedTime == NULL) {
26677
        WOLFSSL_MSG("XGMTIME failed");
26678
        ret = DATE_E;
26679
    }
26680
    if (ret == 0) {
26681
        localTime = *expandedTime;
26682
26683
        /* adjust */
26684
        localTime.tm_year += 1900;
26685
        localTime.tm_mon +=    1;
26686
26687
        SetTime(&localTime, before);
26688
26689
        /* add daysValid of seconds */
26690
        then = now + (daysValid * (time_t)86400);
26691
        expandedTime = XGMTIME(&then, tmpTime);
26692
        if (expandedTime == NULL) {
26693
            WOLFSSL_MSG("XGMTIME failed");
26694
            ret = DATE_E;
26695
        }
26696
    }
26697
    if (ret == 0) {
26698
        localTime = *expandedTime;
26699
26700
        /* adjust */
26701
        localTime.tm_year += 1900;
26702
        localTime.tm_mon  +=    1;
26703
26704
        SetTime(&localTime, after);
26705
    }
26706
26707
    return ret;
26708
}
26709
#endif /* WOLFSSL_ASN_TEMPLATE */
26710
26711
26712
#ifndef WOLFSSL_ASN_TEMPLATE
26713
/* encode info from cert into DER encoded format */
26714
static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
26715
                      WC_RNG* rng, DsaKey* dsaKey, ed25519_key* ed25519Key,
26716
                      ed448_key* ed448Key, falcon_key* falconKey,
26717
                      dilithium_key* dilithiumKey)
26718
{
26719
    int ret;
26720
26721
    if (cert == NULL || der == NULL || rng == NULL)
26722
        return BAD_FUNC_ARG;
26723
26724
    /* make sure at least one key type is provided */
26725
    if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL &&
26726
        dsaKey == NULL && ed448Key == NULL && falconKey == NULL &&
26727
        dilithiumKey == NULL) {
26728
        return PUBLIC_KEY_E;
26729
    }
26730
26731
    /* init */
26732
    XMEMSET(der, 0, sizeof(DerCert));
26733
26734
    /* version */
26735
    der->versionSz = SetMyVersion(cert->version, der->version, TRUE);
26736
26737
    /* serial number (must be positive) */
26738
    if (cert->serialSz == 0) {
26739
        /* generate random serial */
26740
        cert->serialSz = CTC_GEN_SERIAL_SZ;
26741
        ret = wc_RNG_GenerateBlock(rng, cert->serial, cert->serialSz);
26742
        if (ret != 0)
26743
            return ret;
26744
        /* Clear the top bit to avoid a negative value */
26745
        cert->serial[0] &= 0x7f;
26746
    }
26747
    der->serialSz = SetSerialNumber(cert->serial, cert->serialSz, der->serial,
26748
        sizeof(der->serial), CTC_SERIAL_SIZE);
26749
    if (der->serialSz < 0)
26750
        return der->serialSz;
26751
26752
    /* signature algo */
26753
    der->sigAlgoSz = SetAlgoID(cert->sigType, der->sigAlgo, oidSigType, 0);
26754
    if (der->sigAlgoSz <= 0)
26755
        return ALGO_ID_E;
26756
26757
    /* public key */
26758
#ifndef NO_RSA
26759
    if (cert->keyType == RSA_KEY) {
26760
        if (rsaKey == NULL)
26761
            return PUBLIC_KEY_E;
26762
        der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey,
26763
                                           sizeof(der->publicKey), 1);
26764
    }
26765
#endif
26766
26767
#ifdef HAVE_ECC
26768
    if (cert->keyType == ECC_KEY) {
26769
        if (eccKey == NULL)
26770
            return PUBLIC_KEY_E;
26771
        der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey,
26772
                                           sizeof(der->publicKey), 1, 0);
26773
    }
26774
#endif
26775
26776
#if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
26777
    if (cert->keyType == DSA_KEY) {
26778
        if (dsaKey == NULL)
26779
            return PUBLIC_KEY_E;
26780
        der->publicKeySz = wc_SetDsaPublicKey(der->publicKey, dsaKey,
26781
                                              sizeof(der->publicKey), 1);
26782
    }
26783
#endif
26784
26785
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
26786
    if (cert->keyType == ED25519_KEY) {
26787
        if (ed25519Key == NULL)
26788
            return PUBLIC_KEY_E;
26789
        der->publicKeySz = wc_Ed25519PublicKeyToDer(ed25519Key, der->publicKey,
26790
            (word32)sizeof(der->publicKey), 1);
26791
    }
26792
#endif
26793
26794
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
26795
    if (cert->keyType == ED448_KEY) {
26796
        if (ed448Key == NULL)
26797
            return PUBLIC_KEY_E;
26798
        der->publicKeySz = wc_Ed448PublicKeyToDer(ed448Key, der->publicKey,
26799
            (word32)sizeof(der->publicKey), 1);
26800
    }
26801
#endif
26802
26803
#if defined(HAVE_PQC)
26804
#if defined(HAVE_FALCON)
26805
    if ((cert->keyType == FALCON_LEVEL1_KEY) ||
26806
        (cert->keyType == FALCON_LEVEL5_KEY)) {
26807
        if (falconKey == NULL)
26808
            return PUBLIC_KEY_E;
26809
26810
        der->publicKeySz =
26811
            wc_Falcon_PublicKeyToDer(falconKey, der->publicKey,
26812
                                     (word32)sizeof(der->publicKey), 1);
26813
    }
26814
#endif /* HAVE_FALCON */
26815
#if defined(HAVE_DILITHIUM)
26816
    if ((cert->keyType == DILITHIUM_LEVEL2_KEY) ||
26817
        (cert->keyType == DILITHIUM_LEVEL3_KEY) ||
26818
        (cert->keyType == DILITHIUM_LEVEL5_KEY) ||
26819
        (cert->keyType == DILITHIUM_AES_LEVEL2_KEY) ||
26820
        (cert->keyType == DILITHIUM_AES_LEVEL3_KEY) ||
26821
        (cert->keyType == DILITHIUM_AES_LEVEL5_KEY)) {
26822
        if (dilithiumKey == NULL)
26823
            return PUBLIC_KEY_E;
26824
26825
        der->publicKeySz =
26826
            wc_Dilithium_PublicKeyToDer(dilithiumKey, der->publicKey,
26827
                                     (word32)sizeof(der->publicKey), 1);
26828
    }
26829
#endif /* HAVE_DILITHIUM */
26830
#endif /* HAVE_PQC */
26831
26832
    if (der->publicKeySz <= 0)
26833
        return PUBLIC_KEY_E;
26834
26835
    der->validitySz = 0;
26836
    /* copy date validity if already set in cert struct */
26837
    if (cert->beforeDateSz && cert->afterDateSz) {
26838
        der->validitySz = CopyValidity(der->validity, cert);
26839
        if (der->validitySz <= 0)
26840
            return DATE_E;
26841
    }
26842
26843
    /* set date validity using daysValid if not set already */
26844
    if (der->validitySz == 0) {
26845
        der->validitySz = SetValidity(der->validity, cert->daysValid);
26846
        if (der->validitySz <= 0)
26847
            return DATE_E;
26848
    }
26849
26850
    /* subject name */
26851
#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
26852
    if (XSTRLEN((const char*)cert->sbjRaw) > 0) {
26853
        /* Use the raw subject */
26854
        int idx;
26855
26856
        der->subjectSz = min(sizeof(der->subject),
26857
                (word32)XSTRLEN((const char*)cert->sbjRaw));
26858
        /* header */
26859
        idx = SetSequence(der->subjectSz, der->subject);
26860
        if (der->subjectSz + idx > (int)sizeof(der->subject)) {
26861
            return SUBJECT_E;
26862
        }
26863
26864
        XMEMCPY((char*)der->subject + idx, (const char*)cert->sbjRaw,
26865
                der->subjectSz);
26866
        der->subjectSz += idx;
26867
    }
26868
    else
26869
#endif
26870
    {
26871
        /* Use the name structure */
26872
        der->subjectSz = SetNameEx(der->subject, sizeof(der->subject),
26873
                &cert->subject, cert->heap);
26874
    }
26875
    if (der->subjectSz <= 0)
26876
        return SUBJECT_E;
26877
26878
    /* issuer name */
26879
#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
26880
    if (XSTRLEN((const char*)cert->issRaw) > 0) {
26881
        /* Use the raw issuer */
26882
        int idx;
26883
26884
        der->issuerSz = min(sizeof(der->issuer),
26885
                (word32)XSTRLEN((const char*)cert->issRaw));
26886
26887
        /* header */
26888
        idx = SetSequence(der->issuerSz, der->issuer);
26889
        if (der->issuerSz + idx > (int)sizeof(der->issuer)) {
26890
            return ISSUER_E;
26891
        }
26892
26893
        XMEMCPY((char*)der->issuer + idx, (const char*)cert->issRaw,
26894
                der->issuerSz);
26895
        der->issuerSz += idx;
26896
    }
26897
    else
26898
#endif
26899
    {
26900
        /* Use the name structure */
26901
        der->issuerSz = SetNameEx(der->issuer, sizeof(der->issuer),
26902
                cert->selfSigned ? &cert->subject : &cert->issuer, cert->heap);
26903
    }
26904
    if (der->issuerSz <= 0)
26905
        return ISSUER_E;
26906
26907
    /* set the extensions */
26908
    der->extensionsSz = 0;
26909
26910
    /* RFC 5280 : 4.2.1.9. Basic Constraints
26911
     * The pathLenConstraint field is meaningful only if the CA boolean is
26912
     * asserted and the key usage extension, if present, asserts the
26913
     * keyCertSign bit */
26914
    /* Set CA and path length */
26915
    if ((cert->isCA) && (cert->pathLenSet)
26916
#ifdef WOLFSSL_CERT_EXT
26917
        && ((cert->keyUsage & KEYUSE_KEY_CERT_SIGN) || (!cert->keyUsage))
26918
#endif
26919
        ) {
26920
        der->caSz = SetCaWithPathLen(der->ca, sizeof(der->ca), cert->pathLen);
26921
        if (der->caSz <= 0)
26922
            return CA_TRUE_E;
26923
26924
        der->extensionsSz += der->caSz;
26925
    }
26926
    /* Set CA */
26927
    else if (cert->isCA) {
26928
        der->caSz = SetCa(der->ca, sizeof(der->ca));
26929
        if (der->caSz <= 0)
26930
            return CA_TRUE_E;
26931
26932
        der->extensionsSz += der->caSz;
26933
    }
26934
    /* Set Basic Constraint */
26935
    else if (cert->basicConstSet) {
26936
        der->caSz = SetBC(der->ca, sizeof(der->ca));
26937
        if (der->caSz <= 0)
26938
            return EXTENSIONS_E;
26939
26940
        der->extensionsSz += der->caSz;
26941
    }
26942
    else
26943
        der->caSz = 0;
26944
26945
#ifdef WOLFSSL_ALT_NAMES
26946
    /* Alternative Name */
26947
    if (cert->altNamesSz) {
26948
        der->altNamesSz = SetAltNames(der->altNames, sizeof(der->altNames),
26949
                                      cert->altNames, cert->altNamesSz,
26950
                                      cert->altNamesCrit);
26951
        if (der->altNamesSz <= 0)
26952
            return ALT_NAME_E;
26953
26954
        der->extensionsSz += der->altNamesSz;
26955
    }
26956
    else
26957
        der->altNamesSz = 0;
26958
#endif
26959
26960
#ifdef WOLFSSL_CERT_EXT
26961
    /* SKID */
26962
    if (cert->skidSz) {
26963
        /* check the provided SKID size */
26964
        if (cert->skidSz > (int)min(CTC_MAX_SKID_SIZE, sizeof(der->skid)))
26965
            return SKID_E;
26966
26967
        /* Note: different skid buffers sizes for der (MAX_KID_SZ) and
26968
            cert (CTC_MAX_SKID_SIZE). */
26969
        der->skidSz = SetSKID(der->skid, sizeof(der->skid),
26970
                              cert->skid, cert->skidSz);
26971
        if (der->skidSz <= 0)
26972
            return SKID_E;
26973
26974
        der->extensionsSz += der->skidSz;
26975
    }
26976
    else
26977
        der->skidSz = 0;
26978
26979
    /* AKID */
26980
    if (cert->akidSz) {
26981
        /* check the provided AKID size */
26982
        if ((
26983
#ifdef WOLFSSL_AKID_NAME
26984
             !cert->rawAkid &&
26985
#endif
26986
              cert->akidSz > (int)min(CTC_MAX_AKID_SIZE, sizeof(der->akid)))
26987
#ifdef WOLFSSL_AKID_NAME
26988
          || (cert->rawAkid && cert->akidSz > (int)sizeof(der->akid))
26989
#endif
26990
             )
26991
            return AKID_E;
26992
26993
        der->akidSz = SetAKID(der->akid, sizeof(der->akid), cert->akid,
26994
                                cert->akidSz,
26995
#ifdef WOLFSSL_AKID_NAME
26996
                                cert->rawAkid
26997
#else
26998
                                0
26999
#endif
27000
                                );
27001
        if (der->akidSz <= 0)
27002
            return AKID_E;
27003
27004
        der->extensionsSz += der->akidSz;
27005
    }
27006
    else
27007
        der->akidSz = 0;
27008
27009
    /* Key Usage */
27010
    if (cert->keyUsage != 0){
27011
        der->keyUsageSz = SetKeyUsage(der->keyUsage, sizeof(der->keyUsage),
27012
                                      cert->keyUsage);
27013
        if (der->keyUsageSz <= 0)
27014
            return KEYUSAGE_E;
27015
27016
        der->extensionsSz += der->keyUsageSz;
27017
    }
27018
    else
27019
        der->keyUsageSz = 0;
27020
27021
    /* Extended Key Usage */
27022
    if (cert->extKeyUsage != 0){
27023
        der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage,
27024
                                sizeof(der->extKeyUsage), cert->extKeyUsage);
27025
        if (der->extKeyUsageSz <= 0)
27026
            return EXTKEYUSAGE_E;
27027
27028
        der->extensionsSz += der->extKeyUsageSz;
27029
    }
27030
    else
27031
        der->extKeyUsageSz = 0;
27032
27033
#ifndef IGNORE_NETSCAPE_CERT_TYPE
27034
    /* Netscape Certificate Type */
27035
    if (cert->nsCertType != 0) {
27036
        der->nsCertTypeSz = SetNsCertType(cert, der->nsCertType,
27037
                                sizeof(der->nsCertType), cert->nsCertType);
27038
        if (der->nsCertTypeSz <= 0)
27039
            return EXTENSIONS_E;
27040
27041
        der->extensionsSz += der->nsCertTypeSz;
27042
    }
27043
    else
27044
        der->nsCertTypeSz = 0;
27045
#endif
27046
27047
    if (cert->crlInfoSz > 0) {
27048
        der->crlInfoSz = SetCRLInfo(cert, der->crlInfo, sizeof(der->crlInfo),
27049
                                cert->crlInfo, cert->crlInfoSz);
27050
        if (der->crlInfoSz <= 0)
27051
            return EXTENSIONS_E;
27052
27053
        der->extensionsSz += der->crlInfoSz;
27054
    }
27055
    else
27056
        der->crlInfoSz = 0;
27057
27058
    /* Certificate Policies */
27059
    if (cert->certPoliciesNb != 0) {
27060
        der->certPoliciesSz = SetCertificatePolicies(der->certPolicies,
27061
                                                     sizeof(der->certPolicies),
27062
                                                     cert->certPolicies,
27063
                                                     cert->certPoliciesNb,
27064
                                                     cert->heap);
27065
        if (der->certPoliciesSz <= 0)
27066
            return CERTPOLICIES_E;
27067
27068
        der->extensionsSz += der->certPoliciesSz;
27069
    }
27070
    else
27071
        der->certPoliciesSz = 0;
27072
#endif /* WOLFSSL_CERT_EXT */
27073
27074
    /* put extensions */
27075
    if (der->extensionsSz > 0) {
27076
27077
        /* put the start of extensions sequence (ID, Size) */
27078
        der->extensionsSz = SetExtensionsHeader(der->extensions,
27079
                                                sizeof(der->extensions),
27080
                                                der->extensionsSz);
27081
        if (der->extensionsSz <= 0)
27082
            return EXTENSIONS_E;
27083
27084
        /* put CA */
27085
        if (der->caSz) {
27086
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
27087
                                &der->extensionsSz,
27088
                                der->ca, der->caSz);
27089
            if (ret == 0)
27090
                return EXTENSIONS_E;
27091
        }
27092
27093
#ifdef WOLFSSL_ALT_NAMES
27094
        /* put Alternative Names */
27095
        if (der->altNamesSz) {
27096
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
27097
                                &der->extensionsSz,
27098
                                der->altNames, der->altNamesSz);
27099
            if (ret <= 0)
27100
                return EXTENSIONS_E;
27101
        }
27102
#endif
27103
27104
#ifdef WOLFSSL_CERT_EXT
27105
        /* put SKID */
27106
        if (der->skidSz) {
27107
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
27108
                                &der->extensionsSz,
27109
                                der->skid, der->skidSz);
27110
            if (ret <= 0)
27111
                return EXTENSIONS_E;
27112
        }
27113
27114
        /* put AKID */
27115
        if (der->akidSz) {
27116
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
27117
                                &der->extensionsSz,
27118
                                der->akid, der->akidSz);
27119
            if (ret <= 0)
27120
                return EXTENSIONS_E;
27121
        }
27122
27123
        /* put CRL Distribution Points */
27124
        if (der->crlInfoSz) {
27125
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
27126
                                &der->extensionsSz,
27127
                                der->crlInfo, der->crlInfoSz);
27128
            if (ret <= 0)
27129
                return EXTENSIONS_E;
27130
        }
27131
27132
        /* put KeyUsage */
27133
        if (der->keyUsageSz) {
27134
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
27135
                                &der->extensionsSz,
27136
                                der->keyUsage, der->keyUsageSz);
27137
            if (ret <= 0)
27138
                return EXTENSIONS_E;
27139
        }
27140
27141
        /* put ExtendedKeyUsage */
27142
        if (der->extKeyUsageSz) {
27143
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
27144
                                &der->extensionsSz,
27145
                                der->extKeyUsage, der->extKeyUsageSz);
27146
            if (ret <= 0)
27147
                return EXTENSIONS_E;
27148
        }
27149
27150
        /* put Netscape Cert Type */
27151
#ifndef IGNORE_NETSCAPE_CERT_TYPE
27152
        if (der->nsCertTypeSz) {
27153
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
27154
                                &der->extensionsSz,
27155
                                der->nsCertType, der->nsCertTypeSz);
27156
            if (ret <= 0)
27157
                return EXTENSIONS_E;
27158
        }
27159
#endif
27160
27161
        /* put Certificate Policies */
27162
        if (der->certPoliciesSz) {
27163
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
27164
                                &der->extensionsSz,
27165
                                der->certPolicies, der->certPoliciesSz);
27166
            if (ret <= 0)
27167
                return EXTENSIONS_E;
27168
        }
27169
#endif /* WOLFSSL_CERT_EXT */
27170
    }
27171
27172
    der->total = der->versionSz + der->serialSz + der->sigAlgoSz +
27173
        der->publicKeySz + der->validitySz + der->subjectSz + der->issuerSz +
27174
        der->extensionsSz;
27175
27176
    return 0;
27177
}
27178
27179
27180
/* write DER encoded cert to buffer, size already checked */
27181
static int WriteCertBody(DerCert* der, byte* buf)
27182
{
27183
    int idx;
27184
27185
    /* signed part header */
27186
    idx = SetSequence(der->total, buf);
27187
    /* version */
27188
    XMEMCPY(buf + idx, der->version, der->versionSz);
27189
    idx += der->versionSz;
27190
    /* serial */
27191
    XMEMCPY(buf + idx, der->serial, der->serialSz);
27192
    idx += der->serialSz;
27193
    /* sig algo */
27194
    XMEMCPY(buf + idx, der->sigAlgo, der->sigAlgoSz);
27195
    idx += der->sigAlgoSz;
27196
    /* issuer */
27197
    XMEMCPY(buf + idx, der->issuer, der->issuerSz);
27198
    idx += der->issuerSz;
27199
    /* validity */
27200
    XMEMCPY(buf + idx, der->validity, der->validitySz);
27201
    idx += der->validitySz;
27202
    /* subject */
27203
    XMEMCPY(buf + idx, der->subject, der->subjectSz);
27204
    idx += der->subjectSz;
27205
    /* public key */
27206
    XMEMCPY(buf + idx, der->publicKey, der->publicKeySz);
27207
    idx += der->publicKeySz;
27208
    if (der->extensionsSz) {
27209
        /* extensions */
27210
        XMEMCPY(buf + idx, der->extensions, min(der->extensionsSz,
27211
                                                   (int)sizeof(der->extensions)));
27212
        idx += der->extensionsSz;
27213
    }
27214
27215
    return idx;
27216
}
27217
#endif /* !WOLFSSL_ASN_TEMPLATE */
27218
27219
27220
/* Make signature from buffer (sz), write to sig (sigSz) */
27221
static int MakeSignature(CertSignCtx* certSignCtx, const byte* buf, int sz,
27222
    byte* sig, int sigSz, RsaKey* rsaKey, ecc_key* eccKey,
27223
    ed25519_key* ed25519Key, ed448_key* ed448Key, falcon_key* falconKey,
27224
    dilithium_key* dilithiumKey, WC_RNG* rng, int sigAlgoType, void* heap)
27225
{
27226
    int digestSz = 0, typeH = 0, ret = 0;
27227
27228
    (void)digestSz;
27229
    (void)typeH;
27230
    (void)buf;
27231
    (void)sz;
27232
    (void)sig;
27233
    (void)sigSz;
27234
    (void)rsaKey;
27235
    (void)eccKey;
27236
    (void)ed25519Key;
27237
    (void)ed448Key;
27238
    (void)falconKey;
27239
    (void)dilithiumKey;
27240
    (void)rng;
27241
    (void)heap;
27242
27243
    switch (certSignCtx->state) {
27244
    case CERTSIGN_STATE_BEGIN:
27245
    case CERTSIGN_STATE_DIGEST:
27246
27247
        certSignCtx->state = CERTSIGN_STATE_DIGEST;
27248
        certSignCtx->digest = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap,
27249
            DYNAMIC_TYPE_TMP_BUFFER);
27250
        if (certSignCtx->digest == NULL) {
27251
            ret = MEMORY_E; goto exit_ms;
27252
        }
27253
27254
        ret = HashForSignature(buf, sz, sigAlgoType, certSignCtx->digest,
27255
                               &typeH, &digestSz, 0);
27256
        /* set next state, since WC_PENDING_E rentry for these are not "call again" */
27257
        certSignCtx->state = CERTSIGN_STATE_ENCODE;
27258
        if (ret != 0) {
27259
            goto exit_ms;
27260
        }
27261
        FALL_THROUGH;
27262
27263
    case CERTSIGN_STATE_ENCODE:
27264
    #ifndef NO_RSA
27265
        if (rsaKey) {
27266
            certSignCtx->encSig = (byte*)XMALLOC(MAX_DER_DIGEST_SZ, heap,
27267
                DYNAMIC_TYPE_TMP_BUFFER);
27268
            if (certSignCtx->encSig == NULL) {
27269
                ret = MEMORY_E; goto exit_ms;
27270
            }
27271
27272
            /* signature */
27273
            certSignCtx->encSigSz = wc_EncodeSignature(certSignCtx->encSig,
27274
                                          certSignCtx->digest, digestSz, typeH);
27275
        }
27276
    #endif /* !NO_RSA */
27277
        FALL_THROUGH;
27278
27279
    case CERTSIGN_STATE_DO:
27280
        certSignCtx->state = CERTSIGN_STATE_DO;
27281
        ret = ALGO_ID_E; /* default to error */
27282
27283
    #ifndef NO_RSA
27284
        if (rsaKey) {
27285
            /* signature */
27286
            ret = wc_RsaSSL_Sign(certSignCtx->encSig, certSignCtx->encSigSz,
27287
                                 sig, sigSz, rsaKey, rng);
27288
        }
27289
    #endif /* !NO_RSA */
27290
27291
    #ifdef HAVE_ECC
27292
        if (!rsaKey && eccKey) {
27293
            word32 outSz = sigSz;
27294
27295
            ret = wc_ecc_sign_hash(certSignCtx->digest, digestSz,
27296
                                   sig, &outSz, rng, eccKey);
27297
            if (ret == 0)
27298
                ret = outSz;
27299
        }
27300
    #endif /* HAVE_ECC */
27301
27302
    #if defined(HAVE_ED25519) && defined(HAVE_ED25519_SIGN)
27303
        if (!rsaKey && !eccKey && ed25519Key) {
27304
            word32 outSz = sigSz;
27305
27306
            ret = wc_ed25519_sign_msg(buf, sz, sig, &outSz, ed25519Key);
27307
            if (ret == 0)
27308
                ret = outSz;
27309
        }
27310
    #endif /* HAVE_ED25519 && HAVE_ED25519_SIGN */
27311
27312
    #if defined(HAVE_ED448) && defined(HAVE_ED448_SIGN)
27313
        if (!rsaKey && !eccKey && !ed25519Key && ed448Key) {
27314
            word32 outSz = sigSz;
27315
27316
            ret = wc_ed448_sign_msg(buf, sz, sig, &outSz, ed448Key, NULL, 0);
27317
            if (ret == 0)
27318
                ret = outSz;
27319
        }
27320
    #endif /* HAVE_ED448 && HAVE_ED448_SIGN */
27321
27322
    #if defined(HAVE_PQC)
27323
    #if defined(HAVE_FALCON)
27324
        if (!rsaKey && !eccKey && !ed25519Key && !ed448Key && falconKey) {
27325
            word32 outSz = sigSz;
27326
            ret = wc_falcon_sign_msg(buf, sz, sig, &outSz, falconKey);
27327
            if (ret == 0)
27328
                ret = outSz;
27329
        }
27330
    #endif /* HAVE_FALCON */
27331
    #if defined(HAVE_DILITHIUM)
27332
        if (!rsaKey && !eccKey && !ed25519Key && !ed448Key && !falconKey &&
27333
            dilithiumKey) {
27334
            word32 outSz = sigSz;
27335
            ret = wc_dilithium_sign_msg(buf, sz, sig, &outSz, dilithiumKey);
27336
            if (ret == 0)
27337
                ret = outSz;
27338
        }
27339
    #endif /* HAVE_DILITHIUM */
27340
    #endif /* HAVE_PQC */
27341
27342
        break;
27343
    }
27344
27345
exit_ms:
27346
27347
#ifdef WOLFSSL_ASYNC_CRYPT
27348
    if (ret == WC_PENDING_E) {
27349
        return ret;
27350
    }
27351
#endif
27352
27353
#ifndef NO_RSA
27354
    if (rsaKey) {
27355
        XFREE(certSignCtx->encSig, heap, DYNAMIC_TYPE_TMP_BUFFER);
27356
    }
27357
#endif /* !NO_RSA */
27358
27359
    XFREE(certSignCtx->digest, heap, DYNAMIC_TYPE_TMP_BUFFER);
27360
    certSignCtx->digest = NULL;
27361
27362
    /* reset state */
27363
    certSignCtx->state = CERTSIGN_STATE_BEGIN;
27364
27365
    if (ret < 0) {
27366
        WOLFSSL_ERROR_VERBOSE(ret);
27367
    }
27368
27369
    return ret;
27370
}
27371
27372
27373
#ifdef WOLFSSL_ASN_TEMPLATE
27374
/* Generate a random integer value of at most len bytes.
27375
 *
27376
 * Most-significant bit will not be set when maximum size.
27377
 * Random value may be smaller than maximum size in bytes.
27378
 *
27379
 * @param [in]  rng  Random number generator.
27380
 * @param [out] out  Buffer to hold integer value.
27381
 * @param [in]  len  Maximum number of bytes of integer.
27382
 * @return  0 on success.
27383
 * @return  -ve when random number generation failed.
27384
 */
27385
static int GenerateInteger(WC_RNG* rng, byte* out, int len)
27386
{
27387
    int ret;
27388
27389
    /* Generate random number. */
27390
    ret = wc_RNG_GenerateBlock(rng, out, len);
27391
    if (ret == 0) {
27392
        int i;
27393
27394
        /* Clear the top bit to make positive. */
27395
        out[0] &= 0x7f;
27396
27397
        /* Find first non-zero byte. One zero byte is valid though. */
27398
        for (i = 0; i < len - 1; i++) {
27399
            if (out[i] != 0) {
27400
                break;
27401
            }
27402
        }
27403
        if (i != 0) {
27404
            /* Remove leading zeros. */
27405
            XMEMMOVE(out, out + i, len - i);
27406
        }
27407
    }
27408
27409
    return ret;
27410
}
27411
27412
/* ASN.1 template for a Certificate.
27413
 * X.509: RFC 5280, 4.1 - Basic Certificate Fields.
27414
 */
27415
static const ASNItem sigASN[] = {
27416
/* SEQ          */    { 0, ASN_SEQUENCE, 1, 1, 0 },
27417
                                     /* tbsCertificate */
27418
/* TBS_SEQ      */        { 1, ASN_SEQUENCE, 1, 0, 0 },
27419
                                     /* signatureAlgorithm */
27420
/* SIGALGO_SEQ  */        { 1, ASN_SEQUENCE, 1, 1, 0 },
27421
/* SIGALGO_OID  */            { 2, ASN_OBJECT_ID, 0, 0, 0 },
27422
/* SIGALGO_NULL */            { 2, ASN_TAG_NULL, 0, 0, 0 },
27423
                                     /* signatureValue */
27424
/* SIGNATURE    */        { 1, ASN_BIT_STRING, 0, 0, 0 },
27425
};
27426
enum {
27427
    SIGASN_IDX_SEQ = 0,
27428
    SIGASN_IDX_TBS_SEQ,
27429
    SIGASN_IDX_SIGALGO_SEQ,
27430
    SIGASN_IDX_SIGALGO_OID,
27431
    SIGASN_IDX_SIGALGO_NULL,
27432
    SIGASN_IDX_SIGNATURE,
27433
};
27434
27435
/* Number of items in ASN.1 template for a Certificate. */
27436
#define sigASN_Length (sizeof(sigASN) / sizeof(ASNItem))
27437
#endif
27438
27439
/* add signature to end of buffer, size of buffer assumed checked, return
27440
   new length */
27441
int AddSignature(byte* buf, int bodySz, const byte* sig, int sigSz,
27442
                        int sigAlgoType)
27443
{
27444
#ifndef WOLFSSL_ASN_TEMPLATE
27445
    byte seq[MAX_SEQ_SZ];
27446
    int  idx = bodySz, seqSz;
27447
27448
    /* algo */
27449
    idx += SetAlgoID(sigAlgoType, buf ? buf + idx : NULL, oidSigType, 0);
27450
    /* bit string */
27451
    idx += SetBitString(sigSz, 0, buf ? buf + idx : NULL);
27452
    /* signature */
27453
    if (buf)
27454
        XMEMCPY(buf + idx, sig, sigSz);
27455
    idx += sigSz;
27456
27457
    /* make room for overall header */
27458
    seqSz = SetSequence(idx, seq);
27459
    if (buf) {
27460
        XMEMMOVE(buf + seqSz, buf, idx);
27461
        XMEMCPY(buf, seq, seqSz);
27462
    }
27463
27464
    return idx + seqSz;
27465
#else
27466
    DECL_ASNSETDATA(dataASN, sigASN_Length);
27467
    word32 seqSz;
27468
    int sz;
27469
    int ret = 0;
27470
27471
    CALLOC_ASNSETDATA(dataASN, sigASN_Length, ret, NULL);
27472
27473
    /* In place, put body between SEQUENCE and signature. */
27474
    if (ret == 0) {
27475
        /* Set sigature OID and signature data. */
27476
        SetASN_OID(&dataASN[SIGASN_IDX_SIGALGO_OID], sigAlgoType, oidSigType);
27477
        if (IsSigAlgoECC(sigAlgoType)) {
27478
            /* ECDSA and EdDSA doesn't have NULL tagged item. */
27479
            dataASN[SIGASN_IDX_SIGALGO_NULL].noOut = 1;
27480
        }
27481
        SetASN_Buffer(&dataASN[SIGASN_IDX_SIGNATURE], sig, sigSz);
27482
        /* Calculate size of signature data. */
27483
        ret = SizeASN_Items(&sigASN[SIGASN_IDX_SIGALGO_SEQ],
27484
                &dataASN[SIGASN_IDX_SIGALGO_SEQ], sigASN_Length - 2, &sz);
27485
    }
27486
    if (ret == 0) {
27487
        /* Calculate size of outer sequence by calculating size of the encoded
27488
         * length and adding 1 for tag. */
27489
        seqSz = SizeASNHeader(bodySz + sz);
27490
        if (buf != NULL) {
27491
            /* Move body to after sequence. */
27492
            XMEMMOVE(buf + seqSz, buf, bodySz);
27493
        }
27494
        /* Leave space for body in encoding. */
27495
        SetASN_ReplaceBuffer(&dataASN[SIGASN_IDX_TBS_SEQ], NULL, bodySz);
27496
27497
        /* Calculate overall size and put in offsets and lengths. */
27498
        ret = SizeASN_Items(sigASN, dataASN, sigASN_Length, &sz);
27499
    }
27500
    if ((ret == 0) && (buf != NULL)) {
27501
        /* Write SEQUENCE and signature around body. */
27502
        SetASN_Items(sigASN, dataASN, sigASN_Length, buf);
27503
    }
27504
27505
    if (ret == 0) {
27506
        /* Return the encoding size. */
27507
        ret = sz;
27508
    }
27509
27510
    FREE_ASNSETDATA(dataASN, NULL);
27511
    return ret;
27512
#endif /* WOLFSSL_ASN_TEMPLATE */
27513
}
27514
27515
27516
/* Make an x509 Certificate v3 any key type from cert input, write to buffer */
27517
static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
27518
                       RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng,
27519
                       DsaKey* dsaKey, ed25519_key* ed25519Key,
27520
                       ed448_key* ed448Key, falcon_key* falconKey,
27521
                       dilithium_key* dilithiumKey)
27522
{
27523
#ifndef WOLFSSL_ASN_TEMPLATE
27524
    int ret;
27525
#ifdef WOLFSSL_SMALL_STACK
27526
    DerCert* der;
27527
#else
27528
    DerCert der[1];
27529
#endif
27530
27531
    if (derBuffer == NULL)
27532
        return BAD_FUNC_ARG;
27533
27534
    if (eccKey)
27535
        cert->keyType = ECC_KEY;
27536
    else if (rsaKey)
27537
        cert->keyType = RSA_KEY;
27538
    else if (dsaKey)
27539
        cert->keyType = DSA_KEY;
27540
    else if (ed25519Key)
27541
        cert->keyType = ED25519_KEY;
27542
    else if (ed448Key)
27543
        cert->keyType = ED448_KEY;
27544
#ifdef HAVE_PQC
27545
#ifdef HAVE_FALCON
27546
    else if ((falconKey != NULL) && (falconKey->level == 1))
27547
        cert->keyType = FALCON_LEVEL1_KEY;
27548
    else if ((falconKey != NULL) && (falconKey->level == 5))
27549
        cert->keyType = FALCON_LEVEL5_KEY;
27550
#endif /* HAVE_FALCON */
27551
#ifdef HAVE_DILITHIUM
27552
    else if ((dilithiumKey != NULL) && (dilithiumKey->level == 2)
27553
             && (dilithiumKey->sym == SHAKE_VARIANT))
27554
        cert->keyType = DILITHIUM_LEVEL2_KEY;
27555
    else if ((dilithiumKey != NULL) && (dilithiumKey->level == 3)
27556
             && (dilithiumKey->sym == SHAKE_VARIANT))
27557
        cert->keyType = DILITHIUM_LEVEL3_KEY;
27558
    else if ((dilithiumKey != NULL) && (dilithiumKey->level == 5)
27559
             && (dilithiumKey->sym == SHAKE_VARIANT))
27560
        cert->keyType = DILITHIUM_LEVEL5_KEY;
27561
    else if ((dilithiumKey != NULL) && (dilithiumKey->level == 2)
27562
             && (dilithiumKey->sym == AES_VARIANT))
27563
        cert->keyType = DILITHIUM_AES_LEVEL2_KEY;
27564
    else if ((dilithiumKey != NULL) && (dilithiumKey->level == 3)
27565
             && (dilithiumKey->sym == AES_VARIANT))
27566
        cert->keyType = DILITHIUM_AES_LEVEL3_KEY;
27567
    else if ((dilithiumKey != NULL) && (dilithiumKey->level == 5)
27568
             && (dilithiumKey->sym == AES_VARIANT))
27569
        cert->keyType = DILITHIUM_AES_LEVEL5_KEY;
27570
#endif /* HAVE_DILITHIUM */
27571
#endif /* HAVE_PQC */
27572
    else
27573
        return BAD_FUNC_ARG;
27574
27575
#ifdef WOLFSSL_SMALL_STACK
27576
    der = (DerCert*)XMALLOC(sizeof(DerCert), cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
27577
    if (der == NULL)
27578
        return MEMORY_E;
27579
#endif
27580
27581
    ret = EncodeCert(cert, der, rsaKey, eccKey, rng, dsaKey, ed25519Key,
27582
                     ed448Key, falconKey, dilithiumKey);
27583
    if (ret == 0) {
27584
        if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
27585
            ret = BUFFER_E;
27586
        else
27587
            ret = cert->bodySz = WriteCertBody(der, derBuffer);
27588
    }
27589
27590
#ifdef WOLFSSL_SMALL_STACK
27591
    XFREE(der, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
27592
#endif
27593
27594
    return ret;
27595
#else
27596
    /* TODO: issRaw and sbjRaw should be NUL terminated. */
27597
    DECL_ASNSETDATA(dataASN, x509CertASN_Length);
27598
    word32 publicKeySz = 0;
27599
    word32 issuerSz = 0;
27600
    word32 subjectSz = 0;
27601
    word32 extSz = 0;
27602
    int sz = 0;
27603
    int ret = 0;
27604
    word32 issRawLen = 0;
27605
    word32 sbjRawLen = 0;
27606
27607
    (void)falconKey;    /* Unused without OQS */
27608
    (void)dilithiumKey; /* Unused without OQS */
27609
27610
    CALLOC_ASNSETDATA(dataASN, x509CertASN_Length, ret, cert->heap);
27611
27612
    if (ret == 0) {
27613
        /* Set key type into certificate object based on key passed in. */
27614
        if (rsaKey) {
27615
            cert->keyType = RSA_KEY;
27616
        }
27617
        else if (eccKey) {
27618
            cert->keyType = ECC_KEY;
27619
        }
27620
        else if (dsaKey) {
27621
            cert->keyType = DSA_KEY;
27622
        }
27623
        else if (ed25519Key) {
27624
            cert->keyType = ED25519_KEY;
27625
        }
27626
        else if (ed448Key) {
27627
            cert->keyType = ED448_KEY;
27628
        }
27629
#ifdef HAVE_PQC
27630
#ifdef HAVE_FALCON
27631
        else if ((falconKey != NULL) && (falconKey->level == 1)) {
27632
            cert->keyType = FALCON_LEVEL1_KEY;
27633
        }
27634
        else if ((falconKey != NULL) && (falconKey->level == 5)) {
27635
            cert->keyType = FALCON_LEVEL5_KEY;
27636
        }
27637
#endif /* HAVE_FALCON */
27638
#ifdef HAVE_DILITHIUM
27639
        else if ((dilithiumKey != NULL) && (dilithiumKey->level == 2)
27640
                 && (dilithiumKey->sym == SHAKE_VARIANT)) {
27641
            cert->keyType = DILITHIUM_LEVEL2_KEY;
27642
        }
27643
        else if ((dilithiumKey != NULL) && (dilithiumKey->level == 3)
27644
                 && (dilithiumKey->sym == SHAKE_VARIANT)) {
27645
            cert->keyType = DILITHIUM_LEVEL3_KEY;
27646
        }
27647
        else if ((dilithiumKey != NULL) && (dilithiumKey->level == 5)
27648
                 && (dilithiumKey->sym == SHAKE_VARIANT)) {
27649
            cert->keyType = DILITHIUM_LEVEL5_KEY;
27650
        }
27651
        else if ((dilithiumKey != NULL) && (dilithiumKey->level == 2)
27652
                 && (dilithiumKey->sym == AES_VARIANT)) {
27653
            cert->keyType = DILITHIUM_AES_LEVEL2_KEY;
27654
        }
27655
        else if ((dilithiumKey != NULL) && (dilithiumKey->level == 3)
27656
                 && (dilithiumKey->sym == AES_VARIANT)) {
27657
            cert->keyType = DILITHIUM_AES_LEVEL3_KEY;
27658
        }
27659
        else if ((dilithiumKey != NULL) && (dilithiumKey->level == 5)
27660
                 && (dilithiumKey->sym == AES_VARIANT)) {
27661
            cert->keyType = DILITHIUM_AES_LEVEL5_KEY;
27662
        }
27663
#endif /* HAVE_DILITHIUM */
27664
#endif /* HAVE_PQC */
27665
        else {
27666
            ret = BAD_FUNC_ARG;
27667
        }
27668
    }
27669
    if ((ret == 0) && (cert->serialSz == 0)) {
27670
        /* Generate random serial number. */
27671
        cert->serialSz = CTC_GEN_SERIAL_SZ;
27672
        ret = GenerateInteger(rng, cert->serial, CTC_GEN_SERIAL_SZ);
27673
    }
27674
    if (ret == 0) {
27675
        /* Determine issuer name size. */
27676
    #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) || \
27677
        defined(WOLFSSL_CERT_REQ)
27678
        issRawLen = (word32)XSTRLEN((const char*)cert->issRaw);
27679
        if (issRawLen > 0) {
27680
            issuerSz = min(sizeof(cert->issRaw), issRawLen);
27681
        }
27682
        else
27683
    #endif
27684
        {
27685
            /* Calculate issuer name encoding size. If the cert is self-signed
27686
             * use the subject instead of the issuer. */
27687
            issuerSz = SetNameEx(NULL, WC_ASN_NAME_MAX, cert->selfSigned ?
27688
                                 &cert->subject : &cert->issuer, cert->heap);
27689
            ret = issuerSz;
27690
        }
27691
    }
27692
    if (ret >= 0) {
27693
        /* Determine subject name size. */
27694
    #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) || \
27695
        defined(WOLFSSL_CERT_REQ)
27696
        sbjRawLen = (word32)XSTRLEN((const char*)cert->sbjRaw);
27697
        if (sbjRawLen > 0) {
27698
            subjectSz = min(sizeof(cert->sbjRaw), sbjRawLen);
27699
        }
27700
        else
27701
    #endif
27702
        {
27703
            /* Calculate subject name encoding size. */
27704
            subjectSz = SetNameEx(NULL, WC_ASN_NAME_MAX, &cert->subject,
27705
                                  cert->heap);
27706
            ret = subjectSz;
27707
        }
27708
    }
27709
    if (ret >= 0) {
27710
        /* Calculate public key encoding size. */
27711
        ret = publicKeySz = EncodePublicKey(cert->keyType, NULL, 0, rsaKey,
27712
            eccKey, ed25519Key, ed448Key, dsaKey);
27713
    }
27714
    if (ret >= 0) {
27715
        /* Calculate extensions encoding size - may be 0. */
27716
        ret = extSz = EncodeExtensions(cert, NULL, 0, 0);
27717
    }
27718
    if (ret >= 0) {
27719
        /* Don't write out outer sequence - only doing body. */
27720
        dataASN[X509CERTASN_IDX_SEQ].noOut = 1;
27721
        /* Set version, serial number and signature OID */
27722
        SetASN_Int8Bit(&dataASN[X509CERTASN_IDX_TBS_VER_INT], cert->version);
27723
        SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_SERIAL], cert->serial,
27724
                cert->serialSz);
27725
        SetASN_OID(&dataASN[X509CERTASN_IDX_TBS_ALGOID_OID], cert->sigType,
27726
                oidSigType);
27727
        if (IsSigAlgoECC(cert->sigType)) {
27728
            /* No NULL tagged item with ECDSA and EdDSA signature OIDs. */
27729
            dataASN[X509CERTASN_IDX_TBS_ALGOID_PARAMS_NULL].noOut = 1;
27730
        }
27731
    #ifdef WC_RSA_PSS
27732
        /* TODO: Encode RSA PSS parameters. */
27733
        dataASN[X509CERTASN_IDX_TBS_ALGOID_PARAMS].noOut = 1;
27734
    #endif
27735
        if (issRawLen > 0) {
27736
    #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) || \
27737
        defined(WOLFSSL_CERT_REQ)
27738
            /* Put in encoded issuer name. */
27739
            SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ],
27740
                    cert->issRaw, issuerSz);
27741
    #endif
27742
        }
27743
        else {
27744
            /* Leave space for issuer name. */
27745
            SetASN_ReplaceBuffer(&dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ],
27746
                    NULL, issuerSz);
27747
        }
27748
27749
        if (cert->beforeDateSz && cert->afterDateSz) {
27750
            if (cert->beforeDate[0] == ASN_UTC_TIME) {
27751
                /* Make space for before date data. */
27752
                SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC],
27753
                        cert->beforeDate + 2, ASN_UTC_TIME_SIZE - 1);
27754
                /* Don't put out Generalized Time before data. */
27755
                dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT].noOut = 1;
27756
            }
27757
            else {
27758
                /* Don't put out UTC before data. */
27759
                dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC].noOut = 1;
27760
                /* Make space for before date data. */
27761
                SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT],
27762
                        cert->beforeDate + 2, ASN_GEN_TIME_SZ);
27763
            }
27764
            if (cert->afterDate[0] == ASN_UTC_TIME) {
27765
                /* Make space for after date data. */
27766
                SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC],
27767
                        cert->afterDate + 2, ASN_UTC_TIME_SIZE - 1);
27768
                /* Don't put out UTC Generalized Time after data. */
27769
                dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT].noOut = 1;
27770
            }
27771
            else {
27772
                /* Don't put out UTC after data. */
27773
                dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC].noOut = 1;
27774
                /* Make space for after date data. */
27775
                SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT],
27776
                        cert->afterDate + 2, ASN_GEN_TIME_SZ);
27777
            }
27778
        }
27779
        else
27780
        {
27781
            /* Don't put out UTC before data. */
27782
            dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC].noOut = 1;
27783
            /* Make space for before date data. */
27784
            SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT],
27785
                    NULL, ASN_GEN_TIME_SZ);
27786
            /* Don't put out UTC after data. */
27787
            dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC].noOut = 1;
27788
            /* Make space for after date data. */
27789
            SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT],
27790
                    NULL, ASN_GEN_TIME_SZ);
27791
        }
27792
        if (sbjRawLen > 0) {
27793
            /* Put in encoded subject name. */
27794
    #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) || \
27795
        defined(WOLFSSL_CERT_REQ)
27796
            SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_SUBJECT_SEQ],
27797
                    cert->sbjRaw, subjectSz);
27798
    #endif
27799
        }
27800
        else {
27801
            /* Leave space for subject name. */
27802
            SetASN_ReplaceBuffer(&dataASN[X509CERTASN_IDX_TBS_SUBJECT_SEQ],
27803
                    NULL, subjectSz);
27804
        }
27805
        /* Leave space for public key. */
27806
        SetASN_ReplaceBuffer(&dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ],
27807
                NULL, publicKeySz);
27808
        /* Replacement buffer instead of algorithm identifier items. */
27809
        SetASNItem_NoOut(dataASN,
27810
                X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_SEQ,
27811
                X509CERTASN_IDX_TBS_SPUBKEYINFO_PUBKEY);
27812
        /* issuerUniqueID and subjectUniqueID not supported. */
27813
        dataASN[X509CERTASN_IDX_TBS_ISSUERUID].noOut = 1;
27814
        dataASN[X509CERTASN_IDX_TBS_SUBJECTUID].noOut = 1;
27815
        /* Leave space for extensions if any set into certificate object. */
27816
        if (extSz > 0) {
27817
            SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_EXT_SEQ], NULL, extSz);
27818
        }
27819
        else {
27820
            SetASNItem_NoOutNode(dataASN, x509CertASN,
27821
                    X509CERTASN_IDX_TBS_EXT, x509CertASN_Length);
27822
        }
27823
        /* No signature - added later. */
27824
        SetASNItem_NoOut(dataASN, X509CERTASN_IDX_SIGALGO_SEQ,
27825
                X509CERTASN_IDX_SIGNATURE);
27826
27827
        /* Calculate encoded certificate body size. */
27828
        ret = SizeASN_Items(x509CertASN, dataASN, x509CertASN_Length, &sz);
27829
    }
27830
    /* Check buffer is big enough for encoded data. */
27831
    if ((ret == 0) && (sz > (int)derSz)) {
27832
        ret = BUFFER_E;
27833
    }
27834
    if (ret == 0) {
27835
        /* Encode certificate body into buffer. */
27836
        SetASN_Items(x509CertASN, dataASN, x509CertASN_Length, derBuffer);
27837
27838
        if (issRawLen == 0) {
27839
            /* Encode issuer name into buffer. Use the subject as the issuer
27840
             * if it is self-signed. Size will be correct because we did the
27841
             * same for size. */
27842
            ret = SetNameEx(
27843
                (byte*)dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ].data.buffer.data,
27844
                dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ].data.buffer.length,
27845
                cert->selfSigned ? &cert->subject : &cert->issuer, cert->heap);
27846
        }
27847
    }
27848
    if ((ret >= 0) && (sbjRawLen == 0)) {
27849
        /* Encode subject name into buffer. */
27850
        ret = SetNameEx(
27851
            (byte*)dataASN[X509CERTASN_IDX_TBS_SUBJECT_SEQ].data.buffer.data,
27852
            dataASN[X509CERTASN_IDX_TBS_SUBJECT_SEQ].data.buffer.length,
27853
            &cert->subject, cert->heap);
27854
    }
27855
    if (ret >= 0) {
27856
        if (cert->beforeDateSz == 0 || cert->afterDateSz == 0)
27857
        {
27858
            /* Encode validity into buffer. */
27859
            ret = SetValidity(
27860
                (byte*)dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT]
27861
                               .data.buffer.data,
27862
                (byte*)dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT]
27863
                               .data.buffer.data, cert->daysValid);
27864
        }
27865
    }
27866
    if (ret >= 0) {
27867
        /* Encode public key into buffer. */
27868
        ret = EncodePublicKey(cert->keyType,
27869
            (byte*)dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ]
27870
                           .data.buffer.data,
27871
            dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ]
27872
                           .data.buffer.length,
27873
            rsaKey, eccKey, ed25519Key, ed448Key, dsaKey);
27874
    }
27875
    if ((ret >= 0) && (!dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].noOut)) {
27876
        /* Encode extensions into buffer. */
27877
        ret = EncodeExtensions(cert,
27878
                (byte*)dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].data.buffer.data,
27879
                dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].data.buffer.length, 0);
27880
    }
27881
    if (ret >= 0) {
27882
        /* Store encoded certifcate body size. */
27883
        cert->bodySz = sz;
27884
        /* Return the encoding size. */
27885
        ret = sz;
27886
    }
27887
27888
    FREE_ASNSETDATA(dataASN, cert->heap);
27889
    return ret;
27890
#endif
27891
}
27892
27893
27894
/* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */
27895
int wc_MakeCert_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType,
27896
                   void* key, WC_RNG* rng)
27897
{
27898
    RsaKey*            rsaKey = NULL;
27899
    DsaKey*            dsaKey = NULL;
27900
    ecc_key*           eccKey = NULL;
27901
    ed25519_key*       ed25519Key = NULL;
27902
    ed448_key*         ed448Key = NULL;
27903
    falcon_key*        falconKey = NULL;
27904
    dilithium_key*     dilithiumKey = NULL;
27905
27906
    if (keyType == RSA_TYPE)
27907
        rsaKey = (RsaKey*)key;
27908
    else if (keyType == DSA_TYPE)
27909
        dsaKey = (DsaKey*)key;
27910
    else if (keyType == ECC_TYPE)
27911
        eccKey = (ecc_key*)key;
27912
    else if (keyType == ED25519_TYPE)
27913
        ed25519Key = (ed25519_key*)key;
27914
    else if (keyType == ED448_TYPE)
27915
        ed448Key = (ed448_key*)key;
27916
    else if (keyType == FALCON_LEVEL1_TYPE)
27917
        falconKey = (falcon_key*)key;
27918
    else if (keyType == FALCON_LEVEL5_TYPE)
27919
        falconKey = (falcon_key*)key;
27920
    else if (keyType == DILITHIUM_LEVEL2_TYPE)
27921
        dilithiumKey = (dilithium_key*)key;
27922
    else if (keyType == DILITHIUM_LEVEL3_TYPE)
27923
        dilithiumKey = (dilithium_key*)key;
27924
    else if (keyType == DILITHIUM_LEVEL5_TYPE)
27925
        dilithiumKey = (dilithium_key*)key;
27926
    else if (keyType == DILITHIUM_AES_LEVEL2_TYPE)
27927
        dilithiumKey = (dilithium_key*)key;
27928
    else if (keyType == DILITHIUM_AES_LEVEL3_TYPE)
27929
        dilithiumKey = (dilithium_key*)key;
27930
    else if (keyType == DILITHIUM_AES_LEVEL5_TYPE)
27931
        dilithiumKey = (dilithium_key*)key;
27932
27933
    return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, dsaKey,
27934
                       ed25519Key, ed448Key, falconKey, dilithiumKey);
27935
}
27936
27937
/* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */
27938
WOLFSSL_ABI
27939
int wc_MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey,
27940
             ecc_key* eccKey, WC_RNG* rng)
27941
{
27942
    return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, NULL,
27943
                       NULL, NULL, NULL);
27944
}
27945
27946
#ifdef WOLFSSL_CERT_REQ
27947
27948
#ifndef WOLFSSL_ASN_TEMPLATE
27949
/* return size of data set on success
27950
 * if getting size only then attr and oid should be NULL
27951
 */
27952
static int SetReqAttribSingle(byte* output, int* idx, char* attr, int attrSz,
27953
        const byte* oid, int oidSz, byte printable, int extSz)
27954
{
27955
    int totalSz  = 0;
27956
    int seqSz = 0;
27957
    int setSz = 0;
27958
    int strSz = 0;
27959
    byte seq[MAX_SEQ_SZ];
27960
    byte set[MAX_SET_SZ];
27961
    byte str[MAX_PRSTR_SZ];
27962
27963
    totalSz = SetObjectId(oidSz, NULL);
27964
    totalSz += oidSz;
27965
    if (extSz > 0) {
27966
        totalSz += setSz = SetSet(extSz, set);
27967
        totalSz += seqSz = SetSequence(totalSz + extSz, seq);
27968
        totalSz += extSz;
27969
    }
27970
    else {
27971
        if (printable) {
27972
            totalSz += strSz = SetPrintableString(attrSz, str);
27973
        }
27974
        else {
27975
            totalSz += strSz = SetUTF8String(attrSz, str);
27976
        }
27977
        totalSz += setSz = SetSet(strSz + attrSz, set);
27978
        totalSz += seqSz = SetSequence(totalSz + attrSz, seq);
27979
        totalSz += attrSz;
27980
    }
27981
27982
    if (oid) {
27983
        XMEMCPY(&output[*idx], seq, seqSz);
27984
        *idx += seqSz;
27985
        *idx += SetObjectId(oidSz, output + *idx);
27986
        XMEMCPY(&output[*idx], oid, oidSz);
27987
        *idx += oidSz;
27988
        XMEMCPY(&output[*idx], set, setSz);
27989
        *idx += setSz;
27990
        if (strSz > 0) {
27991
            XMEMCPY(&output[*idx], str, strSz);
27992
            *idx += strSz;
27993
            if (attrSz > 0) {
27994
                XMEMCPY(&output[*idx], attr, attrSz);
27995
                *idx += attrSz;
27996
            }
27997
        }
27998
    }
27999
    return totalSz;
28000
}
28001
28002
28003
28004
static int SetReqAttrib(byte* output, Cert* cert, int extSz)
28005
{
28006
    int sz      = 0; /* overall size */
28007
    int setSz   = 0;
28008
28009
    output[0] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED;
28010
    sz++;
28011
28012
    if (cert->challengePw[0]) {
28013
        setSz += SetReqAttribSingle(output, &sz, NULL,
28014
                (int)XSTRLEN(cert->challengePw), NULL,
28015
                sizeof(attrChallengePasswordOid),
28016
                cert->challengePwPrintableString, 0);
28017
    }
28018
28019
    if (cert->unstructuredName[0]) {
28020
        setSz += SetReqAttribSingle(output, &sz, NULL,
28021
                (int)XSTRLEN(cert->unstructuredName), NULL,
28022
                sizeof(attrUnstructuredNameOid), 1, 0);
28023
    }
28024
28025
    if (extSz) {
28026
        setSz += SetReqAttribSingle(output, &sz, NULL, 0, NULL,
28027
                sizeof(attrExtensionRequestOid), 1, extSz);
28028
    }
28029
28030
    /* Put the pieces together. */
28031
    sz += SetLength(setSz, &output[sz]);
28032
    if (sz + setSz - extSz > MAX_ATTRIB_SZ) {
28033
        WOLFSSL_MSG("Attribute Buffer is not big enough!");
28034
        return REQ_ATTRIBUTE_E;
28035
    }
28036
28037
    if (cert->challengePw[0]) {
28038
        SetReqAttribSingle(output, &sz, cert->challengePw,
28039
                (int)XSTRLEN(cert->challengePw), &attrChallengePasswordOid[0],
28040
                sizeof(attrChallengePasswordOid),
28041
                cert->challengePwPrintableString, 0);
28042
    }
28043
28044
    if (cert->unstructuredName[0]) {
28045
        SetReqAttribSingle(output, &sz, cert->unstructuredName,
28046
                (int)XSTRLEN(cert->unstructuredName),
28047
                &attrUnstructuredNameOid[0],
28048
                sizeof(attrUnstructuredNameOid), 1, 0);
28049
    }
28050
28051
    if (extSz) {
28052
        SetReqAttribSingle(output, &sz, NULL, 0, &attrExtensionRequestOid[0],
28053
                sizeof(attrExtensionRequestOid), 1, extSz);
28054
        /* The actual extension data will be tacked onto the output later. */
28055
    }
28056
28057
    return sz;
28058
}
28059
28060
#ifdef WOLFSSL_CUSTOM_OID
28061
/* encode a custom oid and value */
28062
static int SetCustomObjectId(Cert* cert, byte* output, word32 outSz,
28063
    CertOidField* custom)
28064
{
28065
    int idx = 0, cust_lenSz, cust_oidSz;
28066
28067
    if (cert == NULL || output == NULL || custom == NULL) {
28068
        return BAD_FUNC_ARG;
28069
    }
28070
    if (custom->oid == NULL || custom->oidSz <= 0) {
28071
        return 0; /* none set */
28072
    }
28073
28074
    /* Octet String header */
28075
    cust_lenSz = SetOctetString(custom->valSz, NULL);
28076
    cust_oidSz = SetObjectId(custom->oidSz, NULL);
28077
28078
    /* check for output buffer room */
28079
    if ((word32)(custom->valSz + custom->oidSz + cust_lenSz + cust_oidSz) >
28080
                                                                        outSz) {
28081
        return BUFFER_E;
28082
    }
28083
28084
    /* put sequence with total */
28085
    idx = SetSequence(custom->valSz + custom->oidSz + cust_lenSz + cust_oidSz,
28086
                      output);
28087
28088
    /* put oid header */
28089
    idx += SetObjectId(custom->oidSz, output+idx);
28090
    XMEMCPY(output+idx, custom->oid, custom->oidSz);
28091
    idx += custom->oidSz;
28092
28093
    /* put value */
28094
    idx += SetOctetString(custom->valSz, output+idx);
28095
    XMEMCPY(output+idx, custom->val, custom->valSz);
28096
    idx += custom->valSz;
28097
28098
    return idx;
28099
}
28100
#endif /* WOLFSSL_CUSTOM_OID */
28101
28102
28103
/* encode info from cert into DER encoded format */
28104
static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
28105
                         DsaKey* dsaKey, ecc_key* eccKey,
28106
                         ed25519_key* ed25519Key, ed448_key* ed448Key,
28107
                         falcon_key* falconKey, dilithium_key* dilithiumKey)
28108
{
28109
    int ret;
28110
28111
    (void)eccKey;
28112
    (void)ed25519Key;
28113
    (void)ed448Key;
28114
    (void)falconKey;
28115
    (void)dilithiumKey;
28116
28117
    if (cert == NULL || der == NULL)
28118
        return BAD_FUNC_ARG;
28119
28120
    if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL &&
28121
        dsaKey == NULL && ed448Key == NULL && falconKey == NULL &&
28122
        falconKey == NULL) {
28123
        return PUBLIC_KEY_E;
28124
    }
28125
28126
    /* init */
28127
    XMEMSET(der, 0, sizeof(DerCert));
28128
28129
    /* version */
28130
    der->versionSz = SetMyVersion(cert->version, der->version, FALSE);
28131
28132
    /* subject name */
28133
#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
28134
    if (XSTRLEN((const char*)cert->sbjRaw) > 0) {
28135
        /* Use the raw subject */
28136
        int idx;
28137
28138
        der->subjectSz = min(sizeof(der->subject),
28139
                (word32)XSTRLEN((const char*)cert->sbjRaw));
28140
        /* header */
28141
        idx = SetSequence(der->subjectSz, der->subject);
28142
        if (der->subjectSz + idx > (int)sizeof(der->subject)) {
28143
            return SUBJECT_E;
28144
        }
28145
28146
        XMEMCPY((char*)der->subject + idx, (const char*)cert->sbjRaw,
28147
                der->subjectSz);
28148
        der->subjectSz += idx;
28149
    }
28150
    else
28151
#endif
28152
    {
28153
        der->subjectSz = SetNameEx(der->subject, sizeof(der->subject),
28154
                &cert->subject, cert->heap);
28155
    }
28156
    if (der->subjectSz <= 0)
28157
        return SUBJECT_E;
28158
28159
    /* public key */
28160
#ifndef NO_RSA
28161
    if (cert->keyType == RSA_KEY) {
28162
        if (rsaKey == NULL)
28163
            return PUBLIC_KEY_E;
28164
        der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey,
28165
                                           sizeof(der->publicKey), 1);
28166
    }
28167
#endif
28168
28169
#if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
28170
    if (cert->keyType == DSA_KEY) {
28171
        if (dsaKey == NULL)
28172
            return PUBLIC_KEY_E;
28173
        der->publicKeySz = wc_SetDsaPublicKey(der->publicKey, dsaKey,
28174
                                           sizeof(der->publicKey), 1);
28175
    }
28176
#endif
28177
28178
#ifdef HAVE_ECC
28179
    if (cert->keyType == ECC_KEY) {
28180
        if (eccKey == NULL)
28181
            return PUBLIC_KEY_E;
28182
        der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey,
28183
                                           sizeof(der->publicKey), 1, 0);
28184
    }
28185
#endif
28186
28187
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
28188
    if (cert->keyType == ED25519_KEY) {
28189
        if (ed25519Key == NULL)
28190
            return PUBLIC_KEY_E;
28191
        der->publicKeySz = wc_Ed25519PublicKeyToDer(ed25519Key, der->publicKey,
28192
            (word32)sizeof(der->publicKey), 1);
28193
    }
28194
#endif
28195
28196
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
28197
    if (cert->keyType == ED448_KEY) {
28198
        if (ed448Key == NULL)
28199
            return PUBLIC_KEY_E;
28200
        der->publicKeySz = wc_Ed448PublicKeyToDer(ed448Key, der->publicKey,
28201
            (word32)sizeof(der->publicKey), 1);
28202
    }
28203
#endif
28204
#if defined(HAVE_PQC)
28205
#if defined(HAVE_FALCON)
28206
    if ((cert->keyType == FALCON_LEVEL1_KEY) ||
28207
        (cert->keyType == FALCON_LEVEL5_KEY)) {
28208
        if (falconKey == NULL)
28209
            return PUBLIC_KEY_E;
28210
        der->publicKeySz = wc_Falcon_PublicKeyToDer(falconKey,
28211
            der->publicKey, (word32)sizeof(der->publicKey), 1);
28212
    }
28213
#endif
28214
#if defined(HAVE_DILITHIUM)
28215
    if ((cert->keyType == DILITHIUM_LEVEL2_KEY) ||
28216
        (cert->keyType == DILITHIUM_LEVEL3_KEY) ||
28217
        (cert->keyType == DILITHIUM_LEVEL5_KEY) ||
28218
        (cert->keyType == DILITHIUM_AES_LEVEL2_KEY) ||
28219
        (cert->keyType == DILITHIUM_AES_LEVEL3_KEY) ||
28220
        (cert->keyType == DILITHIUM_AES_LEVEL5_KEY)) {
28221
        if (dilithiumKey == NULL)
28222
            return PUBLIC_KEY_E;
28223
        der->publicKeySz = wc_Dilithium_PublicKeyToDer(dilithiumKey,
28224
            der->publicKey, (word32)sizeof(der->publicKey), 1);
28225
    }
28226
#endif
28227
#endif /* HAVE_PQC */
28228
28229
    if (der->publicKeySz <= 0)
28230
        return PUBLIC_KEY_E;
28231
28232
    /* set the extensions */
28233
    der->extensionsSz = 0;
28234
28235
    /* RFC 5280 : 4.2.1.9. Basic Constraints
28236
     * The pathLenConstraint field is meaningful only if the CA boolean is
28237
     * asserted and the key usage extension, if present, asserts the
28238
     * keyCertSign bit */
28239
    /* Set CA and path length */
28240
    if ((cert->isCA) && (cert->pathLenSet)
28241
#ifdef WOLFSSL_CERT_EXT
28242
        && ((cert->keyUsage & KEYUSE_KEY_CERT_SIGN) || (!cert->keyUsage))
28243
#endif
28244
        ) {
28245
        der->caSz = SetCaWithPathLen(der->ca, sizeof(der->ca), cert->pathLen);
28246
        if (der->caSz <= 0)
28247
            return CA_TRUE_E;
28248
28249
        der->extensionsSz += der->caSz;
28250
    }
28251
    /* Set CA */
28252
    else if (cert->isCA) {
28253
        der->caSz = SetCa(der->ca, sizeof(der->ca));
28254
        if (der->caSz <= 0)
28255
            return CA_TRUE_E;
28256
28257
        der->extensionsSz += der->caSz;
28258
    }
28259
    /* Set Basic Constraint */
28260
    else if (cert->basicConstSet) {
28261
        der->caSz = SetBC(der->ca, sizeof(der->ca));
28262
        if (der->caSz <= 0)
28263
            return EXTENSIONS_E;
28264
28265
        der->extensionsSz += der->caSz;
28266
    }
28267
    else
28268
        der->caSz = 0;
28269
28270
#ifdef WOLFSSL_ALT_NAMES
28271
    /* Alternative Name */
28272
    if (cert->altNamesSz) {
28273
        der->altNamesSz = SetAltNames(der->altNames, sizeof(der->altNames),
28274
                                      cert->altNames, cert->altNamesSz,
28275
                                      cert->altNamesCrit);
28276
        if (der->altNamesSz <= 0)
28277
            return ALT_NAME_E;
28278
28279
        der->extensionsSz += der->altNamesSz;
28280
    }
28281
    else
28282
        der->altNamesSz = 0;
28283
#endif
28284
28285
#ifdef WOLFSSL_CERT_EXT
28286
    /* SKID */
28287
    if (cert->skidSz) {
28288
        /* check the provided SKID size */
28289
        if (cert->skidSz > (int)min(CTC_MAX_SKID_SIZE, sizeof(der->skid)))
28290
            return SKID_E;
28291
28292
        der->skidSz = SetSKID(der->skid, sizeof(der->skid),
28293
                              cert->skid, cert->skidSz);
28294
        if (der->skidSz <= 0)
28295
            return SKID_E;
28296
28297
        der->extensionsSz += der->skidSz;
28298
    }
28299
    else
28300
        der->skidSz = 0;
28301
28302
    /* Key Usage */
28303
    if (cert->keyUsage != 0) {
28304
        der->keyUsageSz = SetKeyUsage(der->keyUsage, sizeof(der->keyUsage),
28305
                                      cert->keyUsage);
28306
        if (der->keyUsageSz <= 0)
28307
            return KEYUSAGE_E;
28308
28309
        der->extensionsSz += der->keyUsageSz;
28310
    }
28311
    else
28312
        der->keyUsageSz = 0;
28313
28314
    /* Extended Key Usage */
28315
    if (cert->extKeyUsage != 0) {
28316
        der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage,
28317
                                sizeof(der->extKeyUsage), cert->extKeyUsage);
28318
        if (der->extKeyUsageSz <= 0)
28319
            return EXTKEYUSAGE_E;
28320
28321
        der->extensionsSz += der->extKeyUsageSz;
28322
    }
28323
    else
28324
        der->extKeyUsageSz = 0;
28325
28326
#endif /* WOLFSSL_CERT_EXT */
28327
28328
#ifdef WOLFSSL_CUSTOM_OID
28329
    /* encode a custom oid and value */
28330
    /* zero returns, means none set */
28331
    ret = SetCustomObjectId(cert, der->extCustom,
28332
        sizeof(der->extCustom), &cert->extCustom);
28333
    if (ret < 0)
28334
        return ret;
28335
    der->extCustomSz = ret;
28336
    der->extensionsSz += der->extCustomSz;
28337
#endif
28338
28339
    /* put extensions */
28340
    if (der->extensionsSz > 0) {
28341
        /* put the start of sequence (ID, Size) */
28342
        der->extensionsSz = SetSequence(der->extensionsSz, der->extensions);
28343
        if (der->extensionsSz <= 0)
28344
            return EXTENSIONS_E;
28345
28346
        /* put CA */
28347
        if (der->caSz) {
28348
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
28349
                                &der->extensionsSz,
28350
                                der->ca, der->caSz);
28351
            if (ret <= 0)
28352
                return EXTENSIONS_E;
28353
        }
28354
28355
#ifdef WOLFSSL_ALT_NAMES
28356
        /* put Alternative Names */
28357
        if (der->altNamesSz) {
28358
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
28359
                                &der->extensionsSz,
28360
                                der->altNames, der->altNamesSz);
28361
            if (ret <= 0)
28362
                return EXTENSIONS_E;
28363
        }
28364
#endif
28365
28366
#ifdef WOLFSSL_CERT_EXT
28367
        /* put SKID */
28368
        if (der->skidSz) {
28369
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
28370
                                &der->extensionsSz,
28371
                                der->skid, der->skidSz);
28372
            if (ret <= 0)
28373
                return EXTENSIONS_E;
28374
        }
28375
28376
        /* put AKID */
28377
        if (der->akidSz) {
28378
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
28379
                                &der->extensionsSz,
28380
                                der->akid, der->akidSz);
28381
            if (ret <= 0)
28382
                return EXTENSIONS_E;
28383
        }
28384
28385
        /* put KeyUsage */
28386
        if (der->keyUsageSz) {
28387
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
28388
                                &der->extensionsSz,
28389
                                der->keyUsage, der->keyUsageSz);
28390
            if (ret <= 0)
28391
                return EXTENSIONS_E;
28392
        }
28393
28394
        /* put ExtendedKeyUsage */
28395
        if (der->extKeyUsageSz) {
28396
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
28397
                                &der->extensionsSz,
28398
                                der->extKeyUsage, der->extKeyUsageSz);
28399
            if (ret <= 0)
28400
                return EXTENSIONS_E;
28401
        }
28402
28403
    #ifdef WOLFSSL_CUSTOM_OID
28404
        if (der->extCustomSz) {
28405
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
28406
                                &der->extensionsSz,
28407
                                der->extCustom, der->extCustomSz);
28408
            if (ret <= 0)
28409
                return EXTENSIONS_E;
28410
        }
28411
    #endif
28412
#endif /* WOLFSSL_CERT_EXT */
28413
    }
28414
28415
    der->attribSz = SetReqAttrib(der->attrib, cert, der->extensionsSz);
28416
    if (der->attribSz <= 0)
28417
        return REQ_ATTRIBUTE_E;
28418
28419
    der->total = der->versionSz + der->subjectSz + der->publicKeySz +
28420
        der->extensionsSz + der->attribSz;
28421
28422
    return 0;
28423
}
28424
28425
28426
/* write DER encoded cert req to buffer, size already checked */
28427
static int WriteCertReqBody(DerCert* der, byte* buf)
28428
{
28429
    int idx;
28430
28431
    /* signed part header */
28432
    idx = SetSequence(der->total, buf);
28433
    /* version */
28434
    if (buf)
28435
        XMEMCPY(buf + idx, der->version, der->versionSz);
28436
    idx += der->versionSz;
28437
    /* subject */
28438
    if (buf)
28439
        XMEMCPY(buf + idx, der->subject, der->subjectSz);
28440
    idx += der->subjectSz;
28441
    /* public key */
28442
    if (buf)
28443
        XMEMCPY(buf + idx, der->publicKey, der->publicKeySz);
28444
    idx += der->publicKeySz;
28445
    /* attributes */
28446
    if (buf)
28447
        XMEMCPY(buf + idx, der->attrib, der->attribSz);
28448
    idx += der->attribSz;
28449
    /* extensions */
28450
    if (der->extensionsSz) {
28451
        if (buf)
28452
            XMEMCPY(buf + idx, der->extensions, min(der->extensionsSz,
28453
                                               (int)sizeof(der->extensions)));
28454
        idx += der->extensionsSz;
28455
    }
28456
28457
    return idx;
28458
}
28459
#endif
28460
28461
#ifdef WOLFSSL_ASN_TEMPLATE
28462
/* ASN.1 template for Certificate Request body.
28463
 * PKCS #10: RFC 2986, 4.1 - CertificationRequestInfo
28464
 */
28465
static const ASNItem certReqBodyASN[] = {
28466
/* SEQ             */ { 0, ASN_SEQUENCE, 1, 1, 0 },
28467
                                             /* version */
28468
/* VER             */     { 1, ASN_INTEGER, 0, 0, 0 },
28469
                                             /* subject */
28470
/* SUBJ_SEQ        */     { 1, ASN_SEQUENCE, 1, 0, 0 },
28471
                                             /* subjectPKInfo */
28472
/* SPUBKEYINFO_SEQ */     { 1, ASN_SEQUENCE, 1, 0, 0 },
28473
                                             /*  attributes*/
28474
/* ATTRS           */     { 1, ASN_CONTEXT_SPECIFIC | 0, 1, 1, 1 },
28475
                                                 /* Challenge Password Attribute */
28476
/* ATTRS_CPW_SEQ   */         { 2, ASN_SEQUENCE, 1, 1, 1 },
28477
/* ATTRS_CPW_OID   */             { 3, ASN_OBJECT_ID, 0, 0, 0 },
28478
/* ATTRS_CPW_SET   */             { 3, ASN_SET, 1, 1, 0 },
28479
/* ATTRS_CPW_PS    */                 { 4, ASN_PRINTABLE_STRING, 0, 0, 0 },
28480
/* ATTRS_CPW_UTF   */                 { 4, ASN_UTF8STRING, 0, 0, 0 },
28481
                                                 /* Extensions Attribute */
28482
/* EXT_SEQ         */         { 2, ASN_SEQUENCE, 1, 1, 1 },
28483
/* EXT_OID         */             { 3, ASN_OBJECT_ID, 0, 0, 0 },
28484
/* EXT_SET         */             { 3, ASN_SET, 1, 1, 0 },
28485
/* EXT_BODY        */                 { 4, ASN_SEQUENCE, 1, 0, 0 },
28486
};
28487
enum {
28488
    CERTREQBODYASN_IDX_SEQ = 0,
28489
    CERTREQBODYASN_IDX_VER,
28490
    CERTREQBODYASN_IDX_SUBJ_SEQ,
28491
    CERTREQBODYASN_IDX_SPUBKEYINFO_SEQ,
28492
    CERTREQBODYASN_IDX_ATTRS,
28493
    CERTREQBODYASN_IDX_ATTRS_CPW_SEQ,
28494
    CERTREQBODYASN_IDX_ATTRS_CPW_OID,
28495
    CERTREQBODYASN_IDX_ATTRS_CPW_SET,
28496
    CERTREQBODYASN_IDX_ATTRS_CPW_PS,
28497
    CERTREQBODYASN_IDX_ATTRS_CPW_UTF,
28498
    CERTREQBODYASN_IDX_EXT_SEQ,
28499
    CERTREQBODYASN_IDX_EXT_OID,
28500
    CERTREQBODYASN_IDX_EXT_SET,
28501
    CERTREQBODYASN_IDX_EXT_BODY,
28502
};
28503
28504
/* Number of items in ASN.1 template for Certificate Request body. */
28505
#define certReqBodyASN_Length (sizeof(certReqBodyASN) / sizeof(ASNItem))
28506
#endif
28507
28508
static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
28509
                   RsaKey* rsaKey, DsaKey* dsaKey, ecc_key* eccKey,
28510
                   ed25519_key* ed25519Key, ed448_key* ed448Key,
28511
                   falcon_key* falconKey, dilithium_key* dilithiumKey)
28512
{
28513
#ifndef WOLFSSL_ASN_TEMPLATE
28514
    int ret;
28515
#ifdef WOLFSSL_SMALL_STACK
28516
    DerCert* der;
28517
#else
28518
    DerCert der[1];
28519
#endif
28520
28521
    if (eccKey)
28522
        cert->keyType = ECC_KEY;
28523
    else if (rsaKey)
28524
        cert->keyType = RSA_KEY;
28525
    else if (dsaKey)
28526
        cert->keyType = DSA_KEY;
28527
    else if (ed25519Key)
28528
        cert->keyType = ED25519_KEY;
28529
    else if (ed448Key)
28530
        cert->keyType = ED448_KEY;
28531
#ifdef HAVE_PQC
28532
#ifdef HAVE_FALCON
28533
    else if ((falconKey != NULL) && (falconKey->level == 1))
28534
        cert->keyType = FALCON_LEVEL1_KEY;
28535
    else if ((falconKey != NULL) && (falconKey->level == 5))
28536
        cert->keyType = FALCON_LEVEL5_KEY;
28537
#endif /* HAVE_FALCON */
28538
#ifdef HAVE_DILITHIUM
28539
    else if ((dilithiumKey != NULL) && (dilithiumKey->level == 2)
28540
             && (dilithiumKey->sym == SHAKE_VARIANT))
28541
        cert->keyType = DILITHIUM_LEVEL2_KEY;
28542
    else if ((dilithiumKey != NULL) && (dilithiumKey->level == 3)
28543
             && (dilithiumKey->sym == SHAKE_VARIANT))
28544
        cert->keyType = DILITHIUM_LEVEL3_KEY;
28545
    else if ((dilithiumKey != NULL) && (dilithiumKey->level == 5)
28546
             && (dilithiumKey->sym == SHAKE_VARIANT))
28547
        cert->keyType = DILITHIUM_LEVEL5_KEY;
28548
    else if ((dilithiumKey != NULL) && (dilithiumKey->level == 2)
28549
             && (dilithiumKey->sym == AES_VARIANT))
28550
        cert->keyType = DILITHIUM_AES_LEVEL2_KEY;
28551
    else if ((dilithiumKey != NULL) && (dilithiumKey->level == 3)
28552
             && (dilithiumKey->sym == AES_VARIANT))
28553
        cert->keyType = DILITHIUM_AES_LEVEL3_KEY;
28554
    else if ((dilithiumKey != NULL) && (dilithiumKey->level == 5)
28555
             && (dilithiumKey->sym == AES_VARIANT))
28556
        cert->keyType = DILITHIUM_AES_LEVEL5_KEY;
28557
#endif /* HAVE_DILITHIUM */
28558
#endif /* HAVE_PQC */
28559
    else
28560
        return BAD_FUNC_ARG;
28561
28562
#ifdef WOLFSSL_SMALL_STACK
28563
    der = (DerCert*)XMALLOC(sizeof(DerCert), cert->heap,
28564
                                                    DYNAMIC_TYPE_TMP_BUFFER);
28565
    if (der == NULL)
28566
        return MEMORY_E;
28567
#endif
28568
28569
    ret = EncodeCertReq(cert, der, rsaKey, dsaKey, eccKey, ed25519Key, ed448Key,
28570
                        falconKey, dilithiumKey);
28571
28572
    if (ret == 0) {
28573
        if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
28574
            ret = BUFFER_E;
28575
        else
28576
            ret = cert->bodySz = WriteCertReqBody(der, derBuffer);
28577
    }
28578
28579
#ifdef WOLFSSL_SMALL_STACK
28580
    XFREE(der, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
28581
#endif
28582
28583
    return ret;
28584
#else
28585
    DECL_ASNSETDATA(dataASN, certReqBodyASN_Length);
28586
    word32 publicKeySz;
28587
    word32 subjectSz = 0;
28588
    word32 extSz;
28589
    int sz = 0;
28590
    int ret = 0;
28591
#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
28592
    word32 sbjRawSz;
28593
#endif
28594
28595
    /* Unused without OQS */
28596
    (void)falconKey;
28597
    (void)dilithiumKey;
28598
28599
    CALLOC_ASNSETDATA(dataASN, certReqBodyASN_Length, ret, cert->heap);
28600
28601
    if (ret == 0) {
28602
        /* Set key type into certificate object based on key passed in. */
28603
        if (rsaKey != NULL) {
28604
            cert->keyType = RSA_KEY;
28605
        }
28606
        else if (eccKey != NULL) {
28607
            cert->keyType = ECC_KEY;
28608
        }
28609
        else if (dsaKey != NULL) {
28610
            cert->keyType = DSA_KEY;
28611
        }
28612
        else if (ed25519Key != NULL) {
28613
            cert->keyType = ED25519_KEY;
28614
        }
28615
        else if (ed448Key != NULL) {
28616
            cert->keyType = ED448_KEY;
28617
        }
28618
#ifdef HAVE_PQC
28619
#ifdef HAVE_FALCON
28620
        else if ((falconKey != NULL) && (falconKey->level == 1)) {
28621
            cert->keyType = FALCON_LEVEL1_KEY;
28622
        }
28623
        else if ((falconKey != NULL) && (falconKey->level == 5)) {
28624
            cert->keyType = FALCON_LEVEL5_KEY;
28625
        }
28626
#endif /* HAVE_FALCON */
28627
#ifdef HAVE_DILITHIUM
28628
        else if ((dilithiumKey != NULL) && (dilithiumKey->level == 2)
28629
                 && (dilithiumKey->sym == SHAKE_VARIANT)) {
28630
            cert->keyType = DILITHIUM_LEVEL2_KEY;
28631
        }
28632
        else if ((dilithiumKey != NULL) && (dilithiumKey->level == 3)
28633
                 && (dilithiumKey->sym == SHAKE_VARIANT)) {
28634
            cert->keyType = DILITHIUM_LEVEL3_KEY;
28635
        }
28636
        else if ((dilithiumKey != NULL) && (dilithiumKey->level == 5)
28637
                 && (dilithiumKey->sym == SHAKE_VARIANT)) {
28638
            cert->keyType = DILITHIUM_LEVEL5_KEY;
28639
        }
28640
        else if ((dilithiumKey != NULL) && (dilithiumKey->level == 2)
28641
                 && (dilithiumKey->sym == AES_VARIANT)) {
28642
            cert->keyType = DILITHIUM_AES_LEVEL2_KEY;
28643
        }
28644
        else if ((dilithiumKey != NULL) && (dilithiumKey->level == 3)
28645
                 && (dilithiumKey->sym == AES_VARIANT)) {
28646
            cert->keyType = DILITHIUM_AES_LEVEL3_KEY;
28647
        }
28648
        else if ((dilithiumKey != NULL) && (dilithiumKey->level == 5)
28649
                 && (dilithiumKey->sym == AES_VARIANT)) {
28650
            cert->keyType = DILITHIUM_AES_LEVEL5_KEY;
28651
        }
28652
#endif /* HAVE_DILITHIUM */
28653
#endif /* HAVE_PQC */
28654
        else {
28655
            ret = BAD_FUNC_ARG;
28656
        }
28657
    }
28658
    if (ret == 0) {
28659
        /* Determine subject name size. */
28660
    #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
28661
        sbjRawSz = (word32)XSTRLEN((const char*)cert->sbjRaw);
28662
        if (sbjRawSz > 0) {
28663
            subjectSz = min(sizeof(cert->sbjRaw), sbjRawSz);
28664
        }
28665
        else
28666
    #endif
28667
        {
28668
            subjectSz = SetNameEx(NULL, WC_ASN_NAME_MAX, &cert->subject, cert->heap);
28669
            ret = subjectSz;
28670
        }
28671
    }
28672
    if (ret >= 0) {
28673
        /* Determine encode public key size. */
28674
         ret = publicKeySz = EncodePublicKey(cert->keyType, NULL, 0, rsaKey,
28675
             eccKey, ed25519Key, ed448Key, dsaKey);
28676
    }
28677
    if (ret >= 0) {
28678
        /* Determine encode extensions size. */
28679
        ret = extSz = EncodeExtensions(cert, NULL, 0, 1);
28680
    }
28681
    if (ret >= 0) {
28682
        /* Set version. */
28683
        SetASN_Int8Bit(&dataASN[CERTREQBODYASN_IDX_VER], cert->version);
28684
    #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
28685
        if (sbjRawSz > 0) {
28686
            /* Put in encoded subject name. */
28687
            SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_SUBJ_SEQ], cert->sbjRaw,
28688
                    subjectSz);
28689
        }
28690
        else
28691
    #endif
28692
        {
28693
            /* Leave space for subject name. */
28694
            SetASN_ReplaceBuffer(&dataASN[CERTREQBODYASN_IDX_SUBJ_SEQ], NULL,
28695
                    subjectSz);
28696
        }
28697
        /* Leave space for public key. */
28698
        SetASN_ReplaceBuffer(&dataASN[CERTREQBODYASN_IDX_SPUBKEYINFO_SEQ],
28699
                NULL, publicKeySz);
28700
        if (cert->challengePw[0] != '\0') {
28701
            /* Add challenge password attribute. */
28702
            /* Set challenge password OID. */
28703
            SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_ATTRS_CPW_OID],
28704
                attrChallengePasswordOid, sizeof(attrChallengePasswordOid));
28705
            /* Enable the ASN template item with the appropriate tag. */
28706
            if (cert->challengePwPrintableString) {
28707
                /* PRINTABLE_STRING - set buffer */
28708
                SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_ATTRS_CPW_PS],
28709
                        (byte*)cert->challengePw,
28710
                        (word32)XSTRLEN(cert->challengePw));
28711
                /* UTF8STRING - don't encode */
28712
                dataASN[CERTREQBODYASN_IDX_ATTRS_CPW_UTF].noOut = 1;
28713
            }
28714
            else {
28715
                /* PRINTABLE_STRING - don't encode */
28716
                dataASN[CERTREQBODYASN_IDX_ATTRS_CPW_PS].noOut = 1;
28717
                /* UTF8STRING - set buffer */
28718
                SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_ATTRS_CPW_UTF],
28719
                        (byte*)cert->challengePw,
28720
                        (word32)XSTRLEN(cert->challengePw));
28721
            }
28722
        }
28723
        else {
28724
            /* Leave out challenge password attribute items. */
28725
            SetASNItem_NoOutNode(dataASN, certReqBodyASN,
28726
                    CERTREQBODYASN_IDX_ATTRS_CPW_SEQ, certReqBodyASN_Length);
28727
        }
28728
        if (extSz > 0) {
28729
            /* Set extension attribute OID. */
28730
            SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_EXT_OID], attrExtensionRequestOid,
28731
                sizeof(attrExtensionRequestOid));
28732
            /* Leave space for data. */
28733
            SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_EXT_BODY], NULL, extSz);
28734
        }
28735
        else {
28736
            /* Leave out extension attribute items. */
28737
            SetASNItem_NoOutNode(dataASN, certReqBodyASN,
28738
                    CERTREQBODYASN_IDX_EXT_SEQ, certReqBodyASN_Length);
28739
        }
28740
28741
        /* Calculate size of encoded certificate request body. */
28742
        ret = SizeASN_Items(certReqBodyASN, dataASN, certReqBodyASN_Length,
28743
                            &sz);
28744
    }
28745
    /* Check buffer is big enough for encoded data. */
28746
    if ((ret == 0) && (sz > (int)derSz)) {
28747
        ret = BUFFER_E;
28748
    }
28749
    if (ret == 0 && derBuffer != NULL) {
28750
        /* Encode certificate request body into buffer. */
28751
        SetASN_Items(certReqBodyASN, dataASN, certReqBodyASN_Length, derBuffer);
28752
28753
        /* Put in generated data */
28754
    #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
28755
        if (sbjRawSz == 0)
28756
    #endif
28757
        {
28758
            /* Encode subject name into space in buffer. */
28759
            ret = SetNameEx(
28760
                (byte*)dataASN[CERTREQBODYASN_IDX_SUBJ_SEQ].data.buffer.data,
28761
                dataASN[CERTREQBODYASN_IDX_SUBJ_SEQ].data.buffer.length,
28762
                &cert->subject, cert->heap);
28763
        }
28764
    }
28765
    if (ret >= 0 && derBuffer != NULL) {
28766
        /* Encode public key into space in buffer. */
28767
        ret = EncodePublicKey(cert->keyType,
28768
            (byte*)dataASN[CERTREQBODYASN_IDX_SPUBKEYINFO_SEQ].data.buffer.data,
28769
            dataASN[CERTREQBODYASN_IDX_SPUBKEYINFO_SEQ].data.buffer.length,
28770
            rsaKey, eccKey, ed25519Key, ed448Key, dsaKey);
28771
    }
28772
    if ((ret >= 0 && derBuffer != NULL) &&
28773
            (!dataASN[CERTREQBODYASN_IDX_EXT_BODY].noOut)) {
28774
        /* Encode extensions into space in buffer. */
28775
        ret = EncodeExtensions(cert,
28776
                (byte*)dataASN[CERTREQBODYASN_IDX_EXT_BODY].data.buffer.data,
28777
                dataASN[CERTREQBODYASN_IDX_EXT_BODY].data.buffer.length, 1);
28778
    }
28779
    if (ret >= 0) {
28780
        /* Store encoded certifcate request body size. */
28781
        cert->bodySz = sz;
28782
        /* Return the encoding size. */
28783
        ret = sz;
28784
    }
28785
28786
    FREE_ASNSETDATA(dataASN, cert->heap);
28787
    return ret;
28788
#endif /* WOLFSSL_ASN_TEMPLATE */
28789
}
28790
28791
int wc_MakeCertReq_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType,
28792
                      void* key)
28793
{
28794
    RsaKey*        rsaKey = NULL;
28795
    DsaKey*        dsaKey = NULL;
28796
    ecc_key*       eccKey = NULL;
28797
    ed25519_key*   ed25519Key = NULL;
28798
    ed448_key*     ed448Key = NULL;
28799
    falcon_key*    falconKey = NULL;
28800
    dilithium_key* dilithiumKey = NULL;
28801
28802
    if (keyType == RSA_TYPE)
28803
        rsaKey = (RsaKey*)key;
28804
    else if (keyType == DSA_TYPE)
28805
        dsaKey = (DsaKey*)key;
28806
    else if (keyType == ECC_TYPE)
28807
        eccKey = (ecc_key*)key;
28808
    else if (keyType == ED25519_TYPE)
28809
        ed25519Key = (ed25519_key*)key;
28810
    else if (keyType == ED448_TYPE)
28811
        ed448Key = (ed448_key*)key;
28812
    else if (keyType == FALCON_LEVEL1_TYPE)
28813
        falconKey = (falcon_key*)key;
28814
    else if (keyType == FALCON_LEVEL5_TYPE)
28815
        falconKey = (falcon_key*)key;
28816
    else if (keyType == DILITHIUM_LEVEL2_TYPE)
28817
        dilithiumKey = (dilithium_key*)key;
28818
    else if (keyType == DILITHIUM_LEVEL3_TYPE)
28819
        dilithiumKey = (dilithium_key*)key;
28820
    else if (keyType == DILITHIUM_LEVEL5_TYPE)
28821
        dilithiumKey = (dilithium_key*)key;
28822
    else if (keyType == DILITHIUM_AES_LEVEL2_TYPE)
28823
        dilithiumKey = (dilithium_key*)key;
28824
    else if (keyType == DILITHIUM_AES_LEVEL3_TYPE)
28825
        dilithiumKey = (dilithium_key*)key;
28826
    else if (keyType == DILITHIUM_AES_LEVEL5_TYPE)
28827
        dilithiumKey = (dilithium_key*)key;
28828
28829
    return MakeCertReq(cert, derBuffer, derSz, rsaKey, dsaKey, eccKey,
28830
                       ed25519Key, ed448Key, falconKey, dilithiumKey);
28831
}
28832
28833
WOLFSSL_ABI
28834
int wc_MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
28835
                   RsaKey* rsaKey, ecc_key* eccKey)
28836
{
28837
    return MakeCertReq(cert, derBuffer, derSz, rsaKey, NULL, eccKey, NULL,
28838
                       NULL, NULL, NULL);
28839
}
28840
#endif /* WOLFSSL_CERT_REQ */
28841
28842
28843
static int SignCert(int requestSz, int sType, byte* buf, word32 buffSz,
28844
                    RsaKey* rsaKey, ecc_key* eccKey, ed25519_key* ed25519Key,
28845
                    ed448_key* ed448Key, falcon_key* falconKey,
28846
                    dilithium_key* dilithiumKey, WC_RNG* rng)
28847
{
28848
    int sigSz = 0;
28849
    void* heap = NULL;
28850
    CertSignCtx* certSignCtx;
28851
#ifndef WOLFSSL_ASYNC_CRYPT
28852
    CertSignCtx  certSignCtx_lcl;
28853
28854
    certSignCtx = &certSignCtx_lcl;
28855
    XMEMSET(certSignCtx, 0, sizeof(CertSignCtx));
28856
#else
28857
    certSignCtx = NULL;
28858
#endif
28859
28860
    if (requestSz < 0)
28861
        return requestSz;
28862
28863
    /* locate ctx */
28864
    if (rsaKey) {
28865
    #ifndef NO_RSA
28866
    #ifdef WOLFSSL_ASYNC_CRYPT
28867
        certSignCtx = &rsaKey->certSignCtx;
28868
    #endif
28869
        heap = rsaKey->heap;
28870
    #else
28871
        return NOT_COMPILED_IN;
28872
    #endif /* NO_RSA */
28873
    }
28874
    else if (eccKey) {
28875
    #ifdef HAVE_ECC
28876
    #ifdef WOLFSSL_ASYNC_CRYPT
28877
        certSignCtx = &eccKey->certSignCtx;
28878
    #endif
28879
        heap = eccKey->heap;
28880
    #else
28881
        return NOT_COMPILED_IN;
28882
    #endif /* HAVE_ECC */
28883
    }
28884
28885
#ifdef WOLFSSL_ASYNC_CRYPT
28886
    if (certSignCtx == NULL) {
28887
        return BAD_FUNC_ARG;
28888
    }
28889
#endif
28890
28891
    if (certSignCtx->sig == NULL) {
28892
        certSignCtx->sig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, heap,
28893
            DYNAMIC_TYPE_TMP_BUFFER);
28894
        if (certSignCtx->sig == NULL)
28895
            return MEMORY_E;
28896
    }
28897
28898
    sigSz = MakeSignature(certSignCtx, buf, requestSz, certSignCtx->sig,
28899
        MAX_ENCODED_SIG_SZ, rsaKey, eccKey, ed25519Key, ed448Key,
28900
        falconKey, dilithiumKey, rng, sType, heap);
28901
#ifdef WOLFSSL_ASYNC_CRYPT
28902
    if (sigSz == WC_PENDING_E) {
28903
        /* Not free'ing certSignCtx->sig here because it could still be in use
28904
         * with async operations. */
28905
        return sigSz;
28906
    }
28907
#endif
28908
28909
    if (sigSz >= 0) {
28910
        if (requestSz + MAX_SEQ_SZ * 2 + sigSz > (int)buffSz)
28911
            sigSz = BUFFER_E;
28912
        else
28913
            sigSz = AddSignature(buf, requestSz, certSignCtx->sig, sigSz,
28914
                                 sType);
28915
    }
28916
28917
    XFREE(certSignCtx->sig, heap, DYNAMIC_TYPE_TMP_BUFFER);
28918
    certSignCtx->sig = NULL;
28919
28920
    return sigSz;
28921
}
28922
28923
int wc_SignCert_ex(int requestSz, int sType, byte* buf, word32 buffSz,
28924
                   int keyType, void* key, WC_RNG* rng)
28925
{
28926
    RsaKey*            rsaKey = NULL;
28927
    ecc_key*           eccKey = NULL;
28928
    ed25519_key*       ed25519Key = NULL;
28929
    ed448_key*         ed448Key = NULL;
28930
    falcon_key*        falconKey = NULL;
28931
    dilithium_key*     dilithiumKey = NULL;
28932
28933
    if (keyType == RSA_TYPE)
28934
        rsaKey = (RsaKey*)key;
28935
    else if (keyType == ECC_TYPE)
28936
        eccKey = (ecc_key*)key;
28937
    else if (keyType == ED25519_TYPE)
28938
        ed25519Key = (ed25519_key*)key;
28939
    else if (keyType == ED448_TYPE)
28940
        ed448Key = (ed448_key*)key;
28941
    else if (keyType == FALCON_LEVEL1_TYPE)
28942
        falconKey = (falcon_key*)key;
28943
    else if (keyType == FALCON_LEVEL5_TYPE)
28944
        falconKey = (falcon_key*)key;
28945
    else if (keyType == DILITHIUM_LEVEL2_TYPE)
28946
        dilithiumKey = (dilithium_key*)key;
28947
    else if (keyType == DILITHIUM_LEVEL3_TYPE)
28948
        dilithiumKey = (dilithium_key*)key;
28949
    else if (keyType == DILITHIUM_LEVEL5_TYPE)
28950
        dilithiumKey = (dilithium_key*)key;
28951
    else if (keyType == DILITHIUM_AES_LEVEL2_TYPE)
28952
        dilithiumKey = (dilithium_key*)key;
28953
    else if (keyType == DILITHIUM_AES_LEVEL3_TYPE)
28954
        dilithiumKey = (dilithium_key*)key;
28955
    else if (keyType == DILITHIUM_AES_LEVEL5_TYPE)
28956
        dilithiumKey = (dilithium_key*)key;
28957
28958
    return SignCert(requestSz, sType, buf, buffSz, rsaKey, eccKey, ed25519Key,
28959
                    ed448Key, falconKey, dilithiumKey, rng);
28960
}
28961
28962
int wc_SignCert(int requestSz, int sType, byte* buf, word32 buffSz,
28963
                RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng)
28964
{
28965
    return SignCert(requestSz, sType, buf, buffSz, rsaKey, eccKey, NULL, NULL,
28966
                    NULL, NULL, rng);
28967
}
28968
28969
WOLFSSL_ABI
28970
int wc_MakeSelfCert(Cert* cert, byte* buf, word32 buffSz,
28971
                    RsaKey* key, WC_RNG* rng)
28972
{
28973
    int ret;
28974
28975
    ret = wc_MakeCert(cert, buf, buffSz, key, NULL, rng);
28976
    if (ret < 0)
28977
        return ret;
28978
28979
    return wc_SignCert(cert->bodySz, cert->sigType,
28980
                       buf, buffSz, key, NULL, rng);
28981
}
28982
28983
28984
#ifdef WOLFSSL_CERT_EXT
28985
28986
/* Get raw subject from cert, which may contain OIDs not parsed by Decode.
28987
   The raw subject pointer will only be valid while "cert" is valid. */
28988
WOLFSSL_ABI
28989
int wc_GetSubjectRaw(byte **subjectRaw, Cert *cert)
28990
{
28991
    int rc = BAD_FUNC_ARG;
28992
    if ((subjectRaw != NULL) && (cert != NULL)) {
28993
        *subjectRaw = cert->sbjRaw;
28994
        rc = 0;
28995
    }
28996
    return rc;
28997
}
28998
28999
/* Set KID from public key */
29000
static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey,
29001
                                 ed25519_key* ed25519Key, ed448_key* ed448Key,
29002
                                 falcon_key* falconKey,
29003
                                 dilithium_key* dilithiumKey, int kid_type)
29004
{
29005
    byte *buf;
29006
    int   bufferSz, ret;
29007
29008
    if (cert == NULL ||
29009
        (rsakey == NULL && eckey == NULL && ed25519Key == NULL &&
29010
         ed448Key == NULL && falconKey == NULL && dilithiumKey == NULL) ||
29011
        (kid_type != SKID_TYPE && kid_type != AKID_TYPE))
29012
        return BAD_FUNC_ARG;
29013
29014
    buf = (byte *)XMALLOC(MAX_PUBLIC_KEY_SZ, cert->heap,
29015
                                                       DYNAMIC_TYPE_TMP_BUFFER);
29016
    if (buf == NULL)
29017
        return MEMORY_E;
29018
29019
    /* Public Key */
29020
    bufferSz = -1;
29021
#ifndef NO_RSA
29022
    /* RSA public key */
29023
    if (rsakey != NULL)
29024
        bufferSz = SetRsaPublicKey(buf, rsakey, MAX_PUBLIC_KEY_SZ, 0);
29025
#endif
29026
#ifdef HAVE_ECC
29027
    /* ECC public key */
29028
    if (eckey != NULL)
29029
        bufferSz = SetEccPublicKey(buf, eckey, MAX_PUBLIC_KEY_SZ, 0, 0);
29030
#endif
29031
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
29032
    /* ED25519 public key */
29033
    if (ed25519Key != NULL) {
29034
        bufferSz = wc_Ed25519PublicKeyToDer(ed25519Key, buf, MAX_PUBLIC_KEY_SZ, 0);
29035
    }
29036
#endif
29037
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
29038
    /* ED448 public key */
29039
    if (ed448Key != NULL) {
29040
        bufferSz = wc_Ed448PublicKeyToDer(ed448Key, buf, MAX_PUBLIC_KEY_SZ, 0);
29041
    }
29042
#endif
29043
#if defined(HAVE_PQC)
29044
#if defined(HAVE_FALCON)
29045
    if (falconKey != NULL) {
29046
        bufferSz = wc_Falcon_PublicKeyToDer(falconKey, buf, MAX_PUBLIC_KEY_SZ,
29047
                                            0);
29048
    }
29049
#endif
29050
#if defined(HAVE_DILITHIUM)
29051
    if (dilithiumKey != NULL) {
29052
        bufferSz = wc_Dilithium_PublicKeyToDer(dilithiumKey, buf,
29053
                                               MAX_PUBLIC_KEY_SZ, 0);
29054
    }
29055
#endif
29056
#endif /* HAVE_PQC */
29057
29058
    if (bufferSz <= 0) {
29059
        XFREE(buf, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
29060
        return PUBLIC_KEY_E;
29061
    }
29062
29063
    /* Compute SKID by hashing public key */
29064
    if (kid_type == SKID_TYPE) {
29065
        ret = CalcHashId(buf, bufferSz, cert->skid);
29066
        cert->skidSz = KEYID_SIZE;
29067
    }
29068
    else if (kid_type == AKID_TYPE) {
29069
        ret = CalcHashId(buf, bufferSz, cert->akid);
29070
        cert->akidSz = KEYID_SIZE;
29071
    }
29072
    else
29073
        ret = BAD_FUNC_ARG;
29074
29075
    XFREE(buf, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
29076
    return ret;
29077
}
29078
29079
int wc_SetSubjectKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key)
29080
{
29081
    RsaKey*            rsaKey = NULL;
29082
    ecc_key*           eccKey = NULL;
29083
    ed25519_key*       ed25519Key = NULL;
29084
    ed448_key*         ed448Key = NULL;
29085
    falcon_key*        falconKey = NULL;
29086
    dilithium_key*     dilithiumKey = NULL;
29087
29088
    if (keyType == RSA_TYPE)
29089
        rsaKey = (RsaKey*)key;
29090
    else if (keyType == ECC_TYPE)
29091
        eccKey = (ecc_key*)key;
29092
    else if (keyType == ED25519_TYPE)
29093
        ed25519Key = (ed25519_key*)key;
29094
    else if (keyType == ED448_TYPE)
29095
        ed448Key = (ed448_key*)key;
29096
    else if (keyType == FALCON_LEVEL1_TYPE)
29097
        falconKey = (falcon_key*)key;
29098
    else if (keyType == FALCON_LEVEL5_TYPE)
29099
        falconKey = (falcon_key*)key;
29100
    else if (keyType == DILITHIUM_LEVEL2_TYPE)
29101
        dilithiumKey = (dilithium_key*)key;
29102
    else if (keyType == DILITHIUM_LEVEL3_TYPE)
29103
        dilithiumKey = (dilithium_key*)key;
29104
    else if (keyType == DILITHIUM_LEVEL5_TYPE)
29105
        dilithiumKey = (dilithium_key*)key;
29106
    else if (keyType == DILITHIUM_AES_LEVEL2_TYPE)
29107
        dilithiumKey = (dilithium_key*)key;
29108
    else if (keyType == DILITHIUM_AES_LEVEL3_TYPE)
29109
        dilithiumKey = (dilithium_key*)key;
29110
    else if (keyType == DILITHIUM_AES_LEVEL5_TYPE)
29111
        dilithiumKey = (dilithium_key*)key;
29112
29113
    return SetKeyIdFromPublicKey(cert, rsaKey, eccKey, ed25519Key, ed448Key,
29114
                                 falconKey, dilithiumKey, SKID_TYPE);
29115
}
29116
29117
/* Set SKID from RSA or ECC public key */
29118
int wc_SetSubjectKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey)
29119
{
29120
    return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, NULL, NULL, NULL,
29121
                                 SKID_TYPE);
29122
}
29123
29124
int wc_SetAuthKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key)
29125
{
29126
    RsaKey*            rsaKey = NULL;
29127
    ecc_key*           eccKey = NULL;
29128
    ed25519_key*       ed25519Key = NULL;
29129
    ed448_key*         ed448Key = NULL;
29130
    falcon_key*        falconKey = NULL;
29131
    dilithium_key*     dilithiumKey = NULL;
29132
29133
    if (keyType == RSA_TYPE)
29134
        rsaKey = (RsaKey*)key;
29135
    else if (keyType == ECC_TYPE)
29136
        eccKey = (ecc_key*)key;
29137
    else if (keyType == ED25519_TYPE)
29138
        ed25519Key = (ed25519_key*)key;
29139
    else if (keyType == ED448_TYPE)
29140
        ed448Key = (ed448_key*)key;
29141
    else if (keyType == FALCON_LEVEL1_TYPE)
29142
        falconKey = (falcon_key*)key;
29143
    else if (keyType == FALCON_LEVEL5_TYPE)
29144
        falconKey = (falcon_key*)key;
29145
    else if (keyType == DILITHIUM_LEVEL2_TYPE)
29146
        dilithiumKey = (dilithium_key*)key;
29147
    else if (keyType == DILITHIUM_LEVEL3_TYPE)
29148
        dilithiumKey = (dilithium_key*)key;
29149
    else if (keyType == DILITHIUM_LEVEL5_TYPE)
29150
        dilithiumKey = (dilithium_key*)key;
29151
    else if (keyType == DILITHIUM_AES_LEVEL2_TYPE)
29152
        dilithiumKey = (dilithium_key*)key;
29153
    else if (keyType == DILITHIUM_AES_LEVEL3_TYPE)
29154
        dilithiumKey = (dilithium_key*)key;
29155
    else if (keyType == DILITHIUM_AES_LEVEL5_TYPE)
29156
        dilithiumKey = (dilithium_key*)key;
29157
29158
    return SetKeyIdFromPublicKey(cert, rsaKey, eccKey, ed25519Key, ed448Key,
29159
                                 falconKey, dilithiumKey, AKID_TYPE);
29160
}
29161
29162
/* Set SKID from RSA or ECC public key */
29163
int wc_SetAuthKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey)
29164
{
29165
    return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, NULL, NULL, NULL,
29166
                                 AKID_TYPE);
29167
}
29168
29169
29170
#if !defined(NO_FILESYSTEM) && !defined(NO_ASN_CRYPT)
29171
29172
/* Set SKID from public key file in PEM */
29173
int wc_SetSubjectKeyId(Cert *cert, const char* file)
29174
{
29175
    int     ret, derSz;
29176
    byte*   der;
29177
    word32  idx;
29178
    RsaKey  *rsakey = NULL;
29179
    ecc_key *eckey = NULL;
29180
29181
    if (cert == NULL || file == NULL)
29182
        return BAD_FUNC_ARG;
29183
29184
    der = (byte*)XMALLOC(MAX_PUBLIC_KEY_SZ, cert->heap, DYNAMIC_TYPE_CERT);
29185
    if (der == NULL) {
29186
        WOLFSSL_MSG("wc_SetSubjectKeyId memory Problem");
29187
        return MEMORY_E;
29188
    }
29189
    derSz = MAX_PUBLIC_KEY_SZ;
29190
29191
    XMEMSET(der, 0, derSz);
29192
    derSz = wc_PemPubKeyToDer(file, der, derSz);
29193
    if (derSz <= 0) {
29194
        XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
29195
        return derSz;
29196
    }
29197
29198
    /* Load PubKey in internal structure */
29199
#ifndef NO_RSA
29200
    rsakey = (RsaKey*) XMALLOC(sizeof(RsaKey), cert->heap, DYNAMIC_TYPE_RSA);
29201
    if (rsakey == NULL) {
29202
        XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
29203
        return MEMORY_E;
29204
    }
29205
29206
    if (wc_InitRsaKey(rsakey, cert->heap) != 0) {
29207
        WOLFSSL_MSG("wc_InitRsaKey failure");
29208
        XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);
29209
        XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
29210
        return MEMORY_E;
29211
    }
29212
29213
    idx = 0;
29214
    ret = wc_RsaPublicKeyDecode(der, &idx, rsakey, derSz);
29215
    if (ret != 0)
29216
#endif
29217
    {
29218
#ifndef NO_RSA
29219
        WOLFSSL_MSG("wc_RsaPublicKeyDecode failed");
29220
        wc_FreeRsaKey(rsakey);
29221
        XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);
29222
        rsakey = NULL;
29223
#endif
29224
#ifdef HAVE_ECC
29225
        /* Check to load ecc public key */
29226
        eckey = (ecc_key*) XMALLOC(sizeof(ecc_key), cert->heap,
29227
                                                              DYNAMIC_TYPE_ECC);
29228
        if (eckey == NULL) {
29229
            XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
29230
            return MEMORY_E;
29231
        }
29232
29233
        if (wc_ecc_init(eckey) != 0) {
29234
            WOLFSSL_MSG("wc_ecc_init failure");
29235
            wc_ecc_free(eckey);
29236
            XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);
29237
            XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
29238
            return MEMORY_E;
29239
        }
29240
29241
        idx = 0;
29242
        ret = wc_EccPublicKeyDecode(der, &idx, eckey, derSz);
29243
        if (ret != 0) {
29244
            WOLFSSL_MSG("wc_EccPublicKeyDecode failed");
29245
            XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
29246
            wc_ecc_free(eckey);
29247
            XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);
29248
            return PUBLIC_KEY_E;
29249
        }
29250
#else
29251
        XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
29252
        return PUBLIC_KEY_E;
29253
#endif /* HAVE_ECC */
29254
    }
29255
29256
    XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
29257
29258
    ret = wc_SetSubjectKeyIdFromPublicKey(cert, rsakey, eckey);
29259
29260
#ifndef NO_RSA
29261
    wc_FreeRsaKey(rsakey);
29262
    XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);
29263
#endif
29264
#ifdef HAVE_ECC
29265
    wc_ecc_free(eckey);
29266
    XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);
29267
#endif
29268
    return ret;
29269
}
29270
29271
#endif /* !NO_FILESYSTEM && !NO_ASN_CRYPT */
29272
29273
static int SetAuthKeyIdFromDcert(Cert* cert, DecodedCert* decoded)
29274
{
29275
    int ret = 0;
29276
29277
    /* Subject Key Id not found !! */
29278
    if (decoded->extSubjKeyIdSet == 0) {
29279
        ret = ASN_NO_SKID;
29280
    }
29281
29282
    /* SKID invalid size */
29283
    else if (sizeof(cert->akid) < sizeof(decoded->extSubjKeyId)) {
29284
        ret = MEMORY_E;
29285
    }
29286
29287
    else {
29288
        /* Put the SKID of CA to AKID of certificate */
29289
        XMEMCPY(cert->akid, decoded->extSubjKeyId, KEYID_SIZE);
29290
        cert->akidSz = KEYID_SIZE;
29291
    }
29292
29293
    return ret;
29294
}
29295
29296
/* Set AKID from certificate contains in buffer (DER encoded) */
29297
int wc_SetAuthKeyIdFromCert(Cert *cert, const byte *der, int derSz)
29298
{
29299
    int ret = 0;
29300
29301
    if (cert == NULL) {
29302
        ret = BAD_FUNC_ARG;
29303
    }
29304
    else {
29305
        /* Check if decodedCert is cached */
29306
        if (cert->der != der) {
29307
            /* Allocate cache for the decoded cert */
29308
            ret = wc_SetCert_LoadDer(cert, der, derSz);
29309
        }
29310
29311
        if (ret >= 0) {
29312
            ret = SetAuthKeyIdFromDcert(cert, (DecodedCert*)cert->decodedCert);
29313
#ifndef WOLFSSL_CERT_GEN_CACHE
29314
            wc_SetCert_Free(cert);
29315
#endif
29316
        }
29317
    }
29318
29319
    return ret;
29320
}
29321
29322
29323
#ifndef NO_FILESYSTEM
29324
29325
/* Set AKID from certificate file in PEM */
29326
int wc_SetAuthKeyId(Cert *cert, const char* file)
29327
{
29328
    int         ret;
29329
    DerBuffer*  der = NULL;
29330
29331
    if (cert == NULL || file == NULL)
29332
        return BAD_FUNC_ARG;
29333
29334
    ret = wc_PemCertToDer_ex(file, &der);
29335
    if (ret == 0)
29336
    {
29337
        ret = wc_SetAuthKeyIdFromCert(cert, der->buffer, der->length);
29338
        FreeDer(&der);
29339
    }
29340
29341
    return ret;
29342
}
29343
29344
#endif /* !NO_FILESYSTEM */
29345
29346
/* Set KeyUsage from human readable string */
29347
int wc_SetKeyUsage(Cert *cert, const char *value)
29348
{
29349
    int ret = 0;
29350
    char *token, *str, *ptr;
29351
    word32 len;
29352
29353
    if (cert == NULL || value == NULL)
29354
        return BAD_FUNC_ARG;
29355
29356
    cert->keyUsage = 0;
29357
29358
    /* duplicate string (including terminator) */
29359
    len = (word32)XSTRLEN(value);
29360
    str = (char*)XMALLOC(len+1, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
29361
    if (str == NULL)
29362
        return MEMORY_E;
29363
    XMEMCPY(str, value, len+1);
29364
29365
    /* parse value, and set corresponding Key Usage value */
29366
    if ((token = XSTRTOK(str, ",", &ptr)) == NULL) {
29367
        XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
29368
        return KEYUSAGE_E;
29369
    }
29370
    while (token != NULL)
29371
    {
29372
        if (!XSTRCASECMP(token, "digitalSignature"))
29373
            cert->keyUsage |= KEYUSE_DIGITAL_SIG;
29374
        else if (!XSTRCASECMP(token, "nonRepudiation") ||
29375
                 !XSTRCASECMP(token, "contentCommitment"))
29376
            cert->keyUsage |= KEYUSE_CONTENT_COMMIT;
29377
        else if (!XSTRCASECMP(token, "keyEncipherment"))
29378
            cert->keyUsage |= KEYUSE_KEY_ENCIPHER;
29379
        else if (!XSTRCASECMP(token, "dataEncipherment"))
29380
            cert->keyUsage |= KEYUSE_DATA_ENCIPHER;
29381
        else if (!XSTRCASECMP(token, "keyAgreement"))
29382
            cert->keyUsage |= KEYUSE_KEY_AGREE;
29383
        else if (!XSTRCASECMP(token, "keyCertSign"))
29384
            cert->keyUsage |= KEYUSE_KEY_CERT_SIGN;
29385
        else if (!XSTRCASECMP(token, "cRLSign"))
29386
            cert->keyUsage |= KEYUSE_CRL_SIGN;
29387
        else if (!XSTRCASECMP(token, "encipherOnly"))
29388
            cert->keyUsage |= KEYUSE_ENCIPHER_ONLY;
29389
        else if (!XSTRCASECMP(token, "decipherOnly"))
29390
            cert->keyUsage |= KEYUSE_DECIPHER_ONLY;
29391
        else {
29392
            ret = KEYUSAGE_E;
29393
            break;
29394
        }
29395
29396
        token = XSTRTOK(NULL, ",", &ptr);
29397
    }
29398
29399
    XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
29400
    return ret;
29401
}
29402
29403
/* Set ExtendedKeyUsage from human readable string */
29404
int wc_SetExtKeyUsage(Cert *cert, const char *value)
29405
{
29406
    int ret = 0;
29407
    char *token, *str, *ptr;
29408
    word32 len;
29409
29410
    if (cert == NULL || value == NULL)
29411
        return BAD_FUNC_ARG;
29412
29413
    cert->extKeyUsage = 0;
29414
29415
    /* duplicate string (including terminator) */
29416
    len = (word32)XSTRLEN(value);
29417
    str = (char*)XMALLOC(len+1, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
29418
    if (str == NULL)
29419
        return MEMORY_E;
29420
    XMEMCPY(str, value, len+1);
29421
29422
    /* parse value, and set corresponding Key Usage value */
29423
    if ((token = XSTRTOK(str, ",", &ptr)) == NULL) {
29424
        XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
29425
        return EXTKEYUSAGE_E;
29426
    }
29427
29428
    while (token != NULL)
29429
    {
29430
        if (!XSTRCASECMP(token, "any"))
29431
            cert->extKeyUsage |= EXTKEYUSE_ANY;
29432
        else if (!XSTRCASECMP(token, "serverAuth"))
29433
            cert->extKeyUsage |= EXTKEYUSE_SERVER_AUTH;
29434
        else if (!XSTRCASECMP(token, "clientAuth"))
29435
            cert->extKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
29436
        else if (!XSTRCASECMP(token, "codeSigning"))
29437
            cert->extKeyUsage |= EXTKEYUSE_CODESIGN;
29438
        else if (!XSTRCASECMP(token, "emailProtection"))
29439
            cert->extKeyUsage |= EXTKEYUSE_EMAILPROT;
29440
        else if (!XSTRCASECMP(token, "timeStamping"))
29441
            cert->extKeyUsage |= EXTKEYUSE_TIMESTAMP;
29442
        else if (!XSTRCASECMP(token, "OCSPSigning"))
29443
            cert->extKeyUsage |= EXTKEYUSE_OCSP_SIGN;
29444
        else {
29445
            ret = EXTKEYUSAGE_E;
29446
            break;
29447
        }
29448
29449
        token = XSTRTOK(NULL, ",", &ptr);
29450
    }
29451
29452
    XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
29453
    return ret;
29454
}
29455
29456
#ifdef WOLFSSL_EKU_OID
29457
/*
29458
 * cert structure to set EKU oid in
29459
 * oid  the oid in byte representation
29460
 * sz   size of oid buffer
29461
 * idx  index of array to place oid
29462
 *
29463
 * returns 0 on success
29464
 */
29465
int wc_SetExtKeyUsageOID(Cert *cert, const char *in, word32 sz, byte idx,
29466
        void* heap)
29467
{
29468
    byte oid[MAX_OID_SZ];
29469
    word32 oidSz = MAX_OID_SZ;
29470
29471
    if (idx >= CTC_MAX_EKU_NB || sz >= CTC_MAX_EKU_OID_SZ) {
29472
        WOLFSSL_MSG("Either idx or sz was too large");
29473
        return BAD_FUNC_ARG;
29474
    }
29475
29476
    if (EncodePolicyOID(oid, &oidSz, in, heap) != 0) {
29477
        return BUFFER_E;
29478
    }
29479
29480
    XMEMCPY(cert->extKeyUsageOID[idx], oid, oidSz);
29481
    cert->extKeyUsageOIDSz[idx] = oidSz;
29482
    cert->extKeyUsage |= EXTKEYUSE_USER;
29483
29484
    return 0;
29485
}
29486
#endif /* WOLFSSL_EKU_OID */
29487
29488
#if defined(WOLFSSL_ASN_TEMPLATE) && defined(WOLFSSL_CERT_GEN) && \
29489
    defined(WOLFSSL_CUSTOM_OID) && defined(HAVE_OID_ENCODING) && \
29490
    defined(WOLFSSL_CERT_EXT)
29491
int wc_SetCustomExtension(Cert *cert, int critical, const char *oid,
29492
                          const byte *der, word32 derSz) {
29493
    CertExtension *ext;
29494
    byte encodedOid[MAX_OID_SZ];
29495
    word32 encodedOidSz = MAX_OID_SZ;
29496
    int ret;
29497
29498
    if (cert == NULL || oid == NULL || der == NULL || derSz == 0) {
29499
        return BAD_FUNC_ARG;
29500
    }
29501
29502
    if (cert->customCertExtCount >= NUM_CUSTOM_EXT) {
29503
        return MEMORY_E;
29504
    }
29505
29506
    /* Make sure we can properly parse the OID. */
29507
    ret = EncodePolicyOID(encodedOid, &encodedOidSz, oid, NULL);
29508
    if (ret != 0) {
29509
        return ret;
29510
    }
29511
29512
    ext = &cert->customCertExt[cert->customCertExtCount];
29513
29514
    ext->oid = oid;
29515
    ext->crit = (critical == 0) ? 0 : 1;
29516
    ext->val = der;
29517
    ext->valSz = derSz;
29518
29519
    cert->customCertExtCount++;
29520
    return 0;
29521
}
29522
#endif
29523
29524
#endif /* WOLFSSL_CERT_EXT */
29525
29526
29527
#ifdef WOLFSSL_ALT_NAMES
29528
29529
static int SetAltNamesFromDcert(Cert* cert, DecodedCert* decoded)
29530
{
29531
    int ret = 0;
29532
29533
    cert->altNamesSz = 0;
29534
    if (decoded->altNames) {
29535
        ret = FlattenAltNames(cert->altNames,
29536
            sizeof(cert->altNames), decoded->altNames);
29537
        if (ret >= 0) {
29538
            cert->altNamesSz = ret;
29539
            ret = 0;
29540
        }
29541
    }
29542
29543
    return ret;
29544
}
29545
29546
#ifndef NO_FILESYSTEM
29547
29548
/* Set Alt Names from der cert, return 0 on success */
29549
static int SetAltNamesFromCert(Cert* cert, const byte* der, int derSz)
29550
{
29551
    int ret;
29552
#ifdef WOLFSSL_SMALL_STACK
29553
    DecodedCert* decoded;
29554
#else
29555
    DecodedCert decoded[1];
29556
#endif
29557
29558
    if (derSz < 0)
29559
        return derSz;
29560
29561
#ifdef WOLFSSL_SMALL_STACK
29562
    decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cert->heap,
29563
                                                       DYNAMIC_TYPE_TMP_BUFFER);
29564
    if (decoded == NULL)
29565
        return MEMORY_E;
29566
#endif
29567
29568
    InitDecodedCert(decoded, der, derSz, NULL);
29569
    ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
29570
29571
    if (ret < 0) {
29572
        WOLFSSL_MSG("ParseCertRelative error");
29573
    }
29574
    else {
29575
        ret = SetAltNamesFromDcert(cert, decoded);
29576
    }
29577
29578
    FreeDecodedCert(decoded);
29579
#ifdef WOLFSSL_SMALL_STACK
29580
    XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
29581
#endif
29582
29583
    return ret < 0 ? ret : 0;
29584
}
29585
29586
#endif
29587
29588
static int SetDatesFromDcert(Cert* cert, DecodedCert* decoded)
29589
{
29590
    int ret = 0;
29591
29592
    if (decoded->beforeDate == NULL || decoded->afterDate == NULL) {
29593
        WOLFSSL_MSG("Couldn't extract dates");
29594
        ret = -1;
29595
    }
29596
    else if (decoded->beforeDateLen > MAX_DATE_SIZE ||
29597
                                        decoded->afterDateLen > MAX_DATE_SIZE) {
29598
        WOLFSSL_MSG("Bad date size");
29599
        ret = -1;
29600
    }
29601
    else {
29602
        XMEMCPY(cert->beforeDate, decoded->beforeDate, decoded->beforeDateLen);
29603
        XMEMCPY(cert->afterDate,  decoded->afterDate,  decoded->afterDateLen);
29604
29605
        cert->beforeDateSz = decoded->beforeDateLen;
29606
        cert->afterDateSz  = decoded->afterDateLen;
29607
    }
29608
29609
    return ret;
29610
}
29611
29612
#endif /* WOLFSSL_ALT_NAMES */
29613
29614
static void SetNameFromDcert(CertName* cn, DecodedCert* decoded)
29615
{
29616
    int sz;
29617
29618
    if (decoded->subjectCN) {
29619
        sz = (decoded->subjectCNLen < CTC_NAME_SIZE) ? decoded->subjectCNLen
29620
                                                     : CTC_NAME_SIZE - 1;
29621
        XSTRNCPY(cn->commonName, decoded->subjectCN, sz);
29622
        cn->commonName[sz] = '\0';
29623
        cn->commonNameEnc = decoded->subjectCNEnc;
29624
    }
29625
    if (decoded->subjectC) {
29626
        sz = (decoded->subjectCLen < CTC_NAME_SIZE) ? decoded->subjectCLen
29627
                                                    : CTC_NAME_SIZE - 1;
29628
        XSTRNCPY(cn->country, decoded->subjectC, sz);
29629
        cn->country[sz] = '\0';
29630
        cn->countryEnc = decoded->subjectCEnc;
29631
    }
29632
    if (decoded->subjectST) {
29633
        sz = (decoded->subjectSTLen < CTC_NAME_SIZE) ? decoded->subjectSTLen
29634
                                                     : CTC_NAME_SIZE - 1;
29635
        XSTRNCPY(cn->state, decoded->subjectST, sz);
29636
        cn->state[sz] = '\0';
29637
        cn->stateEnc = decoded->subjectSTEnc;
29638
    }
29639
    if (decoded->subjectL) {
29640
        sz = (decoded->subjectLLen < CTC_NAME_SIZE) ? decoded->subjectLLen
29641
                                                    : CTC_NAME_SIZE - 1;
29642
        XSTRNCPY(cn->locality, decoded->subjectL, sz);
29643
        cn->locality[sz] = '\0';
29644
        cn->localityEnc = decoded->subjectLEnc;
29645
    }
29646
    if (decoded->subjectO) {
29647
        sz = (decoded->subjectOLen < CTC_NAME_SIZE) ? decoded->subjectOLen
29648
                                                    : CTC_NAME_SIZE - 1;
29649
        XSTRNCPY(cn->org, decoded->subjectO, sz);
29650
        cn->org[sz] = '\0';
29651
        cn->orgEnc = decoded->subjectOEnc;
29652
    }
29653
    if (decoded->subjectOU) {
29654
        sz = (decoded->subjectOULen < CTC_NAME_SIZE) ? decoded->subjectOULen
29655
                                                     : CTC_NAME_SIZE - 1;
29656
        XSTRNCPY(cn->unit, decoded->subjectOU, sz);
29657
        cn->unit[sz] = '\0';
29658
        cn->unitEnc = decoded->subjectOUEnc;
29659
    }
29660
    if (decoded->subjectSN) {
29661
        sz = (decoded->subjectSNLen < CTC_NAME_SIZE) ? decoded->subjectSNLen
29662
                                                     : CTC_NAME_SIZE - 1;
29663
        XSTRNCPY(cn->sur, decoded->subjectSN, sz);
29664
        cn->sur[sz] = '\0';
29665
        cn->surEnc = decoded->subjectSNEnc;
29666
    }
29667
    if (decoded->subjectSND) {
29668
        sz = (decoded->subjectSNDLen < CTC_NAME_SIZE) ? decoded->subjectSNDLen
29669
                                                     : CTC_NAME_SIZE - 1;
29670
        XSTRNCPY(cn->serialDev, decoded->subjectSND, sz);
29671
        cn->serialDev[sz] = '\0';
29672
        cn->serialDevEnc = decoded->subjectSNDEnc;
29673
    }
29674
    if (decoded->subjectUID) {
29675
        sz = (decoded->subjectUIDLen < CTC_NAME_SIZE) ? decoded->subjectUIDLen
29676
                                                     : CTC_NAME_SIZE - 1;
29677
        XSTRNCPY(cn->userId, decoded->subjectUID, sz);
29678
        cn->userId[sz] = '\0';
29679
        cn->userIdEnc = decoded->subjectUIDEnc;
29680
    }
29681
#ifdef WOLFSSL_CERT_EXT
29682
    if (decoded->subjectBC) {
29683
        sz = (decoded->subjectBCLen < CTC_NAME_SIZE) ? decoded->subjectBCLen
29684
                                                     : CTC_NAME_SIZE - 1;
29685
        XSTRNCPY(cn->busCat, decoded->subjectBC, sz);
29686
        cn->busCat[sz] = '\0';
29687
        cn->busCatEnc = decoded->subjectBCEnc;
29688
    }
29689
    if (decoded->subjectJC) {
29690
        sz = (decoded->subjectJCLen < CTC_NAME_SIZE) ? decoded->subjectJCLen
29691
                                                     : CTC_NAME_SIZE - 1;
29692
        XSTRNCPY(cn->joiC, decoded->subjectJC, sz);
29693
        cn->joiC[sz] = '\0';
29694
        cn->joiCEnc = decoded->subjectJCEnc;
29695
    }
29696
    if (decoded->subjectJS) {
29697
        sz = (decoded->subjectJSLen < CTC_NAME_SIZE) ? decoded->subjectJSLen
29698
                                                     : CTC_NAME_SIZE - 1;
29699
        XSTRNCPY(cn->joiSt, decoded->subjectJS, sz);
29700
        cn->joiSt[sz] = '\0';
29701
        cn->joiStEnc = decoded->subjectJSEnc;
29702
    }
29703
#endif
29704
    if (decoded->subjectEmail) {
29705
        sz = (decoded->subjectEmailLen < CTC_NAME_SIZE)
29706
           ?  decoded->subjectEmailLen : CTC_NAME_SIZE - 1;
29707
        XSTRNCPY(cn->email, decoded->subjectEmail, sz);
29708
        cn->email[sz] = '\0';
29709
    }
29710
#if defined(WOLFSSL_CERT_NAME_ALL) && \
29711
    (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT))
29712
    if (decoded->subjectN) {
29713
        sz = (decoded->subjectNLen < CTC_NAME_SIZE) ? decoded->subjectNLen
29714
                                                     : CTC_NAME_SIZE - 1;
29715
        XSTRNCPY(cn->dnName, decoded->subjectN, sz);
29716
        cn->dnName[sz] = '\0';
29717
        cn->dnNameEnc = decoded->subjectNEnc;
29718
    }
29719
    if (decoded->subjectI) {
29720
        sz = (decoded->subjectILen < CTC_NAME_SIZE) ? decoded->subjectILen
29721
                                                     : CTC_NAME_SIZE - 1;
29722
        XSTRNCPY(cn->initials, decoded->subjectI, sz);
29723
        cn->initials[sz] = '\0';
29724
        cn->initialsEnc = decoded->subjectIEnc;
29725
    }
29726
    if (decoded->subjectGN) {
29727
        sz = (decoded->subjectGNLen < CTC_NAME_SIZE) ? decoded->subjectGNLen
29728
                                                     : CTC_NAME_SIZE - 1;
29729
        XSTRNCPY(cn->givenName, decoded->subjectGN, sz);
29730
        cn->givenName[sz] = '\0';
29731
        cn->givenNameEnc = decoded->subjectGNEnc;
29732
    }
29733
    if (decoded->subjectDNQ) {
29734
        sz = (decoded->subjectDNQLen < CTC_NAME_SIZE) ? decoded->subjectDNQLen
29735
                                                     : CTC_NAME_SIZE - 1;
29736
        XSTRNCPY(cn->dnQualifier, decoded->subjectDNQ, sz);
29737
        cn->dnQualifier[sz] = '\0';
29738
        cn->dnQualifierEnc = decoded->subjectDNQEnc;
29739
    }
29740
#endif /* WOLFSSL_CERT_NAME_ALL */
29741
}
29742
29743
#ifndef NO_FILESYSTEM
29744
29745
/* Set cn name from der buffer, return 0 on success */
29746
static int SetNameFromCert(CertName* cn, const byte* der, int derSz)
29747
{
29748
    int ret;
29749
#ifdef WOLFSSL_SMALL_STACK
29750
    DecodedCert* decoded;
29751
#else
29752
    DecodedCert decoded[1];
29753
#endif
29754
29755
    if (derSz < 0)
29756
        return derSz;
29757
29758
#ifdef WOLFSSL_SMALL_STACK
29759
    decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
29760
                                                       DYNAMIC_TYPE_TMP_BUFFER);
29761
    if (decoded == NULL)
29762
        return MEMORY_E;
29763
#endif
29764
29765
    InitDecodedCert(decoded, der, derSz, NULL);
29766
    ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
29767
29768
    if (ret < 0) {
29769
        WOLFSSL_MSG("ParseCertRelative error");
29770
    }
29771
    else {
29772
        SetNameFromDcert(cn, decoded);
29773
    }
29774
29775
    FreeDecodedCert(decoded);
29776
29777
#ifdef WOLFSSL_SMALL_STACK
29778
    XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
29779
#endif
29780
29781
    return ret < 0 ? ret : 0;
29782
}
29783
29784
/* Set cert issuer from issuerFile in PEM */
29785
WOLFSSL_ABI
29786
int wc_SetIssuer(Cert* cert, const char* issuerFile)
29787
{
29788
    int         ret;
29789
    DerBuffer*  der = NULL;
29790
29791
    if (cert == NULL || issuerFile == NULL)
29792
        return BAD_FUNC_ARG;
29793
29794
    ret = wc_PemCertToDer_ex(issuerFile, &der);
29795
    if (ret == 0) {
29796
        cert->selfSigned = 0;
29797
        ret = SetNameFromCert(&cert->issuer, der->buffer, der->length);
29798
29799
        FreeDer(&der);
29800
    }
29801
29802
    return ret;
29803
}
29804
29805
29806
/* Set cert subject from subjectFile in PEM */
29807
WOLFSSL_ABI
29808
int wc_SetSubject(Cert* cert, const char* subjectFile)
29809
{
29810
    int         ret;
29811
    DerBuffer*  der = NULL;
29812
29813
    if (cert == NULL || subjectFile == NULL)
29814
        return BAD_FUNC_ARG;
29815
29816
    ret = wc_PemCertToDer_ex(subjectFile, &der);
29817
    if (ret == 0) {
29818
        ret = SetNameFromCert(&cert->subject, der->buffer, der->length);
29819
29820
        FreeDer(&der);
29821
    }
29822
29823
    return ret;
29824
}
29825
29826
#ifdef WOLFSSL_ALT_NAMES
29827
29828
/* Set alt names from file in PEM */
29829
WOLFSSL_ABI
29830
int wc_SetAltNames(Cert* cert, const char* file)
29831
{
29832
    int         ret;
29833
    DerBuffer*  der = NULL;
29834
29835
    if (cert == NULL) {
29836
        return BAD_FUNC_ARG;
29837
    }
29838
29839
    ret = wc_PemCertToDer_ex(file, &der);
29840
    if (ret == 0) {
29841
        ret = SetAltNamesFromCert(cert, der->buffer, der->length);
29842
29843
        FreeDer(&der);
29844
    }
29845
29846
    return ret;
29847
}
29848
29849
#endif /* WOLFSSL_ALT_NAMES */
29850
29851
#endif /* !NO_FILESYSTEM */
29852
29853
/* Set cert issuer from DER buffer */
29854
WOLFSSL_ABI
29855
int wc_SetIssuerBuffer(Cert* cert, const byte* der, int derSz)
29856
{
29857
    int ret = 0;
29858
29859
    if (cert == NULL) {
29860
        ret = BAD_FUNC_ARG;
29861
    }
29862
    else {
29863
        cert->selfSigned = 0;
29864
29865
        /* Check if decodedCert is cached */
29866
        if (cert->der != der) {
29867
            /* Allocate cache for the decoded cert */
29868
            ret = wc_SetCert_LoadDer(cert, der, derSz);
29869
        }
29870
29871
        if (ret >= 0) {
29872
            SetNameFromDcert(&cert->issuer, (DecodedCert*)cert->decodedCert);
29873
#ifndef WOLFSSL_CERT_GEN_CACHE
29874
            wc_SetCert_Free(cert);
29875
#endif
29876
        }
29877
    }
29878
29879
    return ret;
29880
}
29881
29882
/* Set cert subject from DER buffer */
29883
WOLFSSL_ABI
29884
int wc_SetSubjectBuffer(Cert* cert, const byte* der, int derSz)
29885
{
29886
    int ret = 0;
29887
29888
    if (cert == NULL) {
29889
        ret = BAD_FUNC_ARG;
29890
    }
29891
    else {
29892
        /* Check if decodedCert is cached */
29893
        if (cert->der != der) {
29894
            /* Allocate cache for the decoded cert */
29895
            ret = wc_SetCert_LoadDer(cert, der, derSz);
29896
        }
29897
29898
        if (ret >= 0) {
29899
            SetNameFromDcert(&cert->subject, (DecodedCert*)cert->decodedCert);
29900
#ifndef WOLFSSL_CERT_GEN_CACHE
29901
            wc_SetCert_Free(cert);
29902
#endif
29903
        }
29904
    }
29905
29906
    return ret;
29907
}
29908
#ifdef WOLFSSL_CERT_EXT
29909
/* Set cert raw subject from DER buffer */
29910
WOLFSSL_ABI
29911
int wc_SetSubjectRaw(Cert* cert, const byte* der, int derSz)
29912
{
29913
    int ret = 0;
29914
29915
    if (cert == NULL) {
29916
        ret = BAD_FUNC_ARG;
29917
    }
29918
    else {
29919
        /* Check if decodedCert is cached */
29920
        if (cert->der != der) {
29921
            /* Allocate cache for the decoded cert */
29922
            ret = wc_SetCert_LoadDer(cert, der, derSz);
29923
        }
29924
29925
        if (ret >= 0) {
29926
            if ((((DecodedCert*)cert->decodedCert)->subjectRaw) &&
29927
                (((DecodedCert*)cert->decodedCert)->subjectRawLen <=
29928
                        (int)sizeof(CertName))) {
29929
                XMEMCPY(cert->sbjRaw,
29930
                        ((DecodedCert*)cert->decodedCert)->subjectRaw,
29931
                        ((DecodedCert*)cert->decodedCert)->subjectRawLen);
29932
            }
29933
#ifndef WOLFSSL_CERT_GEN_CACHE
29934
            wc_SetCert_Free(cert);
29935
#endif
29936
        }
29937
    }
29938
29939
    return ret;
29940
}
29941
29942
/* Set cert raw issuer from DER buffer */
29943
WOLFSSL_ABI
29944
int wc_SetIssuerRaw(Cert* cert, const byte* der, int derSz)
29945
{
29946
    int ret = 0;
29947
29948
    if (cert == NULL) {
29949
        ret = BAD_FUNC_ARG;
29950
    }
29951
    else {
29952
        /* Check if decodedCert is cached */
29953
        if (cert->der != der) {
29954
            /* Allocate cache for the decoded cert */
29955
            ret = wc_SetCert_LoadDer(cert, der, derSz);
29956
        }
29957
29958
        if (ret >= 0) {
29959
            if ((((DecodedCert*)cert->decodedCert)->subjectRaw) &&
29960
                (((DecodedCert*)cert->decodedCert)->subjectRawLen <=
29961
                        (int)sizeof(CertName))) {
29962
                /* Copy the subject to the issuer field */
29963
                XMEMCPY(cert->issRaw,
29964
                        ((DecodedCert*)cert->decodedCert)->subjectRaw,
29965
                        ((DecodedCert*)cert->decodedCert)->subjectRawLen);
29966
            }
29967
#ifndef WOLFSSL_CERT_GEN_CACHE
29968
            wc_SetCert_Free(cert);
29969
#endif
29970
        }
29971
    }
29972
    return ret;
29973
}
29974
#endif
29975
29976
#ifdef WOLFSSL_ALT_NAMES
29977
29978
/* Set cert alt names from DER buffer */
29979
WOLFSSL_ABI
29980
int wc_SetAltNamesBuffer(Cert* cert, const byte* der, int derSz)
29981
{
29982
    int ret = 0;
29983
29984
    if (cert == NULL) {
29985
       ret = BAD_FUNC_ARG;
29986
    }
29987
    else {
29988
        /* Check if decodedCert is cached */
29989
        if (cert->der != der) {
29990
            /* Allocate cache for the decoded cert */
29991
            ret = wc_SetCert_LoadDer(cert, der, derSz);
29992
        }
29993
29994
        if (ret >= 0) {
29995
            ret = SetAltNamesFromDcert(cert, (DecodedCert*)cert->decodedCert);
29996
#ifndef WOLFSSL_CERT_GEN_CACHE
29997
            wc_SetCert_Free(cert);
29998
#endif
29999
       }
30000
    }
30001
30002
    return(ret);
30003
}
30004
30005
/* Set cert dates from DER buffer */
30006
WOLFSSL_ABI
30007
int wc_SetDatesBuffer(Cert* cert, const byte* der, int derSz)
30008
{
30009
    int ret = 0;
30010
30011
    if (cert == NULL) {
30012
     ret = BAD_FUNC_ARG;
30013
    }
30014
    else {
30015
        /* Check if decodedCert is cached */
30016
        if (cert->der != der) {
30017
            /* Allocate cache for the decoded cert */
30018
            ret = wc_SetCert_LoadDer(cert, der, derSz);
30019
        }
30020
30021
        if (ret >= 0) {
30022
            ret = SetDatesFromDcert(cert, (DecodedCert*)cert->decodedCert);
30023
#ifndef WOLFSSL_CERT_GEN_CACHE
30024
            wc_SetCert_Free(cert);
30025
#endif
30026
        }
30027
    }
30028
30029
    return(ret);
30030
}
30031
30032
#endif /* WOLFSSL_ALT_NAMES */
30033
30034
#endif /* WOLFSSL_CERT_GEN */
30035
30036
#if (defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT)) \
30037
        || defined(OPENSSL_EXTRA)
30038
/* Encode OID string representation to ITU-T X.690 format */
30039
int EncodePolicyOID(byte *out, word32 *outSz, const char *in, void* heap)
30040
{
30041
    word32 val, idx = 0, nb_val;
30042
    char *token, *str, *ptr;
30043
    word32 len;
30044
30045
    (void)heap;
30046
30047
    if (out == NULL || outSz == NULL || *outSz < 2 || in == NULL)
30048
        return BAD_FUNC_ARG;
30049
30050
    /* duplicate string (including terminator) */
30051
    len = (word32)XSTRLEN(in);
30052
    str = (char *)XMALLOC(len+1, heap, DYNAMIC_TYPE_TMP_BUFFER);
30053
    if (str == NULL)
30054
        return MEMORY_E;
30055
    XMEMCPY(str, in, len+1);
30056
30057
    nb_val = 0;
30058
30059
    /* parse value, and set corresponding Policy OID value */
30060
    token = XSTRTOK(str, ".", &ptr);
30061
    while (token != NULL)
30062
    {
30063
        val = (word32)XATOI(token);
30064
30065
        if (nb_val == 0) {
30066
            if (val > 2) {
30067
                XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
30068
                return ASN_OBJECT_ID_E;
30069
            }
30070
30071
            out[idx] = (byte)(40 * val);
30072
        }
30073
        else if (nb_val == 1) {
30074
            if (val > 127) {
30075
                XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
30076
                return ASN_OBJECT_ID_E;
30077
            }
30078
30079
            if (idx > *outSz) {
30080
                XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
30081
                return BUFFER_E;
30082
            }
30083
30084
            out[idx++] += (byte)val;
30085
        }
30086
        else {
30087
            word32  tb = 0, x;
30088
            int     i = 0;
30089
            byte    oid[MAX_OID_SZ];
30090
30091
            while (val >= 128) {
30092
                x = val % 128;
30093
                val /= 128;
30094
                oid[i++] = (byte) (((tb++) ? 0x80 : 0) | x);
30095
            }
30096
30097
            if ((idx+(word32)i) >= *outSz) {
30098
                XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
30099
                return BUFFER_E;
30100
            }
30101
30102
            oid[i] = (byte) (((tb++) ? 0x80 : 0) | val);
30103
30104
            /* push value in the right order */
30105
            while (i >= 0)
30106
                out[idx++] = oid[i--];
30107
        }
30108
30109
        token = XSTRTOK(NULL, ".", &ptr);
30110
        nb_val++;
30111
    }
30112
30113
    *outSz = idx;
30114
30115
    XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
30116
    return 0;
30117
}
30118
#endif /* WOLFSSL_CERT_EXT || OPENSSL_EXTRA */
30119
30120
#endif /* !NO_CERTS */
30121
30122
#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL))
30123
/* Helper function for wolfSSL_i2d_DHparams */
30124
int StoreDHparams(byte* out, word32* outLen, mp_int* p, mp_int* g)
30125
{
30126
#ifndef WOLFSSL_ASN_TEMPLATE
30127
    word32 idx = 0;
30128
    word32 total;
30129
30130
    WOLFSSL_ENTER("StoreDHparams");
30131
30132
    if (out == NULL) {
30133
        WOLFSSL_MSG("Null buffer error");
30134
        return BUFFER_E;
30135
    }
30136
30137
    /* determine size */
30138
    /* integer - g */
30139
    idx = SetASNIntMP(g, -1, NULL);
30140
    /* integer - p */
30141
    idx += SetASNIntMP(p, -1, NULL);
30142
    total = idx;
30143
     /* sequence */
30144
    idx += SetSequence(idx, NULL);
30145
30146
    /* make sure output fits in buffer */
30147
    if (idx > *outLen) {
30148
        return BUFFER_E;
30149
    }
30150
30151
    /* write DH parameters */
30152
    /* sequence - for P and G only */
30153
    idx = SetSequence(total, out);
30154
    /* integer - p */
30155
    idx += SetASNIntMP(p, -1, out + idx);
30156
    /* integer - g */
30157
    idx += SetASNIntMP(g, -1, out + idx);
30158
    *outLen = idx;
30159
30160
    return 0;
30161
#else
30162
    ASNSetData dataASN[dhParamASN_Length];
30163
    int ret = 0;
30164
    int sz = 0;
30165
30166
    WOLFSSL_ENTER("StoreDHparams");
30167
    if (out == NULL) {
30168
        ret = BUFFER_E;
30169
    }
30170
    if (ret == 0) {
30171
        XMEMSET(dataASN, 0, sizeof(dataASN));
30172
        /* Set mp_int containing p and g. */
30173
        SetASN_MP(&dataASN[DHPARAMASN_IDX_PRIME], p);
30174
        SetASN_MP(&dataASN[DHPARAMASN_IDX_BASE], g);
30175
        /* privateValueLength not encoded. */
30176
        dataASN[DHPARAMASN_IDX_PRIVLEN].noOut = 1;
30177
30178
        /* Calculate the size of the DH parameters. */
30179
        ret = SizeASN_Items(dhParamASN, dataASN, dhParamASN_Length, &sz);
30180
    }
30181
    /* Check buffer is big enough for encoding. */
30182
    if ((ret == 0) && ((int)*outLen < sz)) {
30183
        ret = BUFFER_E;
30184
    }
30185
    if (ret == 0) {
30186
        /* Encode the DH parameters into buffer. */
30187
        SetASN_Items(dhParamASN, dataASN, dhParamASN_Length, out);
30188
        /* Set the actual encoding size. */
30189
        *outLen = sz;
30190
    }
30191
30192
    return ret;
30193
#endif /* WOLFSSL_ASN_TEMPLATE */
30194
}
30195
#endif /* !NO_DH && (WOLFSSL_QT || OPENSSL_ALL) */
30196
30197
#if defined(HAVE_ECC) || !defined(NO_DSA)
30198
30199
#ifdef WOLFSSL_ASN_TEMPLATE
30200
/* ASN.1 template for DSA signature.
30201
 * RFC 5912, 6 - DSA-Sig-Value
30202
 */
30203
static const ASNItem dsaSigASN[] = {
30204
/* SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 },
30205
                            /* r */
30206
/* R   */     { 1, ASN_INTEGER, 0, 0, 0 },
30207
                            /* s */
30208
/* S   */     { 1, ASN_INTEGER, 0, 0, 0 },
30209
};
30210
enum {
30211
    DSASIGASN_IDX_SEQ = 0,
30212
    DSASIGASN_IDX_R,
30213
    DSASIGASN_IDX_S,
30214
};
30215
30216
#define dsaSigASN_Length (sizeof(dsaSigASN) / sizeof(ASNItem))
30217
#endif
30218
30219
/* Der Encode r & s ints into out, outLen is (in/out) size */
30220
int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s)
30221
2.59k
{
30222
2.59k
#ifndef WOLFSSL_ASN_TEMPLATE
30223
2.59k
    word32 idx = 0;
30224
2.59k
    int    rSz;                           /* encoding size */
30225
2.59k
    int    sSz;
30226
2.59k
    word32 headerSz = 4;   /* 2*ASN_TAG + 2*LEN(ENUM) */
30227
30228
    /* If the leading bit on the INTEGER is a 1, add a leading zero */
30229
2.59k
    int rLeadingZero = mp_leading_bit(r);
30230
2.59k
    int sLeadingZero = mp_leading_bit(s);
30231
2.59k
    int rLen = mp_unsigned_bin_size(r);   /* big int size */
30232
2.59k
    int sLen = mp_unsigned_bin_size(s);
30233
30234
2.59k
    if (*outLen < (rLen + rLeadingZero + sLen + sLeadingZero +
30235
2.59k
                   headerSz + 2))  /* SEQ_TAG + LEN(ENUM) */
30236
43
        return BUFFER_E;
30237
30238
2.54k
    idx = SetSequence(rLen + rLeadingZero + sLen+sLeadingZero + headerSz, out);
30239
30240
    /* store r */
30241
2.54k
    rSz = SetASNIntMP(r, *outLen - idx, &out[idx]);
30242
2.54k
    if (rSz < 0)
30243
0
        return rSz;
30244
2.54k
    idx += rSz;
30245
30246
    /* store s */
30247
2.54k
    sSz = SetASNIntMP(s, *outLen - idx, &out[idx]);
30248
2.54k
    if (sSz < 0)
30249
4
        return sSz;
30250
2.54k
    idx += sSz;
30251
30252
2.54k
    *outLen = idx;
30253
30254
2.54k
    return 0;
30255
#else
30256
    ASNSetData dataASN[dsaSigASN_Length];
30257
    int ret;
30258
    int sz;
30259
30260
    /* Clear dynamic data and set mp_ints r and s */
30261
    XMEMSET(dataASN, 0, sizeof(dataASN));
30262
    SetASN_MP(&dataASN[DSASIGASN_IDX_R], r);
30263
    SetASN_MP(&dataASN[DSASIGASN_IDX_S], s);
30264
30265
    /* Calculate size of encoding. */
30266
    ret = SizeASN_Items(dsaSigASN, dataASN, dsaSigASN_Length, &sz);
30267
    /* Check buffer is big enough for encoding. */
30268
    if ((ret == 0) && ((int)*outLen < sz)) {
30269
       ret = BUFFER_E;
30270
    }
30271
    if (ret == 0) {
30272
        /* Encode DSA signature into buffer. */
30273
        SetASN_Items(dsaSigASN, dataASN, dsaSigASN_Length, out);
30274
        /* Set the actual encoding size. */
30275
        *outLen = sz;
30276
    }
30277
30278
    return ret;
30279
#endif /* WOLFSSL_ASN_TEMPLATE */
30280
2.54k
}
30281
30282
#ifndef WOLFSSL_ASN_TEMPLATE
30283
/* determine if leading bit is set */
30284
static int is_leading_bit_set(const byte* input, word32 sz)
30285
0
{
30286
0
    byte c = 0;
30287
0
    if (sz > 0)
30288
0
        c = input[0];
30289
0
    return (c & 0x80) != 0;
30290
0
}
30291
static int trim_leading_zeros(const byte** input, word32 sz)
30292
0
{
30293
0
    int i, leadingZeroCount = 0;
30294
0
    const byte* tmp = *input;
30295
0
    for (i=0; i<(int)sz; i++) {
30296
0
        if (tmp[i] != 0)
30297
0
            break;
30298
0
        leadingZeroCount++;
30299
0
    }
30300
    /* catch all zero case */
30301
0
    if (sz > 0 && leadingZeroCount == (int)sz) {
30302
0
        leadingZeroCount--;
30303
0
    }
30304
0
    *input += leadingZeroCount;
30305
0
    sz -= leadingZeroCount;
30306
0
    return sz;
30307
0
}
30308
#endif
30309
30310
/* Der Encode r & s ints into out, outLen is (in/out) size */
30311
/* All input/outputs are assumed to be big-endian */
30312
int StoreECC_DSA_Sig_Bin(byte* out, word32* outLen, const byte* r, word32 rLen,
30313
    const byte* s, word32 sLen)
30314
0
{
30315
0
#ifndef WOLFSSL_ASN_TEMPLATE
30316
0
    int ret;
30317
0
    word32 idx;
30318
0
    word32 headerSz = 4;   /* 2*ASN_TAG + 2*LEN(ENUM) */
30319
0
    int rAddLeadZero, sAddLeadZero;
30320
30321
0
    if ((out == NULL) || (outLen == NULL) || (r == NULL) || (s == NULL))
30322
0
        return BAD_FUNC_ARG;
30323
30324
    /* Trim leading zeros */
30325
0
    rLen = trim_leading_zeros(&r, rLen);
30326
0
    sLen = trim_leading_zeros(&s, sLen);
30327
    /* If the leading bit on the INTEGER is a 1, add a leading zero */
30328
    /* Add leading zero if MSB is set */
30329
0
    rAddLeadZero = is_leading_bit_set(r, rLen);
30330
0
    sAddLeadZero = is_leading_bit_set(s, sLen);
30331
30332
0
    if (*outLen < (rLen + rAddLeadZero + sLen + sAddLeadZero +
30333
0
                   headerSz + 2))  /* SEQ_TAG + LEN(ENUM) */
30334
0
        return BUFFER_E;
30335
30336
0
    idx = SetSequence(rLen+rAddLeadZero + sLen+sAddLeadZero + headerSz, out);
30337
30338
    /* store r */
30339
0
    ret = SetASNInt(rLen, rAddLeadZero ? 0x80 : 0x00, &out[idx]);
30340
0
    if (ret < 0)
30341
0
        return ret;
30342
0
    idx += ret;
30343
0
    XMEMCPY(&out[idx], r, rLen);
30344
0
    idx += rLen;
30345
30346
    /* store s */
30347
0
    ret = SetASNInt(sLen, sAddLeadZero ? 0x80 : 0x00, &out[idx]);
30348
0
    if (ret < 0)
30349
0
        return ret;
30350
0
    idx += ret;
30351
0
    XMEMCPY(&out[idx], s, sLen);
30352
0
    idx += sLen;
30353
30354
0
    *outLen = idx;
30355
30356
0
    return 0;
30357
#else
30358
    ASNSetData dataASN[dsaSigASN_Length];
30359
    int ret;
30360
    int sz;
30361
30362
    /* Clear dynamic data and set buffers for r and s */
30363
    XMEMSET(dataASN, 0, sizeof(dataASN));
30364
    SetASN_Buffer(&dataASN[DSASIGASN_IDX_R], r, rLen);
30365
    SetASN_Buffer(&dataASN[DSASIGASN_IDX_S], s, sLen);
30366
30367
    /* Calculate size of encoding. */
30368
    ret = SizeASN_Items(dsaSigASN, dataASN, dsaSigASN_Length, &sz);
30369
    /* Check buffer is big enough for encoding. */
30370
    if ((ret == 0) && ((int)*outLen < sz)) {
30371
       ret = BUFFER_E;
30372
    }
30373
    if (ret == 0) {
30374
        /* Encode DSA signature into buffer. */
30375
        SetASN_Items(dsaSigASN, dataASN, dsaSigASN_Length, out);
30376
        /* Set the actual encoding size. */
30377
        *outLen = sz;
30378
    }
30379
30380
    return ret;
30381
#endif /* WOLFSSL_ASN_TEMPLATE */
30382
0
}
30383
30384
/* Der Decode ECC-DSA Signature with R/S as unsigned bin */
30385
/* All input/outputs are assumed to be big-endian */
30386
int DecodeECC_DSA_Sig_Bin(const byte* sig, word32 sigLen, byte* r, word32* rLen,
30387
    byte* s, word32* sLen)
30388
0
{
30389
0
#ifndef WOLFSSL_ASN_TEMPLATE
30390
0
    int    ret;
30391
0
    word32 idx = 0;
30392
0
    int    len = 0;
30393
30394
0
    if (GetSequence(sig, &idx, &len, sigLen) < 0) {
30395
0
        return ASN_ECC_KEY_E;
30396
0
    }
30397
30398
0
#ifndef NO_STRICT_ECDSA_LEN
30399
    /* enable strict length checking for signature */
30400
0
    if (sigLen != idx + (word32)len) {
30401
0
        return ASN_ECC_KEY_E;
30402
0
    }
30403
#else
30404
    /* allow extra signature bytes at end */
30405
    if ((word32)len > (sigLen - idx)) {
30406
        return ASN_ECC_KEY_E;
30407
    }
30408
#endif
30409
30410
0
    ret = GetASNInt(sig, &idx, &len, sigLen);
30411
0
    if (ret != 0)
30412
0
        return ret;
30413
0
    if (rLen)
30414
0
        *rLen = len;
30415
0
    if (r)
30416
0
        XMEMCPY(r, (byte*)sig + idx, len);
30417
0
    idx += len;
30418
30419
0
    ret = GetASNInt(sig, &idx, &len, sigLen);
30420
0
    if (ret != 0)
30421
0
        return ret;
30422
0
    if (sLen)
30423
0
        *sLen = len;
30424
0
    if (s)
30425
0
        XMEMCPY(s, (byte*)sig + idx, len);
30426
30427
0
#ifndef NO_STRICT_ECDSA_LEN
30428
    /* sanity check that the index has been advanced all the way to the end of
30429
     * the buffer */
30430
0
    if (idx + len != sigLen) {
30431
0
        ret = ASN_ECC_KEY_E;
30432
0
    }
30433
0
#endif
30434
30435
0
    return ret;
30436
#else
30437
    ASNGetData dataASN[dsaSigASN_Length];
30438
    word32 idx = 0;
30439
30440
    /* Clear dynamic data and set buffers to put r and s into. */
30441
    XMEMSET(dataASN, 0, sizeof(dataASN));
30442
    GetASN_Buffer(&dataASN[DSASIGASN_IDX_R], r, rLen);
30443
    GetASN_Buffer(&dataASN[DSASIGASN_IDX_S], s, sLen);
30444
30445
    /* Decode the DSA signature. */
30446
    return GetASN_Items(dsaSigASN, dataASN, dsaSigASN_Length, 1, sig, &idx,
30447
                        sigLen);
30448
#endif /* WOLFSSL_ASN_TEMPLATE */
30449
0
}
30450
30451
int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s)
30452
3.71k
{
30453
3.71k
#ifndef WOLFSSL_ASN_TEMPLATE
30454
3.71k
    word32 idx = 0;
30455
3.71k
    int    len = 0;
30456
30457
3.71k
    if (GetSequence(sig, &idx, &len, sigLen) < 0) {
30458
0
        return ASN_ECC_KEY_E;
30459
0
    }
30460
30461
3.71k
#ifndef NO_STRICT_ECDSA_LEN
30462
    /* enable strict length checking for signature */
30463
3.71k
    if (sigLen != idx + (word32)len) {
30464
8
        return ASN_ECC_KEY_E;
30465
8
    }
30466
#else
30467
    /* allow extra signature bytes at end */
30468
    if ((word32)len > (sigLen - idx)) {
30469
        return ASN_ECC_KEY_E;
30470
    }
30471
#endif
30472
30473
3.71k
    if (GetIntPositive(r, sig, &idx, sigLen) < 0) {
30474
0
        return ASN_ECC_KEY_E;
30475
0
    }
30476
30477
3.71k
    if (GetIntPositive(s, sig, &idx, sigLen) < 0) {
30478
0
        mp_clear(r);
30479
0
        return ASN_ECC_KEY_E;
30480
0
    }
30481
30482
3.71k
#ifndef NO_STRICT_ECDSA_LEN
30483
    /* sanity check that the index has been advanced all the way to the end of
30484
     * the buffer */
30485
3.71k
    if (idx != sigLen) {
30486
0
        mp_clear(r);
30487
0
        mp_clear(s);
30488
0
        return ASN_ECC_KEY_E;
30489
0
    }
30490
3.71k
#endif
30491
30492
3.71k
    return 0;
30493
#else
30494
    ASNGetData dataASN[dsaSigASN_Length];
30495
    word32 idx = 0;
30496
    int ret;
30497
30498
    /* Clear dynamic data and set mp_ints to put r and s into. */
30499
    XMEMSET(dataASN, 0, sizeof(dataASN));
30500
    GetASN_MP(&dataASN[DSASIGASN_IDX_R], r);
30501
    GetASN_MP(&dataASN[DSASIGASN_IDX_S], s);
30502
30503
    /* Decode the DSA signature. */
30504
    ret = GetASN_Items(dsaSigASN, dataASN, dsaSigASN_Length, 1, sig, &idx,
30505
                       sigLen);
30506
#ifndef NO_STRICT_ECDSA_LEN
30507
    /* sanity check that the index has been advanced all the way to the end of
30508
     * the buffer */
30509
    if ((ret == 0) && (idx != sigLen)) {
30510
        mp_clear(r);
30511
        mp_clear(s);
30512
        ret = ASN_ECC_KEY_E;
30513
    }
30514
30515
#endif
30516
    return ret;
30517
#endif /* WOLFSSL_ASN_TEMPLATE */
30518
3.71k
}
30519
#endif
30520
30521
30522
#ifdef WOLFSSL_ASN_TEMPLATE
30523
#ifdef WOLFSSL_CUSTOM_CURVES
30524
/* Convert data to hex string.
30525
 *
30526
 * Big-endian byte array is converted to big-endian hexadecimal string.
30527
 *
30528
 * @param [in]  input  Buffer containing data.
30529
 * @param [in]  inSz   Size of data in buffer.
30530
 * @param [out] out    Buffer to hold hex string.
30531
 */
30532
static void DataToHexString(const byte* input, word32 inSz, char* out)
30533
{
30534
    static const char hexChar[] = { '0', '1', '2', '3', '4', '5', '6', '7',
30535
                                    '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
30536
    word32 i;
30537
30538
    /* Converting a byte of data at a time to two hex characters. */
30539
    for (i = 0; i < inSz; i++) {
30540
        out[i*2 + 0] = hexChar[input[i] >> 4];
30541
        out[i*2 + 1] = hexChar[input[i] & 0xf];
30542
    }
30543
    /* NUL terminate string. */
30544
    out[i * 2] = '\0';
30545
}
30546
30547
/* Convert data to hex string and place in allocated buffer.
30548
 *
30549
 * Big-endian byte array is converted to big-endian hexadecimal string.
30550
 *
30551
 * @param [in]  input     Buffer containing data.
30552
 * @param [in]  inSz      Size of data in buffer.
30553
 * @param [out] out       Allocated buffer holding hex string.
30554
 * @param [in]  heap      Dynamic memory allocation hint.
30555
 * @param [in]  heapType  Type of heap to use.
30556
 * @return  0 on succcess.
30557
 * @return  MEMORY_E when dynamic memory allocation fails.
30558
 */
30559
static int DataToHexStringAlloc(const byte* input, word32 inSz, char** out,
30560
                                void* heap, int heapType)
30561
{
30562
    int ret = 0;
30563
    char* str;
30564
30565
    /* Allocate for 2 string characters ber byte plus NUL. */
30566
    str = (char*)XMALLOC(inSz * 2 + 1, heap, heapType);
30567
    if (str == NULL) {
30568
        ret = MEMORY_E;
30569
    }
30570
    else {
30571
        /* Convert to hex string. */
30572
        DataToHexString(input, inSz, str);
30573
        *out = str;
30574
    }
30575
30576
    (void)heap;
30577
    (void)heapType;
30578
30579
    return ret;
30580
}
30581
30582
/* ASN.1 template for SpecifiedECDomain.
30583
 * SEC 1 Ver. 2.0, C.2 - Syntax for Elliptic Curve Domain Parameters
30584
 * NOTE: characteristic-two-field not supported. */
30585
static const ASNItem eccSpecifiedASN[] = {
30586
            /* version */
30587
/* VER        */ { 0, ASN_INTEGER, 0, 0, 0 },
30588
                                     /* fieldID */
30589
/* PRIME_SEQ  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
30590
                                         /* prime-field or characteristic-two-field */
30591
/* PRIME_OID  */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
30592
                                         /* Prime-p */
30593
/* PRIME_P    */     { 1, ASN_INTEGER, 0, 0, 0 },
30594
                                     /* fieldID */
30595
/* PARAM_SEQ, */ { 0, ASN_SEQUENCE, 1, 1, 0 },
30596
                                         /* a */
30597
/* PARAM_A    */     { 1, ASN_OCTET_STRING, 0, 0, 0 },
30598
                                         /* b */
30599
/* PARAM_B    */     { 1, ASN_OCTET_STRING, 0, 0, 0 },
30600
                                         /* seed */
30601
/* PARAM_SEED */     { 1, ASN_BIT_STRING, 0, 0, 1 },
30602
                                     /* base */
30603
/* BASE       */ { 0, ASN_OCTET_STRING, 0, 0, 0 },
30604
                                     /* order */
30605
/* ORDER      */ { 0, ASN_INTEGER, 0, 0, 0 },
30606
                                     /* cofactor */
30607
/* COFACTOR   */ { 0, ASN_INTEGER, 0, 0, 1 },
30608
                                     /* hash */
30609
/* HASH_SEQ   */ { 0, ASN_SEQUENCE, 0, 0, 1 },
30610
};
30611
enum {
30612
    ECCSPECIFIEDASN_IDX_VER = 0,
30613
    ECCSPECIFIEDASN_IDX_PRIME_SEQ,
30614
    ECCSPECIFIEDASN_IDX_PRIME_OID,
30615
    ECCSPECIFIEDASN_IDX_PRIME_P,
30616
    ECCSPECIFIEDASN_IDX_PARAM_SEQ,
30617
    ECCSPECIFIEDASN_IDX_PARAM_A,
30618
    ECCSPECIFIEDASN_IDX_PARAM_B,
30619
    ECCSPECIFIEDASN_IDX_PARAM_SEED,
30620
    ECCSPECIFIEDASN_IDX_BASE,
30621
    ECCSPECIFIEDASN_IDX_ORDER,
30622
    ECCSPECIFIEDASN_IDX_COFACTOR,
30623
    ECCSPECIFIEDASN_IDX_HASH_SEQ,
30624
};
30625
30626
/* Number of items in ASN.1 template for SpecifiedECDomain. */
30627
#define eccSpecifiedASN_Length (sizeof(eccSpecifiedASN) / sizeof(ASNItem))
30628
30629
/* OID indicating the prime field is explicity defined. */
30630
static const byte primeFieldOID[] = {
30631
    0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01
30632
};
30633
static const char ecSetCustomName[] = "Custom";
30634
30635
/* Explicit EC parameter values. */
30636
static int EccSpecifiedECDomainDecode(const byte* input, word32 inSz,
30637
                                      ecc_key* key)
30638
{
30639
    DECL_ASNGETDATA(dataASN, eccSpecifiedASN_Length);
30640
    int ret = 0;
30641
    ecc_set_type* curve;
30642
    word32 idx = 0;
30643
    byte version;
30644
    byte cofactor;
30645
    const byte *base;
30646
    word32 baseLen;
30647
30648
    /* Allocate a new parameter set. */
30649
    curve = (ecc_set_type*)XMALLOC(sizeof(*curve), key->heap,
30650
                                                       DYNAMIC_TYPE_ECC_BUFFER);
30651
    if (curve == NULL)
30652
        ret = MEMORY_E;
30653
30654
    CALLOC_ASNGETDATA(dataASN, eccSpecifiedASN_Length, ret, key->heap);
30655
30656
    if (ret == 0) {
30657
        /* Clear out parameters and set fields to indicate it is custom. */
30658
        XMEMSET(curve, 0, sizeof(*curve));
30659
        /* Set name to be: "Custom" */
30660
    #ifndef WOLFSSL_ECC_CURVE_STATIC
30661
        curve->name = ecSetCustomName;
30662
    #else
30663
        XMEMCPY((void*)curve->name, ecSetCustomName, sizeof(ecSetCustomName));
30664
    #endif
30665
        curve->id = ECC_CURVE_CUSTOM;
30666
30667
        /* Get version, must have prime field OID and get co-factor. */
30668
        GetASN_Int8Bit(&dataASN[ECCSPECIFIEDASN_IDX_VER], &version);
30669
        GetASN_ExpBuffer(&dataASN[ECCSPECIFIEDASN_IDX_PRIME_OID],
30670
                primeFieldOID, sizeof(primeFieldOID));
30671
        GetASN_Int8Bit(&dataASN[ECCSPECIFIEDASN_IDX_COFACTOR], &cofactor);
30672
        /* Decode the explicit parameters. */
30673
        ret = GetASN_Items(eccSpecifiedASN, dataASN, eccSpecifiedASN_Length, 1,
30674
                           input, &idx, inSz);
30675
    }
30676
    /* Version must be 1 or 2 for supporting explicit parameters. */
30677
    if ((ret == 0) && (version < 1 || version > 3)) {
30678
        ret = ASN_PARSE_E;
30679
    }
30680
    /* Only version 2 and above can have a seed. */
30681
    if ((ret == 0) && (dataASN[ECCSPECIFIEDASN_IDX_PARAM_SEED].tag != 0) &&
30682
            (version < 2)) {
30683
        ret = ASN_PARSE_E;
30684
    }
30685
    /* Only version 2 and above can have a hash algorithm. */
30686
    if ((ret == 0) && (dataASN[ECCSPECIFIEDASN_IDX_HASH_SEQ].tag != 0) &&
30687
            (version < 2)) {
30688
        ret = ASN_PARSE_E;
30689
    }
30690
    if ((ret == 0) && (dataASN[ECCSPECIFIEDASN_IDX_COFACTOR].tag != 0)) {
30691
        /* Store optional co-factor. */
30692
        curve->cofactor = cofactor;
30693
    }
30694
    if (ret == 0) {
30695
        /* Length of the prime in bytes is the curve size. */
30696
        curve->size =
30697
                (int)dataASN[ECCSPECIFIEDASN_IDX_PRIME_P].data.ref.length;
30698
        /* Base point: 0x04 <x> <y> (must be uncompressed). */
30699
        GetASN_GetConstRef(&dataASN[ECCSPECIFIEDASN_IDX_BASE], &base,
30700
                &baseLen);
30701
        if ((baseLen < (word32)curve->size * 2 + 1) || (base[0] != 0x4)) {
30702
            ret = ASN_PARSE_E;
30703
        }
30704
    }
30705
    /* Put the curve parameters into the set.
30706
     * Convert the big-endian number byte array to a big-endian string.
30707
     */
30708
    #ifndef WOLFSSL_ECC_CURVE_STATIC
30709
    /* Allocate buffer to put hex strings into. */
30710
    if (ret == 0) {
30711
        /* Base X-ordinate */
30712
        ret = DataToHexStringAlloc(base + 1, curve->size,
30713
                                   (char**)&curve->Gx, key->heap,
30714
                                   DYNAMIC_TYPE_ECC_BUFFER);
30715
    }
30716
    if (ret == 0) {
30717
        /* Base Y-ordinate */
30718
        ret = DataToHexStringAlloc(base + 1 + curve->size, curve->size,
30719
                                   (char**)&curve->Gy, key->heap,
30720
                                   DYNAMIC_TYPE_ECC_BUFFER);
30721
    }
30722
    if (ret == 0) {
30723
        /* Prime */
30724
        ret = DataToHexStringAlloc(
30725
                dataASN[ECCSPECIFIEDASN_IDX_PRIME_P].data.ref.data,
30726
                dataASN[ECCSPECIFIEDASN_IDX_PRIME_P].data.ref.length,
30727
                (char**)&curve->prime, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
30728
    }
30729
    if (ret == 0) {
30730
        /* Parameter A */
30731
        ret = DataToHexStringAlloc(
30732
                dataASN[ECCSPECIFIEDASN_IDX_PARAM_A].data.ref.data,
30733
                dataASN[ECCSPECIFIEDASN_IDX_PARAM_A].data.ref.length,
30734
                (char**)&curve->Af, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
30735
    }
30736
    if (ret == 0) {
30737
        /* Parameter B */
30738
        ret = DataToHexStringAlloc(
30739
                dataASN[ECCSPECIFIEDASN_IDX_PARAM_B].data.ref.data,
30740
                dataASN[ECCSPECIFIEDASN_IDX_PARAM_B].data.ref.length,
30741
                (char**)&curve->Bf, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
30742
    }
30743
    if (ret == 0) {
30744
        /* Order of curve */
30745
        ret = DataToHexStringAlloc(
30746
                dataASN[ECCSPECIFIEDASN_IDX_ORDER].data.ref.data,
30747
                dataASN[ECCSPECIFIEDASN_IDX_ORDER].data.ref.length,
30748
                (char**)&curve->order, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
30749
    }
30750
    #else
30751
    if (ret == 0) {
30752
        /* Base X-ordinate */
30753
        DataToHexString(base + 1, curve->size, curve->Gx);
30754
        /* Base Y-ordinate */
30755
        DataToHexString(base + 1 + curve->size, curve->size, curve->Gy);
30756
        /* Prime */
30757
        DataToHexString(dataASN[ECCSPECIFIEDASN_IDX_PRIME_P].data.ref.data,
30758
                        dataASN[ECCSPECIFIEDASN_IDX_PRIME_P].data.ref.length,
30759
                        curve->prime);
30760
        /* Parameter A */
30761
        DataToHexString(dataASN[ECCSPECIFIEDASN_IDX_PARAM_A].data.ref.data,
30762
                        dataASN[ECCSPECIFIEDASN_IDX_PARAM_A].data.ref.length,
30763
                        curve->Af);
30764
        /* Parameter B */
30765
        DataToHexString(dataASN[ECCSPECIFIEDASN_IDX_PARAM_B].data.ref.data,
30766
                        dataASN[ECCSPECIFIEDASN_IDX_PARAM_B].data.ref.length,
30767
                        curve->Bf);
30768
        /* Order of curve */
30769
        DataToHexString(dataASN[ECCSPECIFIEDASN_IDX_ORDER].data.ref.data,
30770
                        dataASN[ECCSPECIFIEDASN_IDX_ORDER].data.ref.length,
30771
                        curve->order);
30772
    }
30773
    #endif /* WOLFSSL_ECC_CURVE_STATIC */
30774
30775
    /* Store parameter set in key. */
30776
    if ((ret == 0) && (wc_ecc_set_custom_curve(key, curve) < 0)) {
30777
        ret = ASN_PARSE_E;
30778
    }
30779
    if (ret == 0) {
30780
        /* The parameter set was allocated.. */
30781
        key->deallocSet = 1;
30782
    }
30783
30784
    if ((ret != 0) && (curve != NULL)) {
30785
        /* Failed to set parameters so free paramter set. */
30786
        wc_ecc_free_curve(curve, key->heap);
30787
    }
30788
30789
    FREE_ASNGETDATA(dataASN, key->heap);
30790
    return ret;
30791
}
30792
#endif /* WOLFSSL_CUSTOM_CURVES */
30793
#endif /* WOLFSSL_ASN_TEMPLATE */
30794
30795
#ifdef HAVE_ECC
30796
30797
#ifdef WOLFSSL_ASN_TEMPLATE
30798
/* ASN.1 template for ECC private key.
30799
 * SEC.1 Ver 2.0, C.4 - Syntax for Elliptic Curve Private Keys
30800
 */
30801
static const ASNItem eccKeyASN[] = {
30802
/* SEQ         */    { 0, ASN_SEQUENCE, 1, 1, 0 },
30803
                                       /* version */
30804
/* VER         */        { 1, ASN_INTEGER, 0, 0, 0 },
30805
                                       /* privateKey */
30806
/* PKEY        */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
30807
                                       /* parameters */
30808
/* PARAMS      */        { 1, ASN_CONTEXT_SPECIFIC | ASN_ECC_PARAMS, 1, 1, 1 },
30809
                                           /* named */
30810
/* CURVEID     */            { 2, ASN_OBJECT_ID, 0, 0, 2 },
30811
                                           /* specified */
30812
/* CURVEPARAMS */            { 2, ASN_SEQUENCE, 1, 0, 2 },
30813
                                       /* publicKey */
30814
/* PUBKEY      */        { 1, ASN_CONTEXT_SPECIFIC | ASN_ECC_PUBKEY, 1, 1, 1 },
30815
                                           /* Uncompressed point - X9.62. */
30816
/* PUBKEY_VAL, */            { 2, ASN_BIT_STRING, 0, 0, 0 },
30817
};
30818
enum {
30819
    ECCKEYASN_IDX_SEQ = 0,
30820
    ECCKEYASN_IDX_VER,
30821
    ECCKEYASN_IDX_PKEY,
30822
    ECCKEYASN_IDX_PARAMS,
30823
    ECCKEYASN_IDX_CURVEID,
30824
    ECCKEYASN_IDX_CURVEPARAMS,
30825
    ECCKEYASN_IDX_PUBKEY,
30826
    ECCKEYASN_IDX_PUBKEY_VAL,
30827
};
30828
30829
/* Number of items in ASN.1 template for ECC private key. */
30830
#define eccKeyASN_Length (sizeof(eccKeyASN) / sizeof(ASNItem))
30831
#endif
30832
30833
WOLFSSL_ABI
30834
int wc_EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key,
30835
                        word32 inSz)
30836
0
{
30837
0
#ifndef WOLFSSL_ASN_TEMPLATE
30838
0
    word32 oidSum;
30839
0
    int    version, length;
30840
0
    int    privSz, pubSz = 0;
30841
0
    byte   b;
30842
0
    int    ret = 0;
30843
0
    int    curve_id = ECC_CURVE_DEF;
30844
0
#ifdef WOLFSSL_SMALL_STACK
30845
0
    byte* priv;
30846
0
    byte* pub = NULL;
30847
#else
30848
    byte priv[ECC_MAXSIZE+1];
30849
    byte pub[2*(ECC_MAXSIZE+1)]; /* public key has two parts plus header */
30850
#endif
30851
0
    word32 algId = 0;
30852
0
    byte* pubData = NULL;
30853
30854
0
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
30855
0
        return BAD_FUNC_ARG;
30856
30857
    /* if has pkcs8 header skip it */
30858
0
    if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) {
30859
        /* ignore error, did not have pkcs8 header */
30860
0
    }
30861
30862
0
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
30863
0
        return ASN_PARSE_E;
30864
30865
0
    if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
30866
0
        return ASN_PARSE_E;
30867
30868
0
    if (*inOutIdx >= inSz)
30869
0
        return ASN_PARSE_E;
30870
30871
0
    b = input[*inOutIdx];
30872
0
    *inOutIdx += 1;
30873
30874
    /* priv type */
30875
0
    if (b != 4 && b != 6 && b != 7)
30876
0
        return ASN_PARSE_E;
30877
30878
0
    if (GetLength(input, inOutIdx, &length, inSz) < 0)
30879
0
        return ASN_PARSE_E;
30880
0
    privSz = length;
30881
30882
0
    if (privSz > ECC_MAXSIZE)
30883
0
        return BUFFER_E;
30884
30885
0
#ifdef WOLFSSL_SMALL_STACK
30886
0
    priv = (byte*)XMALLOC(privSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
30887
0
    if (priv == NULL)
30888
0
        return MEMORY_E;
30889
0
#endif
30890
30891
    /* priv key */
30892
0
    XMEMCPY(priv, &input[*inOutIdx], privSz);
30893
0
    *inOutIdx += length;
30894
30895
0
    if ((*inOutIdx + 1) < inSz) {
30896
        /* prefix 0, may have */
30897
0
        b = input[*inOutIdx];
30898
0
        if (b == ECC_PREFIX_0) {
30899
0
            *inOutIdx += 1;
30900
30901
0
            if (GetLength(input, inOutIdx, &length, inSz) <= 0)
30902
0
                ret = ASN_PARSE_E;
30903
0
            else {
30904
0
                ret = GetObjectId(input, inOutIdx, &oidSum, oidIgnoreType,
30905
0
                                  inSz);
30906
0
                if (ret == 0) {
30907
0
                    if ((ret = CheckCurve(oidSum)) < 0)
30908
0
                        ret = ECC_CURVE_OID_E;
30909
0
                    else {
30910
0
                        curve_id = ret;
30911
0
                        ret = 0;
30912
0
                    }
30913
0
                }
30914
0
            }
30915
0
        }
30916
0
    }
30917
30918
0
    if (ret == 0 && (*inOutIdx + 1) < inSz) {
30919
        /* prefix 1 */
30920
0
        b = input[*inOutIdx];
30921
0
        *inOutIdx += 1;
30922
30923
0
        if (b != ECC_PREFIX_1) {
30924
0
            ret = ASN_ECC_KEY_E;
30925
0
        }
30926
0
        else if (GetLength(input, inOutIdx, &length, inSz) <= 0) {
30927
0
            ret = ASN_PARSE_E;
30928
0
        }
30929
0
        else {
30930
            /* key header */
30931
0
            ret = CheckBitString(input, inOutIdx, &length, inSz, 0, NULL);
30932
0
            if (ret == 0) {
30933
                /* pub key */
30934
0
                pubSz = length;
30935
0
                if (pubSz > 2*(ECC_MAXSIZE+1))
30936
0
                    ret = BUFFER_E;
30937
0
                else {
30938
0
            #ifdef WOLFSSL_SMALL_STACK
30939
0
                    pub = (byte*)XMALLOC(pubSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
30940
0
                    if (pub == NULL)
30941
0
                        ret = MEMORY_E;
30942
0
                    else
30943
0
            #endif
30944
0
                    {
30945
0
                        XMEMCPY(pub, &input[*inOutIdx], pubSz);
30946
0
                        *inOutIdx += length;
30947
0
                        pubData = pub;
30948
0
                    }
30949
0
                }
30950
0
            }
30951
0
        }
30952
0
    }
30953
30954
0
    if (ret == 0) {
30955
0
        ret = wc_ecc_import_private_key_ex(priv, privSz, pubData, pubSz, key,
30956
0
                                                                      curve_id);
30957
0
    }
30958
30959
0
#ifdef WOLFSSL_SMALL_STACK
30960
0
    XFREE(priv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
30961
0
    XFREE(pub,  key->heap, DYNAMIC_TYPE_TMP_BUFFER);
30962
0
#endif
30963
30964
0
    return ret;
30965
#else
30966
    DECL_ASNGETDATA(dataASN, eccKeyASN_Length);
30967
    byte version;
30968
    int ret = 0;
30969
    int curve_id = ECC_CURVE_DEF;
30970
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
30971
    word32 algId = 0;
30972
#endif
30973
30974
    /* Validate parameters. */
30975
    if ((input == NULL) || (inOutIdx == NULL) || (key == NULL) || (inSz == 0)) {
30976
        ret = BAD_FUNC_ARG;
30977
    }
30978
30979
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
30980
    /* if has pkcs8 header skip it */
30981
    if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) {
30982
        /* ignore error, did not have pkcs8 header */
30983
    }
30984
#endif
30985
30986
    CALLOC_ASNGETDATA(dataASN, eccKeyASN_Length, ret, key->heap);
30987
30988
    if (ret == 0) {
30989
        /* Get the version and set the expected OID type. */
30990
        GetASN_Int8Bit(&dataASN[ECCKEYASN_IDX_VER], &version);
30991
        GetASN_OID(&dataASN[ECCKEYASN_IDX_CURVEID], oidCurveType);
30992
        /* Decode the private ECC key. */
30993
        ret = GetASN_Items(eccKeyASN, dataASN, eccKeyASN_Length, 1, input,
30994
                           inOutIdx, inSz);
30995
    }
30996
    /* Only version 1 supported. */
30997
    if ((ret == 0) && (version != 1)) {
30998
        ret = ASN_PARSE_E;
30999
    }
31000
    /* Curve Parameters are optional. */
31001
    if ((ret == 0) && (dataASN[ECCKEYASN_IDX_PARAMS].tag != 0)) {
31002
        if (dataASN[ECCKEYASN_IDX_CURVEID].tag != 0) {
31003
            /* Named curve - check and get id. */
31004
            curve_id = CheckCurve(dataASN[ECCKEYASN_IDX_CURVEID].data.oid.sum);
31005
            if (curve_id < 0) {
31006
                ret = ECC_CURVE_OID_E;
31007
            }
31008
        }
31009
        else {
31010
    #ifdef WOLFSSL_CUSTOM_CURVES
31011
            /* Parse explicit parameters. */
31012
            ret = EccSpecifiedECDomainDecode(
31013
                    dataASN[ECCKEYASN_IDX_CURVEPARAMS].data.ref.data,
31014
                    dataASN[ECCKEYASN_IDX_CURVEPARAMS].data.ref.length, key);
31015
    #else
31016
            /* Explicit parameters not supported in build configuration. */
31017
            ret = ASN_PARSE_E;
31018
    #endif
31019
        }
31020
    }
31021
    if (ret == 0) {
31022
        /* Import private key value and public point (may be NULL). */
31023
        ret = wc_ecc_import_private_key_ex(
31024
                dataASN[ECCKEYASN_IDX_PKEY].data.ref.data,
31025
                dataASN[ECCKEYASN_IDX_PKEY].data.ref.length,
31026
                dataASN[ECCKEYASN_IDX_PUBKEY_VAL].data.ref.data,
31027
                dataASN[ECCKEYASN_IDX_PUBKEY_VAL].data.ref.length,
31028
                key, curve_id);
31029
    }
31030
31031
    FREE_ASNGETDATA(dataASN, key->heap);
31032
    return ret;
31033
#endif
31034
0
}
31035
31036
31037
#ifdef WOLFSSL_CUSTOM_CURVES
31038
#ifndef WOLFSSL_ASN_TEMPLATE
31039
/* returns 0 on success */
31040
static int ASNToHexString(const byte* input, word32* inOutIdx, char** out,
31041
                          word32 inSz, void* heap, int heapType)
31042
{
31043
    int len;
31044
    int i;
31045
    char* str;
31046
    word32 localIdx;
31047
    byte   tag;
31048
31049
    if (*inOutIdx >= inSz) {
31050
        return BUFFER_E;
31051
    }
31052
31053
    localIdx = *inOutIdx;
31054
    if (GetASNTag(input, &localIdx, &tag, inSz) == 0 && tag == ASN_INTEGER) {
31055
        if (GetASNInt(input, inOutIdx, &len, inSz) < 0)
31056
            return ASN_PARSE_E;
31057
    }
31058
    else {
31059
        if (GetOctetString(input, inOutIdx, &len, inSz) < 0)
31060
            return ASN_PARSE_E;
31061
    }
31062
31063
    str = (char*)XMALLOC(len * 2 + 1, heap, heapType);
31064
    if (str == NULL) {
31065
        return MEMORY_E;
31066
    }
31067
31068
    for (i=0; i<len; i++)
31069
        ByteToHexStr(input[*inOutIdx + i], str + i*2);
31070
    str[len*2] = '\0';
31071
31072
    *inOutIdx += len;
31073
    *out = str;
31074
31075
    (void)heap;
31076
    (void)heapType;
31077
31078
    return 0;
31079
}
31080
31081
static int EccKeyParamCopy(char** dst, char* src)
31082
{
31083
    int ret = 0;
31084
#ifdef WOLFSSL_ECC_CURVE_STATIC
31085
    word32 length;
31086
#endif
31087
31088
    if (dst == NULL || src == NULL)
31089
        return BAD_FUNC_ARG;
31090
31091
#ifndef WOLFSSL_ECC_CURVE_STATIC
31092
    *dst = src;
31093
#else
31094
    length = (int)XSTRLEN(src) + 1;
31095
    if (length > MAX_ECC_STRING) {
31096
        WOLFSSL_MSG("ECC Param too large for buffer");
31097
        ret = BUFFER_E;
31098
    }
31099
    else {
31100
        XSTRNCPY(*dst, src, MAX_ECC_STRING);
31101
    }
31102
    XFREE(src, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
31103
#endif
31104
31105
    return ret;
31106
}
31107
#endif /* !WOLFSSL_ASN_TEMPLATE */
31108
#endif /* WOLFSSL_CUSTOM_CURVES */
31109
31110
WOLFSSL_ABI
31111
int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx,
31112
                          ecc_key* key, word32 inSz)
31113
0
{
31114
0
#ifndef WOLFSSL_ASN_TEMPLATE
31115
0
    int    ret;
31116
0
    int    version, length;
31117
0
    int    curve_id = ECC_CURVE_DEF;
31118
0
    word32 oidSum, localIdx;
31119
0
    byte   tag, isPrivFormat = 0;
31120
31121
0
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
31122
0
        return BAD_FUNC_ARG;
31123
31124
0
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
31125
0
        return ASN_PARSE_E;
31126
31127
    /* Check if ECC private key is being used and skip private portion */
31128
0
    if (GetMyVersion(input, inOutIdx, &version, inSz) >= 0) {
31129
0
        isPrivFormat = 1;
31130
31131
        /* Type private key */
31132
0
        if (*inOutIdx >= inSz)
31133
0
            return ASN_PARSE_E;
31134
0
        tag = input[*inOutIdx];
31135
0
        *inOutIdx += 1;
31136
0
        if (tag != 4 && tag != 6 && tag != 7)
31137
0
            return ASN_PARSE_E;
31138
31139
        /* Skip Private Key */
31140
0
        if (GetLength(input, inOutIdx, &length, inSz) < 0)
31141
0
            return ASN_PARSE_E;
31142
0
        if (length > ECC_MAXSIZE)
31143
0
            return BUFFER_E;
31144
0
        *inOutIdx += length;
31145
31146
        /* Private Curve Header */
31147
0
        if (*inOutIdx >= inSz)
31148
0
            return ASN_PARSE_E;
31149
0
        tag = input[*inOutIdx];
31150
0
        *inOutIdx += 1;
31151
0
        if (tag != ECC_PREFIX_0)
31152
0
            return ASN_ECC_KEY_E;
31153
0
        if (GetLength(input, inOutIdx, &length, inSz) <= 0)
31154
0
            return ASN_PARSE_E;
31155
0
    }
31156
    /* Standard ECC public key */
31157
0
    else {
31158
0
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
31159
0
            return ASN_PARSE_E;
31160
31161
0
        ret = SkipObjectId(input, inOutIdx, inSz);
31162
0
        if (ret != 0)
31163
0
            return ret;
31164
0
    }
31165
31166
0
    if (*inOutIdx >= inSz) {
31167
0
        return BUFFER_E;
31168
0
    }
31169
31170
0
    localIdx = *inOutIdx;
31171
0
    if (GetASNTag(input, &localIdx, &tag, inSz) == 0 &&
31172
0
            tag == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
31173
#ifdef WOLFSSL_CUSTOM_CURVES
31174
        ecc_set_type* curve;
31175
        int len;
31176
        char* point = NULL;
31177
31178
        ret = 0;
31179
31180
        curve = (ecc_set_type*)XMALLOC(sizeof(*curve), key->heap,
31181
                                                       DYNAMIC_TYPE_ECC_BUFFER);
31182
        if (curve == NULL)
31183
            ret = MEMORY_E;
31184
31185
        if (ret == 0) {
31186
            static const char customName[] = "Custom";
31187
            XMEMSET(curve, 0, sizeof(*curve));
31188
        #ifndef WOLFSSL_ECC_CURVE_STATIC
31189
            curve->name = customName;
31190
        #else
31191
            XMEMCPY((void*)curve->name, customName, sizeof(customName));
31192
        #endif
31193
            curve->id = ECC_CURVE_CUSTOM;
31194
31195
            if (GetSequence(input, inOutIdx, &length, inSz) < 0)
31196
                ret = ASN_PARSE_E;
31197
        }
31198
31199
        if (ret == 0) {
31200
            GetInteger7Bit(input, inOutIdx, inSz);
31201
            if (GetSequence(input, inOutIdx, &length, inSz) < 0)
31202
                ret = ASN_PARSE_E;
31203
        }
31204
        if (ret == 0) {
31205
            char* p = NULL;
31206
            SkipObjectId(input, inOutIdx, inSz);
31207
            ret = ASNToHexString(input, inOutIdx, &p, inSz,
31208
                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
31209
            if (ret == 0)
31210
                ret = EccKeyParamCopy((char**)&curve->prime, p);
31211
        }
31212
        if (ret == 0) {
31213
            curve->size = (int)XSTRLEN(curve->prime) / 2;
31214
31215
            if (GetSequence(input, inOutIdx, &length, inSz) < 0)
31216
                ret = ASN_PARSE_E;
31217
        }
31218
        if (ret == 0) {
31219
            char* af = NULL;
31220
            ret = ASNToHexString(input, inOutIdx, &af, inSz,
31221
                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
31222
            if (ret == 0)
31223
                ret = EccKeyParamCopy((char**)&curve->Af, af);
31224
        }
31225
        if (ret == 0) {
31226
            char* bf = NULL;
31227
            ret = ASNToHexString(input, inOutIdx, &bf, inSz,
31228
                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
31229
            if (ret == 0)
31230
                ret = EccKeyParamCopy((char**)&curve->Bf, bf);
31231
        }
31232
        if (ret == 0) {
31233
            localIdx = *inOutIdx;
31234
            if (*inOutIdx < inSz && GetASNTag(input, &localIdx, &tag, inSz)
31235
                    == 0 && tag == ASN_BIT_STRING) {
31236
                len = 0;
31237
                ret = GetASNHeader(input, ASN_BIT_STRING, inOutIdx, &len, inSz);
31238
                if (ret > 0)
31239
                    ret = 0; /* reset on success */
31240
                *inOutIdx += len;
31241
            }
31242
        }
31243
        if (ret == 0) {
31244
            ret = ASNToHexString(input, inOutIdx, (char**)&point, inSz,
31245
                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
31246
31247
            /* sanity check that point buffer is not smaller than the expected
31248
             * size to hold ( 0 4 || Gx || Gy )
31249
             * where Gx and Gy are each the size of curve->size * 2 */
31250
            if (ret == 0 && (int)XSTRLEN(point) < (curve->size * 4) + 2) {
31251
                XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
31252
                ret = BUFFER_E;
31253
            }
31254
        }
31255
        if (ret == 0) {
31256
        #ifndef WOLFSSL_ECC_CURVE_STATIC
31257
            curve->Gx = (const char*)XMALLOC(curve->size * 2 + 2, key->heap,
31258
                                                       DYNAMIC_TYPE_ECC_BUFFER);
31259
            curve->Gy = (const char*)XMALLOC(curve->size * 2 + 2, key->heap,
31260
                                                       DYNAMIC_TYPE_ECC_BUFFER);
31261
            if (curve->Gx == NULL || curve->Gy == NULL) {
31262
                XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
31263
                ret = MEMORY_E;
31264
            }
31265
        #else
31266
            if (curve->size * 2 + 2 > MAX_ECC_STRING) {
31267
                WOLFSSL_MSG("curve size is too large to fit in buffer");
31268
                ret = BUFFER_E;
31269
            }
31270
        #endif
31271
        }
31272
        if (ret == 0) {
31273
            char* o = NULL;
31274
31275
            XMEMCPY((char*)curve->Gx, point + 2, curve->size * 2);
31276
            XMEMCPY((char*)curve->Gy, point + curve->size * 2 + 2,
31277
                                                               curve->size * 2);
31278
            ((char*)curve->Gx)[curve->size * 2] = '\0';
31279
            ((char*)curve->Gy)[curve->size * 2] = '\0';
31280
            XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
31281
            ret = ASNToHexString(input, inOutIdx, &o, inSz,
31282
                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
31283
            if (ret == 0)
31284
                ret = EccKeyParamCopy((char**)&curve->order, o);
31285
        }
31286
        if (ret == 0) {
31287
            curve->cofactor = GetInteger7Bit(input, inOutIdx, inSz);
31288
31289
        #ifndef WOLFSSL_ECC_CURVE_STATIC
31290
            curve->oid = NULL;
31291
        #else
31292
            XMEMSET((void*)curve->oid, 0, sizeof(curve->oid));
31293
        #endif
31294
            curve->oidSz = 0;
31295
            curve->oidSum = 0;
31296
31297
            if (wc_ecc_set_custom_curve(key, curve) < 0) {
31298
                ret = ASN_PARSE_E;
31299
            }
31300
31301
            key->deallocSet = 1;
31302
31303
            curve = NULL;
31304
        }
31305
        if (curve != NULL)
31306
            wc_ecc_free_curve(curve, key->heap);
31307
31308
        if (ret < 0)
31309
            return ret;
31310
#else
31311
0
        return ASN_PARSE_E;
31312
0
#endif /* WOLFSSL_CUSTOM_CURVES */
31313
0
    }
31314
0
    else {
31315
        /* ecc params information */
31316
0
        ret = GetObjectId(input, inOutIdx, &oidSum, oidIgnoreType, inSz);
31317
0
        if (ret != 0)
31318
0
            return ret;
31319
31320
        /* get curve id */
31321
0
        if ((ret = CheckCurve(oidSum)) < 0)
31322
0
            return ECC_CURVE_OID_E;
31323
0
        else {
31324
0
            curve_id = ret;
31325
0
        }
31326
0
    }
31327
31328
0
    if (isPrivFormat) {
31329
        /* Public Curve Header - skip */
31330
0
        if (*inOutIdx >= inSz)
31331
0
            return ASN_PARSE_E;
31332
0
        tag = input[*inOutIdx];
31333
0
        *inOutIdx += 1;
31334
0
        if (tag != ECC_PREFIX_1)
31335
0
            return ASN_ECC_KEY_E;
31336
0
        if (GetLength(input, inOutIdx, &length, inSz) <= 0)
31337
0
            return ASN_PARSE_E;
31338
0
    }
31339
31340
    /* key header */
31341
0
    ret = CheckBitString(input, inOutIdx, &length, inSz, 1, NULL);
31342
0
    if (ret != 0)
31343
0
        return ret;
31344
31345
    /* This is the raw point data compressed or uncompressed. */
31346
0
    if (wc_ecc_import_x963_ex(input + *inOutIdx, length, key,
31347
0
                                                            curve_id) != 0) {
31348
0
        return ASN_ECC_KEY_E;
31349
0
    }
31350
31351
0
    *inOutIdx += length;
31352
31353
0
    return 0;
31354
#else
31355
    /* eccKeyASN is longer than eccPublicKeyASN. */
31356
    DECL_ASNGETDATA(dataASN, eccKeyASN_Length);
31357
    int ret = 0;
31358
    int curve_id = ECC_CURVE_DEF;
31359
    int oidIdx = ECCPUBLICKEYASN_IDX_ALGOID_CURVEID;
31360
#ifdef WOLFSSL_CUSTOM_CURVES
31361
    int specIdx = ECCPUBLICKEYASN_IDX_ALGOID_PARAMS;
31362
#endif
31363
    int pubIdx = ECCPUBLICKEYASN_IDX_PUBKEY;
31364
31365
    if ((input == NULL) || (inOutIdx == NULL) || (key == NULL) || (inSz == 0)) {
31366
        ret = BAD_FUNC_ARG;
31367
    }
31368
31369
    ALLOC_ASNGETDATA(dataASN, eccKeyASN_Length, ret, key->heap);
31370
31371
    if (ret == 0) {
31372
        /* Clear dynamic data for ECC public key. */
31373
        XMEMSET(dataASN, 0, sizeof(*dataASN) * eccPublicKeyASN_Length);
31374
        /* Set required ECDSA OID and ignore the curve OID type. */
31375
        GetASN_ExpBuffer(&dataASN[ECCPUBLICKEYASN_IDX_ALGOID_OID], keyEcdsaOid,
31376
                sizeof(keyEcdsaOid));
31377
        GetASN_OID(&dataASN[oidIdx], oidIgnoreType);
31378
        /* Decode the public ECC key. */
31379
        ret = GetASN_Items(eccPublicKeyASN, dataASN, eccPublicKeyASN_Length, 1,
31380
                           input, inOutIdx, inSz);
31381
        if (ret != 0) {
31382
            oidIdx = ECCKEYASN_IDX_CURVEID;
31383
        #ifdef WOLFSSL_CUSTOM_CURVES
31384
            specIdx = ECCKEYASN_IDX_CURVEPARAMS;
31385
        #endif
31386
            pubIdx = ECCKEYASN_IDX_PUBKEY_VAL;
31387
31388
            /* Clear dynamic data for ECC private key. */
31389
            XMEMSET(dataASN, 0, sizeof(*dataASN) * eccKeyASN_Length);
31390
            /* Check named curve OID type. */
31391
            GetASN_OID(&dataASN[oidIdx], oidIgnoreType);
31392
            /* Try private key format .*/
31393
            ret = GetASN_Items(eccKeyASN, dataASN, eccKeyASN_Length, 1, input,
31394
                               inOutIdx, inSz);
31395
            if (ret != 0) {
31396
                ret = ASN_PARSE_E;
31397
            }
31398
        }
31399
    }
31400
31401
    if (ret == 0) {
31402
        if (dataASN[oidIdx].tag != 0) {
31403
            /* Named curve - check and get id. */
31404
            curve_id = CheckCurve(dataASN[oidIdx].data.oid.sum);
31405
            if (curve_id < 0) {
31406
                ret = ASN_OBJECT_ID_E;
31407
            }
31408
        }
31409
        else {
31410
        #ifdef WOLFSSL_CUSTOM_CURVES
31411
            /* Parse explicit parameters. */
31412
            ret = EccSpecifiedECDomainDecode(dataASN[specIdx].data.ref.data,
31413
                                         dataASN[specIdx].data.ref.length, key);
31414
        #else
31415
            /* Explicit parameters not supported in build configuration. */
31416
            ret = ASN_PARSE_E;
31417
        #endif
31418
        }
31419
    }
31420
    if (ret == 0) {
31421
        /* Import public point. */
31422
        ret = wc_ecc_import_x963_ex(dataASN[pubIdx].data.ref.data,
31423
                dataASN[pubIdx].data.ref.length, key, curve_id);
31424
        if (ret != 0) {
31425
            ret = ASN_ECC_KEY_E;
31426
        }
31427
    }
31428
31429
    FREE_ASNGETDATA(dataASN, key->heap);
31430
    return ret;
31431
#endif /* WOLFSSL_ASN_TEMPLATE */
31432
0
}
31433
31434
#if defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT)
31435
/* build DER formatted ECC key, include optional public key if requested,
31436
 * return length on success, negative on error */
31437
static int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 *inLen,
31438
                             int pubIn, int curveIn)
31439
0
{
31440
0
#ifndef WOLFSSL_ASN_TEMPLATE
31441
0
    byte   curve[MAX_ALGO_SZ+2];
31442
0
    byte   ver[MAX_VERSION_SZ];
31443
0
    byte   seq[MAX_SEQ_SZ];
31444
0
    int    ret, totalSz, curveSz, verSz;
31445
0
    int    privHdrSz  = ASN_ECC_HEADER_SZ;
31446
0
    int    pubHdrSz   = ASN_ECC_CONTEXT_SZ + ASN_ECC_HEADER_SZ;
31447
#ifdef WOLFSSL_NO_MALLOC
31448
    byte   prv[MAX_ECC_BYTES + ASN_ECC_HEADER_SZ + MAX_SEQ_SZ];
31449
    byte   pub[(MAX_ECC_BYTES * 2) + 1 + ASN_ECC_CONTEXT_SZ +
31450
                              ASN_ECC_HEADER_SZ + MAX_SEQ_SZ];
31451
#else
31452
0
    byte   *prv = NULL, *pub = NULL;
31453
0
#endif
31454
31455
0
    word32 idx = 0, prvidx = 0, pubidx = 0, curveidx = 0;
31456
0
    word32 seqSz, privSz, pubSz = ECC_BUFSIZE;
31457
31458
0
    if (key == NULL || (output == NULL && inLen == NULL))
31459
0
        return BAD_FUNC_ARG;
31460
31461
0
    if (curveIn) {
31462
        /* curve */
31463
0
        curve[curveidx++] = ECC_PREFIX_0;
31464
0
        curveidx++ /* to put the size after computation */;
31465
0
        curveSz = SetCurve(key, curve+curveidx, MAX_ALGO_SZ);
31466
0
        if (curveSz < 0)
31467
0
            return curveSz;
31468
        /* set computed size */
31469
0
        curve[1] = (byte)curveSz;
31470
0
        curveidx += curveSz;
31471
0
    }
31472
31473
    /* private */
31474
0
    privSz = key->dp->size;
31475
31476
#ifdef WOLFSSL_QNX_CAAM
31477
    /* check if is a black key, and add MAC size if needed */
31478
    if (key->blackKey > 0 && key->blackKey != CAAM_BLACK_KEY_ECB) {
31479
        privSz = privSz + WC_CAAM_MAC_SZ;
31480
    }
31481
#endif
31482
31483
0
#ifndef WOLFSSL_NO_MALLOC
31484
0
    prv = (byte*)XMALLOC(privSz + privHdrSz + MAX_SEQ_SZ,
31485
0
                         key->heap, DYNAMIC_TYPE_TMP_BUFFER);
31486
0
    if (prv == NULL) {
31487
0
        return MEMORY_E;
31488
0
    }
31489
#else
31490
    if (sizeof(prv) < privSz + privHdrSz + MAX_SEQ_SZ) {
31491
        return BUFFER_E;
31492
    }
31493
#endif
31494
0
    if (privSz < ASN_LONG_LENGTH) {
31495
0
        prvidx += SetOctetString8Bit(privSz, &prv[prvidx]);
31496
0
    }
31497
0
    else {
31498
0
        prvidx += SetOctetString(privSz, &prv[prvidx]);
31499
0
    }
31500
0
    ret = wc_ecc_export_private_only(key, prv + prvidx, &privSz);
31501
0
    if (ret < 0) {
31502
0
    #ifndef WOLFSSL_NO_MALLOC
31503
0
        XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
31504
0
    #endif
31505
0
        return ret;
31506
0
    }
31507
0
    prvidx += privSz;
31508
31509
    /* pubIn */
31510
0
    if (pubIn) {
31511
0
        PRIVATE_KEY_UNLOCK();
31512
0
        ret = wc_ecc_export_x963(key, NULL, &pubSz);
31513
0
        PRIVATE_KEY_LOCK();
31514
0
        if (ret != LENGTH_ONLY_E) {
31515
0
        #ifndef WOLFSSL_NO_MALLOC
31516
0
            XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
31517
0
        #endif
31518
0
            return ret;
31519
0
        }
31520
31521
0
    #ifndef WOLFSSL_NO_MALLOC
31522
0
        pub = (byte*)XMALLOC(pubSz + pubHdrSz + MAX_SEQ_SZ,
31523
0
                             key->heap, DYNAMIC_TYPE_TMP_BUFFER);
31524
0
        if (pub == NULL) {
31525
0
            XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
31526
0
            return MEMORY_E;
31527
0
        }
31528
    #else
31529
        if (sizeof(pub) < pubSz + pubHdrSz + MAX_SEQ_SZ) {
31530
            return BUFFER_E;
31531
        }
31532
    #endif
31533
31534
0
        pub[pubidx++] = ECC_PREFIX_1;
31535
0
        if (pubSz > 128) /* leading zero + extra size byte */
31536
0
            pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 2, pub+pubidx);
31537
0
        else /* leading zero */
31538
0
            pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 1, pub+pubidx);
31539
31540
        /* SetBitString adds leading zero */
31541
0
        pubidx += SetBitString(pubSz, 0, pub + pubidx);
31542
0
        PRIVATE_KEY_UNLOCK();
31543
0
        ret = wc_ecc_export_x963(key, pub + pubidx, &pubSz);
31544
0
        PRIVATE_KEY_LOCK();
31545
0
        if (ret != 0) {
31546
0
        #ifndef WOLFSSL_NO_MALLOC
31547
0
            XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
31548
0
            XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
31549
0
        #endif
31550
0
            return ret;
31551
0
        }
31552
0
        pubidx += pubSz;
31553
0
    }
31554
31555
    /* make headers */
31556
0
    verSz = SetMyVersion(1, ver, FALSE);
31557
0
    seqSz = SetSequence(verSz + prvidx + pubidx + curveidx, seq);
31558
31559
0
    totalSz = prvidx + pubidx + curveidx + verSz + seqSz;
31560
0
    if (output == NULL) {
31561
0
        *inLen = totalSz;
31562
0
    #ifndef WOLFSSL_NO_MALLOC
31563
0
        XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
31564
0
        if (pubIn) {
31565
0
            XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
31566
0
        }
31567
0
    #endif
31568
0
        return LENGTH_ONLY_E;
31569
0
    }
31570
0
    if (inLen != NULL && totalSz > (int)*inLen) {
31571
0
        #ifndef WOLFSSL_NO_MALLOC
31572
0
        XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
31573
0
        if (pubIn) {
31574
0
            XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
31575
0
        }
31576
0
        #endif
31577
0
        return BAD_FUNC_ARG;
31578
0
    }
31579
31580
    /* write out */
31581
    /* seq */
31582
0
    XMEMCPY(output + idx, seq, seqSz);
31583
0
    idx = seqSz;
31584
31585
    /* ver */
31586
0
    XMEMCPY(output + idx, ver, verSz);
31587
0
    idx += verSz;
31588
31589
    /* private */
31590
0
    XMEMCPY(output + idx, prv, prvidx);
31591
0
    idx += prvidx;
31592
0
#ifndef WOLFSSL_NO_MALLOC
31593
0
    XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
31594
0
#endif
31595
31596
    /* curve */
31597
0
    XMEMCPY(output + idx, curve, curveidx);
31598
0
    idx += curveidx;
31599
31600
    /* pubIn */
31601
0
    if (pubIn) {
31602
0
        XMEMCPY(output + idx, pub, pubidx);
31603
        /* idx += pubidx;  not used after write, if more data remove comment */
31604
0
    #ifndef WOLFSSL_NO_MALLOC
31605
0
        XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
31606
0
    #endif
31607
0
    }
31608
31609
0
    return totalSz;
31610
#else
31611
    DECL_ASNSETDATA(dataASN, eccKeyASN_Length);
31612
    word32 privSz, pubSz;
31613
    int sz = 0;
31614
    int ret = 0;
31615
    int curveIdSz = 0;
31616
31617
    /* Check validity of parameters. */
31618
    if ((key == NULL) || ((output == NULL) && (inLen == NULL))) {
31619
        ret = BAD_FUNC_ARG;
31620
    }
31621
31622
    /* Check key has parameters when encoding curve. */
31623
    if ((ret == 0) && curveIn && (key->dp == NULL)) {
31624
        ret = BAD_FUNC_ARG;
31625
    }
31626
31627
    CALLOC_ASNSETDATA(dataASN, eccKeyASN_Length, ret, key->heap);
31628
31629
    if (ret == 0) {
31630
        /* Private key size is the curve size. */
31631
        privSz = key->dp->size;
31632
        if (pubIn) {
31633
            /* Get the length of the public key. */
31634
            PRIVATE_KEY_UNLOCK();
31635
            ret = wc_ecc_export_x963(key, NULL, &pubSz);
31636
            PRIVATE_KEY_LOCK();
31637
            if (ret == LENGTH_ONLY_E)
31638
                ret = 0;
31639
        }
31640
    }
31641
    if (ret == 0) {
31642
        /* Version: 1 */
31643
        SetASN_Int8Bit(&dataASN[ECCKEYASN_IDX_VER], 1);
31644
        /* Leave space for private key. */
31645
        SetASN_Buffer(&dataASN[ECCKEYASN_IDX_PKEY], NULL, privSz);
31646
        if (curveIn) {
31647
            /* Get length of the named curve OID to put into the encoding. */
31648
            curveIdSz = SetCurve(key, NULL, 0);
31649
            if (curveIdSz < 0) {
31650
                ret = curveIdSz;
31651
            }
31652
            /* Curve OID */
31653
            SetASN_ReplaceBuffer(&dataASN[ECCKEYASN_IDX_CURVEID], NULL,
31654
                curveIdSz);
31655
            /* TODO: add support for SpecifiedECDomain curve. */
31656
            dataASN[ECCKEYASN_IDX_CURVEPARAMS].noOut = 1;
31657
        }
31658
        else {
31659
            SetASNItem_NoOutNode(dataASN, eccKeyASN, ECCKEYASN_IDX_PARAMS,
31660
                    eccKeyASN_Length);
31661
        }
31662
        if (ret == 0) {
31663
            if (pubIn) {
31664
                /* Leave space for public key. */
31665
                SetASN_Buffer(&dataASN[ECCKEYASN_IDX_PUBKEY_VAL], NULL, pubSz);
31666
            }
31667
            else {
31668
                /* Don't write out public key. */
31669
                SetASNItem_NoOutNode(dataASN, eccKeyASN, ECCKEYASN_IDX_PUBKEY,
31670
                                     eccKeyASN_Length);
31671
            }
31672
            /* Calculate size of the private key encoding. */
31673
            ret = SizeASN_Items(eccKeyASN, dataASN, eccKeyASN_Length, &sz);
31674
        }
31675
    }
31676
    /* Return the size if no buffer. */
31677
    if ((ret == 0) && (output == NULL)) {
31678
        *inLen = sz;
31679
        ret = LENGTH_ONLY_E;
31680
    }
31681
    /* Check the buffer is big enough. */
31682
    if ((ret == 0) && (inLen != NULL) && (sz > (int)*inLen)) {
31683
        ret = BAD_FUNC_ARG;
31684
    }
31685
    if ((ret == 0) && (output != NULL)) {
31686
        /* Encode the private key. */
31687
        SetASN_Items(eccKeyASN, dataASN, eccKeyASN_Length, output);
31688
31689
        if (curveIn) {
31690
            /* Put named curve OID data into encoding. */
31691
            curveIdSz = SetCurve(key,
31692
                (byte*)dataASN[ECCKEYASN_IDX_CURVEID].data.buffer.data,
31693
                curveIdSz);
31694
            if (curveIdSz < 0) {
31695
                ret = curveIdSz;
31696
            }
31697
        }
31698
        if (ret == 0) {
31699
            /* Export the private value into the buffer. */
31700
            ret = wc_ecc_export_private_only(key,
31701
                (byte*)dataASN[ECCKEYASN_IDX_PKEY].data.buffer.data, &privSz);
31702
        }
31703
        if ((ret == 0) && pubIn) {
31704
            /* Export the public point into the buffer. */
31705
            PRIVATE_KEY_UNLOCK();
31706
            ret = wc_ecc_export_x963(key,
31707
                    (byte*)dataASN[ECCKEYASN_IDX_PUBKEY_VAL].data.buffer.data,
31708
                    &pubSz);
31709
            PRIVATE_KEY_LOCK();
31710
        }
31711
    }
31712
    if (ret == 0) {
31713
        /* Return the encoding size. */
31714
        ret = sz;
31715
    }
31716
31717
    FREE_ASNSETDATA(dataASN, key->heap);
31718
    return ret;
31719
#endif
31720
0
}
31721
31722
/* Write a Private ecc key, including public to DER format,
31723
 * length on success else < 0 */
31724
WOLFSSL_ABI
31725
int wc_EccKeyToDer(ecc_key* key, byte* output, word32 inLen)
31726
0
{
31727
0
    return wc_BuildEccKeyDer(key, output, &inLen, 1, 1);
31728
0
}
31729
31730
/* Write only private ecc key to DER format,
31731
 * length on success else < 0 */
31732
int wc_EccKeyDerSize(ecc_key* key, int pub)
31733
0
{
31734
0
    word32 sz = 0;
31735
0
    int ret;
31736
31737
0
    ret = wc_BuildEccKeyDer(key, NULL, &sz, pub, 1);
31738
31739
0
    if (ret != LENGTH_ONLY_E) {
31740
0
        return ret;
31741
0
    }
31742
0
    return sz;
31743
0
 }
31744
31745
/* Write only private ecc key to DER format,
31746
 * length on success else < 0 */
31747
int wc_EccPrivateKeyToDer(ecc_key* key, byte* output, word32 inLen)
31748
0
{
31749
0
    return wc_BuildEccKeyDer(key, output, &inLen, 0, 1);
31750
0
}
31751
31752
31753
31754
#ifdef HAVE_PKCS8
31755
31756
/* Write only private ecc key or both private and public parts to unencrypted
31757
 * PKCS#8 format.
31758
 *
31759
 * If output is NULL, places required PKCS#8 buffer size in outLen and
31760
 * returns LENGTH_ONLY_E.
31761
 *
31762
 * return length on success else < 0 */
31763
static int eccToPKCS8(ecc_key* key, byte* output, word32* outLen,
31764
        int includePublic)
31765
0
{
31766
0
    int ret, tmpDerSz;
31767
0
    int algoID = 0;
31768
0
    word32 oidSz = 0;
31769
0
    word32 pkcs8Sz = 0;
31770
0
    const byte* curveOID = NULL;
31771
#ifdef WOLFSSL_NO_MALLOC
31772
    byte  tmpDer[ECC_BUFSIZE];
31773
#else
31774
0
    byte* tmpDer = NULL;
31775
0
#endif
31776
0
    word32 sz = ECC_BUFSIZE;
31777
31778
0
    if (key == NULL || key->dp == NULL || outLen == NULL)
31779
0
        return BAD_FUNC_ARG;
31780
31781
    /* set algoID, get curve OID */
31782
0
    algoID = ECDSAk;
31783
0
    ret = wc_ecc_get_oid(key->dp->oidSum, &curveOID, &oidSz);
31784
0
    if (ret < 0)
31785
0
        return ret;
31786
31787
0
#ifndef WOLFSSL_NO_MALLOC
31788
    /* temp buffer for plain DER key */
31789
0
    tmpDer = (byte*)XMALLOC(ECC_BUFSIZE, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
31790
0
    if (tmpDer == NULL)
31791
0
        return MEMORY_E;
31792
0
#endif
31793
0
    XMEMSET(tmpDer, 0, ECC_BUFSIZE);
31794
31795
0
    ret = wc_BuildEccKeyDer(key, tmpDer, &sz, includePublic, 0);
31796
0
    if (ret < 0) {
31797
0
    #ifndef WOLFSSL_NO_MALLOC
31798
0
        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
31799
0
    #endif
31800
0
        return ret;
31801
0
    }
31802
0
    tmpDerSz = ret;
31803
31804
    /* get pkcs8 expected output size */
31805
0
    ret = wc_CreatePKCS8Key(NULL, &pkcs8Sz, tmpDer, tmpDerSz, algoID,
31806
0
                            curveOID, oidSz);
31807
0
    if (ret != LENGTH_ONLY_E) {
31808
0
    #ifndef WOLFSSL_NO_MALLOC
31809
0
        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
31810
0
    #endif
31811
0
        return ret;
31812
0
    }
31813
31814
0
    if (output == NULL) {
31815
0
    #ifndef WOLFSSL_NO_MALLOC
31816
0
        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
31817
0
    #endif
31818
0
        *outLen = pkcs8Sz;
31819
0
        return LENGTH_ONLY_E;
31820
31821
0
    }
31822
0
    else if (*outLen < pkcs8Sz) {
31823
0
    #ifndef WOLFSSL_NO_MALLOC
31824
0
        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
31825
0
    #endif
31826
0
        WOLFSSL_MSG("Input buffer too small for ECC PKCS#8 key");
31827
0
        return BUFFER_E;
31828
0
    }
31829
31830
0
    ret = wc_CreatePKCS8Key(output, &pkcs8Sz, tmpDer, tmpDerSz,
31831
0
                            algoID, curveOID, oidSz);
31832
0
    if (ret < 0) {
31833
0
    #ifndef WOLFSSL_NO_MALLOC
31834
0
        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
31835
0
    #endif
31836
0
        return ret;
31837
0
    }
31838
31839
0
#ifndef WOLFSSL_NO_MALLOC
31840
0
    XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
31841
0
#endif
31842
31843
0
    *outLen = ret;
31844
0
    return ret;
31845
0
}
31846
31847
/* Write only private ecc key to unencrypted PKCS#8 format.
31848
 *
31849
 * return length on success else < 0 */
31850
int wc_EccPrivateKeyToPKCS8(ecc_key* key, byte* output, word32* outLen)
31851
0
{
31852
0
    return eccToPKCS8(key, output, outLen, 0);
31853
0
}
31854
31855
/* Write both private and public ecc keys to unencrypted PKCS#8 format.
31856
 *
31857
 * return length on success else < 0 */
31858
int wc_EccKeyToPKCS8(ecc_key* key, byte* output,
31859
                     word32* outLen)
31860
0
{
31861
0
    return eccToPKCS8(key, output, outLen, 1);
31862
0
}
31863
#endif /* HAVE_PKCS8 */
31864
#endif /* HAVE_ECC_KEY_EXPORT && !NO_ASN_CRYPT */
31865
#endif /* HAVE_ECC */
31866
31867
#ifdef WC_ENABLE_ASYM_KEY_IMPORT
31868
#ifdef WOLFSSL_ASN_TEMPLATE
31869
/* ASN.1 template for Ed25519 and Ed448 private key.
31870
 * RFC 8410, 7 - Private Key Format (but public value is EXPLICIT OCTET_STRING)
31871
 */
31872
static const ASNItem edKeyASN[] = {
31873
/* SEQ            */    { 0, ASN_SEQUENCE, 1, 1, 0 },
31874
                                         /* Version */
31875
/* VER            */        { 1, ASN_INTEGER, 0, 0, 0 },
31876
                                         /* privateKeyAlgorithm */
31877
/* PKEYALGO_SEQ   */        { 1, ASN_SEQUENCE, 1, 1, 0 },
31878
/* PKEYALGO_OID   */            { 2, ASN_OBJECT_ID, 0, 0, 1 },
31879
                                         /* privateKey */
31880
/* PKEY           */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
31881
                                             /* CurvePrivateKey */
31882
/* PKEY_CURVEPKEY */            { 2, ASN_OCTET_STRING, 0, 0, 0 },
31883
                                         /* attributes */
31884
/* ATTRS          */        { 1, ASN_CONTEXT_SPECIFIC | ASN_ASYMKEY_ATTRS, 1, 1, 1 },
31885
                                         /* publicKey */
31886
/* PUBKEY         */        { 1, ASN_CONTEXT_SPECIFIC | ASN_ASYMKEY_PUBKEY, 0, 0, 1 },
31887
};
31888
enum {
31889
    EDKEYASN_IDX_SEQ = 0,
31890
    EDKEYASN_IDX_VER,
31891
    EDKEYASN_IDX_PKEYALGO_SEQ,
31892
    EDKEYASN_IDX_PKEYALGO_OID,
31893
    EDKEYASN_IDX_PKEY,
31894
    EDKEYASN_IDX_PKEY_CURVEPKEY,
31895
    EDKEYASN_IDX_ATTRS,
31896
    EDKEYASN_IDX_PUBKEY,
31897
};
31898
31899
/* Number of items in ASN.1 template for Ed25519 and Ed448 private key. */
31900
#define edKeyASN_Length (sizeof(edKeyASN) / sizeof(ASNItem))
31901
#endif
31902
31903
#if ((defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)) \
31904
    || (defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_KEY_IMPORT)) \
31905
    || (defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)) \
31906
    || (defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_IMPORT)) \
31907
    || (defined(HAVE_PQC) && defined(HAVE_FALCON)) \
31908
    || (defined(HAVE_PQC) && defined(HAVE_DILITHIUM)))
31909
31910
int DecodeAsymKey(const byte* input, word32* inOutIdx, word32 inSz,
31911
    byte* privKey, word32* privKeyLen,
31912
    byte* pubKey, word32* pubKeyLen, int keyType)
31913
0
{
31914
0
#ifndef WOLFSSL_ASN_TEMPLATE
31915
0
    word32 oid;
31916
0
    int version, length, endKeyIdx, privSz, pubSz;
31917
0
    const byte* priv;
31918
0
    const byte* pub;
31919
#else
31920
    int ret = 0;
31921
    DECL_ASNGETDATA(dataASN, edKeyASN_Length);
31922
    CALLOC_ASNGETDATA(dataASN, edKeyASN_Length, ret, NULL);
31923
#endif
31924
31925
0
    if (input == NULL || inOutIdx == NULL || inSz == 0 ||
31926
0
        privKey == NULL || privKeyLen == NULL) {
31927
0
        return BAD_FUNC_ARG;
31928
0
    }
31929
31930
0
#ifndef WOLFSSL_ASN_TEMPLATE
31931
0
    if (GetSequence(input, inOutIdx, &length, inSz) >= 0) {
31932
0
        endKeyIdx = *inOutIdx + length;
31933
31934
0
        if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
31935
0
            return ASN_PARSE_E;
31936
0
        if (version != 0) {
31937
0
            WOLFSSL_MSG("Unrecognized version of ED25519 private key");
31938
0
            return ASN_PARSE_E;
31939
0
        }
31940
31941
0
        if (GetAlgoId(input, inOutIdx, &oid, oidKeyType, inSz) < 0)
31942
0
            return ASN_PARSE_E;
31943
0
        if (oid != (word32)keyType)
31944
0
            return ASN_PARSE_E;
31945
31946
0
        if (GetOctetString(input, inOutIdx, &length, inSz) < 0)
31947
0
            return ASN_PARSE_E;
31948
31949
0
        if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0)
31950
0
            return ASN_PARSE_E;
31951
31952
0
        priv = input + *inOutIdx;
31953
0
        *inOutIdx += privSz;
31954
0
    }
31955
0
    else {
31956
0
        if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0)
31957
0
            return ASN_PARSE_E;
31958
31959
0
        priv = input + *inOutIdx;
31960
0
        *inOutIdx += privSz;
31961
0
        endKeyIdx = *inOutIdx;
31962
0
    }
31963
31964
0
    if ((word32)privSz > *privKeyLen)
31965
0
        return BUFFER_E;
31966
31967
0
    if (endKeyIdx == (int)*inOutIdx) {
31968
0
        *privKeyLen = privSz;
31969
0
        XMEMCPY(privKey, priv, *privKeyLen);
31970
0
        if (pubKeyLen != NULL)
31971
0
            *pubKeyLen = 0;
31972
0
    }
31973
0
    else {
31974
0
        if (pubKeyLen == NULL) {
31975
0
            return BAD_FUNC_ARG;
31976
0
        }
31977
31978
0
        if (GetASNHeader(input, ASN_CONTEXT_SPECIFIC | ASN_ASYMKEY_PUBKEY | 1,
31979
0
                         inOutIdx, &pubSz, inSz) < 0) {
31980
0
            return ASN_PARSE_E;
31981
0
        }
31982
31983
0
        if ((word32)pubSz > *pubKeyLen)
31984
0
            return BUFFER_E;
31985
31986
0
        pub = input + *inOutIdx;
31987
0
        *inOutIdx += pubSz;
31988
31989
0
        *privKeyLen = privSz;
31990
0
        XMEMCPY(privKey, priv, *privKeyLen);
31991
0
        *pubKeyLen = pubSz;
31992
0
        if (pubKey != NULL)
31993
0
            XMEMCPY(pubKey, pub, *pubKeyLen);
31994
0
    }
31995
0
    if (endKeyIdx != (int)*inOutIdx)
31996
0
        return ASN_PARSE_E;
31997
0
    return 0;
31998
#else
31999
    if (ret == 0) {
32000
        /* Require OID. */
32001
        word32 oidSz;
32002
        const byte* oid = OidFromId(keyType, oidKeyType, &oidSz);
32003
        GetASN_ExpBuffer(&dataASN[EDKEYASN_IDX_PKEYALGO_OID], oid, oidSz);
32004
        /* Parse full private key. */
32005
        ret = GetASN_Items(edKeyASN, dataASN, edKeyASN_Length, 1, input,
32006
                inOutIdx, inSz);
32007
        if (ret != 0) {
32008
            /* Parse just the OCTET_STRING. */
32009
            ret = GetASN_Items(&edKeyASN[EDKEYASN_IDX_PKEY_CURVEPKEY],
32010
                    &dataASN[EDKEYASN_IDX_PKEY_CURVEPKEY], 1, 0, input,
32011
                    inOutIdx, inSz);
32012
            if (ret != 0) {
32013
                ret = ASN_PARSE_E;
32014
            }
32015
        }
32016
    }
32017
    /* Check the private value length is correct. */
32018
    if ((ret == 0) && dataASN[EDKEYASN_IDX_PKEY_CURVEPKEY].data.ref.length
32019
            > *privKeyLen) {
32020
        ret = ASN_PARSE_E;
32021
    }
32022
    if ((ret == 0) && dataASN[EDKEYASN_IDX_PUBKEY].tag == 0) {
32023
        *privKeyLen = dataASN[EDKEYASN_IDX_PKEY_CURVEPKEY].data.ref.length;
32024
        XMEMCPY(privKey, dataASN[EDKEYASN_IDX_PKEY_CURVEPKEY].data.ref.data,
32025
                *privKeyLen);
32026
        if (pubKeyLen != NULL)
32027
            *pubKeyLen = 0;
32028
    }
32029
    else if ((ret == 0) &&
32030
             (pubKeyLen != NULL) &&
32031
             (dataASN[EDKEYASN_IDX_PUBKEY].data.ref.length > *pubKeyLen)) {
32032
        ret = ASN_PARSE_E;
32033
    }
32034
    else if (ret == 0) {
32035
        /* Import private and public value. */
32036
        *privKeyLen = dataASN[EDKEYASN_IDX_PKEY_CURVEPKEY].data.ref.length;
32037
        XMEMCPY(privKey, dataASN[EDKEYASN_IDX_PKEY_CURVEPKEY].data.ref.data,
32038
                *privKeyLen);
32039
        if (pubKeyLen != NULL)
32040
            *pubKeyLen = dataASN[EDKEYASN_IDX_PUBKEY].data.ref.length;
32041
        if (pubKey != NULL && pubKeyLen != NULL)
32042
            XMEMCPY(pubKey, dataASN[EDKEYASN_IDX_PUBKEY].data.ref.data,
32043
                    *pubKeyLen);
32044
    }
32045
32046
    FREE_ASNGETDATA(dataASN, NULL);
32047
    return ret;
32048
#endif /* WOLFSSL_ASN_TEMPLATE */
32049
0
}
32050
32051
int DecodeAsymKeyPublic(const byte* input, word32* inOutIdx, word32 inSz,
32052
    byte* pubKey, word32* pubKeyLen, int keyType)
32053
0
{
32054
0
    int ret = 0;
32055
0
#ifndef WOLFSSL_ASN_TEMPLATE
32056
0
    int length;
32057
0
    word32 oid;
32058
#else
32059
    word32 len;
32060
    DECL_ASNGETDATA(dataASN, edPubKeyASN_Length);
32061
#endif
32062
32063
0
    if (input == NULL || inSz == 0 || inOutIdx == NULL ||
32064
0
        pubKey == NULL || pubKeyLen == NULL) {
32065
0
        return BAD_FUNC_ARG;
32066
0
    }
32067
32068
0
#ifndef WOLFSSL_ASN_TEMPLATE
32069
0
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
32070
0
        return ASN_PARSE_E;
32071
32072
0
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
32073
0
        return ASN_PARSE_E;
32074
32075
0
    if (GetObjectId(input, inOutIdx, &oid, oidKeyType, inSz) < 0)
32076
0
        return ASN_PARSE_E;
32077
0
    if (oid != (word32)keyType)
32078
0
        return ASN_PARSE_E;
32079
32080
    /* key header */
32081
0
    ret = CheckBitString(input, inOutIdx, &length, inSz, 1, NULL);
32082
0
    if (ret != 0)
32083
0
        return ret;
32084
32085
    /* check that the value found is not too large for pubKey buffer */
32086
0
    if ((word32)length > *pubKeyLen)
32087
0
        return ASN_PARSE_E;
32088
32089
    /* check that input buffer is exhausted */
32090
0
    if (*inOutIdx + (word32)length != inSz)
32091
0
        return ASN_PARSE_E;
32092
32093
    /* This is the raw point data compressed or uncompressed. */
32094
0
    *pubKeyLen = length;
32095
0
    XMEMCPY(pubKey, input + *inOutIdx, *pubKeyLen);
32096
#else
32097
    len = inSz - *inOutIdx;
32098
32099
    CALLOC_ASNGETDATA(dataASN, edPubKeyASN_Length, ret, NULL);
32100
32101
    if (ret == 0) {
32102
        /* Require OID. */
32103
        word32 oidSz;
32104
        const byte* oid = OidFromId(keyType, oidKeyType, &oidSz);
32105
32106
        GetASN_ExpBuffer(&dataASN[EDPUBKEYASN_IDX_ALGOID_OID], oid, oidSz);
32107
        /* Decode Ed25519 private key. */
32108
        ret = GetASN_Items(edPubKeyASN, dataASN, edPubKeyASN_Length, 1, input,
32109
                inOutIdx, inSz);
32110
        if (ret != 0)
32111
            ret = ASN_PARSE_E;
32112
        /* check that input buffer is exhausted */
32113
        if (*inOutIdx != inSz)
32114
            ret = ASN_PARSE_E;
32115
    }
32116
    /* Check the public value length is correct. */
32117
    if ((ret == 0) &&
32118
            (dataASN[EDPUBKEYASN_IDX_PUBKEY].data.ref.length > *pubKeyLen)) {
32119
        ret = ASN_PARSE_E;
32120
    }
32121
    /* Check that the all the buffer was used. */
32122
    if ((ret == 0) &&
32123
            (GetASNItem_Length(dataASN[EDPUBKEYASN_IDX_SEQ], input) != len)) {
32124
        ret = ASN_PARSE_E;
32125
    }
32126
    if (ret == 0) {
32127
        *pubKeyLen = dataASN[EDPUBKEYASN_IDX_PUBKEY].data.ref.length;
32128
        XMEMCPY(pubKey, dataASN[EDPUBKEYASN_IDX_PUBKEY].data.ref.data,
32129
                *pubKeyLen);
32130
    }
32131
32132
    FREE_ASNGETDATA(dataASN, NULL);
32133
#endif /* WOLFSSL_ASN_TEMPLATE */
32134
0
    return ret;
32135
0
}
32136
#endif
32137
#endif /* WC_ENABLE_ASYM_KEY_IMPORT */
32138
32139
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
32140
int wc_Ed25519PrivateKeyDecode(const byte* input, word32* inOutIdx,
32141
                               ed25519_key* key, word32 inSz)
32142
0
{
32143
0
    int ret;
32144
0
    byte privKey[ED25519_KEY_SIZE], pubKey[ED25519_PUB_KEY_SIZE];
32145
0
    word32 privKeyLen = (word32)sizeof(privKey);
32146
0
    word32 pubKeyLen = (word32)sizeof(pubKey);
32147
32148
0
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
32149
0
        return BAD_FUNC_ARG;
32150
0
    }
32151
32152
0
    ret = DecodeAsymKey(input, inOutIdx, inSz, privKey, &privKeyLen,
32153
0
        pubKey, &pubKeyLen, ED25519k);
32154
0
    if (ret == 0) {
32155
0
        if (pubKeyLen == 0) {
32156
0
            ret = wc_ed25519_import_private_only(privKey, privKeyLen, key);
32157
0
        }
32158
0
        else {
32159
0
            ret = wc_ed25519_import_private_key(privKey, privKeyLen,
32160
0
                pubKey, pubKeyLen, key);
32161
0
        }
32162
0
    }
32163
0
    return ret;
32164
0
}
32165
32166
int wc_Ed25519PublicKeyDecode(const byte* input, word32* inOutIdx,
32167
                              ed25519_key* key, word32 inSz)
32168
0
{
32169
0
    int ret;
32170
0
    byte pubKey[ED25519_PUB_KEY_SIZE];
32171
0
    word32 pubKeyLen = (word32)sizeof(pubKey);
32172
32173
0
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
32174
0
        return BAD_FUNC_ARG;
32175
0
    }
32176
32177
0
    ret = DecodeAsymKeyPublic(input, inOutIdx, inSz,
32178
0
        pubKey, &pubKeyLen, ED25519k);
32179
0
    if (ret == 0) {
32180
0
        ret = wc_ed25519_import_public(pubKey, pubKeyLen, key);
32181
0
    }
32182
0
    return ret;
32183
0
}
32184
#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT */
32185
32186
#if defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_KEY_IMPORT)
32187
int wc_Curve25519PrivateKeyDecode(const byte* input, word32* inOutIdx,
32188
                               curve25519_key* key, word32 inSz)
32189
0
{
32190
0
    int ret;
32191
0
    byte privKey[CURVE25519_KEYSIZE];
32192
0
    word32 privKeyLen = CURVE25519_KEYSIZE;
32193
32194
0
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
32195
0
        return BAD_FUNC_ARG;
32196
0
    }
32197
32198
0
    ret = DecodeAsymKey(input, inOutIdx, inSz, privKey, &privKeyLen,
32199
0
        NULL, NULL, X25519k);
32200
0
    if (ret == 0) {
32201
0
        ret = wc_curve25519_import_private(privKey, privKeyLen, key);
32202
0
    }
32203
0
    return ret;
32204
0
}
32205
32206
int wc_Curve25519PublicKeyDecode(const byte* input, word32* inOutIdx,
32207
                              curve25519_key* key, word32 inSz)
32208
0
{
32209
0
    int ret;
32210
0
    byte pubKey[CURVE25519_KEYSIZE];
32211
0
    word32 pubKeyLen = (word32)sizeof(pubKey);
32212
32213
0
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
32214
0
        return BAD_FUNC_ARG;
32215
0
    }
32216
32217
0
    ret = DecodeAsymKeyPublic(input, inOutIdx, inSz,
32218
0
        pubKey, &pubKeyLen, X25519k);
32219
0
    if (ret == 0) {
32220
0
        ret = wc_curve25519_import_public(pubKey, pubKeyLen, key);
32221
0
    }
32222
0
    return ret;
32223
0
}
32224
#endif /* HAVE_CURVE25519 && HAVE_ED25519_KEY_IMPORT */
32225
32226
32227
#ifdef WC_ENABLE_ASYM_KEY_EXPORT
32228
32229
/* Build ASN.1 formatted key based on RFC 5958 (Asymmetric Key Packages)
32230
 *
32231
 * Pass NULL for output to get the size of the encoding.
32232
 *
32233
 * @param [in]  privKey      private key buffer
32234
 * @param [in]  privKeyLen   private ket buffer length
32235
 * @param [in]  pubKey       public key buffer (optional)
32236
 * @param [in]  pubKeyLen    public ket buffer length
32237
 * @param [out] output       Buffer to put encoded data in (optional)
32238
 * @param [in]  outLen       Size of buffer in bytes
32239
 * @param [in]  keyType      is "enum Key_Sum" like ED25519k
32240
 * @return  Size of encoded data in bytes on success
32241
 * @return  BAD_FUNC_ARG when key is NULL.
32242
 * @return  MEMORY_E when dynamic memory allocation failed.
32243
 */
32244
int SetAsymKeyDer(const byte* privKey, word32 privKeyLen,
32245
    const byte* pubKey, word32 pubKeyLen,
32246
    byte* output, word32 outLen, int keyType)
32247
0
{
32248
0
    int ret = 0;
32249
0
#ifndef WOLFSSL_ASN_TEMPLATE
32250
0
    word32 idx = 0, seqSz, verSz, algoSz, privSz, pubSz = 0, sz;
32251
#else
32252
    DECL_ASNSETDATA(dataASN, edKeyASN_Length);
32253
    int sz;
32254
#endif
32255
32256
    /* Validate parameters. */
32257
0
    if (privKey == NULL || outLen == 0) {
32258
0
        return BAD_FUNC_ARG;
32259
0
    }
32260
32261
0
#ifndef WOLFSSL_ASN_TEMPLATE
32262
    /* calculate size */
32263
0
    if (pubKey) {
32264
0
        pubSz = 2 + pubKeyLen;
32265
0
    }
32266
0
    privSz = 2 + 2 + privKeyLen;
32267
0
    algoSz = SetAlgoID(keyType, NULL, oidKeyType, 0);
32268
0
    verSz  = 3; /* version is 3 bytes (enum + id + version(byte)) */
32269
0
    seqSz  = SetSequence(verSz + algoSz + privSz + pubSz, NULL);
32270
0
    sz = seqSz + verSz + algoSz + privSz + pubSz;
32271
32272
    /* checkout output size */
32273
0
    if (output != NULL && sz > outLen) {
32274
0
        ret = BAD_FUNC_ARG;
32275
0
    }
32276
32277
0
    if (ret == 0 && output != NULL) {
32278
        /* write out */
32279
        /* seq */
32280
0
        seqSz = SetSequence(verSz + algoSz + privSz + pubSz, output);
32281
0
        idx = seqSz;
32282
        /* ver */
32283
0
        SetMyVersion(0, output + idx, FALSE);
32284
0
        idx += verSz;
32285
        /* algo */
32286
0
        algoSz = SetAlgoID(keyType, output + idx, oidKeyType, 0);
32287
0
        idx += algoSz;
32288
        /* privKey */
32289
0
        idx += SetOctetString(2 + privKeyLen, output + idx);
32290
0
        idx += SetOctetString(privKeyLen, output + idx);
32291
0
        XMEMCPY(output + idx, privKey, privKeyLen);
32292
0
        idx += privKeyLen;
32293
        /* pubKey */
32294
0
        if (pubKey) {
32295
0
            idx += SetHeader(ASN_CONTEXT_SPECIFIC | ASN_ASYMKEY_PUBKEY |
32296
0
                             1, pubKeyLen, output + idx);
32297
0
            XMEMCPY(output + idx, pubKey, pubKeyLen);
32298
0
            idx += pubKeyLen;
32299
0
        }
32300
0
        sz = idx;
32301
0
    }
32302
0
    if (ret == 0) {
32303
        /* Return size of encoding. */
32304
0
        ret = sz;
32305
0
    }
32306
#else
32307
32308
    CALLOC_ASNSETDATA(dataASN, edKeyASN_Length, ret, NULL);
32309
32310
    if (ret == 0) {
32311
        /* Set version = 0 */
32312
        SetASN_Int8Bit(&dataASN[EDKEYASN_IDX_VER], 0);
32313
        /* Set OID. */
32314
        SetASN_OID(&dataASN[EDKEYASN_IDX_PKEYALGO_OID], keyType, oidKeyType);
32315
        /* Leave space for private key. */
32316
        SetASN_Buffer(&dataASN[EDKEYASN_IDX_PKEY_CURVEPKEY], NULL, privKeyLen);
32317
        /* Don't write out attributes. */
32318
        dataASN[EDKEYASN_IDX_ATTRS].noOut = 1;
32319
        if (pubKey) {
32320
            /* Leave space for public key. */
32321
            SetASN_Buffer(&dataASN[EDKEYASN_IDX_PUBKEY], NULL, pubKeyLen);
32322
        }
32323
        else {
32324
            /* Don't put out public part. */
32325
            SetASNItem_NoOutNode(dataASN, edKeyASN, EDKEYASN_IDX_PUBKEY,
32326
                    edKeyASN_Length);
32327
        }
32328
32329
        /* Calculate the size of encoding. */
32330
        ret = SizeASN_Items(edKeyASN, dataASN, edKeyASN_Length, &sz);
32331
    }
32332
32333
    /* Check buffer is big enough. */
32334
    if ((ret == 0) && (output != NULL) && (sz > (int)outLen)) {
32335
        ret = BAD_FUNC_ARG;
32336
    }
32337
    if ((ret == 0) && (output != NULL)) {
32338
        /* Encode private key. */
32339
        SetASN_Items(edKeyASN, dataASN, edKeyASN_Length, output);
32340
32341
        /* Put private value into space provided. */
32342
        XMEMCPY((byte*)dataASN[EDKEYASN_IDX_PKEY_CURVEPKEY].data.buffer.data,
32343
                privKey, privKeyLen);
32344
32345
        if (pubKey != NULL) {
32346
            /* Put public value into space provided. */
32347
            XMEMCPY((byte*)dataASN[EDKEYASN_IDX_PUBKEY].data.buffer.data,
32348
                    pubKey, pubKeyLen);
32349
        }
32350
    }
32351
    if (ret == 0) {
32352
        /* Return size of encoding. */
32353
        ret = sz;
32354
    }
32355
32356
    FREE_ASNSETDATA(dataASN, NULL);
32357
#endif
32358
0
    return ret;
32359
0
}
32360
#endif /* WC_ENABLE_ASYM_KEY_EXPORT */
32361
32362
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
32363
/* Write a Private ED25519 key, including public to DER format,
32364
 * length on success else < 0 */
32365
int wc_Ed25519KeyToDer(ed25519_key* key, byte* output, word32 inLen)
32366
0
{
32367
0
    if (key == NULL) {
32368
0
        return BAD_FUNC_ARG;
32369
0
    }
32370
0
    return SetAsymKeyDer(key->k, ED25519_KEY_SIZE,
32371
0
        key->p, ED25519_PUB_KEY_SIZE, output, inLen, ED25519k);
32372
0
}
32373
32374
/* Write only private ED25519 key to DER format,
32375
 * length on success else < 0 */
32376
int wc_Ed25519PrivateKeyToDer(ed25519_key* key, byte* output, word32 inLen)
32377
0
{
32378
0
    if (key == NULL) {
32379
0
        return BAD_FUNC_ARG;
32380
0
    }
32381
0
    return SetAsymKeyDer(key->k, ED25519_KEY_SIZE,
32382
0
        NULL, 0, output, inLen, ED25519k);
32383
0
}
32384
#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_EXPORT */
32385
32386
#if defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_KEY_EXPORT)
32387
/* Write only private Curve25519 key to DER format,
32388
 * length on success else < 0 */
32389
int wc_Curve25519PrivateKeyToDer(curve25519_key* key, byte* output, word32 inLen)
32390
0
{
32391
0
    int    ret;
32392
0
    byte   privKey[CURVE25519_KEYSIZE];
32393
0
    word32 privKeyLen = CURVE25519_KEYSIZE;
32394
32395
0
    if (key == NULL) {
32396
0
        return BAD_FUNC_ARG;
32397
0
    }
32398
32399
0
    ret = wc_curve25519_export_private_raw(key, privKey, &privKeyLen);
32400
0
    if (ret == 0) {
32401
0
        ret = SetAsymKeyDer(privKey, privKeyLen, NULL, 0, output, inLen,
32402
0
            X25519k);
32403
0
    }
32404
0
    return ret;
32405
0
}
32406
32407
/* Write a public Curve25519 key to DER format,
32408
 * length on success else < 0 */
32409
int wc_Curve25519PublicKeyToDer(curve25519_key* key, byte* output, word32 inLen,
32410
                             int withAlg)
32411
0
{
32412
0
    int    ret;
32413
0
    byte   pubKey[CURVE25519_PUB_KEY_SIZE];
32414
0
    word32 pubKeyLen = (word32)sizeof(pubKey);
32415
32416
0
    if (key == NULL || output == NULL) {
32417
0
        return BAD_FUNC_ARG;
32418
0
    }
32419
32420
0
    ret = wc_curve25519_export_public(key, pubKey, &pubKeyLen);
32421
0
    if (ret == 0) {
32422
0
        ret = SetAsymKeyDerPublic(pubKey, pubKeyLen, output, inLen,
32423
0
            X25519k, withAlg);
32424
0
    }
32425
0
    return ret;
32426
0
}
32427
#endif /* HAVE_CURVE25519 && HAVE_CURVE25519_KEY_EXPORT */
32428
32429
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)
32430
int wc_Ed448PrivateKeyDecode(const byte* input, word32* inOutIdx,
32431
                               ed448_key* key, word32 inSz)
32432
0
{
32433
0
    int ret;
32434
0
    byte privKey[ED448_KEY_SIZE], pubKey[ED448_PUB_KEY_SIZE];
32435
0
    word32 privKeyLen = (word32)sizeof(privKey);
32436
0
    word32 pubKeyLen = (word32)sizeof(pubKey);
32437
32438
0
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
32439
0
        return BAD_FUNC_ARG;
32440
0
    }
32441
32442
0
    ret = DecodeAsymKey(input, inOutIdx, inSz, privKey, &privKeyLen,
32443
0
        pubKey, &pubKeyLen, ED448k);
32444
0
    if (ret == 0) {
32445
0
        if (pubKeyLen == 0) {
32446
0
            ret = wc_ed448_import_private_only(privKey, privKeyLen, key);
32447
0
        }
32448
0
        else {
32449
0
            ret = wc_ed448_import_private_key(privKey, privKeyLen,
32450
0
                pubKey, pubKeyLen, key);
32451
0
        }
32452
0
    }
32453
0
    return ret;
32454
0
}
32455
32456
int wc_Ed448PublicKeyDecode(const byte* input, word32* inOutIdx,
32457
                              ed448_key* key, word32 inSz)
32458
0
{
32459
0
    int ret;
32460
0
    byte pubKey[ED448_PUB_KEY_SIZE];
32461
0
    word32 pubKeyLen = (word32)sizeof(pubKey);
32462
32463
0
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
32464
0
        return BAD_FUNC_ARG;
32465
0
    }
32466
32467
0
    ret = DecodeAsymKeyPublic(input, inOutIdx, inSz,
32468
0
        pubKey, &pubKeyLen, ED448k);
32469
0
    if (ret == 0) {
32470
0
        ret = wc_ed448_import_public(pubKey, pubKeyLen, key);
32471
0
    }
32472
0
    return ret;
32473
0
}
32474
#endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT */
32475
32476
#if defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_IMPORT)
32477
int wc_Curve448PrivateKeyDecode(const byte* input, word32* inOutIdx,
32478
                               curve448_key* key, word32 inSz)
32479
0
{
32480
0
    int ret;
32481
0
    byte privKey[CURVE448_KEY_SIZE];
32482
0
    word32 privKeyLen = CURVE448_KEY_SIZE;
32483
32484
0
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
32485
0
        return BAD_FUNC_ARG;
32486
0
    }
32487
32488
0
    ret = DecodeAsymKey(input, inOutIdx, inSz, privKey, &privKeyLen,
32489
0
        NULL, NULL, X448k);
32490
0
    if (ret == 0) {
32491
0
        ret = wc_curve448_import_private(privKey, privKeyLen, key);
32492
0
    }
32493
0
    return ret;
32494
0
}
32495
32496
int wc_Curve448PublicKeyDecode(const byte* input, word32* inOutIdx,
32497
                              curve448_key* key, word32 inSz)
32498
0
{
32499
0
    int ret;
32500
0
    byte pubKey[CURVE448_PUB_KEY_SIZE];
32501
0
    word32 pubKeyLen = (word32)sizeof(pubKey);
32502
32503
0
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
32504
0
        return BAD_FUNC_ARG;
32505
0
    }
32506
32507
0
    ret = DecodeAsymKeyPublic(input, inOutIdx, inSz,
32508
0
        pubKey, &pubKeyLen, X448k);
32509
0
    if (ret == 0) {
32510
0
        ret = wc_curve448_import_public(pubKey, pubKeyLen, key);
32511
0
    }
32512
0
    return ret;
32513
0
}
32514
#endif /* HAVE_CURVE448 && HAVE_ED448_KEY_IMPORT */
32515
32516
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
32517
/* Write a Private ecc key, including public to DER format,
32518
 * length on success else < 0 */
32519
int wc_Ed448KeyToDer(ed448_key* key, byte* output, word32 inLen)
32520
0
{
32521
0
    if (key == NULL) {
32522
0
        return BAD_FUNC_ARG;
32523
0
    }
32524
0
    return SetAsymKeyDer(key->k, ED448_KEY_SIZE,
32525
0
        key->p, ED448_KEY_SIZE, output, inLen, ED448k);
32526
0
}
32527
32528
/* Write only private ecc key to DER format,
32529
 * length on success else < 0 */
32530
int wc_Ed448PrivateKeyToDer(ed448_key* key, byte* output, word32 inLen)
32531
0
{
32532
0
    if (key == NULL) {
32533
0
        return BAD_FUNC_ARG;
32534
0
    }
32535
0
    return SetAsymKeyDer(key->k, ED448_KEY_SIZE,
32536
0
        NULL, 0, output, inLen, ED448k);
32537
0
}
32538
32539
#endif /* HAVE_ED448 && HAVE_ED448_KEY_EXPORT */
32540
32541
#if defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_EXPORT)
32542
/* Write private Curve448 key to DER format,
32543
 * length on success else < 0 */
32544
int wc_Curve448PrivateKeyToDer(curve448_key* key, byte* output, word32 inLen)
32545
0
{
32546
0
    int    ret;
32547
0
    byte   privKey[CURVE448_KEY_SIZE];
32548
0
    word32 privKeyLen = CURVE448_KEY_SIZE;
32549
32550
0
    if (key == NULL) {
32551
0
        return BAD_FUNC_ARG;
32552
0
    }
32553
32554
0
    ret = wc_curve448_export_private_raw(key, privKey, &privKeyLen);
32555
0
    if (ret == 0) {
32556
0
        ret = SetAsymKeyDer(privKey, privKeyLen, NULL, 0, output, inLen,
32557
0
            X448k);
32558
0
    }
32559
0
    return ret;
32560
0
}
32561
/* Write a public Curve448 key to DER format,
32562
 * length on success else < 0 */
32563
int wc_Curve448PublicKeyToDer(curve448_key* key, byte* output, word32 inLen,
32564
                             int withAlg)
32565
0
{
32566
0
    int    ret;
32567
0
    byte   pubKey[CURVE448_PUB_KEY_SIZE];
32568
0
    word32 pubKeyLen = (word32)sizeof(pubKey);
32569
32570
0
    if (key == NULL || output == NULL) {
32571
0
        return BAD_FUNC_ARG;
32572
0
    }
32573
32574
0
    ret = wc_curve448_export_public(key, pubKey, &pubKeyLen);
32575
0
    if (ret == 0) {
32576
0
        ret = SetAsymKeyDerPublic(pubKey, pubKeyLen, output, inLen,
32577
0
            X448k, withAlg);
32578
0
    }
32579
0
    return ret;
32580
0
}
32581
#endif /* HAVE_CURVE448 && HAVE_CURVE448_KEY_EXPORT */
32582
32583
32584
#ifndef WOLFSSL_ASN_TEMPLATE
32585
#if defined(HAVE_OCSP) || defined(HAVE_CRL)
32586
32587
/* Get raw Date only, no processing, 0 on success */
32588
static int GetBasicDate(const byte* source, word32* idx, byte* date,
32589
                        byte* format, int maxIdx)
32590
{
32591
    int    ret, length;
32592
    const byte *datePtr = NULL;
32593
32594
    WOLFSSL_ENTER("GetBasicDate");
32595
32596
    ret = GetDateInfo(source, idx, &datePtr, format, &length, maxIdx);
32597
    if (ret < 0)
32598
        return ret;
32599
32600
    XMEMCPY(date, datePtr, length);
32601
32602
    return 0;
32603
}
32604
32605
#endif /* HAVE_OCSP || HAVE_CRL */
32606
#endif /* WOLFSSL_ASN_TEMPLATE */
32607
32608
32609
#ifdef HAVE_OCSP
32610
32611
#ifndef WOLFSSL_ASN_TEMPLATE
32612
static int GetEnumerated(const byte* input, word32* inOutIdx, int *value,
32613
        int sz)
32614
{
32615
    word32 idx = *inOutIdx;
32616
    word32 len;
32617
    byte   tag;
32618
32619
    WOLFSSL_ENTER("GetEnumerated");
32620
32621
    *value = 0;
32622
32623
    if (GetASNTag(input, &idx, &tag, sz) < 0)
32624
        return ASN_PARSE_E;
32625
32626
    if (tag != ASN_ENUMERATED)
32627
        return ASN_PARSE_E;
32628
32629
    if ((int)idx >= sz)
32630
        return BUFFER_E;
32631
32632
    len = input[idx++];
32633
    if (len > 4 || (int)(len + idx) > sz)
32634
        return ASN_PARSE_E;
32635
32636
    while (len--) {
32637
        *value  = *value << 8 | input[idx++];
32638
    }
32639
32640
    *inOutIdx = idx;
32641
32642
    return *value;
32643
}
32644
#endif /* !WOLFSSL_ASN_TEMPLATE */
32645
32646
32647
#ifdef WOLFSSL_ASN_TEMPLATE
32648
/* ASN.1 template for OCSP single response.
32649
 * RFC 6960, 4.2.1 - ASN.1 Specification of the OCSP Response
32650
 */
32651
static const ASNItem singleResponseASN[] = {
32652
/* SEQ                   */ { 0, ASN_SEQUENCE, 1, 1, 0 },
32653
                                                      /* certId */
32654
/* CID_SEQ               */     { 1, ASN_SEQUENCE, 1, 1, 0 },
32655
                                                          /* hashAlgorithm */
32656
/* CID_HASHALGO_SEQ      */         { 2, ASN_SEQUENCE, 1, 1, 0 },
32657
/* CID_HASHALGO_OID      */             { 3, ASN_OBJECT_ID, 0, 0, 0 },
32658
/* CID_HASHALGO_NULL     */             { 3, ASN_TAG_NULL, 0, 0, 1 },
32659
                                                          /* issuerNameHash */
32660
/* CID_ISSUERHASH        */         { 2, ASN_OCTET_STRING, 0, 0, 0 },
32661
                                                          /* issuerKeyHash */
32662
/* CID_ISSUERKEYHASH     */         { 2, ASN_OCTET_STRING, 0, 0, 0 },
32663
                                                          /* serialNumber */
32664
/* CID_SERIAL            */         { 2, ASN_INTEGER, 0, 0, 0 },
32665
                                                      /* certStatus - CHOICE */
32666
                                                      /* good              [0] IMPLICIT NULL */
32667
/* CS_GOOD               */     { 1, ASN_CONTEXT_SPECIFIC | 0, 0, 0, 2 },
32668
                                                      /* revoked           [1] IMPLICIT RevokedInfo */
32669
/* CS_REVOKED            */     { 1, ASN_CONTEXT_SPECIFIC | 1, 1, 1, 2 },
32670
                                                          /* revocationTime */
32671
/* CS_REVOKED_TIME       */         { 2, ASN_GENERALIZED_TIME, 0, 0, 0 },
32672
                                                          /* revocationReason  [0] EXPLICIT CRLReason OPTIONAL */
32673
/* CS_REVOKED_REASON     */         { 2, ASN_CONTEXT_SPECIFIC | 0, 0, 1, 1 },
32674
                                                              /* crlReason */
32675
/* CS_REVOKED_REASON_VAL */             { 3, ASN_ENUMERATED, 0, 0, 0 },
32676
                                                      /* unknown           [2] IMPLICIT UnknownInfo ::= NULL */
32677
/* UNKNOWN               */     { 1, ASN_CONTEXT_SPECIFIC | 2, 0, 0, 2 },
32678
32679
                                                      /* thisUpdate */
32680
/* THISUPDATE_GT         */     { 1, ASN_GENERALIZED_TIME, 0, 0, 0 },
32681
                                                      /* nextUpdate */
32682
/* NEXTUPDATE            */     { 1, ASN_CONTEXT_SPECIFIC | 0, 1, 1, 1 },
32683
/* NEXTUPDATE_GT         */         { 2, ASN_GENERALIZED_TIME, 0, 0, 0 },
32684
                                                      /* singleExtensions */
32685
/* EXT                   */     { 1, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 1 },
32686
};
32687
enum {
32688
    SINGLERESPONSEASN_IDX_SEQ = 0,
32689
    SINGLERESPONSEASN_IDX_CID_SEQ,
32690
    SINGLERESPONSEASN_IDX_CID_HASHALGO_SEQ,
32691
    SINGLERESPONSEASN_IDX_CID_HASHALGO_OID,
32692
    SINGLERESPONSEASN_IDX_CID_HASHALGO_NULL,
32693
    SINGLERESPONSEASN_IDX_CID_ISSUERHASH,
32694
    SINGLERESPONSEASN_IDX_CID_ISSUERKEYHASH,
32695
    SINGLERESPONSEASN_IDX_CID_SERIAL,
32696
    SINGLERESPONSEASN_IDX_CS_GOOD,
32697
    SINGLERESPONSEASN_IDX_CS_REVOKED,
32698
    SINGLERESPONSEASN_IDX_CS_REVOKED_TIME,
32699
    SINGLERESPONSEASN_IDX_CS_REVOKED_REASON,
32700
    SINGLERESPONSEASN_IDX_CS_REVOKED_REASON_VAL,
32701
    SINGLERESPONSEASN_IDX_UNKNOWN,
32702
    SINGLERESPONSEASN_IDX_THISUPDATE_GT,
32703
    SINGLERESPONSEASN_IDX_NEXTUPDATE,
32704
    SINGLERESPONSEASN_IDX_NEXTUPDATE_GT,
32705
    SINGLERESPONSEASN_IDX_EXT,
32706
};
32707
32708
/* Number of items in ASN.1 template for OCSP single response. */
32709
#define singleResponseASN_Length (sizeof(singleResponseASN) / sizeof(ASNItem))
32710
#endif
32711
32712
static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size,
32713
                                int wrapperSz, OcspEntry* single)
32714
{
32715
#ifndef WOLFSSL_ASN_TEMPLATE
32716
    word32 idx = *ioIndex, prevIndex, oid, localIdx, certIdIdx;
32717
    int length;
32718
    int ret;
32719
    byte tag;
32720
32721
    WOLFSSL_ENTER("DecodeSingleResponse");
32722
32723
    prevIndex = idx;
32724
32725
    /* Wrapper around the Single Response */
32726
    if (GetSequence(source, &idx, &length, size) < 0)
32727
        return ASN_PARSE_E;
32728
32729
    /* Wrapper around the CertID */
32730
    certIdIdx = idx;
32731
    if (GetSequence(source, &idx, &length, size) < 0)
32732
        return ASN_PARSE_E;
32733
    single->rawCertId = source + certIdIdx;
32734
    /* Hash algorithm */
32735
    ret = GetAlgoId(source, &idx, &oid, oidIgnoreType, size);
32736
    if (ret < 0)
32737
        return ret;
32738
    single->hashAlgoOID = oid;
32739
    /* Save reference to the hash of CN */
32740
    ret = GetOctetString(source, &idx, &length, size);
32741
    if (ret < 0)
32742
        return ret;
32743
    if (length > (int)sizeof(single->issuerHash))
32744
        return BUFFER_E;
32745
    XMEMCPY(single->issuerHash, source + idx, length);
32746
    idx += length;
32747
    /* Save reference to the hash of the issuer public key */
32748
    ret = GetOctetString(source, &idx, &length, size);
32749
    if (ret < 0)
32750
        return ret;
32751
    if (length > (int)sizeof(single->issuerKeyHash))
32752
        return BUFFER_E;
32753
    XMEMCPY(single->issuerKeyHash, source + idx, length);
32754
    idx += length;
32755
32756
    /* Get serial number */
32757
    if (wc_GetSerialNumber(source, &idx, single->status->serial,
32758
                        &single->status->serialSz, size) < 0)
32759
        return ASN_PARSE_E;
32760
    single->rawCertIdSize = idx - certIdIdx;
32761
32762
    if (idx >= size)
32763
        return BUFFER_E;
32764
32765
    /* CertStatus */
32766
    switch (source[idx++])
32767
    {
32768
        case (ASN_CONTEXT_SPECIFIC | CERT_GOOD):
32769
            single->status->status = CERT_GOOD;
32770
            idx++;
32771
            break;
32772
        case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_REVOKED):
32773
            single->status->status = CERT_REVOKED;
32774
            if (GetLength(source, &idx, &length, size) < 0)
32775
                return ASN_PARSE_E;
32776
            idx += length;
32777
            break;
32778
        case (ASN_CONTEXT_SPECIFIC | CERT_UNKNOWN):
32779
            single->status->status = CERT_UNKNOWN;
32780
            idx++;
32781
            break;
32782
        default:
32783
            return ASN_PARSE_E;
32784
    }
32785
32786
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
32787
    single->status->thisDateAsn = source + idx;
32788
    localIdx = 0;
32789
    if (GetDateInfo(single->status->thisDateAsn, &localIdx, NULL,
32790
                    (byte*)&single->status->thisDateParsed.type,
32791
                    &single->status->thisDateParsed.length, size) < 0)
32792
        return ASN_PARSE_E;
32793
    XMEMCPY(single->status->thisDateParsed.data,
32794
            single->status->thisDateAsn + localIdx - single->status->thisDateParsed.length,
32795
            single->status->thisDateParsed.length);
32796
#endif
32797
    if (GetBasicDate(source, &idx, single->status->thisDate,
32798
                                                &single->status->thisDateFormat, size) < 0)
32799
        return ASN_PARSE_E;
32800
32801
#ifndef NO_ASN_TIME
32802
#ifndef WOLFSSL_NO_OCSP_DATE_CHECK
32803
    if (!XVALIDATE_DATE(single->status->thisDate, single->status->thisDateFormat, BEFORE))
32804
        return ASN_BEFORE_DATE_E;
32805
#endif
32806
#endif
32807
32808
    /* The following items are optional. Only check for them if there is more
32809
     * unprocessed data in the singleResponse wrapper. */
32810
    localIdx = idx;
32811
    if (((int)(idx - prevIndex) < wrapperSz) &&
32812
        GetASNTag(source, &localIdx, &tag, size) == 0 &&
32813
        tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
32814
    {
32815
        idx++;
32816
        if (GetLength(source, &idx, &length, size) < 0)
32817
            return ASN_PARSE_E;
32818
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
32819
        single->status->nextDateAsn = source + idx;
32820
        localIdx = 0;
32821
        if (GetDateInfo(single->status->nextDateAsn, &localIdx, NULL,
32822
                        (byte*)&single->status->nextDateParsed.type,
32823
                        &single->status->nextDateParsed.length, size) < 0)
32824
            return ASN_PARSE_E;
32825
        XMEMCPY(single->status->nextDateParsed.data,
32826
                single->status->nextDateAsn + localIdx - single->status->nextDateParsed.length,
32827
                single->status->nextDateParsed.length);
32828
#endif
32829
        if (GetBasicDate(source, &idx, single->status->nextDate,
32830
                                                &single->status->nextDateFormat, size) < 0)
32831
            return ASN_PARSE_E;
32832
32833
#ifndef NO_ASN_TIME
32834
#ifndef WOLFSSL_NO_OCSP_DATE_CHECK
32835
        if (!XVALIDATE_DATE(single->status->nextDate, single->status->nextDateFormat, AFTER))
32836
            return ASN_AFTER_DATE_E;
32837
#endif
32838
#endif
32839
    }
32840
32841
    /* Skip the optional extensions in singleResponse. */
32842
    localIdx = idx;
32843
    if (((int)(idx - prevIndex) < wrapperSz) &&
32844
        GetASNTag(source, &localIdx, &tag, size) == 0 &&
32845
        tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
32846
    {
32847
        idx++;
32848
        if (GetLength(source, &idx, &length, size) < 0)
32849
            return ASN_PARSE_E;
32850
        idx += length;
32851
    }
32852
32853
    *ioIndex = idx;
32854
32855
    return 0;
32856
#else
32857
    DECL_ASNGETDATA(dataASN, singleResponseASN_Length);
32858
    int ret = 0;
32859
    CertStatus* cs = NULL;
32860
    word32 serialSz;
32861
    word32 issuerHashLen;
32862
    word32 issuerKeyHashLen;
32863
    word32 thisDateLen;
32864
    word32 nextDateLen;
32865
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
32866
    defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY)
32867
    WOLFSSL_ASN1_TIME *at;
32868
#endif
32869
32870
    (void)wrapperSz;
32871
32872
    WOLFSSL_ENTER("DecodeSingleResponse");
32873
32874
    CALLOC_ASNGETDATA(dataASN, singleResponseASN_Length, ret, NULL);
32875
32876
    if (ret == 0) {
32877
        /* Certificate Status field. */
32878
        cs = single->status;
32879
32880
        /* Set maximum lengths for data. */
32881
        issuerHashLen    = OCSP_DIGEST_SIZE;
32882
        issuerKeyHashLen = OCSP_DIGEST_SIZE;
32883
        serialSz         = EXTERNAL_SERIAL_SIZE;
32884
        thisDateLen      = MAX_DATE_SIZE;
32885
        nextDateLen      = MAX_DATE_SIZE;
32886
32887
        /* Set OID type, buffers to hold data and variables to hold size. */
32888
        GetASN_OID(&dataASN[SINGLERESPONSEASN_IDX_CID_HASHALGO_OID],
32889
                oidHashType);
32890
        GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_CID_ISSUERHASH],
32891
                single->issuerHash, &issuerHashLen);
32892
        GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_CID_ISSUERKEYHASH],
32893
                single->issuerKeyHash, &issuerKeyHashLen);
32894
        GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_CID_SERIAL], cs->serial,
32895
                &serialSz);
32896
        GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_THISUPDATE_GT],
32897
                cs->thisDate, &thisDateLen);
32898
        GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_NEXTUPDATE_GT],
32899
                cs->nextDate, &nextDateLen);
32900
        /* TODO: decode revoked time and reason. */
32901
        /* Decode OCSP single response. */
32902
        ret = GetASN_Items(singleResponseASN, dataASN, singleResponseASN_Length,
32903
                1, source, ioIndex, size);
32904
    }
32905
    /* Validate the issuer hash length is the size required. */
32906
    if ((ret == 0) && (issuerHashLen != OCSP_DIGEST_SIZE)) {
32907
        ret = ASN_PARSE_E;
32908
    }
32909
    /* Validate the issuer key hash length is the size required. */
32910
    if ((ret == 0) && (issuerKeyHashLen != OCSP_DIGEST_SIZE)) {
32911
        ret = ASN_PARSE_E;
32912
    }
32913
    if (ret == 0) {
32914
        /* Store serial size. */
32915
        cs->serialSz = serialSz;
32916
32917
        /* Determine status by which item was found. */
32918
        if (dataASN[SINGLERESPONSEASN_IDX_CS_GOOD].tag != 0) {
32919
            cs->status = CERT_GOOD;
32920
        }
32921
        if (dataASN[SINGLERESPONSEASN_IDX_CS_REVOKED].tag != 0) {
32922
            cs->status = CERT_REVOKED;
32923
        }
32924
        if (dataASN[SINGLERESPONSEASN_IDX_UNKNOWN].tag != 0) {
32925
            cs->status = CERT_UNKNOWN;
32926
        }
32927
32928
        /* Store the thisDate format - only one possible. */
32929
        cs->thisDateFormat = ASN_GENERALIZED_TIME;
32930
    #if !defined(NO_ASN_TIME) && !defined(WOLFSSL_NO_OCSP_DATE_CHECK)
32931
        /* Check date is a valid string and BEFORE now. */
32932
        if (!XVALIDATE_DATE(cs->thisDate, ASN_GENERALIZED_TIME, BEFORE)) {
32933
            ret = ASN_BEFORE_DATE_E;
32934
        }
32935
    }
32936
    if (ret == 0) {
32937
    #endif
32938
    #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
32939
        defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY)
32940
        /* Store ASN.1 version of thisDate. */
32941
        cs->thisDateAsn = GetASNItem_Addr(
32942
                dataASN[SINGLERESPONSEASN_IDX_THISUPDATE_GT], source);
32943
        at = &cs->thisDateParsed;
32944
        at->type = ASN_GENERALIZED_TIME;
32945
        XMEMCPY(at->data, cs->thisDate, thisDateLen);
32946
        at->length = thisDateLen;
32947
    #endif
32948
    }
32949
    if ((ret == 0) &&
32950
            (dataASN[SINGLERESPONSEASN_IDX_NEXTUPDATE_GT].tag != 0)) {
32951
        /* Store the nextDate format - only one possible. */
32952
        cs->nextDateFormat = ASN_GENERALIZED_TIME;
32953
    #if !defined(NO_ASN_TIME) && !defined(WOLFSSL_NO_OCSP_DATE_CHECK)
32954
        /* Check date is a valid string and AFTER now. */
32955
        if (!XVALIDATE_DATE(cs->nextDate, ASN_GENERALIZED_TIME, AFTER)) {
32956
            ret = ASN_AFTER_DATE_E;
32957
        }
32958
    }
32959
    if ((ret == 0) &&
32960
            (dataASN[SINGLERESPONSEASN_IDX_NEXTUPDATE_GT].tag != 0)) {
32961
    #endif
32962
    #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
32963
        defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY)
32964
        /* Store ASN.1 version of thisDate. */
32965
        cs->nextDateAsn = GetASNItem_Addr(
32966
                dataASN[SINGLERESPONSEASN_IDX_NEXTUPDATE_GT], source);
32967
        at = &cs->nextDateParsed;
32968
        at->type = ASN_GENERALIZED_TIME;
32969
        XMEMCPY(at->data, cs->nextDate, nextDateLen);
32970
        at->length = nextDateLen;
32971
    #endif
32972
    }
32973
    if (ret == 0) {
32974
        /* OcspEntry now used. */
32975
        single->used = 1;
32976
    }
32977
32978
    FREE_ASNGETDATA(dataASN, NULL);
32979
    return ret;
32980
#endif
32981
}
32982
32983
#ifdef WOLFSSL_ASN_TEMPLATE
32984
/* ASN.1 template for OCSP response extension header.
32985
 * RFC 6960, 4.2.1 - ASN.1 Specification of the OCSP Response
32986
 */
32987
static const ASNItem respExtHdrASN[] = {
32988
                                   /* responseExtensions */
32989
/* EXT     */    { 0, ASN_CONTEXT_SPECIFIC | 1, 1, 1, 0 },
32990
                                       /* extensions */
32991
/* EXT_SEQ */        { 1, ASN_SEQUENCE, 1, 1, 0 },
32992
};
32993
enum {
32994
    RESPEXTHDRASN_IDX_EXT = 0,
32995
    RESPEXTHDRASN_IDX_EXT_SEQ,
32996
};
32997
32998
/* Number of items in ASN.1 template for OCSP response extension header. */
32999
#define respExtHdrASN_Length (sizeof(respExtHdrASN) / sizeof(ASNItem))
33000
#endif
33001
33002
static int DecodeOcspRespExtensions(byte* source, word32* ioIndex,
33003
                                    OcspResponse* resp, word32 sz)
33004
{
33005
#ifndef WOLFSSL_ASN_TEMPLATE
33006
    word32 idx = *ioIndex;
33007
    int length;
33008
    int ext_bound; /* boundary index for the sequence of extensions */
33009
    word32 oid;
33010
    int ret;
33011
    byte tag;
33012
33013
    WOLFSSL_ENTER("DecodeOcspRespExtensions");
33014
33015
    if ((idx + 1) > sz)
33016
        return BUFFER_E;
33017
33018
    if (GetASNTag(source, &idx, &tag, sz) < 0)
33019
        return ASN_PARSE_E;
33020
33021
    if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
33022
        return ASN_PARSE_E;
33023
33024
    if (GetLength(source, &idx, &length, sz) < 0)
33025
        return ASN_PARSE_E;
33026
33027
    if (GetSequence(source, &idx, &length, sz) < 0)
33028
        return ASN_PARSE_E;
33029
33030
    ext_bound = idx + length;
33031
33032
    while (idx < (word32)ext_bound) {
33033
        word32 localIdx;
33034
33035
        if (GetSequence(source, &idx, &length, sz) < 0) {
33036
            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
33037
            return ASN_PARSE_E;
33038
        }
33039
33040
        oid = 0;
33041
        if (GetObjectId(source, &idx, &oid, oidOcspType, sz) < 0) {
33042
            WOLFSSL_MSG("\tfail: OBJECT ID");
33043
            return ASN_PARSE_E;
33044
        }
33045
33046
        /* check for critical flag */
33047
        if ((idx + 1) > (word32)sz) {
33048
            WOLFSSL_MSG("\tfail: malformed buffer");
33049
            return BUFFER_E;
33050
        }
33051
33052
        localIdx = idx;
33053
        if (GetASNTag(source, &localIdx, &tag, sz) == 0 && tag == ASN_BOOLEAN) {
33054
            WOLFSSL_MSG("\tfound optional critical flag, moving past");
33055
            ret = GetBoolean(source, &idx, sz);
33056
            if (ret < 0)
33057
                return ret;
33058
        }
33059
33060
        ret = GetOctetString(source, &idx, &length, sz);
33061
        if (ret < 0)
33062
            return ret;
33063
33064
        if (oid == OCSP_NONCE_OID) {
33065
            /* get data inside extra OCTET_STRING */
33066
            ret = GetOctetString(source, &idx, &length, sz);
33067
            if (ret < 0)
33068
                return ret;
33069
33070
            resp->nonce = source + idx;
33071
            resp->nonceSz = length;
33072
        }
33073
33074
        idx += length;
33075
    }
33076
33077
    *ioIndex = idx;
33078
    return 0;
33079
#else
33080
    /* certExtASN_Length is greater than respExtHdrASN_Length */
33081
    DECL_ASNGETDATA(dataASN, certExtASN_Length);
33082
    int ret = 0;
33083
    word32 idx = *ioIndex;
33084
    word32 maxIdx = 0;
33085
33086
    WOLFSSL_ENTER("DecodeOcspRespExtensions");
33087
33088
    CALLOC_ASNGETDATA(dataASN, certExtASN_Length, ret, resp->heap);
33089
33090
    if (ret == 0) {
33091
        /* Check for header and move past. */
33092
        ret = GetASN_Items(respExtHdrASN, dataASN, respExtHdrASN_Length, 0,
33093
            source, &idx, sz);
33094
    }
33095
    if (ret == 0) {
33096
        /* Keep end extensions index for total length check. */
33097
        maxIdx = idx + dataASN[RESPEXTHDRASN_IDX_EXT_SEQ].length;
33098
    }
33099
33100
    /* Step through all extensions. */
33101
    while ((ret == 0) && (idx < maxIdx)) {
33102
        /* Clear dynamic data, set OID type to expect. */
33103
        XMEMSET(dataASN, 0, sizeof(*dataASN) * certExtASN_Length);
33104
        GetASN_OID(&dataASN[CERTEXTASN_IDX_OID], oidOcspType);
33105
        /* TODO: check criticality. */
33106
        /* Decode OCSP response extension. */
33107
        ret = GetASN_Items(certExtASN, dataASN, certExtASN_Length, 0,
33108
                           source, &idx, sz);
33109
        if (ret == 0) {
33110
            word32 oid = dataASN[CERTEXTASN_IDX_OID].data.oid.sum;
33111
            int length = dataASN[CERTEXTASN_IDX_VAL].length;
33112
33113
            if (oid == OCSP_NONCE_OID) {
33114
                /* Extract nonce data. */
33115
                ret = GetOctetString(source, &idx, &length, sz);
33116
                if (ret >= 0) {
33117
                    ret = 0;
33118
                    /* get data inside extra OCTET_STRING */
33119
                    resp->nonce = source + idx;
33120
                    resp->nonceSz = length;
33121
                }
33122
            }
33123
            /* Ignore all other extension types. */
33124
33125
            /* Skip over rest of extension. */
33126
            idx += length;
33127
        }
33128
    }
33129
33130
    /* Return index after extensions. */
33131
    *ioIndex = idx;
33132
33133
    FREE_ASNGETDATA(dataASN, resp->heap);
33134
    return ret;
33135
#endif
33136
}
33137
33138
#ifdef WOLFSSL_ASN_TEMPLATE
33139
/* ASN.1 template for OCSP ResponseData.
33140
 * RFC 6960, 4.2.1 - ASN.1 Specification of the OCSP Response
33141
 */
33142
static const ASNItem ocspRespDataASN[] = {
33143
/* SEQ         */    { 0, ASN_SEQUENCE, 1, 1, 0 },
33144
                                             /* version DEFAULT v1 */
33145
/* VER_PRESENT */        { 1, ASN_CONTEXT_SPECIFIC | 0, 1, 1, 1 },
33146
/* VER         */            { 2, ASN_INTEGER, 1, 0, 0 },
33147
                                             /* byName */
33148
/* BYNAME      */        { 1, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 2 },
33149
                                             /* byKey */
33150
/* BYKEY       */        { 1, ASN_CONTEXT_SPECIFIC | 2, 1, 0, 2 },
33151
                                             /* producedAt */
33152
/* PA          */        { 1, ASN_GENERALIZED_TIME, 0, 0, 0, },
33153
                                             /* responses */
33154
/* RESP        */        { 1, ASN_SEQUENCE, 1, 0, 0 },
33155
                                             /* responseExtensions */
33156
/* RESPEXT     */        { 1, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 1 }
33157
};
33158
enum {
33159
    OCSPRESPDATAASN_IDX_SEQ = 0,
33160
    OCSPRESPDATAASN_IDX_VER_PRESENT,
33161
    OCSPRESPDATAASN_IDX_VER,
33162
    OCSPRESPDATAASN_IDX_BYNAME,
33163
    OCSPRESPDATAASN_IDX_BYKEY,
33164
    OCSPRESPDATAASN_IDX_PA,
33165
    OCSPRESPDATAASN_IDX_RESP,
33166
    OCSPRESPDATAASN_IDX_RESPEXT,
33167
};
33168
33169
/* Number of items in ASN.1 template for OCSP ResponseData. */
33170
#define ocspRespDataASN_Length (sizeof(ocspRespDataASN) / sizeof(ASNItem))
33171
#endif
33172
33173
static int DecodeResponseData(byte* source, word32* ioIndex,
33174
                              OcspResponse* resp, word32 size)
33175
{
33176
#ifndef WOLFSSL_ASN_TEMPLATE
33177
    word32 idx = *ioIndex, prev_idx, localIdx;
33178
    int length;
33179
    int version;
33180
    int ret;
33181
    byte tag;
33182
    int wrapperSz;
33183
    OcspEntry* single;
33184
33185
    WOLFSSL_ENTER("DecodeResponseData");
33186
33187
    resp->response = source + idx;
33188
    prev_idx = idx;
33189
    if (GetSequence(source, &idx, &length, size) < 0)
33190
        return ASN_PARSE_E;
33191
    resp->responseSz = length + idx - prev_idx;
33192
33193
    /* Get version. It is an EXPLICIT[0] DEFAULT(0) value. If this
33194
     * item isn't an EXPLICIT[0], then set version to zero and move
33195
     * onto the next item.
33196
     */
33197
    localIdx = idx;
33198
    if (GetASNTag(source, &localIdx, &tag, size) == 0 &&
33199
            tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
33200
    {
33201
        idx += 2; /* Eat the value and length */
33202
        if (GetMyVersion(source, &idx, &version, size) < 0)
33203
            return ASN_PARSE_E;
33204
    } else
33205
        version = 0;
33206
33207
    localIdx = idx;
33208
    if (GetASNTag(source, &localIdx, &tag, size) == 0 &&
33209
        ( tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1) ||
33210
          tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2) ))
33211
    {
33212
        idx++; /* advance past ASN tag */
33213
        if (GetLength(source, &idx, &length, size) < 0)
33214
            return ASN_PARSE_E;
33215
        idx += length;
33216
    }
33217
    else
33218
        return ASN_PARSE_E;
33219
33220
    /* save pointer to the producedAt time */
33221
    if (GetBasicDate(source, &idx, resp->producedDate,
33222
                                        &resp->producedDateFormat, size) < 0)
33223
        return ASN_PARSE_E;
33224
33225
    /* Outer wrapper of the SEQUENCE OF Single Responses. */
33226
    if (GetSequence(source, &idx, &wrapperSz, size) < 0)
33227
        return ASN_PARSE_E;
33228
33229
    localIdx = idx;
33230
    single = resp->single;
33231
    while (idx - localIdx < (word32)wrapperSz) {
33232
        ret = DecodeSingleResponse(source, &idx, size, wrapperSz, single);
33233
        if (ret < 0)
33234
            return ret; /* ASN_PARSE_E, ASN_BEFORE_DATE_E, ASN_AFTER_DATE_E */
33235
        if (idx - localIdx < (word32)wrapperSz) {
33236
            single->next = (OcspEntry*)XMALLOC(sizeof(OcspEntry), resp->heap,
33237
                DYNAMIC_TYPE_OCSP_ENTRY);
33238
            if (single->next == NULL) {
33239
                return MEMORY_E;
33240
            }
33241
            XMEMSET(single->next, 0, sizeof(OcspEntry));
33242
33243
            single->next->status = (CertStatus*)XMALLOC(sizeof(CertStatus),
33244
                resp->heap, DYNAMIC_TYPE_OCSP_STATUS);
33245
            if (single->next->status == NULL) {
33246
                XFREE(single->next, resp->heap, DYNAMIC_TYPE_OCSP_ENTRY);
33247
                single->next = NULL;
33248
                return MEMORY_E;
33249
            }
33250
            XMEMSET(single->next->status, 0, sizeof(CertStatus));
33251
33252
            single->next->isDynamic = 1;
33253
33254
            single = single->next;
33255
        }
33256
    }
33257
33258
    /*
33259
     * Check the length of the ResponseData against the current index to
33260
     * see if there are extensions, they are optional.
33261
     */
33262
    if (idx - prev_idx < resp->responseSz)
33263
        if (DecodeOcspRespExtensions(source, &idx, resp, size) < 0)
33264
            return ASN_PARSE_E;
33265
33266
    *ioIndex = idx;
33267
    return 0;
33268
#else
33269
    DECL_ASNGETDATA(dataASN, ocspRespDataASN_Length);
33270
    int ret = 0;
33271
    byte version;
33272
    word32 dateSz, idx = *ioIndex;
33273
    OcspEntry* single;
33274
33275
    WOLFSSL_ENTER("DecodeResponseData");
33276
33277
    CALLOC_ASNGETDATA(dataASN, ocspRespDataASN_Length, ret, resp->heap);
33278
33279
    if (ret == 0) {
33280
        resp->response = source + idx;
33281
        /* Default, not present, is v1 = 0. */
33282
        version = 0;
33283
        /* Max size of date supported. */
33284
        dateSz = MAX_DATE_SIZE;
33285
33286
        /* Set the where to put version an produced date. */
33287
        GetASN_Int8Bit(&dataASN[OCSPRESPDATAASN_IDX_VER], &version);
33288
        GetASN_Buffer(&dataASN[OCSPRESPDATAASN_IDX_PA], resp->producedDate,
33289
                &dateSz);
33290
        /* Decode the ResponseData. */
33291
        ret = GetASN_Items(ocspRespDataASN, dataASN, ocspRespDataASN_Length,
33292
                1, source, ioIndex, size);
33293
    }
33294
    /* Only support v1 == 0 */
33295
    if ((ret == 0) && (version != 0)) {
33296
        ret = ASN_PARSE_E;
33297
    }
33298
    /* Ensure date is a minimal size. */
33299
    if ((ret == 0) && (dateSz < MIN_DATE_SIZE)) {
33300
        ret = ASN_PARSE_E;
33301
    }
33302
    if (ret == 0) {
33303
        /* TODO: use byName/byKey fields. */
33304
        /* Store size of response. */
33305
        resp->responseSz = *ioIndex - idx;
33306
        /* Store date format/tag. */
33307
        resp->producedDateFormat = dataASN[OCSPRESPDATAASN_IDX_PA].tag;
33308
33309
        /* Get the index of the responses SEQUENCE. */
33310
        idx = GetASNItem_DataIdx(dataASN[OCSPRESPDATAASN_IDX_RESP], source);
33311
        /* Start with the pre-existing OcspEntry. */
33312
        single = resp->single;
33313
    }
33314
    while ((ret == 0) && (idx < dataASN[OCSPRESPDATAASN_IDX_RESPEXT].offset)) {
33315
        /* Allocate and use a new OCSP entry if this is used. */
33316
        if (single->used) {
33317
            single->next = (OcspEntry*)XMALLOC(sizeof(OcspEntry), resp->heap,
33318
                    DYNAMIC_TYPE_OCSP_ENTRY);
33319
            if (single->next == NULL) {
33320
                ret = MEMORY_E;
33321
            }
33322
            else {
33323
                XMEMSET(single->next, 0, sizeof(OcspEntry));
33324
33325
                single->next->status = (CertStatus*)XMALLOC(sizeof(CertStatus),
33326
                    resp->heap, DYNAMIC_TYPE_OCSP_STATUS);
33327
                if (single->next->status == NULL) {
33328
                    XFREE(single->next, resp->heap, DYNAMIC_TYPE_OCSP_ENTRY);
33329
                    single->next = NULL;
33330
                    ret = MEMORY_E;
33331
                }
33332
                else {
33333
                    XMEMSET(single->next->status, 0, sizeof(CertStatus));
33334
33335
                    /* Entry to be freed. */
33336
                    single->isDynamic = 1;
33337
                    /* used will be 0 (false) */
33338
33339
                    single = single->next;
33340
                }
33341
            }
33342
        }
33343
        if (ret == 0) {
33344
            /* Decode SingleResponse into OcspEntry. */
33345
            ret = DecodeSingleResponse(source, &idx,
33346
                    dataASN[OCSPRESPDATAASN_IDX_RESPEXT].offset,
33347
                    dataASN[OCSPRESPDATAASN_IDX_RESP].length, single);
33348
            /* single->used set on successful decode. */
33349
        }
33350
    }
33351
33352
    /* Check if there were extensions. */
33353
    if ((ret == 0) &&
33354
            (dataASN[OCSPRESPDATAASN_IDX_RESPEXT].data.buffer.data != NULL)) {
33355
        /* Get index of [1] */
33356
        idx = dataASN[OCSPRESPDATAASN_IDX_RESPEXT].offset;
33357
        /* Decode the response extensions. */
33358
        if (DecodeOcspRespExtensions(source, &idx, resp, *ioIndex) < 0) {
33359
            ret = ASN_PARSE_E;
33360
        }
33361
    }
33362
33363
    FREE_ASNGETDATA(dataASN, resp->heap);
33364
    return ret;
33365
#endif
33366
}
33367
33368
33369
#ifndef WOLFSSL_ASN_TEMPLATE
33370
#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
33371
33372
static int DecodeCerts(byte* source,
33373
                            word32* ioIndex, OcspResponse* resp, word32 size)
33374
{
33375
    word32 idx = *ioIndex;
33376
    byte tag;
33377
33378
    WOLFSSL_ENTER("DecodeCerts");
33379
33380
    if (GetASNTag(source, &idx, &tag, size) < 0)
33381
        return ASN_PARSE_E;
33382
33383
    if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
33384
    {
33385
        int length;
33386
33387
        if (GetLength(source, &idx, &length, size) < 0)
33388
            return ASN_PARSE_E;
33389
33390
        if (GetSequence(source, &idx, &length, size) < 0)
33391
            return ASN_PARSE_E;
33392
33393
        resp->cert = source + idx;
33394
        resp->certSz = length;
33395
33396
        idx += length;
33397
    }
33398
    *ioIndex = idx;
33399
    return 0;
33400
}
33401
33402
#endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */
33403
#endif /* !WOLFSSL_ASN_TEMPLATE */
33404
33405
#ifdef WOLFSSL_ASN_TEMPLATE
33406
/* ASN.1 template for BasicOCSPResponse.
33407
 * RFC 6960, 4.2.1 - ASN.1 Specification of the OCSP Response
33408
 */
33409
static const ASNItem ocspBasicRespASN[] = {
33410
/* SEQ          */ { 0, ASN_SEQUENCE, 1, 1, 0 },
33411
                                            /* tbsResponseData */
33412
/* TBS_SEQ      */     { 1, ASN_SEQUENCE, 1, 0, 0, },
33413
                                            /* signatureAlgorithm */
33414
/* SIGALGO      */     { 1, ASN_SEQUENCE, 1, 1, 0, },
33415
/* SIGALGO_OID  */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
33416
/* SIGALGO_NULL */         { 2, ASN_TAG_NULL, 0, 0, 1 },
33417
                                            /* signature */
33418
/* SIGNATURE    */     { 1, ASN_BIT_STRING, 0, 0, 0 },
33419
                                            /* certs */
33420
/* CERTS        */     { 1, ASN_CONTEXT_SPECIFIC | 0, 1, 1, 1 },
33421
/* CERTS_SEQ    */         { 2, ASN_SEQUENCE, 1, 0, 0, },
33422
};
33423
enum {
33424
    OCSPBASICRESPASN_IDX_SEQ = 0,
33425
    OCSPBASICRESPASN_IDX_TBS_SEQ,
33426
    OCSPBASICRESPASN_IDX_SIGALGO,
33427
    OCSPBASICRESPASN_IDX_SIGALGO_OID,
33428
    OCSPBASICRESPASN_IDX_SIGALGO_NULL,
33429
    OCSPBASICRESPASN_IDX_SIGNATURE,
33430
    OCSPBASICRESPASN_IDX_CERTS,
33431
    OCSPBASICRESPASN_IDX_CERTS_SEQ,
33432
};
33433
33434
/* Number of items in ASN.1 template for BasicOCSPResponse. */
33435
#define ocspBasicRespASN_Length (sizeof(ocspBasicRespASN) / sizeof(ASNItem))
33436
#endif /* WOLFSSL_ASN_TEMPLATE */
33437
33438
static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
33439
            OcspResponse* resp, word32 size, void* cm, void* heap, int noVerify)
33440
{
33441
#ifndef WOLFSSL_ASN_TEMPLATE
33442
    int    length;
33443
    word32 idx = *ioIndex;
33444
    word32 end_index;
33445
    int    ret;
33446
    int    sigLength;
33447
33448
    WOLFSSL_ENTER("DecodeBasicOcspResponse");
33449
    (void)heap;
33450
33451
    if (GetSequence(source, &idx, &length, size) < 0)
33452
        return ASN_PARSE_E;
33453
33454
    if (idx + length > size)
33455
        return ASN_INPUT_E;
33456
    end_index = idx + length;
33457
33458
    if ((ret = DecodeResponseData(source, &idx, resp, size)) < 0)
33459
        return ret; /* ASN_PARSE_E, ASN_BEFORE_DATE_E, ASN_AFTER_DATE_E */
33460
33461
    /* Get the signature algorithm */
33462
    if (GetAlgoId(source, &idx, &resp->sigOID, oidSigType, size) < 0)
33463
        return ASN_PARSE_E;
33464
33465
    ret = CheckBitString(source, &idx, &sigLength, size, 1, NULL);
33466
    if (ret != 0)
33467
        return ret;
33468
33469
    resp->sigSz = sigLength;
33470
    resp->sig = source + idx;
33471
    idx += sigLength;
33472
33473
    /*
33474
     * Check the length of the BasicOcspResponse against the current index to
33475
     * see if there are certificates, they are optional.
33476
     */
33477
#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
33478
    if (idx < end_index)
33479
    {
33480
        int cert_inited = 0;
33481
#ifdef WOLFSSL_SMALL_STACK
33482
        DecodedCert *cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
33483
                                                  DYNAMIC_TYPE_TMP_BUFFER);
33484
        if (cert == NULL)
33485
            return MEMORY_E;
33486
#else
33487
        DecodedCert cert[1];
33488
#endif
33489
33490
        do {
33491
            if (DecodeCerts(source, &idx, resp, size) < 0) {
33492
                ret = ASN_PARSE_E;
33493
                break;
33494
            }
33495
33496
            InitDecodedCert(cert, resp->cert, resp->certSz, heap);
33497
            cert_inited = 1;
33498
33499
            /* Don't verify if we don't have access to Cert Manager. */
33500
            ret = ParseCertRelative(cert, CERT_TYPE,
33501
                                    noVerify ? NO_VERIFY : VERIFY_OCSP_CERT,
33502
                                    cm);
33503
            if (ret < 0) {
33504
                WOLFSSL_MSG("\tOCSP Responder certificate parsing failed");
33505
                break;
33506
            }
33507
33508
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK
33509
            if ((cert->extExtKeyUsage & EXTKEYUSE_OCSP_SIGN) == 0) {
33510
                if (XMEMCMP(cert->subjectHash,
33511
                            resp->single->issuerHash, OCSP_DIGEST_SIZE) == 0) {
33512
                    WOLFSSL_MSG("\tOCSP Response signed by issuer");
33513
                }
33514
                else {
33515
                    WOLFSSL_MSG("\tOCSP Responder key usage check failed");
33516
    #ifdef OPENSSL_EXTRA
33517
                    resp->verifyError = OCSP_BAD_ISSUER;
33518
    #else
33519
                    ret = BAD_OCSP_RESPONDER;
33520
                    break;
33521
    #endif
33522
                }
33523
            }
33524
#endif
33525
33526
            /* ConfirmSignature is blocking here */
33527
            ret = ConfirmSignature(
33528
                &cert->sigCtx,
33529
                resp->response, resp->responseSz,
33530
                cert->publicKey, cert->pubKeySize, cert->keyOID,
33531
                resp->sig, resp->sigSz, resp->sigOID, NULL, 0, NULL);
33532
33533
            if (ret != 0) {
33534
                WOLFSSL_MSG("\tOCSP Confirm signature failed");
33535
                ret = ASN_OCSP_CONFIRM_E;
33536
                break;
33537
            }
33538
        } while(0);
33539
33540
        if (cert_inited)
33541
            FreeDecodedCert(cert);
33542
#ifdef WOLFSSL_SMALL_STACK
33543
        XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
33544
#endif
33545
33546
        if (ret != 0)
33547
            return ret;
33548
    }
33549
    else
33550
#endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */
33551
    {
33552
        Signer* ca;
33553
        int sigValid = -1;
33554
33555
        #ifndef NO_SKID
33556
            ca = GetCA(cm, resp->single->issuerKeyHash);
33557
        #else
33558
            ca = GetCA(cm, resp->single->issuerHash);
33559
        #endif
33560
33561
        if (ca) {
33562
            SignatureCtx sigCtx;
33563
            InitSignatureCtx(&sigCtx, heap, INVALID_DEVID);
33564
33565
            /* ConfirmSignature is blocking here */
33566
            sigValid = ConfirmSignature(&sigCtx, resp->response,
33567
                resp->responseSz, ca->publicKey, ca->pubKeySize, ca->keyOID,
33568
                resp->sig, resp->sigSz, resp->sigOID, NULL, 0, NULL);
33569
        }
33570
        if (ca == NULL || sigValid != 0) {
33571
            WOLFSSL_MSG("\tOCSP Confirm signature failed");
33572
            return ASN_OCSP_CONFIRM_E;
33573
        }
33574
33575
        (void)noVerify;
33576
    }
33577
33578
    *ioIndex = idx;
33579
    return 0;
33580
#else
33581
    DECL_ASNGETDATA(dataASN, ocspBasicRespASN_Length);
33582
    int ret = 0;
33583
    word32 idx = *ioIndex;
33584
#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
33585
    #ifdef WOLFSSL_SMALL_STACK
33586
        DecodedCert* cert = NULL;
33587
    #else
33588
        DecodedCert cert[1];
33589
    #endif
33590
    int certInit = 0;
33591
#endif
33592
33593
    WOLFSSL_ENTER("DecodeBasicOcspResponse");
33594
    (void)heap;
33595
33596
    CALLOC_ASNGETDATA(dataASN, ocspBasicRespASN_Length, ret, heap);
33597
33598
    if (ret == 0) {
33599
        /* Set expecting signature OID. */
33600
        GetASN_OID(&dataASN[OCSPBASICRESPASN_IDX_SIGALGO_OID], oidSigType);
33601
        /* Decode BasicOCSPResponse. */
33602
        ret = GetASN_Items(ocspBasicRespASN, dataASN, ocspBasicRespASN_Length,
33603
                1, source, &idx, size);
33604
    }
33605
    if (ret == 0) {
33606
        word32 dataIdx = 0;
33607
        /* Decode the response data. */
33608
        if (DecodeResponseData(
33609
                GetASNItem_Addr(dataASN[OCSPBASICRESPASN_IDX_TBS_SEQ], source),
33610
                &dataIdx, resp,
33611
                GetASNItem_Length(dataASN[OCSPBASICRESPASN_IDX_TBS_SEQ], source)
33612
                ) < 0) {
33613
            ret = ASN_PARSE_E;
33614
        }
33615
    }
33616
    if (ret == 0) {
33617
        /* Get the signature OID and signature. */
33618
        resp->sigOID = dataASN[OCSPBASICRESPASN_IDX_SIGALGO_OID].data.oid.sum;
33619
        GetASN_GetRef(&dataASN[OCSPBASICRESPASN_IDX_SIGNATURE], &resp->sig,
33620
                &resp->sigSz);
33621
    }
33622
#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
33623
    if ((ret == 0) &&
33624
            (dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data != NULL)) {
33625
        /* TODO: support more than one certificate. */
33626
        /* Store reference to certificate BER data. */
33627
        GetASN_GetRef(&dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ], &resp->cert,
33628
                &resp->certSz);
33629
33630
        /* Allocate a certificate object to decode cert into. */
33631
    #ifdef WOLFSSL_SMALL_STACK
33632
        cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), heap,
33633
                DYNAMIC_TYPE_TMP_BUFFER);
33634
        if (cert == NULL) {
33635
            ret = MEMORY_E;
33636
        }
33637
    }
33638
    if ((ret == 0) &&
33639
            (dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data != NULL)) {
33640
    #endif
33641
        /* Initialize the crtificate object. */
33642
        InitDecodedCert(cert, resp->cert, resp->certSz, heap);
33643
        certInit = 1;
33644
        /* Parse the certificate and don't verify if we don't have access to
33645
         * Cert Manager. */
33646
        ret = ParseCertRelative(cert, CERT_TYPE, noVerify ? NO_VERIFY : VERIFY,
33647
                cm);
33648
        if (ret < 0) {
33649
            WOLFSSL_MSG("\tOCSP Responder certificate parsing failed");
33650
        }
33651
    }
33652
    if ((ret == 0) &&
33653
            (dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data != NULL)) {
33654
        /* TODO: ConfirmSignature is blocking here */
33655
        /* Check the signature of the response. */
33656
        ret = ConfirmSignature(&cert->sigCtx, resp->response, resp->responseSz,
33657
            cert->publicKey, cert->pubKeySize, cert->keyOID, resp->sig,
33658
            resp->sigSz, resp->sigOID, NULL, 0, NULL);
33659
        if (ret != 0) {
33660
            WOLFSSL_MSG("\tOCSP Confirm signature failed");
33661
            ret = ASN_OCSP_CONFIRM_E;
33662
        }
33663
    }
33664
    if ((ret == 0) &&
33665
            (dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data == NULL))
33666
#else
33667
    if (ret == 0)
33668
#endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */
33669
    {
33670
        Signer* ca;
33671
        int sigValid = -1;
33672
33673
        /* Resonse didn't have a certificate - lookup CA. */
33674
    #ifndef NO_SKID
33675
        ca = GetCA(cm, resp->single->issuerKeyHash);
33676
    #else
33677
        ca = GetCA(cm, resp->single->issuerHash);
33678
    #endif
33679
        if (ca) {
33680
            SignatureCtx sigCtx;
33681
            /* Initialize he signature context. */
33682
            InitSignatureCtx(&sigCtx, heap, INVALID_DEVID);
33683
33684
            /* TODO: ConfirmSignature is blocking here */
33685
            /* Check the signature of the response CA public key. */
33686
            sigValid = ConfirmSignature(&sigCtx, resp->response,
33687
                resp->responseSz, ca->publicKey, ca->pubKeySize, ca->keyOID,
33688
                resp->sig, resp->sigSz, resp->sigOID, NULL, 0, NULL);
33689
        }
33690
        if ((ca == NULL) || (sigValid != 0)) {
33691
            /* Didn't find certificate or signature verificate failed. */
33692
            WOLFSSL_MSG("\tOCSP Confirm signature failed");
33693
            ret = ASN_OCSP_CONFIRM_E;
33694
        }
33695
    }
33696
33697
    if (ret == 0) {
33698
        /* Update the position to after response data. */
33699
        *ioIndex = idx;
33700
    }
33701
33702
#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
33703
    if (certInit) {
33704
        FreeDecodedCert(cert);
33705
    }
33706
    #ifdef WOLFSSL_SMALL_STACK
33707
    if (cert != NULL) {
33708
        /* Dispose of certificate object. */
33709
        XFREE(cert, heap, DYNAMIC_TYPE_TMP_BUFFER);
33710
    }
33711
    #endif
33712
#endif
33713
    FREE_ASNGETDATA(dataASN, heap);
33714
    return ret;
33715
#endif /* WOLFSSL_ASN_TEMPLATE */
33716
}
33717
33718
33719
void InitOcspResponse(OcspResponse* resp, OcspEntry* single, CertStatus* status,
33720
                      byte* source, word32 inSz, void* heap)
33721
{
33722
    WOLFSSL_ENTER("InitOcspResponse");
33723
33724
    XMEMSET(status, 0, sizeof(CertStatus));
33725
    XMEMSET(single,  0, sizeof(OcspEntry));
33726
    XMEMSET(resp,   0, sizeof(OcspResponse));
33727
33728
    single->status       = status;
33729
    resp->responseStatus = -1;
33730
    resp->single         = single;
33731
    resp->source         = source;
33732
    resp->maxIdx         = inSz;
33733
    resp->heap           = heap;
33734
}
33735
33736
void FreeOcspResponse(OcspResponse* resp)
33737
{
33738
    OcspEntry *single, *next;
33739
    for (single = resp->single; single; single = next) {
33740
        next = single->next;
33741
        if (single->isDynamic) {
33742
            XFREE(single->status, resp->heap, DYNAMIC_TYPE_OCSP_STATUS);
33743
            XFREE(single, resp->heap, DYNAMIC_TYPE_OCSP_ENTRY);
33744
        }
33745
    }
33746
}
33747
33748
#ifdef WOLFSSL_ASN_TEMPLATE
33749
/* ASN.1 template for OCSPResponse.
33750
 * RFC 6960, 4.2.1 - ASN.1 Specification of the OCSP Response
33751
 */
33752
static const ASNItem ocspResponseASN[] = {
33753
                                     /* OCSPResponse ::= SEQUENCE */
33754
/* SEQ        */ { 0, ASN_SEQUENCE, 1, 1, 0 },
33755
                                         /* responseStatus      OCSPResponseStatus */
33756
/* STATUS     */     { 1, ASN_ENUMERATED, 0, 0, 0, },
33757
                                         /* responseBytes   [0] EXPLICIT ResponseBytes OPTIONAL */
33758
/* BYTES      */     { 1, ASN_CONTEXT_SPECIFIC | 0, 1, 1, 1 },
33759
                                             /* ResponseBytes ::= SEQUENCE */
33760
/* BYTES_SEQ  */         { 2, ASN_SEQUENCE, 1, 1, 0 },
33761
                                                /* responseType   OBJECT IDENTIFIER */
33762
/* BYTES_TYPE */            { 3, ASN_OBJECT_ID, 0, 0, 0 },
33763
                                                /* response       OCTET STRING */
33764
/* BYTES_VAL  */            { 3, ASN_OCTET_STRING, 0, 0, 0 },
33765
};
33766
enum {
33767
    OCSPRESPONSEASN_IDX_SEQ = 0,
33768
33769
    OCSPRESPONSEASN_IDX_STATUS,
33770
33771
    OCSPRESPONSEASN_IDX_BYTES,
33772
33773
    OCSPRESPONSEASN_IDX_BYTES_SEQ,
33774
33775
    OCSPRESPONSEASN_IDX_BYTES_TYPE,
33776
33777
    OCSPRESPONSEASN_IDX_BYTES_VAL,
33778
};
33779
33780
/* Number of items in ASN.1 template for OCSPResponse. */
33781
#define ocspResponseASN_Length (sizeof(ocspResponseASN) / sizeof(ASNItem))
33782
#endif /* WOLFSSL_ASN_TEMPLATE */
33783
33784
int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap, int noVerify)
33785
{
33786
#ifndef WOLFSSL_ASN_TEMPLATE
33787
    int ret;
33788
    int length = 0;
33789
    word32 idx = 0;
33790
    byte* source = resp->source;
33791
    word32 size = resp->maxIdx;
33792
    word32 oid;
33793
    byte   tag;
33794
33795
    WOLFSSL_ENTER("OcspResponseDecode");
33796
33797
    /* peel the outer SEQUENCE wrapper */
33798
    if (GetSequence(source, &idx, &length, size) < 0) {
33799
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
33800
        return ASN_PARSE_E;
33801
    }
33802
33803
    /* First get the responseStatus, an ENUMERATED */
33804
    if (GetEnumerated(source, &idx, &resp->responseStatus, size) < 0) {
33805
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
33806
        return ASN_PARSE_E;
33807
    }
33808
33809
    if (resp->responseStatus != OCSP_SUCCESSFUL) {
33810
        WOLFSSL_LEAVE("OcspResponseDecode", 0);
33811
        return 0;
33812
    }
33813
33814
    /* Next is an EXPLICIT record called ResponseBytes, OPTIONAL */
33815
    if (idx >= size) {
33816
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
33817
        return ASN_PARSE_E;
33818
    }
33819
    if (GetASNTag(source, &idx, &tag, size) < 0) {
33820
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
33821
        return ASN_PARSE_E;
33822
    }
33823
    if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
33824
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
33825
        return ASN_PARSE_E;
33826
    }
33827
    if (GetLength(source, &idx, &length, size) < 0) {
33828
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
33829
        return ASN_PARSE_E;
33830
    }
33831
33832
    /* Get the responseBytes SEQUENCE */
33833
    if (GetSequence(source, &idx, &length, size) < 0) {
33834
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
33835
        return ASN_PARSE_E;
33836
    }
33837
33838
    /* Check ObjectID for the resposeBytes */
33839
    if (GetObjectId(source, &idx, &oid, oidOcspType, size) < 0) {
33840
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
33841
        return ASN_PARSE_E;
33842
    }
33843
    if (oid != OCSP_BASIC_OID) {
33844
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
33845
        return ASN_PARSE_E;
33846
    }
33847
    ret = GetOctetString(source, &idx, &length, size);
33848
    if (ret < 0) {
33849
        WOLFSSL_LEAVE("OcspResponseDecode", ret);
33850
        return ret;
33851
    }
33852
33853
    ret = DecodeBasicOcspResponse(source, &idx, resp, size, cm, heap, noVerify);
33854
    if (ret < 0) {
33855
        WOLFSSL_LEAVE("OcspResponseDecode", ret);
33856
        return ret;
33857
    }
33858
33859
    WOLFSSL_LEAVE("OcspResponseDecode", 0);
33860
    return 0;
33861
#else
33862
    DECL_ASNGETDATA(dataASN, ocspResponseASN_Length);
33863
    int ret = 0;
33864
    word32 idx = 0, size = resp->maxIdx;
33865
    byte* source = resp->source;
33866
    byte status;
33867
    byte* basic;
33868
    word32 basicSz;
33869
33870
    WOLFSSL_ENTER("OcspResponseDecode");
33871
33872
    CALLOC_ASNGETDATA(dataASN, ocspResponseASN_Length, ret, resp->heap);
33873
33874
    if (ret == 0) {
33875
        /* Set variable to put status in and expect OCSP OID. */
33876
        GetASN_Int8Bit(&dataASN[OCSPRESPONSEASN_IDX_STATUS], &status);
33877
        GetASN_OID(&dataASN[OCSPRESPONSEASN_IDX_BYTES_TYPE], oidOcspType);
33878
        /* Decode OCSPResponse (and ResponseBytes). */
33879
        ret = GetASN_Items(ocspResponseASN, dataASN, ocspResponseASN_Length, 1,
33880
            source, &idx, size);
33881
    }
33882
    if (ret == 0) {
33883
        /* Get response. */
33884
        resp->responseStatus = status;
33885
        if (dataASN[OCSPRESPONSEASN_IDX_BYTES_TYPE].data.oid.sum
33886
                == OCSP_BASIC_OID) {
33887
            /* Get reference to BasicOCSPResponse. */
33888
            GetASN_GetRef(&dataASN[OCSPRESPONSEASN_IDX_BYTES_VAL], &basic,
33889
                    &basicSz);
33890
            idx = 0;
33891
            /* Decode BasicOCSPResponse. */
33892
            ret = DecodeBasicOcspResponse(basic, &idx, resp, basicSz, cm, heap,
33893
                noVerify);
33894
        }
33895
        /* Only support BasicOCSPResponse. */
33896
        else {
33897
            ret = ASN_PARSE_E;
33898
        }
33899
    }
33900
33901
    FREE_ASNGETDATA(dataASN, resp->heap);
33902
    WOLFSSL_LEAVE("OcspResponseDecode", ret);
33903
    return ret;
33904
#endif /* WOLFSSL_ASN_TEMPLATE */
33905
}
33906
33907
#ifdef WOLFSSL_ASN_TEMPLATE
33908
/* ASN.1 template for OCSP nonce extension.
33909
 * RFC 6960, 4.4.1 - Nonce
33910
 * X.509: RFC 5280, 4.1 - Basic Certificate Fields. (Extension)
33911
 */
33912
static const ASNItem ocspNonceExtASN[] = {
33913
/* SEQ       */ { 0, ASN_SEQUENCE, 1, 1, 0 },
33914
                                     /* Extension */
33915
/* EXT       */     { 1, ASN_SEQUENCE, 1, 1, 0 },
33916
                                        /* extnId */
33917
/* EXT_OID   */        {2, ASN_OBJECT_ID, 0, 0, 0 },
33918
                                        /* critcal not encoded. */
33919
                                        /* extnValue */
33920
/* EXT_VAL   */        {2, ASN_OCTET_STRING, 0, 1, 0 },
33921
                                               /* nonce */
33922
/* EXT_NONCE */            {3, ASN_OCTET_STRING, 0, 0, 0 },
33923
};
33924
enum {
33925
    OCSPNONCEEXTASN_IDX_SEQ = 0,
33926
    OCSPNONCEEXTASN_IDX_EXT,
33927
    OCSPNONCEEXTASN_IDX_EXT_OID,
33928
    OCSPNONCEEXTASN_IDX_EXT_VAL,
33929
    OCSPNONCEEXTASN_IDX_EXT_NONCE,
33930
};
33931
33932
/* Number of items in ASN.1 template for OCSP nonce extension. */
33933
#define ocspNonceExtASN_Length (sizeof(ocspNonceExtASN) / sizeof(ASNItem))
33934
#endif /* WOLFSSL_ASN_TEMPLATE */
33935
33936
word32 EncodeOcspRequestExtensions(OcspRequest* req, byte* output, word32 size)
33937
{
33938
    const byte NonceObjId[] = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
33939
                                       0x30, 0x01, 0x02 };
33940
#ifndef WOLFSSL_ASN_TEMPLATE
33941
    byte seqArray[5][MAX_SEQ_SZ];
33942
    word32 seqSz[5], totalSz = (word32)sizeof(NonceObjId);
33943
33944
    WOLFSSL_ENTER("SetOcspReqExtensions");
33945
33946
    if (!req || !output || !req->nonceSz)
33947
        return 0;
33948
33949
    totalSz += req->nonceSz;
33950
    totalSz += seqSz[0] = SetOctetString(req->nonceSz, seqArray[0]);
33951
    totalSz += seqSz[1] = SetOctetString(req->nonceSz + seqSz[0], seqArray[1]);
33952
    totalSz += seqSz[2] = SetObjectId(sizeof(NonceObjId), seqArray[2]);
33953
    totalSz += seqSz[3] = SetSequence(totalSz, seqArray[3]);
33954
    totalSz += seqSz[4] = SetSequence(totalSz, seqArray[4]);
33955
33956
    if (totalSz > size)
33957
        return 0;
33958
33959
    totalSz = 0;
33960
33961
    XMEMCPY(output + totalSz, seqArray[4], seqSz[4]);
33962
    totalSz += seqSz[4];
33963
33964
    XMEMCPY(output + totalSz, seqArray[3], seqSz[3]);
33965
    totalSz += seqSz[3];
33966
33967
    XMEMCPY(output + totalSz, seqArray[2], seqSz[2]);
33968
    totalSz += seqSz[2];
33969
33970
    XMEMCPY(output + totalSz, NonceObjId, sizeof(NonceObjId));
33971
    totalSz += (word32)sizeof(NonceObjId);
33972
33973
    XMEMCPY(output + totalSz, seqArray[1], seqSz[1]);
33974
    totalSz += seqSz[1];
33975
33976
    XMEMCPY(output + totalSz, seqArray[0], seqSz[0]);
33977
    totalSz += seqSz[0];
33978
33979
    XMEMCPY(output + totalSz, req->nonce, req->nonceSz);
33980
    totalSz += req->nonceSz;
33981
33982
    return totalSz;
33983
#else
33984
    int ret = 0;
33985
33986
    WOLFSSL_ENTER("SetOcspReqExtensions");
33987
33988
    /* Check request has nonce to write in extension. */
33989
    if (req != NULL && req->nonceSz != 0) {
33990
        DECL_ASNSETDATA(dataASN, ocspNonceExtASN_Length);
33991
        int sz;
33992
33993
        CALLOC_ASNSETDATA(dataASN, ocspNonceExtASN_Length, ret, req->heap);
33994
33995
        /* Set nonce extension OID and nonce. */
33996
        SetASN_Buffer(&dataASN[OCSPNONCEEXTASN_IDX_EXT_OID], NonceObjId,
33997
                sizeof(NonceObjId));
33998
        SetASN_Buffer(&dataASN[OCSPNONCEEXTASN_IDX_EXT_NONCE], req->nonce,
33999
                req->nonceSz);
34000
        /* Calculate size of nonce extension. */
34001
        ret = SizeASN_Items(ocspNonceExtASN, dataASN, ocspNonceExtASN_Length,
34002
                            &sz);
34003
        /* Check buffer big enough for encoding if supplied. */
34004
        if ((ret == 0) && (output != NULL) && (sz > (int)size)) {
34005
            ret = BUFFER_E;
34006
        }
34007
        if ((ret == 0) && (output != NULL)) {
34008
            /* Encode nonce extension. */
34009
            SetASN_Items(ocspNonceExtASN, dataASN, ocspNonceExtASN_Length,
34010
                         output);
34011
        }
34012
        if (ret == 0) {
34013
            /* Return size of encoding. */
34014
            ret = sz;
34015
        }
34016
34017
        FREE_ASNSETDATA(dataASN, req->heap);
34018
    }
34019
34020
    return ret;
34021
#endif /* WOLFSSL_ASN_TEMPLATE */
34022
}
34023
34024
34025
#ifdef WOLFSSL_ASN_TEMPLATE
34026
/* ASN.1 template for OCSPRequest.
34027
 * RFC 6960, 4.1.1 - ASN.1 Specification of the OCSP Request
34028
 */
34029
static const ASNItem ocspRequestASN[] = {
34030
                                              /* OCSPRequest */
34031
/* SEQ               */    { 0, ASN_SEQUENCE, 1, 1, 0 },
34032
                                                  /* tbsRequest */
34033
/* TBS               */        { 1, ASN_SEQUENCE, 1, 1, 0 },
34034
                                                      /* version not written - v1 */
34035
                                                      /* requestorName not written */
34036
                                                      /* requestList */
34037
/* TBS_SEQ           */            { 2, ASN_SEQUENCE, 1, 1, 0 },
34038
                                                          /* Request */
34039
/* TBS_LIST          */                { 3, ASN_SEQUENCE, 1, 1, 0 },
34040
                                                              /* reqCert */
34041
/* TBS_REQ_CID       */                    { 4, ASN_SEQUENCE, 1, 1, 0 },
34042
                                                                  /* hashAlgorithm */
34043
/* TBS_REQ_HASH      */                        { 5, ASN_SEQUENCE, 1, 1, 0 },
34044
/* TBS_REQ_HASH_OID  */                            { 6, ASN_OBJECT_ID, 0, 0, 0 },
34045
                                                                  /* issuerNameHash */
34046
/* TBS_REQ_ISSUER    */                        { 5, ASN_OCTET_STRING, 0, 0, 0 },
34047
                                                                  /* issuerKeyHash */
34048
/* TBS_REQ_ISSUERKEY */                        { 5, ASN_OCTET_STRING, 0, 0, 0 },
34049
                                                                  /* serialNumber */
34050
/* TBS_REQ_SERIAL    */                        { 5, ASN_INTEGER, 0, 0, 0 },
34051
                                                      /* requestExtensions */
34052
/* TBS_REQEXT        */            { 2, ASN_CONTEXT_SPECIFIC | 2, 1, 0, 0 },
34053
                                                  /* optionalSignature not written. */
34054
};
34055
enum {
34056
    OCSPREQUESTASN_IDX_SEQ = 0,
34057
    OCSPREQUESTASN_IDX_TBS,
34058
    OCSPREQUESTASN_IDX_TBS_SEQ,
34059
    OCSPREQUESTASN_IDX_TBS_LIST,
34060
    OCSPREQUESTASN_IDX_TBS_REQ_CID,
34061
    OCSPREQUESTASN_IDX_TBS_REQ_HASH,
34062
    OCSPREQUESTASN_IDX_TBS_REQ_HASH_OID,
34063
    OCSPREQUESTASN_IDX_TBS_REQ_ISSUER,
34064
    OCSPREQUESTASN_IDX_TBS_REQ_ISSUERKEY,
34065
    OCSPREQUESTASN_IDX_TBS_REQ_SERIAL,
34066
    OCSPREQUESTASN_IDX_TBS_REQEXT,
34067
};
34068
34069
/* Number of items in ASN.1 template for OCSPRequest. */
34070
#define ocspRequestASN_Length (sizeof(ocspRequestASN) / sizeof(ASNItem))
34071
#endif
34072
34073
int EncodeOcspRequest(OcspRequest* req, byte* output, word32 size)
34074
{
34075
#ifndef WOLFSSL_ASN_TEMPLATE
34076
    byte seqArray[5][MAX_SEQ_SZ];
34077
    /* The ASN.1 of the OCSP Request is an onion of sequences */
34078
    byte algoArray[MAX_ALGO_SZ];
34079
    byte issuerArray[MAX_ENCODED_DIG_SZ];
34080
    byte issuerKeyArray[MAX_ENCODED_DIG_SZ];
34081
    byte snArray[MAX_SN_SZ];
34082
    byte extArray[MAX_OCSP_EXT_SZ];
34083
    word32 seqSz[5], algoSz, issuerSz, issuerKeySz, extSz, totalSz;
34084
    int i, snSz;
34085
34086
    WOLFSSL_ENTER("EncodeOcspRequest");
34087
34088
#ifdef NO_SHA
34089
    algoSz = SetAlgoID(SHA256h, algoArray, oidHashType, 0);
34090
#else
34091
    algoSz = SetAlgoID(SHAh, algoArray, oidHashType, 0);
34092
#endif
34093
34094
    issuerSz    = SetDigest(req->issuerHash,    KEYID_SIZE,    issuerArray);
34095
    issuerKeySz = SetDigest(req->issuerKeyHash, KEYID_SIZE,    issuerKeyArray);
34096
    snSz        = SetSerialNumber(req->serial,  req->serialSz, snArray,
34097
                                                          MAX_SN_SZ, MAX_SN_SZ);
34098
    extSz       = 0;
34099
34100
    if (snSz < 0)
34101
        return snSz;
34102
34103
    if (req->nonceSz) {
34104
        /* TLS Extensions use this function too - put extensions after
34105
         * ASN.1: Context Specific [2].
34106
         */
34107
        extSz = EncodeOcspRequestExtensions(req, extArray + 2,
34108
                                            OCSP_NONCE_EXT_SZ);
34109
        extSz += SetExplicit(2, extSz, extArray);
34110
    }
34111
34112
    totalSz = algoSz + issuerSz + issuerKeySz + snSz;
34113
    for (i = 4; i >= 0; i--) {
34114
        seqSz[i] = SetSequence(totalSz, seqArray[i]);
34115
        totalSz += seqSz[i];
34116
        if (i == 2) totalSz += extSz;
34117
    }
34118
34119
    if (output == NULL)
34120
        return totalSz;
34121
    if (totalSz > size)
34122
        return BUFFER_E;
34123
34124
    totalSz = 0;
34125
    for (i = 0; i < 5; i++) {
34126
        XMEMCPY(output + totalSz, seqArray[i], seqSz[i]);
34127
        totalSz += seqSz[i];
34128
    }
34129
34130
    XMEMCPY(output + totalSz, algoArray, algoSz);
34131
    totalSz += algoSz;
34132
34133
    XMEMCPY(output + totalSz, issuerArray, issuerSz);
34134
    totalSz += issuerSz;
34135
34136
    XMEMCPY(output + totalSz, issuerKeyArray, issuerKeySz);
34137
    totalSz += issuerKeySz;
34138
34139
    XMEMCPY(output + totalSz, snArray, snSz);
34140
    totalSz += snSz;
34141
34142
    if (extSz != 0) {
34143
        XMEMCPY(output + totalSz, extArray, extSz);
34144
        totalSz += extSz;
34145
    }
34146
34147
    return totalSz;
34148
#else
34149
    DECL_ASNSETDATA(dataASN, ocspRequestASN_Length);
34150
    word32 extSz = 0;
34151
    int sz = 0;
34152
    int ret = 0;
34153
34154
    WOLFSSL_ENTER("EncodeOcspRequest");
34155
34156
    CALLOC_ASNSETDATA(dataASN, ocspRequestASN_Length, ret, req->heap);
34157
34158
    if (ret == 0) {
34159
        /* Set OID of hash algorithm use on issuer and key. */
34160
    #ifdef NO_SHA
34161
        SetASN_OID(&dataASN[OCSPREQUESTASN_IDX_TBS_REQ_HASH_OID], SHA256h,
34162
                oidHashType);
34163
    #else
34164
        SetASN_OID(&dataASN[OCSPREQUESTASN_IDX_TBS_REQ_HASH_OID], SHAh,
34165
                oidHashType);
34166
    #endif
34167
        /* Set issuer, issuer key hash and serial number of certificate being
34168
         * checked. */
34169
        SetASN_Buffer(&dataASN[OCSPREQUESTASN_IDX_TBS_REQ_ISSUER],
34170
                req->issuerHash, KEYID_SIZE);
34171
        SetASN_Buffer(&dataASN[OCSPREQUESTASN_IDX_TBS_REQ_ISSUERKEY],
34172
                req->issuerKeyHash, KEYID_SIZE);
34173
        SetASN_Buffer(&dataASN[OCSPREQUESTASN_IDX_TBS_REQ_SERIAL],
34174
                req->serial, req->serialSz);
34175
        /* Only extension to write is nonce - check if one to encode. */
34176
        if (req->nonceSz) {
34177
            /* Get size of extensions and leave space for them in encoding. */
34178
            ret = extSz = EncodeOcspRequestExtensions(req, NULL, 0);
34179
            SetASN_Buffer(&dataASN[OCSPREQUESTASN_IDX_TBS_REQEXT], NULL, extSz);
34180
            if (ret > 0) {
34181
                ret = 0;
34182
            }
34183
        }
34184
        else {
34185
            /* Don't write out extensions. */
34186
            dataASN[OCSPREQUESTASN_IDX_TBS_REQEXT].noOut = 1;
34187
        }
34188
    }
34189
    if (ret == 0) {
34190
        /* Calculate size of encoding. */
34191
        ret = SizeASN_Items(ocspRequestASN, dataASN, ocspRequestASN_Length,
34192
                &sz);
34193
    }
34194
    /* Check buffer big enough for encoding if supplied. */
34195
    if ((ret == 0) && (output != NULL) && (sz > (int)size)) {
34196
        ret = BUFFER_E;
34197
    }
34198
    if ((ret == 0) && (output != NULL)) {
34199
        /* Encode OCSPRequest. */
34200
        SetASN_Items(ocspRequestASN, dataASN, ocspRequestASN_Length, output);
34201
        if (req->nonceSz) {
34202
            /* Encode extensions into space provided. */
34203
            ret = EncodeOcspRequestExtensions(req,
34204
                (byte*)dataASN[OCSPREQUESTASN_IDX_TBS_REQEXT].data.buffer.data,
34205
                extSz);
34206
            if (ret > 0) {
34207
                ret = 0;
34208
            }
34209
        }
34210
    }
34211
34212
    if (ret == 0) {
34213
        /* Return size of encoding. */
34214
        ret = sz;
34215
    }
34216
34217
    FREE_ASNSETDATA(dataASN, req->heap);
34218
    return ret;
34219
#endif /* WOLFSSL_ASN_TEMPLATE */
34220
}
34221
34222
34223
int InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce,
34224
                                                                     void* heap)
34225
{
34226
    int ret;
34227
34228
    WOLFSSL_ENTER("InitOcspRequest");
34229
34230
    if (req == NULL)
34231
        return BAD_FUNC_ARG;
34232
34233
    XMEMSET(req, 0, sizeof(OcspRequest));
34234
    req->heap = heap;
34235
34236
    if (cert) {
34237
        XMEMCPY(req->issuerHash,    cert->issuerHash,    KEYID_SIZE);
34238
        XMEMCPY(req->issuerKeyHash, cert->issuerKeyHash, KEYID_SIZE);
34239
34240
        req->serial = (byte*)XMALLOC(cert->serialSz, req->heap,
34241
                                                     DYNAMIC_TYPE_OCSP_REQUEST);
34242
        if (req->serial == NULL)
34243
            return MEMORY_E;
34244
34245
        XMEMCPY(req->serial, cert->serial, cert->serialSz);
34246
        req->serialSz = cert->serialSz;
34247
34248
        if (cert->extAuthInfoSz != 0 && cert->extAuthInfo != NULL) {
34249
            req->url = (byte*)XMALLOC(cert->extAuthInfoSz + 1, req->heap,
34250
                                                     DYNAMIC_TYPE_OCSP_REQUEST);
34251
            if (req->url == NULL) {
34252
                XFREE(req->serial, req->heap, DYNAMIC_TYPE_OCSP);
34253
                return MEMORY_E;
34254
            }
34255
34256
            XMEMCPY(req->url, cert->extAuthInfo, cert->extAuthInfoSz);
34257
            req->urlSz = cert->extAuthInfoSz;
34258
            req->url[req->urlSz] = 0;
34259
        }
34260
    }
34261
34262
    if (useNonce) {
34263
        WC_RNG rng;
34264
34265
    #ifndef HAVE_FIPS
34266
        ret = wc_InitRng_ex(&rng, req->heap, INVALID_DEVID);
34267
    #else
34268
        ret = wc_InitRng(&rng);
34269
    #endif
34270
        if (ret != 0) {
34271
            WOLFSSL_MSG("\tCannot initialize RNG. Skipping the OCSP Nonce.");
34272
        } else {
34273
            if (wc_RNG_GenerateBlock(&rng, req->nonce, MAX_OCSP_NONCE_SZ) != 0)
34274
                WOLFSSL_MSG("\tCannot run RNG. Skipping the OCSP Nonce.");
34275
            else
34276
                req->nonceSz = MAX_OCSP_NONCE_SZ;
34277
34278
            wc_FreeRng(&rng);
34279
        }
34280
    }
34281
34282
    return 0;
34283
}
34284
34285
void FreeOcspRequest(OcspRequest* req)
34286
{
34287
    WOLFSSL_ENTER("FreeOcspRequest");
34288
34289
    if (req) {
34290
        if (req->serial)
34291
            XFREE(req->serial, req->heap, DYNAMIC_TYPE_OCSP_REQUEST);
34292
        req->serial = NULL;
34293
34294
#ifdef OPENSSL_EXTRA
34295
        if (req->serialInt) {
34296
            if (req->serialInt->isDynamic) {
34297
                XFREE(req->serialInt->data, NULL, DYNAMIC_TYPE_OPENSSL);
34298
            }
34299
            XFREE(req->serialInt, NULL, DYNAMIC_TYPE_OPENSSL);
34300
        }
34301
        req->serialInt = NULL;
34302
#endif
34303
34304
        if (req->url)
34305
            XFREE(req->url, req->heap, DYNAMIC_TYPE_OCSP_REQUEST);
34306
        req->url = NULL;
34307
    }
34308
}
34309
34310
34311
int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp)
34312
{
34313
    int cmp = -1; /* default as not matching, cmp gets set on each check */
34314
    OcspEntry *single, *next, *prev = NULL, *top;
34315
34316
    WOLFSSL_ENTER("CompareOcspReqResp");
34317
34318
    if (req == NULL) {
34319
        WOLFSSL_MSG("\tReq missing");
34320
        return -1;
34321
    }
34322
    if (resp == NULL || resp->single == NULL) {
34323
        WOLFSSL_MSG("\tResp missing");
34324
        return 1;
34325
    }
34326
34327
    /* Nonces are not critical. The responder may not necessarily add
34328
     * the nonce to the response. */
34329
    if (req->nonceSz && resp->nonce != NULL
34330
#ifndef WOLFSSL_FORCE_OCSP_NONCE_CHECK
34331
            && resp->nonceSz != 0
34332
#endif
34333
    ) {
34334
        cmp = req->nonceSz - resp->nonceSz;
34335
        if (cmp != 0) {
34336
            WOLFSSL_MSG("\tnonceSz mismatch");
34337
            return cmp;
34338
        }
34339
34340
        cmp = XMEMCMP(req->nonce, resp->nonce, req->nonceSz);
34341
        if (cmp != 0) {
34342
            WOLFSSL_MSG("\tnonce mismatch");
34343
            return cmp;
34344
        }
34345
    }
34346
34347
    /* match based on found status and return */
34348
    for (single = resp->single; single; single = next) {
34349
        cmp = req->serialSz - single->status->serialSz;
34350
        if (cmp == 0) {
34351
            cmp = XMEMCMP(req->serial, single->status->serial, req->serialSz)
34352
               || XMEMCMP(req->issuerHash, single->issuerHash, OCSP_DIGEST_SIZE)
34353
               || XMEMCMP(req->issuerKeyHash, single->issuerKeyHash, OCSP_DIGEST_SIZE);
34354
            if (cmp == 0) {
34355
                /* match found */
34356
                if (resp->single != single && prev) {
34357
                    /* move to top of list */
34358
                    top = resp->single;
34359
                    resp->single = single;
34360
                    prev->next = single->next;
34361
                    single->next = top;
34362
                }
34363
                break;
34364
            }
34365
        }
34366
        next = single->next;
34367
        prev = single;
34368
    }
34369
34370
    if (cmp != 0) {
34371
        WOLFSSL_MSG("\trequest and response mismatch");
34372
        return cmp;
34373
    }
34374
34375
    return 0;
34376
}
34377
34378
#endif /* HAVE_OCSP */
34379
34380
34381
#ifdef WOLFSSL_ASN_TEMPLATE
34382
/* ASN.1 template for certificate name hash. */
34383
static const ASNItem nameHashASN[] = {
34384
/* OID  */ { 0, ASN_OBJECT_ID, 0, 0, 1 },
34385
/* NAME */ { 0, ASN_SEQUENCE, 1, 0, 0 },
34386
};
34387
enum {
34388
    NAMEHASHASN_IDX_OID = 0,
34389
    NAMEHASHASN_IDX_NAME,
34390
};
34391
34392
/* Number of items in ASN.1 template for certificate name hash. */
34393
#define nameHashASN_Length (sizeof(nameHashASN) / sizeof(ASNItem))
34394
#endif /* WOLFSSL_ASN_TEMPLATE */
34395
34396
/* store WC_SHA hash of NAME */
34397
int GetNameHash(const byte* source, word32* idx, byte* hash, int maxIdx)
34398
0
{
34399
0
#ifndef WOLFSSL_ASN_TEMPLATE
34400
0
    int    length;  /* length of all distinguished names */
34401
0
    int    ret;
34402
0
    word32 dummy;
34403
0
    byte   tag;
34404
34405
0
    WOLFSSL_ENTER("GetNameHash");
34406
34407
0
    dummy = *idx;
34408
0
    if (GetASNTag(source, &dummy, &tag, maxIdx) == 0 && tag == ASN_OBJECT_ID) {
34409
0
        WOLFSSL_MSG("Trying optional prefix...");
34410
34411
0
        if (GetLength(source, idx, &length, maxIdx) < 0)
34412
0
            return ASN_PARSE_E;
34413
34414
0
        *idx += length;
34415
0
        WOLFSSL_MSG("Got optional prefix");
34416
0
    }
34417
34418
    /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
34419
     * calculated over the entire DER encoding of the Name field, including
34420
     * the tag and length. */
34421
0
    dummy = *idx;
34422
0
    if (GetSequence(source, idx, &length, maxIdx) < 0)
34423
0
        return ASN_PARSE_E;
34424
34425
0
    ret = CalcHashId(source + dummy, length + *idx - dummy, hash);
34426
34427
0
    *idx += length;
34428
34429
0
    return ret;
34430
#else
34431
    ASNGetData dataASN[nameHashASN_Length];
34432
    int ret;
34433
34434
    XMEMSET(dataASN, 0, sizeof(dataASN));
34435
    /* Ignore the OID even when present. */
34436
    GetASN_OID(&dataASN[NAMEHASHASN_IDX_OID], oidIgnoreType);
34437
    /* Decode certificate name. */
34438
    ret = GetASN_Items(nameHashASN, dataASN, nameHashASN_Length, 0, source, idx,
34439
           maxIdx);
34440
    if (ret == 0) {
34441
        /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
34442
         * calculated over the entire DER encoding of the Name field, including
34443
         * the tag and length. */
34444
        /* Calculate hash of complete name including SEQUENCE. */
34445
        ret = CalcHashId(
34446
                GetASNItem_Addr(dataASN[NAMEHASHASN_IDX_NAME], source),
34447
                GetASNItem_Length(dataASN[NAMEHASHASN_IDX_NAME], source),
34448
                hash);
34449
    }
34450
34451
    return ret;
34452
#endif /* WOLFSSL_ASN_TEMPLATE */
34453
0
}
34454
34455
#ifdef HAVE_CRL
34456
34457
#ifdef OPENSSL_EXTRA
34458
static char* GetNameFromDer(const byte* source, int sz)
34459
{
34460
    char* out;
34461
34462
    out = (char*)XMALLOC(sz, NULL, DYNAMIC_TYPE_OPENSSL);
34463
    if (out == NULL) {
34464
        WOLFSSL_MSG("Name malloc failed");
34465
        return NULL;
34466
    }
34467
34468
    XMEMCPY(out, source, sz);
34469
34470
    return out;
34471
}
34472
#endif
34473
34474
/* initialize decoded CRL */
34475
void InitDecodedCRL(DecodedCRL* dcrl, void* heap)
34476
{
34477
    WOLFSSL_MSG("InitDecodedCRL");
34478
34479
    XMEMSET(dcrl, 0, sizeof(DecodedCRL));
34480
    dcrl->heap = heap;
34481
#ifdef WOLFSSL_HEAP_TEST
34482
    dcrl->heap = (void*)WOLFSSL_HEAP_TEST;
34483
#endif
34484
}
34485
34486
34487
/* free decoded CRL resources */
34488
void FreeDecodedCRL(DecodedCRL* dcrl)
34489
{
34490
    RevokedCert* tmp = dcrl->certs;
34491
34492
    WOLFSSL_MSG("FreeDecodedCRL");
34493
34494
    while(tmp) {
34495
        RevokedCert* next = tmp->next;
34496
        XFREE(tmp, dcrl->heap, DYNAMIC_TYPE_REVOKED);
34497
        tmp = next;
34498
    }
34499
#ifdef OPENSSL_EXTRA
34500
    if (dcrl->issuer != NULL)
34501
        XFREE(dcrl->issuer, NULL, DYNAMIC_TYPE_OPENSSL);
34502
#endif
34503
}
34504
34505
34506
#ifdef WOLFSSL_ASN_TEMPLATE
34507
/* ASN.1 template for revoked certificates.
34508
 * X.509: RFC 5280, 5.1 - CRL Fields
34509
 */
34510
static const ASNItem revokedASN[] = {
34511
/* SEQ      */    { 0, ASN_SEQUENCE, 1, 1, 0 },
34512
                                     /* userCertificate    CertificateSerialNumber */
34513
/* CERT     */        { 1, ASN_INTEGER, 0, 0, 0 },
34514
                                     /* revocationDate     Time */
34515
/* TIME_UTC */        { 1, ASN_UTC_TIME, 0, 0, 2 },
34516
/* TIME_GT  */        { 1, ASN_GENERALIZED_TIME, 0, 0, 2 },
34517
                                     /* crlEntryExensions  Extensions */
34518
/* TIME_EXT */        { 1, ASN_SEQUENCE, 1, 0, 1 },
34519
};
34520
enum {
34521
    REVOKEDASN_IDX_SEQ = 0,
34522
    REVOKEDASN_IDX_CERT,
34523
    REVOKEDASN_IDX_TIME_UTC,
34524
    REVOKEDASN_IDX_TIME_GT,
34525
    REVOKEDASN_IDX_TIME_EXT,
34526
};
34527
34528
/* Number of items in ASN.1 template for revoked certificates. */
34529
#define revokedASN_Length (sizeof(revokedASN) / sizeof(ASNItem))
34530
#endif
34531
34532
/* Get Revoked Cert list, 0 on success */
34533
static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl,
34534
                      int maxIdx)
34535
{
34536
#ifndef WOLFSSL_ASN_TEMPLATE
34537
#ifndef NO_ASN_TIME
34538
    int ret;
34539
#endif
34540
    int len;
34541
    word32 end;
34542
    RevokedCert* rc;
34543
34544
    WOLFSSL_ENTER("GetRevoked");
34545
34546
    if (GetSequence(buff, idx, &len, maxIdx) < 0)
34547
        return ASN_PARSE_E;
34548
34549
    end = *idx + len;
34550
34551
    rc = (RevokedCert*)XMALLOC(sizeof(RevokedCert), dcrl->heap,
34552
                                                          DYNAMIC_TYPE_REVOKED);
34553
    if (rc == NULL) {
34554
        WOLFSSL_MSG("Alloc Revoked Cert failed");
34555
        return MEMORY_E;
34556
    }
34557
34558
    if (wc_GetSerialNumber(buff, idx, rc->serialNumber, &rc->serialSz,
34559
                                                                maxIdx) < 0) {
34560
        XFREE(rc, dcrl->heap, DYNAMIC_TYPE_REVOKED);
34561
        return ASN_PARSE_E;
34562
    }
34563
34564
    /* add to list */
34565
    rc->next = dcrl->certs;
34566
    dcrl->certs = rc;
34567
    dcrl->totalCerts++;
34568
34569
    /* get date */
34570
#ifndef NO_ASN_TIME
34571
    ret = GetBasicDate(buff, idx, rc->revDate, &rc->revDateFormat, maxIdx);
34572
    if (ret < 0) {
34573
        WOLFSSL_MSG("Expecting Date");
34574
        return ret;
34575
    }
34576
#endif
34577
    /* skip extensions */
34578
    *idx = end;
34579
34580
    return 0;
34581
#else
34582
    DECL_ASNGETDATA(dataASN, revokedASN_Length);
34583
    int ret = 0;
34584
    word32 serialSz = EXTERNAL_SERIAL_SIZE;
34585
    word32 revDateSz = MAX_DATE_SIZE;
34586
    RevokedCert* rc;
34587
34588
    /* Allocate a new revoked certificate object. */
34589
    rc = (RevokedCert*)XMALLOC(sizeof(RevokedCert), dcrl->heap,
34590
            DYNAMIC_TYPE_CRL);
34591
    if (rc == NULL) {
34592
        ret = MEMORY_E;
34593
    }
34594
34595
    CALLOC_ASNGETDATA(dataASN, revokedASN_Length, ret, dcrl->heap);
34596
34597
    if (ret == 0) {
34598
        /* Set buffer to place serial number into. */
34599
        GetASN_Buffer(&dataASN[REVOKEDASN_IDX_CERT], rc->serialNumber,
34600
                &serialSz);
34601
        /* Set buffer to store revocation date. */
34602
        GetASN_Buffer(&dataASN[REVOKEDASN_IDX_TIME_UTC], rc->revDate,
34603
                &revDateSz);
34604
        GetASN_Buffer(&dataASN[REVOKEDASN_IDX_TIME_GT], rc->revDate,
34605
                &revDateSz);
34606
        /* Decode the Revoked */
34607
        ret = GetASN_Items(revokedASN, dataASN, revokedASN_Length, 1, buff, idx,
34608
                maxIdx);
34609
    }
34610
    if (ret == 0) {
34611
        /* Store size of serial number. */
34612
        rc->serialSz = serialSz;
34613
        rc->revDateFormat = (dataASN[REVOKEDASN_IDX_TIME_UTC].tag != 0)
34614
                ? dataASN[REVOKEDASN_IDX_TIME_UTC].tag
34615
                : dataASN[REVOKEDASN_IDX_TIME_GT].tag;
34616
34617
        /* TODO: use extensions, only v2 */
34618
        /* Add revoked certificate to chain. */
34619
        rc->next = dcrl->certs;
34620
        dcrl->certs = rc;
34621
        dcrl->totalCerts++;
34622
    }
34623
34624
    FREE_ASNGETDATA(dataASN, dcrl->heap);
34625
    if ((ret != 0) && (rc != NULL)) {
34626
        XFREE(rc, dcrl->heap, DYNAMIC_TYPE_CRL);
34627
    }
34628
    return ret;
34629
#endif /* WOLFSSL_ASN_TEMPLATE */
34630
}
34631
34632
#ifdef WOLFSSL_ASN_TEMPLATE
34633
/* Parse the revoked certificates of a CRL.
34634
 *
34635
 * @param [in] dcrl    Decoded CRL object.
34636
 * @param [in] buff    Buffer holding CRL.
34637
 * @param [in] idx     Index into buffer of revoked certificates.
34638
 * @param [in] maxIdx  Maximum index of revoked cartificates data.
34639
 * @return  0 on success.
34640
 * @return  ASN_PARSE_E on failure.
34641
 */
34642
static int ParseCRL_RevokedCerts(DecodedCRL* dcrl, const byte* buff, word32 idx,
34643
    word32 maxIdx)
34644
{
34645
    int ret = 0;
34646
34647
    /* Parse each revoked cerificate. */
34648
    while ((ret == 0) && (idx < maxIdx)) {
34649
        /* Parse a revoked certificate. */
34650
        if (GetRevoked(buff, &idx, dcrl, maxIdx) < 0) {
34651
            ret = ASN_PARSE_E;
34652
        }
34653
    }
34654
34655
    return ret;
34656
}
34657
#endif /* WOLFSSL_ASN_TEMPLATE */
34658
34659
#ifndef WOLFSSL_ASN_TEMPLATE
34660
/* Get CRL Signature, 0 on success */
34661
static int GetCRL_Signature(const byte* source, word32* idx, DecodedCRL* dcrl,
34662
                            int maxIdx)
34663
{
34664
    int    length;
34665
    int    ret;
34666
34667
    WOLFSSL_ENTER("GetCRL_Signature");
34668
34669
    ret = CheckBitString(source, idx, &length, maxIdx, 1, NULL);
34670
    if (ret != 0)
34671
        return ret;
34672
    dcrl->sigLength = length;
34673
34674
    dcrl->signature = (byte*)&source[*idx];
34675
    *idx += dcrl->sigLength;
34676
34677
    return 0;
34678
}
34679
#endif /* !WOLFSSL_ASN_TEMPLATE */
34680
34681
int VerifyCRL_Signature(SignatureCtx* sigCtx, const byte* toBeSigned,
34682
                        word32 tbsSz, const byte* signature, word32 sigSz,
34683
                        word32 signatureOID, Signer *ca, void* heap)
34684
{
34685
    /* try to confirm/verify signature */
34686
#ifndef IGNORE_KEY_EXTENSIONS
34687
    if ((ca->keyUsage & KEYUSE_CRL_SIGN) == 0) {
34688
        WOLFSSL_MSG("CA cannot sign CRLs");
34689
        WOLFSSL_ERROR_VERBOSE(ASN_CRL_NO_SIGNER_E);
34690
        return ASN_CRL_NO_SIGNER_E;
34691
    }
34692
#endif /* IGNORE_KEY_EXTENSIONS */
34693
34694
    InitSignatureCtx(sigCtx, heap, INVALID_DEVID);
34695
    if (ConfirmSignature(sigCtx, toBeSigned, tbsSz, ca->publicKey,
34696
                         ca->pubKeySize, ca->keyOID, signature, sigSz,
34697
                         signatureOID, NULL, 0, NULL) != 0) {
34698
        WOLFSSL_MSG("CRL Confirm signature failed");
34699
        WOLFSSL_ERROR_VERBOSE(ASN_CRL_CONFIRM_E);
34700
        return ASN_CRL_CONFIRM_E;
34701
    }
34702
34703
    return 0;
34704
}
34705
34706
#ifdef WOLFSSL_ASN_TEMPLATE
34707
/* Find the signer for the CRL and verify the signature.
34708
 *
34709
 * @param [in] dcrl  Decoded CRL object.
34710
 * @param [in] buff  Buffer holding CRL.
34711
 * @param [in] cm    Certificate manager object.
34712
 * @return  0 on success.
34713
 * @return  ASN_CRL_NO_SIGNER_E when no signer found.
34714
 * @return  ASN_CRL_CONFIRM_E when signature did not verify.
34715
 */
34716
static int PaseCRL_CheckSignature(DecodedCRL* dcrl, const byte* buff, void* cm)
34717
{
34718
    int ret = 0;
34719
    Signer* ca = NULL;
34720
    SignatureCtx sigCtx;
34721
34722
    /* OpenSSL doesn't add skid by default for CRLs cause firefox chokes.
34723
     * If experiencing issues uncomment NO_SKID define in CRL section of
34724
     * wolfssl/wolfcrypt/settings.h */
34725
#ifndef NO_SKID
34726
    if (dcrl->extAuthKeyIdSet) {
34727
        /* more unique than issuerHash */
34728
        ca = GetCA(cm, dcrl->extAuthKeyId);
34729
    }
34730
    /* Check issuerHash matched CA's subjectNameHash. */
34731
    if ((ca != NULL) && (XMEMCMP(dcrl->issuerHash, ca->subjectNameHash,
34732
                                 KEYID_SIZE) != 0)) {
34733
        ca = NULL;
34734
    }
34735
    if (ca == NULL) {
34736
        ca = GetCAByName(cm, dcrl->issuerHash); /* last resort */
34737
        /* If AKID is available then this CA doesn't have the public
34738
         * key required */
34739
        if (ca && dcrl->extAuthKeyIdSet) {
34740
            WOLFSSL_MSG("CA SKID doesn't match AKID");
34741
            ca = NULL;
34742
        }
34743
    }
34744
#else
34745
    ca = GetCA(cm, dcrl->issuerHash);
34746
#endif /* !NO_SKID */
34747
    WOLFSSL_MSG("About to verify CRL signature");
34748
34749
    if (ca == NULL) {
34750
        WOLFSSL_MSG("Did NOT find CRL issuer CA");
34751
        ret = ASN_CRL_NO_SIGNER_E;
34752
        WOLFSSL_ERROR_VERBOSE(ret);
34753
    }
34754
34755
    if (ret == 0) {
34756
        WOLFSSL_MSG("Found CRL issuer CA");
34757
        /* Verify CRL signature with CA. */
34758
        ret = VerifyCRL_Signature(&sigCtx, buff + dcrl->certBegin,
34759
           dcrl->sigIndex - dcrl->certBegin, dcrl->signature, dcrl->sigLength,
34760
           dcrl->signatureOID, ca, dcrl->heap);
34761
    }
34762
34763
    return ret;
34764
}
34765
#endif
34766
34767
#ifndef WOLFSSL_ASN_TEMPLATE
34768
static int ParseCRL_CertList(DecodedCRL* dcrl, const byte* buf,
34769
        word32* inOutIdx, int sz, int verify)
34770
{
34771
    word32 oid, dateIdx, idx, checkIdx;
34772
    int length;
34773
#ifdef WOLFSSL_NO_CRL_NEXT_DATE
34774
    int doNextDate = 1;
34775
#endif
34776
    byte tag;
34777
34778
    if (dcrl == NULL || inOutIdx == NULL || buf == NULL) {
34779
        return BAD_FUNC_ARG;
34780
    }
34781
34782
    /* may have version */
34783
    idx = *inOutIdx;
34784
34785
    checkIdx = idx;
34786
    if (GetASNTag(buf, &checkIdx, &tag, sz) == 0 && tag == ASN_INTEGER) {
34787
        if (GetMyVersion(buf, &idx, &dcrl->version, sz) < 0)
34788
            return ASN_PARSE_E;
34789
        dcrl->version++;
34790
    }
34791
34792
    if (GetAlgoId(buf, &idx, &oid, oidIgnoreType, sz) < 0)
34793
        return ASN_PARSE_E;
34794
34795
    checkIdx = idx;
34796
    if (GetSequence(buf, &checkIdx, &length, sz) < 0) {
34797
        return ASN_PARSE_E;
34798
    }
34799
#ifdef OPENSSL_EXTRA
34800
    dcrl->issuerSz = length + (checkIdx - idx);
34801
    dcrl->issuer   = (byte*)GetNameFromDer(buf + idx, (int)dcrl->issuerSz);
34802
#endif
34803
34804
    if (GetNameHash(buf, &idx, dcrl->issuerHash, sz) < 0)
34805
        return ASN_PARSE_E;
34806
34807
    if (GetBasicDate(buf, &idx, dcrl->lastDate, &dcrl->lastDateFormat, sz) < 0)
34808
        return ASN_PARSE_E;
34809
34810
    dateIdx = idx;
34811
34812
    if (GetBasicDate(buf, &idx, dcrl->nextDate, &dcrl->nextDateFormat, sz) < 0)
34813
    {
34814
#ifndef WOLFSSL_NO_CRL_NEXT_DATE
34815
        (void)dateIdx;
34816
        return ASN_PARSE_E;
34817
#else
34818
        dcrl->nextDateFormat = ASN_OTHER_TYPE;  /* skip flag */
34819
        doNextDate = 0;
34820
        idx = dateIdx;
34821
#endif
34822
    }
34823
34824
#ifdef WOLFSSL_NO_CRL_NEXT_DATE
34825
    if (doNextDate)
34826
#endif
34827
    {
34828
#ifndef NO_ASN_TIME
34829
        if (verify != NO_VERIFY &&
34830
                !XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, AFTER)) {
34831
            WOLFSSL_MSG("CRL after date is no longer valid");
34832
            WOLFSSL_ERROR_VERBOSE(CRL_CERT_DATE_ERR);
34833
            return CRL_CERT_DATE_ERR;
34834
        }
34835
#else
34836
        (void)verify;
34837
#endif
34838
    }
34839
34840
    checkIdx = idx;
34841
    if (idx != dcrl->sigIndex &&
34842
           GetASNTag(buf, &checkIdx, &tag, sz) == 0 && tag != CRL_EXTENSIONS) {
34843
34844
        int len;
34845
34846
        if (GetSequence(buf, &idx, &len, sz) < 0)
34847
            return ASN_PARSE_E;
34848
        len += idx;
34849
34850
        while (idx < (word32)len) {
34851
            if (GetRevoked(buf, &idx, dcrl, len) < 0)
34852
                return ASN_PARSE_E;
34853
        }
34854
    }
34855
34856
    *inOutIdx = idx;
34857
34858
    return 0;
34859
}
34860
#endif /* !WOLFSSL_ASN_TEMPLATE */
34861
34862
34863
#ifndef NO_SKID
34864
static int ParseCRL_AuthKeyIdExt(const byte* input, int sz, DecodedCRL* dcrl)
34865
{
34866
#ifndef WOLFSSL_ASN_TEMPLATE
34867
    word32 idx = 0;
34868
    int length = 0, ret = 0;
34869
    byte tag;
34870
34871
    WOLFSSL_ENTER("ParseCRL_AuthKeyIdExt");
34872
34873
    if (GetSequence(input, &idx, &length, sz) < 0) {
34874
        WOLFSSL_MSG("\tfail: should be a SEQUENCE");
34875
        return ASN_PARSE_E;
34876
    }
34877
34878
    if (GetASNTag(input, &idx, &tag, sz) < 0) {
34879
        return ASN_PARSE_E;
34880
    }
34881
34882
    if (tag != (ASN_CONTEXT_SPECIFIC | 0)) {
34883
        WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available");
34884
        return 0;
34885
    }
34886
34887
    if (GetLength(input, &idx, &length, sz) <= 0) {
34888
        WOLFSSL_MSG("\tfail: extension data length");
34889
        return ASN_PARSE_E;
34890
    }
34891
34892
    dcrl->extAuthKeyIdSet = 1;
34893
    /* Get the hash or hash of the hash if wrong size. */
34894
    ret = GetHashId(input + idx, length, dcrl->extAuthKeyId);
34895
34896
    return ret;
34897
#else
34898
    DECL_ASNGETDATA(dataASN, authKeyIdASN_Length);
34899
    int ret = 0;
34900
    word32 idx = 0;
34901
34902
    WOLFSSL_ENTER("ParseCRL_AuthKeyIdExt");
34903
34904
    CALLOC_ASNGETDATA(dataASN, authKeyIdASN_Length, ret, dcrl->heap);
34905
34906
    if (ret == 0) {
34907
        /* Parse an authority key identifier. */
34908
        ret = GetASN_Items(authKeyIdASN, dataASN, authKeyIdASN_Length, 1, input,
34909
                           &idx, sz);
34910
    }
34911
    if (ret == 0) {
34912
        /* Key id is optional. */
34913
        if (dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data == NULL) {
34914
            WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available");
34915
        }
34916
        else {
34917
            /* Get the hash or hash of the hash if wrong size. */
34918
            ret = GetHashId(dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data,
34919
                dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.length,
34920
                dcrl->extAuthKeyId);
34921
        }
34922
    }
34923
34924
    FREE_ASNGETDATA(dataASN, dcrl->heap);
34925
    return ret;
34926
#endif /* WOLFSSL_ASN_TEMPLATE */
34927
}
34928
#endif
34929
34930
34931
#ifndef WOLFSSL_ASN_TEMPLATE
34932
static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf,
34933
        word32* inOutIdx, word32 sz)
34934
{
34935
    int length;
34936
    word32 idx;
34937
    word32 ext_bound; /* boundary index for the sequence of extensions */
34938
    word32 oid;
34939
    byte tag;
34940
34941
    WOLFSSL_ENTER("ParseCRL_Extensions");
34942
    (void)dcrl;
34943
34944
    if (inOutIdx == NULL)
34945
        return BAD_FUNC_ARG;
34946
34947
    idx = *inOutIdx;
34948
34949
    /* CRL Extensions are optional */
34950
    if ((idx + 1) > sz)
34951
        return 0;
34952
34953
    /* CRL Extensions are optional */
34954
    if (GetASNTag(buf, &idx, &tag, sz) < 0)
34955
        return 0;
34956
34957
    /* CRL Extensions are optional */
34958
    if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
34959
        return 0;
34960
34961
    if (GetLength(buf, &idx, &length, sz) < 0)
34962
        return ASN_PARSE_E;
34963
34964
    if (GetSequence(buf, &idx, &length, sz) < 0)
34965
        return ASN_PARSE_E;
34966
34967
    ext_bound = idx + length;
34968
34969
    while (idx < (word32)ext_bound) {
34970
        word32 localIdx;
34971
        int ret;
34972
34973
        if (GetSequence(buf, &idx, &length, sz) < 0) {
34974
            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
34975
            return ASN_PARSE_E;
34976
        }
34977
34978
        oid = 0;
34979
        if (GetObjectId(buf, &idx, &oid, oidCrlExtType, sz) < 0) {
34980
            WOLFSSL_MSG("\tfail: OBJECT ID");
34981
            return ASN_PARSE_E;
34982
        }
34983
34984
        /* check for critical flag */
34985
        if ((idx + 1) > (word32)sz) {
34986
            WOLFSSL_MSG("\tfail: malformed buffer");
34987
            return BUFFER_E;
34988
        }
34989
34990
        localIdx = idx;
34991
        if (GetASNTag(buf, &localIdx, &tag, sz) == 0 && tag == ASN_BOOLEAN) {
34992
            WOLFSSL_MSG("\tfound optional critical flag, moving past");
34993
            ret = GetBoolean(buf, &idx, sz);
34994
            if (ret < 0)
34995
                return ret;
34996
        }
34997
34998
        ret = GetOctetString(buf, &idx, &length, sz);
34999
        if (ret < 0)
35000
            return ret;
35001
35002
        if (oid == AUTH_KEY_OID) {
35003
        #ifndef NO_SKID
35004
            ret = ParseCRL_AuthKeyIdExt(buf + idx, length, dcrl);
35005
            if (ret < 0) {
35006
                WOLFSSL_MSG("\tcouldn't parse AuthKeyId extension");
35007
                return ret;
35008
            }
35009
        #endif
35010
        }
35011
        else if (oid == CRL_NUMBER_OID) {
35012
            localIdx = idx;
35013
            if (GetASNTag(buf, &localIdx, &tag, sz) == 0 &&
35014
                    tag == ASN_INTEGER) {
35015
                ret = GetASNInt(buf, &idx, &length, sz);
35016
                if (ret < 0) {
35017
                    WOLFSSL_MSG("\tcouldn't parse CRL number extension");
35018
                    return ret;
35019
                }
35020
                else {
35021
                    if (length > 1) {
35022
                        int    i;
35023
                    #ifdef WOLFSSL_SMALL_STACK
35024
                        mp_int* m = (mp_int*)XMALLOC(sizeof(*m), NULL,
35025
                                DYNAMIC_TYPE_BIGINT);
35026
                        if (m == NULL) {
35027
                            return MEMORY_E;
35028
                        }
35029
                    #else
35030
                        mp_int m[1];
35031
                    #endif
35032
35033
                        if (mp_init(m) != MP_OKAY) {
35034
                            ret = MP_INIT_E;
35035
                        }
35036
35037
                        if (ret == 0)
35038
                            ret = mp_read_unsigned_bin(m, buf + idx, length);
35039
                        if (ret != MP_OKAY)
35040
                            ret = BUFFER_E;
35041
35042
                        if (ret == 0) {
35043
                            dcrl->crlNumber = 0;
35044
                            for (i = 0; i < (*m).used; ++i) {
35045
                                if (i > (int)sizeof(word32)) {
35046
                                    break;
35047
                                }
35048
                                dcrl->crlNumber |= ((word32)(*m).dp[i]) <<
35049
                                    (DIGIT_BIT * i);
35050
                            }
35051
                        }
35052
35053
                        mp_free(m);
35054
                    #ifdef WOLFSSL_SMALL_STACK
35055
                        XFREE(m, NULL, DYNAMIC_TYPE_BIGINT);
35056
                    #endif
35057
35058
                        if (ret != 0)
35059
                            return ret;
35060
                    }
35061
                    else {
35062
                        dcrl->crlNumber = buf[idx];
35063
                    }
35064
                }
35065
            }
35066
        }
35067
35068
        idx += length;
35069
    }
35070
35071
    *inOutIdx = idx;
35072
35073
    return 0;
35074
}
35075
#else
35076
/* Parse the extensions of a CRL.
35077
 *
35078
 * @param [in] dcrl    Decoded CRL object.
35079
 * @param [in] buff    Buffer holding CRL.
35080
 * @param [in] idx     Index into buffer of extensions.
35081
 * @param [in] maxIdx  Maximum index of extension data.
35082
 * @return  0 on success.
35083
 * @return  ASN_PARSE_E on failure.
35084
 */
35085
static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf, word32 idx,
35086
        word32 maxIdx)
35087
{
35088
    DECL_ASNGETDATA(dataASN, certExtASN_Length);
35089
    int ret = 0;
35090
35091
    ALLOC_ASNGETDATA(dataASN, certExtASN_Length, ret, dcrl->heap);
35092
35093
    while ((ret == 0) && (idx < maxIdx)) {
35094
        byte critical = 0;
35095
35096
        /* Clear dynamic data. */
35097
        XMEMSET(dataASN, 0, sizeof(*dataASN) * certExtASN_Length);
35098
        /* Ensure OID is an extention type. */
35099
        GetASN_OID(&dataASN[CERTEXTASN_IDX_OID], oidCertExtType);
35100
        /* Set criticality variable. */
35101
        GetASN_Int8Bit(&dataASN[CERTEXTASN_IDX_CRIT], &critical);
35102
        /* Parse extension wrapper. */
35103
        ret = GetASN_Items(certExtASN, dataASN, certExtASN_Length, 0, buf, &idx,
35104
                maxIdx);
35105
        if (ret == 0) {
35106
            /* OID in extension. */
35107
            word32 oid = dataASN[CERTEXTASN_IDX_OID].data.oid.sum;
35108
            /* Length of extension data. */
35109
            int length = dataASN[CERTEXTASN_IDX_VAL].length;
35110
35111
            if (oid == AUTH_KEY_OID) {
35112
            #ifndef NO_SKID
35113
                /* Parse Authority Key Id extesion.
35114
                 * idx is at start of OCTET_STRING data. */
35115
                ret = ParseCRL_AuthKeyIdExt(buf + idx, length, dcrl);
35116
                if (ret != 0) {
35117
                    WOLFSSL_MSG("\tcouldn't parse AuthKeyId extension");
35118
                }
35119
            #endif
35120
            }
35121
            /* TODO: Parse CRL Number extension */
35122
            /* TODO: check criticality */
35123
            /* Move index on to next extension. */
35124
            idx += length;
35125
        }
35126
    }
35127
35128
    if (ret < 0) {
35129
        ret = ASN_PARSE_E;
35130
    }
35131
35132
    FREE_ASNGETDATA(dataASN, dcrl->heap);
35133
35134
    return ret;
35135
}
35136
#endif /* !WOLFSSL_ASN_TEMPLATE */
35137
35138
35139
#ifdef WOLFSSL_ASN_TEMPLATE
35140
/* ASN.1 template for a CRL- CertificateList.
35141
 * X.509: RFC 5280, 5.1 - CRL Fields
35142
 */
35143
static const ASNItem crlASN[] = {
35144
                                       /* CertificateList */
35145
/* SEQ                */    { 0, ASN_SEQUENCE, 1, 1, 0 },
35146
                                           /* tbsCertList */
35147
/* TBS                */        { 1, ASN_SEQUENCE, 1, 1, 0 },
35148
                                               /* version     Version OPTIONAL if present must be v2 */
35149
/* TBS_VER            */            { 2, ASN_INTEGER, 0, 0, 1 },
35150
                                               /* signature */
35151
/* TBS_SIGALGO        */            { 2, ASN_SEQUENCE, 1, 1, 0 },
35152
/* TBS_SIGALGO_OID    */                { 3, ASN_OBJECT_ID, 0, 0, 0 },
35153
/* TBS_SIGALGO_NULL   */                { 3, ASN_TAG_NULL, 0, 0, 1 },
35154
                                               /* issuer */
35155
/* TBS_ISSUER         */            { 2, ASN_SEQUENCE, 1, 0, 0 },
35156
                                               /* thisUpdate */
35157
/* TBS_THISUPDATE_UTC */            { 2, ASN_UTC_TIME, 0, 0, 2 },
35158
/* TBS_THISUPDATE_GT  */            { 2, ASN_GENERALIZED_TIME, 0, 0, 2 },
35159
                                               /* nextUpdate */
35160
/* TBS_NEXTUPDATE_UTC */            { 2, ASN_UTC_TIME, 0, 0, 3 },
35161
/* TBS_NEXTUPDATE_GT  */            { 2, ASN_GENERALIZED_TIME, 0, 0, 3 },
35162
                                               /* revokedCertificates */
35163
/* TBS_REVOKEDCERTS   */            { 2, ASN_SEQUENCE, 1, 0, 1 },
35164
                                               /* crlExtensions */
35165
/* TBS_EXT            */            { 2, ASN_CONTEXT_SPECIFIC | 0, 1, 1, 1 },
35166
/* TBS_EXT_SEQ        */                { 3, ASN_SEQUENCE, 1, 0, 0 },
35167
                                           /* signatureAlgorithm */
35168
/* SIGALGO            */        { 1, ASN_SEQUENCE, 1, 1, 0 },
35169
/* SIGALGO_OID        */            { 2, ASN_OBJECT_ID, 0, 0, 0 },
35170
/* SIGALGO_NULL       */            { 2, ASN_TAG_NULL, 0, 0, 1 },
35171
                                           /* signatureValue */
35172
/* SIGNATURE          */        { 1, ASN_BIT_STRING, 0, 0, 0 },
35173
};
35174
enum {
35175
    CRLASN_IDX_SEQ = 0,
35176
    CRLASN_IDX_TBS,
35177
    CRLASN_IDX_TBS_VER,
35178
    CRLASN_IDX_TBS_SIGALGO,
35179
    CRLASN_IDX_TBS_SIGALGO_OID,
35180
    CRLASN_IDX_TBS_SIGALGO_NULL,
35181
    CRLASN_IDX_TBS_ISSUER,
35182
    CRLASN_IDX_TBS_THISUPDATE_UTC,
35183
    CRLASN_IDX_TBS_THISUPDATE_GT,
35184
    CRLASN_IDX_TBS_NEXTUPDATE_UTC,
35185
    CRLASN_IDX_TBS_NEXTUPDATE_GT,
35186
    CRLASN_IDX_TBS_REVOKEDCERTS,
35187
    CRLASN_IDX_TBS_EXT,
35188
    CRLASN_IDX_TBS_EXT_SEQ,
35189
    CRLASN_IDX_SIGALGO,
35190
    CRLASN_IDX_SIGALGO_OID,
35191
    CRLASN_IDX_SIGALGO_NULL,
35192
    CRLASN_IDX_SIGNATURE,
35193
};
35194
35195
/* Number of items in ASN.1 template for a CRL- CertificateList. */
35196
#define crlASN_Length (sizeof(crlASN) / sizeof(ASNItem))
35197
#endif
35198
35199
/* parse crl buffer into decoded state, 0 on success */
35200
int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, int verify,
35201
        void* cm)
35202
{
35203
#ifndef WOLFSSL_ASN_TEMPLATE
35204
    Signer*      ca = NULL;
35205
    SignatureCtx sigCtx;
35206
    int          ret = 0;
35207
    int          len;
35208
    word32       idx = 0;
35209
35210
    WOLFSSL_MSG("ParseCRL");
35211
35212
    /* raw crl hash */
35213
    /* hash here if needed for optimized comparisons
35214
     * wc_Sha sha;
35215
     * wc_InitSha(&sha);
35216
     * wc_ShaUpdate(&sha, buff, sz);
35217
     * wc_ShaFinal(&sha, dcrl->crlHash); */
35218
35219
    if (GetSequence(buff, &idx, &len, sz) < 0)
35220
        return ASN_PARSE_E;
35221
35222
    dcrl->certBegin = idx;
35223
    /* Normalize sz for the length inside the outer sequence. */
35224
    sz = len + idx;
35225
35226
    if (GetSequence(buff, &idx, &len, sz) < 0)
35227
        return ASN_PARSE_E;
35228
    dcrl->sigIndex = len + idx;
35229
35230
    if (ParseCRL_CertList(dcrl, buff, &idx, dcrl->sigIndex, verify) < 0)
35231
        return ASN_PARSE_E;
35232
35233
    if (ParseCRL_Extensions(dcrl, buff, &idx, dcrl->sigIndex) < 0)
35234
        return ASN_PARSE_E;
35235
35236
    idx = dcrl->sigIndex;
35237
35238
    if (GetAlgoId(buff, &idx, &dcrl->signatureOID, oidSigType, sz) < 0)
35239
        return ASN_PARSE_E;
35240
35241
    if (GetCRL_Signature(buff, &idx, dcrl, sz) < 0)
35242
        return ASN_PARSE_E;
35243
35244
    /* openssl doesn't add skid by default for CRLs cause firefox chokes
35245
       if experiencing issues uncomment NO_SKID define in CRL section of
35246
       wolfssl/wolfcrypt/settings.h */
35247
#ifndef NO_SKID
35248
    if (dcrl->extAuthKeyIdSet) {
35249
        ca = GetCA(cm, dcrl->extAuthKeyId); /* more unique than issuerHash */
35250
    }
35251
    if (ca != NULL && XMEMCMP(dcrl->issuerHash, ca->subjectNameHash,
35252
                KEYID_SIZE) != 0) {
35253
        ca = NULL;
35254
    }
35255
    if (ca == NULL) {
35256
        ca = GetCAByName(cm, dcrl->issuerHash); /* last resort */
35257
        /* If AKID is available then this CA doesn't have the public
35258
         * key required */
35259
        if (ca && dcrl->extAuthKeyIdSet) {
35260
            WOLFSSL_MSG("CA SKID doesn't match AKID");
35261
            ca = NULL;
35262
        }
35263
    }
35264
#else
35265
    ca = GetCA(cm, dcrl->issuerHash);
35266
#endif /* !NO_SKID */
35267
    WOLFSSL_MSG("About to verify CRL signature");
35268
35269
    if (ca == NULL) {
35270
        WOLFSSL_MSG("Did NOT find CRL issuer CA");
35271
        ret = ASN_CRL_NO_SIGNER_E;
35272
        WOLFSSL_ERROR_VERBOSE(ret);
35273
        goto end;
35274
    }
35275
35276
    WOLFSSL_MSG("Found CRL issuer CA");
35277
    ret = VerifyCRL_Signature(&sigCtx, buff + dcrl->certBegin,
35278
           dcrl->sigIndex - dcrl->certBegin, dcrl->signature, dcrl->sigLength,
35279
           dcrl->signatureOID, ca, dcrl->heap);
35280
35281
end:
35282
    return ret;
35283
#else
35284
    DECL_ASNGETDATA(dataASN, crlASN_Length);
35285
    int ret = 0;
35286
    /* Default version - v1 = 0 */
35287
    byte version = 0;
35288
    word32 idx = 0;
35289
    /* Size of buffer for date. */
35290
    word32 lastDateSz = MAX_DATE_SIZE;
35291
    word32 nextDateSz = MAX_DATE_SIZE;
35292
35293
    WOLFSSL_MSG("ParseCRL");
35294
35295
    CALLOC_ASNGETDATA(dataASN, crlASN_Length, ret, dcrl->heap);
35296
35297
    if (ret == 0) {
35298
        /* Set variable to store version. */
35299
        GetASN_Int8Bit(&dataASN[CRLASN_IDX_TBS_VER], &version);
35300
        /* Set expecting signature OID. */
35301
        GetASN_OID(&dataASN[CRLASN_IDX_TBS_SIGALGO_OID], oidSigType);
35302
        /* Set buffer to put last and next date into. */
35303
        GetASN_Buffer(&dataASN[CRLASN_IDX_TBS_THISUPDATE_UTC], dcrl->lastDate,
35304
                &lastDateSz);
35305
        GetASN_Buffer(&dataASN[CRLASN_IDX_TBS_THISUPDATE_GT], dcrl->lastDate,
35306
                &lastDateSz);
35307
        GetASN_Buffer(&dataASN[CRLASN_IDX_TBS_NEXTUPDATE_UTC], dcrl->nextDate,
35308
                &nextDateSz);
35309
        GetASN_Buffer(&dataASN[CRLASN_IDX_TBS_NEXTUPDATE_GT], dcrl->nextDate,
35310
                &nextDateSz);
35311
        /* Set expecting signature OID. */
35312
        GetASN_OID(&dataASN[CRLASN_IDX_SIGALGO_OID], oidSigType);
35313
        /* Decode the CRL. */
35314
        ret = GetASN_Items(crlASN, dataASN, crlASN_Length, 1, buff, &idx, sz);
35315
    }
35316
    /* Version must be v2 = 1 if present. */
35317
    if ((ret == 0) && (dataASN[CRLASN_IDX_TBS_VER].tag != 0) &&
35318
            (version != 1)) {
35319
        ret = ASN_PARSE_E;
35320
    }
35321
    /* Check minimum size of last date. */
35322
    if ((ret == 0) && (lastDateSz < MIN_DATE_SIZE)) {
35323
        ret = ASN_PARSE_E;
35324
    }
35325
    /* Check minimum size of next date. */
35326
    if ((ret == 0) && (nextDateSz < MIN_DATE_SIZE)) {
35327
        ret = ASN_PARSE_E;
35328
    }
35329
    /* 'signatureAlgorithm' OID must be the same as 'signature' OID. */
35330
    if ((ret == 0) && (dataASN[CRLASN_IDX_SIGALGO_OID].data.oid.sum !=
35331
            dataASN[CRLASN_IDX_TBS_SIGALGO_OID].data.oid.sum)) {
35332
        ret = ASN_PARSE_E;
35333
    }
35334
    if (ret == 0) {
35335
        /* Store version */
35336
        dcrl->version = ++version;
35337
        /* Store offset of to be signed part. */
35338
        dcrl->certBegin = dataASN[CRLASN_IDX_TBS].offset;
35339
        /* Store index of signature. */
35340
        dcrl->sigIndex = dataASN[CRLASN_IDX_SIGALGO].offset;
35341
        /* Store address and length of signature data. */
35342
        GetASN_GetRef(&dataASN[CRLASN_IDX_SIGNATURE], &dcrl->signature,
35343
                &dcrl->sigLength);
35344
        /* Get the signature OID. */
35345
        dcrl->signatureOID = dataASN[CRLASN_IDX_SIGALGO_OID].data.oid.sum;
35346
        /* Get the format/tag of the last and next date. */
35347
        dcrl->lastDateFormat = (dataASN[CRLASN_IDX_TBS_THISUPDATE_UTC].tag != 0)
35348
                ? dataASN[CRLASN_IDX_TBS_THISUPDATE_UTC].tag
35349
                : dataASN[CRLASN_IDX_TBS_THISUPDATE_GT].tag;
35350
        dcrl->nextDateFormat = (dataASN[CRLASN_IDX_TBS_NEXTUPDATE_UTC].tag != 0)
35351
                ? dataASN[CRLASN_IDX_TBS_NEXTUPDATE_UTC].tag
35352
                : dataASN[CRLASN_IDX_TBS_NEXTUPDATE_GT].tag;
35353
    #ifndef NO_ASN_TIME
35354
        if (dcrl->nextDateFormat != 0) {
35355
            /* Next date was set, so validate it. */
35356
            if (verify != NO_VERIFY &&
35357
                 !XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, AFTER)) {
35358
                WOLFSSL_MSG("CRL after date is no longer valid");
35359
                ret = CRL_CERT_DATE_ERR;
35360
                WOLFSSL_ERROR_VERBOSE(ret);
35361
            }
35362
        }
35363
    }
35364
    if (ret == 0) {
35365
    #endif
35366
        /* Parse and store the issuer name. */
35367
        dcrl->issuerSz = GetASNItem_Length(dataASN[CRLASN_IDX_TBS_ISSUER],
35368
                            buff);
35369
        dcrl->issuer   = (byte*)GetNameFromDer((byte*)GetASNItem_Addr(
35370
                            dataASN[CRLASN_IDX_TBS_ISSUER], buff),
35371
                            (int)dcrl->issuerSz);
35372
        /* Calculate the Hash id from the issuer name. */
35373
        ret = CalcHashId(GetASNItem_Addr(dataASN[CRLASN_IDX_TBS_ISSUER], buff),
35374
                dcrl->issuerSz, dcrl->issuerHash);
35375
        if (ret < 0) {
35376
            ret = ASN_PARSE_E;
35377
        }
35378
    }
35379
    if ((ret == 0) && (dataASN[CRLASN_IDX_TBS_REVOKEDCERTS].tag != 0)) {
35380
        /* Parse revoked cerificates - starting after SEQUENCE OF. */
35381
        ret = ParseCRL_RevokedCerts(dcrl, buff,
35382
            GetASNItem_DataIdx(dataASN[CRLASN_IDX_TBS_REVOKEDCERTS], buff),
35383
            GetASNItem_EndIdx(dataASN[CRLASN_IDX_TBS_REVOKEDCERTS], buff));
35384
    }
35385
    if (ret == 0) {
35386
        /* Parse the extensions - starting after SEQUENCE OF. */
35387
        ret = ParseCRL_Extensions(dcrl, buff,
35388
            GetASNItem_DataIdx(dataASN[CRLASN_IDX_TBS_EXT_SEQ], buff),
35389
            GetASNItem_EndIdx(dataASN[CRLASN_IDX_TBS_EXT_SEQ], buff));
35390
    }
35391
    if (ret == 0) {
35392
        /* Find signer and verify signature. */
35393
        ret = PaseCRL_CheckSignature(dcrl, buff, cm);
35394
    }
35395
35396
    FREE_ASNGETDATA(dataASN, dcrl->heap);
35397
    return ret;
35398
#endif /* WOLFSSL_ASN_TEMPLATE */
35399
}
35400
35401
#endif /* HAVE_CRL */
35402
35403
35404
35405
#ifdef WOLFSSL_CERT_PIV
35406
35407
#ifdef WOLFSSL_ASN_TEMPLATE
35408
/* Template for PIV. */
35409
static const ASNItem pivASN[] = {
35410
/* CERT        */ { 0, ASN_PIV_CERT, 0, 0, 0 },
35411
/* NONCE       */ { 0, ASN_PIV_NONCE, 0, 0, 1 },
35412
/* SIGNEDNONCE */ { 0, ASN_PIV_SIGNED_NONCE, 0, 0, 1 },
35413
};
35414
enum {
35415
    PIVASN_IDX_CERT = 0,
35416
    PIVASN_IDX_NONCE,
35417
    PIVASN_IDX_SIGNEDNONCE,
35418
};
35419
35420
#define pivASN_Length (sizeof(pivASN) / sizeof(ASNItem))
35421
35422
static const ASNItem pivCertASN[] = {
35423
                          /* 0x53 = 0x40 | 0x13 */
35424
/* CERT */ { 1, ASN_APPLICATION | 0x13, 0, 1, 0 },
35425
                               /* 0x70 = 0x40 | 0x10 + 0x20 (CONSTRUCTED) */
35426
/* X509 */      { 2, ASN_APPLICATION | 0x10, 1, 0, 0 },
35427
                               /* 0x71 = 0x40 | 0x11 + 0x20 (CONSTRUCTED) */
35428
/* INFO */      { 2, ASN_APPLICATION | 0x11, 1, 0, 1 },
35429
                               /* 0xFE = 0xC0 | 0x1E + 0x20 (CONSTRUCTED) */
35430
/* ERR */      { 2, ASN_PRIVATE | 0x1e, 1, 0, 1 },
35431
};
35432
enum {
35433
    PIVCERTASN_IDX_CERT,
35434
    PIVCERTASN_IDX_X509,
35435
    PIVCERTASN_IDX_INFO,
35436
    PIVCERTASN_IDX_ERR,
35437
};
35438
35439
#define pivCertASN_Length (sizeof(pivCertASN) / sizeof(ASNItem))
35440
#endif
35441
35442
int wc_ParseCertPIV(wc_CertPIV* piv, const byte* buf, word32 totalSz)
35443
{
35444
#ifndef WOLFSSL_ASN_TEMPLATE
35445
    int length = 0;
35446
    word32 idx = 0;
35447
35448
    WOLFSSL_ENTER("wc_ParseCertPIV");
35449
35450
    if (piv == NULL || buf == NULL || totalSz == 0)
35451
        return BAD_FUNC_ARG;
35452
35453
    XMEMSET(piv, 0, sizeof(wc_CertPIV));
35454
35455
    /* Detect Identiv PIV (with 0x0A, 0x0B and 0x0C sections) */
35456
    /* Certificate (0A 82 05FA) */
35457
    if (GetASNHeader(buf, ASN_PIV_CERT, &idx, &length, totalSz) >= 0) {
35458
        /* Identiv Type PIV card */
35459
        piv->isIdentiv = 1;
35460
35461
        piv->cert =   &buf[idx];
35462
        piv->certSz = length;
35463
        idx += length;
35464
35465
        /* Nonce (0B 14) */
35466
        if (GetASNHeader(buf, ASN_PIV_NONCE, &idx, &length, totalSz) >= 0) {
35467
            piv->nonce =   &buf[idx];
35468
            piv->nonceSz = length;
35469
            idx += length;
35470
        }
35471
35472
        /* Signed Nonce (0C 82 0100) */
35473
        if (GetASNHeader(buf, ASN_PIV_SIGNED_NONCE, &idx, &length, totalSz) >= 0) {
35474
            piv->signedNonce =   &buf[idx];
35475
            piv->signedNonceSz = length;
35476
        }
35477
35478
        idx = 0;
35479
        buf = piv->cert;
35480
        totalSz = piv->certSz;
35481
    }
35482
35483
    /* Certificate Buffer Total Size (53 82 05F6) */
35484
    if (GetASNHeader(buf, ASN_APPLICATION | ASN_PRINTABLE_STRING, &idx,
35485
                                                   &length, totalSz) < 0) {
35486
        return ASN_PARSE_E;
35487
    }
35488
    /* PIV Certificate (70 82 05ED) */
35489
    if (GetASNHeader(buf, ASN_PIV_TAG_CERT, &idx, &length,
35490
                                                         totalSz) < 0) {
35491
        return ASN_PARSE_E;
35492
    }
35493
35494
    /* Capture certificate buffer pointer and length */
35495
    piv->cert =   &buf[idx];
35496
    piv->certSz = length;
35497
    idx += length;
35498
35499
    /* PIV Certificate Info (71 01 00) */
35500
    if (GetASNHeader(buf, ASN_PIV_TAG_CERT_INFO, &idx, &length,
35501
                                                        totalSz) >= 0) {
35502
        if (length >= 1) {
35503
            piv->compression = (buf[idx] & ASN_PIV_CERT_INFO_COMPRESSED);
35504
            piv->isX509 =      ((buf[idx] & ASN_PIV_CERT_INFO_ISX509) != 0);
35505
        }
35506
        idx += length;
35507
    }
35508
35509
    /* PIV Error Detection (FE 00) */
35510
    if (GetASNHeader(buf, ASN_PIV_TAG_ERR_DET, &idx, &length,
35511
                                                        totalSz) >= 0) {
35512
        piv->certErrDet =   &buf[idx];
35513
        piv->certErrDetSz = length;
35514
        idx += length;
35515
    }
35516
35517
    return 0;
35518
#else
35519
    /* pivCertASN_Length is longer than pivASN_Length */
35520
    DECL_ASNGETDATA(dataASN, pivCertASN_Length);
35521
    int ret = 0;
35522
    word32 idx;
35523
    byte info;
35524
35525
    WOLFSSL_ENTER("wc_ParseCertPIV");
35526
35527
    ALLOC_ASNGETDATA(dataASN, pivCertASN_Length, ret, NULL);
35528
35529
    if (ret == 0) {
35530
        /* Clear dynamic data. */
35531
        XMEMSET(dataASN, 0, sizeof(*dataASN) * pivASN_Length);
35532
        /* Start parsing from start of buffer. */
35533
        idx = 0;
35534
        /* Parse Identiv wrapper. */
35535
        ret = GetASN_Items(pivASN, dataASN, pivASN_Length, 1, buf, &idx,
35536
                totalSz);
35537
        if (ret == 0) {
35538
            /* Identiv wrapper found. */
35539
            piv->isIdentiv = 1;
35540
            /* Get nonce reference. */
35541
            if (dataASN[PIVASN_IDX_NONCE].tag != 0) {
35542
                GetASN_GetConstRef(&dataASN[PIVASN_IDX_NONCE], &piv->nonce,
35543
                        &piv->nonceSz);
35544
            }
35545
            /* Get signedNonce reference. */
35546
            if (dataASN[PIVASN_IDX_SIGNEDNONCE].tag != 0) {
35547
                GetASN_GetConstRef(&dataASN[PIVASN_IDX_SIGNEDNONCE],
35548
                        &piv->signedNonce, &piv->signedNonceSz);
35549
            }
35550
            /* Get the certificate data for parsing. */
35551
            GetASN_GetConstRef(&dataASN[PIVASN_IDX_CERT], &buf, &totalSz);
35552
        }
35553
        ret = 0;
35554
    }
35555
    if (ret == 0) {
35556
        /* Clear dynamic data and set variable to put cert info into. */
35557
        XMEMSET(dataASN, 0, sizeof(*dataASN) * pivCertASN_Length);
35558
        GetASN_Int8Bit(&dataASN[PIVCERTASN_IDX_INFO], &info);
35559
        /* Start parsing from start of buffer. */
35560
        idx = 0;
35561
        /* Parse PIV cetificate data. */
35562
        ret = GetASN_Items(pivCertASN, dataASN, pivCertASN_Length, 1, buf, &idx,
35563
                totalSz);
35564
        if (ret == 0) {
35565
            /* Get X.509 certificate reference. */
35566
            GetASN_GetConstRef(&dataASN[PIVCERTASN_IDX_X509], &piv->cert,
35567
                    &piv->certSz);
35568
            /* Set the certificate info if available. */
35569
            if (dataASN[PIVCERTASN_IDX_INFO].tag != 0) {
35570
                /* Bits 1 and 2 are compression. */
35571
                piv->compression = info & ASN_PIV_CERT_INFO_COMPRESSED;
35572
                /* Bits 3 is X509 flag. */
35573
                piv->isX509 = ((info & ASN_PIV_CERT_INFO_ISX509) != 0);
35574
            }
35575
            /* Get X.509 certificate error detection reference. */
35576
            GetASN_GetConstRef(&dataASN[PIVCERTASN_IDX_ERR], &piv->certErrDet,
35577
                     &piv->certErrDetSz);
35578
        }
35579
        ret = 0;
35580
    }
35581
35582
    FREE_ASNGETDATA(dataASN, NULL);
35583
    return ret;
35584
#endif /* WOLFSSL_ASN_TEMPLATE */
35585
}
35586
35587
#endif /* WOLFSSL_CERT_PIV */
35588
35589
35590
35591
#ifdef HAVE_SMIME
35592
35593
/*****************************************************************************
35594
* wc_MIME_parse_headers - Reads the char array in and parses out MIME headers
35595
* and parameters into headers.  Will continue until in has no more content.
35596
*
35597
* RETURNS:
35598
* returns zero on success, non-zero on error.
35599
*/
35600
int wc_MIME_parse_headers(char* in, int inLen, MimeHdr** headers)
35601
{
35602
    MimeHdr* nextHdr = NULL;
35603
    MimeHdr* curHdr = NULL;
35604
    MimeParam* nextParam = NULL;
35605
    size_t start = 0;
35606
    size_t end = 0;
35607
    char* nameAttr = NULL;
35608
    char* bodyVal = NULL;
35609
    MimeTypes mimeType = MIME_HDR;
35610
    MimeStatus mimeStatus = MIME_NAMEATTR;
35611
    int ret = -1;
35612
    size_t pos = 0;
35613
    size_t lineLen = 0;
35614
    char* curLine = NULL;
35615
    char* ptr = NULL;
35616
35617
    if (in == NULL || inLen <= 0 || in[inLen] != '\0' || headers == NULL) {
35618
        ret = BAD_FUNC_ARG;
35619
        goto error;
35620
    }
35621
    nextHdr = (MimeHdr*)XMALLOC(sizeof(MimeHdr), NULL, DYNAMIC_TYPE_PKCS7);
35622
    nextParam = (MimeParam*)XMALLOC(sizeof(MimeParam), NULL,
35623
                                    DYNAMIC_TYPE_PKCS7);
35624
    if (nextHdr == NULL || nextParam == NULL) {
35625
        ret = MEMORY_E;
35626
        goto error;
35627
    }
35628
    XMEMSET(nextHdr, 0, (word32)sizeof(MimeHdr));
35629
    XMEMSET(nextParam, 0, (word32)sizeof(MimeParam));
35630
35631
    curLine = XSTRTOK(in, "\r\n", &ptr);
35632
    if (curLine == NULL) {
35633
        ret = ASN_PARSE_E;
35634
        goto error;
35635
    }
35636
35637
    while (curLine != NULL) {
35638
        /* Leftover from previous line, add params to previous header. */
35639
        if (curLine[0] == ' ' && curHdr) {
35640
            mimeType = MIME_PARAM;
35641
        }
35642
        else {
35643
            mimeType = MIME_HDR;
35644
        }
35645
        start = 0;
35646
        lineLen = XSTRLEN(curLine);
35647
        if (lineLen == 0) {
35648
            ret = BAD_FUNC_ARG;
35649
            goto error;
35650
        }
35651
35652
        for (pos = 0; pos < lineLen; pos++) {
35653
            char cur = curLine[pos];
35654
35655
            if (mimeStatus == MIME_NAMEATTR && ((cur == ':' &&
35656
                mimeType == MIME_HDR) || (cur == '=' &&
35657
                mimeType == MIME_PARAM)) && pos >= 1) {
35658
                mimeStatus = MIME_BODYVAL;
35659
                end = pos-1;
35660
                if (nameAttr != NULL)
35661
                    XFREE(nameAttr, NULL, DYNAMIC_TYPE_PKCS7);
35662
                ret = wc_MIME_header_strip(curLine, &nameAttr, start, end);
35663
                if (ret) {
35664
                    goto error;
35665
                }
35666
                start = pos+1;
35667
            }
35668
            else if (mimeStatus == MIME_BODYVAL && cur == ';' && pos >= 1) {
35669
                end = pos-1;
35670
                if (bodyVal != NULL)
35671
                    XFREE(bodyVal, NULL, DYNAMIC_TYPE_PKCS7);
35672
                ret = wc_MIME_header_strip(curLine, &bodyVal, start, end);
35673
                if (ret) {
35674
                    goto error;
35675
                }
35676
                if (mimeType == MIME_HDR) {
35677
                    nextHdr->name = nameAttr;
35678
                    nameAttr = NULL;
35679
                    nextHdr->body = bodyVal;
35680
                    bodyVal = NULL;
35681
                    nextHdr->next = curHdr;
35682
                    curHdr = nextHdr;
35683
                    nextHdr = (MimeHdr*)XMALLOC(sizeof(MimeHdr), NULL,
35684
                                                DYNAMIC_TYPE_PKCS7);
35685
                    if (nextHdr == NULL) {
35686
                        ret = MEMORY_E;
35687
                        goto error;
35688
                    }
35689
                    XMEMSET(nextHdr, 0, (word32)sizeof(MimeHdr));
35690
                }
35691
                else {
35692
                    nextParam->attribute = nameAttr;
35693
                    nameAttr = NULL;
35694
                    nextParam->value = bodyVal;
35695
                    bodyVal = NULL;
35696
                    nextParam->next = curHdr->params;
35697
                    curHdr->params = nextParam;
35698
                    nextParam = (MimeParam*)XMALLOC(sizeof(MimeParam), NULL,
35699
                                                    DYNAMIC_TYPE_PKCS7);
35700
                    if (nextParam == NULL) {
35701
                        ret = MEMORY_E;
35702
                        goto error;
35703
                    }
35704
                    XMEMSET(nextParam, 0, (word32)sizeof(MimeParam));
35705
                }
35706
                mimeType = MIME_PARAM;
35707
                mimeStatus = MIME_NAMEATTR;
35708
                start = pos+1;
35709
            }
35710
        }
35711
35712
        end = lineLen-1;
35713
        /* Omit newline characters. */
35714
        while ((curLine[end] == '\r' || curLine[end] == '\n') && end > 0) {
35715
            end--;
35716
        }
35717
        if (end >= start && mimeStatus == MIME_BODYVAL) {
35718
            ret = wc_MIME_header_strip(curLine, &bodyVal, start, end);
35719
            if (ret) {
35720
                goto error;
35721
            }
35722
            if (mimeType == MIME_HDR) {
35723
                nextHdr->name = nameAttr;
35724
                nameAttr = NULL;
35725
                nextHdr->body = bodyVal;
35726
                bodyVal = NULL;
35727
                nextHdr->next = curHdr;
35728
                curHdr = nextHdr;
35729
                nextHdr = (MimeHdr*)XMALLOC(sizeof(MimeHdr), NULL,
35730
                                            DYNAMIC_TYPE_PKCS7);
35731
                if (nextHdr == NULL) {
35732
                    ret = MEMORY_E;
35733
                    goto error;
35734
                }
35735
                XMEMSET(nextHdr, 0, (word32)sizeof(MimeHdr));
35736
            } else {
35737
                nextParam->attribute = nameAttr;
35738
                nameAttr = NULL;
35739
                nextParam->value = bodyVal;
35740
                bodyVal = NULL;
35741
                nextParam->next = curHdr->params;
35742
                curHdr->params = nextParam;
35743
                nextParam = (MimeParam*)XMALLOC(sizeof(MimeParam), NULL,
35744
                                                DYNAMIC_TYPE_PKCS7);
35745
                if (nextParam == NULL) {
35746
                    ret = MEMORY_E;
35747
                    goto error;
35748
                }
35749
                XMEMSET(nextParam, 0, (word32)sizeof(MimeParam));
35750
            }
35751
        }
35752
35753
        curLine = XSTRTOK(NULL, "\r\n", &ptr);
35754
        mimeStatus = MIME_NAMEATTR;
35755
    }
35756
35757
    *headers = curHdr;
35758
    ret = 0; /* success if at this point */
35759
35760
error:
35761
    if (ret != 0)
35762
        wc_MIME_free_hdrs(curHdr);
35763
    wc_MIME_free_hdrs(nextHdr);
35764
    if (nameAttr != NULL)
35765
        XFREE(nameAttr, NULL, DYNAMIC_TYPE_PKCS7);
35766
    if (bodyVal != NULL)
35767
        XFREE(bodyVal, NULL, DYNAMIC_TYPE_PKCS7);
35768
    XFREE(nextParam, NULL, DYNAMIC_TYPE_PKCS7);
35769
35770
    return ret;
35771
}
35772
35773
/*****************************************************************************
35774
* wc_MIME_header_strip - Reads the string in from indices start to end, strips
35775
* out disallowed/separator characters and places the rest into *out.
35776
*
35777
* RETURNS:
35778
* returns zero on success, non-zero on error.
35779
*/
35780
int wc_MIME_header_strip(char* in, char** out, size_t start, size_t end)
35781
{
35782
    size_t inPos = start;
35783
    size_t outPos = 0;
35784
    size_t inLen = 0;
35785
35786
    if (end < start || in == NULL || out == NULL) {
35787
        return BAD_FUNC_ARG;
35788
    }
35789
35790
    inLen = XSTRLEN(in);
35791
    if (start > inLen || end > inLen) {
35792
        return BAD_FUNC_ARG;
35793
    }
35794
35795
    *out = (char*)XMALLOC(((end-start)+2)*sizeof(char), NULL,
35796
                          DYNAMIC_TYPE_PKCS7);
35797
    if (*out == NULL) {
35798
        return MEMORY_E;
35799
    }
35800
35801
    while (inPos <= end) {
35802
        if (in[inPos] >= MIME_HEADER_ASCII_MIN && in[inPos] <=
35803
            MIME_HEADER_ASCII_MAX && in[inPos] != ';' && in[inPos] != '\"') {
35804
            (*out)[outPos] = in[inPos];
35805
            outPos++;
35806
        }
35807
        inPos++;
35808
    }
35809
    (*out)[outPos] = '\0';
35810
35811
    return 0;
35812
}
35813
35814
/*****************************************************************************
35815
* wc_MIME_find_header_name - Searches through all given headers until a header with
35816
* a name matching the provided name is found.
35817
*
35818
* RETURNS:
35819
* returns a pointer to the found header, if no match was found, returns NULL.
35820
*/
35821
MimeHdr* wc_MIME_find_header_name(const char* name, MimeHdr* header)
35822
{
35823
    while (header) {
35824
        if (!XSTRCMP(name, header->name)) {
35825
            return header;
35826
        }
35827
        header = header->next;
35828
    }
35829
35830
    return header;
35831
}
35832
35833
/*****************************************************************************
35834
* wc_MIME_find_param_attr - Searches through all parameters until a parameter
35835
* with a attribute matching the provided attribute is found.
35836
*
35837
* RETURNS:
35838
* returns a pointer to the found parameter, if no match was found,
35839
* returns NULL.
35840
*/
35841
MimeParam* wc_MIME_find_param_attr(const char* attribute,
35842
                                    MimeParam* param)
35843
{
35844
    while (param) {
35845
        if (!XSTRCMP(attribute, param->attribute)) {
35846
            return param;
35847
        }
35848
        param = param->next;
35849
    }
35850
35851
    return param;
35852
}
35853
35854
/*****************************************************************************
35855
* wc_MIME_single_canonicalize - Canonicalize a line by converting the trailing
35856
* line ending to CRLF.
35857
*
35858
* line - input line to canonicalize
35859
* len  - length of line in chars on input, length of output array on return
35860
*
35861
* RETURNS:
35862
* returns a pointer to a canonicalized line on success, NULL on error.
35863
*/
35864
char* wc_MIME_single_canonicalize(const char* line, word32* len)
35865
{
35866
    size_t end = 0;
35867
    char* canonLine = NULL;
35868
35869
    if (line == NULL || len == NULL || *len == 0) {
35870
        return NULL;
35871
    }
35872
35873
    end = *len;
35874
    while (end >= 1 && ((line[end-1] == '\r') || (line[end-1] == '\n'))) {
35875
        end--;
35876
    }
35877
35878
    /* Need 2 chars for \r\n and 1 for EOL */
35879
    canonLine = (char*)XMALLOC((end+3)*sizeof(char), NULL, DYNAMIC_TYPE_PKCS7);
35880
    if (canonLine == NULL) {
35881
        return NULL;
35882
    }
35883
35884
    XMEMCPY(canonLine, line, end);
35885
    canonLine[end] = '\r';
35886
    canonLine[end+1] = '\n';
35887
    canonLine[end+2] = '\0';
35888
    *len = (word32)(end + 3);
35889
35890
    return canonLine;
35891
}
35892
35893
/*****************************************************************************
35894
* wc_MIME_free_hdrs - Frees all MIME headers, parameters and strings starting from
35895
* the provided header pointer.
35896
*
35897
* RETURNS:
35898
* returns zero on success, non-zero on error.
35899
*/
35900
int wc_MIME_free_hdrs(MimeHdr* head)
35901
{
35902
    MimeHdr* curHdr = NULL;
35903
    MimeParam* curParam = NULL;
35904
35905
    while (head) {
35906
        while (head->params) {
35907
            curParam = head->params;
35908
            head->params = head->params->next;
35909
            XFREE(curParam->attribute, NULL, DYNAMIC_TYPE_PKCS7);
35910
            XFREE(curParam->value, NULL, DYNAMIC_TYPE_PKCS7);
35911
            XFREE(curParam, NULL, DYNAMIC_TYPE_PKCS7);
35912
        }
35913
        curHdr = head;
35914
        head = head->next;
35915
        XFREE(curHdr->name, NULL, DYNAMIC_TYPE_PKCS7);
35916
        XFREE(curHdr->body, NULL, DYNAMIC_TYPE_PKCS7);
35917
        XFREE(curHdr, NULL, DYNAMIC_TYPE_PKCS7);
35918
    }
35919
35920
    return 0;
35921
}
35922
35923
#endif /* HAVE_SMIME */
35924
35925
35926
#undef ERROR_OUT
35927
35928
#endif /* !NO_ASN */
35929
35930
#ifdef WOLFSSL_SEP
35931
35932
35933
#endif /* WOLFSSL_SEP */