Coverage Report

Created: 2023-11-19 07:08

/src/wolfssl/wolfcrypt/src/asn.c
Line
Count
Source (jump to first uncovered line)
1
/* asn.c
2
 *
3
 * Copyright (C) 2006-2023 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 2 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
/*
23
 * 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_CHECK: Disables ASN time checks (avoiding the ASN_BEFORE_DATE_E
46
 * and ASN_AFTER_DATE_E errors). Safer ways to avoid date errors would be to
47
 * set the WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY flag when calling the _ex versions of
48
 * cert loading functions or to define the WOLFSSL_NO_OCSP_DATE_CHECK macro to
49
 * skip OCSP date errors. Defining NO_ASN_TIME_CHECK will skip ALL date checks
50
 * and could pose a security risk.
51
 * NO_ASN_TIME: Disables time parts of the ASN code for systems without an RTC
52
    or wishing to save space.
53
 * IGNORE_NAME_CONSTRAINTS: Skip ASN name checks.
54
 * ASN_DUMP_OID: Allows dump of OID information for debugging.
55
 * RSA_DECODE_EXTRA: Decodes extra information in RSA public key.
56
 * WOLFSSL_CERT_GEN: Cert generation. Saves extra certificate info in GetName.
57
 * WOLFSSL_NO_ASN_STRICT: Disable strict RFC compliance checks to
58
    restore 3.13.0 behavior.
59
 * WOLFSSL_NO_OCSP_OPTIONAL_CERTS: Skip optional OCSP certs (responder issuer
60
    must still be trusted)
61
 * WOLFSSL_NO_TRUSTED_CERTS_VERIFY: Workaround for situation where entire cert
62
    chain is not loaded. This only matches on subject and public key and
63
    does not perform a PKI validation, so it is not a secure solution.
64
    Only enabled for OCSP.
65
 * WOLFSSL_NO_OCSP_ISSUER_CHECK: Can be defined for backwards compatibility to
66
    disable checking of https://www.rfc-editor.org/rfc/rfc6960#section-4.2.2.2.
67
 * WOLFSSL_SMALL_CERT_VERIFY: Verify the certificate signature without using
68
    DecodedCert. Doubles up on some code but allows smaller dynamic memory
69
    usage.
70
 * WOLFSSL_NO_OCSP_DATE_CHECK: Disable date checks for OCSP responses. This
71
    may be required when the system's real-time clock is not very accurate.
72
    It is recommended to enforce the nonce check instead if possible.
73
 * WOLFSSL_FORCE_OCSP_NONCE_CHECK: Require nonces to be available in OCSP
74
    responses. The nonces are optional and may not be supported by all
75
    responders. If it can be ensured that the used responder sends nonces this
76
    option may improve security.
77
 * WOLFSSL_ASN_TEMPLATE: Encoding and decoding using a template.
78
 * WOLFSSL_DEBUG_ASN_TEMPLATE: Enables debugging output when using ASN.1
79
    templates.
80
 * WOLFSSL_ASN_TEMPLATE_TYPE_CHECK: Use ASN functions to better test compiler
81
    type issues for testing
82
 * CRLDP_VALIDATE_DATA: For ASN template only, validates the reason data
83
 * WOLFSSL_AKID_NAME: Enable support for full AuthorityKeyIdentifier extension.
84
    Only supports copying full AKID from an existing certificate.
85
 * WOLFSSL_CUSTOM_OID: Enable custom OID support for subject and request
86
    extensions
87
 * WOLFSSL_HAVE_ISSUER_NAMES: Store pointers to issuer name components and their
88
    lengths and encodings.
89
 * WOLFSSL_SUBJ_DIR_ATTR: Enable support for SubjectDirectoryAttributes
90
    extension.
91
 * WOLFSSL_SUBJ_INFO_ACC: Enable support for SubjectInfoAccess extension.
92
 * WOLFSSL_FPKI: Enable support for FPKI (Federal PKI) extensions.
93
 * WOLFSSL_CERT_NAME_ALL: Adds more certificate name capability at the
94
    cost of taking up more memory. Adds initials, givenname, dnQualifer for
95
    example.
96
 * WC_ASN_HASH_SHA256: Force use of SHA2-256 for the internal hash ID calcs.
97
*/
98
99
#include <wolfssl/wolfcrypt/error-crypt.h>
100
#ifndef NO_RSA
101
    #include <wolfssl/wolfcrypt/rsa.h>
102
    #if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_CRYPTOCELL)
103
        extern int wc_InitRsaHw(RsaKey* key);
104
    #endif
105
#endif
106
107
#ifndef NO_ASN
108
109
#include <wolfssl/wolfcrypt/asn.h>
110
#include <wolfssl/wolfcrypt/coding.h>
111
#include <wolfssl/wolfcrypt/md2.h>
112
#include <wolfssl/wolfcrypt/hmac.h>
113
#include <wolfssl/wolfcrypt/pwdbased.h>
114
#include <wolfssl/wolfcrypt/des3.h>
115
#include <wolfssl/wolfcrypt/aes.h>
116
#include <wolfssl/wolfcrypt/rc2.h>
117
#include <wolfssl/wolfcrypt/wc_encrypt.h>
118
#include <wolfssl/wolfcrypt/logging.h>
119
120
#include <wolfssl/wolfcrypt/random.h>
121
#include <wolfssl/wolfcrypt/hash.h>
122
#ifdef NO_INLINE
123
    #include <wolfssl/wolfcrypt/misc.h>
124
#else
125
    #define WOLFSSL_MISC_INCLUDED
126
    #include <wolfcrypt/src/misc.c>
127
#endif
128
129
#ifndef NO_RC4
130
    #include <wolfssl/wolfcrypt/arc4.h>
131
#endif
132
133
#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
134
    #include <wolfssl/wolfcrypt/sha512.h>
135
#endif
136
137
#ifndef NO_SHA256
138
    #include <wolfssl/wolfcrypt/sha256.h>
139
#endif
140
141
#ifdef HAVE_ECC
142
    #include <wolfssl/wolfcrypt/ecc.h>
143
#endif
144
145
#ifdef WOLFSSL_SM2
146
    #include <wolfssl/wolfcrypt/sm2.h>
147
#endif
148
149
#ifdef HAVE_ED25519
150
    #include <wolfssl/wolfcrypt/ed25519.h>
151
#endif
152
#ifdef HAVE_CURVE25519
153
    #include <wolfssl/wolfcrypt/curve25519.h>
154
#endif
155
156
#ifdef HAVE_ED448
157
    #include <wolfssl/wolfcrypt/ed448.h>
158
#endif
159
#ifdef HAVE_CURVE448
160
    #include <wolfssl/wolfcrypt/curve448.h>
161
#endif
162
163
#ifdef HAVE_PQC
164
    #if defined(HAVE_FALCON)
165
    #include <wolfssl/wolfcrypt/falcon.h>
166
    #endif
167
    #if defined(HAVE_DILITHIUM)
168
    #include <wolfssl/wolfcrypt/dilithium.h>
169
    #endif
170
    #if defined(HAVE_SPHINCS)
171
    #include <wolfssl/wolfcrypt/sphincs.h>
172
    #endif
173
#endif
174
175
#ifdef WOLFSSL_QNX_CAAM
176
    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
177
#endif
178
179
#if defined(WOLFSSL_RENESAS_SCEPROTECT) || defined(WOLFSSL_RENESAS_TSIP_TLS)
180
    #include <wolfssl/wolfcrypt/port/Renesas/renesas_cmn.h>
181
#endif
182
183
#ifndef NO_DSA
184
    #include <wolfssl/wolfcrypt/dsa.h>
185
#else
186
    typedef void* DsaKey;
187
#endif
188
189
#ifdef WOLF_CRYPTO_CB
190
    #include <wolfssl/wolfcrypt/cryptocb.h>
191
#endif
192
193
#ifndef WOLFCRYPT_ONLY
194
    #include <wolfssl/internal.h>
195
#endif
196
197
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
198
    #include <wolfssl/openssl/objects.h>
199
#endif
200
201
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
202
        !defined(WOLFCRYPT_ONLY)
203
    #define WOLFSSL_X509_NAME_AVAILABLE
204
#endif
205
206
#ifdef _MSC_VER
207
    /* 4996 warning to use MS extensions e.g., strcpy_s instead of XSTRNCPY */
208
    #pragma warning(disable: 4996)
209
#endif
210
211
0
#define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; }
212
213
#if !defined(NO_SKID) && (!defined(HAVE_FIPS) || !defined(HAVE_FIPS_VERSION))
214
    #if !defined(HAVE_SELFTEST) || (defined(HAVE_SELFTEST) && \
215
                                   (!defined(HAVE_SELFTEST_VERSION) || \
216
                                    HAVE_SELFTEST_VERSION < 2))
217
    #ifndef WOLFSSL_AES_KEY_SIZE_ENUM
218
    #define WOLFSSL_AES_KEY_SIZE_ENUM
219
    enum Asn_Misc {
220
        AES_IV_SIZE         = 16,
221
        AES_128_KEY_SIZE    = 16,
222
        AES_192_KEY_SIZE    = 24,
223
        AES_256_KEY_SIZE    = 32
224
    };
225
    #endif
226
    #endif /* HAVE_SELFTEST */
227
#endif
228
229
#if defined(WOLFSSL_ASN_PRINT) || defined(WOLFSSL_DEBUG_ASN_TEMPLATE)
230
231
/* String representations of tags. */
232
static const char* tagString[4][32] = {
233
    /* Universal */
234
    {
235
        "EOC",
236
        "BOOLEAN",
237
        "INTEGER",
238
        "BIT STRING",
239
        "OCTET STRING",
240
        "NULL",
241
        "OBJECT ID",
242
        "ObjectDescriptor",
243
        "INSTANCE OF",
244
        "REAL",
245
        "ENUMERATED",
246
        "EMBEDDED PDV",
247
        "UT8String",
248
        "RELATIVE-OID",
249
        "(0x0e) 14",
250
        "(0x0f) 15",
251
        "SEQUENCE",
252
        "SET",
253
        "NumericString",
254
        "PrintableString",
255
        "T61String",
256
        "VideotexString",
257
        "IA5String",
258
        "UTCTime",
259
        "GeneralizedTime",
260
        "GraphicString",
261
        "ISO646String",
262
        "GeneralString",
263
        "UniversalString",
264
        "CHARACTER STRING",
265
        "BMPString",
266
        "(0x1f) 31",
267
    },
268
    /* Application */
269
    {
270
         "[A 0]",  "[A 1]",  "[A 2]",  "[A 3]",
271
         "[A 4]",  "[A 5]",  "[A 6]",  "[A 7]",
272
         "[A 8]",  "[A 9]", "[A 10]", "[A 11]",
273
        "[A 12]", "[A 13]", "[A 14]", "[A 15]",
274
        "[A 16]", "[A 17]", "[A 18]", "[A 19]",
275
        "[A 20]", "[A 21]", "[A 22]", "[A 23]",
276
        "[A 24]", "[A 25]", "[A 26]", "[A 27]",
277
        "[A 28]", "[A 20]", "[A 30]", "[A 31]"
278
    },
279
    /* Context-Specific */
280
    {
281
         "[0]",  "[1]",  "[2]",  "[3]",  "[4]",  "[5]",  "[6]",  "[7]",
282
         "[8]",  "[9]", "[10]", "[11]", "[12]", "[13]", "[14]", "[15]",
283
        "[16]", "[17]", "[18]", "[19]", "[20]", "[21]", "[22]", "[23]",
284
        "[24]", "[25]", "[26]", "[27]", "[28]", "[20]", "[30]", "[31]"
285
    },
286
    /* Private */
287
    {
288
         "[P 0]",  "[P 1]",  "[P 2]",  "[P 3]",
289
         "[P 4]",  "[P 5]",  "[P 6]",  "[P 7]",
290
         "[P 8]",  "[P 9]", "[P 10]", "[P 11]",
291
        "[P 12]", "[P 13]", "[P 14]", "[P 15]",
292
        "[P 16]", "[P 17]", "[P 18]", "[P 19]",
293
        "[P 20]", "[P 21]", "[P 22]", "[P 23]",
294
        "[P 24]", "[P 25]", "[P 26]", "[P 27]",
295
        "[P 28]", "[P 20]", "[P 30]", "[P 31]"
296
    }
297
};
298
299
/* Converts a tag byte to string.
300
 *
301
 * @param [in] tag  BER tag value to interpret.
302
 * @return  String corresponding to tag.
303
 */
304
static const char* TagString(byte tag)
305
0
{
306
0
    return tagString[tag >> 6][tag & ASN_TYPE_MASK];
307
0
}
308
309
#endif
310
311
312
/* Calculates the minimum number of bytes required to encode the value.
313
 *
314
 * Only support up to 2^24-1.
315
 *
316
 * @param [in] value  Value to be encoded.
317
 * @return  Number of bytes to encode value.
318
 */
319
static word32 BytePrecision(word32 value)
320
304
{
321
304
    word32 i;
322
903
    for (i = (word32)sizeof(value) - 1; i; --i)
323
903
        if (value >> ((i - 1) * WOLFSSL_BIT_SIZE))
324
304
            break;
325
326
304
    return i;
327
304
}
328
329
/* DER encodes the length value in output buffer.
330
 *
331
 *    0 ->  2^7-1: <len byte>.
332
 *  2^7 ->       : <0x80 + #bytes> <len big-endian bytes>
333
 *
334
 * @param [in]      length  Value to encode.
335
 * @param [in, out] output  Buffer to encode into.
336
 * @return  Number of bytes used in encoding.
337
 */
338
WOLFSSL_LOCAL word32 SetASNLength(word32 length, byte* output)
339
1.62k
{
340
1.62k
    word32 i = 0;
341
342
1.62k
    if (length < ASN_LONG_LENGTH)
343
1.52k
        output[i++] = (byte)length;
344
94
    else {
345
94
        word32 j;
346
347
94
        output[i++] = (byte)(BytePrecision(length) | ASN_LONG_LENGTH);
348
349
188
        for (j = BytePrecision(length); j; --j) {
350
94
            output[i] = (byte)(length >> ((j - 1) * WOLFSSL_BIT_SIZE));
351
94
            i++;
352
94
        }
353
94
    }
354
355
1.62k
    return i;
356
1.62k
}
357
358
#ifdef WOLFSSL_ASN_TEMPLATE
359
/* Calculate the size of a DER encoded length value.
360
 *
361
 *    0 ->  2^7-1: <length byte>.
362
 *  2^7 ->       : <0x80 + #bytes> <big-endian length bytes>
363
 *
364
 * @param [in] length  Value to encode.
365
 * @return  Number of bytes required to encode.
366
 */
367
static word32 SizeASNLength(word32 length)
368
1.68k
{
369
1.68k
    return 1 + ((length >= ASN_LONG_LENGTH) ? BytePrecision(length) : 0);
370
1.68k
}
371
372
/* Calculate the size of a DER encoded header.
373
 *
374
 * Header = Tag | Encoded length
375
 *
376
 * @param [in] length  Length value to encode.
377
 * @return  Number of bytes required to encode a DER header.
378
 */
379
#define SizeASNHeader(length) \
380
1.68k
    (1 + SizeASNLength(length))
381
#endif
382
383
#ifdef WOLFSSL_ASN_TEMPLATE
384
#ifdef WOLFSSL_SMALL_STACK
385
    /* Declare the variable that is the dynamic data for decoding BER data.
386
     *
387
     * @param [in] name  Variable name to declare.
388
     * @param [in] cnt   Number of elements required.
389
     */
390
    #define DECL_ASNGETDATA(name, cnt)                                         \
391
0
        ASNGetData* name = NULL
392
393
    /* Allocates the dynamic BER decoding data.
394
     *
395
     * @param [in]      name  Variable name to declare.
396
     * @param [in]      cnt   Number of elements required.
397
     * @param [in, out] err   Error variable.
398
     * @param [in]      heap  Dynamic memory allocation hint.
399
     */
400
    #define ALLOC_ASNGETDATA(name, cnt, err, heap)                             \
401
0
    do {                                                                       \
402
0
        if ((err) == 0) {                                                      \
403
0
            (name) = (ASNGetData*)XMALLOC(sizeof(ASNGetData) * (cnt), (heap),  \
404
0
                                        DYNAMIC_TYPE_TMP_BUFFER);              \
405
0
            if ((name) == NULL) {                                              \
406
0
                (err) = MEMORY_E;                                              \
407
0
            }                                                                  \
408
0
        }                                                                      \
409
0
    }                                                                          \
410
0
    while (0)
411
412
    /* Allocates the dynamic BER decoding data and clears the memory.
413
     *
414
     * @param [in]      name  Variable name to declare.
415
     * @param [in]      cnt   Number of elements required.
416
     * @param [in, out] err   Error variable.
417
     * @param [in]      heap  Dynamic memory allocation hint.
418
     */
419
    #define CALLOC_ASNGETDATA(name, cnt, err, heap)                            \
420
0
    do {                                                                       \
421
0
        ALLOC_ASNGETDATA(name, cnt, err, heap);                                \
422
0
        if ((err) == 0) {                                                      \
423
0
            XMEMSET((name), 0, sizeof(ASNGetData) * (cnt));                    \
424
0
        }                                                                      \
425
0
    }                                                                          \
426
0
    while (0)
427
428
    /* Disposes of the dynamic BER decoding data.
429
     *
430
     * @param [in]      name  Variable name to declare.
431
     * @param [in]      heap  Dynamic memory allocation hint.
432
     */
433
    #define FREE_ASNGETDATA(name, heap)                                        \
434
0
    do {                                                                       \
435
0
        if ((name) != NULL) {                                                  \
436
0
            XFREE((name), (heap), DYNAMIC_TYPE_TMP_BUFFER);                    \
437
0
        }                                                                      \
438
0
    }                                                                          \
439
0
    while (0)
440
441
    /* Declare the variable that is the dynamic data for encoding DER data.
442
     *
443
     * @param [in] name  Variable name to declare.
444
     * @param [in] cnt   Number of elements required.
445
     */
446
    #define DECL_ASNSETDATA(name, cnt)                                         \
447
0
        ASNSetData* name = NULL
448
449
    /* Allocates the dynamic DER encoding data.
450
     *
451
     * @param [in]      name  Variable name to declare.
452
     * @param [in]      cnt   Number of elements required.
453
     * @param [in, out] err   Error variable.
454
     * @param [in]      heap  Dynamic memory allocation hint.
455
     */
456
    #define ALLOC_ASNSETDATA(name, cnt, err, heap)                             \
457
0
    do {                                                                       \
458
0
        if ((err) == 0) {                                                      \
459
0
            (name) = (ASNSetData*)XMALLOC(sizeof(ASNGetData) * (cnt), (heap),  \
460
0
                                    DYNAMIC_TYPE_TMP_BUFFER);                  \
461
0
            if ((name) == NULL) {                                              \
462
0
                (err) = MEMORY_E;                                              \
463
0
            }                                                                  \
464
0
        }                                                                      \
465
0
    }                                                                          \
466
0
    while (0)
467
468
    /* Allocates the dynamic DER encoding data and clears the memory.
469
     *
470
     * @param [in]      name  Variable name to declare.
471
     * @param [in]      cnt   Number of elements required.
472
     * @param [in, out] err   Error variable.
473
     * @param [in]      heap  Dynamic memory allocation hint.
474
     */
475
    #define CALLOC_ASNSETDATA(name, cnt, err, heap)                            \
476
0
    do {                                                                       \
477
0
        ALLOC_ASNSETDATA(name, cnt, err, heap);                                \
478
0
        if ((err) == 0) {                                                      \
479
0
            XMEMSET(name, 0, sizeof(ASNSetData) * (cnt));                      \
480
0
        }                                                                      \
481
0
    }                                                                          \
482
0
    while (0)
483
484
    /* Disposes of the dynamic DER encoding data.
485
     *
486
     * @param [in]      name  Variable name to declare.
487
     * @param [in]      heap  Dynamic memory allocation hint.
488
     */
489
    #define FREE_ASNSETDATA(name, heap)                                        \
490
0
    do {                                                                       \
491
0
        if ((name) != NULL) {                                                  \
492
0
            XFREE(name, heap, DYNAMIC_TYPE_TMP_BUFFER);                        \
493
0
        }                                                                      \
494
0
    }                                                                          \
495
0
    while (0)
496
#else
497
    /* Declare the variable that is the dynamic data for decoding BER data.
498
     *
499
     * @param [in] name  Variable name to declare.
500
     * @param [in] cnt   Number of elements required.
501
     */
502
    #define DECL_ASNGETDATA(name, cnt)                  \
503
        ASNGetData name[cnt]
504
505
    /* No implementation as declaration is static.
506
     *
507
     * @param [in]      name  Variable name to declare.
508
     * @param [in]      cnt   Number of elements required.
509
     * @param [in, out] err   Error variable.
510
     * @param [in]      heap  Dynamic memory allocation hint.
511
     */
512
    #define ALLOC_ASNGETDATA(name, cnt, err, heap)
513
514
    /* Clears the memory of the dynamic BER encoding data.
515
     *
516
     * @param [in]      name  Variable name to declare.
517
     * @param [in]      cnt   Number of elements required.
518
     * @param [in, out] err   Error variable.
519
     * @param [in]      heap  Dynamic memory allocation hint.
520
     */
521
    #define CALLOC_ASNGETDATA(name, cnt, err, heap)     \
522
        XMEMSET(name, 0, sizeof(name))
523
524
    /* No implementation as declaration is static.
525
     *
526
     * @param [in]      name  Variable name to declare.
527
     * @param [in]      heap  Dynamic memory allocation hint.
528
     */
529
    #define FREE_ASNGETDATA(name, heap)
530
531
    /* Declare the variable that is the dynamic data for encoding DER data.
532
     *
533
     * @param [in] name  Variable name to declare.
534
     * @param [in] cnt   Number of elements required.
535
     */
536
    #define DECL_ASNSETDATA(name, cnt)                  \
537
        ASNSetData name[cnt]
538
539
    /* No implementation as declaration is static.
540
     *
541
     * @param [in]      name  Variable name to declare.
542
     * @param [in]      cnt   Number of elements required.
543
     * @param [in, out] err   Error variable.
544
     * @param [in]      heap  Dynamic memory allocation hint.
545
     */
546
    #define ALLOC_ASNSETDATA(name, cnt, err, heap)
547
548
    /* Clears the memory of the dynamic BER encoding data.
549
     *
550
     * @param [in]      name  Variable name to declare.
551
     * @param [in]      cnt   Number of elements required.
552
     * @param [in, out] err   Error variable.
553
     * @param [in]      heap  Dynamic memory allocation hint.
554
     */
555
    #define CALLOC_ASNSETDATA(name, cnt, err, heap)     \
556
        XMEMSET(name, 0, sizeof(name))
557
558
    /* No implementation as declaration is static.
559
     *
560
     * @param [in]      name  Variable name to declare.
561
     * @param [in]      heap  Dynamic memory allocation hint.
562
     */
563
    #define FREE_ASNSETDATA(name, heap)
564
#endif
565
566
567
#ifdef DEBUG_WOLFSSL
568
    /* Enable this when debugging the parsing or creation of ASN.1 data. */
569
    #if 0
570
        #define WOLFSSL_DEBUG_ASN_TEMPLATE
571
    #endif
572
#endif
573
574
#ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
575
576
#include <stdarg.h>
577
578
/* Log a message that has the printf format string.
579
 *
580
 * @param [in] <va_args>  printf style arguments.
581
 */
582
#define WOLFSSL_MSG_VSNPRINTF(...)                    \
583
    do {                                              \
584
      char line[81];                                  \
585
      snprintf(line, sizeof(line) - 1, __VA_ARGS__);  \
586
      line[sizeof(line) - 1] = '\0';                  \
587
      WOLFSSL_MSG(line);                              \
588
    }                                                 \
589
    while (0)
590
#endif
591
592
/* Returns whether ASN.1 item is an integer and the Most-Significant Bit is set.
593
 *
594
 * @param [in] asn     ASN.1 items to encode.
595
 * @param [in] data_a  Data to place in each item. Lengths set were not known.
596
 * @param [in] i       Index of item to check.
597
 * @return  1 when ASN.1 item is an integer and MSB is 1.
598
 * @erturn  0 otherwise.
599
 */
600
#define ASNIntMSBSet(asn, data_a, i)                  \
601
1.64k
    (((asn)[i].tag == ASN_INTEGER) &&                 \
602
1.64k
      ((data_a)[i].data.buffer.data != NULL &&        \
603
0
      ((data_a)[i].data.buffer.data[0] & 0x80) == 0x80))
604
605
606
/* Calculate the size of a DER encoded number.
607
 *
608
 * @param [in] n     Number to be encoded.
609
 * @param [in] bits  Maximum number of bits to encode.
610
 * @param [in] tag   BER tag e.g. INTEGER, BIT_STRING, etc.
611
 * @return  Number of bytes to the ASN.1 item.
612
 */
613
static word32 SizeASN_Num(word32 n, int bits, byte tag)
614
0
{
615
0
    int    j;
616
0
    word32 len;
617
618
0
    len = 1 + 1 + (word32)bits / 8;
619
    /* Discover actual size by checking for high zeros. */
620
0
    for (j = bits - 8; j > 0; j -= 8) {
621
0
        if (n >> j)
622
0
            break;
623
0
        len--;
624
0
    }
625
0
    if (tag == ASN_BIT_STRING)
626
0
        len++;
627
0
    else if ((tag == ASN_INTEGER) && (((n >> j) & 0x80) == 0x80))
628
0
        len++;
629
630
0
    return len;
631
0
}
632
633
/* Calculate the size of the data in the constructed item based on the
634
 * length of the ASN.1 items below.
635
 *
636
 * @param [in]      asn    ASN.1 items to encode.
637
 * @param [in, out] data   Data to place in each item. Lengths set were not
638
 *                         known.
639
 * @param [in]      idx    Index of item working on.
640
 */
641
static void SizeASN_CalcDataLength(const ASNItem* asn, ASNSetData *data,
642
                                   int idx, int max)
643
562
{
644
562
    int j;
645
646
562
    data[idx].data.buffer.length = 0;
647
    /* Sum the item length of all items underneath. */
648
1.68k
    for (j = idx + 1; j < max; j++) {
649
        /* Stop looking if the next ASN.1 is same level or higher. */
650
1.12k
        if (asn[j].depth <= asn[idx].depth)
651
0
            break;
652
        /* Only add in length if it is one level below. */
653
1.12k
        if (asn[j].depth - 1 == asn[idx].depth) {
654
1.12k
            data[idx].data.buffer.length += data[j].length;
655
            /* The length of a header only item doesn't include the data unless
656
             * a replacement buffer is supplied.
657
             */
658
1.12k
            if (asn[j].headerOnly && data[j].data.buffer.data == NULL &&
659
1.12k
                    data[j].dataType != ASN_DATA_TYPE_REPLACE_BUFFER) {
660
0
                data[idx].data.buffer.length += data[j].data.buffer.length;
661
0
            }
662
1.12k
        }
663
1.12k
    }
664
562
}
665
666
/* Calculate the size of the DER encoding.
667
 *
668
 * Call SetASN_Items() to write encoding to a buffer.
669
 *
670
 * @param [in]      asn    ASN.1 items to encode.
671
 * @param [in, out] data   Data to place in each item. Lengths set where not
672
 *                         known.
673
 * @param [in]      count  Count of items to encode.
674
 * @param [out]     encSz  Length of the DER encoding.
675
 * @return  0 on success.
676
 * @return  BAD_STATE_E when the data type is not supported.
677
 */
678
int SizeASN_Items(const ASNItem* asn, ASNSetData *data, int count, int* encSz)
679
562
{
680
562
    int    i;
681
562
    word32 sz = 0;
682
562
    word32 len;
683
562
    word32 dataLen;
684
562
    int    length;
685
686
#ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
687
    WOLFSSL_ENTER("SizeASN_Items");
688
#endif
689
690
2.24k
    for (i = count - 1; i >= 0; i--) {
691
        /* Skip this ASN.1 item when encoding. */
692
1.68k
        if (data[i].noOut) {
693
            /* Set the offset to the current size - used in writing DER. */
694
0
            data[i].offset = sz;
695
0
            continue;
696
0
        }
697
698
1.68k
        len = 0;
699
1.68k
        switch (data[i].dataType) {
700
            /* Calculate the size of the number of different sizes. */
701
0
            case ASN_DATA_TYPE_WORD8:
702
0
                len = SizeASN_Num(data[i].data.u8, 8, asn[i].tag);
703
0
                break;
704
0
            case ASN_DATA_TYPE_WORD16:
705
0
                len = SizeASN_Num(data[i].data.u16, 16, asn[i].tag);
706
0
                break;
707
        #ifdef WOLFSSL_ASN_TEMPLATE_NEED_SET_INT32
708
            /* Not used yet! */
709
            case ASN_DATA_TYPE_WORD32:
710
                len = SizeASN_Num(data[i].data.u32, 32, asn[i].tag);
711
                break;
712
        #endif
713
714
1.12k
            case ASN_DATA_TYPE_MP:
715
                /* Calculate the size of the MP integer data. */
716
1.12k
                length = mp_unsigned_bin_size(data[i].data.mp);
717
1.12k
                length += mp_leading_bit(data[i].data.mp) ? 1 : 0;
718
1.12k
                len = (word32)SizeASNHeader((word32)length) + (word32)length;
719
1.12k
                break;
720
721
0
            case ASN_DATA_TYPE_REPLACE_BUFFER:
722
                /* Buffer is put in directly - use the length. */
723
0
                len = data[i].data.buffer.length;
724
0
                break;
725
726
562
            case ASN_DATA_TYPE_NONE:
727
                /* Calculate the size based on the data to be included.
728
                 * Mostly used for constructed items.
729
                 */
730
562
                if (asn[i].headerOnly) {
731
562
                    if (data[i].data.buffer.data != NULL) {
732
                        /* Force all child nodes to be ignored. Buffer
733
                         * overwrites children. */
734
0
                        {
735
0
                            int ii;
736
0
                            for (ii = i + 1; ii < count; ii++) {
737
0
                                if (asn[ii].depth <= asn[i].depth)
738
0
                                    break;
739
0
                                sz -= data[ii].length;
740
0
                                data[ii].noOut = 1;
741
0
                            }
742
0
                        }
743
0
                    }
744
562
                    else {
745
                        /* Calculate data length from items below if no buffer
746
                         * supplied. */
747
562
                        SizeASN_CalcDataLength(asn, data, i, count);
748
562
                    }
749
562
                }
750
562
                if (asn[i].tag == ASN_BOOLEAN) {
751
0
                    dataLen = 1;
752
0
                }
753
562
                else {
754
562
                    dataLen = data[i].data.buffer.length;
755
562
                }
756
                /* BIT_STRING and INTEGER have one byte prepended. */
757
562
                if ((asn[i].tag == ASN_BIT_STRING) ||
758
562
                                                   ASNIntMSBSet(asn, data, i)) {
759
0
                    dataLen++;
760
                    /* ASN.1 items are below and cannot include extra byte. */
761
0
                    if (asn[i].headerOnly) {
762
0
                        len++;
763
0
                    }
764
0
                }
765
                /* Add in the size of tag and length. */
766
562
                len += SizeASNHeader(dataLen);
767
                /* Include data in length if not header only or if
768
                 * buffer supplied. */
769
562
                if (!asn[i].headerOnly || data[i].data.buffer.data != NULL) {
770
0
                    len += dataLen;
771
0
                }
772
562
                break;
773
774
        #ifdef DEBUG_WOLFSSL
775
            default:
776
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
777
                WOLFSSL_MSG_VSNPRINTF("%2d: %d", i, data[i].dataType);
778
                WOLFSSL_MSG("Bad data type");
779
            #endif
780
                return BAD_STATE_E;
781
        #endif
782
1.68k
        }
783
784
        /* Set the total length of the item. */
785
1.68k
        data[i].length = len;
786
        /* Add length to total size. */
787
1.68k
        sz += len;
788
        /* Set the offset to the current size - used in writing DER. */
789
1.68k
        data[i].offset = sz;
790
791
    #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
792
        WOLFSSL_MSG_VSNPRINTF("%2d: %4d %4d %c %*s %-16s", i,
793
                data[i].offset, data[i].length, asn[i].constructed ? '+' : ' ',
794
                asn[i].depth, "", TagString(asn[i].tag));
795
    #endif
796
1.68k
    }
797
798
562
    *encSz = (int)sz;
799
562
    return 0;
800
562
}
801
802
/* Create the DER encoding of a number.
803
 *
804
 * Assumes that the out buffer is large enough for encoding.
805
 *
806
 * @param [in] n     Number to be encoded.
807
 * @param [in] bits  Maximum number of bits to encode.
808
 * @param [in] tag   DER tag e.g. INTEGER, BIT_STRING, etc.
809
 */
810
static void SetASN_Num(word32 n, int bits, byte* out, byte tag)
811
0
{
812
0
    int    j;
813
0
    word32 idx;
814
0
    byte   len;
815
816
    /* Encoding: Tag (1 byte) | Length (1 byte) | Data (number) */
817
818
    /* Data will start at index 2 unless BIT_STRING or INTEGER */
819
0
    idx = 2;
820
821
    /* Set the length of the number based on maximum bit length. */
822
0
    len = (byte)(bits / 8);
823
    /* Discover actual size by checking for leading zero bytes. */
824
0
    for (j = bits - 8; j > 0; j -= 8) {
825
0
        if ((n >> j) != 0) {
826
0
            break;
827
0
        }
828
0
        len--;
829
0
    }
830
    /* Keep j, index of first non-zero byte, for writing out. */
831
832
    /* A BIT_STRING has the number of unused bits in last byte prepended to
833
     * data.
834
     */
835
0
    if (tag == ASN_BIT_STRING) {
836
0
        byte unusedBits = 0;
837
0
        byte lastByte = (byte)(n >> j);
838
839
        /* Quick check last bit. */
840
0
        if ((lastByte & 0x01) == 0x00) {
841
0
            unusedBits++;
842
            /* Check each bit for first least significant bit set. */
843
0
            while (((lastByte >> unusedBits) & 0x01) == 0x00)
844
0
                unusedBits++;
845
0
        }
846
        /* Add unused bits byte. */
847
0
        len++;
848
0
        out[idx++] = unusedBits;
849
0
    }
850
851
    /* An INTEGER has a prepended byte if MSB of number is 1 - makes encoded
852
     * value positive. */
853
0
    if ((tag == ASN_INTEGER) && (((n >> j) & 0x80) == 0x80)) {
854
0
        len++;
855
0
        out[idx++] = 0;
856
0
    }
857
858
    /* Go back and put in length. */
859
0
    out[1] = len;
860
    /* Place in the required bytes of the number. */
861
0
    for (; j >= 0; j -= 8)
862
0
        out[idx++] = (byte)(n >> j);
863
0
}
864
865
/* Creates the DER encoding of the ASN.1 items.
866
 *
867
 * Assumes the output buffer is large enough to hold encoding.
868
 * Must call SizeASN_Items() to determine size of encoding and offsets.
869
 *
870
 * @param [in]      asn     ASN.1 items to encode.
871
 * @param [in]      data    Data to place in each item.
872
 * @param [in]      count   Count of items to encode.
873
 * @param [in, out] output  Buffer to write encoding into.
874
 * @return  Size of the DER encoding in bytes.
875
 */
876
int SetASN_Items(const ASNItem* asn, ASNSetData *data, int count, byte* output)
877
541
{
878
541
    int    i;
879
541
    int    length;
880
541
    int    err;
881
541
    word32 sz;
882
541
    word32 idx;
883
541
    byte*  out;
884
885
#ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
886
    WOLFSSL_ENTER("SetASN_Items");
887
#endif
888
889
    /* Offset of first item is the total length.
890
     * SizeASN_Items() calculated this. */
891
541
    sz = data[0].offset;
892
893
    /* Write out each item. */
894
2.16k
    for (i = 0; i < count; i++) {
895
        /* Skip items not writing out. */
896
1.62k
        if (data[i].noOut)
897
0
            continue;
898
899
        /* Start position to write item based on reverse offsets. */
900
1.62k
        out = output + sz - data[i].offset;
901
        /* Index from start of item out. */
902
1.62k
        idx = 0;
903
904
1.62k
        if (data[i].dataType != ASN_DATA_TYPE_REPLACE_BUFFER) {
905
            /* Put in the tag - not dumping in DER from buffer. */
906
1.62k
            out[idx++] = asn[i].tag |
907
1.62k
                         (asn[i].constructed ? ASN_CONSTRUCTED : 0);
908
1.62k
        }
909
910
    #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
911
        WOLFSSL_MSG_VSNPRINTF("%2d: %4d %4d %c %*s %-16s", i,
912
                sz - data[i].offset,
913
                data[i].length, asn[i].constructed ? '+' : ' ', asn[i].depth,
914
                "", TagString(asn[i].tag));
915
    #endif
916
917
1.62k
        switch (data[i].dataType) {
918
            /* Write out the length and data of a number. */
919
0
            case ASN_DATA_TYPE_WORD8:
920
0
                SetASN_Num(data[i].data.u8, 8, out, asn[i].tag);
921
0
                break;
922
0
            case ASN_DATA_TYPE_WORD16:
923
0
                SetASN_Num(data[i].data.u16, 16, out, asn[i].tag);
924
0
                break;
925
        #ifdef WOLFSSL_ASN_TEMPLATE_NEED_SET_INT32
926
            /* Not used yet! */
927
            case ASN_DATA_TYPE_WORD32:
928
                SetASN_Num(data[i].data.u32, 32, out, asn[i].tag);
929
                break;
930
        #endif
931
932
            /* Write out the length and data of a multi-precision number. */
933
1.08k
            case ASN_DATA_TYPE_MP:
934
                /* Get length in bytes. */
935
1.08k
                length = mp_unsigned_bin_size(data[i].data.mp);
936
                /* Add one for leading zero to make encoding a positive num. */
937
1.08k
                length += mp_leading_bit(data[i].data.mp) ? 1 : 0;
938
                /* Write out length. */
939
1.08k
                idx += SetASNLength((word32)length, out + idx);
940
                /* Write out leading zero to make positive. */
941
1.08k
                if (mp_leading_bit(data[i].data.mp)) {
942
416
                    out[idx++] = 0;
943
416
                }
944
                /* Encode number in big-endian byte array. */
945
1.08k
                err = mp_to_unsigned_bin(data[i].data.mp, out + idx);
946
1.08k
                if (err != MP_OKAY) {
947
0
                    WOLFSSL_MSG("SetASN_Items: Failed to write mp_int");
948
0
                    return MP_TO_E;
949
0
                }
950
1.08k
                break;
951
952
1.08k
            case ASN_DATA_TYPE_REPLACE_BUFFER:
953
0
                if (data[i].data.buffer.data == NULL) {
954
                    /* Return pointer for caller to use. */
955
0
                    data[i].data.buffer.data = out + idx;
956
0
                }
957
0
                else {
958
                    /* Dump in the DER encoded data. */
959
0
                    XMEMCPY(out + idx, data[i].data.buffer.data,
960
0
                            data[i].data.buffer.length);
961
0
                }
962
0
                break;
963
964
541
            case ASN_DATA_TYPE_NONE:
965
541
                if (asn[i].tag == ASN_BOOLEAN) {
966
                    /* Always one byte of data. */
967
0
                    out[idx++] = 1;
968
                    /* TRUE = 0xff, FALSE = 0x00 */
969
0
                    out[idx] = data[i].data.u8 ? 0xffU : 0x00U;
970
0
                }
971
541
                else if (asn[i].tag == ASN_TAG_NULL) {
972
                    /* NULL tag is always a zero length item. */
973
0
                    out[idx] = 0;
974
0
                }
975
541
                else {
976
541
                    word32 dataLen = data[i].data.buffer.length;
977
                    /* Add one to data length for BIT_STRING unused bits and
978
                     * INTEGER leading zero to make positive.
979
                     */
980
541
                    if ((asn[i].tag == ASN_BIT_STRING) ||
981
541
                                                   ASNIntMSBSet(asn, data, i)) {
982
0
                        dataLen++;
983
0
                    }
984
                    /* Write out length. */
985
541
                    idx += SetASNLength(dataLen, out + idx);
986
541
                    if ((asn[i].tag == ASN_BIT_STRING) ||
987
541
                                                   ASNIntMSBSet(asn, data, i)) {
988
                       /* Write out leading byte. BIT_STRING has no unused bits
989
                        * - use number data types if needed. */
990
0
                        out[idx++] = 0x00;
991
0
                    }
992
                    /* Record pointer for caller if data not supplied. */
993
541
                    if (data[i].data.buffer.data == NULL) {
994
541
                        data[i].data.buffer.data = out + idx;
995
541
                    }
996
                    /* Copy supplied data if not putting out header only or
997
                     * if buffer supplied. */
998
0
                    else if (!asn[i].headerOnly ||
999
0
                            data[i].data.buffer.data != NULL) {
1000
                        /* Allow data to come from output buffer. */
1001
0
                        XMEMMOVE(out + idx, data[i].data.buffer.data,
1002
0
                                 data[i].data.buffer.length);
1003
0
                    }
1004
541
                }
1005
541
                break;
1006
1007
        #ifdef DEBUG_WOLFSSL
1008
            default:
1009
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1010
                WOLFSSL_MSG_VSNPRINTF("Bad data type: %d", data[i].dataType);
1011
            #endif
1012
                return BAD_STATE_E;
1013
        #endif
1014
1.62k
        }
1015
1.62k
    }
1016
1017
541
    return (int)sz;
1018
541
}
1019
1020
1021
static int GetOID(const byte* input, word32* inOutIdx, word32* oid,
1022
                  word32 oidType, int length);
1023
1024
/* Maximum supported depth in ASN.1 description. */
1025
#define GET_ASN_MAX_DEPTH          7
1026
/* Maximum number of checked numbered choices. Only one of the items with the
1027
 * number is allowed.
1028
 */
1029
2.29k
#define GET_ASN_MAX_CHOICES        2
1030
1031
/* Use existing function to decode BER length encoding. */
1032
2.30k
#define GetASN_Length GetLength_ex
1033
1034
/* Check an INTEGER's first byte - must be a positive number.
1035
 *
1036
 * @param [in] input    BER encoded data.
1037
 * @param [in] idx      Index of BIT_STRING data.
1038
 * @param [in] length   Length of input data.
1039
 * @param [in] positive Indicates number must be positive.
1040
 * @return  0 on success.
1041
 * @return  ASN_PARSE_E when 0 is not required but seen.
1042
 * @return  ASN_EXPECT_0_E when 0 is required and not seen.
1043
 */
1044
static int GetASN_Integer(const byte* input, word32 idx, int length,
1045
                          int positive)
1046
1.53k
{
1047
1.53k
#if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) || \
1048
1.53k
    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
1049
    /* Check contents consist of one or more octets. */
1050
1.53k
    if (length == 0) {
1051
0
        WOLFSSL_MSG("Zero length INTEGER not allowed");
1052
0
        return ASN_PARSE_E;
1053
0
    }
1054
1.53k
#endif
1055
1.53k
    if (input[idx] == 0) {
1056
        /* Check leading zero byte required. */
1057
602
        if ((length > 1) && ((input[idx + 1] & 0x80) == 0)) {
1058
0
            WOLFSSL_MSG("Zero not required on INTEGER");
1059
0
        #ifndef WOLFSSL_ASN_INT_LEAD_0_ANY
1060
0
            return ASN_PARSE_E;
1061
0
        #endif
1062
0
        }
1063
602
    }
1064
    /* Check whether a leading zero byte was required. */
1065
935
    else if (positive && (input[idx] & 0x80)) {
1066
0
        WOLFSSL_MSG("INTEGER is negative");
1067
0
    #ifndef WOLFSSL_ASN_INT_LEAD_0_ANY
1068
0
        return ASN_EXPECT_0_E;
1069
0
    #endif /* WOLFSSL_ASN_INT_LEAD_0_ANY */
1070
0
    }
1071
1072
1.53k
    return 0;
1073
1.53k
}
1074
1075
/* Check a BIT_STRING's first byte - unused bits.
1076
 *
1077
 * @param [in] input   BER encoded data.
1078
 * @param [in] idx     Index of BIT_STRING data.
1079
 * @param [in] length  Length of input data.
1080
 * @return  0 on success.
1081
 * @return  ASN_PARSE_E when unused bits is invalid.
1082
 */
1083
static int GetASN_BitString(const byte* input, word32 idx, int length)
1084
0
{
1085
0
#if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) || \
1086
0
    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
1087
    /* Check contents consist of one or more octets. */
1088
0
    if (length == 0) {
1089
    #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1090
        WOLFSSL_MSG("Zero length BIT STRING not allowed");
1091
    #endif
1092
0
        return ASN_PARSE_E;
1093
0
    }
1094
0
#endif
1095
    /* Ensure unused bits value is valid range. */
1096
0
    if (input[idx] > 7) {
1097
    #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1098
        WOLFSSL_MSG_VSNPRINTF("BIT STRING unused bits too big: %d > 7",
1099
                input[idx]);
1100
    #endif
1101
0
        return ASN_PARSE_E;
1102
0
    }
1103
    /* Ensure unused bits are zero. */
1104
0
    if ((byte)(input[idx + (word32)length - 1] << (8 - input[idx])) != 0) {
1105
    #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1106
        WOLFSSL_MSG_VSNPRINTF("BIT STRING unused bits used: %d %02x",
1107
                input[idx], input[idx + length - 1]);
1108
    #endif
1109
0
        return ASN_PARSE_E;
1110
0
    }
1111
1112
0
    return 0;
1113
0
}
1114
1115
/* Get the ASN.1 items from the BER encoding.
1116
 *
1117
 * @param [in] asn         ASN.1 item expected.
1118
 * @param [in] data        Data array to place found item into.
1119
 * @param [in] input       BER encoded data.
1120
 * @param [in] idx         Starting index of item data.
1121
 * @param [in] len         Length of input buffer upto end of this item's data.
1122
 * @param [in] zeroPadded  INTEGER was zero padded to make positive.
1123
 * @return  0 on success.
1124
 * @return  ASN_PARSE_E when BER encoded data is invalid.
1125
 * @return  ASN_EXPECT_0_E when NULL tagged item has a non-zero length.
1126
 * @return  MP_INIT_E when the unable to initialize an mp_int.
1127
 * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
1128
 * @return  BAD_STATE_E when the data type is not supported.
1129
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
1130
 */
1131
static int GetASN_StoreData(const ASNItem* asn, ASNGetData* data,
1132
                            const byte* input, word32 idx, int len,
1133
                            int zeroPadded)
1134
1.53k
{
1135
1.53k
    int i;
1136
1.53k
    int err;
1137
1138
    /* Parse data based on data type to extract. */
1139
1.53k
    switch (data->dataType) {
1140
        /* Parse a data into a number of specified bits. */
1141
0
        case ASN_DATA_TYPE_WORD8:
1142
            /* Check data is small enough to fit. */
1143
0
            if (len != 1) {
1144
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1145
                WOLFSSL_MSG_VSNPRINTF("Expecting one byte: %d", len);
1146
            #endif
1147
0
                return ASN_PARSE_E;
1148
0
            }
1149
            /* Fill number with all of data. */
1150
0
            *data->data.u8 = input[idx];
1151
0
            break;
1152
0
        case ASN_DATA_TYPE_WORD16:
1153
            /* Check data is small enough to fit. */
1154
0
            if (len == 0 || len > 2) {
1155
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1156
                WOLFSSL_MSG_VSNPRINTF("Expecting 1 or 2 bytes: %d", len);
1157
            #endif
1158
0
                return ASN_PARSE_E;
1159
0
            }
1160
            /* Fill number with all of data. */
1161
0
            *data->data.u16 = 0;
1162
0
            for (i = 0; i < len; i++) {
1163
0
                *data->data.u16 <<= 8;
1164
0
                *data->data.u16 |= input[idx + (word32)i] ;
1165
0
            }
1166
0
            break;
1167
0
        case ASN_DATA_TYPE_WORD32:
1168
            /* Check data is small enough to fit. */
1169
0
            if (len == 0 || len > 4) {
1170
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1171
                WOLFSSL_MSG_VSNPRINTF("Expecting 1 to 4 bytes: %d", len);
1172
            #endif
1173
0
                return ASN_PARSE_E;
1174
0
            }
1175
            /* Fill number with all of data. */
1176
0
            *data->data.u32 = 0;
1177
0
            for (i = 0; i < len; i++) {
1178
0
                *data->data.u32 <<= 8;
1179
0
                *data->data.u32 |= input[idx + (word32)i] ;
1180
0
            }
1181
0
            break;
1182
1183
0
        case ASN_DATA_TYPE_BUFFER:
1184
            /* Check buffer is big enough to hold data. */
1185
0
            if (len > (int)*data->data.buffer.length) {
1186
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1187
                WOLFSSL_MSG_VSNPRINTF("Buffer too small for data: %d %d", len,
1188
                        *data->data.buffer.length);
1189
            #endif
1190
0
                return ASN_PARSE_E;
1191
0
            }
1192
            /* Copy in data and record actual length seen. */
1193
0
            XMEMCPY(data->data.buffer.data, input + idx, (size_t)len);
1194
0
            *data->data.buffer.length = (word32)len;
1195
0
            break;
1196
1197
0
        case ASN_DATA_TYPE_EXP_BUFFER:
1198
            /* Check data is same size expected. */
1199
0
            if (len != (int)data->data.ref.length) {
1200
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1201
                WOLFSSL_MSG_VSNPRINTF("Data not expected length: %d %d", len,
1202
                        data->data.ref.length);
1203
            #endif
1204
0
                return ASN_PARSE_E;
1205
0
            }
1206
            /* Check data is same as expected. */
1207
0
            if (XMEMCMP(data->data.ref.data, input + idx, (size_t)len) != 0) {
1208
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1209
                WOLFSSL_MSG("Data not as expected");
1210
            #endif
1211
0
                return ASN_PARSE_E;
1212
0
            }
1213
0
            break;
1214
1215
480
        case ASN_DATA_TYPE_MP:
1216
480
        case ASN_DATA_TYPE_MP_POS_NEG:
1217
            /* Initialize mp_int and read in big-endian byte array. */
1218
480
            if (mp_init(data->data.mp) != MP_OKAY) {
1219
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1220
                WOLFSSL_MSG_VSNPRINTF("Failed to init mp: %p", data->data.mp);
1221
            #endif
1222
0
                return MP_INIT_E;
1223
0
            }
1224
480
            FALL_THROUGH;
1225
1.53k
        case ASN_DATA_TYPE_MP_INITED:
1226
1.53k
            err = mp_read_unsigned_bin(data->data.mp, (byte*)input + idx,
1227
1.53k
                                       (word32)len);
1228
1.53k
            if (err != 0) {
1229
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1230
                WOLFSSL_MSG_VSNPRINTF("Failed to read mp: %d", err);
1231
            #endif
1232
3
                mp_clear(data->data.mp);
1233
3
                return ASN_GETINT_E;
1234
3
            }
1235
        #ifdef HAVE_WOLF_BIGINT
1236
            err = wc_bigint_from_unsigned_bin(&data->data.mp->raw, input + idx,
1237
                    len);
1238
            if (err != 0) {
1239
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1240
                WOLFSSL_MSG_VSNPRINTF("Failed to create bigint: %d", err);
1241
            #endif
1242
                mp_clear(data->data.mp);
1243
                return ASN_GETINT_E;
1244
            }
1245
        #endif /* HAVE_WOLF_BIGINT */
1246
1247
1.53k
        #ifdef WOLFSSL_SP_INT_NEGATIVE
1248
            /* Don't always read as positive. */
1249
1.53k
            if ((data->dataType == ASN_DATA_TYPE_MP_POS_NEG) && (!zeroPadded) &&
1250
1.53k
                (input[idx] & 0x80)) {
1251
0
                #ifdef MP_NEG
1252
0
                    data->data.mp->sign = MP_NEG;
1253
                #else
1254
                    #ifdef OPENSSL_EXTRA
1255
                        /* public API wolfSSL_ASN1_INTEGER_get() depends
1256
                         * indirectly on negative bignum handling here.
1257
                         */
1258
                        #error OPENSSL_EXTRA requires negative bignum support.
1259
                    #endif
1260
                    #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1261
                    WOLFSSL_MSG_VSNPRINTF("ASN negative integer without bignum support.");
1262
                    #endif
1263
                    mp_clear(data->data.mp);
1264
                    return ASN_GETINT_E;
1265
                #endif
1266
0
            }
1267
        #else
1268
            (void)zeroPadded;
1269
        #endif
1270
1.53k
            break;
1271
1272
0
        case ASN_DATA_TYPE_CHOICE:
1273
            /* Check if tag matched any of the choices specified. */
1274
0
            for (i = 0; data->data.choice[i] != 0; i++)
1275
0
                if (data->data.choice[i] == data->tag)
1276
0
                    break;
1277
0
            if (data->data.choice[i] == 0) {
1278
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1279
                WOLFSSL_MSG("Tag didn't match a choice");
1280
            #endif
1281
0
                return ASN_PARSE_E;
1282
0
            }
1283
1284
            /* Store data pointer and length for caller. */
1285
0
            data->data.ref.data = input + idx;
1286
0
            data->data.ref.length = (word32)len;
1287
0
            break;
1288
1289
0
        case ASN_DATA_TYPE_NONE:
1290
            /* Default behaviour based on tag. */
1291
0
            if (asn->tag == ASN_BOOLEAN) {
1292
                /* BOOLEAN has only one byte of data in BER. */
1293
0
                if (len != 1) {
1294
                #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1295
                    WOLFSSL_MSG_VSNPRINTF("BOOLEAN length too long: %d", len);
1296
                #endif
1297
0
                    return ASN_PARSE_E;
1298
0
                }
1299
0
                if (data->data.u8 == NULL)
1300
0
                    return BAD_STATE_E;
1301
                /* Store C boolean value. */
1302
0
                *data->data.u8 = (input[idx] != 0);
1303
0
                break;
1304
0
            }
1305
0
            if (asn->tag == ASN_TAG_NULL) {
1306
                /* NULL has no data in BER. */
1307
0
                if (len != 0) {
1308
                #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1309
                    WOLFSSL_MSG_VSNPRINTF("NULL length too long: %d", len);
1310
                #endif
1311
0
                    return ASN_EXPECT_0_E;
1312
0
                }
1313
0
                data->data.ref.data = input + idx;
1314
0
                break;
1315
0
            }
1316
0
            if (asn->tag == ASN_OBJECT_ID) {
1317
0
                word32 oidIdx = 0;
1318
                /* Store OID data pointer and length */
1319
0
                data->data.oid.data = input + idx;
1320
0
                data->data.oid.length = (word32)len;
1321
                /* Get the OID sum. */
1322
0
                err = GetOID(input + idx, &oidIdx, &data->data.oid.sum,
1323
0
                        data->data.oid.type, len);
1324
0
                if (err < 0) {
1325
                #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1326
                    WOLFSSL_MSG_VSNPRINTF("OID check failed: %d", err);
1327
                #endif
1328
0
                    return err;
1329
0
                }
1330
0
                break;
1331
0
            }
1332
1333
            /* Otherwise store data pointer and length. */
1334
0
            data->data.ref.data = input + idx;
1335
0
            data->data.ref.length = (word32)len;
1336
0
            break;
1337
1338
    #ifdef DEBUG_WOLFSSL
1339
        default:
1340
            /* Bad ASN data type. */
1341
        #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1342
            WOLFSSL_MSG_VSNPRINTF("Bad data type: %d", data->dataType);
1343
        #endif
1344
            return BAD_STATE_E;
1345
    #endif
1346
1.53k
    }
1347
1348
1.53k
    return 0;
1349
1.53k
}
1350
1351
/* Get the ASN.1 items from the BER encoding.
1352
 *
1353
 * @param [in]      asn       ASN.1 items expected.
1354
 * @param [in]      data      Data array to place found items into.
1355
 * @param [in]      count     Count of items to parse.
1356
 * @param [in]      complete  Whether the whole buffer is to be used up.
1357
 * @param [in]      input     BER encoded data.
1358
 * @param [in, out] inOutIdx  On in, starting index of data.
1359
 *                            On out, end of parsed data.
1360
 * @param [in]      length    Length of input buffer.
1361
 * @return  0 on success.
1362
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
1363
 *          is invalid.
1364
 * @return  BUFFER_E when data in buffer is too small.
1365
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
1366
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
1367
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
1368
 *          non-zero length.
1369
 * @return  MP_INIT_E when the unable to initialize an mp_int.
1370
 * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
1371
 * @return  BAD_STATE_E when the data type is not supported.
1372
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
1373
 */
1374
int GetASN_Items(const ASNItem* asn, ASNGetData *data, int count, int complete,
1375
                 const byte* input, word32* inOutIdx, word32 length)
1376
769
{
1377
769
    int    i;
1378
769
    int    j;
1379
769
    int    err;
1380
769
    int    len;
1381
    /* Current index into buffer. */
1382
769
    word32 idx = *inOutIdx;
1383
    /* Initialize the end index at each depth to be the length. */
1384
769
    word32 endIdx[GET_ASN_MAX_DEPTH] = { length, length, length, length, length,
1385
769
                                         length, length };
1386
    /* Set choices to -1 to indicate they haven't been seen or found. */
1387
769
    signed char   choiceMet[GET_ASN_MAX_CHOICES] = { -1, -1 };
1388
    /* Not matching a choice right now. */
1389
769
    int    choice = 0;
1390
    /* Current depth of ASN.1 item. */
1391
769
    int    depth;
1392
    /* Minimum depth value seen. */
1393
769
    int    minDepth;
1394
    /* Integer had a zero prepended. */
1395
769
    int    zeroPadded;
1396
1397
#ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1398
    WOLFSSL_ENTER("GetASN_Items");
1399
#endif
1400
1401
    /* Start depth at first items depth. */
1402
769
    minDepth = depth = asn[0].depth;
1403
    /* Check every ASN.1 item. */
1404
3.07k
    for (i = 0; i < count; i++) {
1405
        /* Store offset of ASN.1 item. */
1406
2.30k
        data[i].offset = idx;
1407
        /* Length of data in ASN.1 item starts empty. */
1408
2.30k
        data[i].length = 0;
1409
        /* Get current item depth. */
1410
2.30k
        depth = asn[i].depth;
1411
    #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1412
        if (depth > GET_ASN_MAX_DEPTH) {
1413
            WOLFSSL_MSG("Depth in template too large");
1414
            return ASN_PARSE_E;
1415
        }
1416
    #endif
1417
        /* Keep track of minimum depth. */
1418
2.30k
        if (depth < minDepth) {
1419
0
            minDepth = depth;
1420
0
        }
1421
1422
        /* Reset choice if different from previous. */
1423
2.30k
        if (choice > 0 && asn[i].optional != choice) {
1424
0
            choice = 0;
1425
0
        }
1426
        /* Check if first of numbered choice. */
1427
2.30k
        if (choice == 0 && asn[i].optional > 1) {
1428
0
            choice = asn[i].optional;
1429
0
            if (choiceMet[choice - 2] == -1) {
1430
                /* Choice seen but not found a match yet. */
1431
0
                choiceMet[choice - 2] = 0;
1432
0
            }
1433
0
        }
1434
1435
        /* Check for end of data or not a choice and tag not matching. */
1436
2.30k
        if (idx == endIdx[depth] || (data[i].dataType != ASN_DATA_TYPE_CHOICE &&
1437
2.30k
                              (input[idx] & ~ASN_CONSTRUCTED) != asn[i].tag)) {
1438
0
            if (asn[i].optional) {
1439
                /* Skip over ASN.1 items underneath this optional item. */
1440
0
                for (j = i + 1; j < count; j++) {
1441
0
                    if (asn[i].depth >= asn[j].depth)
1442
0
                        break;
1443
0
                    data[j].offset = idx;
1444
0
                    data[j].length = 0;
1445
0
                }
1446
0
                i = j - 1;
1447
0
                continue;
1448
0
            }
1449
1450
            /* Check for end of data. */
1451
0
            if (idx == length) {
1452
        #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1453
                WOLFSSL_MSG_VSNPRINTF(
1454
                    "%2d: %4d %4d %c %*s %-16s%*s  (index past end)",
1455
                    i, data[i].offset, data[i].length,
1456
                    asn[i].constructed ? '+' : ' ', asn[i].depth, "",
1457
                    TagString(asn[i].tag), 6 - asn[i].depth, "");
1458
                WOLFSSL_MSG_VSNPRINTF("Index past end of data: %d %d", idx,
1459
                        length);
1460
        #endif
1461
0
                return BUFFER_E;
1462
0
            }
1463
        #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1464
            /* Show expected versus found. */
1465
            WOLFSSL_MSG_VSNPRINTF(
1466
                "%2d: %4d %4d %c %*s %-16s%*s  Tag=0x%02x (%s)",
1467
                i, data[i].offset, data[i].length,
1468
                asn[i].constructed ? '+' : ' ', asn[i].depth, "",
1469
                TagString(asn[i].tag), 6 - asn[i].depth, "",
1470
                input[idx], TagString(input[idx]));
1471
        #endif
1472
            /* Check for end of data at this depth. */
1473
0
            if (idx == endIdx[depth]) {
1474
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1475
                WOLFSSL_MSG_VSNPRINTF("Index past outer item: %d %d", idx,
1476
                        endIdx[depth]);
1477
            #endif
1478
0
                return ASN_PARSE_E;
1479
0
            }
1480
1481
            /* Expecting an OBJECT_ID */
1482
0
            if (asn[i].tag == ASN_OBJECT_ID) {
1483
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1484
                WOLFSSL_MSG("Expecting OBJECT ID");
1485
            #endif
1486
0
                return ASN_OBJECT_ID_E;
1487
0
            }
1488
            /* Expecting a BIT_STRING */
1489
0
            if (asn[i].tag == ASN_BIT_STRING) {
1490
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1491
                WOLFSSL_MSG("Expecting BIT STRING");
1492
            #endif
1493
0
                return ASN_BITSTR_E;
1494
0
            }
1495
            /* Not the expected tag. */
1496
        #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1497
            WOLFSSL_MSG("Bad tag");
1498
        #endif
1499
0
            return ASN_PARSE_E;
1500
0
        }
1501
1502
        /* Store found tag in data. */
1503
2.30k
        data[i].tag = input[idx];
1504
2.30k
        if (data[i].dataType != ASN_DATA_TYPE_CHOICE) {
1505
2.30k
            int constructed = (input[idx] & ASN_CONSTRUCTED) == ASN_CONSTRUCTED;
1506
            /* Check constructed match expected for non-choice ASN.1 item. */
1507
2.30k
            if (asn[i].constructed != constructed) {
1508
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1509
                WOLFSSL_MSG_VSNPRINTF(
1510
                        "%2d: %4d %4d %c %*s %-16s%*s  Tag=0x%02x (%s)",
1511
                        i, data[i].offset, data[i].length,
1512
                        asn[i].constructed ? '+' : ' ', asn[i].depth, "",
1513
                        TagString(asn[i].tag), 6 - asn[i].depth, "",
1514
                        input[idx], TagString(input[idx]));
1515
                if (!constructed) {
1516
                    WOLFSSL_MSG("Not constructed");
1517
                }
1518
                else {
1519
                    WOLFSSL_MSG("Not expected to be constructed");
1520
                }
1521
            #endif
1522
0
                return ASN_PARSE_E;
1523
0
            }
1524
2.30k
        }
1525
        /* Move index to start of length. */
1526
2.30k
        idx++;
1527
        /* Get the encoded length. */
1528
2.30k
        if (GetASN_Length(input, &idx, &len, endIdx[depth], 1) < 0) {
1529
        #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1530
            WOLFSSL_MSG_VSNPRINTF("%2d: idx=%d len=%d end=%d", i, idx, len,
1531
                    endIdx[depth]);
1532
        #endif
1533
0
            return ASN_PARSE_E;
1534
0
        }
1535
        /* Store length of data. */
1536
2.30k
        data[i].length = (word32)len;
1537
        /* Note the max length of items under this one. */
1538
2.30k
        endIdx[depth + 1] = idx + (word32)len;
1539
2.30k
        if (choice > 1) {
1540
            /* Note we found a number choice. */
1541
0
            choiceMet[choice - 2] = 1;
1542
0
        }
1543
1544
    #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1545
        WOLFSSL_MSG_VSNPRINTF("%2d: %4d %4d %c %*s %-16s", i,
1546
                data[i].offset, data[i].length, asn[i].constructed ? '+' : ' ',
1547
                asn[i].depth, "", TagString(data[i].tag));
1548
    #endif
1549
1550
        /* Assume no zero padding on INTEGER. */
1551
2.30k
        zeroPadded = 0;
1552
        /* Check data types that prepended a byte. */
1553
2.30k
        if (asn[i].tag == ASN_INTEGER) {
1554
            /* Check validity of first byte. */
1555
1.53k
            err = GetASN_Integer(input, idx, len,
1556
1.53k
                    data[i].dataType == ASN_DATA_TYPE_MP ||
1557
1.53k
                    data[i].dataType == ASN_DATA_TYPE_MP_INITED);
1558
1.53k
            if (err != 0)
1559
0
                return err;
1560
1.53k
            if (len > 1 && input[idx] == 0) {
1561
602
                zeroPadded = 1;
1562
                /* Move over prepended byte. */
1563
602
                idx++;
1564
602
                len--;
1565
602
            }
1566
1.53k
        }
1567
769
        else if (asn[i].tag == ASN_BIT_STRING) {
1568
            /* Check prepended byte is correct. */
1569
0
            err = GetASN_BitString(input, idx, len);
1570
0
            if (err != 0)
1571
0
                return err;
1572
            /* Move over prepended byte. */
1573
0
            idx++;
1574
0
            len--;
1575
0
        }
1576
769
        else if ((asn[i].tag == ASN_OBJECT_ID) && (len < 3)) {
1577
        #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1578
            WOLFSSL_MSG_VSNPRINTF("OID length must be 3 or more: %d", len);
1579
        #endif
1580
0
            return ASN_PARSE_E;
1581
0
        }
1582
1583
        /* Don't parse data if only header required. */
1584
2.30k
        if (asn[i].headerOnly) {
1585
            /* Store reference to data and length. */
1586
769
            data[i].data.ref.data = input + idx;
1587
769
            data[i].data.ref.length = (word32)len;
1588
769
            continue;
1589
769
        }
1590
1591
        /* Store the data at idx in the ASN data item. */
1592
1.53k
        err = GetASN_StoreData(&asn[i], &data[i], input, idx, len, zeroPadded);
1593
1.53k
        if (err != 0) {
1594
3
            return err;
1595
3
        }
1596
1597
        /* Move index to next item. */
1598
1.53k
        idx += (word32)len;
1599
1600
        /* When matched numbered choice ... */
1601
1.53k
        if (asn[i].optional > 1) {
1602
            /* Skip over other ASN.1 items of the same number. */
1603
0
            for (j = i + 1; j < count; j++) {
1604
0
                if (asn[j].depth <= asn[i].depth &&
1605
0
                                           asn[j].optional != asn[i].optional) {
1606
0
                   break;
1607
0
                }
1608
0
            }
1609
0
            i = j - 1;
1610
0
        }
1611
1.53k
    }
1612
1613
766
    if (complete) {
1614
        /* When expecting ASN.1 items to completely use data, check we did. */
1615
0
        for (j = depth; j > minDepth; j--) {
1616
0
            if (idx < endIdx[j]) {
1617
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1618
                WOLFSSL_MSG_VSNPRINTF(
1619
                    "More data in constructed item at depth: %d", j - 1);
1620
            #endif
1621
0
                return ASN_PARSE_E;
1622
0
            }
1623
0
        }
1624
0
    }
1625
1626
    /* Check all choices where met - found an item for them. */
1627
2.29k
    for (j = 0; j < GET_ASN_MAX_CHOICES; j++) {
1628
1.53k
        if (choiceMet[j] == 0) {
1629
        #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1630
            WOLFSSL_MSG_VSNPRINTF("No choice seen: %d", j + 2);
1631
        #endif
1632
0
            return ASN_PARSE_E;
1633
0
        }
1634
1.53k
    }
1635
1636
    /* Return index after ASN.1 data has been parsed. */
1637
766
    *inOutIdx = idx;
1638
1639
766
    return 0;
1640
766
}
1641
1642
#ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1643
/* Calculate the size of the DER encoding.
1644
 *
1645
 * Call SetASN_Items() to write encoding to a buffer.
1646
 *
1647
 * @param [in]      asn    ASN.1 items to encode.
1648
 * @param [in, out] data   Data to place in each item. Lengths set were not
1649
 *                         known.
1650
 * @param [in]      count  Count of items to encode.
1651
 * @param [out]     len    Length of the DER encoding.
1652
 * @return  Size of the DER encoding in bytes.
1653
 */
1654
static int SizeASN_ItemsDebug(const char* name, const ASNItem* asn,
1655
    ASNSetData *data, int count, int* encSz)
1656
{
1657
    WOLFSSL_MSG_VSNPRINTF("TEMPLATE: %s", name);
1658
    return SizeASN_Items(asn, data, count, encSz);
1659
}
1660
1661
/* Creates the DER encoding of the ASN.1 items.
1662
 *
1663
 * Assumes the output buffer is large enough to hold encoding.
1664
 * Must call SizeASN_Items() to determine size of encoding and offsets.
1665
 *
1666
 * Displays the template name first.
1667
 *
1668
 * @param [in]      name    Name of ASN.1 template.
1669
 * @param [in]      asn     ASN.1 items to encode.
1670
 * @param [in]      data    Data to place in each item.
1671
 * @param [in]      count   Count of items to encode.
1672
 * @param [in, out] output  Buffer to write encoding into.
1673
 * @return  Size of the DER encoding in bytes.
1674
 */
1675
static int SetASN_ItemsDebug(const char* name, const ASNItem* asn,
1676
    ASNSetData *data, int count, byte* output)
1677
{
1678
    WOLFSSL_MSG_VSNPRINTF("TEMPLATE: %s", name);
1679
    return SetASN_Items(asn, data, count, output);
1680
}
1681
1682
/* Get the ASN.1 items from the BER encoding.
1683
 *
1684
 * Displays the template name first.
1685
 *
1686
 * @param [in]      name      Name of ASN.1 template.
1687
 * @param [in]      asn       ASN.1 items expected.
1688
 * @param [in]      data      Data array to place found items into.
1689
 * @param [in]      count     Count of items to parse.
1690
 * @param [in]      complete  Whether the whole buffer is to be used up.
1691
 * @param [in]      input     BER encoded data.
1692
 * @param [in, out] inOutIdx  On in, starting index of data.
1693
 *                            On out, end of parsed data.
1694
 * @param [in]      maxIdx    Maximum index of input data.
1695
 * @return  0 on success.
1696
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
1697
 * is invalid.
1698
 * @return  BUFFER_E when data in buffer is too small.
1699
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
1700
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
1701
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
1702
 *          non-zero length.
1703
 * @return  MP_INIT_E when the unable to initialize an mp_int.
1704
 * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
1705
 * @return  BAD_STATE_E when the data type is not supported.
1706
 */
1707
static int GetASN_ItemsDebug(const char* name, const ASNItem* asn,
1708
    ASNGetData *data, int count, int complete, const byte* input,
1709
    word32* inOutIdx, word32 maxIdx)
1710
{
1711
    WOLFSSL_MSG_VSNPRINTF("TEMPLATE: %s", name);
1712
    return GetASN_Items(asn, data, count, complete, input, inOutIdx, maxIdx);
1713
}
1714
1715
/* Calculate the size of the DER encoding.
1716
 *
1717
 * Call SetASN_Items() to write encoding to a buffer.
1718
 *
1719
 * @param [in]      asn    ASN.1 items to encode.
1720
 * @param [in, out] data   Data to place in each item. Lengths set were not
1721
 *                         known.
1722
 * @param [in]      count  Count of items to encode.
1723
 * @param [out]     len    Length of the DER encoding.
1724
 * @return  Size of the DER encoding in bytes.
1725
 */
1726
#define SizeASN_Items(asn, data, count, encSz)  \
1727
    SizeASN_ItemsDebug(#asn, asn, data, count, encSz)
1728
1729
/* Creates the DER encoding of the ASN.1 items.
1730
 *
1731
 * Assumes the output buffer is large enough to hold encoding.
1732
 * Must call SizeASN_Items() to determine size of encoding and offsets.
1733
 *
1734
 * Displays the template name first.
1735
 *
1736
 * @param [in]      name    Name of ASN.1 template.
1737
 * @param [in]      asn     ASN.1 items to encode.
1738
 * @param [in]      data    Data to place in each item.
1739
 * @param [in]      count   Count of items to encode.
1740
 * @param [in, out] output  Buffer to write encoding into.
1741
 * @return  Size of the DER encoding in bytes.
1742
 */
1743
#define SetASN_Items(asn, data, count, output)  \
1744
    SetASN_ItemsDebug(#asn, asn, data, count, output)
1745
1746
/* Get the ASN.1 items from the BER encoding.
1747
 *
1748
 * Displays the template name first.
1749
 *
1750
 * @param [in]      name      Name of ASN.1 template.
1751
 * @param [in]      asn       ASN.1 items expected.
1752
 * @param [in]      data      Data array to place found items into.
1753
 * @param [in]      count     Count of items to parse.
1754
 * @param [in]      complete  Whether the whole buffer is to be used up.
1755
 * @param [in]      input     BER encoded data.
1756
 * @param [in, out] inOutIdx  On in, starting index of data.
1757
 *                            On out, end of parsed data.
1758
 * @param [in]      maxIdx    Maximum index of input data.
1759
 * @return  0 on success.
1760
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
1761
 * is invalid.
1762
 * @return  BUFFER_E when data in buffer is too small.
1763
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
1764
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
1765
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
1766
 *          non-zero length.
1767
 * @return  MP_INIT_E when the unable to initialize an mp_int.
1768
 * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
1769
 * @return  BAD_STATE_E when the data type is not supported.
1770
 */
1771
#define GetASN_Items(asn, data, count, complete, input, inOutIdx, maxIdx)  \
1772
    GetASN_ItemsDebug(#asn, asn, data, count, complete, input, inOutIdx, maxIdx)
1773
#endif /* WOLFSSL_DEBUG_ASN_TEMPLATE */
1774
1775
/* Decode a BER encoded constructed sequence.
1776
 *
1777
 * @param [in]       input     Buffer of BER encoded data.
1778
 * @param [in, out]  inOutIdx  On in, index to start decoding from.
1779
 *                             On out, index of next encoded byte.
1780
 * @param [out]      len       Length of data under SEQUENCE.
1781
 * @param [in]       maxIdx    Maximim index of data. Index of byte after SEQ.
1782
 * @param [in]       complete  All data used with SEQUENCE and data under.
1783
 * @return  0 on success.
1784
 * @return  BUFFER_E when not enough data to complete decode.
1785
 * @return  ASN_PARSE when decoding failed.
1786
 */
1787
static int GetASN_Sequence(const byte* input, word32* inOutIdx, int* len,
1788
                           word32 maxIdx, int complete)
1789
0
{
1790
0
    int ret = 0;
1791
0
    word32 idx = *inOutIdx;
1792
1793
    /* Check buffer big enough for tag. */
1794
0
    if (idx + 1 > maxIdx) {
1795
0
        ret = BUFFER_E;
1796
0
    }
1797
    /* Check it is a constructed SEQUENCE. */
1798
0
    if ((ret == 0) && (input[idx++] != (ASN_SEQUENCE | ASN_CONSTRUCTED))) {
1799
0
        ret = ASN_PARSE_E;
1800
0
    }
1801
    /* Get the length. */
1802
0
    if ((ret == 0) && (GetASN_Length(input, &idx, len, maxIdx, 1) < 0)) {
1803
0
        ret = ASN_PARSE_E;
1804
0
    }
1805
    /* Check all data used if complete set. */
1806
0
    if ((ret == 0) && complete && (idx + (word32)*len != maxIdx)) {
1807
0
        ret = ASN_PARSE_E;
1808
0
    }
1809
0
    if (ret == 0) {
1810
        /* Return index of next byte of encoded data. */
1811
0
        *inOutIdx = idx;
1812
0
    }
1813
1814
0
    return ret;
1815
0
}
1816
1817
1818
#ifdef WOLFSSL_ASN_TEMPLATE_TYPE_CHECK
1819
/* Setup ASN data item to get an 8-bit number.
1820
 *
1821
 * @param [in] dataASN  Dynamic ASN data item.
1822
 * @param [in] num      Pointer to an 8-bit variable.
1823
 */
1824
void GetASN_Int8Bit(ASNGetData *dataASN, byte* num)
1825
{
1826
    dataASN->dataType = ASN_DATA_TYPE_WORD8;
1827
    dataASN->data.u8  = num;
1828
}
1829
1830
/* Setup ASN data item to get a 16-bit number.
1831
 *
1832
 * @param [in] dataASN  Dynamic ASN data item.
1833
 * @param [in] num      Pointer to a 16-bit variable.
1834
 */
1835
void GetASN_Int16Bit(ASNGetData *dataASN, word16* num)
1836
{
1837
    dataASN->dataType = ASN_DATA_TYPE_WORD16;
1838
    dataASN->data.u16 = num;
1839
}
1840
1841
/* Setup ASN data item to get a 32-bit number.
1842
 *
1843
 * @param [in] dataASN  Dynamic ASN data item.
1844
 * @param [in] num      Pointer to a 32-bit variable.
1845
 */
1846
void GetASN_Int32Bit(ASNGetData *dataASN, word32* num)
1847
{
1848
    dataASN->dataType = ASN_DATA_TYPE_WORD32;
1849
    dataASN->data.u32 = num;
1850
}
1851
1852
/* Setup ASN data item to get data into a buffer of a specific length.
1853
 *
1854
 * @param [in] dataASN  Dynamic ASN data item.
1855
 * @param [in] data     Buffer to hold data.
1856
 * @param [in] length   Length of buffer in bytes.
1857
 */
1858
void GetASN_Buffer(ASNGetData *dataASN, byte* data, word32* length)
1859
{
1860
    dataASN->dataType           = ASN_DATA_TYPE_BUFFER;
1861
    dataASN->data.buffer.data   = data;
1862
    dataASN->data.buffer.length = length;
1863
}
1864
1865
/* Setup ASN data item to check parsed data against expected buffer.
1866
 *
1867
 * @param [in] dataASN  Dynamic ASN data item.
1868
 * @param [in] data     Buffer containing expected data.
1869
 * @param [in] length   Length of buffer in bytes.
1870
 */
1871
void GetASN_ExpBuffer(ASNGetData *dataASN, const byte* data, word32 length)
1872
{
1873
    dataASN->dataType        = ASN_DATA_TYPE_EXP_BUFFER;
1874
    dataASN->data.ref.data   = data;
1875
    dataASN->data.ref.length = length;
1876
}
1877
1878
/* Setup ASN data item to get a number into an mp_int.
1879
 *
1880
 * @param [in] dataASN  Dynamic ASN data item.
1881
 * @param [in] num      Multi-precision number object.
1882
 */
1883
void GetASN_MP(ASNGetData *dataASN, mp_int* num)
1884
{
1885
    dataASN->dataType = ASN_DATA_TYPE_MP;
1886
    dataASN->data.mp  = num;
1887
}
1888
1889
/* Setup ASN data item to get a number into an mp_int that is initialized.
1890
 *
1891
 * @param [in] dataASN  Dynamic ASN data item.
1892
 * @param [in] num      Multi-precision number object.
1893
 */
1894
void GetASN_MP_Inited(ASNGetData *dataASN, mp_int* num)
1895
{
1896
    dataASN->dataType = ASN_DATA_TYPE_MP_INITED;
1897
    dataASN->data.mp  = num;
1898
}
1899
1900
/* Setup ASN data item to get a positive or negative number into an mp_int.
1901
 *
1902
 * @param [in] dataASN  Dynamic ASN data item.
1903
 * @param [in] num      Multi-precision number object.
1904
 */
1905
void GetASN_MP_PosNeg(ASNGetData *dataASN, mp_int* num)
1906
{
1907
    dataASN->dataType = ASN_DATA_TYPE_MP_POS_NEG;
1908
    dataASN->data.mp  = num;
1909
}
1910
1911
/* Setup ASN data item to be a choice of tags.
1912
 *
1913
 * @param [in] dataASN  Dynamic ASN data item.
1914
 * @param [in] options  0 terminated list of tags that are valid.
1915
 */
1916
void GetASN_Choice(ASNGetData *dataASN, const byte* options)
1917
{
1918
    dataASN->dataType    = ASN_DATA_TYPE_CHOICE;
1919
    dataASN->data.choice = options;
1920
}
1921
1922
/* Setup ASN data item to get a boolean value.
1923
 *
1924
 * @param [in] dataASN  Dynamic ASN data item.
1925
 * @param [in] num      Pointer to an 8-bit variable.
1926
 */
1927
void GetASN_Boolean(ASNGetData *dataASN, byte* num)
1928
{
1929
    dataASN->dataType    = ASN_DATA_TYPE_NONE;
1930
    dataASN->data.choice = num;
1931
}
1932
1933
/* Setup ASN data item to be a an OID of a specific type.
1934
 *
1935
 * @param [in] dataASN  Dynamic ASN data item.
1936
 * @param [in] oidType  Type of OID to expect.
1937
 */
1938
void GetASN_OID(ASNGetData *dataASN, int oidType)
1939
{
1940
    dataASN->data.oid.type = oidType;
1941
}
1942
1943
/* Get the data and length from an ASN data item.
1944
 *
1945
 * @param [in]  dataASN  Dynamic ASN data item.
1946
 * @param [out] data     Pointer to data of item.
1947
 * @param [out] length   Length of buffer in bytes.
1948
 */
1949
void GetASN_GetConstRef(ASNGetData * dataASN, const byte** data, word32* length)
1950
{
1951
    *data   = dataASN->data.ref.data;
1952
    *length = dataASN->data.ref.length;
1953
}
1954
1955
/* Get the data and length from an ASN data item.
1956
 *
1957
 * @param [in]  dataASN  Dynamic ASN data item.
1958
 * @param [out] data     Pointer to data of item.
1959
 * @param [out] length   Length of buffer in bytes.
1960
 */
1961
void GetASN_GetRef(ASNGetData * dataASN, byte** data, word32* length)
1962
{
1963
    *data   = (byte*)dataASN->data.ref.data;
1964
    *length =        dataASN->data.ref.length;
1965
}
1966
1967
/* Get the data and length from an ASN data item that is an OID.
1968
 *
1969
 * @param [in]  dataASN  Dynamic ASN data item.
1970
 * @param [out] data     Pointer to .
1971
 * @param [out] length   Length of buffer in bytes.
1972
 */
1973
void GetASN_OIDData(ASNGetData * dataASN, byte** data, word32* length)
1974
{
1975
    *data   = (byte*)dataASN->data.oid.data;
1976
    *length =        dataASN->data.oid.length;
1977
}
1978
1979
/* Setup an ASN data item to set a boolean.
1980
 *
1981
 * @param [in] dataASN  Dynamic ASN data item.
1982
 * @param [in] val      Boolean value.
1983
 */
1984
void SetASN_Boolean(ASNSetData *dataASN, byte val)
1985
{
1986
    dataASN->dataType = ASN_DATA_TYPE_NONE;
1987
    dataASN->data.u8  = val;
1988
}
1989
1990
/* Setup an ASN data item to set an 8-bit number.
1991
 *
1992
 * @param [in] dataASN  Dynamic ASN data item.
1993
 * @param [in] num      8-bit number to set.
1994
 */
1995
void SetASN_Int8Bit(ASNSetData *dataASN, byte num)
1996
{
1997
    dataASN->dataType = ASN_DATA_TYPE_WORD8;
1998
    dataASN->data.u8  = num;
1999
}
2000
2001
/* Setup an ASN data item to set a 16-bit number.
2002
 *
2003
 * @param [in] dataASN  Dynamic ASN data item.
2004
 * @param [in] num      16-bit number to set.
2005
 */
2006
void SetASN_Int16Bit(ASNSetData *dataASN, word16 num)
2007
{
2008
    dataASN->dataType = ASN_DATA_TYPE_WORD16;
2009
    dataASN->data.u16 = num;
2010
}
2011
2012
/* Setup an ASN data item to set the data in a buffer.
2013
 *
2014
 * @param [in] dataASN  Dynamic ASN data item.
2015
 * @param [in] data     Buffer containing data to set.
2016
 * @param [in] length   Length of data in buffer in bytes.
2017
 */
2018
void SetASN_Buffer(ASNSetData *dataASN, const byte* data, word32 length)
2019
{
2020
    dataASN->data.buffer.data   = data;
2021
    dataASN->data.buffer.length = length;
2022
}
2023
2024
/* Setup an ASN data item to set the DER encode data in a buffer.
2025
 *
2026
 * @param [in] dataASN  Dynamic ASN data item.
2027
 * @param [in] data     Buffer containing BER encoded data to set.
2028
 * @param [in] length   Length of data in buffer in bytes.
2029
 */
2030
void SetASN_ReplaceBuffer(ASNSetData *dataASN, const byte* data, word32 length)
2031
{
2032
    dataASN->dataType           = ASN_DATA_TYPE_REPLACE_BUFFER;
2033
    dataASN->data.buffer.data   = data;
2034
    dataASN->data.buffer.length = length;
2035
}
2036
2037
/* Setup an ASN data item to set an multi-precision number.
2038
 *
2039
 * @param [in] dataASN  Dynamic ASN data item.
2040
 * @param [in] num      Multi-precision number.
2041
 */
2042
void SetASN_MP(ASNSetData *dataASN, mp_int* num)
2043
{
2044
    dataASN->dataType = ASN_DATA_TYPE_MP;
2045
    dataASN->data.mp  = num;
2046
}
2047
2048
/* Setup an ASN data item to set an OID based on id and type.
2049
 *
2050
 * oid and oidType pair are unique.
2051
 *
2052
 * @param [in] dataASN  Dynamic ASN data item.
2053
 * @param [in] oid      OID identifier.
2054
 * @param [in] oidType  Type of OID.
2055
 */
2056
void SetASN_OID(ASNSetData *dataASN, int oid, int oidType)
2057
{
2058
    dataASN->data.buffer.data = OidFromId(oid, oidType,
2059
                                                  &dataASN->data.buffer.length);
2060
}
2061
#endif /* WOLFSSL_ASN_TEMPLATE_TYPE_CHECK */
2062
2063
#ifdef CRLDP_VALIDATE_DATA
2064
/* Get the data of the BIT_STRING as a 16-bit number.
2065
 *
2066
 * @param [in]  dataASN  Dynamic ASN data item.
2067
 * @param [out] val      ASN.1 item's data as a 16-bit number.
2068
 * @return  0 on success.
2069
 * @return  ASN_PARSE_E when BITSTRING value is more than 2 bytes.
2070
 * @return  ASN_PARSE_E when unused bits of BITSTRING is invalid.
2071
 */
2072
static int GetASN_BitString_Int16Bit(ASNGetData* dataASN, word16* val)
2073
{
2074
    int ret;
2075
    int i;
2076
    const byte* input = dataASN->data.ref.data;
2077
    int length = dataASN->data.ref.length;
2078
2079
    /* Validate the BIT_STRING data. */
2080
    ret = GetASN_BitString(input, 0, length);
2081
    if (ret == 0) {
2082
        /* Skip unused bits byte. */
2083
        input++;
2084
        length--;
2085
2086
        /* Check the data is usable. */
2087
        if (length == 0 || length > 2) {
2088
#ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
2089
            WOLFSSL_MSG_VSNPRINTF("Expecting 1 or 2 bytes: %d", length);
2090
#endif
2091
            ret = ASN_PARSE_E;
2092
        }
2093
    }
2094
    if (ret == 0) {
2095
        /* Fill 16-bit var with all the data. */
2096
        *val = 0;
2097
        for (i = 0; i < length; i++) {
2098
            *val <<= 8;
2099
            *val |= input[i];
2100
        }
2101
    }
2102
    return ret;
2103
}
2104
#endif /* CRLDP_VALIDATE_DATA */
2105
2106
#endif /* WOLFSSL_ASN_TEMPLATE */
2107
2108
2109
/* Decode the BER/DER length field.
2110
 *
2111
 * @param [in]      input     BER encoded data.
2112
 * @param [in, out] inOutIdx  On in, starting index of length.
2113
 *                            On out, end of parsed length.
2114
 * @param [out]     len       Length value decoded.
2115
 * @param [in]      maxIdx    Maximum index of input data.
2116
 * @return  Length on success.
2117
 * @return  ASN_PARSE_E if the encoding is invalid.
2118
 * @return  BUFFER_E when not enough data to complete decode.
2119
 */
2120
int GetLength(const byte* input, word32* inOutIdx, int* len, word32 maxIdx)
2121
0
{
2122
0
    return GetLength_ex(input, inOutIdx, len, maxIdx, 1);
2123
0
}
2124
2125
2126
/* Decode the BER/DER length field and check the length is valid on request.
2127
 *
2128
 * BER/DER has Type-Length-Value triplets.
2129
 * When requested will check that the Length decoded, indicating the number
2130
 * of bytes in the Value, is available in the buffer after the Length bytes.
2131
 *
2132
 * Only supporting a length upto INT_MAX.
2133
 *
2134
 * @param [in]      input     BER encoded data.
2135
 * @param [in, out] inOutIdx  On in, starting index of length.
2136
 *                            On out, end of parsed length.
2137
 * @param [out]     len       Length value decoded.
2138
 * @param [in]      maxIdx    Maximum index of input data.
2139
 * @param [in]      check     Whether to check the buffer has at least the
2140
 *                            decoded length of bytes remaining.
2141
 * @return  Length on success.
2142
 * @return  ASN_PARSE_E if the encoding is invalid.
2143
 * @return  BUFFER_E when not enough data to complete decode.
2144
 */
2145
int GetLength_ex(const byte* input, word32* inOutIdx, int* len, word32 maxIdx,
2146
                 int check)
2147
2.30k
{
2148
2.30k
    int     length = 0;
2149
2.30k
    word32  idx = (word32)*inOutIdx;
2150
2.30k
    byte    b;
2151
2152
    /* Ensure zero return length on error. */
2153
2.30k
    *len = 0;
2154
2155
    /* Check there is at least one byte available containing length information.
2156
     */
2157
2.30k
    if ((idx + 1) > maxIdx) {
2158
0
        WOLFSSL_MSG("GetLength - bad index on input");
2159
0
        return BUFFER_E;
2160
0
    }
2161
2162
    /* Get the first length byte. */
2163
2.30k
    b = input[idx++];
2164
    /* Check if the first byte indicates the count of bytes. */
2165
2.30k
    if (b >= ASN_LONG_LENGTH) {
2166
        /* Bottom 7 bits are the number of bytes to calculate length with.
2167
         * Note: 0 indicates indefinite length encoding *not* 0 bytes of length.
2168
         */
2169
140
        word32 bytes = (word32)b & 0x7FU;
2170
140
        int minLen;
2171
2172
        /* Calculate minimum length to be encoded with bytes. */
2173
140
        if (b == ASN_INDEF_LENGTH) {
2174
            /* Indefinite length encoding - no length bytes. */
2175
0
            minLen = 0;
2176
0
        }
2177
140
        else if (bytes == 1) {
2178
140
            minLen = 0x80;
2179
140
        }
2180
        /* Only support up to the number of bytes that fit into return var. */
2181
0
        else if (bytes > sizeof(length)) {
2182
0
            WOLFSSL_MSG("GetLength - overlong data length spec");
2183
0
            return ASN_PARSE_E;
2184
0
        } else {
2185
0
            minLen = 1 << ((bytes - 1) * 8);
2186
0
        }
2187
2188
        /* Check the number of bytes required are available. */
2189
140
        if ((idx + bytes) > maxIdx) {
2190
0
            WOLFSSL_MSG("GetLength - bad long length");
2191
0
            return BUFFER_E;
2192
0
        }
2193
2194
        /* Big-endian encoding of number. */
2195
280
        while (bytes--) {
2196
140
            b = input[idx++];
2197
140
            length = (length << 8) | b;
2198
140
        }
2199
        /* Negative value indicates we overflowed the signed int. */
2200
140
        if (length < 0) {
2201
0
            return ASN_PARSE_E;
2202
0
        }
2203
        /* Don't allow lengths that are longer than strictly required. */
2204
140
        if (length < minLen) {
2205
0
            return ASN_PARSE_E;
2206
0
        }
2207
140
    }
2208
2.16k
    else {
2209
        /* Length in first byte. */
2210
2.16k
        length = b;
2211
2.16k
    }
2212
2213
    /* When requested, check the buffer has at least length bytes left. */
2214
2.30k
    if (check && ((idx + (word32)length) > maxIdx)) {
2215
0
        WOLFSSL_MSG("GetLength - value exceeds buffer length");
2216
0
        return BUFFER_E;
2217
0
    }
2218
2219
    /* Return index after length encoding. */
2220
2.30k
    *inOutIdx = idx;
2221
    /* Return length if valid. */
2222
2.30k
    if (length > 0) {
2223
2.30k
        *len = length;
2224
2.30k
    }
2225
2226
    /* Return length calculated or error code. */
2227
2.30k
    return length;
2228
2.30k
}
2229
2230
2231
/* Gets the tag of next BER/DER encoded item.
2232
 *
2233
 * Checks there is enough data in the buffer for the tag byte.
2234
 *
2235
 * @param [in]      input     BER encoded data.
2236
 * @param [in, out] inOutIdx  On in, starting index of tag.
2237
 *                            On out, end of parsed tag.
2238
 * @param [out]     tag       Tag value found.
2239
 * @param [in]      maxIdx    Maximum index of input data.
2240
 *
2241
 * return  0 on success
2242
 * return  BAD_FUNC_ARG when tag, inOutIdx or input is NULL.
2243
 * return  BUFFER_E when not enough space in buffer for tag.
2244
 */
2245
int GetASNTag(const byte* input, word32* inOutIdx, byte* tag, word32 maxIdx)
2246
0
{
2247
0
    int ret = 0;
2248
0
    word32 idx = 0;
2249
2250
    /* Check validity of parameters. */
2251
0
    if ((tag == NULL) || (inOutIdx == NULL) || (input == NULL)) {
2252
0
        ret = BAD_FUNC_ARG;
2253
0
    }
2254
0
    if (ret == 0) {
2255
        /* Get index and ensure space for tag. */
2256
0
        idx = *inOutIdx;
2257
0
        if (idx + ASN_TAG_SZ > maxIdx) {
2258
0
            WOLFSSL_MSG("Buffer too small for ASN tag");
2259
0
            ret = BUFFER_E;
2260
0
        }
2261
0
    }
2262
0
    if (ret == 0) {
2263
        /* Return the tag and the index after tag. */
2264
0
        *tag = input[idx];
2265
0
        *inOutIdx = idx + ASN_TAG_SZ;
2266
0
    }
2267
    /* Return error code. */
2268
0
    return ret;
2269
0
}
2270
2271
2272
/* Decode the DER/BER header (Type-Length) and check the length when requested.
2273
 *
2274
 * BER/DER has Type-Length-Value triplets.
2275
 * Check that the tag/type is the required value.
2276
 * When requested will check that the Length decoded, indicating the number
2277
 * of bytes in the Value, is available in the buffer after the Length bytes.
2278
 *
2279
 * Only supporting a length upto INT_MAX.
2280
 *
2281
 * @param [in]      input     Buffer holding DER/BER encoded data.
2282
 * @param [in]      tag       ASN.1 tag value expected in header.
2283
 * @param [in, out] inOutIdx  On in, starting index of header.
2284
 *                            On out, end of parsed header.
2285
 * @param [out]     len       Number of bytes in the ASN.1 data.
2286
 * @param [in]      maxIdx    Length of data in buffer.
2287
 * @param [in]      check     Whether to check the buffer has at least the
2288
 *                            decoded length of bytes remaining.
2289
 * @return  Number of bytes in the ASN.1 data on success.
2290
 * @return  BUFFER_E when there is not enough data to parse.
2291
 * @return  ASN_PARSE_E when the expected tag is not found or length is invalid.
2292
 */
2293
static int GetASNHeader_ex(const byte* input, byte tag, word32* inOutIdx,
2294
                           int* len, word32 maxIdx, int check)
2295
0
{
2296
0
    int    ret = 0;
2297
0
    word32 idx = *inOutIdx;
2298
0
    byte   tagFound;
2299
0
    int    length = 0;
2300
2301
    /* Get tag/type. */
2302
0
    if (GetASNTag(input, &idx, &tagFound, maxIdx) != 0) {
2303
0
        ret = ASN_PARSE_E;
2304
0
    }
2305
    /* Ensure tag is the expected value. */
2306
0
    if ((ret == 0) && (tagFound != tag)) {
2307
0
        ret = ASN_PARSE_E;
2308
0
    }
2309
    /* Get the encoded length. */
2310
0
    if ((ret == 0) && (GetLength_ex(input, &idx, &length, maxIdx, check) < 0)) {
2311
0
        ret = ASN_PARSE_E;
2312
0
    }
2313
0
    if (ret == 0) {
2314
        /* Return the length of data and index after header. */
2315
0
        *len      = length;
2316
0
        *inOutIdx = idx;
2317
0
        ret = length;
2318
0
    }
2319
    /* Return number of data bytes or error code. */
2320
0
    return ret;
2321
0
}
2322
2323
2324
/* Decode the DER/BER header (Type-Length) and check the length.
2325
 *
2326
 * BER/DER has Type-Length-Value triplets.
2327
 * Check that the tag/type is the required value.
2328
 * Checks that the Length decoded, indicating the number of bytes in the Value,
2329
 * is available in the buffer after the Length bytes.
2330
 *
2331
 * @param [in]      input     Buffer holding DER/BER encoded data.
2332
 * @param [in]      tag       ASN.1 tag value expected in header.
2333
 * @param [in, out] inOutIdx  On in, starting index of header.
2334
 *                            On out, end of parsed header.
2335
 * @param [out]     len       Number of bytes in the ASN.1 data.
2336
 * @param [in]      maxIdx    Length of data in buffer.
2337
 * @return  Number of bytes in the ASN.1 data on success.
2338
 * @return  BUFFER_E when there is not enough data to parse.
2339
 * @return  ASN_PARSE_E when the expected tag is not found or length is invalid.
2340
 */
2341
static int GetASNHeader(const byte* input, byte tag, word32* inOutIdx, int* len,
2342
                        word32 maxIdx)
2343
0
{
2344
0
    return GetASNHeader_ex(input, tag, inOutIdx, len, maxIdx, 1);
2345
0
}
2346
2347
#ifndef WOLFSSL_ASN_TEMPLATE
2348
static int GetHeader(const byte* input, byte* tag, word32* inOutIdx, int* len,
2349
                     word32 maxIdx, int check)
2350
{
2351
    word32 idx = *inOutIdx;
2352
    int    length;
2353
2354
    if ((idx + 1) > maxIdx)
2355
        return BUFFER_E;
2356
2357
    *tag = input[idx++];
2358
2359
    if (GetLength_ex(input, &idx, &length, maxIdx, check) < 0)
2360
        return ASN_PARSE_E;
2361
2362
    *len      = length;
2363
    *inOutIdx = idx;
2364
    return length;
2365
}
2366
#endif
2367
2368
/* Decode the header of a BER/DER encoded SEQUENCE.
2369
 *
2370
 * @param [in]      input     Buffer holding DER/BER encoded data.
2371
 * @param [in, out] inOutIdx  On in, starting index of header.
2372
 *                            On out, end of parsed header.
2373
 * @param [out]     len       Number of bytes in the ASN.1 data.
2374
 * @param [in]      maxIdx    Length of data in buffer.
2375
 * @return  Number of bytes in the ASN.1 data on success.
2376
 * @return  BUFFER_E when there is not enough data to parse.
2377
 * @return  ASN_PARSE_E when the tag is not a SEQUENCE or length is invalid.
2378
 */
2379
int GetSequence(const byte* input, word32* inOutIdx, int* len,
2380
                           word32 maxIdx)
2381
0
{
2382
0
    return GetASNHeader(input, ASN_SEQUENCE | ASN_CONSTRUCTED, inOutIdx, len,
2383
0
                        maxIdx);
2384
0
}
2385
2386
/* Decode the header of a BER/DER encoded SEQUENCE.
2387
 *
2388
 * @param [in]      input     Buffer holding DER/BER encoded data.
2389
 * @param [in, out] inOutIdx  On in, starting index of header.
2390
 *                            On out, end of parsed header.
2391
 * @param [out]     len       Number of bytes in the ASN.1 data.
2392
 * @param [in]      maxIdx    Length of data in buffer.
2393
 * @param [in]      check     Whether to check the buffer has at least the
2394
 *                            decoded length of bytes remaining.
2395
 * @return  Number of bytes in the ASN.1 data on success.
2396
 * @return  BUFFER_E when there is not enough data to parse.
2397
 * @return  ASN_PARSE_E when the tag is not a SEQUENCE or length is invalid.
2398
 */
2399
int GetSequence_ex(const byte* input, word32* inOutIdx, int* len,
2400
                           word32 maxIdx, int check)
2401
0
{
2402
0
    return GetASNHeader_ex(input, ASN_SEQUENCE | ASN_CONSTRUCTED, inOutIdx, len,
2403
0
                        maxIdx, check);
2404
0
}
2405
2406
/* Decode the header of a BER/DER encoded SET.
2407
 *
2408
 * @param [in]      input     Buffer holding DER/BER encoded data.
2409
 * @param [in, out] inOutIdx  On in, starting index of header.
2410
 *                            On out, end of parsed header.
2411
 * @param [out]     len       Number of bytes in the ASN.1 data.
2412
 * @param [in]      maxIdx    Length of data in buffer.
2413
 * @return  Number of bytes in the ASN.1 data on success.
2414
 * @return  BUFFER_E when there is not enough data to parse.
2415
 * @return  ASN_PARSE_E when the tag is not a SET or length is invalid.
2416
 */
2417
int GetSet(const byte* input, word32* inOutIdx, int* len,
2418
                        word32 maxIdx)
2419
0
{
2420
0
    return GetASNHeader(input, ASN_SET | ASN_CONSTRUCTED, inOutIdx, len,
2421
0
                        maxIdx);
2422
0
}
2423
2424
/* Decode the header of a BER/DER encoded SET.
2425
 *
2426
 * @param [in]      input     Buffer holding DER/BER encoded data.
2427
 * @param [in, out] inOutIdx  On in, starting index of header.
2428
 *                            On out, end of parsed header.
2429
 * @param [out]     len       Number of bytes in the ASN.1 data.
2430
 * @param [in]      maxIdx    Length of data in buffer.
2431
 * @param [in]      check     Whether to check the buffer has at least the
2432
 *                            decoded length of bytes remaining.
2433
 * @return  Number of bytes in the ASN.1 data on success.
2434
 * @return  BUFFER_E when there is not enough data to parse.
2435
 * @return  ASN_PARSE_E when the tag is not a SET or length is invalid.
2436
 */
2437
int GetSet_ex(const byte* input, word32* inOutIdx, int* len,
2438
                        word32 maxIdx, int check)
2439
0
{
2440
0
    return GetASNHeader_ex(input, ASN_SET | ASN_CONSTRUCTED, inOutIdx, len,
2441
0
                        maxIdx, check);
2442
0
}
2443
2444
#if !defined(WOLFSSL_ASN_TEMPLATE) || defined(HAVE_OCSP)
2445
/* Decode the BER/DER encoded NULL.
2446
 *
2447
 * No data in a NULL ASN.1 item.
2448
 * Ensure that the all fields are as expected and move index past the element.
2449
 *
2450
 * @param [in]      input     Buffer holding DER/BER encoded data.
2451
 * @param [in, out] inOutIdx  On in, starting index of NULL item.
2452
 *                            On out, end of parsed NULL item.
2453
 * @param [in]      maxIdx    Length of data in buffer.
2454
 * @return  0 on success.
2455
 * @return  BUFFER_E when there is not enough data to parse.
2456
 * @return  ASN_TAG_NULL_E when the NULL tag is not found.
2457
 * @return  ASN_EXPECT_0_E when the length is not zero.
2458
 */
2459
static int GetASNNull(const byte* input, word32* inOutIdx, word32 maxIdx)
2460
{
2461
    int ret = 0;
2462
    word32 idx = *inOutIdx;
2463
2464
    /* Check buffer has enough data for a NULL item. */
2465
    if ((idx + 2) > maxIdx) {
2466
        ret = BUFFER_E;
2467
    }
2468
    /* Check the tag is NULL. */
2469
    if ((ret == 0) && (input[idx++] != ASN_TAG_NULL)) {
2470
        ret = ASN_TAG_NULL_E;
2471
    }
2472
    /* Check the length is zero. */
2473
    if ((ret == 0) && (input[idx++] != 0)) {
2474
        ret = ASN_EXPECT_0_E;
2475
    }
2476
    if (ret == 0) {
2477
        /* Return the index after NULL tag. */
2478
        *inOutIdx = idx;
2479
    }
2480
    /* Return error code. */
2481
    return ret;
2482
}
2483
#endif
2484
2485
#ifndef WOLFSSL_ASN_TEMPLATE
2486
/* Set the DER/BER encoding of the ASN.1 NULL element.
2487
 *
2488
 * output  Buffer to write into.
2489
 * returns the number of bytes added to the buffer.
2490
 */
2491
static int SetASNNull(byte* output)
2492
{
2493
    output[0] = ASN_TAG_NULL;
2494
    output[1] = 0;
2495
2496
    return 2;
2497
}
2498
#endif
2499
2500
#ifndef NO_CERTS
2501
#ifndef WOLFSSL_ASN_TEMPLATE
2502
/* Get the DER/BER encoding of an ASN.1 BOOLEAN.
2503
 *
2504
 * input     Buffer holding DER/BER encoded data.
2505
 * inOutIdx  Current index into buffer to parse.
2506
 * maxIdx    Length of data in buffer.
2507
 * returns BUFFER_E when there is not enough data to parse.
2508
 *         ASN_PARSE_E when the BOOLEAN tag is not found or length is not 1.
2509
 *         Otherwise, 0 to indicate the value was false and 1 to indicate true.
2510
 */
2511
static int GetBoolean(const byte* input, word32* inOutIdx, word32 maxIdx)
2512
{
2513
    word32 idx = *inOutIdx;
2514
    byte   b;
2515
2516
    if ((idx + 3) > maxIdx)
2517
        return BUFFER_E;
2518
2519
    b = input[idx++];
2520
    if (b != ASN_BOOLEAN)
2521
        return ASN_PARSE_E;
2522
2523
    if (input[idx++] != 1)
2524
        return ASN_PARSE_E;
2525
2526
    b = input[idx++] != 0;
2527
2528
    *inOutIdx = idx;
2529
    return b;
2530
}
2531
#endif
2532
#endif /* !NO_CERTS*/
2533
2534
2535
/* Decode the header of a BER/DER encoded OCTET STRING.
2536
 *
2537
 * @param [in]      input     Buffer holding DER/BER encoded data.
2538
 * @param [in, out] inOutIdx  On in, starting index of header.
2539
 *                            On out, end of parsed header.
2540
 * @param [out]     len       Number of bytes in the ASN.1 data.
2541
 * @param [in]      maxIdx    Length of data in buffer.
2542
 * @return  Number of bytes in the ASN.1 data on success.
2543
 * @return  BUFFER_E when there is not enough data to parse.
2544
 * @return  ASN_PARSE_E when the tag is not a OCTET STRING or length is invalid.
2545
 */
2546
int GetOctetString(const byte* input, word32* inOutIdx, int* len, word32 maxIdx)
2547
0
{
2548
0
    return GetASNHeader(input, ASN_OCTET_STRING, inOutIdx, len, maxIdx);
2549
0
}
2550
2551
#ifndef WOLFSSL_ASN_TEMPLATE
2552
/* Get the DER/BER encoding of an ASN.1 INTEGER header.
2553
 *
2554
 * Removes the leading zero byte when found.
2555
 *
2556
 * input     Buffer holding DER/BER encoded data.
2557
 * inOutIdx  Current index into buffer to parse.
2558
 * len       The number of bytes in the ASN.1 data (excluding any leading zero).
2559
 * maxIdx    Length of data in buffer.
2560
 * returns BUFFER_E when there is not enough data to parse.
2561
 *         ASN_PARSE_E when the INTEGER tag is not found, length is invalid,
2562
 *         or invalid use of or missing leading zero.
2563
 *         Otherwise, 0 to indicate success.
2564
 */
2565
static int GetASNInt(const byte* input, word32* inOutIdx, int* len,
2566
                     word32 maxIdx)
2567
{
2568
    int    ret;
2569
2570
    ret = GetASNHeader(input, ASN_INTEGER, inOutIdx, len, maxIdx);
2571
    if (ret < 0)
2572
        return ret;
2573
2574
    if (*len > 0) {
2575
2576
#ifndef WOLFSSL_ASN_INT_LEAD_0_ANY
2577
        /* check for invalid padding on negative integer.
2578
         * c.f. X.690 (ISO/IEC 8825-2:2003 (E)) 10.4.6; RFC 5280 4.1
2579
         */
2580
        if (*len > 1) {
2581
            if ((input[*inOutIdx] == 0xff) && (input[*inOutIdx + 1] & 0x80))
2582
                return ASN_PARSE_E;
2583
        }
2584
#endif
2585
2586
        /* remove leading zero, unless there is only one 0x00 byte */
2587
        if ((input[*inOutIdx] == 0x00) && (*len > 1)) {
2588
            (*inOutIdx)++;
2589
            (*len)--;
2590
2591
#ifndef WOLFSSL_ASN_INT_LEAD_0_ANY
2592
            if (*len > 0 && (input[*inOutIdx] & 0x80) == 0)
2593
                return ASN_PARSE_E;
2594
#endif
2595
        }
2596
    }
2597
2598
    return 0;
2599
}
2600
2601
#ifndef NO_CERTS
2602
/* Get the DER/BER encoding of an ASN.1 INTEGER that has a value of no more than
2603
 * 7 bits.
2604
 *
2605
 * input     Buffer holding DER/BER encoded data.
2606
 * inOutIdx  Current index into buffer to parse.
2607
 * maxIdx    Length of data in buffer.
2608
 * returns BUFFER_E when there is not enough data to parse.
2609
 *         ASN_PARSE_E when the INTEGER tag is not found or length is invalid.
2610
 *         Otherwise, the 7-bit value.
2611
 */
2612
static int GetInteger7Bit(const byte* input, word32* inOutIdx, word32 maxIdx)
2613
{
2614
    word32 idx = *inOutIdx;
2615
    byte   b;
2616
2617
    if ((idx + 3) > maxIdx)
2618
        return BUFFER_E;
2619
2620
    if (GetASNTag(input, &idx, &b, maxIdx) != 0)
2621
        return ASN_PARSE_E;
2622
    if (b != ASN_INTEGER)
2623
        return ASN_PARSE_E;
2624
    if (input[idx++] != 1)
2625
        return ASN_PARSE_E;
2626
    b = input[idx++];
2627
2628
    *inOutIdx = idx;
2629
    return b;
2630
}
2631
#endif /* !NO_CERTS */
2632
2633
#if defined(WC_RSA_PSS) && !defined(NO_RSA)
2634
/* Get the DER/BER encoding of an ASN.1 INTEGER that has a value of no more than
2635
 * 16 bits.
2636
 *
2637
 * input     Buffer holding DER/BER encoded data.
2638
 * inOutIdx  Current index into buffer to parse.
2639
 * maxIdx    Length of data in buffer.
2640
 * returns BUFFER_E when there is not enough data to parse.
2641
 *         ASN_PARSE_E when the INTEGER tag is not found or length is invalid.
2642
 *         Otherwise, the 16-bit value.
2643
 */
2644
static int GetInteger16Bit(const byte* input, word32* inOutIdx, word32 maxIdx)
2645
{
2646
    word32 idx = *inOutIdx;
2647
    byte tag;
2648
    word16 n;
2649
2650
    if ((idx + 2) > maxIdx)
2651
        return BUFFER_E;
2652
2653
    if (GetASNTag(input, &idx, &tag, maxIdx) != 0)
2654
        return ASN_PARSE_E;
2655
    if (tag != ASN_INTEGER)
2656
        return ASN_PARSE_E;
2657
    if (input[idx] == 1) {
2658
        idx++;
2659
        if ((idx + 1) > maxIdx) {
2660
            return ASN_PARSE_E;
2661
        }
2662
        n = input[idx++];
2663
    }
2664
    else if (input[idx] == 2) {
2665
        idx++;
2666
        if ((idx + 2) > maxIdx) {
2667
            return ASN_PARSE_E;
2668
        }
2669
        n = input[idx++];
2670
        n = (n << 8) | input[idx++];
2671
    }
2672
    else
2673
        return ASN_PARSE_E;
2674
2675
    *inOutIdx = idx;
2676
    return n;
2677
}
2678
#endif /* WC_RSA_PSS && !NO_RSA */
2679
#endif /* !WOLFSSL_ASN_TEMPLATE */
2680
2681
#if !defined(NO_DSA) && !defined(NO_SHA)
2682
static const char sigSha1wDsaName[] = "SHAwDSA";
2683
static const char sigSha256wDsaName[] = "SHA256wDSA";
2684
#endif /* NO_DSA */
2685
#ifndef NO_RSA
2686
#ifdef WOLFSSL_MD2
2687
    static const char  sigMd2wRsaName[] = "md2WithRSAEncryption";
2688
#endif
2689
#ifndef NO_MD5
2690
    static const char  sigMd5wRsaName[] = "md5WithRSAEncryption";
2691
#endif
2692
#ifndef NO_SHA
2693
    static const char  sigSha1wRsaName[] = "sha1WithRSAEncryption";
2694
#endif
2695
#ifdef WOLFSSL_SHA224
2696
    static const char sigSha224wRsaName[] = "sha224WithRSAEncryption";
2697
#endif
2698
#ifndef NO_SHA256
2699
    static const char sigSha256wRsaName[] = "sha256WithRSAEncryption";
2700
#endif
2701
#ifdef WOLFSSL_SHA384
2702
    static const char sigSha384wRsaName[] = "sha384WithRSAEncryption";
2703
#endif
2704
#ifdef WOLFSSL_SHA512
2705
    static const char sigSha512wRsaName[] = "sha512WithRSAEncryption";
2706
#endif
2707
#ifdef WOLFSSL_SHA3
2708
#ifndef WOLFSSL_NOSHA3_224
2709
    static const char sigSha3_224wRsaName[] = "sha3_224WithRSAEncryption";
2710
#endif
2711
#ifndef WOLFSSL_NOSHA3_256
2712
    static const char sigSha3_256wRsaName[] = "sha3_256WithRSAEncryption";
2713
#endif
2714
#ifndef WOLFSSL_NOSHA3_384
2715
    static const char sigSha3_384wRsaName[] = "sha3_384WithRSAEncryption";
2716
#endif
2717
#ifndef WOLFSSL_NOSHA3_512
2718
    static const char sigSha3_512wRsaName[] = "sha3_512WithRSAEncryption";
2719
#endif
2720
#endif
2721
#ifdef WC_RSA_PSS
2722
    static const char sigRsaSsaPssName[] = "rsassaPss";
2723
#endif
2724
#endif /* NO_RSA */
2725
#ifdef HAVE_ECC
2726
#ifndef NO_SHA
2727
    static const char sigSha1wEcdsaName[] = "SHAwECDSA";
2728
#endif
2729
#ifdef WOLFSSL_SHA224
2730
    static const char sigSha224wEcdsaName[] = "SHA224wECDSA";
2731
#endif
2732
#ifndef NO_SHA256
2733
    static const char sigSha256wEcdsaName[] = "SHA256wECDSA";
2734
#endif
2735
#ifdef WOLFSSL_SHA384
2736
    static const char sigSha384wEcdsaName[] = "SHA384wECDSA";
2737
#endif
2738
#ifdef WOLFSSL_SHA512
2739
    static const char sigSha512wEcdsaName[] = "SHA512wECDSA";
2740
#endif
2741
#ifdef WOLFSSL_SHA3
2742
#ifndef WOLFSSL_NOSHA3_224
2743
    static const char sigSha3_224wEcdsaName[] = "SHA3_224wECDSA";
2744
#endif
2745
#ifndef WOLFSSL_NOSHA3_256
2746
    static const char sigSha3_256wEcdsaName[] = "SHA3_256wECDSA";
2747
#endif
2748
#ifndef WOLFSSL_NOSHA3_384
2749
    static const char sigSha3_384wEcdsaName[] = "SHA3_384wECDSA";
2750
#endif
2751
#ifndef WOLFSSL_NOSHA3_512
2752
    static const char sigSha3_512wEcdsaName[] = "SHA3_512wECDSA";
2753
#endif
2754
#endif
2755
#endif /* HAVE_ECC */
2756
static const char sigUnknownName[] = "Unknown";
2757
2758
2759
/* Get the human readable string for a signature type
2760
 *
2761
 * oid  Oid value for signature
2762
 */
2763
0
const char* GetSigName(int oid) {
2764
0
    switch (oid) {
2765
    #if !defined(NO_DSA) && !defined(NO_SHA)
2766
        case CTC_SHAwDSA:
2767
            return sigSha1wDsaName;
2768
        case CTC_SHA256wDSA:
2769
            return sigSha256wDsaName;
2770
    #endif /* NO_DSA && NO_SHA */
2771
0
    #ifndef NO_RSA
2772
0
        #ifdef WOLFSSL_MD2
2773
0
        case CTC_MD2wRSA:
2774
0
            return sigMd2wRsaName;
2775
0
        #endif
2776
0
        #ifndef NO_MD5
2777
0
        case CTC_MD5wRSA:
2778
0
            return sigMd5wRsaName;
2779
0
        #endif
2780
0
        #ifndef NO_SHA
2781
0
        case CTC_SHAwRSA:
2782
0
            return sigSha1wRsaName;
2783
0
        #endif
2784
0
        #ifdef WOLFSSL_SHA224
2785
0
        case CTC_SHA224wRSA:
2786
0
            return sigSha224wRsaName;
2787
0
        #endif
2788
0
        #ifndef NO_SHA256
2789
0
        case CTC_SHA256wRSA:
2790
0
            return sigSha256wRsaName;
2791
0
        #endif
2792
0
        #ifdef WOLFSSL_SHA384
2793
0
        case CTC_SHA384wRSA:
2794
0
            return sigSha384wRsaName;
2795
0
        #endif
2796
0
        #ifdef WOLFSSL_SHA512
2797
0
        case CTC_SHA512wRSA:
2798
0
            return sigSha512wRsaName;
2799
0
        #endif
2800
0
        #ifdef WOLFSSL_SHA3
2801
0
        #ifndef WOLFSSL_NOSHA3_224
2802
0
        case CTC_SHA3_224wRSA:
2803
0
            return sigSha3_224wRsaName;
2804
0
        #endif
2805
0
        #ifndef WOLFSSL_NOSHA3_256
2806
0
        case CTC_SHA3_256wRSA:
2807
0
            return sigSha3_256wRsaName;
2808
0
        #endif
2809
0
        #ifndef WOLFSSL_NOSHA3_384
2810
0
        case CTC_SHA3_384wRSA:
2811
0
            return sigSha3_384wRsaName;
2812
0
        #endif
2813
0
        #ifndef WOLFSSL_NOSHA3_512
2814
0
        case CTC_SHA3_512wRSA:
2815
0
            return sigSha3_512wRsaName;
2816
0
        #endif
2817
0
        #endif
2818
0
        #ifdef WC_RSA_PSS
2819
0
        case CTC_RSASSAPSS:
2820
0
            return sigRsaSsaPssName;
2821
0
        #endif
2822
0
    #endif /* NO_RSA */
2823
0
    #ifdef HAVE_ECC
2824
0
        #ifndef NO_SHA
2825
0
        case CTC_SHAwECDSA:
2826
0
            return sigSha1wEcdsaName;
2827
0
        #endif
2828
0
        #ifdef WOLFSSL_SHA224
2829
0
        case CTC_SHA224wECDSA:
2830
0
            return sigSha224wEcdsaName;
2831
0
        #endif
2832
0
        #ifndef NO_SHA256
2833
0
        case CTC_SHA256wECDSA:
2834
0
            return sigSha256wEcdsaName;
2835
0
        #endif
2836
0
        #ifdef WOLFSSL_SHA384
2837
0
        case CTC_SHA384wECDSA:
2838
0
            return sigSha384wEcdsaName;
2839
0
        #endif
2840
0
        #ifdef WOLFSSL_SHA512
2841
0
        case CTC_SHA512wECDSA:
2842
0
            return sigSha512wEcdsaName;
2843
0
        #endif
2844
0
        #ifdef WOLFSSL_SHA3
2845
0
        #ifndef WOLFSSL_NOSHA3_224
2846
0
        case CTC_SHA3_224wECDSA:
2847
0
            return sigSha3_224wEcdsaName;
2848
0
        #endif
2849
0
        #ifndef WOLFSSL_NOSHA3_256
2850
0
        case CTC_SHA3_256wECDSA:
2851
0
            return sigSha3_256wEcdsaName;
2852
0
        #endif
2853
0
        #ifndef WOLFSSL_NOSHA3_384
2854
0
        case CTC_SHA3_384wECDSA:
2855
0
            return sigSha3_384wEcdsaName;
2856
0
        #endif
2857
0
        #ifndef WOLFSSL_NOSHA3_512
2858
0
        case CTC_SHA3_512wECDSA:
2859
0
            return sigSha3_512wEcdsaName;
2860
0
        #endif
2861
0
        #endif
2862
0
    #endif /* HAVE_ECC */
2863
0
        default:
2864
0
            return sigUnknownName;
2865
0
    }
2866
0
}
2867
2868
2869
#if !defined(WOLFSSL_ASN_TEMPLATE) || defined(HAVE_PKCS7) || \
2870
    defined(OPENSSL_EXTRA)
2871
#if !defined(NO_DSA) || defined(HAVE_ECC) || !defined(NO_CERTS) || \
2872
   (!defined(NO_RSA) && \
2873
        (defined(WOLFSSL_CERT_GEN) || \
2874
        ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(HAVE_USER_RSA))))
2875
/* Set the DER/BER encoding of the ASN.1 INTEGER header.
2876
 *
2877
 * When output is NULL, calculate the header length only.
2878
 *
2879
 * @param [in]  len        Length of INTEGER data in bytes.
2880
 * @param [in]  firstByte  First byte of data, most significant byte of integer,
2881
 *                         to encode.
2882
 * @param [out] output     Buffer to write into.
2883
 * @return  Number of bytes added to the buffer.
2884
 */
2885
int SetASNInt(int len, byte firstByte, byte* output)
2886
{
2887
    int idx = 0;
2888
2889
    if (output) {
2890
        /* Write out tag. */
2891
        output[idx] = ASN_INTEGER;
2892
    }
2893
    /* Step over tag. */
2894
    idx += ASN_TAG_SZ;
2895
    /* Check if first byte has top bit set in which case a 0 is needed to
2896
     * maintain positive value. */
2897
    if (firstByte & 0x80) {
2898
        /* Add pre-prepended byte to length of data in INTEGER. */
2899
        len++;
2900
    }
2901
    /* Encode length - passing NULL for output will not encode. */
2902
    idx += (int)SetLength((word32)len, output ? output + idx : NULL);
2903
    /* Put out pre-pended 0 as well. */
2904
    if (firstByte & 0x80) {
2905
        if (output) {
2906
            /* Write out 0 byte. */
2907
            output[idx] = 0x00;
2908
        }
2909
        /* Update index. */
2910
        idx++;
2911
    }
2912
2913
    /* Return index after header. */
2914
    return idx;
2915
}
2916
#endif
2917
#endif
2918
2919
#ifndef WOLFSSL_ASN_TEMPLATE
2920
#if !defined(NO_DSA) || defined(HAVE_ECC) || (defined(WOLFSSL_CERT_GEN) && \
2921
    !defined(NO_RSA)) || ((defined(WOLFSSL_KEY_GEN) || \
2922
    (!defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)) || \
2923
    defined(OPENSSL_EXTRA)) && !defined(NO_RSA) && !defined(HAVE_USER_RSA))
2924
/* Set the DER/BER encoding of the ASN.1 INTEGER element with an mp_int.
2925
 * The number is assumed to be positive.
2926
 *
2927
 * n       Multi-precision integer to encode.
2928
 * maxSz   Maximum size of the encoded integer.
2929
 *         A negative value indicates no check of length requested.
2930
 * output  Buffer to write into.
2931
 * returns BUFFER_E when the data is too long for the buffer.
2932
 *         MP_TO_E when encoding the integer fails.
2933
 *         Otherwise, the number of bytes added to the buffer.
2934
 */
2935
static int SetASNIntMP(mp_int* n, int maxSz, byte* output)
2936
{
2937
    int idx = 0;
2938
    int leadingBit;
2939
    int length;
2940
2941
    leadingBit = mp_leading_bit(n);
2942
    length = mp_unsigned_bin_size(n);
2943
    if (maxSz >= 0 && (1 + length + (leadingBit ? 1 : 0)) > maxSz)
2944
        return BUFFER_E;
2945
    idx = SetASNInt(length, (byte)(leadingBit ? 0x80U : 0x00U), output);
2946
    if (maxSz >= 0 && (idx + length) > maxSz)
2947
        return BUFFER_E;
2948
2949
    if (output) {
2950
        int err = mp_to_unsigned_bin(n, output + idx);
2951
        if (err != MP_OKAY)
2952
            return MP_TO_E;
2953
    }
2954
    idx += length;
2955
2956
    return idx;
2957
}
2958
#endif
2959
2960
#if !defined(NO_RSA) && defined(HAVE_USER_RSA) && \
2961
    (defined(WOLFSSL_CERT_GEN) || defined(OPENSSL_EXTRA))
2962
/* Set the DER/BER encoding of the ASN.1 INTEGER element with an mp_int from
2963
 * an RSA key.
2964
 * The number is assumed to be positive.
2965
 *
2966
 * n       Multi-precision integer to encode.
2967
 * output  Buffer to write into.
2968
 * returns BUFFER_E when the data is too long for the buffer.
2969
 *         MP_TO_E when encoding the integer fails.
2970
 *         Otherwise, the number of bytes added to the buffer.
2971
 */
2972
static int SetASNIntRSA(void* n, byte* output)
2973
{
2974
    int idx = 0;
2975
    int leadingBit;
2976
    int length;
2977
2978
    leadingBit = wc_Rsa_leading_bit(n);
2979
    length = wc_Rsa_unsigned_bin_size(n);
2980
    idx = SetASNInt(length, leadingBit ? 0x80 : 0x00, output);
2981
    if ((idx + length) > MAX_RSA_INT_SZ)
2982
        return BUFFER_E;
2983
2984
    if (output) {
2985
        int err = wc_Rsa_to_unsigned_bin(n, output + idx, length);
2986
        if (err != MP_OKAY)
2987
            return MP_TO_E;
2988
    }
2989
    idx += length;
2990
2991
    return idx;
2992
}
2993
#endif /* !NO_RSA && HAVE_USER_RSA && WOLFSSL_CERT_GEN */
2994
#endif /* !WOLFSSL_ASN_TEMPLATE */
2995
2996
#ifdef WOLFSSL_ASN_TEMPLATE
2997
/* ASN.1 template for an INTEGER. */
2998
static const ASNItem intASN[] = {
2999
/* INT */ { 0, ASN_INTEGER, 0, 0, 0 }
3000
};
3001
enum {
3002
    INTASN_IDX_INT = 0
3003
};
3004
3005
/* Number of items in ASN.1 template for an INTEGER. */
3006
0
#define intASN_Length (sizeof(intASN) / sizeof(ASNItem))
3007
#endif /* WOLFSSL_ASN_TEMPLATE */
3008
3009
/* Windows header clash for WinCE using GetVersion */
3010
/* Decode Version - one byte INTEGER.
3011
 *
3012
 * @param [in]      input     Buffer of BER data.
3013
 * @param [in, out] inOutIdx  On in, start of encoded Version.
3014
 *                            On out, start of next encode ASN.1 item.
3015
 * @param [out]     version   Number encoded in INTEGER.
3016
 * @param [in]      maxIdx    Maximum index of data in buffer.
3017
 * @return  0 on success.
3018
 * @return  ASN_PARSE_E when encoding is invalid.
3019
 * @return  BUFFER_E when data in buffer is too small.
3020
 * @return  ASN_EXPECT_0_E when the most significant bit is set.
3021
 */
3022
int GetMyVersion(const byte* input, word32* inOutIdx,
3023
                               int* version, word32 maxIdx)
3024
0
{
3025
#ifndef WOLFSSL_ASN_TEMPLATE
3026
    word32 idx = *inOutIdx;
3027
    byte   tag;
3028
3029
    if ((idx + MIN_VERSION_SZ) > maxIdx)
3030
        return ASN_PARSE_E;
3031
3032
    if (GetASNTag(input, &idx, &tag, maxIdx) != 0)
3033
        return ASN_PARSE_E;
3034
3035
    if (tag != ASN_INTEGER)
3036
        return ASN_PARSE_E;
3037
3038
    if (input[idx++] != 0x01)
3039
        return ASN_VERSION_E;
3040
3041
    *version  = input[idx++];
3042
    *inOutIdx = idx;
3043
3044
    return *version;
3045
#else
3046
0
    ASNGetData dataASN[intASN_Length];
3047
0
    int ret;
3048
0
    byte num;
3049
3050
    /* Clear dynamic data and set the version number variable. */
3051
0
    XMEMSET(dataASN, 0, sizeof(dataASN));
3052
0
    GetASN_Int8Bit(&dataASN[INTASN_IDX_INT], &num);
3053
    /* Decode the version (INTEGER). */
3054
0
    ret = GetASN_Items(intASN, dataASN, intASN_Length, 0, input, inOutIdx,
3055
0
                       maxIdx);
3056
0
    if (ret == 0) {
3057
        /* Return version through variable and return value. */
3058
0
        *version = num;
3059
0
        ret = num;
3060
0
    }
3061
0
    return ret;
3062
0
#endif /* WOLFSSL_ASN_TEMPLATE */
3063
0
}
3064
3065
3066
#ifndef NO_PWDBASED
3067
/* Decode small integer, 32 bits or less.
3068
 *
3069
 * @param [in]      input     Buffer of BER data.
3070
 * @param [in, out] inOutIdx  On in, start of encoded INTEGER.
3071
 *                            On out, start of next encode ASN.1 item.
3072
 * @param [out]     number    Number encoded in INTEGER.
3073
 * @param [in]      maxIdx    Maximum index of data in buffer.
3074
 * @return  0 on success.
3075
 * @return  ASN_PARSE_E when encoding is invalid.
3076
 * @return  BUFFER_E when data in buffer is too small.
3077
 * @return  ASN_EXPECT_0_E when the most significant bit is set.
3078
 */
3079
int GetShortInt(const byte* input, word32* inOutIdx, int* number, word32 maxIdx)
3080
0
{
3081
#ifndef WOLFSSL_ASN_TEMPLATE
3082
    word32 idx = *inOutIdx;
3083
    word32 len;
3084
    byte   tag;
3085
3086
    *number = 0;
3087
3088
    /* check for type and length bytes */
3089
    if ((idx + 2) > maxIdx)
3090
        return BUFFER_E;
3091
3092
    if (GetASNTag(input, &idx, &tag, maxIdx) != 0)
3093
        return ASN_PARSE_E;
3094
3095
    if (tag != ASN_INTEGER)
3096
        return ASN_PARSE_E;
3097
3098
    len = input[idx++];
3099
    if (len > 4)
3100
        return ASN_PARSE_E;
3101
3102
    if (len + idx > maxIdx)
3103
        return ASN_PARSE_E;
3104
3105
    while (len--) {
3106
        *number  = *number << 8 | input[idx++];
3107
    }
3108
3109
    *inOutIdx = idx;
3110
3111
    return *number;
3112
#else
3113
0
    ASNGetData dataASN[intASN_Length];
3114
0
    int ret;
3115
0
    word32 num;
3116
3117
    /* Clear dynamic data and set the 32-bit number variable. */
3118
0
    XMEMSET(dataASN, 0, sizeof(dataASN));
3119
0
    GetASN_Int32Bit(&dataASN[INTASN_IDX_INT], &num);
3120
    /* Decode the short int (INTEGER). */
3121
0
    ret = GetASN_Items(intASN, dataASN, intASN_Length, 0, input, inOutIdx,
3122
0
                       maxIdx);
3123
0
    if (ret == 0) {
3124
        /* Return number through variable and return value. */
3125
0
        *number = (int)num;
3126
0
        ret = (int)num;
3127
0
    }
3128
0
    return ret;
3129
0
#endif
3130
0
}
3131
3132
3133
#if !defined(WOLFSSL_ASN_TEMPLATE) || defined(HAVE_PKCS8) || \
3134
     defined(HAVE_PKCS12)
3135
/* Set small integer, 32 bits or less. DER encoding with no leading 0s
3136
 * returns total amount written including ASN tag and length byte on success */
3137
int SetShortInt(byte* input, word32* inOutIdx, word32 number, word32 maxIdx)
3138
0
{
3139
0
    word32 idx = *inOutIdx;
3140
0
    int    len = 0;
3141
0
    int    i;
3142
0
    byte ar[MAX_LENGTH_SZ];
3143
3144
    /* check for room for type and length bytes */
3145
0
    if ((idx + 2) > maxIdx)
3146
0
        return BUFFER_E;
3147
3148
0
    input[idx++] = ASN_INTEGER;
3149
0
    idx++; /* place holder for length byte */
3150
0
    if (MAX_LENGTH_SZ + idx > maxIdx)
3151
0
        return ASN_PARSE_E;
3152
3153
    /* find first non zero byte */
3154
0
    XMEMSET(ar, 0, MAX_LENGTH_SZ);
3155
0
    c32toa(number, ar);
3156
0
    for (i = 0; i < MAX_LENGTH_SZ; i++) {
3157
0
        if (ar[i] != 0) {
3158
0
            break;
3159
0
        }
3160
0
    }
3161
3162
    /* handle case of 0 */
3163
0
    if (i == MAX_LENGTH_SZ) {
3164
0
        input[idx++] = 0; len++;
3165
0
    }
3166
3167
0
    for (; i < MAX_LENGTH_SZ && idx < maxIdx; i++) {
3168
0
        input[idx++] = ar[i]; len++;
3169
0
    }
3170
3171
    /* jump back to beginning of input buffer using unaltered inOutIdx value
3172
     * and set number of bytes for integer, then update the index value */
3173
0
    input[*inOutIdx + 1] = (byte)len;
3174
0
    *inOutIdx = idx;
3175
3176
0
    return len + 2; /* size of integer bytes plus ASN TAG and length byte */
3177
0
}
3178
#endif /* !WOLFSSL_ASN_TEMPLATE || HAVE_PKCS8 || HAVE_PKCS12 */
3179
#endif /* !NO_PWDBASED */
3180
3181
#if !defined(WOLFSSL_ASN_TEMPLATE) && !defined(NO_CERTS)
3182
/* May not have one, not an error */
3183
static int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version,
3184
                              word32 maxIdx)
3185
{
3186
    word32 idx = *inOutIdx;
3187
    byte tag;
3188
3189
    WOLFSSL_ENTER("GetExplicitVersion");
3190
3191
    if (GetASNTag(input, &idx, &tag, maxIdx) != 0)
3192
        return ASN_PARSE_E;
3193
3194
    if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
3195
        int ret;
3196
3197
        *inOutIdx = ++idx;  /* skip header */
3198
        ret = GetMyVersion(input, inOutIdx, version, maxIdx);
3199
        if (ret >= 0) {
3200
            /* check if version is expected value rfc 5280 4.1 {0, 1, 2} */
3201
            if (*version > MAX_X509_VERSION || *version < MIN_X509_VERSION) {
3202
                WOLFSSL_MSG("Unexpected certificate version");
3203
                WOLFSSL_ERROR_VERBOSE(ASN_VERSION_E);
3204
                ret = ASN_VERSION_E;
3205
            }
3206
        }
3207
        return ret;
3208
    }
3209
3210
    /* go back as is */
3211
    *version = 0;
3212
3213
    return 0;
3214
}
3215
#endif
3216
3217
/* Decode small integer, 32 bits or less.
3218
 *
3219
 * mp_int is initialized.
3220
 *
3221
 * @param [out]     mpi       mp_int to hold number.
3222
 * @param [in]      input     Buffer of BER data.
3223
 * @param [in, out] inOutIdx  On in, start of encoded INTEGER.
3224
 *                            On out, start of next encode ASN.1 item.
3225
 * @param [in]      maxIdx    Maximum index of data in buffer.
3226
 * @return  0 on success.
3227
 * @return  ASN_PARSE_E when encoding is invalid.
3228
 * @return  BUFFER_E when data in buffer is too small.
3229
 * @return  ASN_EXPECT_0_E when the most significant bit is set.
3230
 * @return  MP_INIT_E when the unable to initialize an mp_int.
3231
 * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
3232
 */
3233
int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx, word32 maxIdx)
3234
0
{
3235
#ifndef WOLFSSL_ASN_TEMPLATE
3236
    word32 idx = *inOutIdx;
3237
    int    ret;
3238
    int    length;
3239
3240
    ret = GetASNInt(input, &idx, &length, maxIdx);
3241
    if (ret != 0)
3242
        return ret;
3243
3244
    if (mp_init(mpi) != MP_OKAY)
3245
        return MP_INIT_E;
3246
3247
    if (mp_read_unsigned_bin(mpi, input + idx, (word32)length) != 0) {
3248
        mp_clear(mpi);
3249
        return ASN_GETINT_E;
3250
    }
3251
3252
#ifdef HAVE_WOLF_BIGINT
3253
    if (wc_bigint_from_unsigned_bin(&mpi->raw, input + idx, length) != 0) {
3254
        mp_clear(mpi);
3255
        return ASN_GETINT_E;
3256
    }
3257
#endif /* HAVE_WOLF_BIGINT */
3258
3259
    *inOutIdx = idx + (word32)length;
3260
3261
    return 0;
3262
#else
3263
0
    ASNGetData dataASN[intASN_Length];
3264
3265
    /* Clear dynamic data and set the mp_int to fill with value. */
3266
0
    XMEMSET(dataASN, 0, sizeof(dataASN));
3267
0
    GetASN_MP_PosNeg(&dataASN[INTASN_IDX_INT], mpi);
3268
    /* Decode the big number (INTEGER). */
3269
0
    return GetASN_Items(intASN, dataASN, intASN_Length, 0, input, inOutIdx,
3270
0
                        maxIdx);
3271
0
#endif
3272
0
}
3273
3274
#if (defined(HAVE_ECC) || !defined(NO_DSA)) && !defined(WOLFSSL_ASN_TEMPLATE)
3275
static int GetIntPositive(mp_int* mpi, const byte* input, word32* inOutIdx,
3276
    word32 maxIdx, int initNum)
3277
{
3278
    word32 idx = *inOutIdx;
3279
    int    ret;
3280
    int    length;
3281
3282
    ret = GetASNInt(input, &idx, &length, maxIdx);
3283
    if (ret != 0)
3284
        return ret;
3285
3286
    if (((input[idx] & 0x80) == 0x80) && (input[idx - 1] != 0x00))
3287
        return MP_INIT_E;
3288
3289
    if (initNum) {
3290
        if (mp_init(mpi) != MP_OKAY)
3291
            return MP_INIT_E;
3292
    }
3293
3294
    if (mp_read_unsigned_bin(mpi, input + idx, (word32)length) != 0) {
3295
        mp_clear(mpi);
3296
        return ASN_GETINT_E;
3297
    }
3298
3299
#ifdef HAVE_WOLF_BIGINT
3300
    if (wc_bigint_from_unsigned_bin(&mpi->raw, input + idx, length) != 0) {
3301
        mp_clear(mpi);
3302
        return ASN_GETINT_E;
3303
    }
3304
#endif /* HAVE_WOLF_BIGINT */
3305
3306
    *inOutIdx = idx + (word32)length;
3307
3308
    return 0;
3309
}
3310
#endif /* (ECC || !NO_DSA) && !WOLFSSL_ASN_TEMPLATE */
3311
3312
#ifndef WOLFSSL_ASN_TEMPLATE
3313
#if (!defined(NO_RSA) && !defined(HAVE_USER_RSA)) || !defined(NO_DSA)
3314
static int SkipInt(const byte* input, word32* inOutIdx, word32 maxIdx)
3315
{
3316
    word32 idx = *inOutIdx;
3317
    int    ret;
3318
    int    length;
3319
3320
    ret = GetASNInt(input, &idx, &length, maxIdx);
3321
    if (ret != 0)
3322
        return ret;
3323
3324
    *inOutIdx = idx + (word32)length;
3325
3326
    return 0;
3327
}
3328
#endif
3329
#endif /* !WOLFSSL_ASN_TEMPLATE */
3330
3331
#ifdef WOLFSSL_ASN_TEMPLATE
3332
/* ASN.1 template for a BIT_STRING. */
3333
static const ASNItem bitStringASN[] = {
3334
/* BIT_STR */ { 0, ASN_BIT_STRING, 0, 1, 0 }
3335
};
3336
enum {
3337
    BITSTRINGASN_IDX_BIT_STR = 0
3338
};
3339
3340
/* Number of items in ASN.1 template for a BIT_STRING. */
3341
0
#define bitStringASN_Length (sizeof(bitStringASN) / sizeof(ASNItem))
3342
#endif
3343
3344
/* Decode and check the BIT_STRING is valid. Return length and unused bits.
3345
 *
3346
 * @param [in]      input       Buffer holding BER encoding.
3347
 * @param [in, out] inOutIdx    On in, start of BIT_STRING.
3348
 *                              On out, start of ASN.1 item after BIT_STRING.
3349
 * @param [out]     len         Length of BIT_STRING data.
3350
 * @param [in]      maxIdx      Maximum index of data in buffer.
3351
 * @param [in]      zeroBits    Indicates whether zero unused bits is expected.
3352
 * @param [in]      unusedBits  Number of unused bits in last byte.
3353
 * @return  0 on success.
3354
 * @return  ASN_PARSE_E when encoding is invalid.
3355
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
3356
 * @return  BUFFER_E when data in buffer is too small.
3357
 * @return  ASN_EXPECT_0_E when unused bits is not zero when expected.
3358
 */
3359
int CheckBitString(const byte* input, word32* inOutIdx, int* len,
3360
                          word32 maxIdx, int zeroBits, byte* unusedBits)
3361
0
{
3362
#ifndef WOLFSSL_ASN_TEMPLATE
3363
    word32 idx = *inOutIdx;
3364
    int    length;
3365
    byte   b;
3366
3367
    if (GetASNTag(input, &idx, &b, maxIdx) != 0) {
3368
        return ASN_BITSTR_E;
3369
    }
3370
3371
    if (b != ASN_BIT_STRING) {
3372
        return ASN_BITSTR_E;
3373
    }
3374
3375
    if (GetLength(input, &idx, &length, maxIdx) < 0)
3376
        return ASN_PARSE_E;
3377
3378
    /* extra sanity check that length is greater than 0 */
3379
    if (length <= 0) {
3380
        WOLFSSL_MSG("Error length was 0 in CheckBitString");
3381
        return BUFFER_E;
3382
    }
3383
3384
    if (idx + 1 > maxIdx) {
3385
        WOLFSSL_MSG("Attempted buffer read larger than input buffer");
3386
        return BUFFER_E;
3387
    }
3388
3389
    b = input[idx];
3390
    if (zeroBits && b != 0x00)
3391
        return ASN_EXPECT_0_E;
3392
    if (b >= 0x08)
3393
        return ASN_PARSE_E;
3394
    if (b != 0) {
3395
        if ((byte)(input[idx + (word32)length - 1] << (8 - b)) != 0)
3396
            return ASN_PARSE_E;
3397
    }
3398
    idx++;
3399
    length--; /* length has been checked for greater than 0 */
3400
3401
    *inOutIdx = idx;
3402
    if (len != NULL)
3403
        *len = length;
3404
    if (unusedBits != NULL)
3405
        *unusedBits = b;
3406
3407
    return 0;
3408
#else
3409
0
    ASNGetData dataASN[bitStringASN_Length];
3410
0
    int ret;
3411
0
    int bits;
3412
3413
    /* Parse BIT_STRING and check validity of unused bits. */
3414
0
    XMEMSET(dataASN, 0, sizeof(dataASN));
3415
    /* Decode BIT_STRING. */
3416
0
    ret = GetASN_Items(bitStringASN, dataASN, bitStringASN_Length, 0, input,
3417
0
            inOutIdx, maxIdx);
3418
0
    if (ret == 0) {
3419
        /* Get unused bits from dynamic ASN.1 data. */
3420
0
        bits = GetASNItem_UnusedBits(dataASN[BITSTRINGASN_IDX_BIT_STR]);
3421
        /* Check unused bits is 0 when expected. */
3422
0
        if (zeroBits && (bits != 0)) {
3423
0
            ret = ASN_EXPECT_0_E;
3424
0
        }
3425
0
    }
3426
0
    if (ret == 0) {
3427
        /* Return length of data and unused bits if required. */
3428
0
        if (len != NULL) {
3429
0
            *len = (int)dataASN[BITSTRINGASN_IDX_BIT_STR].data.ref.length;
3430
0
        }
3431
0
        if (unusedBits != NULL) {
3432
0
            *unusedBits = (byte)bits;
3433
0
        }
3434
0
    }
3435
3436
0
    return ret;
3437
0
#endif
3438
0
}
3439
3440
/* RSA (with CertGen or KeyGen) OR ECC OR ED25519 OR ED448 (with CertGen or
3441
 * KeyGen) */
3442
#if (!defined(NO_RSA) && !defined(HAVE_USER_RSA) && \
3443
     (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || \
3444
      defined(OPENSSL_EXTRA))) || \
3445
    (defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)) || \
3446
    ((defined(HAVE_ED25519) || defined(HAVE_ED448)) && \
3447
     (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || \
3448
      defined(OPENSSL_EXTRA))) || \
3449
    (defined(WC_ENABLE_ASYM_KEY_EXPORT) && !defined(NO_CERT)) || \
3450
    (!defined(NO_DSA) && !defined(HAVE_SELFTEST) && defined(WOLFSSL_KEY_GEN)) || \
3451
    (!defined(NO_DH) && defined(WOLFSSL_DH_EXTRA))
3452
3453
/* Set the DER/BER encoding of the ASN.1 BIT STRING header.
3454
 *
3455
 * When output is NULL, calculate the header length only.
3456
 *
3457
 * @param [in]  len         Length of BIT STRING data.
3458
 *                          That is, the number of least significant zero bits
3459
 *                          before a one.
3460
 *                          The last byte is the most-significant non-zero byte
3461
 *                          of a number.
3462
 * @param [out] output      Buffer to write into.
3463
 * @return  Number of bytes added to the buffer.
3464
 */
3465
word32 SetBitString(word32 len, byte unusedBits, byte* output)
3466
0
{
3467
0
    word32 idx = 0;
3468
3469
0
    if (output) {
3470
        /* Write out tag. */
3471
0
        output[idx] = ASN_BIT_STRING;
3472
0
    }
3473
    /* Step over tag. */
3474
0
    idx += ASN_TAG_SZ;
3475
3476
    /* Encode length - passing NULL for output will not encode.
3477
     * Add one to length for unused bits. */
3478
0
    idx += SetLength(len + 1, output ? output + idx : NULL);
3479
0
    if (output) {
3480
        /* Write out unused bits. */
3481
0
        output[idx] = unusedBits;
3482
0
    }
3483
    /* Skip over unused bits. */
3484
0
    idx++;
3485
3486
    /* Return index after header. */
3487
0
    return idx;
3488
0
}
3489
#endif /* !NO_RSA || HAVE_ECC || HAVE_ED25519 || HAVE_ED448 */
3490
3491
#ifdef ASN_BER_TO_DER
3492
/* Convert BER to DER */
3493
3494
/* Pull informtation from the ASN.1 BER encoded item header */
3495
static int GetBerHeader(const byte* data, word32* idx, word32 maxIdx,
3496
                        byte* pTag, word32* pLen, int* indef)
3497
{
3498
    int len = 0;
3499
    byte tag;
3500
    word32 i = *idx;
3501
3502
    *indef = 0;
3503
3504
    /* Check there is enough data for a minimal header */
3505
    if (i + 2 > maxIdx) {
3506
        return ASN_PARSE_E;
3507
    }
3508
3509
    /* Retrieve tag */
3510
    tag = data[i++];
3511
3512
    /* Indefinite length handled specially */
3513
    if (data[i] == ASN_INDEF_LENGTH) {
3514
        /* Check valid tag for indefinite */
3515
        if (((tag & 0xc0) == 0) && ((tag & ASN_CONSTRUCTED) == 0x00)) {
3516
            return ASN_PARSE_E;
3517
        }
3518
        i++;
3519
        *indef = 1;
3520
    }
3521
    else if (GetLength(data, &i, &len, maxIdx) < 0) {
3522
        return ASN_PARSE_E;
3523
    }
3524
3525
    /* Return tag, length and index after BER item header */
3526
    *pTag = tag;
3527
    *pLen = (word32)len;
3528
    *idx = i;
3529
    return 0;
3530
}
3531
3532
#ifndef INDEF_ITEMS_MAX
3533
#define INDEF_ITEMS_MAX       20
3534
#endif
3535
3536
/* Indef length item data */
3537
typedef struct Indef {
3538
    word32 start;
3539
    int depth;
3540
    int headerLen;
3541
    word32 len;
3542
} Indef;
3543
3544
/* Indef length items */
3545
typedef struct IndefItems
3546
{
3547
    Indef len[INDEF_ITEMS_MAX];
3548
    int cnt;
3549
    int idx;
3550
    int depth;
3551
} IndefItems;
3552
3553
3554
/* Get header length of current item */
3555
static int IndefItems_HeaderLen(IndefItems* items)
3556
{
3557
    return items->len[items->idx].headerLen;
3558
}
3559
3560
/* Get data length of current item */
3561
static word32 IndefItems_Len(IndefItems* items)
3562
{
3563
    return items->len[items->idx].len;
3564
}
3565
3566
/* Add a indefinite length item */
3567
static int IndefItems_AddItem(IndefItems* items, word32 start)
3568
{
3569
    int ret = 0;
3570
    int i;
3571
3572
    if (items->cnt == INDEF_ITEMS_MAX) {
3573
        ret = MEMORY_E;
3574
    }
3575
    else {
3576
        i = items->cnt++;
3577
        items->len[i].start = start;
3578
        items->len[i].depth = items->depth++;
3579
        items->len[i].headerLen = 1;
3580
        items->len[i].len = 0;
3581
        items->idx = i;
3582
    }
3583
3584
    return ret;
3585
}
3586
3587
/* Increase data length of current item */
3588
static void IndefItems_AddData(IndefItems* items, word32 length)
3589
{
3590
    items->len[items->idx].len += length;
3591
}
3592
3593
/* Update header length of current item to reflect data length */
3594
static void IndefItems_UpdateHeaderLen(IndefItems* items)
3595
{
3596
    items->len[items->idx].headerLen +=
3597
                               (int)SetLength(items->len[items->idx].len, NULL);
3598
}
3599
3600
/* Go to indefinite parent of current item */
3601
static void IndefItems_Up(IndefItems* items)
3602
{
3603
    int i;
3604
    int depth = items->len[items->idx].depth - 1;
3605
3606
    for (i = items->cnt - 1; i >= 0; i--) {
3607
        if (items->len[i].depth == depth) {
3608
            break;
3609
        }
3610
    }
3611
    items->idx = i;
3612
    items->depth = depth + 1;
3613
}
3614
3615
/* Calculate final length by adding length of indefinite child items */
3616
static void IndefItems_CalcLength(IndefItems* items)
3617
{
3618
    int i;
3619
    int idx = items->idx;
3620
3621
    for (i = idx + 1; i < items->cnt; i++) {
3622
        if (items->len[i].depth == items->depth) {
3623
            items->len[idx].len += (word32)items->len[i].headerLen;
3624
            items->len[idx].len += items->len[i].len;
3625
        }
3626
    }
3627
    items->len[idx].headerLen += (int)SetLength(items->len[idx].len, NULL);
3628
}
3629
3630
/* Add more data to indefinite length item */
3631
static void IndefItems_MoreData(IndefItems* items, word32 length)
3632
{
3633
    if (items->cnt > 0 && items->idx >= 0) {
3634
        items->len[items->idx].len += length;
3635
    }
3636
}
3637
3638
/* Convert a BER encoding with indefinite length items to DER.
3639
 *
3640
 * ber    BER encoded data.
3641
 * berSz  Length of BER encoded data.
3642
 * der    Buffer to hold DER encoded version of data.
3643
 *        NULL indicates only the length is required.
3644
 * derSz  The size of the buffer to hold the DER encoded data.
3645
 *        Will be set if der is NULL, otherwise the value is checked as der is
3646
 *        filled.
3647
 * returns ASN_PARSE_E if the BER data is invalid and BAD_FUNC_ARG if ber or
3648
 * derSz are NULL.
3649
 */
3650
int wc_BerToDer(const byte* ber, word32 berSz, byte* der, word32* derSz)
3651
{
3652
    int ret = 0;
3653
    word32 i, j;
3654
#ifdef WOLFSSL_SMALL_STACK
3655
    IndefItems* indefItems = NULL;
3656
#else
3657
    IndefItems indefItems[1];
3658
#endif
3659
    byte tag, basic;
3660
    word32 length;
3661
    int indef;
3662
3663
    if (ber == NULL || derSz == NULL)
3664
        return BAD_FUNC_ARG;
3665
3666
#ifdef WOLFSSL_SMALL_STACK
3667
    indefItems = (IndefItems *)XMALLOC(sizeof(IndefItems), NULL,
3668
                                                       DYNAMIC_TYPE_TMP_BUFFER);
3669
    if (indefItems == NULL) {
3670
        ret = MEMORY_E;
3671
        goto end;
3672
    }
3673
#endif
3674
3675
    XMEMSET(indefItems, 0, sizeof(*indefItems));
3676
3677
    /* Calculate indefinite item lengths */
3678
    for (i = 0; i < berSz; ) {
3679
        word32 start = i;
3680
3681
        /* Get next BER item */
3682
        ret = GetBerHeader(ber, &i, berSz, &tag, &length, &indef);
3683
        if (ret != 0) {
3684
            goto end;
3685
        }
3686
3687
        if (indef) {
3688
            /* Indefinite item - add to list */
3689
            ret = IndefItems_AddItem(indefItems, i);
3690
            if (ret != 0) {
3691
                goto end;
3692
            }
3693
3694
            if ((tag & 0xC0) == 0 &&
3695
                tag != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&
3696
                tag != (ASN_SET      | ASN_CONSTRUCTED)) {
3697
                /* Constructed basic type - get repeating tag */
3698
                basic = (byte)(tag & (~ASN_CONSTRUCTED));
3699
3700
                /* Add up lengths of each item below */
3701
                for (; i < berSz; ) {
3702
                    /* Get next BER_item */
3703
                    ret = GetBerHeader(ber, &i, berSz, &tag, &length, &indef);
3704
                    if (ret != 0) {
3705
                        goto end;
3706
                    }
3707
3708
                    /* End of content closes item */
3709
                    if (tag == ASN_EOC) {
3710
                        /* Must be zero length */
3711
                        if (length != 0) {
3712
                            ret = ASN_PARSE_E;
3713
                            goto end;
3714
                        }
3715
                        break;
3716
                    }
3717
3718
                    /* Must not be indefinite and tag must match parent */
3719
                    if (indef || tag != basic) {
3720
                        ret = ASN_PARSE_E;
3721
                        goto end;
3722
                    }
3723
3724
                    /* Add to length */
3725
                    IndefItems_AddData(indefItems, length);
3726
                    /* Skip data */
3727
                    i += length;
3728
                }
3729
3730
                /* Ensure we got an EOC and not end of data */
3731
                if (tag != ASN_EOC) {
3732
                    ret = ASN_PARSE_E;
3733
                    goto end;
3734
                }
3735
3736
                /* Set the header length to include the length field */
3737
                IndefItems_UpdateHeaderLen(indefItems);
3738
                /* Go to indefinite parent item */
3739
                IndefItems_Up(indefItems);
3740
            }
3741
        }
3742
        else if (tag == ASN_EOC) {
3743
            /* End-of-content must be 0 length */
3744
            if (length != 0) {
3745
                ret = ASN_PARSE_E;
3746
                goto end;
3747
            }
3748
            /* Check there is an item to close - missing EOC */
3749
            if (indefItems->depth == 0) {
3750
                ret = ASN_PARSE_E;
3751
                goto end;
3752
            }
3753
3754
            /* Finish calculation of data length for indefinite item */
3755
            IndefItems_CalcLength(indefItems);
3756
            /* Go to indefinite parent item */
3757
            IndefItems_Up(indefItems);
3758
        }
3759
        else {
3760
            /* Known length item to add in - make sure enough data for it */
3761
            if (i + length > berSz) {
3762
                ret = ASN_PARSE_E;
3763
                goto end;
3764
            }
3765
3766
            /* Include all data - can't have indefinite inside definite */
3767
            i += length;
3768
            /* Add entire item to current indefinite item */
3769
            IndefItems_MoreData(indefItems, i - start);
3770
        }
3771
    }
3772
    /* Check we had a EOC for each indefinite item */
3773
    if (indefItems->depth != 0) {
3774
        ret = ASN_PARSE_E;
3775
        goto end;
3776
    }
3777
3778
    /* Write out DER */
3779
3780
    j = 0;
3781
    /* Reset index */
3782
    indefItems->idx = 0;
3783
    for (i = 0; i < berSz; ) {
3784
        word32 start = i;
3785
3786
        /* Get item - checked above */
3787
        (void)GetBerHeader(ber, &i, berSz, &tag, &length, &indef);
3788
        if (indef) {
3789
            if (der != NULL) {
3790
                /* Check enough space for header */
3791
                if (j + (word32)IndefItems_HeaderLen(indefItems) > *derSz) {
3792
                    ret = BUFFER_E;
3793
                    goto end;
3794
                }
3795
3796
                if ((tag & 0xC0) == 0 &&
3797
                    tag != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&
3798
                    tag != (ASN_SET      | ASN_CONSTRUCTED)) {
3799
                    /* Remove constructed tag for basic types */
3800
                    tag &= (byte)~ASN_CONSTRUCTED;
3801
                }
3802
                /* Add tag and length */
3803
                der[j] = tag;
3804
                (void)SetLength(IndefItems_Len(indefItems), der + j + 1);
3805
            }
3806
            /* Add header length of indefinite item */
3807
            j += (word32)IndefItems_HeaderLen(indefItems);
3808
3809
            if ((tag & 0xC0) == 0 &&
3810
                tag != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&
3811
                tag != (ASN_SET      | ASN_CONSTRUCTED)) {
3812
                /* For basic type - get each child item and add data */
3813
                for (; i < berSz; ) {
3814
                    (void)GetBerHeader(ber, &i, berSz, &tag, &length, &indef);
3815
                    if (tag == ASN_EOC) {
3816
                        break;
3817
                    }
3818
                    if (der != NULL) {
3819
                        if (j + length > *derSz) {
3820
                            ret = BUFFER_E;
3821
                            goto end;
3822
                        }
3823
                        XMEMCPY(der + j, ber + i, length);
3824
                    }
3825
                    j += length;
3826
                    i += length;
3827
                }
3828
            }
3829
3830
            /* Move to next indef item in list */
3831
            indefItems->idx++;
3832
        }
3833
        else if (tag == ASN_EOC) {
3834
            /* End-Of-Content is not written out in DER */
3835
        }
3836
        else {
3837
            /* Write out definite length item as is. */
3838
            i += length;
3839
            if (der != NULL) {
3840
                /* Ensure space for item */
3841
                if (j + i - start > *derSz) {
3842
                    ret = BUFFER_E;
3843
                    goto end;
3844
                }
3845
                /* Copy item as is */
3846
                XMEMCPY(der + j, ber + start, i - start);
3847
            }
3848
            j += i - start;
3849
        }
3850
    }
3851
3852
    /* Return the length of the DER encoded ASN.1 */
3853
    *derSz = j;
3854
    if (der == NULL) {
3855
        ret = LENGTH_ONLY_E;
3856
    }
3857
end:
3858
#ifdef WOLFSSL_SMALL_STACK
3859
    if (indefItems != NULL) {
3860
        XFREE(indefItems, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3861
    }
3862
#endif
3863
    return ret;
3864
}
3865
#endif
3866
3867
#ifndef WOLFSSL_ASN_TEMPLATE
3868
#if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)
3869
/* Set the DER/BER encoding of the ASN.1 BIT_STRING with a 16-bit value.
3870
 *
3871
 * val         16-bit value to encode.
3872
 * output      Buffer to write into.
3873
 * returns the number of bytes added to the buffer.
3874
 */
3875
static word32 SetBitString16Bit(word16 val, byte* output)
3876
{
3877
    word32 idx;
3878
    int    len;
3879
    byte   lastByte;
3880
    byte   unusedBits = 0;
3881
3882
    if ((val >> 8) != 0) {
3883
        len = 2;
3884
        lastByte = (byte)(val >> 8);
3885
    }
3886
    else {
3887
        len = 1;
3888
        lastByte = (byte)val;
3889
    }
3890
3891
    while (((lastByte >> unusedBits) & 0x01) == 0x00)
3892
        unusedBits++;
3893
3894
    idx = SetBitString((word32)len, unusedBits, output);
3895
    output[idx++] = (byte)val;
3896
    if (len > 1)
3897
        output[idx++] = (byte)(val >> 8);
3898
3899
    return idx;
3900
}
3901
#endif /* WOLFSSL_CERT_EXT || WOLFSSL_CERT_GEN */
3902
#endif /* !WOLFSSL_ASN_TEMPLATE */
3903
3904
/* hashType */
3905
#ifdef WOLFSSL_MD2
3906
    static const byte hashMd2hOid[] = {42, 134, 72, 134, 247, 13, 2, 2};
3907
#endif
3908
#ifndef NO_MD5
3909
    static const byte hashMd5hOid[] = {42, 134, 72, 134, 247, 13, 2, 5};
3910
#endif
3911
#ifndef NO_SHA
3912
    static const byte hashSha1hOid[] = {43, 14, 3, 2, 26};
3913
#endif
3914
#ifdef WOLFSSL_SHA224
3915
    static const byte hashSha224hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 4};
3916
#endif
3917
#ifndef NO_SHA256
3918
    static const byte hashSha256hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 1};
3919
#endif
3920
#ifdef WOLFSSL_SHA384
3921
    static const byte hashSha384hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 2};
3922
#endif
3923
#ifdef WOLFSSL_SHA512
3924
    static const byte hashSha512hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 3};
3925
    #ifndef WOLFSSL_NOSHA512_224
3926
    static const byte hashSha512_224hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 5};
3927
    #endif
3928
    #ifndef WOLFSSL_NOSHA512_256
3929
    static const byte hashSha512_256hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 6};
3930
    #endif
3931
#endif
3932
#ifdef WOLFSSL_SHA3
3933
#ifndef WOLFSSL_NOSHA3_224
3934
    static const byte hashSha3_224hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 7};
3935
#endif /* WOLFSSL_NOSHA3_224 */
3936
#ifndef WOLFSSL_NOSHA3_256
3937
    static const byte hashSha3_256hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 8};
3938
#endif /* WOLFSSL_NOSHA3_256 */
3939
#ifndef WOLFSSL_NOSHA3_384
3940
    static const byte hashSha3_384hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 9};
3941
#endif /* WOLFSSL_NOSHA3_384 */
3942
#ifndef WOLFSSL_NOSHA3_512
3943
    static const byte hashSha3_512hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 10};
3944
#endif /* WOLFSSL_NOSHA3_512 */
3945
#endif /* WOLFSSL_SHA3 */
3946
3947
/* hmacType */
3948
#ifndef NO_HMAC
3949
    #ifdef WOLFSSL_SHA224
3950
    static const byte hmacSha224Oid[] = {42, 134, 72, 134, 247, 13, 2, 8};
3951
    #endif
3952
    #ifndef NO_SHA256
3953
    static const byte hmacSha256Oid[] = {42, 134, 72, 134, 247, 13, 2, 9};
3954
    #endif
3955
    #ifdef WOLFSSL_SHA384
3956
    static const byte hmacSha384Oid[] = {42, 134, 72, 134, 247, 13, 2, 10};
3957
    #endif
3958
    #ifdef WOLFSSL_SHA512
3959
    static const byte hmacSha512Oid[] = {42, 134, 72, 134, 247, 13, 2, 11};
3960
    #endif
3961
#endif
3962
3963
/* sigType */
3964
#if !defined(NO_DSA) && !defined(NO_SHA)
3965
    static const byte sigSha1wDsaOid[] = {42, 134, 72, 206, 56, 4, 3};
3966
    static const byte sigSha256wDsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 2};
3967
#endif /* NO_DSA */
3968
#ifndef NO_RSA
3969
    #ifdef WOLFSSL_MD2
3970
    static const byte sigMd2wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 2};
3971
    #endif
3972
    #ifndef NO_MD5
3973
    static const byte sigMd5wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 4};
3974
    #endif
3975
    #ifndef NO_SHA
3976
    static const byte sigSha1wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 5};
3977
    #endif
3978
    #ifdef WOLFSSL_SHA224
3979
    static const byte sigSha224wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,14};
3980
    #endif
3981
    #ifndef NO_SHA256
3982
    static const byte sigSha256wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,11};
3983
    #endif
3984
    #ifdef WOLFSSL_SHA384
3985
    static const byte sigSha384wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,12};
3986
    #endif
3987
    #ifdef WOLFSSL_SHA512
3988
    static const byte sigSha512wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,13};
3989
    #endif
3990
    #ifdef WOLFSSL_SHA3
3991
    #ifndef WOLFSSL_NOSHA3_224
3992
    static const byte sigSha3_224wRsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 13};
3993
    #endif
3994
    #ifndef WOLFSSL_NOSHA3_256
3995
    static const byte sigSha3_256wRsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 14};
3996
    #endif
3997
    #ifndef WOLFSSL_NOSHA3_384
3998
    static const byte sigSha3_384wRsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 15};
3999
    #endif
4000
    #ifndef WOLFSSL_NOSHA3_512
4001
    static const byte sigSha3_512wRsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 16};
4002
    #endif
4003
    #endif
4004
    #ifdef WC_RSA_PSS
4005
    static const byte sigRsaSsaPssOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 10};
4006
    #endif
4007
#endif /* NO_RSA */
4008
#ifdef HAVE_ECC
4009
    #ifndef NO_SHA
4010
    static const byte sigSha1wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 1};
4011
    #endif
4012
    #ifdef WOLFSSL_SHA224
4013
    static const byte sigSha224wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 1};
4014
    #endif
4015
    #ifndef NO_SHA256
4016
    static const byte sigSha256wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 2};
4017
    #endif
4018
    #ifdef WOLFSSL_SHA384
4019
    static const byte sigSha384wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 3};
4020
    #endif
4021
    #ifdef WOLFSSL_SHA512
4022
    static const byte sigSha512wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 4};
4023
    #endif
4024
    #ifdef WOLFSSL_SHA3
4025
    #ifndef WOLFSSL_NOSHA3_224
4026
    static const byte sigSha3_224wEcdsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 9};
4027
    #endif
4028
    #ifndef WOLFSSL_NOSHA3_256
4029
    static const byte sigSha3_256wEcdsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 10};
4030
    #endif
4031
    #ifndef WOLFSSL_NOSHA3_384
4032
    static const byte sigSha3_384wEcdsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 11};
4033
    #endif
4034
    #ifndef WOLFSSL_NOSHA3_512
4035
    static const byte sigSha3_512wEcdsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 12};
4036
    #endif
4037
    #endif
4038
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
4039
    /* 0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01, 0x83, 0x75 */
4040
    static const byte sigSm3wSm2Oid[] = {42, 129, 28, 207, 85, 1, 131, 117};
4041
    #endif
4042
#endif /* HAVE_ECC */
4043
#ifdef HAVE_ED25519
4044
    static const byte sigEd25519Oid[] = {43, 101, 112};
4045
#endif /* HAVE_ED25519 */
4046
#ifdef HAVE_ED448
4047
    static const byte sigEd448Oid[] = {43, 101, 113};
4048
#endif /* HAVE_ED448 */
4049
#ifdef HAVE_PQC
4050
#ifdef HAVE_FALCON
4051
    /* Falcon Level 1: 1 3 9999 3 1 */
4052
    static const byte sigFalcon_Level1Oid[] = {43, 206, 15, 3, 1};
4053
4054
    /* Falcon Level 5: 1 3 9999 3 4 */
4055
    static const byte sigFalcon_Level5Oid[] = {43, 206, 15, 3, 4};
4056
#endif /* HAVE_FACON */
4057
#ifdef HAVE_DILITHIUM
4058
    /* Dilithium Level 2: 1.3.6.1.4.1.2.267.7.4.4 */
4059
    static const byte sigDilithium_Level2Oid[] =
4060
        {43, 6, 1, 4, 1, 2, 130, 11, 7, 4, 4};
4061
4062
    /* Dilithium Level 3: 1.3.6.1.4.1.2.267.7.6.5 */
4063
    static const byte sigDilithium_Level3Oid[] =
4064
        {43, 6, 1, 4, 1, 2, 130, 11, 7, 6, 5};
4065
4066
    /* Dilithium Level 5: 1.3.6.1.4.1.2.267.7.8.7 */
4067
    static const byte sigDilithium_Level5Oid[] =
4068
        {43, 6, 1, 4, 1, 2, 130, 11, 7, 8, 7};
4069
#endif /* HAVE_DILITHIUM */
4070
#ifdef HAVE_SPHINCS
4071
    /* Sphincs Fast Level 1: 1 3 9999 6 7 4 */
4072
    static const byte sigSphincsFast_Level1Oid[] =
4073
        {43, 206, 15, 6, 7, 4};
4074
4075
    /* Sphincs Fast Level 3: 1 3 9999 6 8 3 */
4076
    static const byte sigSphincsFast_Level3Oid[] =
4077
        {43, 206, 15, 6, 8, 3};
4078
4079
    /* Sphincs Fast Level 5: 1 3 9999 6 9 3 */
4080
    static const byte sigSphincsFast_Level5Oid[] =
4081
        {43, 206, 15, 6, 9, 3};
4082
4083
    /* Sphincs Small Level 1: 1 3 9999 6 7 10 */
4084
    static const byte sigSphincsSmall_Level1Oid[] =
4085
        {43, 206, 15, 6, 7, 10};
4086
4087
    /* Sphincs Small Level 3: 1 3 9999 6 8 7 */
4088
    static const byte sigSphincsSmall_Level3Oid[] =
4089
        {43, 206, 15, 6, 8, 7};
4090
4091
    /* Sphincs Small Level 5: 1 3 9999 6 9 7 */
4092
    static const byte sigSphincsSmall_Level5Oid[] =
4093
        {43, 206, 15, 6, 9, 7};
4094
#endif /* HAVE_SPHINCS */
4095
#endif /* HAVE_PQC */
4096
4097
/* keyType */
4098
#ifndef NO_DSA
4099
    static const byte keyDsaOid[] = {42, 134, 72, 206, 56, 4, 1};
4100
#endif /* NO_DSA */
4101
#ifndef NO_RSA
4102
    static const byte keyRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 1};
4103
#ifdef WC_RSA_PSS
4104
    static const byte keyRsaPssOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 10};
4105
#endif
4106
#endif /* NO_RSA */
4107
#ifdef HAVE_ECC
4108
    static const byte keyEcdsaOid[] = {42, 134, 72, 206, 61, 2, 1};
4109
#endif /* HAVE_ECC */
4110
#ifdef HAVE_ED25519
4111
    static const byte keyEd25519Oid[] = {43, 101, 112};
4112
#endif /* HAVE_ED25519 */
4113
#ifdef HAVE_CURVE25519
4114
    static const byte keyCurve25519Oid[] = {43, 101, 110};
4115
#endif
4116
#ifdef HAVE_ED448
4117
    static const byte keyEd448Oid[] = {43, 101, 113};
4118
#endif /* HAVE_ED448 */
4119
#ifdef HAVE_CURVE448
4120
    static const byte keyCurve448Oid[] = {43, 101, 111};
4121
#endif /* HAVE_CURVE448 */
4122
#ifndef NO_DH
4123
    static const byte keyDhOid[] = {42, 134, 72, 134, 247, 13, 1, 3, 1};
4124
#endif /* !NO_DH */
4125
#ifdef HAVE_PQC
4126
#ifdef HAVE_FALCON
4127
    /* Falcon Level 1: 1 3 9999 3 1 */
4128
    static const byte keyFalcon_Level1Oid[] = {43, 206, 15, 3, 1};
4129
4130
    /* Falcon Level 5: 1 3 9999 3 4 */
4131
    static const byte keyFalcon_Level5Oid[] = {43, 206, 15, 3, 4};
4132
#endif /* HAVE_FALCON */
4133
#ifdef HAVE_DILITHIUM
4134
    /* Dilithium Level 2: 1.3.6.1.4.1.2.267.7.4.4 */
4135
    static const byte keyDilithium_Level2Oid[] =
4136
        {43, 6, 1, 4, 1, 2, 130, 11, 7, 4, 4};
4137
4138
    /* Dilithium Level 3: 1.3.6.1.4.1.2.267.7.6.5 */
4139
    static const byte keyDilithium_Level3Oid[] =
4140
        {43, 6, 1, 4, 1, 2, 130, 11, 7, 6, 5};
4141
4142
    /* Dilithium Level 5: 1.3.6.1.4.1.2.267.7.8.7 */
4143
    static const byte keyDilithium_Level5Oid[] =
4144
        {43, 6, 1, 4, 1, 2, 130, 11, 7, 8, 7};
4145
#endif /* HAVE_DILITHIUM */
4146
#ifdef HAVE_SPHINCS
4147
    /* Sphincs Fast Level 1: 1 3 9999 6 7 4 */
4148
    static const byte keySphincsFast_Level1Oid[] =
4149
        {43, 206, 15, 6, 7, 4};
4150
4151
    /* Sphincs Fast Level 3: 1 3 9999 6 8 3 */
4152
    static const byte keySphincsFast_Level3Oid[] =
4153
        {43, 206, 15, 6, 8, 3};
4154
4155
    /* Sphincs Fast Level 5: 1 3 9999 6 9 3 */
4156
    static const byte keySphincsFast_Level5Oid[] =
4157
        {43, 206, 15, 6, 9, 3};
4158
4159
    /* Sphincs Small Level 1: 1 3 9999 6 7 10 */
4160
    static const byte keySphincsSmall_Level1Oid[] =
4161
        {43, 206, 15, 6, 7, 10};
4162
4163
    /* Sphincs Small Level 3: 1 3 9999 6 8 7 */
4164
    static const byte keySphincsSmall_Level3Oid[] =
4165
        {43, 206, 15, 6, 8, 7};
4166
4167
    /* Sphincs Small Level 5: 1 3 9999 6 9 7 */
4168
    static const byte keySphincsSmall_Level5Oid[] =
4169
        {43, 206, 15, 6, 9, 7};
4170
#endif /* HAVE_SPHINCS */
4171
#endif /* HAVE_PQC */
4172
4173
/* curveType */
4174
#ifdef HAVE_ECC
4175
    /* See "ecc_sets" table in ecc.c */
4176
#endif /* HAVE_ECC */
4177
4178
#ifdef HAVE_AES_CBC
4179
/* blkType */
4180
    #ifdef WOLFSSL_AES_128
4181
    static const byte blkAes128CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 2};
4182
    #endif
4183
    #ifdef WOLFSSL_AES_192
4184
    static const byte blkAes192CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 22};
4185
    #endif
4186
    #ifdef WOLFSSL_AES_256
4187
    static const byte blkAes256CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 42};
4188
    #endif
4189
#endif /* HAVE_AES_CBC */
4190
#ifdef HAVE_AESGCM
4191
    #ifdef WOLFSSL_AES_128
4192
    static const byte blkAes128GcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 6};
4193
    #endif
4194
    #ifdef WOLFSSL_AES_192
4195
    static const byte blkAes192GcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 26};
4196
    #endif
4197
    #ifdef WOLFSSL_AES_256
4198
    static const byte blkAes256GcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 46};
4199
    #endif
4200
#endif /* HAVE_AESGCM */
4201
#ifdef HAVE_AESCCM
4202
    #ifdef WOLFSSL_AES_128
4203
    static const byte blkAes128CcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 7};
4204
    #endif
4205
    #ifdef WOLFSSL_AES_192
4206
    static const byte blkAes192CcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 27};
4207
    #endif
4208
    #ifdef WOLFSSL_AES_256
4209
    static const byte blkAes256CcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 47};
4210
    #endif
4211
#endif /* HAVE_AESCCM */
4212
4213
#ifndef NO_DES3
4214
    static const byte blkDesCbcOid[]  = {43, 14, 3, 2, 7};
4215
    static const byte blkDes3CbcOid[] = {42, 134, 72, 134, 247, 13, 3, 7};
4216
#endif
4217
4218
/* keyWrapType */
4219
#ifdef WOLFSSL_AES_128
4220
    static const byte wrapAes128Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 5};
4221
#endif
4222
#ifdef WOLFSSL_AES_192
4223
    static const byte wrapAes192Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 25};
4224
#endif
4225
#ifdef WOLFSSL_AES_256
4226
    static const byte wrapAes256Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 45};
4227
#endif
4228
#ifdef HAVE_PKCS7
4229
/* From RFC 3211 */
4230
static const byte wrapPwriKekOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 16, 3,9};
4231
#endif
4232
4233
/* cmsKeyAgreeType */
4234
#ifndef NO_SHA
4235
    static const byte dhSinglePass_stdDH_sha1kdf_Oid[]   =
4236
                                          {43, 129, 5, 16, 134, 72, 63, 0, 2};
4237
#endif
4238
#ifdef WOLFSSL_SHA224
4239
    static const byte dhSinglePass_stdDH_sha224kdf_Oid[] = {43, 129, 4, 1, 11, 0};
4240
#endif
4241
#ifndef NO_SHA256
4242
    static const byte dhSinglePass_stdDH_sha256kdf_Oid[] = {43, 129, 4, 1, 11, 1};
4243
#endif
4244
#ifdef WOLFSSL_SHA384
4245
    static const byte dhSinglePass_stdDH_sha384kdf_Oid[] = {43, 129, 4, 1, 11, 2};
4246
#endif
4247
#ifdef WOLFSSL_SHA512
4248
    static const byte dhSinglePass_stdDH_sha512kdf_Oid[] = {43, 129, 4, 1, 11, 3};
4249
#endif
4250
4251
/* ocspType */
4252
#ifdef HAVE_OCSP
4253
    static const byte ocspBasicOid[]    = {43, 6, 1, 5, 5, 7, 48, 1, 1};
4254
    static const byte ocspNonceOid[]    = {43, 6, 1, 5, 5, 7, 48, 1, 2};
4255
    static const byte ocspNoCheckOid[]  = {43, 6, 1, 5, 5, 7, 48, 1, 5};
4256
#endif /* HAVE_OCSP */
4257
4258
/* certExtType */
4259
static const byte extBasicCaOid[] = {85, 29, 19};
4260
static const byte extAltNamesOid[] = {85, 29, 17};
4261
static const byte extCrlDistOid[] = {85, 29, 31};
4262
static const byte extAuthInfoOid[] = {43, 6, 1, 5, 5, 7, 1, 1};
4263
static const byte extAuthKeyOid[] = {85, 29, 35};
4264
static const byte extSubjKeyOid[] = {85, 29, 14};
4265
static const byte extCertPolicyOid[] = {85, 29, 32};
4266
static const byte extKeyUsageOid[] = {85, 29, 15};
4267
static const byte extInhibitAnyOid[] = {85, 29, 54};
4268
static const byte extExtKeyUsageOid[] = {85, 29, 37};
4269
#ifndef IGNORE_NAME_CONSTRAINTS
4270
    static const byte extNameConsOid[] = {85, 29, 30};
4271
#endif
4272
#ifdef HAVE_CRL
4273
static const byte extCrlNumberOid[] = {85, 29, 20};
4274
#endif
4275
#ifdef WOLFSSL_SUBJ_DIR_ATTR
4276
    static const byte extSubjDirAttrOid[] = {85, 29, 9};
4277
#endif
4278
#ifdef WOLFSSL_SUBJ_INFO_ACC
4279
    static const byte extSubjInfoAccessOid[] = {43, 6, 1, 5, 5, 7, 1, 11};
4280
#endif
4281
4282
/* certAuthInfoType */
4283
static const byte extAuthInfoOcspOid[] = {43, 6, 1, 5, 5, 7, 48, 1};
4284
static const byte extAuthInfoCaIssuerOid[] = {43, 6, 1, 5, 5, 7, 48, 2};
4285
#ifdef WOLFSSL_SUBJ_INFO_ACC
4286
    static const byte extAuthInfoCaRespOid[] = {43, 6, 1, 5, 5, 7, 48, 5};
4287
#endif /* WOLFSSL_SUBJ_INFO_ACC */
4288
4289
/* certPolicyType */
4290
static const byte extCertPolicyAnyOid[] = {85, 29, 32, 0};
4291
#ifdef WOLFSSL_FPKI
4292
#define CERT_POLICY_TYPE_OID_BASE(num) {96, 134, 72, 1, 101, 3, 2, 1, 3, num}
4293
    static const byte extCertPolicyFpkiCommonAuthOid[] =
4294
            CERT_POLICY_TYPE_OID_BASE(13);
4295
    static const byte extCertPolicyFpkiPivAuthOid[] =
4296
            CERT_POLICY_TYPE_OID_BASE(40);
4297
    static const byte extCertPolicyFpkiPivAuthHwOid[] =
4298
            CERT_POLICY_TYPE_OID_BASE(41);
4299
    static const byte extCertPolicyFpkiPiviAuthOid[] =
4300
            CERT_POLICY_TYPE_OID_BASE(45);
4301
#endif /* WOLFSSL_FPKI */
4302
4303
/* certAltNameType */
4304
static const byte extAltNamesHwNameOid[] = {43, 6, 1, 5, 5, 7, 8, 4};
4305
4306
/* certKeyUseType */
4307
static const byte extExtKeyUsageAnyOid[] = {85, 29, 37, 0};
4308
static const byte extExtKeyUsageServerAuthOid[]   = {43, 6, 1, 5, 5, 7, 3, 1};
4309
static const byte extExtKeyUsageClientAuthOid[]   = {43, 6, 1, 5, 5, 7, 3, 2};
4310
static const byte extExtKeyUsageCodeSigningOid[]  = {43, 6, 1, 5, 5, 7, 3, 3};
4311
static const byte extExtKeyUsageEmailProtectOid[] = {43, 6, 1, 5, 5, 7, 3, 4};
4312
static const byte extExtKeyUsageTimestampOid[]    = {43, 6, 1, 5, 5, 7, 3, 8};
4313
static const byte extExtKeyUsageOcspSignOid[]     = {43, 6, 1, 5, 5, 7, 3, 9};
4314
#ifdef WOLFSSL_WOLFSSH
4315
#define EXT_KEY_USAGE_OID_BASE(num) {43, 6, 1, 5, 5, 7, 3, num}
4316
    static const byte extExtKeyUsageSshClientAuthOid[] =
4317
            EXT_KEY_USAGE_OID_BASE(21);
4318
    static const byte extExtKeyUsageSshMSCLOid[] =
4319
            {43, 6, 1, 4, 1, 130, 55, 20, 2, 2};
4320
    static const byte extExtKeyUsageSshKpClientAuthOid[] =
4321
            {43, 6, 1, 5, 2, 3, 4};
4322
#endif /* WOLFSSL_WOLFSSH */
4323
4324
#ifdef WOLFSSL_SUBJ_DIR_ATTR
4325
#define SUBJ_DIR_ATTR_TYPE_OID_BASE(num) {43, 6, 1, 5, 5, 7, 9, num}
4326
    static const byte extSubjDirAttrDobOid[] = SUBJ_DIR_ATTR_TYPE_OID_BASE(1);
4327
    static const byte extSubjDirAttrPobOid[] = SUBJ_DIR_ATTR_TYPE_OID_BASE(2);
4328
    static const byte extSubjDirAttrGenderOid[] =
4329
            SUBJ_DIR_ATTR_TYPE_OID_BASE(3);
4330
    static const byte extSubjDirAttrCocOid[] = SUBJ_DIR_ATTR_TYPE_OID_BASE(4);
4331
    static const byte extSubjDirAttrCorOid[] = SUBJ_DIR_ATTR_TYPE_OID_BASE(5);
4332
#endif
4333
4334
#if defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_GEN) || \
4335
    defined(WOLFSSL_ASN_TEMPLATE) || defined(OPENSSL_EXTRA) || \
4336
    defined(OPENSSL_EXTRA_X509_SMALL)
4337
/* csrAttrType */
4338
#define CSR_ATTR_TYPE_OID_BASE(num) {42, 134, 72, 134, 247, 13, 1, 9, num}
4339
#if !defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_GEN) || \
4340
    defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
4341
    defined(WOLFSSL_ASN_TEMPLATE)
4342
static const byte attrEmailOid[] =             CSR_ATTR_TYPE_OID_BASE(1);
4343
#endif
4344
#ifdef WOLFSSL_CERT_REQ
4345
static const byte attrUnstructuredNameOid[] =  CSR_ATTR_TYPE_OID_BASE(2);
4346
static const byte attrPkcs9ContentTypeOid[] =  CSR_ATTR_TYPE_OID_BASE(3);
4347
static const byte attrChallengePasswordOid[] = CSR_ATTR_TYPE_OID_BASE(7);
4348
static const byte attrExtensionRequestOid[] =  CSR_ATTR_TYPE_OID_BASE(14);
4349
static const byte attrSerialNumberOid[] = {85, 4, 5};
4350
static const byte attrDnQualifier[] = {85, 4, 46};
4351
static const byte attrInitals[] = {85, 4, 43};
4352
static const byte attrSurname[] = {85, 4, 4};
4353
static const byte attrGivenName[] = {85, 4, 42};
4354
#endif
4355
#endif
4356
4357
/* kdfType */
4358
static const byte pbkdf2Oid[] = {42, 134, 72, 134, 247, 13, 1, 5, 12};
4359
4360
/* PKCS5 */
4361
#if !defined(NO_DES3) && !defined(NO_MD5)
4362
static const byte pbeMd5Des[] = {42, 134, 72, 134, 247, 13, 1, 5, 3};
4363
#endif
4364
#if !defined(NO_DES3) && !defined(NO_SHA)
4365
static const byte pbeSha1Des[] = {42, 134, 72, 134, 247, 13, 1, 5, 10};
4366
#endif
4367
static const byte pbes2[] = {42, 134, 72, 134, 247, 13, 1, 5, 13};
4368
4369
/* PKCS12 */
4370
#if !defined(NO_RC4) && !defined(NO_SHA)
4371
static const byte pbeSha1RC4128[] = {42, 134, 72, 134, 247, 13, 1, 12, 1, 1};
4372
#endif
4373
#if !defined(NO_DES3) && !defined(NO_SHA)
4374
static const byte pbeSha1Des3[] = {42, 134, 72, 134, 247, 13, 1, 12, 1, 3};
4375
#endif
4376
#if defined(WC_RC2) && !defined(NO_SHA)
4377
static const byte pbe40Rc2Cbc[] = {42, 134, 72, 134, 247, 13, 1, 12, 1, 6};
4378
#endif
4379
4380
#ifdef HAVE_LIBZ
4381
/* zlib compression */
4382
static const byte zlibCompress[] = {42, 134, 72, 134, 247, 13, 1, 9, 16, 3, 8};
4383
#endif
4384
#ifdef WOLFSSL_APACHE_HTTPD
4385
/* tlsExtType */
4386
static const byte tlsFeatureOid[] = {43, 6, 1, 5, 5, 7, 1, 24};
4387
/* certNameType */
4388
static const byte dnsSRVOid[] = {43, 6, 1, 5, 5, 7, 8, 7};
4389
#endif
4390
4391
#if defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_GEN) || \
4392
    defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
4393
    defined(WOLFSSL_ASN_TEMPLATE)
4394
/* Pilot attribute types (0.9.2342.19200300.100.1.*) */
4395
#define PLT_ATTR_TYPE_OID_BASE(num) {9, 146, 38, 137, 147, 242, 44, 100, 1, num}
4396
static const byte uidOid[] = PLT_ATTR_TYPE_OID_BASE(1); /* user id */
4397
static const byte fvrtDrk[] = PLT_ATTR_TYPE_OID_BASE(5);/* favourite drink*/
4398
#endif
4399
4400
#if defined(WOLFSSL_CERT_GEN) || \
4401
    defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
4402
    defined(WOLFSSL_ASN_TEMPLATE)
4403
static const byte dcOid[] = {9, 146, 38, 137, 147, 242, 44, 100, 1, 25}; /* domain component */
4404
#endif
4405
4406
4407
/* Looks up the ID/type of an OID.
4408
 *
4409
 * When known returns the OID as a byte array and its length.
4410
 * ID-type are unique.
4411
 *
4412
 * Use oidIgnoreType to autofail.
4413
 *
4414
 * @param [in]  id     OID id.
4415
 * @param [in]  type   Type of OID (enum Oid_Types).
4416
 * @param [out] oidSz  Length of OID byte array returned.
4417
 * @return  Array of bytes for the OID.
4418
 * @return  NULL when ID/type not recognized.
4419
 */
4420
const byte* OidFromId(word32 id, word32 type, word32* oidSz)
4421
0
{
4422
0
    const byte* oid = NULL;
4423
4424
0
    *oidSz = 0;
4425
4426
0
    switch (type) {
4427
4428
0
        case oidHashType:
4429
0
            switch (id) {
4430
0
            #ifdef WOLFSSL_MD2
4431
0
                case MD2h:
4432
0
                    oid = hashMd2hOid;
4433
0
                    *oidSz = sizeof(hashMd2hOid);
4434
0
                    break;
4435
0
            #endif
4436
0
            #ifndef NO_MD5
4437
0
                case MD5h:
4438
0
                    oid = hashMd5hOid;
4439
0
                    *oidSz = sizeof(hashMd5hOid);
4440
0
                    break;
4441
0
            #endif
4442
0
            #ifndef NO_SHA
4443
0
                case SHAh:
4444
0
                    oid = hashSha1hOid;
4445
0
                    *oidSz = sizeof(hashSha1hOid);
4446
0
                    break;
4447
0
            #endif
4448
0
            #ifdef WOLFSSL_SHA224
4449
0
                case SHA224h:
4450
0
                    oid = hashSha224hOid;
4451
0
                    *oidSz = sizeof(hashSha224hOid);
4452
0
                    break;
4453
0
            #endif
4454
0
            #ifndef NO_SHA256
4455
0
                case SHA256h:
4456
0
                    oid = hashSha256hOid;
4457
0
                    *oidSz = sizeof(hashSha256hOid);
4458
0
                    break;
4459
0
            #endif
4460
0
            #ifdef WOLFSSL_SHA384
4461
0
                case SHA384h:
4462
0
                    oid = hashSha384hOid;
4463
0
                    *oidSz = sizeof(hashSha384hOid);
4464
0
                    break;
4465
0
            #endif
4466
0
            #ifdef WOLFSSL_SHA512
4467
0
                #ifndef WOLFSSL_NOSHA512_224
4468
0
                case SHA512_224h:
4469
0
                    oid = hashSha512_224hOid;
4470
0
                    *oidSz = sizeof(hashSha512_224hOid);
4471
0
                    break;
4472
0
                #endif
4473
0
                #ifndef WOLFSSL_NOSHA512_256
4474
0
                case SHA512_256h:
4475
0
                    oid = hashSha512_256hOid;
4476
0
                    *oidSz = sizeof(hashSha512_256hOid);
4477
0
                    break;
4478
0
                #endif
4479
0
                case SHA512h:
4480
0
                    oid = hashSha512hOid;
4481
0
                    *oidSz = sizeof(hashSha512hOid);
4482
0
                    break;
4483
0
            #endif
4484
0
            #ifdef WOLFSSL_SHA3
4485
0
            #ifndef WOLFSSL_NOSHA3_224
4486
0
                case SHA3_224h:
4487
0
                    oid = hashSha3_224hOid;
4488
0
                    *oidSz = sizeof(hashSha3_224hOid);
4489
0
                    break;
4490
0
            #endif /* WOLFSSL_NOSHA3_224 */
4491
0
            #ifndef WOLFSSL_NOSHA3_256
4492
0
                case SHA3_256h:
4493
0
                    oid = hashSha3_256hOid;
4494
0
                    *oidSz = sizeof(hashSha3_256hOid);
4495
0
                    break;
4496
0
            #endif /* WOLFSSL_NOSHA3_256 */
4497
0
            #ifndef WOLFSSL_NOSHA3_384
4498
0
                case SHA3_384h:
4499
0
                    oid = hashSha3_384hOid;
4500
0
                    *oidSz = sizeof(hashSha3_384hOid);
4501
0
                    break;
4502
0
            #endif /* WOLFSSL_NOSHA3_384 */
4503
0
            #ifndef WOLFSSL_NOSHA3_512
4504
0
                case SHA3_512h:
4505
0
                    oid = hashSha3_512hOid;
4506
0
                    *oidSz = sizeof(hashSha3_512hOid);
4507
0
                    break;
4508
0
            #endif /* WOLFSSL_NOSHA3_512 */
4509
0
            #endif /* WOLFSSL_SHA3 */
4510
0
                default:
4511
0
                    break;
4512
0
            }
4513
0
            break;
4514
4515
0
        case oidSigType:
4516
0
            switch (id) {
4517
                #if !defined(NO_DSA) && !defined(NO_SHA)
4518
                case CTC_SHAwDSA:
4519
                    oid = sigSha1wDsaOid;
4520
                    *oidSz = sizeof(sigSha1wDsaOid);
4521
                    break;
4522
                case CTC_SHA256wDSA:
4523
                    oid = sigSha256wDsaOid;
4524
                    *oidSz = sizeof(sigSha256wDsaOid);
4525
                    break;
4526
                #endif /* NO_DSA */
4527
0
                #ifndef NO_RSA
4528
0
                #ifdef WOLFSSL_MD2
4529
0
                case CTC_MD2wRSA:
4530
0
                    oid = sigMd2wRsaOid;
4531
0
                    *oidSz = sizeof(sigMd2wRsaOid);
4532
0
                    break;
4533
0
                #endif
4534
0
                #ifndef NO_MD5
4535
0
                case CTC_MD5wRSA:
4536
0
                    oid = sigMd5wRsaOid;
4537
0
                    *oidSz = sizeof(sigMd5wRsaOid);
4538
0
                    break;
4539
0
                #endif
4540
0
                #ifndef NO_SHA
4541
0
                case CTC_SHAwRSA:
4542
0
                    oid = sigSha1wRsaOid;
4543
0
                    *oidSz = sizeof(sigSha1wRsaOid);
4544
0
                    break;
4545
0
                #endif
4546
0
                #ifdef WOLFSSL_SHA224
4547
0
                case CTC_SHA224wRSA:
4548
0
                    oid = sigSha224wRsaOid;
4549
0
                    *oidSz = sizeof(sigSha224wRsaOid);
4550
0
                    break;
4551
0
                #endif
4552
0
                #ifndef NO_SHA256
4553
0
                case CTC_SHA256wRSA:
4554
0
                    oid = sigSha256wRsaOid;
4555
0
                    *oidSz = sizeof(sigSha256wRsaOid);
4556
0
                    break;
4557
0
                #endif
4558
0
                #ifdef WOLFSSL_SHA384
4559
0
                case CTC_SHA384wRSA:
4560
0
                    oid = sigSha384wRsaOid;
4561
0
                    *oidSz = sizeof(sigSha384wRsaOid);
4562
0
                    break;
4563
0
                #endif
4564
0
                #ifdef WOLFSSL_SHA512
4565
0
                case CTC_SHA512wRSA:
4566
0
                    oid = sigSha512wRsaOid;
4567
0
                    *oidSz = sizeof(sigSha512wRsaOid);
4568
0
                    break;
4569
0
                #endif /* WOLFSSL_SHA512 */
4570
0
                #ifdef WOLFSSL_SHA3
4571
0
                #ifndef WOLFSSL_NOSHA3_224
4572
0
                case CTC_SHA3_224wRSA:
4573
0
                    oid = sigSha3_224wRsaOid;
4574
0
                    *oidSz = sizeof(sigSha3_224wRsaOid);
4575
0
                    break;
4576
0
                #endif
4577
0
                #ifndef WOLFSSL_NOSHA3_256
4578
0
                case CTC_SHA3_256wRSA:
4579
0
                    oid = sigSha3_256wRsaOid;
4580
0
                    *oidSz = sizeof(sigSha3_256wRsaOid);
4581
0
                    break;
4582
0
                #endif
4583
0
                #ifndef WOLFSSL_NOSHA3_384
4584
0
                case CTC_SHA3_384wRSA:
4585
0
                    oid = sigSha3_384wRsaOid;
4586
0
                    *oidSz = sizeof(sigSha3_384wRsaOid);
4587
0
                    break;
4588
0
                #endif
4589
0
                #ifndef WOLFSSL_NOSHA3_512
4590
0
                case CTC_SHA3_512wRSA:
4591
0
                    oid = sigSha3_512wRsaOid;
4592
0
                    *oidSz = sizeof(sigSha3_512wRsaOid);
4593
0
                    break;
4594
0
                #endif
4595
0
                #endif
4596
0
                #ifdef WC_RSA_PSS
4597
0
                case CTC_RSASSAPSS:
4598
0
                    oid = sigRsaSsaPssOid;
4599
0
                    *oidSz = sizeof(sigRsaSsaPssOid);
4600
0
                    break;
4601
0
                #endif
4602
0
                #endif /* NO_RSA */
4603
0
                #ifdef HAVE_ECC
4604
0
                #ifndef NO_SHA
4605
0
                case CTC_SHAwECDSA:
4606
0
                    oid = sigSha1wEcdsaOid;
4607
0
                    *oidSz = sizeof(sigSha1wEcdsaOid);
4608
0
                    break;
4609
0
                #endif
4610
0
                #ifdef WOLFSSL_SHA224
4611
0
                case CTC_SHA224wECDSA:
4612
0
                    oid = sigSha224wEcdsaOid;
4613
0
                    *oidSz = sizeof(sigSha224wEcdsaOid);
4614
0
                    break;
4615
0
                #endif
4616
0
                #ifndef NO_SHA256
4617
0
                case CTC_SHA256wECDSA:
4618
0
                    oid = sigSha256wEcdsaOid;
4619
0
                    *oidSz = sizeof(sigSha256wEcdsaOid);
4620
0
                    break;
4621
0
                #endif
4622
0
                #ifdef WOLFSSL_SHA384
4623
0
                case CTC_SHA384wECDSA:
4624
0
                    oid = sigSha384wEcdsaOid;
4625
0
                    *oidSz = sizeof(sigSha384wEcdsaOid);
4626
0
                    break;
4627
0
                #endif
4628
0
                #ifdef WOLFSSL_SHA512
4629
0
                case CTC_SHA512wECDSA:
4630
0
                    oid = sigSha512wEcdsaOid;
4631
0
                    *oidSz = sizeof(sigSha512wEcdsaOid);
4632
0
                    break;
4633
0
                #endif
4634
0
                #ifdef WOLFSSL_SHA3
4635
0
                #ifndef WOLFSSL_NOSHA3_224
4636
0
                case CTC_SHA3_224wECDSA:
4637
0
                    oid = sigSha3_224wEcdsaOid;
4638
0
                    *oidSz = sizeof(sigSha3_224wEcdsaOid);
4639
0
                    break;
4640
0
                #endif
4641
0
                #ifndef WOLFSSL_NOSHA3_256
4642
0
                case CTC_SHA3_256wECDSA:
4643
0
                    oid = sigSha3_256wEcdsaOid;
4644
0
                    *oidSz = sizeof(sigSha3_256wEcdsaOid);
4645
0
                    break;
4646
0
                #endif
4647
0
                #ifndef WOLFSSL_NOSHA3_384
4648
0
                case CTC_SHA3_384wECDSA:
4649
0
                    oid = sigSha3_384wEcdsaOid;
4650
0
                    *oidSz = sizeof(sigSha3_384wEcdsaOid);
4651
0
                    break;
4652
0
                #endif
4653
0
                #ifndef WOLFSSL_NOSHA3_512
4654
0
                case CTC_SHA3_512wECDSA:
4655
0
                    oid = sigSha3_512wEcdsaOid;
4656
0
                    *oidSz = sizeof(sigSha3_512wEcdsaOid);
4657
0
                    break;
4658
0
                #endif
4659
0
                #endif
4660
0
                #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
4661
0
                case CTC_SM3wSM2:
4662
0
                    oid = sigSm3wSm2Oid;
4663
0
                    *oidSz = sizeof(sigSm3wSm2Oid);
4664
0
                    break;
4665
0
                #endif
4666
0
                #endif /* HAVE_ECC */
4667
0
                #ifdef HAVE_ED25519
4668
0
                case CTC_ED25519:
4669
0
                    oid = sigEd25519Oid;
4670
0
                    *oidSz = sizeof(sigEd25519Oid);
4671
0
                    break;
4672
0
                #endif
4673
0
                #ifdef HAVE_ED448
4674
0
                case CTC_ED448:
4675
0
                    oid = sigEd448Oid;
4676
0
                    *oidSz = sizeof(sigEd448Oid);
4677
0
                    break;
4678
0
                #endif
4679
                #ifdef HAVE_PQC
4680
                #ifdef HAVE_FALCON
4681
                case CTC_FALCON_LEVEL1:
4682
                    oid = sigFalcon_Level1Oid;
4683
                    *oidSz = sizeof(sigFalcon_Level1Oid);
4684
                    break;
4685
                case CTC_FALCON_LEVEL5:
4686
                    oid = sigFalcon_Level5Oid;
4687
                    *oidSz = sizeof(sigFalcon_Level5Oid);
4688
                    break;
4689
                #endif /* HAVE_FALCON */
4690
                #ifdef HAVE_DILITHIUM
4691
                case CTC_DILITHIUM_LEVEL2:
4692
                    oid = sigDilithium_Level2Oid;
4693
                    *oidSz = sizeof(sigDilithium_Level2Oid);
4694
                    break;
4695
                case CTC_DILITHIUM_LEVEL3:
4696
                    oid = sigDilithium_Level3Oid;
4697
                    *oidSz = sizeof(sigDilithium_Level3Oid);
4698
                    break;
4699
                case CTC_DILITHIUM_LEVEL5:
4700
                    oid = sigDilithium_Level5Oid;
4701
                    *oidSz = sizeof(sigDilithium_Level5Oid);
4702
                    break;
4703
                #endif /* HAVE_DILITHIUM */
4704
                #ifdef HAVE_SPHINCS
4705
                case CTC_SPHINCS_FAST_LEVEL1:
4706
                    oid = sigSphincsFast_Level1Oid;
4707
                    *oidSz = sizeof(sigSphincsFast_Level1Oid);
4708
                    break;
4709
                case CTC_SPHINCS_FAST_LEVEL3:
4710
                    oid = sigSphincsFast_Level3Oid;
4711
                    *oidSz = sizeof(sigSphincsFast_Level3Oid);
4712
                    break;
4713
                case CTC_SPHINCS_FAST_LEVEL5:
4714
                    oid = sigSphincsFast_Level5Oid;
4715
                    *oidSz = sizeof(sigSphincsFast_Level5Oid);
4716
                    break;
4717
                case CTC_SPHINCS_SMALL_LEVEL1:
4718
                    oid = sigSphincsSmall_Level1Oid;
4719
                    *oidSz = sizeof(sigSphincsSmall_Level1Oid);
4720
                    break;
4721
                case CTC_SPHINCS_SMALL_LEVEL3:
4722
                    oid = sigSphincsSmall_Level3Oid;
4723
                    *oidSz = sizeof(sigSphincsSmall_Level3Oid);
4724
                    break;
4725
                case CTC_SPHINCS_SMALL_LEVEL5:
4726
                    oid = sigSphincsSmall_Level5Oid;
4727
                    *oidSz = sizeof(sigSphincsSmall_Level5Oid);
4728
                    break;
4729
                #endif /* HAVE_SPHINCS */
4730
                #endif /* HAVE_PQC */
4731
0
                default:
4732
0
                    break;
4733
0
            }
4734
0
            break;
4735
4736
0
        case oidKeyType:
4737
0
            switch (id) {
4738
                #ifndef NO_DSA
4739
                case DSAk:
4740
                    oid = keyDsaOid;
4741
                    *oidSz = sizeof(keyDsaOid);
4742
                    break;
4743
                #endif /* NO_DSA */
4744
0
            #ifndef NO_RSA
4745
0
                case RSAk:
4746
0
                    oid = keyRsaOid;
4747
0
                    *oidSz = sizeof(keyRsaOid);
4748
0
                    break;
4749
0
                #ifdef WC_RSA_PSS
4750
0
                case RSAPSSk:
4751
0
                    oid = keyRsaPssOid;
4752
0
                    *oidSz = sizeof(keyRsaPssOid);
4753
0
                    break;
4754
0
                #endif
4755
0
            #endif /* NO_RSA */
4756
0
                #ifdef HAVE_ECC
4757
0
                case ECDSAk:
4758
0
                    oid = keyEcdsaOid;
4759
0
                    *oidSz = sizeof(keyEcdsaOid);
4760
0
                    break;
4761
0
                #endif /* HAVE_ECC */
4762
0
                #ifdef HAVE_ED25519
4763
0
                case ED25519k:
4764
0
                    oid = keyEd25519Oid;
4765
0
                    *oidSz = sizeof(keyEd25519Oid);
4766
0
                    break;
4767
0
                #endif /* HAVE_ED25519 */
4768
0
                #ifdef HAVE_CURVE25519
4769
0
                case X25519k:
4770
0
                    oid = keyCurve25519Oid;
4771
0
                    *oidSz = sizeof(keyCurve25519Oid);
4772
0
                    break;
4773
0
                #endif /* HAVE_CURVE25519 */
4774
0
                #ifdef HAVE_ED448
4775
0
                case ED448k:
4776
0
                    oid = keyEd448Oid;
4777
0
                    *oidSz = sizeof(keyEd448Oid);
4778
0
                    break;
4779
0
                #endif /* HAVE_ED448 */
4780
0
                #ifdef HAVE_CURVE448
4781
0
                case X448k:
4782
0
                    oid = keyCurve448Oid;
4783
0
                    *oidSz = sizeof(keyCurve448Oid);
4784
0
                    break;
4785
0
                #endif /* HAVE_CURVE448 */
4786
0
                #ifndef NO_DH
4787
0
                case DHk:
4788
0
                    oid = keyDhOid;
4789
0
                    *oidSz = sizeof(keyDhOid);
4790
0
                    break;
4791
0
                #endif /* !NO_DH */
4792
                #ifdef HAVE_PQC
4793
                #ifdef HAVE_FALCON
4794
                case FALCON_LEVEL1k:
4795
                    oid = keyFalcon_Level1Oid;
4796
                    *oidSz = sizeof(keyFalcon_Level1Oid);
4797
                    break;
4798
                case FALCON_LEVEL5k:
4799
                    oid = keyFalcon_Level5Oid;
4800
                    *oidSz = sizeof(keyFalcon_Level5Oid);
4801
                    break;
4802
                #endif /* HAVE_FALCON */
4803
                #ifdef HAVE_DILITHIUM
4804
                case DILITHIUM_LEVEL2k:
4805
                    oid = keyDilithium_Level2Oid;
4806
                    *oidSz = sizeof(keyDilithium_Level2Oid);
4807
                    break;
4808
                case DILITHIUM_LEVEL3k:
4809
                    oid = keyDilithium_Level3Oid;
4810
                    *oidSz = sizeof(keyDilithium_Level3Oid);
4811
                    break;
4812
                case DILITHIUM_LEVEL5k:
4813
                    oid = keyDilithium_Level5Oid;
4814
                    *oidSz = sizeof(keyDilithium_Level5Oid);
4815
                    break;
4816
                #endif /* HAVE_DILITHIUM */
4817
                #ifdef HAVE_SPHINCS
4818
                case SPHINCS_FAST_LEVEL1k:
4819
                    oid = keySphincsFast_Level1Oid;
4820
                    *oidSz = sizeof(keySphincsFast_Level1Oid);
4821
                    break;
4822
                case SPHINCS_FAST_LEVEL3k:
4823
                    oid = keySphincsFast_Level3Oid;
4824
                    *oidSz = sizeof(keySphincsFast_Level3Oid);
4825
                    break;
4826
                case SPHINCS_FAST_LEVEL5k:
4827
                    oid = keySphincsFast_Level5Oid;
4828
                    *oidSz = sizeof(keySphincsFast_Level5Oid);
4829
                    break;
4830
                case SPHINCS_SMALL_LEVEL1k:
4831
                    oid = keySphincsSmall_Level1Oid;
4832
                    *oidSz = sizeof(keySphincsSmall_Level1Oid);
4833
                    break;
4834
                case SPHINCS_SMALL_LEVEL3k:
4835
                    oid = keySphincsSmall_Level3Oid;
4836
                    *oidSz = sizeof(keySphincsSmall_Level3Oid);
4837
                    break;
4838
                case SPHINCS_SMALL_LEVEL5k:
4839
                    oid = keySphincsSmall_Level5Oid;
4840
                    *oidSz = sizeof(keySphincsSmall_Level5Oid);
4841
                    break;
4842
                #endif /* HAVE_SPHINCS */
4843
                #endif /* HAVE_PQC */
4844
0
                default:
4845
0
                    break;
4846
0
            }
4847
0
            break;
4848
4849
0
        #ifdef HAVE_ECC
4850
0
        case oidCurveType:
4851
0
            if (wc_ecc_get_oid(id, &oid, oidSz) < 0) {
4852
0
                WOLFSSL_MSG("ECC OID not found");
4853
0
            }
4854
0
            break;
4855
0
        #endif /* HAVE_ECC */
4856
4857
0
        case oidBlkType:
4858
0
            switch (id) {
4859
0
    #ifdef HAVE_AES_CBC
4860
0
        #ifdef WOLFSSL_AES_128
4861
0
                case AES128CBCb:
4862
0
                    oid = blkAes128CbcOid;
4863
0
                    *oidSz = sizeof(blkAes128CbcOid);
4864
0
                    break;
4865
0
        #endif
4866
0
        #ifdef WOLFSSL_AES_192
4867
0
                case AES192CBCb:
4868
0
                    oid = blkAes192CbcOid;
4869
0
                    *oidSz = sizeof(blkAes192CbcOid);
4870
0
                    break;
4871
0
        #endif
4872
0
        #ifdef WOLFSSL_AES_256
4873
0
                case AES256CBCb:
4874
0
                    oid = blkAes256CbcOid;
4875
0
                    *oidSz = sizeof(blkAes256CbcOid);
4876
0
                    break;
4877
0
        #endif
4878
0
    #endif /* HAVE_AES_CBC */
4879
0
    #ifdef HAVE_AESGCM
4880
0
        #ifdef WOLFSSL_AES_128
4881
0
                case AES128GCMb:
4882
0
                    oid = blkAes128GcmOid;
4883
0
                    *oidSz = sizeof(blkAes128GcmOid);
4884
0
                    break;
4885
0
        #endif
4886
0
        #ifdef WOLFSSL_AES_192
4887
0
                case AES192GCMb:
4888
0
                    oid = blkAes192GcmOid;
4889
0
                    *oidSz = sizeof(blkAes192GcmOid);
4890
0
                    break;
4891
0
        #endif
4892
0
        #ifdef WOLFSSL_AES_256
4893
0
                case AES256GCMb:
4894
0
                    oid = blkAes256GcmOid;
4895
0
                    *oidSz = sizeof(blkAes256GcmOid);
4896
0
                    break;
4897
0
        #endif
4898
0
    #endif /* HAVE_AESGCM */
4899
0
    #ifdef HAVE_AESCCM
4900
0
        #ifdef WOLFSSL_AES_128
4901
0
                case AES128CCMb:
4902
0
                    oid = blkAes128CcmOid;
4903
0
                    *oidSz = sizeof(blkAes128CcmOid);
4904
0
                    break;
4905
0
        #endif
4906
0
        #ifdef WOLFSSL_AES_192
4907
0
                case AES192CCMb:
4908
0
                    oid = blkAes192CcmOid;
4909
0
                    *oidSz = sizeof(blkAes192CcmOid);
4910
0
                    break;
4911
0
        #endif
4912
0
        #ifdef WOLFSSL_AES_256
4913
0
                case AES256CCMb:
4914
0
                    oid = blkAes256CcmOid;
4915
0
                    *oidSz = sizeof(blkAes256CcmOid);
4916
0
                    break;
4917
0
        #endif
4918
0
    #endif /* HAVE_AESCCM */
4919
0
    #ifndef NO_DES3
4920
0
                case DESb:
4921
0
                    oid = blkDesCbcOid;
4922
0
                    *oidSz = sizeof(blkDesCbcOid);
4923
0
                    break;
4924
0
                case DES3b:
4925
0
                    oid = blkDes3CbcOid;
4926
0
                    *oidSz = sizeof(blkDes3CbcOid);
4927
0
                    break;
4928
0
    #endif /* !NO_DES3 */
4929
0
                default:
4930
0
                    break;
4931
0
            }
4932
0
            break;
4933
4934
        #ifdef HAVE_OCSP
4935
        case oidOcspType:
4936
            switch (id) {
4937
                case OCSP_BASIC_OID:
4938
                    oid = ocspBasicOid;
4939
                    *oidSz = sizeof(ocspBasicOid);
4940
                    break;
4941
                case OCSP_NONCE_OID:
4942
                    oid = ocspNonceOid;
4943
                    *oidSz = sizeof(ocspNonceOid);
4944
                    break;
4945
                default:
4946
                    break;
4947
            }
4948
            break;
4949
        #endif /* HAVE_OCSP */
4950
4951
0
        case oidCertExtType:
4952
0
            switch (id) {
4953
0
                case BASIC_CA_OID:
4954
0
                    oid = extBasicCaOid;
4955
0
                    *oidSz = sizeof(extBasicCaOid);
4956
0
                    break;
4957
0
                case ALT_NAMES_OID:
4958
0
                    oid = extAltNamesOid;
4959
0
                    *oidSz = sizeof(extAltNamesOid);
4960
0
                    break;
4961
0
                case CRL_DIST_OID:
4962
0
                    oid = extCrlDistOid;
4963
0
                    *oidSz = sizeof(extCrlDistOid);
4964
0
                    break;
4965
0
                case AUTH_INFO_OID:
4966
0
                    oid = extAuthInfoOid;
4967
0
                    *oidSz = sizeof(extAuthInfoOid);
4968
0
                    break;
4969
0
                case AUTH_KEY_OID:
4970
0
                    oid = extAuthKeyOid;
4971
0
                    *oidSz = sizeof(extAuthKeyOid);
4972
0
                    break;
4973
0
                case SUBJ_KEY_OID:
4974
0
                    oid = extSubjKeyOid;
4975
0
                    *oidSz = sizeof(extSubjKeyOid);
4976
0
                    break;
4977
0
                case CERT_POLICY_OID:
4978
0
                    oid = extCertPolicyOid;
4979
0
                    *oidSz = sizeof(extCertPolicyOid);
4980
0
                    break;
4981
0
                case KEY_USAGE_OID:
4982
0
                    oid = extKeyUsageOid;
4983
0
                    *oidSz = sizeof(extKeyUsageOid);
4984
0
                    break;
4985
0
                case INHIBIT_ANY_OID:
4986
0
                    oid = extInhibitAnyOid;
4987
0
                    *oidSz = sizeof(extInhibitAnyOid);
4988
0
                    break;
4989
0
                case EXT_KEY_USAGE_OID:
4990
0
                    oid = extExtKeyUsageOid;
4991
0
                    *oidSz = sizeof(extExtKeyUsageOid);
4992
0
                    break;
4993
0
            #ifndef IGNORE_NAME_CONSTRAINTS
4994
0
                case NAME_CONS_OID:
4995
0
                    oid = extNameConsOid;
4996
0
                    *oidSz = sizeof(extNameConsOid);
4997
0
                    break;
4998
0
            #endif
4999
            #ifdef HAVE_OCSP
5000
                case OCSP_NOCHECK_OID:
5001
                    oid = ocspNoCheckOid;
5002
                    *oidSz = sizeof(ocspNoCheckOid);
5003
                    break;
5004
            #endif
5005
            #ifdef WOLFSSL_SUBJ_DIR_ATTR
5006
                case SUBJ_DIR_ATTR_OID:
5007
                    oid = extSubjDirAttrOid;
5008
                    *oidSz = sizeof(extSubjDirAttrOid);
5009
                    break;
5010
            #endif
5011
            #ifdef WOLFSSL_SUBJ_INFO_ACC
5012
                case SUBJ_INFO_ACC_OID:
5013
                    oid = extSubjInfoAccessOid;
5014
                    *oidSz = sizeof(extSubjInfoAccessOid);
5015
                    break;
5016
            #endif
5017
0
                default:
5018
0
                    break;
5019
0
            }
5020
0
            break;
5021
5022
0
        case oidCrlExtType:
5023
            #ifdef HAVE_CRL
5024
            switch (id) {
5025
                case AUTH_KEY_OID:
5026
                    oid = extAuthKeyOid;
5027
                    *oidSz = sizeof(extAuthKeyOid);
5028
                    break;
5029
                case CRL_NUMBER_OID:
5030
                    oid = extCrlNumberOid;
5031
                    *oidSz = sizeof(extCrlNumberOid);
5032
                    break;
5033
                default:
5034
                    break;
5035
            }
5036
            #endif
5037
0
            break;
5038
5039
0
        case oidCertAuthInfoType:
5040
0
            switch (id) {
5041
0
                case AIA_OCSP_OID:
5042
0
                    oid = extAuthInfoOcspOid;
5043
0
                    *oidSz = sizeof(extAuthInfoOcspOid);
5044
0
                    break;
5045
0
                case AIA_CA_ISSUER_OID:
5046
0
                    oid = extAuthInfoCaIssuerOid;
5047
0
                    *oidSz = sizeof(extAuthInfoCaIssuerOid);
5048
0
                    break;
5049
                #ifdef WOLFSSL_SUBJ_INFO_ACC
5050
                case AIA_CA_REPO_OID:
5051
                    oid = extAuthInfoCaRespOid;
5052
                    *oidSz = sizeof(extAuthInfoCaRespOid);
5053
                    break;
5054
                #endif /* WOLFSSL_SUBJ_INFO_ACC */
5055
0
                default:
5056
0
                    break;
5057
0
            }
5058
0
            break;
5059
5060
0
        case oidCertPolicyType:
5061
0
            switch (id) {
5062
0
                case CP_ANY_OID:
5063
0
                    oid = extCertPolicyAnyOid;
5064
0
                    *oidSz = sizeof(extCertPolicyAnyOid);
5065
0
                    break;
5066
                #if defined(WOLFSSL_FPKI)
5067
                case CP_FPKI_COMMON_AUTH_OID:
5068
                    oid = extCertPolicyFpkiCommonAuthOid;
5069
                    *oidSz = sizeof(extCertPolicyFpkiCommonAuthOid);
5070
                    break;
5071
                case CP_FPKI_PIV_AUTH_OID:
5072
                    oid = extCertPolicyFpkiPivAuthOid;
5073
                    *oidSz = sizeof(extCertPolicyFpkiPivAuthOid);
5074
                    break;
5075
                case CP_FPKI_PIV_AUTH_HW_OID: /* collision with AES256CBCb */
5076
                    oid = extCertPolicyFpkiPivAuthHwOid;
5077
                    *oidSz = sizeof(extCertPolicyFpkiPivAuthHwOid);
5078
                    break;
5079
                case CP_FPKI_PIVI_AUTH_OID:
5080
                    oid = extCertPolicyFpkiPiviAuthOid;
5081
                    *oidSz = sizeof(extCertPolicyFpkiPiviAuthOid);
5082
                    break;
5083
                #endif /* WOLFSSL_FPKI */
5084
0
                default:
5085
0
                    break;
5086
0
            }
5087
0
            break;
5088
5089
0
        case oidCertAltNameType:
5090
0
            switch (id) {
5091
0
                case HW_NAME_OID:
5092
0
                    oid = extAltNamesHwNameOid;
5093
0
                    *oidSz = sizeof(extAltNamesHwNameOid);
5094
0
                    break;
5095
0
                default:
5096
0
                    break;
5097
0
            }
5098
0
            break;
5099
5100
0
        case oidCertKeyUseType:
5101
0
            switch (id) {
5102
0
                case EKU_ANY_OID:
5103
0
                    oid = extExtKeyUsageAnyOid;
5104
0
                    *oidSz = sizeof(extExtKeyUsageAnyOid);
5105
0
                    break;
5106
0
                case EKU_SERVER_AUTH_OID:
5107
0
                    oid = extExtKeyUsageServerAuthOid;
5108
0
                    *oidSz = sizeof(extExtKeyUsageServerAuthOid);
5109
0
                    break;
5110
0
                case EKU_CLIENT_AUTH_OID:
5111
0
                    oid = extExtKeyUsageClientAuthOid;
5112
0
                    *oidSz = sizeof(extExtKeyUsageClientAuthOid);
5113
0
                    break;
5114
0
                case EKU_CODESIGNING_OID:
5115
0
                    oid = extExtKeyUsageCodeSigningOid;
5116
0
                    *oidSz = sizeof(extExtKeyUsageCodeSigningOid);
5117
0
                    break;
5118
0
                case EKU_EMAILPROTECT_OID:
5119
0
                    oid = extExtKeyUsageEmailProtectOid;
5120
0
                    *oidSz = sizeof(extExtKeyUsageEmailProtectOid);
5121
0
                    break;
5122
0
                case EKU_TIMESTAMP_OID:
5123
0
                    oid = extExtKeyUsageTimestampOid;
5124
0
                    *oidSz = sizeof(extExtKeyUsageTimestampOid);
5125
0
                    break;
5126
0
                case EKU_OCSP_SIGN_OID:
5127
0
                    oid = extExtKeyUsageOcspSignOid;
5128
0
                    *oidSz = sizeof(extExtKeyUsageOcspSignOid);
5129
0
                    break;
5130
                #ifdef WOLFSSL_WOLFSSH
5131
                case EKU_SSH_CLIENT_AUTH_OID:
5132
                    oid = extExtKeyUsageSshClientAuthOid;
5133
                    *oidSz = sizeof(extExtKeyUsageSshClientAuthOid);
5134
                    break;
5135
                case EKU_SSH_MSCL_OID:
5136
                    oid = extExtKeyUsageSshMSCLOid;
5137
                    *oidSz = sizeof(extExtKeyUsageSshMSCLOid);
5138
                    break;
5139
                case EKU_SSH_KP_CLIENT_AUTH_OID:
5140
                    oid = extExtKeyUsageSshKpClientAuthOid;
5141
                    *oidSz = sizeof(extExtKeyUsageSshKpClientAuthOid);
5142
                    break;
5143
                #endif /* WOLFSSL_WOLFSSH */
5144
0
                default:
5145
0
                    break;
5146
0
            }
5147
0
            break;
5148
5149
0
        case oidKdfType:
5150
0
            switch (id) {
5151
0
                case PBKDF2_OID:
5152
0
                    oid = pbkdf2Oid;
5153
0
                    *oidSz = sizeof(pbkdf2Oid);
5154
0
                    break;
5155
0
                default:
5156
0
                    break;
5157
0
            }
5158
0
            break;
5159
5160
0
        case oidPBEType:
5161
0
            switch (id) {
5162
0
        #if !defined(NO_SHA) && !defined(NO_RC4)
5163
0
                case PBE_SHA1_RC4_128_SUM:
5164
0
                case PBE_SHA1_RC4_128:
5165
0
                    oid = pbeSha1RC4128;
5166
0
                    *oidSz = sizeof(pbeSha1RC4128);
5167
0
                    break;
5168
0
        #endif
5169
0
        #if !defined(NO_MD5) && !defined(NO_DES3)
5170
0
                case PBE_MD5_DES_SUM:
5171
0
                case PBE_MD5_DES:
5172
0
                    oid = pbeMd5Des;
5173
0
                    *oidSz = sizeof(pbeMd5Des);
5174
0
                    break;
5175
5176
0
        #endif
5177
0
        #if !defined(NO_SHA) && !defined(NO_DES3)
5178
0
                case PBE_SHA1_DES_SUM:
5179
0
                case PBE_SHA1_DES:
5180
0
                    oid = pbeSha1Des;
5181
0
                    *oidSz = sizeof(pbeSha1Des);
5182
0
                    break;
5183
5184
0
        #endif
5185
0
        #if !defined(NO_SHA) && !defined(NO_DES3)
5186
0
                case PBE_SHA1_DES3_SUM:
5187
0
                case PBE_SHA1_DES3:
5188
0
                    oid = pbeSha1Des3;
5189
0
                    *oidSz = sizeof(pbeSha1Des3);
5190
0
                    break;
5191
0
        #endif
5192
        #if !defined(NO_SHA) && defined(WC_RC2)
5193
                case PBE_SHA1_40RC2_CBC_SUM:
5194
                case PBE_SHA1_40RC2_CBC:
5195
                    oid = pbe40Rc2Cbc;
5196
                    *oidSz = sizeof(pbe40Rc2Cbc);
5197
                    break;
5198
        #endif
5199
0
                case PBES2_SUM:
5200
0
                case PBES2:
5201
0
                    oid = pbes2;
5202
0
                    *oidSz = sizeof(pbes2);
5203
0
                    break;
5204
0
                default:
5205
0
                    break;
5206
0
            }
5207
0
            break;
5208
5209
0
        case oidKeyWrapType:
5210
0
            switch (id) {
5211
0
            #ifdef WOLFSSL_AES_128
5212
0
                case AES128_WRAP:
5213
0
                    oid = wrapAes128Oid;
5214
0
                    *oidSz = sizeof(wrapAes128Oid);
5215
0
                    break;
5216
0
            #endif
5217
0
            #ifdef WOLFSSL_AES_192
5218
0
                case AES192_WRAP:
5219
0
                    oid = wrapAes192Oid;
5220
0
                    *oidSz = sizeof(wrapAes192Oid);
5221
0
                    break;
5222
0
            #endif
5223
0
            #ifdef WOLFSSL_AES_256
5224
0
                case AES256_WRAP:
5225
0
                    oid = wrapAes256Oid;
5226
0
                    *oidSz = sizeof(wrapAes256Oid);
5227
0
                    break;
5228
0
            #endif
5229
            #ifdef HAVE_PKCS7
5230
                case PWRI_KEK_WRAP:
5231
                    oid = wrapPwriKekOid;
5232
                    *oidSz = sizeof(wrapPwriKekOid);
5233
                    break;
5234
            #endif
5235
0
                default:
5236
0
                    break;
5237
0
            }
5238
0
            break;
5239
5240
0
        case oidCmsKeyAgreeType:
5241
0
            switch (id) {
5242
0
            #ifndef NO_SHA
5243
0
                case dhSinglePass_stdDH_sha1kdf_scheme:
5244
0
                    oid = dhSinglePass_stdDH_sha1kdf_Oid;
5245
0
                    *oidSz = sizeof(dhSinglePass_stdDH_sha1kdf_Oid);
5246
0
                    break;
5247
0
            #endif
5248
0
            #ifdef WOLFSSL_SHA224
5249
0
                case dhSinglePass_stdDH_sha224kdf_scheme:
5250
0
                    oid = dhSinglePass_stdDH_sha224kdf_Oid;
5251
0
                    *oidSz = sizeof(dhSinglePass_stdDH_sha224kdf_Oid);
5252
0
                    break;
5253
0
            #endif
5254
0
            #ifndef NO_SHA256
5255
0
                case dhSinglePass_stdDH_sha256kdf_scheme:
5256
0
                    oid = dhSinglePass_stdDH_sha256kdf_Oid;
5257
0
                    *oidSz = sizeof(dhSinglePass_stdDH_sha256kdf_Oid);
5258
0
                    break;
5259
0
            #endif
5260
0
            #ifdef WOLFSSL_SHA384
5261
0
                case dhSinglePass_stdDH_sha384kdf_scheme:
5262
0
                    oid = dhSinglePass_stdDH_sha384kdf_Oid;
5263
0
                    *oidSz = sizeof(dhSinglePass_stdDH_sha384kdf_Oid);
5264
0
                    break;
5265
0
            #endif
5266
0
            #ifdef WOLFSSL_SHA512
5267
0
                case dhSinglePass_stdDH_sha512kdf_scheme:
5268
0
                    oid = dhSinglePass_stdDH_sha512kdf_Oid;
5269
0
                    *oidSz = sizeof(dhSinglePass_stdDH_sha512kdf_Oid);
5270
0
                    break;
5271
0
            #endif
5272
0
                default:
5273
0
                    break;
5274
0
            }
5275
0
            break;
5276
5277
0
#ifndef NO_HMAC
5278
0
        case oidHmacType:
5279
0
            switch (id) {
5280
0
        #ifdef WOLFSSL_SHA224
5281
0
                case HMAC_SHA224_OID:
5282
0
                    oid = hmacSha224Oid;
5283
0
                    *oidSz = sizeof(hmacSha224Oid);
5284
0
                    break;
5285
0
        #endif
5286
0
        #ifndef NO_SHA256
5287
0
                case HMAC_SHA256_OID:
5288
0
                    oid = hmacSha256Oid;
5289
0
                    *oidSz = sizeof(hmacSha256Oid);
5290
0
                    break;
5291
0
        #endif
5292
0
        #ifdef WOLFSSL_SHA384
5293
0
                case HMAC_SHA384_OID:
5294
0
                    oid = hmacSha384Oid;
5295
0
                    *oidSz = sizeof(hmacSha384Oid);
5296
0
                    break;
5297
0
        #endif
5298
0
        #ifdef WOLFSSL_SHA512
5299
0
                case HMAC_SHA512_OID:
5300
0
                    oid = hmacSha512Oid;
5301
0
                    *oidSz = sizeof(hmacSha512Oid);
5302
0
                    break;
5303
0
        #endif
5304
0
                default:
5305
0
                    break;
5306
0
            }
5307
0
            break;
5308
0
#endif /* !NO_HMAC */
5309
5310
#ifdef HAVE_LIBZ
5311
        case oidCompressType:
5312
            switch (id) {
5313
                case ZLIBc:
5314
                    oid = zlibCompress;
5315
                    *oidSz = sizeof(zlibCompress);
5316
                    break;
5317
                default:
5318
                    break;
5319
            }
5320
            break;
5321
#endif /* HAVE_LIBZ */
5322
#ifdef WOLFSSL_APACHE_HTTPD
5323
        case oidCertNameType:
5324
            switch (id) {
5325
                 case NID_id_on_dnsSRV:
5326
                    oid = dnsSRVOid;
5327
                    *oidSz = sizeof(dnsSRVOid);
5328
                    break;
5329
                default:
5330
                    break;
5331
            }
5332
            break;
5333
        case oidTlsExtType:
5334
            switch (id) {
5335
                case TLS_FEATURE_OID:
5336
                    oid = tlsFeatureOid;
5337
                    *oidSz = sizeof(tlsFeatureOid);
5338
                    break;
5339
                default:
5340
                    break;
5341
            }
5342
            break;
5343
#endif /* WOLFSSL_APACHE_HTTPD */
5344
#ifdef WOLFSSL_CERT_REQ
5345
        case oidCsrAttrType:
5346
            switch (id) {
5347
                case GIVEN_NAME_OID:
5348
                    oid = attrGivenName;
5349
                    *oidSz = sizeof(attrGivenName);
5350
                    break;
5351
                case SURNAME_OID:
5352
                    oid = attrSurname;
5353
                    *oidSz = sizeof(attrSurname);
5354
                    break;
5355
                case INITIALS_OID:
5356
                    oid = attrInitals;
5357
                    *oidSz = sizeof(attrInitals);
5358
                    break;
5359
                case DNQUALIFIER_OID:
5360
                    oid = attrDnQualifier;
5361
                    *oidSz = sizeof(attrDnQualifier);
5362
                    break;
5363
                case UNSTRUCTURED_NAME_OID:
5364
                    oid = attrUnstructuredNameOid;
5365
                    *oidSz = sizeof(attrUnstructuredNameOid);
5366
                    break;
5367
                case PKCS9_CONTENT_TYPE_OID:
5368
                    oid = attrPkcs9ContentTypeOid;
5369
                    *oidSz = sizeof(attrPkcs9ContentTypeOid);
5370
                    break;
5371
                case CHALLENGE_PASSWORD_OID:
5372
                    oid = attrChallengePasswordOid;
5373
                    *oidSz = sizeof(attrChallengePasswordOid);
5374
                    break;
5375
                case SERIAL_NUMBER_OID:
5376
                    oid = attrSerialNumberOid;
5377
                    *oidSz = sizeof(attrSerialNumberOid);
5378
                    break;
5379
                case USER_ID_OID:
5380
                    oid = uidOid;
5381
                    *oidSz = sizeof(uidOid);
5382
                    break;
5383
                case EXTENSION_REQUEST_OID:
5384
                    oid = attrExtensionRequestOid;
5385
                    *oidSz = sizeof(attrExtensionRequestOid);
5386
                    break;
5387
                default:
5388
                    break;
5389
            }
5390
            break;
5391
#endif
5392
#ifdef WOLFSSL_SUBJ_DIR_ATTR
5393
        case oidSubjDirAttrType:
5394
            switch (id) {
5395
                case SDA_DOB_OID:
5396
                    oid = extSubjDirAttrDobOid;
5397
                    *oidSz = sizeof(extSubjDirAttrDobOid);
5398
                    break;
5399
                case SDA_POB_OID:
5400
                    oid = extSubjDirAttrPobOid;
5401
                    *oidSz = sizeof(extSubjDirAttrPobOid);
5402
                    break;
5403
                case SDA_GENDER_OID:
5404
                    oid = extSubjDirAttrGenderOid;
5405
                    *oidSz = sizeof(extSubjDirAttrGenderOid);
5406
                    break;
5407
                case SDA_COC_OID:
5408
                    oid = extSubjDirAttrCocOid;
5409
                    *oidSz = sizeof(extSubjDirAttrCocOid);
5410
                    break;
5411
                case SDA_COR_OID:
5412
                    oid = extSubjDirAttrCorOid;
5413
                    *oidSz = sizeof(extSubjDirAttrCorOid);
5414
                    break;
5415
                default:
5416
                    break;
5417
            }
5418
            break;
5419
#endif /* WOLFSSL_SUBJ_DIR_ATTR */
5420
0
        case oidIgnoreType:
5421
0
        default:
5422
0
            break;
5423
0
    }
5424
5425
0
    return oid;
5426
0
}
5427
5428
#ifdef HAVE_ECC
5429
5430
/* Check the OID id is for a known elliptic curve.
5431
 *
5432
 * @param [in]  oid  OID id.
5433
 * @return  ECC set id on success.
5434
 * @return  ECC_CURVE_OID_E when OID id is 0 or not supported.
5435
 */
5436
static int CheckCurve(word32 oid)
5437
0
{
5438
0
    int ret;
5439
0
    word32 oidSz;
5440
5441
    /* Lookup OID id. */
5442
0
    ret = wc_ecc_get_oid(oid, NULL, &oidSz);
5443
    /* Check for error or zero length OID size (can't get OID for encoding). */
5444
0
    if ((ret < 0) || (oidSz == 0)) {
5445
0
        WOLFSSL_MSG("CheckCurve not found");
5446
0
        WOLFSSL_ERROR_VERBOSE(ECC_CURVE_OID_E);
5447
0
        ret = ECC_CURVE_OID_E;
5448
0
    }
5449
5450
    /* Return ECC set id or error code. */
5451
0
    return ret;
5452
0
}
5453
5454
#endif
5455
5456
#ifdef HAVE_OID_ENCODING
5457
/* Encode dotted form of OID into byte array version.
5458
 *
5459
 * @param [in]      in     Dotted form of OID.
5460
 * @param [in]      inSz   Count of numbers in dotted form.
5461
 * @param [in]      out    Buffer to hold OID.
5462
 * @param [in, out] outSz  On in, size of buffer.
5463
 *                         On out, number of bytes in buffer.
5464
 * @return  0 on success
5465
 * @return  BAD_FUNC_ARG when in or outSz is NULL.
5466
 * @return  BUFFER_E when buffer too small.
5467
 */
5468
int EncodeObjectId(const word16* in, word32 inSz, byte* out, word32* outSz)
5469
{
5470
    int i, x, len;
5471
    word32 d, t;
5472
5473
    /* check args */
5474
    if (in == NULL || outSz == NULL) {
5475
        return BAD_FUNC_ARG;
5476
    }
5477
5478
    /* compute length of encoded OID */
5479
    d = (in[0] * 40) + in[1];
5480
    len = 0;
5481
    for (i = 1; i < (int)inSz; i++) {
5482
        x = 0;
5483
        t = d;
5484
        while (t) {
5485
            x++;
5486
            t >>= 1;
5487
        }
5488
        len += (x / 7) + ((x % 7) ? 1 : 0) + (d == 0 ? 1 : 0);
5489
5490
        if (i < (int)inSz - 1) {
5491
            d = in[i + 1];
5492
        }
5493
    }
5494
5495
    if (out) {
5496
        /* verify length */
5497
        if ((int)*outSz < len) {
5498
            return BUFFER_E; /* buffer provided is not large enough */
5499
        }
5500
5501
        /* calc first byte */
5502
        d = (in[0] * 40) + in[1];
5503
5504
        /* encode bytes */
5505
        x = 0;
5506
        for (i = 1; i < (int)inSz; i++) {
5507
            if (d) {
5508
                int y = x, z;
5509
                byte mask = 0;
5510
                while (d) {
5511
                    out[x++] = (byte)((d & 0x7F) | mask);
5512
                    d     >>= 7;
5513
                    mask  |= 0x80;  /* upper bit is set on all but the last byte */
5514
                }
5515
                /* now swap bytes y...x-1 */
5516
                z = x - 1;
5517
                while (y < z) {
5518
                    mask = out[y];
5519
                    out[y] = out[z];
5520
                    out[z] = mask;
5521
                    ++y;
5522
                    --z;
5523
                }
5524
            }
5525
            else {
5526
              out[x++] = 0x00; /* zero value */
5527
            }
5528
5529
            /* next word */
5530
            if (i < (int)inSz - 1) {
5531
                d = in[i + 1];
5532
            }
5533
        }
5534
    }
5535
5536
    /* return length */
5537
    *outSz = len;
5538
5539
    return 0;
5540
}
5541
#endif /* HAVE_OID_ENCODING */
5542
5543
#if defined(HAVE_OID_DECODING) || defined(WOLFSSL_ASN_PRINT)
5544
/* Encode dotted form of OID into byte array version.
5545
 *
5546
 * @param [in]      in     Byte array containing OID.
5547
 * @param [in]      inSz   Size of OID in bytes.
5548
 * @param [in]      out    Array to hold dotted form of OID.
5549
 * @param [in, out] outSz  On in, number of elements in array.
5550
 *                         On out, count of numbers in dotted form.
5551
 * @return  0 on success
5552
 * @return  BAD_FUNC_ARG when in or outSz is NULL.
5553
 * @return  BUFFER_E when dotted form buffer too small.
5554
 */
5555
int DecodeObjectId(const byte* in, word32 inSz, word16* out, word32* outSz)
5556
0
{
5557
0
    int x = 0, y = 0;
5558
0
    word32 t = 0;
5559
5560
    /* check args */
5561
0
    if (in == NULL || outSz == NULL) {
5562
0
        return BAD_FUNC_ARG;
5563
0
    }
5564
5565
    /* decode bytes */
5566
0
    while (inSz--) {
5567
0
        t = (t << 7) | (in[x] & 0x7F);
5568
0
        if (!(in[x] & 0x80)) {
5569
0
            if (y >= (int)*outSz) {
5570
0
                return BUFFER_E;
5571
0
            }
5572
0
            if (y == 0) {
5573
0
                out[0] = (word16)(t / 40);
5574
0
                out[1] = (word16)(t % 40);
5575
0
                y = 2;
5576
0
            }
5577
0
            else {
5578
0
                out[y++] = (word16)t;
5579
0
            }
5580
0
            t = 0; /* reset tmp */
5581
0
        }
5582
0
        x++;
5583
0
    }
5584
5585
    /* return length */
5586
0
    *outSz = (word32)y;
5587
5588
0
    return 0;
5589
0
}
5590
#endif /* HAVE_OID_DECODING */
5591
5592
/* Decode the header of a BER/DER encoded OBJECT ID.
5593
 *
5594
 * @param [in]      input     Buffer holding DER/BER encoded data.
5595
 * @param [in, out] inOutIdx  On in, starting index of header.
5596
 *                            On out, end of parsed header.
5597
 * @param [out]     len       Number of bytes in the ASN.1 data.
5598
 * @param [in]      maxIdx    Length of data in buffer.
5599
 * @return  0 on success.
5600
 * @return  BUFFER_E when there is not enough data to parse.
5601
 * @return  ASN_PARSE_E when the tag is not a OBJECT ID or length is invalid.
5602
 */
5603
int GetASNObjectId(const byte* input, word32* inOutIdx, int* len, word32 maxIdx)
5604
0
{
5605
0
    int ret = GetASNHeader(input, ASN_OBJECT_ID, inOutIdx, len, maxIdx);
5606
0
    if (ret > 0) {
5607
        /* Only return 0 on success. */
5608
0
        ret = 0;
5609
0
    }
5610
0
    return ret;
5611
0
}
5612
5613
/* Set the DER/BER encoding of the ASN.1 OBJECT ID header.
5614
 *
5615
 * When output is NULL, calculate the header length only.
5616
 *
5617
 * @param [in]  len        Length of OBJECT ID data in bytes.
5618
 * @param [out] output     Buffer to write into.
5619
 * @return  Number of bytes added to the buffer.
5620
 */
5621
int SetObjectId(int len, byte* output)
5622
0
{
5623
0
    int idx = 0;
5624
5625
0
    if (output) {
5626
        /* Write out tag. */
5627
0
        output[idx] = ASN_OBJECT_ID;
5628
0
    }
5629
    /* Skip tag. */
5630
0
    idx += ASN_TAG_SZ;
5631
    /* Encode length - passing NULL for output will not encode. */
5632
0
    idx += (int)SetLength((word32)len, output ? output + idx : NULL);
5633
5634
    /* Return index after header. */
5635
0
    return idx;
5636
0
}
5637
5638
#ifdef ASN_DUMP_OID
5639
/* Dump the OID information.
5640
 *
5641
 * Decode the OID too if function available.
5642
 *
5643
 * @param [in] oidData  OID data from buffer.
5644
 * @param [in] oidSz    Size of OID data in buffer.
5645
 * @param [in] oid      OID id.
5646
 * @param [in] oidType  Type of OID.
5647
 * @return  0 on success.
5648
 * @return  BUFFER_E when not enough bytes for proper decode.
5649
 *          (HAVE_OID_DECODING)
5650
 */
5651
static int DumpOID(const byte* oidData, word32 oidSz, word32 oid,
5652
                   word32 oidType)
5653
{
5654
    int    ret = 0;
5655
    word32 i;
5656
5657
    /* support for dumping OID information */
5658
    printf("OID (Type %d, Sz %d, Sum %d): ", oidType, oidSz, oid);
5659
    /* Dump bytes in decimal. */
5660
    for (i = 0; i < oidSz; i++) {
5661
        printf("%d, ", oidData[i]);
5662
    }
5663
    printf("\n");
5664
    /* Dump bytes in hexadecimal. */
5665
    for (i = 0; i < oidSz; i++) {
5666
        printf("%02x, ", oidData[i]);
5667
    }
5668
    printf("\n");
5669
5670
    #ifdef HAVE_OID_DECODING
5671
    {
5672
        word16 decOid[MAX_OID_SZ];
5673
        word32 decOidSz = sizeof(decOid);
5674
        /* Decode the OID into dotted form. */
5675
        ret = DecodeObjectId(oidData, oidSz, decOid, &decOidSz);
5676
        if (ret == 0) {
5677
            printf("  Decoded (Sz %d): ", decOidSz);
5678
            for (i=0; i<decOidSz; i++) {
5679
                printf("%d.", decOid[i]);
5680
            }
5681
            printf("\n");
5682
        }
5683
        else {
5684
            printf("DecodeObjectId failed: %d\n", ret);
5685
        }
5686
    }
5687
    #endif /* HAVE_OID_DECODING */
5688
5689
    return ret;
5690
}
5691
#endif /* ASN_DUMP_OID */
5692
5693
/* Get the OID data and verify it is of the type specified when compiled in.
5694
 *
5695
 * @param [in]      input     Buffer holding OID.
5696
 * @param [in, out] inOutIdx  On in, starting index of OID.
5697
 *                            On out, end of parsed OID.
5698
 * @param [out]     oid       OID id.
5699
 * @param [in]      oidType   Expected type of OID. Define NO_VERIFY_OID to
5700
 *                            not compile in check.
5701
 * @param [in]      length    Length of OID data in buffer.
5702
 * @return  0 on success.
5703
 * @return  ASN_UNKNOWN_OID_E when OID is not recognized.
5704
 * @return  BUFFER_E when not enough bytes for proper decode. (ASN_DUMP_OID and
5705
 *          HAVE_OID_DECODING)
5706
 */
5707
static int GetOID(const byte* input, word32* inOutIdx, word32* oid,
5708
                  word32 oidType, int length)
5709
0
{
5710
0
    int    ret = 0;
5711
0
    word32 idx = *inOutIdx;
5712
0
#ifndef NO_VERIFY_OID
5713
0
    word32 actualOidSz;
5714
0
    const byte* actualOid;
5715
0
    const byte* checkOid = NULL;
5716
0
    word32 checkOidSz;
5717
0
#endif /* NO_VERIFY_OID */
5718
#ifdef HAVE_PQC
5719
    word32 found_collision = 0;
5720
#endif
5721
0
    (void)oidType;
5722
0
    *oid = 0;
5723
5724
0
#ifndef NO_VERIFY_OID
5725
    /* Keep references to OID data and length for check. */
5726
0
    actualOid = &input[idx];
5727
0
    actualOidSz = (word32)length;
5728
0
#endif /* NO_VERIFY_OID */
5729
5730
#if defined(HAVE_PQC) && defined(HAVE_LIBOQS)
5731
    /* Since we are summing it up, there could be collisions...and indeed there
5732
     * are: SPHINCS_FAST_LEVEL1 and SPHINCS_FAST_LEVEL3.
5733
     *
5734
     * We will look for the special case of SPHINCS_FAST_LEVEL3 and set *oid to
5735
     * 283 instead of 281; 282 is taken.
5736
     *
5737
     * These hacks will hopefully disappear when new standardized OIDs appear.
5738
     */
5739
    if (memcmp(&input[idx], sigSphincsFast_Level3Oid,
5740
               sizeof(sigSphincsFast_Level3Oid)) == 0) {
5741
        found_collision = SPHINCS_FAST_LEVEL3k;
5742
    }
5743
#endif /* HAVE_PQC */
5744
5745
    /* Sum it up for now. */
5746
0
    while (length--) {
5747
        /* odd HC08 compiler behavior here when input[idx++] */
5748
0
        *oid += (word32)input[idx];
5749
0
        idx++;
5750
0
    }
5751
5752
#ifdef HAVE_PQC
5753
    if (found_collision) {
5754
        *oid = found_collision;
5755
    }
5756
#endif /* HAVE_PQC */
5757
5758
    /* Return the index after the OID data. */
5759
0
    *inOutIdx = idx;
5760
5761
0
#ifndef NO_VERIFY_OID
5762
    /* 'Ignore' type means we don't care which OID it is. */
5763
0
    if (oidType != oidIgnoreType) {
5764
        /* Get the OID data for the id-type. */
5765
0
        checkOid = OidFromId(*oid, oidType, &checkOidSz);
5766
5767
    #if defined(WOLFSSL_FPKI)
5768
        /* Handle OID sum collision of
5769
            AES256CBCb (454) 2.16.840.1.101.3.4.1.42
5770
            CP_FPKI_PIV_AUTH_HW_OID (454) 2.16.840.1.101.3.2.1.3.41
5771
        */
5772
        #if defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
5773
        if ((actualOidSz == (word32)sizeof(blkAes256CbcOid)) &&
5774
                (XMEMCMP(actualOid, blkAes256CbcOid,
5775
                 sizeof(blkAes256CbcOid)) == 0)) {
5776
5777
            checkOid   = blkAes256CbcOid;
5778
            checkOidSz = sizeof(blkAes256CbcOid);
5779
        }
5780
        #endif /* HAVE_AES_CBC */
5781
    #endif /* WOLFSSL_FPKI */
5782
5783
    #ifdef ASN_DUMP_OID
5784
        /* Dump out the data for debug. */
5785
        ret = DumpOID(actualOid, actualOidSz, *oid, oidType);
5786
    #endif
5787
5788
        /* TODO: Want to fail when checkOid is NULL.
5789
         * Can't as too many situations where unknown OID is to be
5790
         * supported. Extra parameter for must not be NULL?
5791
         */
5792
        /* Check that the OID data matches what we found for the OID id. */
5793
0
        if ((ret == 0) && (checkOid != NULL) && ((checkOidSz != actualOidSz) ||
5794
0
                (XMEMCMP(actualOid, checkOid, checkOidSz) != 0))) {
5795
0
            WOLFSSL_MSG("OID Check Failed");
5796
0
            WOLFSSL_ERROR_VERBOSE(ASN_UNKNOWN_OID_E);
5797
0
            ret = ASN_UNKNOWN_OID_E;
5798
0
        }
5799
0
    }
5800
0
#endif /* NO_VERIFY_OID */
5801
5802
0
    return ret;
5803
0
}
5804
5805
#ifdef WOLFSSL_ASN_TEMPLATE
5806
/* ASN.1 template for an OBJECT_ID. */
5807
static const ASNItem objectIdASN[] = {
5808
/* OID */ { 0, ASN_OBJECT_ID, 0, 0, 0 }
5809
};
5810
enum {
5811
    OBJECTIDASN_IDX_OID = 0
5812
};
5813
5814
/* Number of items in ASN.1 template for an OBJECT_ID. */
5815
0
#define objectIdASN_Length (sizeof(objectIdASN) / sizeof(ASNItem))
5816
#endif
5817
5818
/* Get the OID id/sum from the BER encoded OBJECT_ID.
5819
 *
5820
 * @param [in]      input     Buffer holding BER encoded data.
5821
 * @param [in, out] inOutIdx  On in, start of OBJECT_ID.
5822
 *                            On out, start of ASN.1 item after OBJECT_ID.
5823
 * @param [out]     oid       Id of OID in OBJECT_ID data.
5824
 * @param [in]      oidType   Type of OID to expect.
5825
 * @param [in]      maxIdx    Maximum index of data in buffer.
5826
 * @return  0 on success.
5827
 * @return  ASN_PARSE_E when encoding is invalid.
5828
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
5829
 */
5830
int GetObjectId(const byte* input, word32* inOutIdx, word32* oid,
5831
                                  word32 oidType, word32 maxIdx)
5832
0
{
5833
#ifndef WOLFSSL_ASN_TEMPLATE
5834
    int ret, length;
5835
5836
    WOLFSSL_ENTER("GetObjectId");
5837
5838
    ret = GetASNObjectId(input, inOutIdx, &length, maxIdx);
5839
    if (ret != 0)
5840
        return ret;
5841
5842
    return GetOID(input, inOutIdx, oid, oidType, length);
5843
#else
5844
0
    ASNGetData dataASN[objectIdASN_Length];
5845
0
    int ret;
5846
5847
0
    WOLFSSL_ENTER("GetObjectId");
5848
5849
    /* Clear dynamic data and set OID type expected. */
5850
0
    XMEMSET(dataASN, 0, sizeof(dataASN));
5851
0
    GetASN_OID(&dataASN[OBJECTIDASN_IDX_OID], oidType);
5852
    /* Decode OBJECT_ID. */
5853
0
    ret = GetASN_Items(objectIdASN, dataASN, objectIdASN_Length, 0, input,
5854
0
                       inOutIdx, maxIdx);
5855
0
    if (ret == 0) {
5856
        /* Return the id/sum. */
5857
0
        *oid = dataASN[OBJECTIDASN_IDX_OID].data.oid.sum;
5858
0
    }
5859
5860
0
    return ret;
5861
0
#endif /* WOLFSSL_ASN_TEMPLATE */
5862
0
}
5863
5864
#ifndef WOLFSSL_ASN_TEMPLATE
5865
static int SkipObjectId(const byte* input, word32* inOutIdx, word32 maxIdx)
5866
{
5867
    word32 idx = *inOutIdx;
5868
    int    length;
5869
    int ret;
5870
5871
    ret = GetASNObjectId(input, &idx, &length, maxIdx);
5872
    if (ret != 0)
5873
        return ret;
5874
5875
    idx += (word32)length;
5876
    *inOutIdx = idx;
5877
5878
    return 0;
5879
}
5880
#endif
5881
5882
#ifdef WOLFSSL_ASN_TEMPLATE
5883
/* ASN.1 template for an algorithm identifier. */
5884
static const ASNItem algoIdASN[] = {
5885
/*  SEQ  */    { 0, ASN_SEQUENCE, 1, 1, 0 },
5886
/*  OID  */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
5887
/*  NULL */        { 1, ASN_TAG_NULL, 0, 0, 1 },
5888
};
5889
enum {
5890
    ALGOIDASN_IDX_SEQ = 0,
5891
    ALGOIDASN_IDX_OID,
5892
    ALGOIDASN_IDX_NULL
5893
};
5894
5895
/* Number of items in ASN.1 template for an algorithm identifier. */
5896
0
#define algoIdASN_Length (sizeof(algoIdASN) / sizeof(ASNItem))
5897
#endif
5898
5899
/* Get the OID id/sum from the BER encoding of an algorithm identifier.
5900
 *
5901
 * NULL tag is skipped if present.
5902
 *
5903
 * @param [in]      input     Buffer holding BER encoded data.
5904
 * @param [in, out] inOutIdx  On in, start of algorithm identifier.
5905
 *                            On out, start of ASN.1 item after algorithm id.
5906
 * @param [out]     oid       Id of OID in algorithm identifier data.
5907
 * @param [in]      oidType   Type of OID to expect.
5908
 * @param [in]      maxIdx    Maximum index of data in buffer.
5909
 * @return  0 on success.
5910
 * @return  ASN_PARSE_E when encoding is invalid.
5911
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
5912
 */
5913
int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid,
5914
                     word32 oidType, word32 maxIdx)
5915
0
{
5916
#ifndef WOLFSSL_ASN_TEMPLATE
5917
    int    length;
5918
    word32 idx = *inOutIdx;
5919
    int    ret;
5920
    *oid = 0;
5921
5922
    WOLFSSL_ENTER("GetAlgoId");
5923
5924
    if (GetSequence(input, &idx, &length, maxIdx) < 0)
5925
        return ASN_PARSE_E;
5926
5927
    if (GetObjectId(input, &idx, oid, oidType, maxIdx) < 0)
5928
        return ASN_OBJECT_ID_E;
5929
5930
    /* could have NULL tag and 0 terminator, but may not */
5931
    if (idx < maxIdx) {
5932
        word32 localIdx = idx; /*use localIdx to not advance when checking tag*/
5933
        byte   tag;
5934
5935
        if (GetASNTag(input, &localIdx, &tag, maxIdx) == 0) {
5936
            if (tag == ASN_TAG_NULL) {
5937
                ret = GetASNNull(input, &idx, maxIdx);
5938
                if (ret != 0)
5939
                    return ret;
5940
            }
5941
        }
5942
    }
5943
5944
    *inOutIdx = idx;
5945
5946
    return 0;
5947
#else
5948
0
    DECL_ASNGETDATA(dataASN, algoIdASN_Length);
5949
0
    int ret = 0;
5950
5951
0
    WOLFSSL_ENTER("GetAlgoId");
5952
5953
0
    CALLOC_ASNGETDATA(dataASN, algoIdASN_Length, ret, NULL);
5954
0
    if (ret == 0) {
5955
        /* Set OID type expected. */
5956
0
        GetASN_OID(&dataASN[ALGOIDASN_IDX_OID], oidType);
5957
        /* Decode the algorithm identifier. */
5958
0
        ret = GetASN_Items(algoIdASN, dataASN, algoIdASN_Length, 0, input,
5959
0
            inOutIdx, maxIdx);
5960
0
    }
5961
0
    if (ret == 0) {
5962
        /* Return the OID id/sum. */
5963
0
        *oid = dataASN[ALGOIDASN_IDX_OID].data.oid.sum;
5964
0
    }
5965
5966
0
    FREE_ASNGETDATA(dataASN, NULL);
5967
0
    return ret;
5968
0
#endif /* WOLFSSL_ASN_TEMPLATE */
5969
0
}
5970
5971
#ifndef NO_RSA
5972
5973
#ifdef WC_RSA_PSS
5974
/* RFC 8017 - PKCS #1 has RSA PSS parameter ASN definition. */
5975
5976
/* Convert a hash OID to a hash type.
5977
 *
5978
 * @param  [in]   oid   Hash OID.
5979
 * @param  [out]  type  Hash type.
5980
 * @return  0 on success.
5981
 * @return  ASN_PARSE_E when hash OID not supported for RSA PSS.
5982
 */
5983
static int RsaPssHashOidToType(word32 oid, enum wc_HashType* type)
5984
0
{
5985
0
    int ret = 0;
5986
5987
0
    switch (oid) {
5988
    /* SHA-1 is missing as it is the default is not allowed to appear. */
5989
0
#ifdef WOLFSSL_SHA224
5990
0
    case SHA224h:
5991
0
        *type = WC_HASH_TYPE_SHA224;
5992
0
        break;
5993
0
#endif
5994
0
#ifndef NO_SHA256
5995
0
    case SHA256h:
5996
0
        *type = WC_HASH_TYPE_SHA256;
5997
0
        break;
5998
0
#endif
5999
0
#ifdef WOLFSSL_SHA384
6000
0
    case SHA384h:
6001
0
        *type = WC_HASH_TYPE_SHA384;
6002
0
        break;
6003
0
#endif
6004
0
#ifdef WOLFSSL_SHA512
6005
0
    case SHA512h:
6006
0
        *type = WC_HASH_TYPE_SHA512;
6007
0
        break;
6008
    /* TODO: SHA512_224h */
6009
    /* TODO: SHA512_256h */
6010
0
#endif
6011
0
    default:
6012
0
        ret = ASN_PARSE_E;
6013
0
        break;
6014
0
    }
6015
6016
0
    return ret;
6017
0
}
6018
6019
/* Convert a hash OID to a MGF1 type.
6020
 *
6021
 * @param  [in]   oid   Hash OID.
6022
 * @param  [out]  mgf   MGF type.
6023
 * @return  0 on success.
6024
 * @return  ASN_PARSE_E when hash OID not supported for RSA PSS.
6025
 */
6026
static int RsaPssHashOidToMgf1(word32 oid, int* mgf)
6027
0
{
6028
0
    int ret = 0;
6029
6030
0
    switch (oid) {
6031
    /* SHA-1 is missing as it is the default is not allowed to appear. */
6032
0
#ifdef WOLFSSL_SHA224
6033
0
    case SHA224h:
6034
0
        *mgf = WC_MGF1SHA224;
6035
0
        break;
6036
0
#endif
6037
0
#ifndef NO_SHA256
6038
0
    case SHA256h:
6039
0
        *mgf = WC_MGF1SHA256;
6040
0
        break;
6041
0
#endif
6042
0
#ifdef WOLFSSL_SHA384
6043
0
    case SHA384h:
6044
0
        *mgf = WC_MGF1SHA384;
6045
0
        break;
6046
0
#endif
6047
0
#ifdef WOLFSSL_SHA512
6048
0
    case SHA512h:
6049
0
        *mgf = WC_MGF1SHA512;
6050
0
        break;
6051
    /* TODO: SHA512_224h */
6052
    /* TODO: SHA512_256h */
6053
0
#endif
6054
0
    default:
6055
0
        ret = ASN_PARSE_E;
6056
0
        break;
6057
0
    }
6058
6059
0
    return ret;
6060
0
}
6061
6062
#ifndef NO_CERTS
6063
/* Convert a hash OID to a fake signature OID.
6064
 *
6065
 * @param  [in]   oid     Hash OID.
6066
 * @param  [out]  sigOid  Signature OID to pass wto HashForSignature().
6067
 * @return  0 on success.
6068
 * @return  ASN_PARSE_E when hash OID not supported for RSA PSS.
6069
 */
6070
static int RsaPssHashOidToSigOid(word32 oid, word32* sigOid)
6071
0
{
6072
0
    int ret = 0;
6073
6074
0
    switch (oid) {
6075
0
#ifndef NO_SHA
6076
0
    case WC_HASH_TYPE_SHA:
6077
0
        *sigOid = CTC_SHAwRSA;
6078
0
        break;
6079
0
#endif
6080
0
#ifdef WOLFSSL_SHA224
6081
0
    case WC_HASH_TYPE_SHA224:
6082
0
        *sigOid = CTC_SHA224wRSA;
6083
0
        break;
6084
0
#endif
6085
0
#ifndef NO_SHA256
6086
0
    case WC_HASH_TYPE_SHA256:
6087
0
        *sigOid = CTC_SHA256wRSA;
6088
0
        break;
6089
0
#endif
6090
0
#ifdef WOLFSSL_SHA384
6091
0
    case WC_HASH_TYPE_SHA384:
6092
0
        *sigOid = CTC_SHA384wRSA;
6093
0
        break;
6094
0
#endif
6095
0
#ifdef WOLFSSL_SHA512
6096
0
    case WC_HASH_TYPE_SHA512:
6097
0
        *sigOid = CTC_SHA512wRSA;
6098
0
        break;
6099
0
#endif
6100
    /* TODO: SHA512_224h */
6101
    /* TODO: SHA512_256h */
6102
    /* Not supported by HashForSignature() */
6103
0
    default:
6104
0
        ret = ASN_PARSE_E;
6105
0
        break;
6106
0
    }
6107
6108
0
    return ret;
6109
0
}
6110
#endif
6111
6112
#ifdef WOLFSSL_ASN_TEMPLATE
6113
/* ASN tag for hashAlgorigthm. */
6114
#define ASN_TAG_RSA_PSS_HASH        (ASN_CONTEXT_SPECIFIC | 0)
6115
/* ASN tag for maskGenAlgorithm. */
6116
#define ASN_TAG_RSA_PSS_MGF         (ASN_CONTEXT_SPECIFIC | 1)
6117
/* ASN tag for saltLength. */
6118
#define ASN_TAG_RSA_PSS_SALTLEN     (ASN_CONTEXT_SPECIFIC | 2)
6119
/* ASN tag for trailerField. */
6120
#define ASN_TAG_RSA_PSS_TRAILER     (ASN_CONTEXT_SPECIFIC | 3)
6121
6122
/* ASN.1 template for RSA PSS parameters. */
6123
static const ASNItem rsaPssParamsASN[] = {
6124
/*  SEQ         */  { 0, ASN_SEQUENCE, 1, 1, 0 },
6125
/*  HASH        */      { 1, ASN_TAG_RSA_PSS_HASH, 1, 1, 1 },
6126
/*  HASHSEQ     */          { 2, ASN_SEQUENCE, 1, 1, 0 },
6127
/*  HASHOID     */              { 3, ASN_OBJECT_ID, 0, 0, 0 },
6128
/*  HASHNULL    */              { 3, ASN_TAG_NULL, 0, 0, 1 },
6129
/*  MGF         */      { 1, ASN_TAG_RSA_PSS_MGF, 1, 1, 1 },
6130
/*  MGFSEQ      */          { 2, ASN_SEQUENCE, 1, 1, 0 },
6131
/*  MGFOID      */              { 3, ASN_OBJECT_ID, 0, 0, 0 },
6132
/*  MGFPARAM    */              { 3, ASN_SEQUENCE, 1, 1, 0 },
6133
/*  MGFHOID     */                  { 4, ASN_OBJECT_ID, 0, 0, 0 },
6134
/*  MGFHNULL    */                  { 4, ASN_TAG_NULL, 0, 0, 1 },
6135
/*  SALTLEN     */      { 1, ASN_TAG_RSA_PSS_SALTLEN, 1, 1, 1 },
6136
/*  SALTLENINT  */          { 2, ASN_INTEGER, 0, 0, 0 },
6137
/*  TRAILER     */      { 1, ASN_TAG_RSA_PSS_TRAILER, 1, 1, 1 },
6138
/*  TRAILERINT  */          { 2, ASN_INTEGER, 0, 0, 0 },
6139
};
6140
enum {
6141
    RSAPSSPARAMSASN_IDX_SEQ = 0,
6142
    RSAPSSPARAMSASN_IDX_HASH,
6143
    RSAPSSPARAMSASN_IDX_HASHSEQ,
6144
    RSAPSSPARAMSASN_IDX_HASHOID,
6145
    RSAPSSPARAMSASN_IDX_HASHNULL,
6146
    RSAPSSPARAMSASN_IDX_MGF,
6147
    RSAPSSPARAMSASN_IDX_MGFSEQ,
6148
    RSAPSSPARAMSASN_IDX_MGFOID,
6149
    RSAPSSPARAMSASN_IDX_MGFPARAM,
6150
    RSAPSSPARAMSASN_IDX_MGFHOID,
6151
    RSAPSSPARAMSASN_IDX_MGFHNULL,
6152
    RSAPSSPARAMSASN_IDX_SALTLEN,
6153
    RSAPSSPARAMSASN_IDX_SALTLENINT,
6154
    RSAPSSPARAMSASN_IDX_TRAILER,
6155
    RSAPSSPARAMSASN_IDX_TRAILERINT,
6156
};
6157
6158
/* Number of items in ASN.1 template for an algorithm identifier. */
6159
0
#define rsaPssParamsASN_Length (sizeof(rsaPssParamsASN) / sizeof(ASNItem))
6160
#else
6161
/* ASN tag for hashAlgorigthm. */
6162
#define ASN_TAG_RSA_PSS_HASH        (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)
6163
/* ASN tag for maskGenAlgorithm. */
6164
#define ASN_TAG_RSA_PSS_MGF         (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)
6165
/* ASN tag for saltLength. */
6166
#define ASN_TAG_RSA_PSS_SALTLEN     (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)
6167
/* ASN tag for trailerField. */
6168
#define ASN_TAG_RSA_PSS_TRAILER     (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 3)
6169
#endif
6170
6171
/* Decode the RSA PSS parameters.
6172
 *
6173
 * @param  [in]   params   Buffer holding BER encoded RSA PSS parameters.
6174
 * @param  [in]   sz       Size of data in buffer in bytes.
6175
 * @param  [out]  hash     Hash algorithm to use on message.
6176
 * @param  [out]  mgf      MGF algorithm to use with PSS padding.
6177
 * @param  [out]  saltLen  Length of salt in PSS padding.
6178
 * @return  BAD_FUNC_ARG when the params is NULL.
6179
 * @return  ASN_PARSE_E when the decoding fails.
6180
 * @return  0 on success.
6181
 */
6182
static int DecodeRsaPssParams(const byte* params, word32 sz,
6183
    enum wc_HashType* hash, int* mgf, int* saltLen)
6184
0
{
6185
#ifndef WOLFSSL_ASN_TEMPLATE
6186
    int ret = 0;
6187
    word32 idx = 0;
6188
    int len = 0;
6189
    word32 oid = 0;
6190
    byte tag;
6191
    int length;
6192
6193
    if (params == NULL) {
6194
        ret = BAD_FUNC_ARG;
6195
    }
6196
    if ((ret == 0) && (GetSequence_ex(params, &idx, &len, sz, 1) < 0)) {
6197
        ret = ASN_PARSE_E;
6198
    }
6199
    if (ret == 0) {
6200
        if ((idx < sz) && (params[idx] == ASN_TAG_RSA_PSS_HASH)) {
6201
            /* Hash algorithm to use on message. */
6202
            if (GetHeader(params, &tag, &idx, &length, sz, 0) < 0) {
6203
                ret = ASN_PARSE_E;
6204
            }
6205
            if (ret == 0) {
6206
                if (GetAlgoId(params, &idx, &oid, oidHashType, sz) < 0) {
6207
                    ret = ASN_PARSE_E;
6208
                }
6209
            }
6210
            if (ret == 0) {
6211
                ret = RsaPssHashOidToType(oid, hash);
6212
            }
6213
        }
6214
        else {
6215
            /* Default hash algorithm. */
6216
            *hash = WC_HASH_TYPE_SHA;
6217
        }
6218
    }
6219
    if (ret == 0) {
6220
        if ((idx < sz) && (params[idx] == ASN_TAG_RSA_PSS_MGF)) {
6221
            /* MGF and hash algorithm to use with padding. */
6222
            if (GetHeader(params, &tag, &idx, &length, sz, 0) < 0) {
6223
                ret = ASN_PARSE_E;
6224
            }
6225
            if (ret == 0) {
6226
                if (GetAlgoId(params, &idx, &oid, oidIgnoreType, sz) < 0) {
6227
                    ret = ASN_PARSE_E;
6228
                }
6229
            }
6230
            if ((ret == 0) && (oid != MGF1_OID)) {
6231
                ret = ASN_PARSE_E;
6232
            }
6233
            if (ret == 0) {
6234
                ret = GetAlgoId(params, &idx, &oid, oidHashType, sz);
6235
                if (ret == 0) {
6236
                    ret = RsaPssHashOidToMgf1(oid, mgf);
6237
                }
6238
            }
6239
        }
6240
        else {
6241
            /* Default MGF/Hash algorithm. */
6242
            *mgf = WC_MGF1SHA1;
6243
        }
6244
    }
6245
    if (ret == 0) {
6246
        if ((idx < sz) && (params[idx] == ASN_TAG_RSA_PSS_SALTLEN)) {
6247
            /* Salt length to use with padding. */
6248
            if (GetHeader(params, &tag, &idx, &length, sz, 0) < 0) {
6249
                ret = ASN_PARSE_E;
6250
            }
6251
            if (ret == 0) {
6252
                ret = GetInteger16Bit(params, &idx, sz);
6253
                if (ret >= 0) {
6254
                    *saltLen = ret;
6255
                    ret = 0;
6256
                }
6257
            }
6258
        }
6259
        else {
6260
            /* Default salt length. */
6261
            *saltLen = 20;
6262
        }
6263
    }
6264
    if (ret == 0) {
6265
        if ((idx < sz) && (params[idx] == ASN_TAG_RSA_PSS_TRAILER)) {
6266
            /* Unused - trialerField. */
6267
            if (GetHeader(params, &tag, &idx, &length, sz, 0) < 0) {
6268
                ret = ASN_PARSE_E;
6269
            }
6270
            if (ret == 0) {
6271
                ret = GetInteger16Bit(params, &idx, sz);
6272
                if (ret > 0) {
6273
                    ret = 0;
6274
                }
6275
            }
6276
        }
6277
    }
6278
    if ((ret == 0) && (idx != sz)) {
6279
        ret = ASN_PARSE_E;
6280
    }
6281
6282
    return ret;
6283
#else
6284
0
    DECL_ASNGETDATA(dataASN, rsaPssParamsASN_Length);
6285
0
    int ret = 0;
6286
0
    word16 sLen = 20;
6287
6288
0
    if (params == NULL) {
6289
0
        ret = BAD_FUNC_ARG;
6290
0
    }
6291
6292
0
    CALLOC_ASNGETDATA(dataASN, rsaPssParamsASN_Length, ret, NULL);
6293
0
    if (ret == 0) {
6294
0
        word32 inOutIdx = 0;
6295
        /* Default values. */
6296
0
        *hash = WC_HASH_TYPE_SHA;
6297
0
        *mgf = WC_MGF1SHA1;
6298
6299
        /* Set OID type expected. */
6300
0
        GetASN_OID(&dataASN[RSAPSSPARAMSASN_IDX_HASHOID], oidHashType);
6301
0
        GetASN_OID(&dataASN[RSAPSSPARAMSASN_IDX_MGFHOID], oidHashType);
6302
        /* Place the salt length into 16-bit var sLen. */
6303
0
        GetASN_Int16Bit(&dataASN[RSAPSSPARAMSASN_IDX_SALTLENINT], &sLen);
6304
        /* Decode the algorithm identifier. */
6305
0
        ret = GetASN_Items(rsaPssParamsASN, dataASN, rsaPssParamsASN_Length, 1,
6306
0
            params, &inOutIdx, sz);
6307
0
    }
6308
0
    if ((ret == 0) && (dataASN[RSAPSSPARAMSASN_IDX_HASHOID].tag != 0)) {
6309
0
        word32 oid = dataASN[RSAPSSPARAMSASN_IDX_HASHOID].data.oid.sum;
6310
0
        ret = RsaPssHashOidToType(oid, hash);
6311
0
    }
6312
0
    if ((ret == 0) && (dataASN[RSAPSSPARAMSASN_IDX_MGFHOID].tag != 0)) {
6313
0
        word32 oid = dataASN[RSAPSSPARAMSASN_IDX_MGFHOID].data.oid.sum;
6314
0
        ret = RsaPssHashOidToMgf1(oid, mgf);
6315
0
    }
6316
0
    if (ret == 0) {
6317
0
        *saltLen = sLen;
6318
0
    }
6319
6320
0
    FREE_ASNGETDATA(dataASN, NULL);
6321
0
    return ret;
6322
0
#endif /* WOLFSSL_ASN_TEMPLATE */
6323
0
}
6324
#endif /* WC_RSA_PSS */
6325
6326
#ifndef HAVE_USER_RSA
6327
#if defined(WOLFSSL_ASN_TEMPLATE) || (!defined(NO_CERTS) && \
6328
    (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || \
6329
     defined(WOLFSSL_KCAPI_RSA) || defined(WOLFSSL_SE050)))
6330
/* Byte offset of numbers in RSA key. */
6331
size_t rsaIntOffset[] = {
6332
    OFFSETOF(RsaKey, n),
6333
    OFFSETOF(RsaKey, e),
6334
#ifndef WOLFSSL_RSA_PUBLIC_ONLY
6335
    OFFSETOF(RsaKey, d),
6336
    OFFSETOF(RsaKey, p),
6337
    OFFSETOF(RsaKey, q),
6338
#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)
6339
    OFFSETOF(RsaKey, dP),
6340
    OFFSETOF(RsaKey, dQ),
6341
    OFFSETOF(RsaKey, u)
6342
#endif
6343
#endif
6344
};
6345
6346
/* Get a number from the RSA key based on an index.
6347
 *
6348
 * Order: { n, e, d, p, q, dP, dQ, u }
6349
 *
6350
 * Caller must ensure index is not invalid!
6351
 *
6352
 * @param [in] key  RSA key object.
6353
 * @param [in] idx  Index of number.
6354
 * @return  A pointer to an mp_int when valid index.
6355
 * @return  NULL when invalid index.
6356
 */
6357
static mp_int* GetRsaInt(RsaKey* key, int idx)
6358
0
{
6359
    /* Cast key to byte array to and use offset to get to mp_int field. */
6360
0
    return (mp_int*)(((byte*)key) + rsaIntOffset[idx]);
6361
0
}
6362
#endif
6363
6364
#ifdef WOLFSSL_ASN_TEMPLATE
6365
/* ASN.1 template for an RSA private key.
6366
 * PKCS #1: RFC 8017, A.1.2 - RSAPrivateKey
6367
 */
6368
static const ASNItem rsaKeyASN[] = {
6369
/*  SEQ */    { 0, ASN_SEQUENCE, 1, 1, 0 },
6370
/*  VER */        { 1, ASN_INTEGER, 0, 0, 0 },
6371
                /* Integers need to be in this specific order
6372
                 * as asn code depends on this. */
6373
/*  N   */        { 1, ASN_INTEGER, 0, 0, 0 },
6374
/*  E   */        { 1, ASN_INTEGER, 0, 0, 0 },
6375
#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) || defined(WOLFSSL_KEY_GEN)
6376
/*  D   */        { 1, ASN_INTEGER, 0, 0, 0 },
6377
/*  P   */        { 1, ASN_INTEGER, 0, 0, 0 },
6378
/*  Q   */        { 1, ASN_INTEGER, 0, 0, 0 },
6379
/*  DP  */        { 1, ASN_INTEGER, 0, 0, 0 },
6380
/*  DQ  */        { 1, ASN_INTEGER, 0, 0, 0 },
6381
/*  U   */        { 1, ASN_INTEGER, 0, 0, 0 },
6382
                /* otherPrimeInfos  OtherPrimeInfos OPTIONAL
6383
                 * v2 - multiprime */
6384
#endif
6385
};
6386
enum {
6387
    RSAKEYASN_IDX_SEQ = 0,
6388
    RSAKEYASN_IDX_VER,
6389
    /* Integers need to be in this specific order
6390
     * as asn code depends on this. */
6391
    RSAKEYASN_IDX_N,
6392
    RSAKEYASN_IDX_E,
6393
#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) || defined(WOLFSSL_KEY_GEN)
6394
    RSAKEYASN_IDX_D,
6395
    RSAKEYASN_IDX_P,
6396
    RSAKEYASN_IDX_Q,
6397
    RSAKEYASN_IDX_DP,
6398
    RSAKEYASN_IDX_DQ,
6399
    RSAKEYASN_IDX_U,
6400
#endif
6401
    WOLF_ENUM_DUMMY_LAST_ELEMENT(RSAKEYASN_IDX)
6402
};
6403
6404
/* Number of items in ASN.1 template for an RSA private key. */
6405
0
#define rsaKeyASN_Length (sizeof(rsaKeyASN) / sizeof(ASNItem))
6406
#endif
6407
6408
/* Decode RSA private key.
6409
 *
6410
 * PKCS #1: RFC 8017, A.1.2 - RSAPrivateKey
6411
 *
6412
 * Compiling with WOLFSSL_RSA_PUBLIC_ONLY will result in only the public fields
6413
 * being extracted.
6414
 *
6415
 * @param [in]      input     Buffer holding BER encoded data.
6416
 * @param [in, out] inOutIdx  On in, start of RSA private key.
6417
 *                            On out, start of ASN.1 item after RSA private key.
6418
 * @param [in, out] key       RSA key object. May be NULL.
6419
 * @param [out]     keySz     Size of key in bytes. May be NULL.
6420
 * @param [in]      inSz      Number of bytes in buffer.
6421
 * @return  0 on success.
6422
 * @return  BAD_FUNC_ARG when input or inOutIdx is NULL.
6423
 * @return  BAD_FUNC_ARG when key and keySz are NULL.
6424
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
6425
 *          is invalid.
6426
 * @return  BUFFER_E when data in buffer is too small.
6427
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
6428
 *          non-zero length.
6429
 * @return  MP_INIT_E when the unable to initialize an mp_int.
6430
 * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
6431
 */
6432
static int _RsaPrivateKeyDecode(const byte* input, word32* inOutIdx,
6433
    RsaKey* key, int* keySz, word32 inSz)
6434
0
{
6435
#ifndef WOLFSSL_ASN_TEMPLATE
6436
    int version, length;
6437
    word32 algId = 0;
6438
6439
    if (inOutIdx == NULL || input == NULL || (key == NULL && keySz == NULL)) {
6440
        return BAD_FUNC_ARG;
6441
    }
6442
6443
    /* if has pkcs8 header skip it */
6444
    if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) {
6445
        /* ignore error, did not have pkcs8 header */
6446
    }
6447
6448
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
6449
        return ASN_PARSE_E;
6450
6451
    if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
6452
        return ASN_PARSE_E;
6453
6454
    if (key == NULL) {
6455
        int i;
6456
6457
        /* Modulus */
6458
        if (GetASNInt(input, inOutIdx, keySz, inSz) < 0) {
6459
            return ASN_PARSE_E;
6460
        }
6461
        *inOutIdx += (word32)*keySz;
6462
        for (i = 1; i < RSA_INTS; i++) {
6463
            if (SkipInt(input, inOutIdx, inSz) < 0) {
6464
                return ASN_RSA_KEY_E;
6465
            }
6466
        }
6467
    }
6468
    else {
6469
        key->type = RSA_PRIVATE;
6470
6471
    #ifdef WOLFSSL_CHECK_MEM_ZERO
6472
        mp_memzero_add("Decode RSA key d", &key->d);
6473
        mp_memzero_add("Decode RSA key p", &key->p);
6474
        mp_memzero_add("Decode RSA key q", &key->q);
6475
    #if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || \
6476
        !defined(RSA_LOW_MEM)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
6477
        mp_memzero_add("Decode RSA key dP", &key->dP);
6478
        mp_memzero_add("Decode RSA key dQ", &key->dQ);
6479
        mp_memzero_add("Decode RSA key u", &key->u);
6480
    #endif
6481
    #endif
6482
6483
        if (GetInt(&key->n,  input, inOutIdx, inSz) < 0 ||
6484
            GetInt(&key->e,  input, inOutIdx, inSz) < 0 ||
6485
    #ifndef WOLFSSL_RSA_PUBLIC_ONLY
6486
            GetInt(&key->d,  input, inOutIdx, inSz) < 0 ||
6487
            GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
6488
            GetInt(&key->q,  input, inOutIdx, inSz) < 0
6489
    #else
6490
            SkipInt(input, inOutIdx, inSz) < 0 ||
6491
            SkipInt(input, inOutIdx, inSz) < 0 ||
6492
            SkipInt(input, inOutIdx, inSz) < 0
6493
    #endif
6494
           ) {
6495
                return ASN_RSA_KEY_E;
6496
           }
6497
    #if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)) \
6498
        && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
6499
        if (GetInt(&key->dP, input, inOutIdx, inSz) < 0 ||
6500
            GetInt(&key->dQ, input, inOutIdx, inSz) < 0 ||
6501
            GetInt(&key->u,  input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;
6502
    #else
6503
        if (SkipInt(input, inOutIdx, inSz) < 0 ||
6504
            SkipInt(input, inOutIdx, inSz) < 0 ||
6505
            SkipInt(input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;
6506
    #endif
6507
6508
    #if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_CRYPTOCELL)
6509
        if (wc_InitRsaHw(key) != 0) {
6510
            return BAD_STATE_E;
6511
        }
6512
    #endif
6513
    }
6514
6515
    return 0;
6516
#else
6517
0
    DECL_ASNGETDATA(dataASN, rsaKeyASN_Length);
6518
0
    int        ret = 0;
6519
0
    byte       version = (byte)-1;
6520
0
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
6521
0
    word32 algId = 0;
6522
0
#endif
6523
0
    void*      heap = NULL;
6524
6525
    /* Check validity of parameters. */
6526
0
    if ((inOutIdx == NULL) || (input == NULL) || ((key == NULL) &&
6527
0
            (keySz == NULL))) {
6528
0
        ret = BAD_FUNC_ARG;
6529
0
    }
6530
6531
0
    if ((ret == 0) && (key != NULL)) {
6532
0
        heap = key->heap;
6533
0
    }
6534
6535
0
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
6536
0
    if (ret == 0) {
6537
        /* if has pkcs8 header skip it */
6538
0
        if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) {
6539
            /* ignore error, did not have pkcs8 header */
6540
0
        }
6541
0
    }
6542
0
#endif
6543
6544
0
    (void)heap;
6545
0
    CALLOC_ASNGETDATA(dataASN, rsaKeyASN_Length, ret, heap);
6546
6547
0
    if (ret == 0) {
6548
        /* Register variable to hold version field. */
6549
0
        GetASN_Int8Bit(&dataASN[RSAKEYASN_IDX_VER], &version);
6550
        /* Setup data to store INTEGER data in mp_int's in RSA object. */
6551
    #if defined(WOLFSSL_RSA_PUBLIC_ONLY)
6552
        #define RSA_ASN_INTS        RSA_PUB_INTS
6553
        /* Not extracting all data from BER encoding. */
6554
        #define RSA_ASN_COMPLETE    0
6555
    #else
6556
0
        #define RSA_ASN_INTS        RSA_INTS
6557
        /* Extracting all data from BER encoding. */
6558
0
        #define RSA_ASN_COMPLETE    1
6559
0
    #endif
6560
0
        if (key != NULL) {
6561
0
            int i;
6562
            /* Extract all public fields. */
6563
0
            for (i = 0; i < RSA_ASN_INTS; i++) {
6564
0
                GetASN_MP(&dataASN[(byte)RSAKEYASN_IDX_N + i],
6565
0
                    GetRsaInt(key, i));
6566
0
            }
6567
0
        }
6568
        /* Parse BER encoding for RSA private key. */
6569
0
        ret = GetASN_Items(rsaKeyASN, dataASN, rsaKeyASN_Length,
6570
0
            RSA_ASN_COMPLETE, input, inOutIdx, inSz);
6571
0
    }
6572
    /* Check version: 0 - two prime, 1 - multi-prime
6573
     * Multi-prime has optional sequence after coefficient for extra primes.
6574
     * If extra primes, parsing will fail as not all the buffer was used.
6575
     */
6576
0
    if ((ret == 0) && (version > PKCS1v1)) {
6577
0
        ret = ASN_PARSE_E;
6578
0
    }
6579
0
    if ((ret == 0) && (key != NULL)) {
6580
0
    #if !defined(WOLFSSL_RSA_PUBLIC_ONLY)
6581
        /* RSA key object has all private key values. */
6582
0
        key->type = RSA_PRIVATE;
6583
    #else
6584
        /* RSA key object has all public key values. */
6585
        key->type = RSA_PUBLIC;
6586
    #endif
6587
6588
    #ifdef WOLFSSL_XILINX_CRYPT
6589
        if (wc_InitRsaHw(key) != 0)
6590
            ret = BAD_STATE_E;
6591
    #endif
6592
0
    }
6593
0
    else if (ret == 0) {
6594
        /* Not filling in key but do want key size. */
6595
0
        *keySz = (int)dataASN[(byte)RSAKEYASN_IDX_N].length;
6596
        /* Check whether first byte of data is 0x00 and drop it. */
6597
0
        if (input[(int)dataASN[RSAKEYASN_IDX_E].offset - *keySz] == 0) {
6598
0
            (*keySz)--;
6599
0
        }
6600
0
    }
6601
6602
0
    FREE_ASNGETDATA(dataASN, heap);
6603
0
    return ret;
6604
0
#endif /* WOLFSSL_ASN_TEMPLATE */
6605
0
}
6606
6607
/* Decode RSA private key.
6608
 *
6609
 * PKCS #1: RFC 8017, A.1.2 - RSAPrivateKey
6610
 *
6611
 * Compiling with WOLFSSL_RSA_PUBLIC_ONLY will result in only the public fields
6612
 * being extracted.
6613
 *
6614
 * @param [in]      input     Buffer holding BER encoded data.
6615
 * @param [in, out] inOutIdx  On in, start of RSA private key.
6616
 *                            On out, start of ASN.1 item after RSA private key.
6617
 * @param [in, out] key       RSA key object.
6618
 * @param [in]      inSz      Number of bytes in buffer.
6619
 * @return  0 on success.
6620
 * @return  BAD_FUNC_ARG when input, inOutIdx or key is NULL.
6621
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
6622
 *          is invalid.
6623
 * @return  BUFFER_E when data in buffer is too small.
6624
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
6625
 *          non-zero length.
6626
 * @return  MP_INIT_E when the unable to initialize an mp_int.
6627
 * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
6628
 */
6629
int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
6630
    word32 inSz)
6631
0
{
6632
0
    if (key == NULL) {
6633
0
        return BAD_FUNC_ARG;
6634
0
    }
6635
0
    return _RsaPrivateKeyDecode(input, inOutIdx, key, NULL, inSz);
6636
0
}
6637
6638
/* Valdidate RSA private key ASN.1 encoding.
6639
 *
6640
 * PKCS #1: RFC 8017, A.1.2 - RSAPrivateKey
6641
 *
6642
 * Compiling with WOLFSSL_RSA_PUBLIC_ONLY will result in only the public fields
6643
 * being extracted.
6644
 *
6645
 * @param [in]      input     Buffer holding BER encoded data.
6646
 * @param [in, out] inOutIdx  On in, start of RSA private key.
6647
 *                            On out, start of ASN.1 item after RSA private key.
6648
 * @param [in]      inSz      Number of bytes in buffer.
6649
 * @return  0 on success.
6650
 * @return  BAD_FUNC_ARG when input, inOutIdx or keySz is NULL.
6651
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
6652
 *          is invalid.
6653
 * @return  BUFFER_E when data in buffer is too small.
6654
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
6655
 *          non-zero length.
6656
 * @return  MP_INIT_E when the unable to initialize an mp_int.
6657
 * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
6658
 */
6659
int wc_RsaPrivateKeyValidate(const byte* input, word32* inOutIdx, int* keySz,
6660
     word32 inSz)
6661
0
{
6662
0
    return _RsaPrivateKeyDecode(input, inOutIdx, NULL, keySz, inSz);
6663
0
}
6664
6665
#endif /* HAVE_USER_RSA */
6666
#endif /* NO_RSA */
6667
6668
#ifdef WOLFSSL_ASN_TEMPLATE
6669
/* ASN.1 template for a PKCS #8 key.
6670
 * Ignoring optional attributes and public key.
6671
 * PKCS #8: RFC 5958, 2 - PrivateKeyInfo
6672
 */
6673
static const ASNItem pkcs8KeyASN[] = {
6674
/*  SEQ                 */    { 0, ASN_SEQUENCE, 1, 1, 0 },
6675
/*  VER                 */        { 1, ASN_INTEGER, 0, 0, 0 },
6676
/*  PKEY_ALGO_SEQ       */        { 1, ASN_SEQUENCE, 1, 1, 0 },
6677
/*  PKEY_ALGO_OID_KEY   */            { 2, ASN_OBJECT_ID, 0, 0, 0 },
6678
/*  PKEY_ALGO_OID_CURVE */            { 2, ASN_OBJECT_ID, 0, 0, 1 },
6679
/*  PKEY_ALGO_NULL      */            { 2, ASN_TAG_NULL, 0, 0, 1 },
6680
#ifdef WC_RSA_PSS
6681
/*  PKEY_ALGO_PARAM_SEQ */            { 2, ASN_SEQUENCE, 1, 0, 1 },
6682
#endif
6683
/*  PKEY_DATA           */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
6684
                /* attributes            [0] Attributes OPTIONAL */
6685
                /* [[2: publicKey        [1] PublicKey OPTIONAL ]] */
6686
};
6687
enum {
6688
    PKCS8KEYASN_IDX_SEQ = 0,
6689
    PKCS8KEYASN_IDX_VER,
6690
    PKCS8KEYASN_IDX_PKEY_ALGO_SEQ,
6691
    PKCS8KEYASN_IDX_PKEY_ALGO_OID_KEY,
6692
    PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE,
6693
    PKCS8KEYASN_IDX_PKEY_ALGO_NULL,
6694
#ifdef WC_RSA_PSS
6695
    PKCS8KEYASN_IDX_PKEY_ALGO_PARAM_SEQ,
6696
#endif
6697
    PKCS8KEYASN_IDX_PKEY_DATA,
6698
    WOLF_ENUM_DUMMY_LAST_ELEMENT(PKCS8KEYASN_IDX)
6699
};
6700
6701
/* Number of items in ASN.1 template for a PKCS #8 key. */
6702
0
#define pkcs8KeyASN_Length (sizeof(pkcs8KeyASN) / sizeof(ASNItem))
6703
#endif
6704
6705
/* Remove PKCS #8 header around an RSA, ECDSA, Ed25519, or Ed448.
6706
 *
6707
 * @param [in]       input     Buffer holding BER data.
6708
 * @param [in, out]  inOutIdx  On in, start of PKCS #8 encoding.
6709
 *                             On out, start of encoded key.
6710
 * @param [in]       sz        Size of data in buffer.
6711
 * @param [out]      algId     Key's algorithm id from PKCS #8 header.
6712
 * @return  Length of key data on success.
6713
 * @return  BAD_FUNC_ARG when input or inOutIdx is NULL.
6714
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
6715
 *          is invalid.
6716
 * @return  BUFFER_E when data in buffer is too small.
6717
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
6718
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
6719
 *          non-zero length.
6720
 */
6721
int ToTraditionalInline_ex(const byte* input, word32* inOutIdx, word32 sz,
6722
                           word32* algId)
6723
0
{
6724
#ifndef WOLFSSL_ASN_TEMPLATE
6725
    word32 idx;
6726
    int    version, length;
6727
    int    ret;
6728
    byte   tag;
6729
6730
    if (input == NULL || inOutIdx == NULL)
6731
        return BAD_FUNC_ARG;
6732
6733
    idx = *inOutIdx;
6734
6735
    if (GetSequence(input, &idx, &length, sz) < 0)
6736
        return ASN_PARSE_E;
6737
6738
    if (GetMyVersion(input, &idx, &version, sz) < 0)
6739
        return ASN_PARSE_E;
6740
6741
    if (GetAlgoId(input, &idx, algId, oidKeyType, sz) < 0)
6742
        return ASN_PARSE_E;
6743
6744
    if (GetASNTag(input, &idx, &tag, sz) < 0)
6745
        return ASN_PARSE_E;
6746
    idx = idx - 1; /* reset idx after finding tag */
6747
6748
#if defined(WC_RSA_PSS) && !defined(NO_RSA)
6749
    if (*algId == RSAPSSk && tag == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
6750
        word32 seqIdx = idx;
6751
        int seqLen;
6752
        /* Not set when -1. */
6753
        enum wc_HashType hash = WC_HASH_TYPE_NONE;
6754
        int mgf = -1;
6755
        int saltLen = 0;
6756
6757
        if (GetSequence(input, &idx, &seqLen, sz) < 0) {
6758
            return ASN_PARSE_E;
6759
        }
6760
        /* Get the private key parameters. */
6761
        ret = DecodeRsaPssParams(input + seqIdx,
6762
            seqLen + idx - seqIdx, &hash, &mgf, &saltLen);
6763
        if (ret != 0) {
6764
            return ASN_PARSE_E;
6765
        }
6766
        /* TODO: store parameters so that usage can be checked. */
6767
        idx += seqLen;
6768
    }
6769
#endif /* WC_RSA_PSS && !NO_RSA */
6770
6771
    if (tag == ASN_OBJECT_ID) {
6772
        if (SkipObjectId(input, &idx, sz) < 0)
6773
            return ASN_PARSE_E;
6774
    }
6775
6776
    ret = GetOctetString(input, &idx, &length, sz);
6777
    if (ret < 0) {
6778
        if (ret == BUFFER_E)
6779
            return ASN_PARSE_E;
6780
        /* Some private keys don't expect an octet string */
6781
        WOLFSSL_MSG("Couldn't find Octet string");
6782
    }
6783
6784
    *inOutIdx = idx;
6785
6786
    return length;
6787
#else
6788
0
    DECL_ASNGETDATA(dataASN, pkcs8KeyASN_Length);
6789
0
    int ret = 0;
6790
0
    word32 oid = 9;
6791
0
    byte version;
6792
0
    word32 idx;
6793
6794
    /* Check validity of parameters. */
6795
0
    if (input == NULL || inOutIdx == NULL) {
6796
0
        return BAD_FUNC_ARG;
6797
0
    }
6798
6799
0
    idx = *inOutIdx;
6800
6801
0
    CALLOC_ASNGETDATA(dataASN, pkcs8KeyASN_Length, ret, NULL);
6802
6803
0
    if (ret == 0) {
6804
        /* Get version, check key type and curve type. */
6805
0
        GetASN_Int8Bit(&dataASN[PKCS8KEYASN_IDX_VER], &version);
6806
0
        GetASN_OID(&dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_KEY], oidKeyType);
6807
0
        GetASN_OID(&dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE], oidCurveType);
6808
        /* Parse data. */
6809
0
        ret = GetASN_Items(pkcs8KeyASN, dataASN, pkcs8KeyASN_Length, 1, input,
6810
0
                           &idx, sz);
6811
0
    }
6812
6813
0
    if (ret == 0) {
6814
        /* Key type OID. */
6815
0
        oid = dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_KEY].data.oid.sum;
6816
6817
        /* Version 1 includes an optional public key.
6818
         * If public key is included then the parsing will fail as it did not
6819
         * use all the data.
6820
         */
6821
0
        if (version > PKCS8v1) {
6822
0
            ret = ASN_PARSE_E;
6823
0
        }
6824
0
    }
6825
0
    if (ret == 0) {
6826
0
        switch (oid) {
6827
0
    #ifndef NO_RSA
6828
0
            case RSAk:
6829
                /* Must have NULL item but not OBJECT_ID item. */
6830
0
                if ((dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag == 0) ||
6831
0
                    (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE].tag != 0)) {
6832
0
                    ret = ASN_PARSE_E;
6833
0
                }
6834
0
                break;
6835
0
        #ifdef WC_RSA_PSS
6836
0
            case RSAPSSk:
6837
                /* Must not have NULL item. */
6838
0
                if (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag != 0) {
6839
0
                    ret = ASN_PARSE_E;
6840
0
                }
6841
0
                if (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_PARAM_SEQ].tag != 0) {
6842
0
                    enum wc_HashType hash;
6843
0
                    int mgf;
6844
0
                    int saltLen;
6845
0
                    const byte* params = GetASNItem_Addr(
6846
0
                        dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_PARAM_SEQ], input);
6847
0
                    word32 paramsSz = GetASNItem_Length(
6848
0
                        dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_PARAM_SEQ], input);
6849
6850
                    /* Validate the private key parameters. */
6851
0
                    ret = DecodeRsaPssParams(params, paramsSz, &hash, &mgf,
6852
0
                        &saltLen);
6853
0
                    if (ret != 0) {
6854
0
                        return ASN_PARSE_E;
6855
0
                    }
6856
                    /* TODO: store parameters so that usage can be checked. */
6857
0
                }
6858
0
                break;
6859
0
        #endif
6860
0
    #endif
6861
0
        #ifdef HAVE_ECC
6862
0
            case ECDSAk:
6863
                /* Must not have NULL item. */
6864
0
                if (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag != 0) {
6865
0
                    ret = ASN_PARSE_E;
6866
0
                }
6867
0
                break;
6868
0
        #endif
6869
0
        #ifdef HAVE_ED25519
6870
0
            case ED25519k:
6871
                /* Neither NULL item nor OBJECT_ID item allowed. */
6872
0
                if ((dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag != 0) ||
6873
0
                    (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE].tag != 0)) {
6874
0
                    ret = ASN_PARSE_E;
6875
0
                }
6876
0
                break;
6877
0
        #endif
6878
0
        #ifdef HAVE_CURVE25519
6879
0
            case X25519k:
6880
                /* Neither NULL item nor OBJECT_ID item allowed. */
6881
0
                if ((dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag != 0) ||
6882
0
                    (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE].tag != 0)) {
6883
0
                    ret = ASN_PARSE_E;
6884
0
                }
6885
0
                break;
6886
0
        #endif
6887
0
        #ifdef HAVE_ED448
6888
0
            case ED448k:
6889
                /* Neither NULL item nor OBJECT_ID item allowed. */
6890
0
                if ((dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag != 0) ||
6891
0
                    (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE].tag != 0)) {
6892
0
                    ret = ASN_PARSE_E;
6893
0
                }
6894
0
                break;
6895
0
        #endif
6896
0
        #ifdef HAVE_CURVE448
6897
0
            case X448k:
6898
                /* Neither NULL item nor OBJECT_ID item allowed. */
6899
0
                if ((dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag != 0) ||
6900
0
                    (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE].tag != 0)) {
6901
0
                    ret = ASN_PARSE_E;
6902
0
                }
6903
0
                break;
6904
0
        #endif
6905
            /* DSAk not supported. */
6906
            /* Falcon, Dilithium and Sphincs not supported. */
6907
            /* Ignore OID lookup failures. */
6908
0
            default:
6909
0
                break;
6910
0
        }
6911
0
    }
6912
0
    if (ret == 0) {
6913
        /* Return algorithm id of internal key. */
6914
0
        *algId = oid;
6915
        /* Return index to start of internal key. */
6916
0
        *inOutIdx = GetASNItem_DataIdx(dataASN[PKCS8KEYASN_IDX_PKEY_DATA], input);
6917
        /* Return value is length of internal key. */
6918
0
        ret = (int)dataASN[PKCS8KEYASN_IDX_PKEY_DATA].data.ref.length;
6919
0
    }
6920
6921
0
    FREE_ASNGETDATA(dataASN, NULL);
6922
0
    return ret;
6923
0
#endif
6924
0
}
6925
6926
/* TODO: test case  */
6927
int ToTraditionalInline(const byte* input, word32* inOutIdx, word32 sz)
6928
0
{
6929
0
    word32 oid;
6930
6931
0
    return ToTraditionalInline_ex(input, inOutIdx, sz, &oid);
6932
0
}
6933
6934
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
6935
6936
/* Remove PKCS8 header, move beginning of traditional to beginning of input */
6937
int ToTraditional_ex(byte* input, word32 sz, word32* algId)
6938
0
{
6939
0
    word32 inOutIdx = 0;
6940
0
    int    length;
6941
6942
0
    if (input == NULL)
6943
0
        return BAD_FUNC_ARG;
6944
6945
0
    length = ToTraditionalInline_ex(input, &inOutIdx, sz, algId);
6946
0
    if (length < 0)
6947
0
        return length;
6948
6949
0
    if ((word32)length + inOutIdx > sz)
6950
0
        return BUFFER_E;
6951
6952
0
    XMEMMOVE(input, input + inOutIdx, (size_t)length);
6953
6954
0
    return length;
6955
0
}
6956
6957
int ToTraditional(byte* input, word32 sz)
6958
0
{
6959
0
    word32 oid;
6960
6961
0
    return ToTraditional_ex(input, sz, &oid);
6962
0
}
6963
6964
#endif /* HAVE_PKCS8 || HAVE_PKCS12 */
6965
6966
#if defined(HAVE_PKCS8)
6967
6968
int wc_GetPkcs8TraditionalOffset(byte* input, word32* inOutIdx, word32 sz)
6969
0
{
6970
0
    int length;
6971
0
    word32 algId;
6972
6973
0
    if (input == NULL || inOutIdx == NULL || (*inOutIdx > sz))
6974
0
        return BAD_FUNC_ARG;
6975
6976
0
    length = ToTraditionalInline_ex(input, inOutIdx, sz, &algId);
6977
6978
0
    return length;
6979
0
}
6980
6981
int wc_CreatePKCS8Key(byte* out, word32* outSz, byte* key, word32 keySz,
6982
        int algoID, const byte* curveOID, word32 oidSz)
6983
0
{
6984
#ifndef WOLFSSL_ASN_TEMPLATE
6985
    word32 keyIdx = 0;
6986
    word32 tmpSz  = 0;
6987
    word32 sz;
6988
    word32 tmpAlgId = 0;
6989
6990
    /* If out is NULL then return the max size needed
6991
     * + 2 for ASN_OBJECT_ID and ASN_OCTET_STRING tags */
6992
    if (out == NULL && outSz != NULL) {
6993
        *outSz = keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ
6994
                 + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 2;
6995
6996
        if (curveOID != NULL)
6997
            *outSz += oidSz + MAX_LENGTH_SZ + 1;
6998
6999
        WOLFSSL_MSG("Checking size of PKCS8");
7000
7001
        return LENGTH_ONLY_E;
7002
    }
7003
7004
    WOLFSSL_ENTER("wc_CreatePKCS8Key");
7005
7006
    if (key == NULL || out == NULL || outSz == NULL) {
7007
        return BAD_FUNC_ARG;
7008
    }
7009
7010
    /* check the buffer has enough room for largest possible size */
7011
    if (curveOID != NULL) {
7012
        if (*outSz < (keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ
7013
               + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 3 + oidSz + MAX_LENGTH_SZ))
7014
            return BUFFER_E;
7015
    }
7016
    else {
7017
        oidSz = 0; /* with no curveOID oid size must be 0 */
7018
        if (*outSz < (keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ
7019
                  + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 2))
7020
            return BUFFER_E;
7021
    }
7022
7023
    /* sanity check: make sure the key doesn't already have a PKCS 8 header */
7024
    if (ToTraditionalInline_ex(key, &keyIdx, keySz, &tmpAlgId) >= 0) {
7025
        (void)tmpAlgId;
7026
        return ASN_PARSE_E;
7027
    }
7028
7029
    /* PrivateKeyInfo ::= SEQUENCE */
7030
    keyIdx = MAX_SEQ_SZ; /* save room for sequence */
7031
7032
    /*  version Version
7033
     *  no header information just INTEGER */
7034
    sz = (word32)SetMyVersion(PKCS8v0, out + keyIdx, 0);
7035
    tmpSz += sz; keyIdx += sz;
7036
    /*  privateKeyAlgorithm PrivateKeyAlgorithmIdentifier */
7037
    sz = 0; /* set sz to 0 and get privateKey oid buffer size needed */
7038
    if (curveOID != NULL && oidSz > 0) {
7039
        byte buf[MAX_LENGTH_SZ];
7040
        sz = SetLength(oidSz, buf);
7041
        sz += 1; /* plus one for ASN object id */
7042
    }
7043
    sz = (word32)SetAlgoID(algoID, out + keyIdx, oidKeyType, (int)(oidSz + sz));
7044
    tmpSz += sz; keyIdx += sz;
7045
7046
    /*  privateKey          PrivateKey *
7047
     * pkcs8 ecc uses slightly different format. Places curve oid in
7048
     * buffer */
7049
    if (curveOID != NULL && oidSz > 0) {
7050
        sz = (word32)SetObjectId((int)oidSz, out + keyIdx);
7051
        keyIdx += sz; tmpSz += sz;
7052
        XMEMCPY(out + keyIdx, curveOID, oidSz);
7053
        keyIdx += oidSz; tmpSz += oidSz;
7054
    }
7055
7056
    sz = (word32)SetOctetString(keySz, out + keyIdx);
7057
    keyIdx += sz; tmpSz += sz;
7058
    XMEMCPY(out + keyIdx, key, keySz);
7059
    tmpSz += keySz;
7060
7061
    /*  attributes          optional
7062
     * No attributes currently added */
7063
7064
    /* rewind and add sequence */
7065
    sz = SetSequence(tmpSz, out);
7066
    XMEMMOVE(out + sz, out + MAX_SEQ_SZ, tmpSz);
7067
7068
    *outSz = tmpSz + sz;
7069
    return (int)(tmpSz + sz);
7070
#else
7071
0
    DECL_ASNSETDATA(dataASN, pkcs8KeyASN_Length);
7072
0
    int sz;
7073
0
    int ret = 0;
7074
0
    word32 keyIdx = 0;
7075
0
    word32 tmpAlgId = 0;
7076
7077
0
    WOLFSSL_ENTER("wc_CreatePKCS8Key");
7078
7079
    /* Check validity of parameters. */
7080
0
    if (out == NULL && outSz != NULL) {
7081
0
    }
7082
0
    else if (key == NULL || out == NULL || outSz == NULL) {
7083
0
        ret = BAD_FUNC_ARG;
7084
0
    }
7085
7086
    /* Sanity check: make sure key doesn't have PKCS #8 header. */
7087
0
    if (ToTraditionalInline_ex(key, &keyIdx, keySz, &tmpAlgId) >= 0) {
7088
0
        (void)tmpAlgId;
7089
0
        ret = ASN_PARSE_E;
7090
0
    }
7091
7092
0
    CALLOC_ASNSETDATA(dataASN, pkcs8KeyASN_Length, ret, NULL);
7093
7094
0
    if (ret == 0) {
7095
        /* Only support default PKCS #8 format - v0. */
7096
0
        SetASN_Int8Bit(&dataASN[PKCS8KEYASN_IDX_VER], PKCS8v0);
7097
        /* Set key OID that corresponds to key data. */
7098
0
        SetASN_OID(&dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_KEY], (word32)algoID,
7099
0
            oidKeyType);
7100
0
        if (curveOID != NULL && oidSz > 0) {
7101
            /* ECC key and curveOID set to write. */
7102
0
            SetASN_Buffer(&dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE],
7103
0
                curveOID, oidSz);
7104
0
        }
7105
0
        else {
7106
            /* EC curve OID to encode. */
7107
0
            dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE].noOut = 1;
7108
0
        }
7109
        /* Only RSA keys have NULL tagged item after OID. */
7110
0
        dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].noOut = (algoID != RSAk);
7111
0
    #ifdef WC_RSA_PSS
7112
0
        dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_PARAM_SEQ].noOut = 1;
7113
0
    #endif
7114
        /* Set key data to encode. */
7115
0
        SetASN_Buffer(&dataASN[PKCS8KEYASN_IDX_PKEY_DATA], key, keySz);
7116
7117
        /* Get the size of the DER encoding. */
7118
0
        ret = SizeASN_Items(pkcs8KeyASN, dataASN, pkcs8KeyASN_Length, &sz);
7119
0
    }
7120
0
    if (ret == 0) {
7121
        /* Always return the calculated size. */
7122
0
        *outSz = (word32)sz;
7123
0
    }
7124
    /* Check for buffer to encoded into. */
7125
0
    if ((ret == 0) && (out == NULL)) {
7126
0
        WOLFSSL_MSG("Checking size of PKCS8");
7127
0
        ret = LENGTH_ONLY_E;
7128
0
    }
7129
0
    if (ret == 0) {
7130
        /*  Encode PKCS #8 key into buffer. */
7131
0
        SetASN_Items(pkcs8KeyASN, dataASN, pkcs8KeyASN_Length, out);
7132
0
        ret = sz;
7133
0
    }
7134
7135
0
    FREE_ASNSETDATA(dataASN, NULL);
7136
0
    return ret;
7137
0
#endif /* WOLFSSL_ASN_TEMPLATE */
7138
0
}
7139
7140
#endif /* HAVE_PKCS8 */
7141
7142
#if defined(HAVE_PKCS12) || !defined(NO_CHECK_PRIVATE_KEY)
7143
/* check that the private key is a pair for the public key
7144
 * return 1 (true) on match
7145
 * return 0 or negative value on failure/error
7146
 *
7147
 * privKey   : buffer holding DER format private key
7148
 * privKeySz : size of private key buffer
7149
 * pubKey    : buffer holding DER format public key
7150
 * pubKeySz  : size of public key buffer
7151
 * ks        : type of key */
7152
int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz,
7153
                       const byte* pubKey, word32 pubKeySz, enum Key_Sum ks)
7154
0
{
7155
0
    int ret;
7156
0
    (void)privKeySz;
7157
0
    (void)pubKeySz;
7158
0
    (void)ks;
7159
7160
0
    if (privKey == NULL || pubKey == NULL) {
7161
0
        return BAD_FUNC_ARG;
7162
0
    }
7163
7164
0
    #if !defined(NO_RSA) && !defined(NO_ASN_CRYPT)
7165
    /* test if RSA key */
7166
0
    if (ks == RSAk
7167
0
    #ifdef WC_RSA_PSS
7168
0
        || ks == RSAPSSk
7169
0
    #endif
7170
0
        ) {
7171
0
    #ifdef WOLFSSL_SMALL_STACK
7172
0
        RsaKey* a;
7173
0
        RsaKey* b = NULL;
7174
    #else
7175
        RsaKey a[1], b[1];
7176
    #endif
7177
0
        word32 keyIdx = 0;
7178
7179
0
    #ifdef WOLFSSL_SMALL_STACK
7180
0
        a = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
7181
0
        if (a == NULL)
7182
0
            return MEMORY_E;
7183
0
        b = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
7184
0
        if (b == NULL) {
7185
0
            XFREE(a, NULL, DYNAMIC_TYPE_RSA);
7186
0
            return MEMORY_E;
7187
0
        }
7188
0
    #endif
7189
7190
0
        if ((ret = wc_InitRsaKey(a, NULL)) < 0) {
7191
0
    #ifdef WOLFSSL_SMALL_STACK
7192
0
            XFREE(b, NULL, DYNAMIC_TYPE_RSA);
7193
0
            XFREE(a, NULL, DYNAMIC_TYPE_RSA);
7194
0
    #endif
7195
0
            return ret;
7196
0
        }
7197
0
        if ((ret = wc_InitRsaKey(b, NULL)) < 0) {
7198
0
            wc_FreeRsaKey(a);
7199
0
    #ifdef WOLFSSL_SMALL_STACK
7200
0
            XFREE(b, NULL, DYNAMIC_TYPE_RSA);
7201
0
            XFREE(a, NULL, DYNAMIC_TYPE_RSA);
7202
0
    #endif
7203
0
            return ret;
7204
0
        }
7205
0
        if ((ret = wc_RsaPrivateKeyDecode(privKey, &keyIdx, a, privKeySz)) == 0) {
7206
0
            WOLFSSL_MSG("Checking RSA key pair");
7207
0
            keyIdx = 0; /* reset to 0 for parsing public key */
7208
7209
0
            if ((ret = wc_RsaPublicKeyDecode(pubKey, &keyIdx, b,
7210
0
                    pubKeySz)) == 0) {
7211
                /* limit for user RSA crypto because of RsaKey
7212
                 * dereference. */
7213
            #if defined(HAVE_USER_RSA)
7214
                WOLFSSL_MSG("Cannot verify RSA pair with user RSA");
7215
                ret = 1; /* return first RSA cert as match */
7216
            #else
7217
                /* both keys extracted successfully now check n and e
7218
                 * values are the same. This is dereferencing RsaKey */
7219
0
                if (mp_cmp(&(a->n), &(b->n)) != MP_EQ ||
7220
0
                    mp_cmp(&(a->e), &(b->e)) != MP_EQ) {
7221
0
                    ret = MP_CMP_E;
7222
0
                    WOLFSSL_ERROR_VERBOSE(ret);
7223
0
                }
7224
0
                else
7225
0
                    ret = 1;
7226
0
            #endif
7227
0
            }
7228
0
            else {
7229
0
                WOLFSSL_ERROR_VERBOSE(ret);
7230
0
            }
7231
0
        }
7232
0
        wc_FreeRsaKey(b);
7233
0
        wc_FreeRsaKey(a);
7234
0
    #ifdef WOLFSSL_SMALL_STACK
7235
0
        XFREE(b, NULL, DYNAMIC_TYPE_RSA);
7236
0
        XFREE(a, NULL, DYNAMIC_TYPE_RSA);
7237
0
    #endif
7238
0
    }
7239
0
    else
7240
0
    #endif /* !NO_RSA && !NO_ASN_CRYPT */
7241
7242
0
    #if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT)
7243
0
    if (ks == ECDSAk) {
7244
0
    #ifdef WOLFSSL_SMALL_STACK
7245
0
        ecc_key* key_pair;
7246
0
        byte*    privDer;
7247
    #else
7248
        ecc_key  key_pair[1];
7249
        byte     privDer[MAX_ECC_BYTES];
7250
    #endif
7251
0
        word32   privSz = MAX_ECC_BYTES;
7252
0
        word32   keyIdx = 0;
7253
7254
0
    #ifdef WOLFSSL_SMALL_STACK
7255
0
        key_pair = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
7256
0
        if (key_pair == NULL)
7257
0
            return MEMORY_E;
7258
0
        privDer = (byte*)XMALLOC(MAX_ECC_BYTES, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7259
0
        if (privDer == NULL) {
7260
0
            XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
7261
0
            return MEMORY_E;
7262
0
        }
7263
0
    #endif
7264
7265
0
        if ((ret = wc_ecc_init(key_pair)) < 0) {
7266
0
    #ifdef WOLFSSL_SMALL_STACK
7267
0
            XFREE(privDer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7268
0
            XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
7269
0
    #endif
7270
0
            return ret;
7271
0
        }
7272
7273
0
        if ((ret = wc_EccPrivateKeyDecode(privKey, &keyIdx, key_pair,
7274
0
                privKeySz)) == 0) {
7275
0
            WOLFSSL_MSG("Checking ECC key pair");
7276
7277
0
            if ((ret = wc_ecc_export_private_only(key_pair, privDer, &privSz))
7278
0
                                                                         == 0) {
7279
            #ifdef WOLFSSL_CHECK_MEM_ZERO
7280
                wc_MemZero_Add("wc_CheckPrivateKey privDer", privDer, privSz);
7281
            #endif
7282
0
                wc_ecc_free(key_pair);
7283
0
                ret = wc_ecc_init(key_pair);
7284
0
                if (ret == 0) {
7285
0
                    ret = wc_ecc_import_private_key(privDer,
7286
0
                                            privSz, pubKey,
7287
0
                                            pubKeySz, key_pair);
7288
0
                }
7289
7290
                /* public and private extracted successfully now check if is
7291
                 * a pair and also do sanity checks on key. wc_ecc_check_key
7292
                 * checks that private * base generator equals pubkey */
7293
0
                if (ret == 0) {
7294
0
                    if ((ret = wc_ecc_check_key(key_pair)) == 0) {
7295
0
                        ret = 1;
7296
0
                    }
7297
0
                    else {
7298
0
                        WOLFSSL_ERROR_VERBOSE(ret);
7299
0
                    }
7300
0
                }
7301
0
                ForceZero(privDer, privSz);
7302
0
            }
7303
0
        }
7304
0
        else {
7305
0
            WOLFSSL_ERROR_VERBOSE(ret);
7306
0
        }
7307
0
        wc_ecc_free(key_pair);
7308
0
    #ifdef WOLFSSL_SMALL_STACK
7309
0
        XFREE(privDer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7310
0
        XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
7311
    #elif defined(WOLFSSL_CHECK_MEM_ZERO)
7312
        wc_MemZero_Check(privDer, MAX_ECC_BYTES);
7313
    #endif
7314
0
    }
7315
0
    else
7316
0
    #endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT && !NO_ASN_CRYPT */
7317
7318
0
    #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) && !defined(NO_ASN_CRYPT)
7319
0
    if (ks == ED25519k) {
7320
0
    #ifdef WOLFSSL_SMALL_STACK
7321
0
        ed25519_key* key_pair;
7322
    #else
7323
        ed25519_key  key_pair[1];
7324
    #endif
7325
0
        word32       keyIdx = 0;
7326
7327
0
    #ifdef WOLFSSL_SMALL_STACK
7328
0
        key_pair = (ed25519_key*)XMALLOC(sizeof(ed25519_key), NULL,
7329
0
                                                          DYNAMIC_TYPE_ED25519);
7330
0
        if (key_pair == NULL)
7331
0
            return MEMORY_E;
7332
0
    #endif
7333
7334
0
        if ((ret = wc_ed25519_init(key_pair)) < 0) {
7335
0
    #ifdef WOLFSSL_SMALL_STACK
7336
0
            XFREE(key_pair, NULL, DYNAMIC_TYPE_ED25519);
7337
0
    #endif
7338
0
            return ret;
7339
0
        }
7340
0
        if ((ret = wc_Ed25519PrivateKeyDecode(privKey, &keyIdx, key_pair,
7341
0
                privKeySz)) == 0) {
7342
0
            WOLFSSL_MSG("Checking ED25519 key pair");
7343
0
            keyIdx = 0;
7344
0
            if ((ret = wc_ed25519_import_public(pubKey, pubKeySz,
7345
0
                    key_pair)) == 0) {
7346
                /* public and private extracted successfully no check if is
7347
                 * a pair and also do sanity checks on key. wc_ecc_check_key
7348
                 * checks that private * base generator equals pubkey */
7349
0
                if ((ret = wc_ed25519_check_key(key_pair)) == 0) {
7350
0
                    ret = 1;
7351
0
                }
7352
0
                else {
7353
0
                    WOLFSSL_ERROR_VERBOSE(ret);
7354
0
                }
7355
0
            }
7356
0
        }
7357
0
        else {
7358
0
            WOLFSSL_ERROR_VERBOSE(ret);
7359
0
        }
7360
0
        wc_ed25519_free(key_pair);
7361
0
    #ifdef WOLFSSL_SMALL_STACK
7362
0
        XFREE(key_pair, NULL, DYNAMIC_TYPE_ED25519);
7363
0
    #endif
7364
0
    }
7365
0
    else
7366
0
    #endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT && !NO_ASN_CRYPT */
7367
7368
0
    #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) && !defined(NO_ASN_CRYPT)
7369
0
    if (ks == ED448k) {
7370
0
    #ifdef WOLFSSL_SMALL_STACK
7371
0
        ed448_key* key_pair = NULL;
7372
    #else
7373
        ed448_key  key_pair[1];
7374
    #endif
7375
0
        word32     keyIdx = 0;
7376
7377
0
    #ifdef WOLFSSL_SMALL_STACK
7378
0
        key_pair = (ed448_key*)XMALLOC(sizeof(ed448_key), NULL,
7379
0
                                                            DYNAMIC_TYPE_ED448);
7380
0
        if (key_pair == NULL)
7381
0
            return MEMORY_E;
7382
0
    #endif
7383
7384
0
        if ((ret = wc_ed448_init(key_pair)) < 0) {
7385
0
    #ifdef WOLFSSL_SMALL_STACK
7386
0
            XFREE(key_pair, NULL, DYNAMIC_TYPE_ED448);
7387
0
    #endif
7388
0
            return ret;
7389
0
        }
7390
0
        if ((ret = wc_Ed448PrivateKeyDecode(privKey, &keyIdx, key_pair,
7391
0
                privKeySz)) == 0) {
7392
0
            WOLFSSL_MSG("Checking ED448 key pair");
7393
0
            keyIdx = 0;
7394
0
            if ((ret = wc_ed448_import_public(pubKey, pubKeySz,
7395
0
                    key_pair)) == 0) {
7396
                /* public and private extracted successfully no check if is
7397
                 * a pair and also do sanity checks on key. wc_ecc_check_key
7398
                 * checks that private * base generator equals pubkey */
7399
0
                if ((ret = wc_ed448_check_key(key_pair)) == 0) {
7400
0
                    ret = 1;
7401
0
                }
7402
0
                else {
7403
0
                    WOLFSSL_ERROR_VERBOSE(ret);
7404
0
                }
7405
0
            }
7406
0
        }
7407
0
        else {
7408
0
            WOLFSSL_ERROR_VERBOSE(ret);
7409
0
        }
7410
0
        wc_ed448_free(key_pair);
7411
0
    #ifdef WOLFSSL_SMALL_STACK
7412
0
        XFREE(key_pair, NULL, DYNAMIC_TYPE_ED448);
7413
0
    #endif
7414
0
    }
7415
0
    else
7416
0
    #endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT && !NO_ASN_CRYPT */
7417
    #if defined(HAVE_PQC)
7418
    #if defined(HAVE_FALCON)
7419
    if ((ks == FALCON_LEVEL1k) || (ks == FALCON_LEVEL5k)) {
7420
    #ifdef WOLFSSL_SMALL_STACK
7421
        falcon_key* key_pair = NULL;
7422
    #else
7423
        falcon_key  key_pair[1];
7424
    #endif
7425
        word32     keyIdx = 0;
7426
7427
    #ifdef WOLFSSL_SMALL_STACK
7428
        key_pair = (falcon_key*)XMALLOC(sizeof(falcon_key), NULL,
7429
                                        DYNAMIC_TYPE_FALCON);
7430
        if (key_pair == NULL)
7431
            return MEMORY_E;
7432
    #endif
7433
        ret = wc_falcon_init(key_pair);
7434
        if (ret  < 0) {
7435
    #ifdef WOLFSSL_SMALL_STACK
7436
            XFREE(key_pair, NULL, DYNAMIC_TYPE_FALCON);
7437
    #endif
7438
            return ret;
7439
        }
7440
7441
        if (ks == FALCON_LEVEL1k) {
7442
            ret = wc_falcon_set_level(key_pair, 1);
7443
        }
7444
        else if (ks == FALCON_LEVEL5k) {
7445
            ret = wc_falcon_set_level(key_pair, 5);
7446
        }
7447
7448
        if (ret  < 0) {
7449
    #ifdef WOLFSSL_SMALL_STACK
7450
            XFREE(key_pair, NULL, DYNAMIC_TYPE_FALCON);
7451
    #endif
7452
            return ret;
7453
        }
7454
        if ((ret = wc_Falcon_PrivateKeyDecode(privKey, &keyIdx, key_pair,
7455
                                             privKeySz)) == 0) {
7456
            WOLFSSL_MSG("Checking Falcon key pair");
7457
            keyIdx = 0;
7458
            if ((ret = wc_falcon_import_public(pubKey, pubKeySz,
7459
                                               key_pair)) == 0) {
7460
                /* Public and private extracted successfully. Sanity check. */
7461
                if ((ret = wc_falcon_check_key(key_pair)) == 0) {
7462
                    ret = 1;
7463
                }
7464
                else {
7465
                    WOLFSSL_ERROR_VERBOSE(ret);
7466
                }
7467
            }
7468
        }
7469
        else {
7470
            WOLFSSL_ERROR_VERBOSE(ret);
7471
        }
7472
        wc_falcon_free(key_pair);
7473
    #ifdef WOLFSSL_SMALL_STACK
7474
        XFREE(key_pair, NULL, DYNAMIC_TYPE_FALCON);
7475
    #endif
7476
    }
7477
    else
7478
    #endif /* HAVE_FALCON */
7479
    #if defined(HAVE_DILITHIUM)
7480
    if ((ks == DILITHIUM_LEVEL2k) ||
7481
        (ks == DILITHIUM_LEVEL3k) ||
7482
        (ks == DILITHIUM_LEVEL5k)) {
7483
    #ifdef WOLFSSL_SMALL_STACK
7484
        dilithium_key* key_pair = NULL;
7485
    #else
7486
        dilithium_key  key_pair[1];
7487
    #endif
7488
        word32     keyIdx = 0;
7489
7490
    #ifdef WOLFSSL_SMALL_STACK
7491
        key_pair = (dilithium_key*)XMALLOC(sizeof(dilithium_key), NULL,
7492
                                        DYNAMIC_TYPE_DILITHIUM);
7493
        if (key_pair == NULL)
7494
            return MEMORY_E;
7495
    #endif
7496
        ret = wc_dilithium_init(key_pair);
7497
        if (ret  < 0) {
7498
    #ifdef WOLFSSL_SMALL_STACK
7499
            XFREE(key_pair, NULL, DYNAMIC_TYPE_DILITHIUM);
7500
    #endif
7501
            return ret;
7502
        }
7503
7504
        if (ks == DILITHIUM_LEVEL2k) {
7505
            ret = wc_dilithium_set_level(key_pair, 2);
7506
        }
7507
        else if (ks == DILITHIUM_LEVEL3k) {
7508
            ret = wc_dilithium_set_level(key_pair, 3);
7509
        }
7510
        else if (ks == DILITHIUM_LEVEL5k) {
7511
            ret = wc_dilithium_set_level(key_pair, 5);
7512
        }
7513
7514
        if (ret  < 0) {
7515
    #ifdef WOLFSSL_SMALL_STACK
7516
            XFREE(key_pair, NULL, DYNAMIC_TYPE_DILITHIUM);
7517
    #endif
7518
            return ret;
7519
        }
7520
        if ((ret = wc_Dilithium_PrivateKeyDecode(privKey, &keyIdx, key_pair,
7521
                                             privKeySz)) == 0) {
7522
            WOLFSSL_MSG("Checking Dilithium key pair");
7523
            keyIdx = 0;
7524
            if ((ret = wc_dilithium_import_public(pubKey, pubKeySz,
7525
                                               key_pair)) == 0) {
7526
                /* Public and private extracted successfully. Sanity check. */
7527
                if ((ret = wc_dilithium_check_key(key_pair)) == 0)
7528
                    ret = 1;
7529
            }
7530
        }
7531
        wc_dilithium_free(key_pair);
7532
    #ifdef WOLFSSL_SMALL_STACK
7533
        XFREE(key_pair, NULL, DYNAMIC_TYPE_DILITHIUM);
7534
    #endif
7535
    }
7536
    else
7537
    #endif /* HAVE_DILITHIUM */
7538
    #if defined(HAVE_SPHINCS)
7539
    if ((ks == SPHINCS_FAST_LEVEL1k) ||
7540
        (ks == SPHINCS_FAST_LEVEL3k) ||
7541
        (ks == SPHINCS_FAST_LEVEL5k) ||
7542
        (ks == SPHINCS_SMALL_LEVEL1k) ||
7543
        (ks == SPHINCS_SMALL_LEVEL3k) ||
7544
        (ks == SPHINCS_SMALL_LEVEL5k)) {
7545
    #ifdef WOLFSSL_SMALL_STACK
7546
        sphincs_key* key_pair = NULL;
7547
    #else
7548
        sphincs_key  key_pair[1];
7549
    #endif
7550
        word32     keyIdx = 0;
7551
7552
    #ifdef WOLFSSL_SMALL_STACK
7553
        key_pair = (sphincs_key*)XMALLOC(sizeof(sphincs_key), NULL,
7554
                                        DYNAMIC_TYPE_SPHINCS);
7555
        if (key_pair == NULL)
7556
            return MEMORY_E;
7557
    #endif
7558
        ret = wc_sphincs_init(key_pair);
7559
        if (ret  < 0) {
7560
    #ifdef WOLFSSL_SMALL_STACK
7561
            XFREE(key_pair, NULL, DYNAMIC_TYPE_SPHINCS);
7562
    #endif
7563
            return ret;
7564
        }
7565
7566
        if (ks == SPHINCS_FAST_LEVEL1k) {
7567
            ret = wc_sphincs_set_level_and_optim(key_pair, 1, FAST_VARIANT);
7568
        }
7569
        else if (ks == SPHINCS_FAST_LEVEL3k) {
7570
            ret = wc_sphincs_set_level_and_optim(key_pair, 3, FAST_VARIANT);
7571
        }
7572
        else if (ks == SPHINCS_FAST_LEVEL5k) {
7573
            ret = wc_sphincs_set_level_and_optim(key_pair, 5, FAST_VARIANT);
7574
        }
7575
        else if (ks == SPHINCS_SMALL_LEVEL1k) {
7576
            ret = wc_sphincs_set_level_and_optim(key_pair, 1, SMALL_VARIANT);
7577
        }
7578
        else if (ks == SPHINCS_SMALL_LEVEL3k) {
7579
            ret = wc_sphincs_set_level_and_optim(key_pair, 3, SMALL_VARIANT);
7580
        }
7581
        else if (ks == SPHINCS_SMALL_LEVEL5k) {
7582
            ret = wc_sphincs_set_level_and_optim(key_pair, 5, SMALL_VARIANT);
7583
        }
7584
7585
        if (ret  < 0) {
7586
    #ifdef WOLFSSL_SMALL_STACK
7587
            XFREE(key_pair, NULL, DYNAMIC_TYPE_SPHINCS);
7588
    #endif
7589
            return ret;
7590
        }
7591
        if ((ret = wc_Sphincs_PrivateKeyDecode(privKey, &keyIdx, key_pair,
7592
                                             privKeySz)) == 0) {
7593
            WOLFSSL_MSG("Checking Sphincs key pair");
7594
            keyIdx = 0;
7595
            if ((ret = wc_sphincs_import_public(pubKey, pubKeySz,
7596
                                               key_pair)) == 0) {
7597
                /* Public and private extracted successfully. Sanity check. */
7598
                if ((ret = wc_sphincs_check_key(key_pair)) == 0)
7599
                    ret = 1;
7600
            }
7601
        }
7602
        wc_sphincs_free(key_pair);
7603
    #ifdef WOLFSSL_SMALL_STACK
7604
        XFREE(key_pair, NULL, DYNAMIC_TYPE_SPHINCS);
7605
    #endif
7606
    }
7607
    else
7608
    #endif /* HAVE_SPHINCS */
7609
    #endif /* HAVE_PQC */
7610
0
    {
7611
0
        ret = 0;
7612
0
    }
7613
0
    (void)ks;
7614
7615
0
    return ret;
7616
0
}
7617
7618
/* check that the private key is a pair for the public key in certificate
7619
 * return 1 (true) on match
7620
 * return 0 or negative value on failure/error
7621
 *
7622
 * key   : buffer holding DER format key
7623
 * keySz : size of key buffer
7624
 * der   : a initialized and parsed DecodedCert holding a certificate */
7625
int wc_CheckPrivateKeyCert(const byte* key, word32 keySz, DecodedCert* der)
7626
0
{
7627
0
    if (key == NULL || der == NULL) {
7628
0
        return BAD_FUNC_ARG;
7629
0
    }
7630
7631
0
    return wc_CheckPrivateKey(key, keySz, der->publicKey,
7632
0
            der->pubKeySize, (enum Key_Sum) der->keyOID);
7633
0
}
7634
7635
#endif /* HAVE_PKCS12 || !NO_CHECK_PRIVATE_KEY */
7636
7637
#ifndef NO_PWDBASED
7638
7639
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
7640
/* Check the PBE algorithm is supported and return wolfSSL id, version and block
7641
 * size of encryption algorithm.
7642
 *
7643
 * When PBES2, version is PKCS5v2, CheckAlgoV2() must be called to get id and
7644
 * blockSz based on encryption algorithm.
7645
 *
7646
 * @param [in]  first    First byte of OID to use in check.
7647
 * @param [in]  second   Second byte of OID to use in check.
7648
 * @param [out] id       wolfSSL id for PBE algorithm.
7649
 * @param [out] version  Version of PBE OID:
7650
 *                       PKCS12v1 (PBE), PKCS5 (PBES1), PKCS5v2 (PBES2).
7651
 * @param [out] blockSz  Block size of encryption algorithm.
7652
 * @return  0 on success.
7653
 * @return  ALGO_ID_E when OID not supported.
7654
 * @return  ASN_INPUT_E when first byte is invalid.
7655
 */
7656
static int CheckAlgo(int first, int second, int* id, int* version, int* blockSz)
7657
0
{
7658
0
    int ret = 0;
7659
7660
0
    (void)id;
7661
0
    (void)blockSz;
7662
7663
0
    *version = -1;
7664
7665
    /* pkcs-12 1 = pkcs-12PbeIds */
7666
0
    if (first == 1) {
7667
        /* PKCS #12: Appendix C */
7668
0
        switch (second) {
7669
0
#if !defined(NO_SHA)
7670
0
    #ifndef NO_RC4
7671
0
        case PBE_SHA1_RC4_128:
7672
0
            *id = PBE_SHA1_RC4_128;
7673
0
            *version = PKCS12v1;
7674
0
            if (blockSz != NULL) {
7675
0
                *blockSz = 1;
7676
0
            }
7677
0
            break;
7678
0
    #endif
7679
0
    #ifndef NO_DES3
7680
0
        case PBE_SHA1_DES3:
7681
0
            *id = PBE_SHA1_DES3;
7682
0
            *version = PKCS12v1;
7683
0
            if (blockSz != NULL) {
7684
0
                *blockSz = DES_BLOCK_SIZE;
7685
0
            }
7686
0
            break;
7687
0
    #endif
7688
    #ifdef WC_RC2
7689
        case PBE_SHA1_40RC2_CBC:
7690
            *id = PBE_SHA1_40RC2_CBC;
7691
            *version = PKCS12v1;
7692
            if (blockSz != NULL) {
7693
                *blockSz = RC2_BLOCK_SIZE;
7694
            }
7695
            break;
7696
    #endif
7697
0
#endif /* !NO_SHA */
7698
0
        default:
7699
0
            ret = ALGO_ID_E;
7700
0
            break;
7701
0
        }
7702
0
    }
7703
0
    else if (first != PKCS5) {
7704
        /* Bad OID. */
7705
0
        ret = ASN_INPUT_E;
7706
0
    }
7707
    /* PKCS #5 PBES2: Appendix A.4
7708
     * pkcs-5 13 = id-PBES2 */
7709
0
    else if (second == PBES2) {
7710
0
        *version = PKCS5v2;
7711
        /* Id and block size come from CheckAlgoV2() */
7712
0
    }
7713
0
    else  {
7714
        /* PKCS #5 PBES1: Appendix A.3 */
7715
        /* see RFC 2898 for ids */
7716
0
        switch (second) {
7717
0
    #ifndef NO_DES3
7718
0
        #ifndef NO_MD5
7719
0
        case PBES1_MD5_DES:
7720
0
            *id = PBE_MD5_DES;
7721
0
            *version = PKCS5;
7722
0
            if (blockSz != NULL) {
7723
0
                *blockSz = DES_BLOCK_SIZE;
7724
0
            }
7725
0
            break;
7726
0
        #endif
7727
0
        #ifndef NO_SHA
7728
0
        case PBES1_SHA1_DES:
7729
0
            *id = PBE_SHA1_DES;
7730
0
            *version = PKCS5;
7731
0
            if (blockSz != NULL) {
7732
0
                *blockSz = DES_BLOCK_SIZE;
7733
0
            }
7734
0
            break;
7735
0
        #endif
7736
0
    #endif /* !NO_DES3 */
7737
0
        default:
7738
0
            ret = ALGO_ID_E;
7739
0
            break;
7740
0
        }
7741
0
    }
7742
7743
    /* Return error code. */
7744
0
    return ret;
7745
0
}
7746
7747
#endif /* HAVE_PKCS8 || HAVE_PKCS12 */
7748
7749
#ifdef HAVE_PKCS8
7750
7751
/* Check the encryption algorithm with PBES2 is supported and return block size
7752
 * and wolfSSL id for the PBE.
7753
 *
7754
 * @param [in]  oid      Encryption algorithm OID id.
7755
 * @param [out] id       wolfSSL id for PBE algorithm.
7756
 * @param [out] version  Version of PBE OID:
7757
 *                       PKCS12v1 (PBE), PKCS5 (PBES1), PKCS5v2 (PBES2).
7758
 * @return  0 on success.
7759
 * @return  ALGO_ID_E when encryption algorithm is not supported with PBES2.
7760
 */
7761
static int CheckAlgoV2(int oid, int* id, int* blockSz)
7762
0
{
7763
0
    int ret = 0;
7764
7765
0
    (void)id;
7766
0
    (void)blockSz;
7767
7768
0
    switch (oid) {
7769
0
#if !defined(NO_DES3) && !defined(NO_SHA)
7770
0
    case DESb:
7771
0
        *id = PBE_SHA1_DES;
7772
0
        if (blockSz != NULL) {
7773
0
            *blockSz = DES_BLOCK_SIZE;
7774
0
        }
7775
0
        break;
7776
0
    case DES3b:
7777
0
        *id = PBE_SHA1_DES3;
7778
0
        if (blockSz != NULL) {
7779
0
            *blockSz = DES_BLOCK_SIZE;
7780
0
        }
7781
0
        break;
7782
0
#endif
7783
0
#ifdef WOLFSSL_AES_256
7784
0
    case AES256CBCb:
7785
0
        *id = PBE_AES256_CBC;
7786
0
        if (blockSz != NULL) {
7787
0
            *blockSz = AES_BLOCK_SIZE;
7788
0
        }
7789
0
        break;
7790
0
#endif
7791
0
#ifdef WOLFSSL_AES_128
7792
0
    case AES128CBCb:
7793
0
        *id = PBE_AES128_CBC;
7794
0
        if (blockSz != NULL) {
7795
0
            *blockSz = AES_BLOCK_SIZE;
7796
0
        }
7797
0
        break;
7798
0
#endif
7799
0
    default:
7800
0
        WOLFSSL_MSG("No PKCS v2 algo found");
7801
0
        ret = ALGO_ID_E;
7802
0
        break;
7803
0
    }
7804
7805
    /* Return error code. */
7806
0
    return ret;
7807
0
}
7808
7809
#endif /* HAVE_PKCS8 */
7810
7811
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
7812
7813
int wc_GetKeyOID(byte* key, word32 keySz, const byte** curveOID, word32* oidSz,
7814
        int* algoID, void* heap)
7815
0
{
7816
0
    word32 tmpIdx = 0;
7817
7818
0
    if (key == NULL || algoID == NULL)
7819
0
        return BAD_FUNC_ARG;
7820
7821
0
    *algoID = 0;
7822
7823
0
    #if !defined(NO_RSA) && !defined(NO_ASN_CRYPT)
7824
0
    {
7825
0
        RsaKey *rsa = (RsaKey *)XMALLOC(sizeof *rsa, heap, DYNAMIC_TYPE_TMP_BUFFER);
7826
0
        if (rsa == NULL)
7827
0
            return MEMORY_E;
7828
7829
0
        wc_InitRsaKey(rsa, heap);
7830
0
        if (wc_RsaPrivateKeyDecode(key, &tmpIdx, rsa, keySz) == 0) {
7831
0
            *algoID = RSAk;
7832
0
        }
7833
0
        else {
7834
0
            WOLFSSL_MSG("Not RSA DER key");
7835
0
        }
7836
0
        wc_FreeRsaKey(rsa);
7837
0
        XFREE(rsa, heap, DYNAMIC_TYPE_TMP_BUFFER);
7838
0
    }
7839
0
    #endif /* !NO_RSA && !NO_ASN_CRYPT */
7840
0
    #if defined(HAVE_ECC) && !defined(NO_ASN_CRYPT)
7841
0
    if (*algoID == 0) {
7842
0
        ecc_key *ecc = (ecc_key *)XMALLOC(sizeof *ecc, heap, DYNAMIC_TYPE_TMP_BUFFER);
7843
0
        if (ecc == NULL)
7844
0
            return MEMORY_E;
7845
7846
0
        tmpIdx = 0;
7847
0
        wc_ecc_init_ex(ecc, heap, INVALID_DEVID);
7848
0
        if (wc_EccPrivateKeyDecode(key, &tmpIdx, ecc, keySz) == 0) {
7849
0
            *algoID = ECDSAk;
7850
7851
            /* now find oid */
7852
0
            if (wc_ecc_get_oid(ecc->dp->oidSum, curveOID, oidSz) < 0) {
7853
0
                WOLFSSL_MSG("Error getting ECC curve OID");
7854
0
                wc_ecc_free(ecc);
7855
0
                XFREE(ecc, heap, DYNAMIC_TYPE_TMP_BUFFER);
7856
0
                return BAD_FUNC_ARG;
7857
0
            }
7858
0
        }
7859
0
        else {
7860
0
            WOLFSSL_MSG("Not ECC DER key either");
7861
0
        }
7862
0
        wc_ecc_free(ecc);
7863
0
        XFREE(ecc, heap, DYNAMIC_TYPE_TMP_BUFFER);
7864
0
    }
7865
0
#endif /* HAVE_ECC && !NO_ASN_CRYPT */
7866
0
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) && !defined(NO_ASN_CRYPT)
7867
0
    if (*algoID == 0) {
7868
0
        ed25519_key *ed25519 = (ed25519_key *)XMALLOC(sizeof *ed25519, heap,
7869
0
            DYNAMIC_TYPE_TMP_BUFFER);
7870
0
        if (ed25519 == NULL)
7871
0
            return MEMORY_E;
7872
7873
0
        tmpIdx = 0;
7874
0
        if (wc_ed25519_init_ex(ed25519, heap, INVALID_DEVID) == 0) {
7875
0
            if (wc_Ed25519PrivateKeyDecode(key, &tmpIdx, ed25519, keySz) == 0) {
7876
0
                *algoID = ED25519k;
7877
0
            }
7878
0
            else {
7879
0
                WOLFSSL_MSG("Not ED25519 DER key");
7880
0
            }
7881
0
            wc_ed25519_free(ed25519);
7882
0
        }
7883
0
        else {
7884
0
            WOLFSSL_MSG("GetKeyOID wc_ed25519_init failed");
7885
0
        }
7886
0
        XFREE(ed25519, heap, DYNAMIC_TYPE_TMP_BUFFER);
7887
0
    }
7888
0
#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT && !NO_ASN_CRYPT */
7889
0
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) && !defined(NO_ASN_CRYPT)
7890
0
    if (*algoID == 0) {
7891
0
        ed448_key *ed448 = (ed448_key *)XMALLOC(sizeof *ed448, heap,
7892
0
            DYNAMIC_TYPE_TMP_BUFFER);
7893
0
        if (ed448 == NULL)
7894
0
            return MEMORY_E;
7895
7896
0
        tmpIdx = 0;
7897
0
        if (wc_ed448_init(ed448) == 0) {
7898
0
            if (wc_Ed448PrivateKeyDecode(key, &tmpIdx, ed448, keySz) == 0) {
7899
0
                *algoID = ED448k;
7900
0
            }
7901
0
            else {
7902
0
                WOLFSSL_MSG("Not ED448 DER key");
7903
0
            }
7904
0
            wc_ed448_free(ed448);
7905
0
        }
7906
0
        else {
7907
0
            WOLFSSL_MSG("GetKeyOID wc_ed448_init failed");
7908
0
        }
7909
0
        XFREE(ed448, heap, DYNAMIC_TYPE_TMP_BUFFER);
7910
0
    }
7911
0
#endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT && !NO_ASN_CRYPT */
7912
#if defined(HAVE_PQC)
7913
#if defined(HAVE_FALCON)
7914
    if (*algoID == 0) {
7915
        falcon_key *falcon = (falcon_key *)XMALLOC(sizeof(*falcon), heap,
7916
            DYNAMIC_TYPE_TMP_BUFFER);
7917
        if (falcon == NULL)
7918
            return MEMORY_E;
7919
7920
        if (wc_falcon_init(falcon) != 0) {
7921
            tmpIdx = 0;
7922
            if (wc_falcon_set_level(falcon, 1) == 0) {
7923
                if (wc_Falcon_PrivateKeyDecode(key, &tmpIdx, falcon, keySz)
7924
                    == 0) {
7925
                    *algoID = FALCON_LEVEL1k;
7926
                }
7927
                else {
7928
                    WOLFSSL_MSG("Not Falcon Level 1 DER key");
7929
                }
7930
            }
7931
            else if (wc_falcon_set_level(falcon, 5) == 0) {
7932
                if (wc_Falcon_PrivateKeyDecode(key, &tmpIdx, falcon, keySz)
7933
                    == 0) {
7934
                    *algoID = FALCON_LEVEL5k;
7935
                }
7936
                else {
7937
                    WOLFSSL_MSG("Not Falcon Level 5 DER key");
7938
                }
7939
            }
7940
            else {
7941
                WOLFSSL_MSG("GetKeyOID falcon initialization failed");
7942
            }
7943
            wc_falcon_free(falcon);
7944
        }
7945
        XFREE(falcon, heap, DYNAMIC_TYPE_TMP_BUFFER);
7946
    }
7947
#endif /* HAVE_FALCON */
7948
#if defined(HAVE_DILITHIUM)
7949
    if (*algoID == 0) {
7950
        dilithium_key *dilithium = (dilithium_key *)XMALLOC(sizeof(*dilithium),
7951
             heap, DYNAMIC_TYPE_TMP_BUFFER);
7952
        if (dilithium == NULL)
7953
            return MEMORY_E;
7954
7955
        if (wc_dilithium_init(dilithium) != 0) {
7956
            tmpIdx = 0;
7957
            if (wc_dilithium_set_level(dilithium, 2)
7958
                == 0) {
7959
                if (wc_Dilithium_PrivateKeyDecode(key, &tmpIdx, dilithium,
7960
                    keySz) == 0) {
7961
                    *algoID = DILITHIUM_LEVEL2k;
7962
                }
7963
                else {
7964
                    WOLFSSL_MSG("Not Dilithium Level 2 DER key");
7965
                }
7966
            }
7967
            else if (wc_dilithium_set_level(dilithium, 3)
7968
                == 0) {
7969
                if (wc_Dilithium_PrivateKeyDecode(key, &tmpIdx, dilithium,
7970
                    keySz) == 0) {
7971
                    *algoID = DILITHIUM_LEVEL3k;
7972
                }
7973
                else {
7974
                    WOLFSSL_MSG("Not Dilithium Level 3 DER key");
7975
                }
7976
            }
7977
            else if (wc_dilithium_set_level(dilithium, 5)
7978
                == 0) {
7979
                if (wc_Dilithium_PrivateKeyDecode(key, &tmpIdx, dilithium,
7980
                    keySz) == 0) {
7981
                    *algoID = DILITHIUM_LEVEL5k;
7982
                }
7983
                else {
7984
                    WOLFSSL_MSG("Not Dilithium Level 5 DER key");
7985
                }
7986
            }
7987
            else {
7988
                WOLFSSL_MSG("GetKeyOID dilithium initialization failed");
7989
            }
7990
            wc_dilithium_free(dilithium);
7991
        }
7992
        XFREE(dilithium, heap, DYNAMIC_TYPE_TMP_BUFFER);
7993
    }
7994
#endif /* HAVE_DILITHIUM */
7995
#if defined(HAVE_SPHINCS)
7996
    if (*algoID == 0) {
7997
        sphincs_key *sphincs = (sphincs_key *)XMALLOC(sizeof(*sphincs),
7998
             heap, DYNAMIC_TYPE_TMP_BUFFER);
7999
        if (sphincs == NULL)
8000
            return MEMORY_E;
8001
8002
        if (wc_sphincs_init(sphincs) != 0) {
8003
            tmpIdx = 0;
8004
            if (wc_sphincs_set_level_and_optim(sphincs, 1, FAST_VARIANT)
8005
                == 0) {
8006
                if (wc_Sphincs_PrivateKeyDecode(key, &tmpIdx, sphincs,
8007
                    keySz) == 0) {
8008
                    *algoID = SPHINCS_FAST_LEVEL1k;
8009
                }
8010
                else {
8011
                    WOLFSSL_MSG("Not Sphincs-fast Level 1 DER key");
8012
                }
8013
            }
8014
            else if (wc_sphincs_set_level_and_optim(sphincs, 3, FAST_VARIANT)
8015
                == 0) {
8016
                if (wc_Sphincs_PrivateKeyDecode(key, &tmpIdx, sphincs,
8017
                    keySz) == 0) {
8018
                    *algoID = SPHINCS_FAST_LEVEL3k;
8019
                }
8020
                else {
8021
                    WOLFSSL_MSG("Not Sphincs-fast Level 3 DER key");
8022
                }
8023
            }
8024
            else if (wc_sphincs_set_level_and_optim(sphincs, 5, FAST_VARIANT)
8025
                == 0) {
8026
                if (wc_Sphincs_PrivateKeyDecode(key, &tmpIdx, sphincs,
8027
                    keySz) == 0) {
8028
                    *algoID = SPHINCS_FAST_LEVEL5k;
8029
                }
8030
                else {
8031
                    WOLFSSL_MSG("Not Sphincs-fast Level 5 DER key");
8032
                }
8033
            }
8034
            else if (wc_sphincs_set_level_and_optim(sphincs, 1, SMALL_VARIANT)
8035
                == 0) {
8036
                if (wc_Sphincs_PrivateKeyDecode(key, &tmpIdx, sphincs,
8037
                    keySz) == 0) {
8038
                    *algoID = SPHINCS_SMALL_LEVEL1k;
8039
                }
8040
                else {
8041
                    WOLFSSL_MSG("Not Sphincs-small Level 1 DER key");
8042
                }
8043
            }
8044
            else if (wc_sphincs_set_level_and_optim(sphincs, 3, SMALL_VARIANT)
8045
                == 0) {
8046
                if (wc_Sphincs_PrivateKeyDecode(key, &tmpIdx, sphincs,
8047
                    keySz) == 0) {
8048
                    *algoID = SPHINCS_SMALL_LEVEL3k;
8049
                }
8050
                else {
8051
                    WOLFSSL_MSG("Not Sphincs-small Level 3 DER key");
8052
                }
8053
            }
8054
            else if (wc_sphincs_set_level_and_optim(sphincs, 5, SMALL_VARIANT)
8055
                == 0) {
8056
                if (wc_Sphincs_PrivateKeyDecode(key, &tmpIdx, sphincs,
8057
                    keySz) == 0) {
8058
                    *algoID = SPHINCS_SMALL_LEVEL5k;
8059
                }
8060
                else {
8061
                    WOLFSSL_MSG("Not Sphincs-small Level 5 DER key");
8062
                }
8063
            }
8064
            else {
8065
                WOLFSSL_MSG("GetKeyOID sphincs initialization failed");
8066
            }
8067
            wc_sphincs_free(sphincs);
8068
        }
8069
        XFREE(sphincs, heap, DYNAMIC_TYPE_TMP_BUFFER);
8070
    }
8071
#endif /* HAVE_SPHINCS */
8072
#endif /* HAVE_PQC */
8073
8074
    /* if flag is not set then this is not a key that we understand. */
8075
0
    if (*algoID == 0) {
8076
0
        WOLFSSL_MSG("Bad key DER or compile options");
8077
0
        return BAD_FUNC_ARG;
8078
0
    }
8079
8080
0
    (void)tmpIdx;
8081
0
    (void)curveOID;
8082
0
    (void)oidSz;
8083
0
    (void)keySz;
8084
0
    (void)heap;
8085
8086
0
    return 1;
8087
0
}
8088
8089
#endif /* HAVE_PKCS8 || HAVE_PKCS12 */
8090
8091
#ifdef WOLFSSL_ASN_TEMPLATE
8092
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
8093
/* ASN.1 template for PBES2 parameters.
8094
 * PKCS #5: RFC 8018, A.4 - PBES2-params without outer SEQUENCE
8095
 *                    A.2 - PBKDF2-params
8096
 *                    B.2 - Encryption schemes
8097
 *                    C   - AlgorithmIdentifier
8098
 */
8099
static const ASNItem pbes2ParamsASN[] = {
8100
/* KDF_SEQ                */ { 0, ASN_SEQUENCE, 1, 1, 0 },
8101
               /* PBKDF2 */
8102
/* KDF_OID                */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
8103
/* PBKDF2_PARAMS_SEQ      */     { 1, ASN_SEQUENCE, 1, 1, 0 },
8104
                   /* Salt */
8105
/* PBKDF2_PARAMS_SALT     */         { 2, ASN_OCTET_STRING, 0, 0, 0 },
8106
                   /* Iteration count */
8107
/* PBKDF2_PARAMS_ITER     */         { 2, ASN_INTEGER, 0, 0, 0 },
8108
                   /* Key length */
8109
/* PBKDF2_PARAMS_KEYLEN   */         { 2, ASN_INTEGER, 0, 0, 1 },
8110
                   /* PRF - default is HMAC-SHA1 */
8111
/* PBKDF2_PARAMS_PRF      */         { 2, ASN_SEQUENCE, 1, 1, 1 },
8112
/* PBKDF2_PARAMS_PRF_OID  */             { 3, ASN_OBJECT_ID, 0, 0, 0 },
8113
/* PBKDF2_PARAMS_PRF_NULL */             { 3, ASN_TAG_NULL, 0, 0, 1 },
8114
/* ENCS_SEQ               */ { 0, ASN_SEQUENCE, 1, 1, 0 },
8115
                   /* Encryption algorithm */
8116
/* ENCS_OID               */   { 1, ASN_OBJECT_ID, 0, 0, 0 },
8117
                   /* IV for CBC */
8118
/* ENCS_PARAMS            */   { 1, ASN_OCTET_STRING, 0, 0, 0 },
8119
};
8120
enum {
8121
    PBES2PARAMSASN_IDX_KDF_SEQ = 0,
8122
    PBES2PARAMSASN_IDX_KDF_OID,
8123
    PBES2PARAMSASN_IDX_PBKDF2_PARAMS_SEQ,
8124
    PBES2PARAMSASN_IDX_PBKDF2_PARAMS_SALT,
8125
    PBES2PARAMSASN_IDX_PBKDF2_PARAMS_ITER,
8126
    PBES2PARAMSASN_IDX_PBKDF2_PARAMS_KEYLEN,
8127
    PBES2PARAMSASN_IDX_PBKDF2_PARAMS_PRF,
8128
    PBES2PARAMSASN_IDX_PBKDF2_PARAMS_PRF_OID,
8129
    PBES2PARAMSASN_IDX_PBKDF2_PARAMS_PRF_NULL,
8130
    PBES2PARAMSASN_IDX_ENCS_SEQ,
8131
    PBES2PARAMSASN_IDX_ENCS_OID,
8132
    PBES2PARAMSASN_IDX_ENCS_PARAMS
8133
};
8134
8135
/* Number of items in ASN.1 template for PBES2 parameters. */
8136
0
#define pbes2ParamsASN_Length (sizeof(pbes2ParamsASN) / sizeof(ASNItem))
8137
8138
/* ASN.1 template for PBES1 parameters.
8139
 * PKCS #5: RFC 8018, A.3. - PBEParameter without outer SEQUENCE
8140
 */
8141
static const ASNItem pbes1ParamsASN[] = {
8142
            /* Salt */
8143
/* SALT */    { 0, ASN_OCTET_STRING, 0, 0, 0 },
8144
            /* Iteration count */
8145
/* ITER */    { 0, ASN_INTEGER, 0, 0, 0 },
8146
};
8147
enum {
8148
    PBES1PARAMSASN_IDX_SALT = 0,
8149
    PBES1PARAMSASN_IDX_ITER
8150
};
8151
8152
/* Number of items in ASN.1 template for PBES1 parameters. */
8153
0
#define pbes1ParamsASN_Length (sizeof(pbes1ParamsASN) / sizeof(ASNItem))
8154
#endif /* HAVE_PKCS8 || HAVE_PKCS12 */
8155
#endif /* WOLFSSL_ASN_TEMPLATE */
8156
8157
#ifdef HAVE_PKCS8
8158
8159
/*
8160
 * Equivalent to calling TraditionalEnc with the same parameters but with
8161
 * encAlgId set to 0. This function must be kept alive because it's sometimes
8162
 * part of the API (WOLFSSL_ASN_API).
8163
 */
8164
int UnTraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz,
8165
        const char* password, int passwordSz, int vPKCS, int vAlgo,
8166
        byte* salt, word32 saltSz, int itt, WC_RNG* rng, void* heap)
8167
0
{
8168
0
    return TraditionalEnc(key, keySz, out, outSz, password, passwordSz,
8169
0
                vPKCS, vAlgo, 0, salt, saltSz, itt, rng, heap);
8170
0
}
8171
8172
static int GetAlgoV2(int encAlgId, const byte** oid, int *len, int* id,
8173
                     int *blkSz)
8174
0
{
8175
0
    int ret = 0;
8176
8177
0
    switch (encAlgId) {
8178
0
#if !defined(NO_DES3) && !defined(NO_SHA)
8179
0
    case DESb:
8180
0
        *len = sizeof(blkDesCbcOid);
8181
0
        *oid = blkDesCbcOid;
8182
0
        *id = PBE_SHA1_DES;
8183
0
        *blkSz = 8;
8184
0
        break;
8185
0
    case DES3b:
8186
0
        *len = sizeof(blkDes3CbcOid);
8187
0
        *oid = blkDes3CbcOid;
8188
0
        *id = PBE_SHA1_DES3;
8189
0
        *blkSz = 8;
8190
0
        break;
8191
0
#endif
8192
0
#if defined(WOLFSSL_AES_128) && defined(HAVE_AES_CBC)
8193
0
    case AES128CBCb:
8194
0
        *len = sizeof(blkAes128CbcOid);
8195
0
        *oid = blkAes128CbcOid;
8196
0
        *id = PBE_AES128_CBC;
8197
0
        *blkSz = 16;
8198
0
        break;
8199
0
#endif
8200
0
#if defined(WOLFSSL_AES_256) && defined(HAVE_AES_CBC)
8201
0
    case AES256CBCb:
8202
0
        *len = sizeof(blkAes256CbcOid);
8203
0
        *oid = blkAes256CbcOid;
8204
0
        *id = PBE_AES256_CBC;
8205
0
        *blkSz = 16;
8206
0
        break;
8207
0
#endif
8208
0
    default:
8209
0
        (void)len;
8210
0
        (void)oid;
8211
0
        (void)id;
8212
0
        (void)blkSz;
8213
0
        ret = ALGO_ID_E;
8214
0
    }
8215
8216
0
    return ret;
8217
0
}
8218
8219
int wc_EncryptPKCS8Key(byte* key, word32 keySz, byte* out, word32* outSz,
8220
        const char* password, int passwordSz, int vPKCS, int pbeOid,
8221
        int encAlgId, byte* salt, word32 saltSz, int itt, WC_RNG* rng,
8222
        void* heap)
8223
0
{
8224
0
#ifdef WOLFSSL_SMALL_STACK
8225
0
    byte* saltTmp = NULL;
8226
#else
8227
    byte saltTmp[MAX_SALT_SIZE];
8228
#endif
8229
0
    int genSalt = 0;
8230
0
    int ret = 0;
8231
0
    int version = 0;
8232
0
    int pbeId = 0;
8233
0
    int blockSz = 0;
8234
0
    const byte* encOid = NULL;
8235
0
    int encOidSz = 0;
8236
0
    word32 padSz = 0;
8237
0
    word32 innerLen = 0;
8238
0
    const byte* pbeOidBuf = NULL;
8239
0
    word32 pbeOidBufSz = 0;
8240
0
    word32 pbeLen = 0;
8241
0
    word32 kdfLen = 0;
8242
0
    word32 encLen = 0;
8243
0
    byte cbcIv[MAX_IV_SIZE];
8244
0
    word32 idx = 0;
8245
0
    word32 encIdx = 0;
8246
8247
0
    (void)heap;
8248
8249
0
    WOLFSSL_ENTER("wc_EncryptPKCS8Key");
8250
8251
0
    if (key == NULL || outSz == NULL || password == NULL) {
8252
0
        ret = BAD_FUNC_ARG;
8253
0
    }
8254
8255
0
    if (ret == 0) {
8256
0
        ret = CheckAlgo(vPKCS, pbeOid, &pbeId, &version, &blockSz);
8257
0
    }
8258
0
    if (ret == 0 && (salt == NULL || saltSz == 0)) {
8259
0
        genSalt = 1;
8260
0
        saltSz = 8;
8261
0
    }
8262
0
    if (ret == 0 && version == PKCS5v2) {
8263
0
        ret = GetAlgoV2(encAlgId, &encOid, &encOidSz, &pbeId, &blockSz);
8264
0
    }
8265
0
    if (ret == 0) {
8266
0
        padSz = (word32)((blockSz - ((int)keySz & (blockSz - 1))) &
8267
0
            (blockSz - 1));
8268
        /* inner = OCT salt INT itt */
8269
0
        innerLen = 2 + saltSz + 2 + ((itt < 256) ? 1 : ((itt < 65536) ? 2 : 3));
8270
8271
0
        if (version != PKCS5v2) {
8272
0
            pbeOidBuf = OidFromId((word32)pbeId, oidPBEType, &pbeOidBufSz);
8273
            /* pbe = OBJ pbse1 SEQ [ inner ] */
8274
0
            pbeLen = 2 + pbeOidBufSz + 2 + innerLen;
8275
0
        }
8276
0
        else {
8277
0
            pbeOidBuf = pbes2;
8278
0
            pbeOidBufSz = sizeof(pbes2);
8279
            /* kdf = OBJ pbkdf2 [ SEQ innerLen ] */
8280
0
            kdfLen = 2 + sizeof(pbkdf2Oid) + 2 + innerLen;
8281
            /* enc = OBJ enc_alg OCT iv */
8282
0
            encLen = 2 + (word32)encOidSz + 2 + (word32)blockSz;
8283
            /* pbe = OBJ pbse2 SEQ [ SEQ [ kdf ] SEQ [ enc ] ] */
8284
0
            pbeLen = (word32)(2 + sizeof(pbes2) + 2 + 2 + (size_t)kdfLen + 2 +
8285
0
                              (size_t)encLen);
8286
8287
0
            ret = wc_RNG_GenerateBlock(rng, cbcIv, (word32)blockSz);
8288
0
        }
8289
0
    }
8290
0
    if (ret == 0) {
8291
        /* outerLen = length of PBE encoding + octet string data */
8292
        /* Plus 2 for tag and length for pbe */
8293
0
        word32 outerLen = 2 + pbeLen;
8294
        /* Octet string tag, length */
8295
0
        outerLen += 1 + SetLength(keySz + padSz, NULL);
8296
        /* Octet string bytes */
8297
0
        outerLen += keySz + padSz;
8298
0
        if (out == NULL) {
8299
            /* Sequence tag, length */
8300
0
            *outSz = 1 + SetLength(outerLen, NULL) + outerLen;
8301
0
            return LENGTH_ONLY_E;
8302
0
        }
8303
0
        SetOctetString(keySz + padSz, out);
8304
8305
0
        idx += SetSequence(outerLen, out + idx);
8306
8307
0
        encIdx = idx + outerLen - keySz - padSz;
8308
        /* Put Encrypted content in place. */
8309
0
        XMEMCPY(out + encIdx, key, keySz);
8310
0
        if (padSz > 0) {
8311
0
            XMEMSET(out + encIdx + keySz, (int)padSz, padSz);
8312
0
            keySz += padSz;
8313
0
        }
8314
8315
0
        if (genSalt == 1) {
8316
0
        #ifdef WOLFSSL_SMALL_STACK
8317
0
            saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
8318
0
            if (saltTmp == NULL) {
8319
0
                ret = MEMORY_E;
8320
0
            }
8321
0
            else
8322
0
        #endif
8323
0
            {
8324
0
                salt = saltTmp;
8325
0
                if ((ret = wc_RNG_GenerateBlock(rng, saltTmp, saltSz)) != 0) {
8326
0
                    WOLFSSL_MSG("Error generating random salt");
8327
0
                }
8328
0
            }
8329
0
        }
8330
0
    }
8331
0
    if (ret == 0) {
8332
0
        ret = wc_CryptKey(password, passwordSz, salt, (int)saltSz, itt, pbeId,
8333
0
                  out + encIdx, (int)keySz, version, cbcIv, 1, 0);
8334
0
    }
8335
0
    if (ret == 0) {
8336
0
        if (version != PKCS5v2) {
8337
            /* PBE algorithm */
8338
0
            idx += SetSequence(pbeLen, out + idx);
8339
0
            idx += (word32)SetObjectId((int)pbeOidBufSz, out + idx);
8340
0
            XMEMCPY(out + idx, pbeOidBuf, pbeOidBufSz);
8341
0
            idx += pbeOidBufSz;
8342
0
        }
8343
0
        else {
8344
            /* PBES2 algorithm identifier */
8345
0
            idx += SetSequence(pbeLen, out + idx);
8346
0
            idx += (word32)SetObjectId((int)pbeOidBufSz, out + idx);
8347
0
            XMEMCPY(out + idx, pbeOidBuf, pbeOidBufSz);
8348
0
            idx += pbeOidBufSz;
8349
            /* PBES2 Parameters: SEQ [ kdf ] SEQ [ enc ] */
8350
0
            idx += SetSequence(2 + kdfLen + 2 + encLen, out + idx);
8351
            /* KDF Algorithm Identifier */
8352
0
            idx += SetSequence(kdfLen, out + idx);
8353
0
            idx += (word32)SetObjectId((int)sizeof(pbkdf2Oid), out + idx);
8354
0
            XMEMCPY(out + idx, pbkdf2Oid, sizeof(pbkdf2Oid));
8355
0
            idx += sizeof(pbkdf2Oid);
8356
0
        }
8357
0
        idx += SetSequence(innerLen, out + idx);
8358
0
        idx += SetOctetString(saltSz, out + idx);
8359
0
        XMEMCPY(out + idx, salt, saltSz); idx += saltSz;
8360
0
        ret = SetShortInt(out, &idx, (word32)itt, *outSz);
8361
0
        if (ret > 0)
8362
0
            ret = 0;
8363
0
    }
8364
0
    if (ret == 0) {
8365
0
        if (version == PKCS5v2) {
8366
            /* Encryption Algorithm Identifier */
8367
0
            idx += SetSequence(encLen, out + idx);
8368
0
            idx += (word32)SetObjectId(encOidSz, out + idx);
8369
0
            XMEMCPY(out + idx, encOid, (size_t)encOidSz);
8370
0
            idx += (word32)encOidSz;
8371
            /* Encryption Algorithm Parameter: CBC IV */
8372
0
            idx += SetOctetString((word32)blockSz, out + idx);
8373
0
            XMEMCPY(out + idx, cbcIv, (size_t)blockSz);
8374
0
            idx += (word32)blockSz;
8375
0
        }
8376
0
        idx += SetOctetString(keySz, out + idx);
8377
        /* Default PRF - no need to write out OID */
8378
0
        idx += keySz;
8379
8380
0
        ret = (int)idx;
8381
0
    }
8382
8383
0
#ifdef WOLFSSL_SMALL_STACK
8384
0
    if (saltTmp != NULL) {
8385
0
        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
8386
0
    }
8387
0
#endif
8388
8389
0
    WOLFSSL_LEAVE("wc_EncryptPKCS8Key", ret);
8390
8391
0
    return ret;
8392
0
}
8393
8394
int wc_DecryptPKCS8Key(byte* input, word32 sz, const char* password,
8395
        int passwordSz)
8396
0
{
8397
0
    int ret;
8398
0
    int length;
8399
0
    word32 inOutIdx = 0;
8400
8401
0
    if (input == NULL || password == NULL) {
8402
0
        return BAD_FUNC_ARG;
8403
0
    }
8404
8405
0
    if (GetSequence(input, &inOutIdx, &length, sz) < 0) {
8406
0
        ret = ASN_PARSE_E;
8407
0
    }
8408
0
    else {
8409
0
        ret = DecryptContent(input + inOutIdx, sz - inOutIdx, password,
8410
0
                passwordSz);
8411
0
        if (ret > 0) {
8412
0
            XMEMMOVE(input, input + inOutIdx, (size_t)ret);
8413
0
        }
8414
0
    }
8415
8416
0
    if (ret > 0) {
8417
        /* DecryptContent will decrypt the data, but it will leave any padding
8418
         * bytes intact. This code calculates the length without the padding
8419
         * and we return that to the user. */
8420
0
        inOutIdx = 0;
8421
0
        if (GetSequence(input, &inOutIdx, &length, (word32)ret) < 0) {
8422
0
            ret = ASN_PARSE_E;
8423
0
        }
8424
0
        else {
8425
0
            ret = (int)inOutIdx + length;
8426
0
        }
8427
0
    }
8428
8429
0
    return ret;
8430
0
}
8431
8432
/* Takes an unencrypted, traditional DER-encoded key and converts it to a PKCS#8
8433
 * encrypted key. If out is not NULL, it will hold the encrypted key. If it's
8434
 * NULL, LENGTH_ONLY_E will be returned and outSz will have the required out
8435
 * buffer size. */
8436
int TraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz,
8437
        const char* password, int passwordSz, int vPKCS, int vAlgo,
8438
        int encAlgId, byte* salt, word32 saltSz, int itt, WC_RNG* rng,
8439
        void* heap)
8440
0
{
8441
0
    int ret = 0;
8442
0
    byte *pkcs8Key = NULL;
8443
0
    word32 pkcs8KeySz = 0;
8444
0
    int algId = 0;
8445
0
    const byte* curveOid = NULL;
8446
0
    word32 curveOidSz = 0;
8447
8448
0
    if (ret == 0) {
8449
        /* check key type and get OID if ECC */
8450
0
        ret = wc_GetKeyOID(key, keySz, &curveOid, &curveOidSz, &algId, heap);
8451
0
        if (ret == 1)
8452
0
            ret = 0;
8453
0
    }
8454
0
    if (ret == 0) {
8455
0
        ret = wc_CreatePKCS8Key(NULL, &pkcs8KeySz, key, keySz, algId, curveOid,
8456
0
                                                                    curveOidSz);
8457
0
        if (ret == LENGTH_ONLY_E)
8458
0
            ret = 0;
8459
0
    }
8460
0
    if (ret == 0) {
8461
0
        pkcs8Key = (byte*)XMALLOC(pkcs8KeySz, heap, DYNAMIC_TYPE_TMP_BUFFER);
8462
0
        if (pkcs8Key == NULL)
8463
0
            ret = MEMORY_E;
8464
0
    }
8465
0
    if (ret == 0) {
8466
0
        ret = wc_CreatePKCS8Key(pkcs8Key, &pkcs8KeySz, key, keySz, algId,
8467
0
            curveOid, curveOidSz);
8468
0
        if (ret >= 0) {
8469
0
            pkcs8KeySz = (word32)ret;
8470
0
            ret = 0;
8471
0
        }
8472
0
    }
8473
#ifdef WOLFSSL_CHECK_MEM_ZERO
8474
    if (ret == 0) {
8475
        wc_MemZero_Add("TraditionalEnc pkcs8Key", pkcs8Key, pkcs8KeySz);
8476
    }
8477
#endif
8478
0
    if (ret == 0) {
8479
0
        ret = wc_EncryptPKCS8Key(pkcs8Key, pkcs8KeySz, out, outSz, password,
8480
0
            passwordSz, vPKCS, vAlgo, encAlgId, salt, saltSz, itt, rng, heap);
8481
0
    }
8482
8483
0
    if (pkcs8Key != NULL) {
8484
0
        ForceZero(pkcs8Key, pkcs8KeySz);
8485
0
        XFREE(pkcs8Key, heap, DYNAMIC_TYPE_TMP_BUFFER);
8486
0
    }
8487
8488
0
    (void)rng;
8489
8490
0
    return ret;
8491
0
}
8492
8493
/* Same as TraditionalEnc, but in the public API. */
8494
int wc_CreateEncryptedPKCS8Key(byte* key, word32 keySz, byte* out,
8495
        word32* outSz, const char* password, int passwordSz, int vPKCS,
8496
        int pbeOid, int encAlgId, byte* salt, word32 saltSz, int itt,
8497
        WC_RNG* rng, void* heap)
8498
0
{
8499
0
    return TraditionalEnc(key, keySz, out, outSz, password, passwordSz, vPKCS,
8500
0
        pbeOid, encAlgId, salt, saltSz, itt, rng, heap);
8501
0
}
8502
8503
8504
#ifdef WOLFSSL_ASN_TEMPLATE
8505
/* ASN.1 template for PKCS #8/#7 encrypted key for decrypting
8506
 * PKCS #8: RFC 5958, 3 - EncryptedPrivateKeyInfo without outer SEQUENCE
8507
 * PKCS #7: RFC 2315, 10.1 - EncryptedContentInfo without outer SEQUENCE
8508
 */
8509
static const ASNItem pkcs8DecASN[] = {
8510
/* ENCALGO_SEQ    */ { 1, ASN_SEQUENCE, 1, 1, 0 },
8511
/* ENCALGO_OID    */     { 2, ASN_OBJECT_ID, 0, 0, 0 },
8512
/* ENCALGO_PARAMS */     { 2, ASN_SEQUENCE, 1, 0, 0 },
8513
            /* PKCS #7 */
8514
/* ENCCONTENT     */ { 1, ASN_CONTEXT_SPECIFIC | ASN_ENC_CONTENT,
8515
                                       0, 0, 2 },
8516
            /* PKCS #8 */
8517
/* ENCDATA        */ { 1, ASN_OCTET_STRING, 0, 0, 2 },
8518
};
8519
enum {
8520
    PKCS8DECASN_IDX_ENCALGO_SEQ = 0,
8521
    PKCS8DECASN_IDX_ENCALGO_OID,
8522
    PKCS8DECASN_IDX_ENCALGO_PARAMS,
8523
    PKCS8DECASN_IDX_ENCCONTENT,
8524
    PKCS8DECASN_IDX_ENCDATA
8525
};
8526
8527
/* Number of items in ASN.1 template for PKCS #8/#7 encrypted key. */
8528
0
#define pkcs8DecASN_Length (sizeof(pkcs8DecASN) / sizeof(ASNItem))
8529
#endif
8530
8531
/* Decrypt data using PBE algorithm.
8532
 *
8533
 * PKCS #8: RFC 5958, 3 - EncryptedPrivateKeyInfo without outer SEQUENCE
8534
 * PKCS #7: RFC 2315, 10.1 - EncryptedContentInfo without outer SEQUENCE
8535
 *
8536
 * Note: input buffer is overwritten with decrypted data!
8537
 *
8538
 * Salt is in KDF parameters and IV is PBE parameters when needed.
8539
 *
8540
 * @param [in] input       Data to decrypt and unwrap.
8541
 * @param [in] sz          Size of encrypted data.
8542
 * @param [in] password    Password to derive encryption key with.
8543
 * @param [in] passwordSz  Size of password in bytes.
8544
 * @return  Length of decrypted data on success.
8545
 * @return  MEMORY_E when dynamic memory allocation fails.
8546
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
8547
 *          is invalid.
8548
 * @return  BUFFER_E when data in buffer is too small.
8549
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
8550
 * @return  Other when decryption fails.
8551
 */
8552
int DecryptContent(byte* input, word32 sz, const char* password, int passwordSz)
8553
0
{
8554
#ifndef WOLFSSL_ASN_TEMPLATE
8555
    word32 inOutIdx = 0, seqEnd, oid, shaOid = 0;
8556
    int    ret = 0, first, second, length = 0, version, saltSz, id = 0;
8557
    int    iterations = 0, keySz = 0;
8558
#ifdef WOLFSSL_SMALL_STACK
8559
    byte*  salt = NULL;
8560
    byte*  cbcIv = NULL;
8561
#else
8562
    byte   salt[MAX_SALT_SIZE];
8563
    byte   cbcIv[MAX_IV_SIZE];
8564
#endif
8565
    byte   tag;
8566
8567
    if (passwordSz < 0) {
8568
        WOLFSSL_MSG("Bad password size");
8569
        return BAD_FUNC_ARG;
8570
    }
8571
8572
    if (GetAlgoId(input, &inOutIdx, &oid, oidIgnoreType, sz) < 0) {
8573
        ERROR_OUT(ASN_PARSE_E, exit_dc);
8574
    }
8575
8576
    first  = input[inOutIdx - 2];   /* PKCS version always 2nd to last byte */
8577
    second = input[inOutIdx - 1];   /* version.algo, algo id last byte */
8578
8579
    if (CheckAlgo(first, second, &id, &version, NULL) < 0) {
8580
        ERROR_OUT(ASN_INPUT_E, exit_dc); /* Algo ID error */
8581
    }
8582
8583
    if (version == PKCS5v2) {
8584
        if (GetSequence(input, &inOutIdx, &length, sz) < 0) {
8585
            ERROR_OUT(ASN_PARSE_E, exit_dc);
8586
        }
8587
8588
        if (GetAlgoId(input, &inOutIdx, &oid, oidKdfType, sz) < 0) {
8589
            ERROR_OUT(ASN_PARSE_E, exit_dc);
8590
        }
8591
8592
        if (oid != PBKDF2_OID) {
8593
            ERROR_OUT(ASN_PARSE_E, exit_dc);
8594
        }
8595
    }
8596
8597
    if (GetSequence(input, &inOutIdx, &length, sz) <= 0) {
8598
        ERROR_OUT(ASN_PARSE_E, exit_dc);
8599
    }
8600
    /* Find the end of this SEQUENCE so we can check for the OPTIONAL and
8601
     * DEFAULT items. */
8602
    seqEnd = inOutIdx + (word32)length;
8603
8604
    ret = GetOctetString(input, &inOutIdx, &saltSz, sz);
8605
    if (ret < 0)
8606
        goto exit_dc;
8607
8608
    if (saltSz > MAX_SALT_SIZE) {
8609
        ERROR_OUT(ASN_PARSE_E, exit_dc);
8610
    }
8611
8612
#ifdef WOLFSSL_SMALL_STACK
8613
    salt = (byte*)XMALLOC(MAX_SALT_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8614
    if (salt == NULL) {
8615
        ERROR_OUT(MEMORY_E, exit_dc);
8616
    }
8617
#endif
8618
8619
    XMEMCPY(salt, &input[inOutIdx], (size_t)saltSz);
8620
    inOutIdx += (word32)saltSz;
8621
8622
    if (GetShortInt(input, &inOutIdx, &iterations, sz) < 0) {
8623
        ERROR_OUT(ASN_PARSE_E, exit_dc);
8624
    }
8625
8626
    /* OPTIONAL key length */
8627
    if (seqEnd > inOutIdx) {
8628
        word32 localIdx = inOutIdx;
8629
8630
        if (GetASNTag(input, &localIdx, &tag, sz) < 0) {
8631
            ERROR_OUT(ASN_PARSE_E, exit_dc);
8632
        }
8633
8634
        if (tag == ASN_INTEGER &&
8635
                GetShortInt(input, &inOutIdx, &keySz, sz) < 0) {
8636
            ERROR_OUT(ASN_PARSE_E, exit_dc);
8637
        }
8638
    }
8639
8640
    /* DEFAULT HMAC is SHA-1 */
8641
    if (seqEnd > inOutIdx) {
8642
        if (GetAlgoId(input, &inOutIdx, &oid, oidHmacType, sz) < 0) {
8643
            ERROR_OUT(ASN_PARSE_E, exit_dc);
8644
        }
8645
8646
        shaOid = oid;
8647
    }
8648
8649
#ifdef WOLFSSL_SMALL_STACK
8650
    cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8651
    if (cbcIv == NULL) {
8652
        ERROR_OUT(MEMORY_E, exit_dc);
8653
    }
8654
#endif
8655
8656
    if (version == PKCS5v2) {
8657
        /* get encryption algo */
8658
        if (GetAlgoId(input, &inOutIdx, &oid, oidBlkType, sz) < 0) {
8659
            ERROR_OUT(ASN_PARSE_E, exit_dc);
8660
        }
8661
8662
        if (CheckAlgoV2((int)oid, &id, NULL) < 0) {
8663
            ERROR_OUT(ASN_PARSE_E, exit_dc); /* PKCS v2 algo id error */
8664
        }
8665
8666
        if (shaOid == 0)
8667
            shaOid = oid;
8668
8669
        ret = GetOctetString(input, &inOutIdx, &length, sz);
8670
        if (ret < 0)
8671
            goto exit_dc;
8672
8673
        if (length > MAX_IV_SIZE) {
8674
            ERROR_OUT(ASN_PARSE_E, exit_dc);
8675
        }
8676
8677
        XMEMCPY(cbcIv, &input[inOutIdx], (size_t)length);
8678
        inOutIdx += (word32)length;
8679
    }
8680
8681
    if (GetASNTag(input, &inOutIdx, &tag, sz) < 0) {
8682
        ERROR_OUT(ASN_PARSE_E, exit_dc);
8683
    }
8684
8685
    if (tag != (ASN_CONTEXT_SPECIFIC | 0) && tag != ASN_OCTET_STRING) {
8686
        ERROR_OUT(ASN_PARSE_E, exit_dc);
8687
    }
8688
8689
    if (GetLength(input, &inOutIdx, &length, sz) < 0) {
8690
        ERROR_OUT(ASN_PARSE_E, exit_dc);
8691
    }
8692
8693
    ret = wc_CryptKey(password, passwordSz, salt, saltSz, iterations, id,
8694
                   input + inOutIdx, length, version, cbcIv, 0, (int)shaOid);
8695
8696
exit_dc:
8697
#ifdef WOLFSSL_SMALL_STACK
8698
    XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
8699
    XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8700
#endif
8701
8702
    if (ret == 0) {
8703
        XMEMMOVE(input, input + inOutIdx, (size_t)length);
8704
        ret = length;
8705
    }
8706
8707
    return ret;
8708
#else
8709
    /* pbes2ParamsASN longer than pkcs8DecASN_Length/pbes1ParamsASN_Length. */
8710
0
    DECL_ASNGETDATA(dataASN, pbes2ParamsASN_Length);
8711
0
    int    ret = 0;
8712
0
    int    id = 0;
8713
0
    int    version;
8714
0
    word32 idx = 0;
8715
0
    word32 pIdx = 0;
8716
0
    word32 iterations;
8717
0
    word32 keySz = 0;
8718
0
    word32 saltSz = 0;
8719
0
    word32 shaOid = 0;
8720
0
    byte*  salt = NULL;
8721
0
    byte*  key = NULL;
8722
0
    byte   cbcIv[MAX_IV_SIZE];
8723
0
    byte*  params = NULL;
8724
8725
0
    WOLFSSL_ENTER("DecryptContent");
8726
8727
0
    CALLOC_ASNGETDATA(dataASN, pbes2ParamsASN_Length, ret, NULL);
8728
8729
0
    if (ret == 0) {
8730
        /* Check OID is a PBE Type */
8731
0
        GetASN_OID(&dataASN[PKCS8DECASN_IDX_ENCALGO_OID], oidPBEType);
8732
0
        ret = GetASN_Items(pkcs8DecASN, dataASN, pkcs8DecASN_Length, 0, input,
8733
0
                           &idx, sz);
8734
0
    }
8735
0
    if (ret == 0) {
8736
        /* Check the PBE algorithm and get the version and id. */
8737
0
        idx = dataASN[PKCS8DECASN_IDX_ENCALGO_OID].data.oid.length;
8738
        /* Second last byte: 1 (PKCS #12 PBE Id) or 5 (PKCS #5)
8739
         * Last byte: Alg or PBES2 */
8740
0
        ret = CheckAlgo(dataASN[PKCS8DECASN_IDX_ENCALGO_OID].data.oid.data[idx - 2],
8741
0
                  dataASN[PKCS8DECASN_IDX_ENCALGO_OID].data.oid.data[idx - 1],
8742
0
                  &id, &version, NULL);
8743
0
    }
8744
0
    if (ret == 0) {
8745
        /* Get the parameters data. */
8746
0
        GetASN_GetRef(&dataASN[PKCS8DECASN_IDX_ENCALGO_PARAMS], &params, &sz);
8747
        /* Having a numbered choice means none or both will have errored out. */
8748
0
        if (dataASN[PKCS8DECASN_IDX_ENCCONTENT].tag != 0)
8749
0
            GetASN_GetRef(&dataASN[PKCS8DECASN_IDX_ENCCONTENT], &key, &keySz);
8750
0
        else if (dataASN[PKCS8DECASN_IDX_ENCDATA].tag != 0)
8751
0
            GetASN_GetRef(&dataASN[PKCS8DECASN_IDX_ENCDATA], &key, &keySz);
8752
0
        else
8753
0
            ret = ASN_RSA_KEY_E;
8754
0
    }
8755
8756
0
    if (ret == 0) {
8757
0
        if (version != PKCS5v2) {
8758
            /* Initialize for PBES1 parameters and put iterations in var. */
8759
0
            XMEMSET(dataASN, 0, sizeof(*dataASN) * pbes1ParamsASN_Length);
8760
0
            GetASN_Int32Bit(&dataASN[PBES1PARAMSASN_IDX_ITER], &iterations);
8761
            /* Parse the PBES1 parameters. */
8762
0
            ret = GetASN_Items(pbes1ParamsASN, dataASN, pbes1ParamsASN_Length,
8763
0
                               0, params, &pIdx, sz);
8764
0
            if (ret == 0) {
8765
                /* Get the salt data. */
8766
0
                GetASN_GetRef(&dataASN[PBES1PARAMSASN_IDX_SALT], &salt, &saltSz);
8767
0
            }
8768
0
        }
8769
0
        else {
8770
0
            word32 ivSz = MAX_IV_SIZE;
8771
8772
            /* Initialize for PBES2 parameters. Put iterations in var; match
8773
             * KDF, HMAC and cipher, and copy CBC into buffer. */
8774
0
            XMEMSET(dataASN, 0, sizeof(*dataASN) * pbes2ParamsASN_Length);
8775
0
            GetASN_ExpBuffer(&dataASN[PBES2PARAMSASN_IDX_KDF_OID], pbkdf2Oid, sizeof(pbkdf2Oid));
8776
0
            GetASN_Int32Bit(&dataASN[PBES2PARAMSASN_IDX_PBKDF2_PARAMS_ITER], &iterations);
8777
0
            GetASN_OID(&dataASN[PBES2PARAMSASN_IDX_PBKDF2_PARAMS_PRF_OID], oidHmacType);
8778
0
            GetASN_OID(&dataASN[PBES2PARAMSASN_IDX_ENCS_OID], oidBlkType);
8779
0
            GetASN_Buffer(&dataASN[PBES2PARAMSASN_IDX_ENCS_PARAMS], cbcIv, &ivSz);
8780
            /* Parse the PBES2 parameters  */
8781
0
            ret = GetASN_Items(pbes2ParamsASN, dataASN, pbes2ParamsASN_Length,
8782
0
                               0, params, &pIdx, sz);
8783
0
            if (ret == 0) {
8784
                /* Get the salt data. */
8785
0
                GetASN_GetRef(&dataASN[PBES2PARAMSASN_IDX_PBKDF2_PARAMS_SALT], &salt, &saltSz);
8786
                /* Get the digest and encryption algorithm id. */
8787
0
                shaOid = dataASN[PBES2PARAMSASN_IDX_PBKDF2_PARAMS_PRF_OID].data.oid.sum; /* Default HMAC-SHA1 */
8788
0
                id     = (int)dataASN[PBES2PARAMSASN_IDX_ENCS_OID].data.oid.sum;
8789
                /* Convert encryption algorithm to a PBE algorithm if needed. */
8790
0
                CheckAlgoV2(id, &id, NULL);
8791
0
            }
8792
0
        }
8793
0
    }
8794
8795
0
    if (ret == 0) {
8796
        /* Decrypt the key. */
8797
0
        ret = wc_CryptKey(
8798
0
            password, passwordSz, salt, (int)saltSz, (int)iterations, id, key,
8799
0
            (int)keySz, version, cbcIv, 0, (int)shaOid);
8800
0
    }
8801
0
    if (ret == 0) {
8802
        /* Copy the decrypted key into the input (inline). */
8803
0
        XMEMMOVE(input, key, keySz);
8804
0
        ret = (int)keySz;
8805
0
    }
8806
8807
0
    FREE_ASNGETDATA(dataASN, NULL);
8808
0
    return ret;
8809
0
#endif
8810
0
}
8811
8812
/* Decrypt data using PBE algorithm and get key from PKCS#8 wrapping.
8813
 *
8814
 * PKCS #8: RFC 5958, 3 - EncryptedPrivateKeyInfo
8815
 * PKCS #7: RFC 2315, 10.1 - EncryptedContentInfo
8816
 *
8817
 * Note: input buffer is overwritten with decrypted key!
8818
 *
8819
 * Salt is in KDF parameters and IV is PBE parameters when needed.
8820
 *
8821
 * @param [in]  input       Data to decrypt and unwrap.
8822
 * @param [in]  sz          Size of encrypted data.
8823
 * @param [in]  password    Password to derive encryption key with.
8824
 * @param [in]  passwordSz  Size of password in bytes.
8825
 * @param [out] algId       Key algorithm from PKCS#8 wrapper.
8826
 * @return  Length of decrypted data on success.
8827
 * @return  MEMORY_E when dynamic memory allocation fails.
8828
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
8829
 *          is invalid.
8830
 * @return  BUFFER_E when data in buffer is too small.
8831
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
8832
 * @return  Other when decryption fails.
8833
 */
8834
int ToTraditionalEnc(byte* input, word32 sz, const char* password,
8835
                     int passwordSz, word32* algId)
8836
0
{
8837
0
    int ret;
8838
8839
0
    ret = wc_DecryptPKCS8Key(input, sz, password, passwordSz);
8840
0
    if (ret > 0) {
8841
0
        ret = ToTraditional_ex(input, (word32)ret, algId);
8842
0
    }
8843
8844
0
    return ret;
8845
0
}
8846
8847
#endif /* HAVE_PKCS8 */
8848
8849
#ifdef HAVE_PKCS12
8850
8851
#define PKCS8_MIN_BLOCK_SIZE 8
8852
static int Pkcs8Pad(byte* buf, int sz, int blockSz)
8853
0
{
8854
0
    int padSz;
8855
8856
    /* calculate pad size */
8857
0
    padSz = blockSz - (sz & (blockSz - 1));
8858
8859
    /* pad with padSz value */
8860
0
    if (buf) {
8861
0
        int i;
8862
0
        for (i = 0; i < padSz; i++) {
8863
0
            buf[sz+i] = (byte)(padSz & 0xFF);
8864
0
        }
8865
0
    }
8866
8867
    /* return adjusted length */
8868
0
    return sz + padSz;
8869
0
}
8870
8871
#ifdef WOLFSSL_ASN_TEMPLATE
8872
/* ASN.1 template for PKCS #8 encrypted key with PBES1 parameters.
8873
 * PKCS #8: RFC 5958, 3 - EncryptedPrivateKeyInfo
8874
 * PKCS #5: RFC 8018, A.3 - PBEParameter
8875
 */
8876
static const ASNItem p8EncPbes1ASN[] = {
8877
/* SEQ                   */ { 0, ASN_SEQUENCE, 1, 1, 0 },
8878
/* ENCALGO_SEQ           */     { 1, ASN_SEQUENCE, 1, 1, 0 },
8879
                    /* PBE algorithm */
8880
/* ENCALGO_OID           */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
8881
/* ENCALGO_PBEPARAM_SEQ  */         { 2, ASN_SEQUENCE, 1, 1, 0 },
8882
                        /* Salt */
8883
/* ENCALGO_PBEPARAM_SALT */             { 3, ASN_OCTET_STRING, 0, 0, 0 },
8884
                        /* Iteration Count */
8885
/* ENCALGO_PBEPARAM_ITER */             { 3, ASN_INTEGER, 0, 0, 0 },
8886
/* ENCDATA               */     { 1, ASN_OCTET_STRING, 0, 0, 0 },
8887
};
8888
enum {
8889
    P8ENCPBES1ASN_IDX_SEQ = 0,
8890
    P8ENCPBES1ASN_IDX_ENCALGO_SEQ,
8891
    P8ENCPBES1ASN_IDX_ENCALGO_OID,
8892
    P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_SEQ,
8893
    P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_SALT,
8894
    P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_ITER,
8895
    P8ENCPBES1ASN_IDX_ENCDATA
8896
};
8897
8898
0
#define p8EncPbes1ASN_Length (sizeof(p8EncPbes1ASN) / sizeof(ASNItem))
8899
#endif
8900
8901
/* Wrap a private key in PKCS#8 and encrypt.
8902
 *
8903
 * Used for PKCS#12 and PKCS#7.
8904
 * vPKCS is the version of PKCS to use.
8905
 * vAlgo is the algorithm version to use.
8906
 *
8907
 * When salt is NULL, a random number is generated.
8908
 *
8909
 * data returned is :
8910
 * [ seq - obj [ seq -salt,itt]] , construct with encrypted data
8911
 *
8912
 * @param [in]  input       Data to encrypt.
8913
 * @param [in]  inputSz     Length of data in bytes.
8914
 * @param [out] out         Buffer to write wrapped encrypted data into.
8915
 * @param [out] outSz       Length of encrypted data in bytes.
8916
 * @param [in]  password    Password used to create encryption key.
8917
 * @param [in]  passwordSz  Length of password in bytes.
8918
 * @param [in]  vPKCS       First byte used to determine PBE algorithm.
8919
 * @param [in]  vAlgo       Second byte used to determine PBE algorithm.
8920
 * @param [in]  salt        Salt to use with KDF.
8921
 * @param [in]  saltSz      Length of salt in bytes.
8922
 * @param [in]  itt         Number of iterations to use in KDF.
8923
 * @param [in]  rng         Random number generator to use to generate salt.
8924
 * @param [in]  heap        Dynamic memory allocator hint.
8925
 * @return  The size of encrypted data on success
8926
 * @return  LENGTH_ONLY_E when out is NULL and able to encode.
8927
 * @return  ASN_PARSE_E when the salt size is too large.
8928
 * @return  ASN_VERSION_E when attempting to use a PBES2 algorithm (use
8929
 *          TraditionalEnc).
8930
 * @return  MEMORY_E when dynamic memory allocation fails.
8931
 * @return  Other when encryption or random number generation fails.
8932
 */
8933
int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz,
8934
        const char* password, int passwordSz, int vPKCS, int vAlgo,
8935
        byte* salt, word32 saltSz, int itt, WC_RNG* rng, void* heap)
8936
0
{
8937
#ifndef WOLFSSL_ASN_TEMPLATE
8938
    word32 sz;
8939
    word32 inOutIdx = 0;
8940
    word32 tmpIdx   = 0;
8941
    word32 totalSz  = 0;
8942
    word32 seqSz;
8943
    word32 innerSz;
8944
    int    ret;
8945
    int    version, id, blockSz = 0;
8946
#ifdef WOLFSSL_SMALL_STACK
8947
    byte*  saltTmp = NULL;
8948
    byte*  cbcIv   = NULL;
8949
#else
8950
    byte   saltTmp[MAX_SALT_SIZE];
8951
    byte   cbcIv[MAX_IV_SIZE];
8952
#endif
8953
    byte   seq[MAX_SEQ_SZ];
8954
    byte   shr[MAX_SHORT_SZ];
8955
    word32 maxShr = MAX_SHORT_SZ;
8956
    word32 algoSz;
8957
    const  byte* algoName;
8958
8959
    (void)heap;
8960
8961
    WOLFSSL_ENTER("EncryptContent");
8962
8963
    if (CheckAlgo(vPKCS, vAlgo, &id, &version, &blockSz) < 0)
8964
        return ASN_INPUT_E;  /* Algo ID error */
8965
8966
    if (version == PKCS5v2) {
8967
        WOLFSSL_MSG("PKCS#5 version 2 not supported yet");
8968
        return BAD_FUNC_ARG;
8969
    }
8970
8971
    if (saltSz > MAX_SALT_SIZE)
8972
        return ASN_PARSE_E;
8973
8974
    if (outSz == NULL) {
8975
        return BAD_FUNC_ARG;
8976
    }
8977
8978
    /* calculate size */
8979
    /* size of constructed string at end */
8980
    sz = (word32)Pkcs8Pad(NULL, (int)inputSz, blockSz);
8981
    totalSz  = ASN_TAG_SZ;
8982
    totalSz += SetLength(sz, seq);
8983
    totalSz += sz;
8984
8985
    /* size of sequence holding object id and sub sequence of salt and itt */
8986
    algoName = OidFromId((word32)id, oidPBEType, &algoSz);
8987
    if (algoName == NULL) {
8988
        WOLFSSL_MSG("Unknown Algorithm");
8989
        return 0;
8990
    }
8991
    innerSz = (word32)SetObjectId((int)algoSz, seq);
8992
    innerSz += algoSz;
8993
8994
    /* get subsequence of salt and itt */
8995
    if (salt == NULL || saltSz == 0) {
8996
        sz = 8;
8997
    }
8998
    else {
8999
        sz = saltSz;
9000
    }
9001
    seqSz  = SetOctetString(sz, seq);
9002
    seqSz += sz;
9003
9004
    tmpIdx = 0;
9005
    ret = SetShortInt(shr, &tmpIdx, (word32)itt, maxShr);
9006
    if (ret >= 0) {
9007
        seqSz += (word32)ret;
9008
    }
9009
    else {
9010
        return ret;
9011
    }
9012
    innerSz += seqSz + SetSequence(seqSz, seq);
9013
    totalSz += innerSz + SetSequence(innerSz, seq);
9014
9015
    if (out == NULL) {
9016
        *outSz = totalSz;
9017
        return LENGTH_ONLY_E;
9018
    }
9019
9020
    inOutIdx = 0;
9021
    if (totalSz > *outSz)
9022
        return BUFFER_E;
9023
9024
    inOutIdx += SetSequence(innerSz, out + inOutIdx);
9025
    inOutIdx += (word32)SetObjectId((int)algoSz, out + inOutIdx);
9026
    XMEMCPY(out + inOutIdx, algoName, algoSz);
9027
    inOutIdx += algoSz;
9028
    inOutIdx += SetSequence(seqSz, out + inOutIdx);
9029
9030
    /* create random salt if one not provided */
9031
    if (salt == NULL || saltSz == 0) {
9032
        saltSz = 8;
9033
    #ifdef WOLFSSL_SMALL_STACK
9034
        saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
9035
        if (saltTmp == NULL)
9036
            return MEMORY_E;
9037
    #endif
9038
        salt = saltTmp;
9039
9040
        if ((ret = wc_RNG_GenerateBlock(rng, saltTmp, saltSz)) != 0) {
9041
            WOLFSSL_MSG("Error generating random salt");
9042
        #ifdef WOLFSSL_SMALL_STACK
9043
            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
9044
        #endif
9045
            return ret;
9046
        }
9047
    }
9048
    inOutIdx += SetOctetString(saltSz, out + inOutIdx);
9049
    if (saltSz + inOutIdx > *outSz) {
9050
    #ifdef WOLFSSL_SMALL_STACK
9051
        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
9052
    #endif
9053
        return BUFFER_E;
9054
    }
9055
    XMEMCPY(out + inOutIdx, salt, saltSz);
9056
    inOutIdx += saltSz;
9057
9058
    /* place iteration setting in buffer */
9059
    ret = SetShortInt(out, &inOutIdx, (word32)itt, *outSz);
9060
    if (ret < 0) {
9061
    #ifdef WOLFSSL_SMALL_STACK
9062
        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
9063
    #endif
9064
        return ret;
9065
    }
9066
9067
    if (inOutIdx + 1 > *outSz) {
9068
    #ifdef WOLFSSL_SMALL_STACK
9069
        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
9070
    #endif
9071
        return BUFFER_E;
9072
    }
9073
    out[inOutIdx++] = ASN_CONTEXT_SPECIFIC | 0;
9074
9075
    /* get pad size and verify buffer room */
9076
    sz = (word32)Pkcs8Pad(NULL, (int)inputSz, blockSz);
9077
    if (sz + inOutIdx > *outSz) {
9078
    #ifdef WOLFSSL_SMALL_STACK
9079
        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
9080
    #endif
9081
        return BUFFER_E;
9082
    }
9083
    inOutIdx += SetLength(sz, out + inOutIdx);
9084
9085
    /* copy input to output buffer and pad end */
9086
    XMEMCPY(out + inOutIdx, input, inputSz);
9087
    sz = (word32)Pkcs8Pad(out + inOutIdx, (int)inputSz, blockSz);
9088
#ifdef WOLFSSL_SMALL_STACK
9089
    cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
9090
    if (cbcIv == NULL) {
9091
        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
9092
        return MEMORY_E;
9093
    }
9094
#endif
9095
9096
    /* encrypt */
9097
    if ((ret = wc_CryptKey(password, passwordSz, salt, (int)saltSz, itt, id,
9098
                   out + inOutIdx, (int)sz, version, cbcIv, 1, 0)) < 0) {
9099
9100
    #ifdef WOLFSSL_SMALL_STACK
9101
        XFREE(cbcIv,   heap, DYNAMIC_TYPE_TMP_BUFFER);
9102
        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
9103
    #endif
9104
        return ret;  /* encrypt failure */
9105
    }
9106
9107
#ifdef WOLFSSL_SMALL_STACK
9108
    XFREE(cbcIv,   heap, DYNAMIC_TYPE_TMP_BUFFER);
9109
    XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
9110
#endif
9111
9112
    (void)rng;
9113
9114
    return (int)(inOutIdx + sz);
9115
#else
9116
0
    DECL_ASNSETDATA(dataASN, p8EncPbes1ASN_Length);
9117
0
    int ret = 0;
9118
0
    int sz = 0;
9119
0
    int version = 0;
9120
0
    int id = -1;
9121
0
    int blockSz = 0;
9122
0
    word32 pkcs8Sz = 0;
9123
9124
0
    (void)heap;
9125
9126
0
    WOLFSSL_ENTER("EncryptContent");
9127
9128
    /* Must have a output size to return or check. */
9129
0
    if (outSz == NULL) {
9130
0
        ret = BAD_FUNC_ARG;
9131
0
    }
9132
    /* Check salt size is valid. */
9133
0
    if ((ret == 0) && (saltSz > MAX_SALT_SIZE)) {
9134
0
        ret = ASN_PARSE_E;
9135
0
    }
9136
    /* Get algorithm parameters for algorithm identifier. */
9137
0
    if ((ret == 0) && CheckAlgo(vPKCS, vAlgo, &id, &version, &blockSz) < 0) {
9138
0
        ret = ASN_INPUT_E;
9139
0
    }
9140
    /* Check PKCS #5 version - only PBSE1 parameters supported. */
9141
0
    if ((ret == 0) && (version == PKCS5v2)) {
9142
0
        ret = BAD_FUNC_ARG;
9143
0
    }
9144
9145
0
    CALLOC_ASNSETDATA(dataASN, p8EncPbes1ASN_Length, ret, heap);
9146
9147
0
    if (ret == 0) {
9148
        /* Setup data to go into encoding including PBE algorithm, salt,
9149
         * iteration count, and padded key length. */
9150
0
        SetASN_OID(&dataASN[P8ENCPBES1ASN_IDX_ENCALGO_OID], (word32)id,
9151
0
                   oidPBEType);
9152
0
        if (salt == NULL || saltSz == 0) {
9153
0
            salt = NULL;
9154
0
            saltSz = PKCS5_SALT_SZ;
9155
            /* Salt generated into encoding below. */
9156
0
        }
9157
0
        SetASN_Buffer(&dataASN[P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_SALT],
9158
0
                salt, saltSz);
9159
0
        SetASN_Int16Bit(&dataASN[P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_ITER],
9160
0
                        (word16)itt);
9161
0
        pkcs8Sz = (word32)Pkcs8Pad(NULL, (int)inputSz, blockSz);
9162
0
        SetASN_Buffer(&dataASN[P8ENCPBES1ASN_IDX_ENCDATA], NULL, pkcs8Sz);
9163
9164
        /* Calculate size of encoding. */
9165
0
        ret = SizeASN_Items(p8EncPbes1ASN + P8ENCPBES1ASN_IDX_ENCALGO_SEQ,
9166
0
                dataASN + P8ENCPBES1ASN_IDX_ENCALGO_SEQ,
9167
0
                (int)(p8EncPbes1ASN_Length - P8ENCPBES1ASN_IDX_ENCALGO_SEQ),
9168
0
                &sz);
9169
0
    }
9170
    /* Return size when no output buffer. */
9171
0
    if ((ret == 0) && (out == NULL)) {
9172
0
        *outSz = (word32)sz;
9173
0
        ret = LENGTH_ONLY_E;
9174
0
    }
9175
    /* Check output buffer is big enough for encoded data. */
9176
0
    if ((ret == 0) && (sz > (int)*outSz)) {
9177
0
        ret = BAD_FUNC_ARG;
9178
0
    }
9179
0
    if (ret == 0) {
9180
        /* Encode PKCS#8 key. */
9181
0
        SetASN_Items(p8EncPbes1ASN + P8ENCPBES1ASN_IDX_ENCALGO_SEQ,
9182
0
                 dataASN + P8ENCPBES1ASN_IDX_ENCALGO_SEQ,
9183
0
                 (int)(p8EncPbes1ASN_Length - P8ENCPBES1ASN_IDX_ENCALGO_SEQ),
9184
0
                 out);
9185
9186
0
        if (salt == NULL) {
9187
            /* Generate salt into encoding. */
9188
0
            salt = (byte*)dataASN[P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_SALT].
9189
0
                data.buffer.data;
9190
0
            ret = wc_RNG_GenerateBlock(rng, salt, saltSz);
9191
0
        }
9192
0
    }
9193
0
    if (ret == 0) {
9194
0
        byte cbcIv[MAX_IV_SIZE];
9195
        /* Store PKCS#8 key in output buffer. */
9196
0
        byte* pkcs8 =
9197
0
            (byte*)dataASN[P8ENCPBES1ASN_IDX_ENCDATA].data.buffer.data;
9198
0
        XMEMCPY(pkcs8, input, inputSz);
9199
0
        Pkcs8Pad(pkcs8, (int)inputSz, blockSz);
9200
9201
        /* Encrypt PKCS#8 key inline. */
9202
0
        ret = wc_CryptKey(password, passwordSz, salt, (int)saltSz, itt, id,
9203
0
                          pkcs8, (int)pkcs8Sz, version, cbcIv, 1, 0);
9204
0
    }
9205
0
    if (ret == 0) {
9206
        /* Returning size on success. */
9207
0
        ret = sz;
9208
0
    }
9209
9210
0
    FREE_ASNSETDATA(dataASN, heap);
9211
0
    return ret;
9212
0
#endif /* WOLFSSL_ASN_TEMPLATE */
9213
0
}
9214
9215
9216
#endif /* HAVE_PKCS12 */
9217
#endif /* NO_PWDBASED */
9218
9219
#ifndef NO_RSA
9220
9221
#ifndef HAVE_USER_RSA
9222
#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT)
9223
/* This function is to retrieve key position information in a cert.*
9224
 * The information will be used to call TSIP TLS-linked API for    *
9225
 * certificate verification.                                       */
9226
static int RsaPublicKeyDecodeRawIndex(const byte* input, word32* inOutIdx,
9227
                                      word32 inSz, word32* key_n,
9228
                                      word32* key_n_len, word32* key_e,
9229
                                      word32* key_e_len)
9230
{
9231
9232
    int ret = 0;
9233
    int length = 0;
9234
#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
9235
    byte b;
9236
#endif
9237
9238
    if (input == NULL || inOutIdx == NULL)
9239
        return BAD_FUNC_ARG;
9240
9241
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
9242
        return ASN_PARSE_E;
9243
9244
#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
9245
    if ((*inOutIdx + 1) > inSz)
9246
        return BUFFER_E;
9247
9248
    b = input[*inOutIdx];
9249
    if (b != ASN_INTEGER) {
9250
        /* not from decoded cert, will have algo id, skip past */
9251
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
9252
            return ASN_PARSE_E;
9253
9254
        if (SkipObjectId(input, inOutIdx, inSz) < 0)
9255
            return ASN_PARSE_E;
9256
9257
        /* Option NULL ASN.1 tag */
9258
        if (*inOutIdx  >= inSz) {
9259
            return BUFFER_E;
9260
        }
9261
        if (input[*inOutIdx] == ASN_TAG_NULL) {
9262
            ret = GetASNNull(input, inOutIdx, inSz);
9263
            if (ret != 0)
9264
                return ret;
9265
        }
9266
        /* TODO: support RSA PSS */
9267
9268
        /* should have bit tag length and seq next */
9269
        ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);
9270
        if (ret != 0)
9271
            return ret;
9272
9273
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
9274
            return ASN_PARSE_E;
9275
    }
9276
#endif /* OPENSSL_EXTRA */
9277
9278
    /* Get modulus */
9279
    ret = GetASNInt(input, inOutIdx, &length, inSz);
9280
    *key_n += *inOutIdx;
9281
    if (ret < 0) {
9282
        return ASN_RSA_KEY_E;
9283
    }
9284
    if (key_n_len)
9285
        *key_n_len = length;
9286
    *inOutIdx += length;
9287
9288
    /* Get exponent */
9289
    ret = GetASNInt(input, inOutIdx, &length, inSz);
9290
    *key_e += *inOutIdx;
9291
    if (ret < 0) {
9292
        return ASN_RSA_KEY_E;
9293
    }
9294
    if (key_e_len)
9295
        *key_e_len = length;
9296
9297
    return ret;
9298
}
9299
#endif /* WOLFSSL_RENESAS_TSIP */
9300
9301
#ifdef WOLFSSL_ASN_TEMPLATE
9302
/* ASN.1 template for an RSA public key.
9303
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
9304
 * PKCS #1: RFC 8017, A.1.1 - RSAPublicKey
9305
 */
9306
static const ASNItem rsaPublicKeyASN[] = {
9307
/*  SEQ            */ { 0, ASN_SEQUENCE, 1, 1, 0 },
9308
/*  ALGOID_SEQ     */     { 1, ASN_SEQUENCE, 1, 1, 0 },
9309
/*  ALGOID_OID     */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
9310
/*  ALGOID_NULL    */         { 2, ASN_TAG_NULL, 0, 0, 1 },
9311
#ifdef WC_RSA_PSS
9312
/*  ALGOID_P_SEQ   */         { 2, ASN_SEQUENCE, 1, 0, 1 },
9313
#endif
9314
/*  PUBKEY         */     { 1, ASN_BIT_STRING, 0, 1, 0 },
9315
                                                  /* RSAPublicKey */
9316
/*  PUBKEY_RSA_SEQ */         { 2, ASN_SEQUENCE, 1, 1, 0 },
9317
/*  PUBKEY_RSA_N   */             { 3, ASN_INTEGER, 0, 0, 0 },
9318
/*  PUBKEY_RSA_E   */             { 3, ASN_INTEGER, 0, 0, 0 },
9319
};
9320
enum {
9321
    RSAPUBLICKEYASN_IDX_SEQ = 0,
9322
    RSAPUBLICKEYASN_IDX_ALGOID_SEQ,
9323
    RSAPUBLICKEYASN_IDX_ALGOID_OID,
9324
    RSAPUBLICKEYASN_IDX_ALGOID_NULL,
9325
#ifdef WC_RSA_PSS
9326
    RSAPUBLICKEYASN_IDX_ALGOID_P_SEQ,
9327
#endif
9328
    RSAPUBLICKEYASN_IDX_PUBKEY,
9329
    RSAPUBLICKEYASN_IDX_PUBKEY_RSA_SEQ,
9330
    RSAPUBLICKEYASN_IDX_PUBKEY_RSA_N,
9331
    RSAPUBLICKEYASN_IDX_PUBKEY_RSA_E
9332
};
9333
9334
/* Number of items in ASN.1 template for an RSA public key. */
9335
0
#define rsaPublicKeyASN_Length (sizeof(rsaPublicKeyASN) / sizeof(ASNItem))
9336
#endif
9337
9338
/* Decode RSA public key.
9339
 *
9340
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
9341
 * PKCS #1: RFC 8017, A.1.1 - RSAPublicKey
9342
 *
9343
 * @param [in]      input     Buffer holding BER encoded data.
9344
 * @param [in, out] inOutIdx  On in, start of RSA public key.
9345
 *                            On out, start of ASN.1 item after RSA public key.
9346
 * @param [in]      inSz      Number of bytes in buffer.
9347
 * @param [out]     n         Pointer to modulus in buffer.
9348
 * @param [out]     nSz       Size of modulus in bytes.
9349
 * @param [out]     e         Pointer to exponent in buffer.
9350
 * @param [out]     eSz       Size of exponent in bytes.
9351
 * @return  0 on success.
9352
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
9353
 *          is invalid.
9354
 * @return  BUFFER_E when data in buffer is too small.
9355
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
9356
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
9357
 *          non-zero length.
9358
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
9359
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
9360
 */
9361
int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx, word32 inSz,
9362
    const byte** n, word32* nSz, const byte** e, word32* eSz)
9363
0
{
9364
#ifndef WOLFSSL_ASN_TEMPLATE
9365
    int ret = 0;
9366
    int length = 0;
9367
#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
9368
    word32 localIdx;
9369
    byte   tag;
9370
#endif
9371
9372
    if (input == NULL || inOutIdx == NULL)
9373
        return BAD_FUNC_ARG;
9374
9375
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
9376
        return ASN_PARSE_E;
9377
9378
#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
9379
    localIdx = *inOutIdx;
9380
    if (GetASNTag(input, &localIdx, &tag, inSz) < 0)
9381
        return BUFFER_E;
9382
9383
    if (tag != ASN_INTEGER) {
9384
        /* not from decoded cert, will have algo id, skip past */
9385
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
9386
            return ASN_PARSE_E;
9387
9388
        if (SkipObjectId(input, inOutIdx, inSz) < 0)
9389
            return ASN_PARSE_E;
9390
9391
        /* Option NULL ASN.1 tag */
9392
        if (*inOutIdx  >= inSz) {
9393
            return BUFFER_E;
9394
        }
9395
9396
        localIdx = *inOutIdx;
9397
        if (GetASNTag(input, &localIdx, &tag, inSz) < 0)
9398
            return ASN_PARSE_E;
9399
9400
        if (tag == ASN_TAG_NULL) {
9401
            ret = GetASNNull(input, inOutIdx, inSz);
9402
            if (ret != 0)
9403
                return ret;
9404
        }
9405
    #ifdef WC_RSA_PSS
9406
        /* Skip RSA PSS parameters. */
9407
        else if (tag == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
9408
            if (GetSequence(input, inOutIdx, &length, inSz) < 0)
9409
                return ASN_PARSE_E;
9410
            *inOutIdx += length;
9411
        }
9412
    #endif
9413
9414
        /* should have bit tag length and seq next */
9415
        ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);
9416
        if (ret != 0)
9417
            return ret;
9418
9419
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
9420
            return ASN_PARSE_E;
9421
    }
9422
#endif /* OPENSSL_EXTRA */
9423
9424
    /* Get modulus */
9425
    ret = GetASNInt(input, inOutIdx, &length, inSz);
9426
    if (ret < 0) {
9427
        return ASN_RSA_KEY_E;
9428
    }
9429
    if (nSz)
9430
        *nSz = (word32)length;
9431
    if (n)
9432
        *n = &input[*inOutIdx];
9433
    *inOutIdx += (word32)length;
9434
9435
    /* Get exponent */
9436
    ret = GetASNInt(input, inOutIdx, &length, inSz);
9437
    if (ret < 0) {
9438
        return ASN_RSA_KEY_E;
9439
    }
9440
    if (eSz)
9441
        *eSz = (word32)length;
9442
    if (e)
9443
        *e = &input[*inOutIdx];
9444
    *inOutIdx += (word32)length;
9445
9446
    return ret;
9447
#else
9448
0
    DECL_ASNGETDATA(dataASN, rsaPublicKeyASN_Length);
9449
0
    int ret = 0;
9450
0
#ifdef WC_RSA_PSS
9451
0
    word32 oid = RSAk;
9452
0
#endif
9453
9454
    /* Check validity of parameters. */
9455
0
    if (input == NULL || inOutIdx == NULL) {
9456
0
        ret = BAD_FUNC_ARG;
9457
0
    }
9458
9459
0
    CALLOC_ASNGETDATA(dataASN, rsaPublicKeyASN_Length, ret, NULL);
9460
9461
0
    if (ret == 0) {
9462
        /* Try decoding PKCS #1 public key by ignoring rest of ASN.1. */
9463
0
        ret = GetASN_Items(&rsaPublicKeyASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_SEQ],
9464
0
           &dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_SEQ],
9465
0
           (int)(rsaPublicKeyASN_Length - RSAPUBLICKEYASN_IDX_PUBKEY_RSA_SEQ),
9466
0
           0, input, inOutIdx, inSz);
9467
0
        if (ret != 0) {
9468
            /* Didn't work - try whole SubjectKeyInfo instead. */
9469
0
        #ifdef WC_RSA_PSS
9470
            /* Could be RSA or RSA PSS key. */
9471
0
            GetASN_OID(&dataASN[RSAPUBLICKEYASN_IDX_ALGOID_OID], oidKeyType);
9472
        #else
9473
            /* Set the OID to expect. */
9474
            GetASN_ExpBuffer(&dataASN[RSAPUBLICKEYASN_IDX_ALGOID_OID],
9475
                    keyRsaOid, sizeof(keyRsaOid));
9476
        #endif
9477
            /* Decode SubjectKeyInfo. */
9478
0
            ret = GetASN_Items(rsaPublicKeyASN, dataASN,
9479
0
                               rsaPublicKeyASN_Length, 1, input, inOutIdx,
9480
0
                               inSz);
9481
0
        }
9482
0
    }
9483
0
#ifdef WC_RSA_PSS
9484
0
    if ((ret == 0) && (dataASN[RSAPUBLICKEYASN_IDX_ALGOID_OID].tag != 0)) {
9485
        /* Two possible OIDs supported - RSA and RSA PSS. */
9486
0
        oid = dataASN[RSAPUBLICKEYASN_IDX_ALGOID_OID].data.oid.sum;
9487
0
        if ((oid != RSAk) && (oid != RSAPSSk)) {
9488
0
            ret = ASN_PARSE_E;
9489
0
        }
9490
0
    }
9491
0
    if ((ret == 0) && (dataASN[RSAPUBLICKEYASN_IDX_ALGOID_P_SEQ].tag != 0)) {
9492
        /* Can't have NULL and SEQ. */
9493
0
        if (dataASN[RSAPUBLICKEYASN_IDX_ALGOID_NULL].tag != 0) {
9494
0
            ret = ASN_PARSE_E;
9495
0
        }
9496
        /* SEQ present only with RSA PSS. */
9497
0
        if ((ret == 0) && (oid != RSAPSSk)) {
9498
0
            ret = ASN_PARSE_E;
9499
0
        }
9500
0
        if (ret == 0) {
9501
0
            enum wc_HashType hash;
9502
0
            int mgf;
9503
0
            int saltLen;
9504
0
            const byte* params = GetASNItem_Addr(
9505
0
                dataASN[RSAPUBLICKEYASN_IDX_ALGOID_P_SEQ], input);
9506
0
            word32 paramsSz = GetASNItem_Length(
9507
0
                dataASN[RSAPUBLICKEYASN_IDX_ALGOID_P_SEQ], input);
9508
9509
            /* Validate the private key parameters. */
9510
0
            ret = DecodeRsaPssParams(params, paramsSz, &hash, &mgf, &saltLen);
9511
            /* TODO: store parameters so that usage can be checked. */
9512
0
        }
9513
0
    }
9514
0
#endif
9515
0
    if (ret == 0) {
9516
        /* Return the buffers and lengths asked for. */
9517
0
        if (n != NULL) {
9518
0
            *n   = dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_N].data.ref.data;
9519
0
        }
9520
0
        if (nSz != NULL) {
9521
0
            *nSz = dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_N].data.ref.length;
9522
0
        }
9523
0
        if (e != NULL) {
9524
0
            *e   = dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_E].data.ref.data;
9525
0
        }
9526
0
        if (eSz != NULL) {
9527
0
            *eSz = dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_E].data.ref.length;
9528
0
        }
9529
0
    }
9530
9531
0
    FREE_ASNGETDATA(dataASN, NULL);
9532
0
    return ret;
9533
0
#endif /* WOLFSSL_ASN_TEMPLATE */
9534
0
}
9535
9536
/* Decode RSA public key.
9537
 *
9538
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
9539
 * PKCS #1: RFC 8017, A.1.1 - RSAPublicKey
9540
 *
9541
 * @param [in]      input     Buffer holding BER encoded data.
9542
 * @param [in, out] inOutIdx  On in, start of RSA public key.
9543
 *                            On out, start of ASN.1 item after RSA public key.
9544
 * @param [in, out] key       RSA key object.
9545
 * @param [in]      inSz      Number of bytes in buffer.
9546
 * @return  0 on success.
9547
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
9548
 *          is invalid.
9549
 * @return  BUFFER_E when data in buffer is too small.
9550
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
9551
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
9552
 *          non-zero length.
9553
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
9554
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
9555
 */
9556
int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
9557
                       word32 inSz)
9558
0
{
9559
0
    int ret;
9560
0
    const byte *n = NULL, *e = NULL;
9561
0
    word32 nSz = 0, eSz = 0;
9562
9563
0
    if (key == NULL)
9564
0
        return BAD_FUNC_ARG;
9565
9566
0
    ret = wc_RsaPublicKeyDecode_ex(input, inOutIdx, inSz, &n, &nSz, &e, &eSz);
9567
0
    if (ret == 0) {
9568
0
        ret = wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz, key);
9569
0
    }
9570
9571
0
    return ret;
9572
0
}
9573
#endif /* HAVE_USER_RSA */
9574
#endif /* !NO_RSA */
9575
9576
#ifndef NO_DH
9577
#if defined(WOLFSSL_DH_EXTRA)
9578
/*
9579
 * Decodes DH public key to fill specified DhKey.
9580
 *
9581
 * return 0 on success, negative on failure
9582
 */
9583
int wc_DhPublicKeyDecode(const byte* input, word32* inOutIdx,
9584
                DhKey* key, word32 inSz)
9585
{
9586
    int ret = 0;
9587
    int length;
9588
    word32 oid = 0;
9589
9590
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
9591
        return BAD_FUNC_ARG;
9592
9593
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
9594
        return ASN_PARSE_E;
9595
9596
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
9597
        return ASN_PARSE_E;
9598
9599
    ret = GetObjectId(input, inOutIdx, &oid, oidKeyType, inSz);
9600
    if (oid != DHk || ret < 0)
9601
        return ASN_DH_KEY_E;
9602
9603
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
9604
        return ASN_PARSE_E;
9605
9606
    if (GetInt(&key->p, input, inOutIdx, inSz) < 0)
9607
        return ASN_DH_KEY_E;
9608
9609
    if (GetInt(&key->g, input, inOutIdx, inSz) < 0) {
9610
        mp_clear(&key->p);
9611
        return ASN_DH_KEY_E;
9612
    }
9613
    ret = (CheckBitString(input, inOutIdx, &length, inSz, 0, NULL) == 0);
9614
    if (ret > 0) {
9615
        /* Found Bit String WOLFSSL_DH_EXTRA is required to access DhKey.pub */
9616
        if (GetInt(&key->pub, input, inOutIdx, inSz) < 0) {
9617
            mp_clear(&key->p);
9618
            mp_clear(&key->g);
9619
            return ASN_DH_KEY_E;
9620
        }
9621
    }
9622
    else {
9623
        mp_clear(&key->p);
9624
        mp_clear(&key->g);
9625
        return ASN_DH_KEY_E;
9626
    }
9627
    return 0;
9628
}
9629
#endif /* WOLFSSL_DH_EXTRA */
9630
9631
#ifdef WOLFSSL_ASN_TEMPLATE
9632
/* ASN.1 template for DH key.
9633
 * PKCS #3, 9 - DHParameter.
9634
 * (Also in: RFC 2786, 3)
9635
 */
9636
static const ASNItem dhParamASN[] = {
9637
/* SEQ     */    { 0, ASN_SEQUENCE, 1, 1, 0 },
9638
                /* prime */
9639
/* PRIME   */        { 1, ASN_INTEGER, 0, 0, 0 },
9640
                /* base */
9641
/* BASE    */        { 1, ASN_INTEGER, 0, 0, 0 },
9642
                /* privateValueLength */
9643
/* PRIVLEN */        { 1, ASN_INTEGER, 0, 0, 1 },
9644
};
9645
enum {
9646
    DHPARAMASN_IDX_SEQ = 0,
9647
    DHPARAMASN_IDX_PRIME,
9648
    DHPARAMASN_IDX_BASE,
9649
    DHPARAMASN_IDX_PRIVLEN
9650
};
9651
9652
/* Number of items in ASN.1 template for DH key. */
9653
0
#define dhParamASN_Length (sizeof(dhParamASN) / sizeof(ASNItem))
9654
9655
#ifdef WOLFSSL_DH_EXTRA
9656
/* ASN.1 template for DH key wrapped in PKCS #8 or SubjectPublicKeyInfo.
9657
 * PKCS #8: RFC 5208, 5 - PrivateKeyInfo
9658
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
9659
 * RFC 3279, 2.3.3 - DH in SubjectPublicKeyInfo
9660
 */
9661
static const ASNItem dhKeyPkcs8ASN[] = {
9662
/* SEQ                  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
9663
/* VER                  */     { 1, ASN_INTEGER, 0, 0, 1 },
9664
/* PKEYALGO_SEQ         */     { 1, ASN_SEQUENCE, 1, 1, 0 },
9665
/* PKEYALGO_OID         */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
9666
                                                     /* DHParameter */
9667
/* PKEYALGO_PARAM_SEQ   */         { 2, ASN_SEQUENCE, 1, 1, 0 },
9668
                                                         /* p */
9669
/* PKEYALGO_PARAM_P     */             { 3, ASN_INTEGER, 0, 0, 0 },
9670
                                                         /* g */
9671
/* PKEYALGO_PARAM_G     */             { 3, ASN_INTEGER, 0, 0, 0 },
9672
                                                         /* q - factor of p-1 */
9673
/* PKEYALGO_PARAM_Q     */             { 3, ASN_INTEGER, 0, 0, 1 },
9674
                                                         /* j - subgroup factor */
9675
/* PKEYALGO_PARAM_J     */             { 3, ASN_INTEGER, 0, 0, 1 },
9676
                                                         /* ValidationParms */
9677
/* PKEYALGO_PARAM_VALID */             { 3, ASN_SEQUENCE, 0, 0, 1 },
9678
                                                 /* PrivateKey - PKCS #8 */
9679
/* PKEY_STR             */     { 1, ASN_OCTET_STRING, 0, 1, 2 },
9680
/* PKEY_INT             */         { 2, ASN_INTEGER, 0, 0, 0 },
9681
                                                 /* PublicKey - SubjectPublicKeyInfo. */
9682
/* PUBKEY_STR           */     { 1, ASN_BIT_STRING, 0, 1, 2 },
9683
/* PUBKEY_INT           */         { 2, ASN_INTEGER, 0, 0, 0 },
9684
};
9685
enum {
9686
    DHKEYPKCS8ASN_IDX_SEQ = 0,
9687
    DHKEYPKCS8ASN_IDX_VER,
9688
    DHKEYPKCS8ASN_IDX_PKEYALGO_SEQ,
9689
    DHKEYPKCS8ASN_IDX_PKEYALGO_OID,
9690
    DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_SEQ,
9691
    DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_P,
9692
    DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_G,
9693
    DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_Q,
9694
    DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_J,
9695
    DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_VALID,
9696
    DHKEYPKCS8ASN_IDX_PKEY_STR,
9697
    DHKEYPKCS8ASN_IDX_PKEY_INT,
9698
    DHKEYPKCS8ASN_IDX_PUBKEY_STR,
9699
    DHKEYPKCS8ASN_IDX_PUBKEY_INT
9700
};
9701
9702
#define dhKeyPkcs8ASN_Length (sizeof(dhKeyPkcs8ASN) / sizeof(ASNItem))
9703
#endif
9704
#endif
9705
9706
/* Decodes either PKCS#3 DH parameters or PKCS#8 DH key file (WOLFSSL_DH_EXTRA).
9707
 *
9708
 * See also wc_DhParamsLoad(). Loads directly into buffers rather than key
9709
 * object.
9710
 *
9711
 * @param [in]      input     BER/DER encoded data.
9712
 * @param [in, out] inOutIdx  On in, start of DH key data.
9713
 *                            On out, end of DH key data.
9714
 * @param [in, out] key       DH key object.
9715
 * @param [in]      inSz      Size of data in bytes.
9716
 * @return  0 on success.
9717
 * @return  BAD_FUNC_ARG when input, inOutIDx or key is NULL.
9718
 * @return  MEMORY_E when dynamic memory allocation fails.
9719
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
9720
 *          is invalid.
9721
 * @return  BUFFER_E when data in buffer is too small.
9722
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
9723
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
9724
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
9725
 *          non-zero length.
9726
 * @return  MP_INIT_E when the unable to initialize an mp_int.
9727
 * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
9728
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
9729
 */
9730
int wc_DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32 inSz)
9731
0
{
9732
#ifndef WOLFSSL_ASN_TEMPLATE
9733
    int ret = 0;
9734
    int length;
9735
#ifdef WOLFSSL_DH_EXTRA
9736
    #if !defined(HAVE_FIPS) || \
9737
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
9738
    word32 oid = 0, temp = 0;
9739
    #endif
9740
#endif
9741
9742
    WOLFSSL_ENTER("wc_DhKeyDecode");
9743
9744
    if (inOutIdx == NULL)
9745
        return BAD_FUNC_ARG;
9746
9747
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
9748
        return ASN_PARSE_E;
9749
9750
#ifdef WOLFSSL_DH_EXTRA
9751
    #if !defined(HAVE_FIPS) || \
9752
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
9753
    temp = *inOutIdx;
9754
    #endif
9755
#endif
9756
    /* Assume input started after 1.2.840.113549.1.3.1 dhKeyAgreement */
9757
    if (GetInt(&key->p, input, inOutIdx, inSz) < 0) {
9758
        ret = ASN_DH_KEY_E;
9759
    }
9760
    if (ret == 0 && GetInt(&key->g, input, inOutIdx, inSz) < 0) {
9761
        mp_clear(&key->p);
9762
        ret = ASN_DH_KEY_E;
9763
    }
9764
9765
#ifdef WOLFSSL_DH_EXTRA
9766
    #if !defined(HAVE_FIPS) || \
9767
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
9768
    /* If ASN_DH_KEY_E: Check if input started at beginning of key */
9769
    if (ret == ASN_DH_KEY_E) {
9770
        *inOutIdx = temp;
9771
9772
        /* the version (0) - private only (for public skip) */
9773
        if (GetASNInt(input, inOutIdx, &length, inSz) == 0) {
9774
            *inOutIdx += (word32)length;
9775
        }
9776
9777
        /* Size of dhKeyAgreement section */
9778
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
9779
            return ASN_PARSE_E;
9780
9781
        /* Check for dhKeyAgreement */
9782
        ret = GetObjectId(input, inOutIdx, &oid, oidKeyType, inSz);
9783
        if (oid != DHk || ret < 0)
9784
            return ASN_DH_KEY_E;
9785
9786
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
9787
            return ASN_PARSE_E;
9788
9789
        if (GetInt(&key->p, input, inOutIdx, inSz) < 0) {
9790
            return ASN_DH_KEY_E;
9791
        }
9792
        if (ret == 0 && GetInt(&key->g, input, inOutIdx, inSz) < 0) {
9793
            mp_clear(&key->p);
9794
            return ASN_DH_KEY_E;
9795
        }
9796
    }
9797
9798
    temp = *inOutIdx;
9799
    ret = (CheckBitString(input, inOutIdx, &length, inSz, 0, NULL) == 0);
9800
    if (ret > 0) {
9801
        /* Found Bit String */
9802
        if (GetInt(&key->pub, input, inOutIdx, inSz) == 0) {
9803
            WOLFSSL_MSG("Found Public Key");
9804
            ret = 0;
9805
        }
9806
    } else {
9807
        *inOutIdx = temp;
9808
        ret = (GetOctetString(input, inOutIdx, &length, inSz) >= 0);
9809
        if (ret > 0) {
9810
            /* Found Octet String */
9811
            if (GetInt(&key->priv, input, inOutIdx, inSz) == 0) {
9812
                WOLFSSL_MSG("Found Private Key");
9813
9814
                /* Compute public */
9815
                ret = mp_exptmod(&key->g, &key->priv, &key->p, &key->pub);
9816
            }
9817
        } else {
9818
            /* Don't use length from failed CheckBitString/GetOctetString */
9819
            *inOutIdx = temp;
9820
            ret = 0;
9821
        }
9822
    }
9823
    #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
9824
#endif /* WOLFSSL_DH_EXTRA */
9825
9826
    WOLFSSL_LEAVE("wc_DhKeyDecode", ret);
9827
9828
    return ret;
9829
#else
9830
#ifdef WOLFSSL_DH_EXTRA
9831
    DECL_ASNGETDATA(dataASN, dhKeyPkcs8ASN_Length);
9832
#else
9833
0
    DECL_ASNGETDATA(dataASN, dhParamASN_Length);
9834
0
#endif
9835
0
    int ret = 0;
9836
9837
    /* Check input parameters are valid. */
9838
0
    if ((input == NULL) || (inOutIdx == NULL) || (key == NULL)) {
9839
0
        ret = BAD_FUNC_ARG;
9840
0
    }
9841
9842
#ifdef WOLFSSL_DH_EXTRA
9843
    ALLOC_ASNGETDATA(dataASN, dhKeyPkcs8ASN_Length, ret, key->heap);
9844
#else
9845
0
    ALLOC_ASNGETDATA(dataASN, dhParamASN_Length, ret, key->heap);
9846
0
#endif
9847
9848
0
    if (ret == 0) {
9849
        /* Initialize data and set mp_ints to hold p and g. */
9850
0
        XMEMSET(dataASN, 0, sizeof(*dataASN) * dhParamASN_Length);
9851
0
        GetASN_MP(&dataASN[DHPARAMASN_IDX_PRIME], &key->p);
9852
0
        GetASN_MP(&dataASN[DHPARAMASN_IDX_BASE], &key->g);
9853
        /* Try simple PKCS #3 template. */
9854
0
        ret = GetASN_Items(dhParamASN, dataASN, dhParamASN_Length, 1, input,
9855
0
                           inOutIdx, inSz);
9856
#ifdef WOLFSSL_DH_EXTRA
9857
        if (ret != 0) {
9858
            mp_free(&key->p);
9859
            mp_free(&key->g);
9860
9861
            /* Initialize data and set mp_ints to hold p, g, q, priv and pub. */
9862
            XMEMSET(dataASN, 0, sizeof(*dataASN) * dhKeyPkcs8ASN_Length);
9863
            GetASN_ExpBuffer(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_OID],
9864
                    keyDhOid, sizeof(keyDhOid));
9865
            GetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_P], &key->p);
9866
            GetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_G], &key->g);
9867
            GetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_Q], &key->q);
9868
            GetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEY_INT], &key->priv);
9869
            GetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PUBKEY_INT], &key->pub);
9870
            /* Try PKCS #8 wrapped template. */
9871
            ret = GetASN_Items(dhKeyPkcs8ASN, dataASN, dhKeyPkcs8ASN_Length, 1,
9872
                               input, inOutIdx, inSz);
9873
            if (ret == 0) {
9874
                /* VERSION only present in PKCS #8 private key structure */
9875
                if ((dataASN[DHKEYPKCS8ASN_IDX_PKEY_INT].length != 0) &&
9876
                        (dataASN[DHKEYPKCS8ASN_IDX_VER].length == 0)) {
9877
                    ret = ASN_PARSE_E;
9878
                }
9879
                else if ((dataASN[DHKEYPKCS8ASN_IDX_PUBKEY_INT].length != 0) &&
9880
                        (dataASN[DHKEYPKCS8ASN_IDX_VER].length != 0)) {
9881
                    ret = ASN_PARSE_E;
9882
                }
9883
            }
9884
            if ((ret == 0) && mp_iszero(&key->pub)) {
9885
                ret = mp_exptmod(&key->g, &key->priv, &key->p, &key->pub);
9886
            }
9887
        }
9888
#endif
9889
0
    }
9890
9891
0
    FREE_ASNGETDATA(dataASN, key->heap);
9892
0
    return ret;
9893
0
#endif /* WOLFSSL_ASN_TEMPLATE */
9894
0
}
9895
9896
#ifdef WOLFSSL_DH_EXTRA
9897
9898
/* Export DH Key (private or public) */
9899
int wc_DhKeyToDer(DhKey* key, byte* output, word32* outSz, int exportPriv)
9900
{
9901
#ifndef WOLFSSL_ASN_TEMPLATE
9902
    int ret, privSz = 0, pubSz = 0;
9903
    word32 keySz, idx, len, total;
9904
9905
    if (key == NULL || outSz == NULL) {
9906
        return BAD_FUNC_ARG;
9907
    }
9908
9909
    /* determine size */
9910
    if (exportPriv) {
9911
        /* octect string: priv */
9912
        privSz = SetASNIntMP(&key->priv, -1, NULL);
9913
        if (privSz < 0)
9914
            return privSz;
9915
        idx = 1 + SetLength((word32)privSz, NULL) +
9916
            (word32)privSz; /* +1 for ASN_OCTET_STRING */
9917
    }
9918
    else {
9919
        /* bit string: public */
9920
        pubSz = SetASNIntMP(&key->pub, -1, NULL);
9921
        if (pubSz < 0)
9922
            return pubSz;
9923
        idx = SetBitString((word32)pubSz, 0, NULL) + (word32)pubSz;
9924
    }
9925
    keySz = idx;
9926
9927
    /* DH Parameters sequence with P and G */
9928
    total = 0;
9929
    ret = wc_DhParamsToDer(key, NULL, &total);
9930
    if (ret != LENGTH_ONLY_E)
9931
        return ret;
9932
    idx += total;
9933
9934
    /* object dhKeyAgreement 1.2.840.113549.1.3.1 */
9935
    idx += (word32)SetObjectId(sizeof(keyDhOid), NULL);
9936
    idx += (word32)sizeof(keyDhOid);
9937
    len = idx - keySz;
9938
    /* sequence - all but pub/priv */
9939
    idx += SetSequence(len, NULL);
9940
    if (exportPriv) {
9941
        /* version: 0 (ASN_INTEGER, 0x01, 0x00) */
9942
        idx += 3;
9943
    }
9944
    /* sequence */
9945
    total = idx + SetSequence(idx, NULL);
9946
9947
    /* if no output, then just getting size */
9948
    if (output == NULL) {
9949
        *outSz = total;
9950
        return LENGTH_ONLY_E;
9951
    }
9952
9953
    /* make sure output fits in buffer */
9954
    if (total > *outSz) {
9955
        return BUFFER_E;
9956
    }
9957
    total = idx;
9958
9959
    /* sequence */
9960
    idx = SetSequence(total, output);
9961
    if (exportPriv) {
9962
        /* version: 0 */
9963
        idx += (word32)SetMyVersion(0, output + idx, 0);
9964
    }
9965
    /* sequence - all but pub/priv */
9966
    idx += SetSequence(len, output + idx);
9967
    /* object dhKeyAgreement 1.2.840.113549.1.3.1 */
9968
    idx += (word32)SetObjectId(sizeof(keyDhOid), output + idx);
9969
    XMEMCPY(output + idx, keyDhOid, sizeof(keyDhOid));
9970
    idx += sizeof(keyDhOid);
9971
9972
    /* DH Parameters sequence with P and G */
9973
    total = *outSz - idx;
9974
    ret = wc_DhParamsToDer(key, output + idx, &total);
9975
    if (ret < 0)
9976
        return ret;
9977
    idx += total;
9978
9979
    /* octect string: priv */
9980
    if (exportPriv) {
9981
        idx += (word32)SetOctetString((word32)privSz, output + idx);
9982
        idx += (word32)SetASNIntMP(&key->priv, -1, output + idx);
9983
    }
9984
    else {
9985
        /* bit string: public */
9986
        idx += (word32)SetBitString((word32)pubSz, 0, output + idx);
9987
        idx += (word32)SetASNIntMP(&key->pub, -1, output + idx);
9988
    }
9989
    *outSz = idx;
9990
9991
    return (int)idx;
9992
#else
9993
    ASNSetData dataASN[dhKeyPkcs8ASN_Length];
9994
    int ret = 0;
9995
    int sz;
9996
9997
    WOLFSSL_ENTER("wc_DhKeyToDer");
9998
9999
    XMEMSET(dataASN, 0, sizeof(dataASN));
10000
    SetASN_Int8Bit(&dataASN[DHKEYPKCS8ASN_IDX_VER], 0);
10001
    SetASN_OID(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_OID], DHk, oidKeyType);
10002
    /* Set mp_int containing p and g. */
10003
    SetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_P], &key->p);
10004
    SetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_G], &key->g);
10005
    dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_Q].noOut = 1;
10006
    dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_J].noOut = 1;
10007
    dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_VALID].noOut = 1;
10008
10009
    if (exportPriv) {
10010
        SetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEY_INT], &key->priv);
10011
        dataASN[DHKEYPKCS8ASN_IDX_PUBKEY_STR].noOut = 1;
10012
        dataASN[DHKEYPKCS8ASN_IDX_PUBKEY_INT].noOut = 1;
10013
    }
10014
    else {
10015
        dataASN[DHKEYPKCS8ASN_IDX_VER].noOut = 1;
10016
        dataASN[DHKEYPKCS8ASN_IDX_PKEY_STR].noOut = 1;
10017
        dataASN[DHKEYPKCS8ASN_IDX_PKEY_INT].noOut = 1;
10018
        SetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PUBKEY_INT], &key->pub);
10019
    }
10020
10021
    /* Calculate the size of the DH parameters. */
10022
    ret = SizeASN_Items(dhKeyPkcs8ASN, dataASN, dhKeyPkcs8ASN_Length, &sz);
10023
    if (output == NULL) {
10024
        *outSz = (word32)sz;
10025
        ret = LENGTH_ONLY_E;
10026
    }
10027
    /* Check buffer is big enough for encoding. */
10028
    if ((ret == 0) && ((int)*outSz < sz)) {
10029
        ret = BUFFER_E;
10030
    }
10031
    if (ret == 0) {
10032
        /* Encode the DH parameters into buffer. */
10033
        SetASN_Items(dhKeyPkcs8ASN, dataASN, dhKeyPkcs8ASN_Length, output);
10034
        /* Set the actual encoding size. */
10035
        *outSz = (word32)sz;
10036
        /* Return the actual encoding size. */
10037
        ret = sz;
10038
    }
10039
10040
    return ret;
10041
#endif
10042
}
10043
10044
int wc_DhPubKeyToDer(DhKey* key, byte* out, word32* outSz)
10045
{
10046
    return wc_DhKeyToDer(key, out, outSz, 0);
10047
}
10048
int wc_DhPrivKeyToDer(DhKey* key, byte* out, word32* outSz)
10049
{
10050
    return wc_DhKeyToDer(key, out, outSz, 1);
10051
}
10052
10053
10054
/* Convert DH key parameters to DER format, write to output (outSz)
10055
 * If output is NULL then max expected size is set to outSz and LENGTH_ONLY_E is
10056
 * returned.
10057
 *
10058
 * Note : static function due to redefinition complications with DhKey and FIPS
10059
 * version 2 build.
10060
 *
10061
 * return bytes written on success */
10062
int wc_DhParamsToDer(DhKey* key, byte* output, word32* outSz)
10063
{
10064
#ifndef WOLFSSL_ASN_TEMPLATE
10065
    int ret;
10066
    word32 idx, total;
10067
10068
    if (key == NULL || outSz == NULL) {
10069
        return BAD_FUNC_ARG;
10070
    }
10071
10072
    /* determine size */
10073
    /* integer - g */
10074
    ret = SetASNIntMP(&key->g, -1, NULL);
10075
    if (ret < 0)
10076
        return ret;
10077
    idx = (word32)ret;
10078
    /* integer - p */
10079
    ret = SetASNIntMP(&key->p, -1, NULL);
10080
    if (ret < 0)
10081
        return ret;
10082
    idx += (word32)ret;
10083
    total = idx;
10084
     /* sequence */
10085
    idx += SetSequence(idx, NULL);
10086
10087
    if (output == NULL) {
10088
        *outSz = idx;
10089
        return LENGTH_ONLY_E;
10090
    }
10091
    /* make sure output fits in buffer */
10092
    if (idx > *outSz) {
10093
        return BUFFER_E;
10094
    }
10095
10096
10097
    /* write DH parameters */
10098
    /* sequence - for P and G only */
10099
    idx = SetSequence(total, output);
10100
    /* integer - p */
10101
    ret = SetASNIntMP(&key->p, -1, output + idx);
10102
    if (ret < 0)
10103
        return ret;
10104
    idx += (word32)ret;
10105
    /* integer - g */
10106
    ret = SetASNIntMP(&key->g, -1, output + idx);
10107
    if (ret < 0)
10108
        return ret;
10109
    idx += (word32)ret;
10110
    *outSz = idx;
10111
10112
    return (int)idx;
10113
#else
10114
    ASNSetData dataASN[dhParamASN_Length];
10115
    int ret = 0;
10116
    int sz = 0;
10117
10118
    WOLFSSL_ENTER("wc_DhParamsToDer");
10119
10120
    if (key == NULL || outSz == NULL) {
10121
        ret = BAD_FUNC_ARG;
10122
    }
10123
10124
    if (ret == 0) {
10125
        XMEMSET(dataASN, 0, sizeof(dataASN));
10126
        /* Set mp_int containing p and g. */
10127
        SetASN_MP(&dataASN[DHPARAMASN_IDX_PRIME], &key->p);
10128
        SetASN_MP(&dataASN[DHPARAMASN_IDX_BASE], &key->g);
10129
        /* privateValueLength not encoded. */
10130
        dataASN[DHPARAMASN_IDX_PRIVLEN].noOut = 1;
10131
10132
        /* Calculate the size of the DH parameters. */
10133
        ret = SizeASN_Items(dhParamASN, dataASN, dhParamASN_Length, &sz);
10134
    }
10135
    if ((ret == 0) && (output == NULL)) {
10136
        *outSz = (word32)sz;
10137
        ret = LENGTH_ONLY_E;
10138
    }
10139
    /* Check buffer is big enough for encoding. */
10140
    if ((ret == 0) && (*outSz < (word32)sz)) {
10141
        ret = BUFFER_E;
10142
    }
10143
    if (ret == 0) {
10144
        /* Encode the DH parameters into buffer. */
10145
        SetASN_Items(dhParamASN, dataASN, dhParamASN_Length, output);
10146
        /* Set the actual encoding size. */
10147
        *outSz = (word32)sz;
10148
        /* Return count of bytes written. */
10149
        ret = sz;
10150
    }
10151
10152
    return ret;
10153
#endif
10154
}
10155
10156
#endif /* WOLFSSL_DH_EXTRA */
10157
10158
/* Decode DH parameters.
10159
 *
10160
 * PKCS #3, 9 - DHParameter.
10161
 * (Also in: RFC 2786, 3)
10162
 *
10163
 * @param [in]      input     Buffer holding BER encoded data.
10164
 * @param [in, out] inOutIdx  On in, start of RSA public key.
10165
 *                            On out, start of ASN.1 item after RSA public key.
10166
 * @param [in]      inSz      Number of bytes in buffer.
10167
 * @param [in, out] p         Buffer to hold prime.
10168
 * @param [out]     pInOutSz  On in, size of buffer to hold prime in bytes.
10169
 *                            On out, size of prime in bytes.
10170
 * @param [in, out] g         Buffer to hold base.
10171
 * @param [out]     gInOutSz  On in, size of buffer to hold base in bytes.
10172
 *                            On out, size of base in bytes.
10173
 * @return  0 on success.
10174
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
10175
 *          is invalid.
10176
 * @return  BUFFER_E when data in buffer is too small.
10177
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set.
10178
 */
10179
int wc_DhParamsLoad(const byte* input, word32 inSz, byte* p, word32* pInOutSz,
10180
                 byte* g, word32* gInOutSz)
10181
0
{
10182
#ifndef WOLFSSL_ASN_TEMPLATE
10183
    word32 idx = 0;
10184
    int    ret;
10185
    int    length;
10186
10187
    if (GetSequence(input, &idx, &length, inSz) <= 0)
10188
        return ASN_PARSE_E;
10189
10190
    ret = GetASNInt(input, &idx, &length, inSz);
10191
    if (ret != 0)
10192
        return ret;
10193
10194
    if (length <= (int)*pInOutSz) {
10195
        XMEMCPY(p, &input[idx], (size_t)length);
10196
        *pInOutSz = (word32)length;
10197
    }
10198
    else {
10199
        return BUFFER_E;
10200
    }
10201
    idx += (word32)length;
10202
10203
    ret = GetASNInt(input, &idx, &length, inSz);
10204
    if (ret != 0)
10205
        return ret;
10206
10207
    if (length <= (int)*gInOutSz) {
10208
        XMEMCPY(g, &input[idx], (size_t)length);
10209
        *gInOutSz = (word32)length;
10210
    }
10211
    else {
10212
        return BUFFER_E;
10213
    }
10214
10215
    return 0;
10216
#else
10217
0
    DECL_ASNGETDATA(dataASN, dhParamASN_Length);
10218
0
    word32 idx = 0;
10219
0
    int ret = 0;
10220
10221
    /* Make sure pointers are valid before use. */
10222
0
    if ((input == NULL) || (p == NULL) || (pInOutSz == NULL) || (g == NULL) ||
10223
0
            (gInOutSz == NULL)) {
10224
0
        ret = BAD_FUNC_ARG;
10225
0
    }
10226
10227
0
    CALLOC_ASNGETDATA(dataASN, dhParamASN_Length, ret, NULL);
10228
10229
0
    if (ret == 0) {
10230
        /* Set the buffers to copy p and g into. */
10231
0
        GetASN_Buffer(&dataASN[DHPARAMASN_IDX_PRIME], p, pInOutSz);
10232
0
        GetASN_Buffer(&dataASN[DHPARAMASN_IDX_BASE], g, gInOutSz);
10233
        /* Decode the DH Parameters. */
10234
0
        ret = GetASN_Items(dhParamASN, dataASN, dhParamASN_Length, 1, input,
10235
0
                           &idx, inSz);
10236
0
    }
10237
10238
0
    FREE_ASNGETDATA(dataASN, NULL);
10239
0
    return ret;
10240
0
#endif /* WOLFSSL_ASN_TEMPLATE */
10241
0
}
10242
#endif /* !NO_DH */
10243
10244
10245
#ifndef NO_DSA
10246
10247
static mp_int* GetDsaInt(DsaKey* key, int idx)
10248
{
10249
    if (idx == 0)
10250
        return &key->p;
10251
    if (idx == 1)
10252
        return &key->q;
10253
    if (idx == 2)
10254
        return &key->g;
10255
    if (idx == 3)
10256
        return &key->y;
10257
    if (idx == 4)
10258
        return &key->x;
10259
10260
    return NULL;
10261
}
10262
10263
#ifdef WOLFSSL_ASN_TEMPLATE
10264
/* ASN.1 template for DSA public and private keys.
10265
 * Public key: seq, p, q, g, y
10266
 * Private key: seq, version, p, q, g, y, x
10267
 * RFC 3279, 2.3.2 - DSA in SubjectPublicKeyInfo
10268
 */
10269
static const ASNItem dsaKeyASN[] = {
10270
/* SEQ */    { 0, ASN_SEQUENCE, 1, 1, 0 },
10271
/* VER */        { 1, ASN_INTEGER, 0, 0, 0 },
10272
/* P   */        { 1, ASN_INTEGER, 0, 0, 0 },
10273
/* Q   */        { 1, ASN_INTEGER, 0, 0, 0 },
10274
/* G   */        { 1, ASN_INTEGER, 0, 0, 0 },
10275
/* Y   */        { 1, ASN_INTEGER, 0, 0, 0 },
10276
/* X   */        { 1, ASN_INTEGER, 0, 0, 0 },
10277
};
10278
enum {
10279
    DSAKEYASN_IDX_SEQ = 0,
10280
    DSAKEYASN_IDX_VER,
10281
    DSAKEYASN_IDX_P,
10282
    DSAKEYASN_IDX_Q,
10283
    DSAKEYASN_IDX_G,
10284
    DSAKEYASN_IDX_Y,
10285
    DSAKEYASN_IDX_X
10286
};
10287
10288
/* Number of items in ASN.1 template for DSA private key. */
10289
#define dsaKeyASN_Length (sizeof(dsaKeyASN) / sizeof(ASNItem))
10290
/* Number of items in ASN.1 template for DSA public key. */
10291
#define dsaPublicKeyASN_Length ((sizeof(dsaKeyASN) / sizeof(ASNItem)) - 2)
10292
10293
/* ASN.1 template for PublicKeyInfo with DSA.
10294
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
10295
 * RFC 3279, 2.3.2 - DSA in SubjectPublicKeyInfo
10296
 */
10297
static const ASNItem dsaPubKeyASN[] = {
10298
/* SEQ             */ { 0, ASN_SEQUENCE, 1, 1, 0 },
10299
/* ALGOID_SEQ      */     { 1, ASN_SEQUENCE, 1, 1, 0 },
10300
/* ALGOID_OID      */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
10301
/* ALGOID_PARAMS   */         { 2, ASN_SEQUENCE, 1, 1, 0 },
10302
                                                   /* p */
10303
/* ALGOID_PARAMS_P */             { 3, ASN_INTEGER, 0, 0, 0 },
10304
                                                   /* q */
10305
/* ALGOID_PARAMS_Q */             { 3, ASN_INTEGER, 0, 0, 0 },
10306
                                                   /* g */
10307
/* ALGOID_PARAMS_G */             { 3, ASN_INTEGER, 0, 0, 0 },
10308
/* PUBKEY_STR      */     { 1, ASN_BIT_STRING, 0, 1, 1 },
10309
                                               /* y */
10310
/* PUBKEY_Y        */         { 2, ASN_INTEGER, 0, 0, 0 },
10311
};
10312
enum {
10313
    DSAPUBKEYASN_IDX_SEQ = 0,
10314
    DSAPUBKEYASN_IDX_ALGOID_SEQ,
10315
    DSAPUBKEYASN_IDX_ALGOID_OID,
10316
    DSAPUBKEYASN_IDX_ALGOID_PARAMS,
10317
    DSAPUBKEYASN_IDX_ALGOID_PARAMS_P,
10318
    DSAPUBKEYASN_IDX_ALGOID_PARAMS_Q,
10319
    DSAPUBKEYASN_IDX_ALGOID_PARAMS_G,
10320
    DSAPUBKEYASN_IDX_PUBKEY_STR,
10321
    DSAPUBKEYASN_IDX_PUBKEY_Y
10322
};
10323
10324
/* Number of items in ASN.1 template for PublicKeyInfo with DSA. */
10325
#define dsaPubKeyASN_Length (sizeof(dsaPubKeyASN) / sizeof(ASNItem))
10326
#endif /* WOLFSSL_ASN_TEMPLATE */
10327
10328
/* Decode DSA public key.
10329
 *
10330
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
10331
 * RFC 3279, 2.3.2 - DSA in SubjectPublicKeyInfo
10332
 *
10333
 * @param [in]      input     Buffer holding BER encoded data.
10334
 * @param [in, out] inOutIdx  On in, start of DSA public key.
10335
 *                            On out, start of ASN.1 item after DSA public key.
10336
 * @param [in, out] key       DSA key object.
10337
 * @param [in]      inSz      Number of bytes in buffer.
10338
 * @return  0 on success.
10339
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
10340
 *          is invalid.
10341
 * @return  BUFFER_E when data in buffer is too small.
10342
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
10343
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
10344
 *          non-zero length.
10345
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
10346
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
10347
 */
10348
int wc_DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
10349
                          word32 inSz)
10350
{
10351
#ifndef WOLFSSL_ASN_TEMPLATE
10352
    int    length;
10353
    int    ret = 0;
10354
    word32 oid;
10355
    word32 maxIdx;
10356
10357
    if (input == NULL || inOutIdx == NULL || key == NULL)
10358
        return BAD_FUNC_ARG;
10359
10360
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
10361
        return ASN_PARSE_E;
10362
10363
    maxIdx = (word32)(*inOutIdx + (word32)length);
10364
    if (GetInt(&key->p,  input, inOutIdx, maxIdx) < 0 ||
10365
        GetInt(&key->q,  input, inOutIdx, maxIdx) < 0 ||
10366
        GetInt(&key->g,  input, inOutIdx, maxIdx) < 0 ||
10367
        GetInt(&key->y,  input, inOutIdx, maxIdx) < 0 )
10368
        ret = ASN_DH_KEY_E;
10369
10370
    if (ret != 0) {
10371
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
10372
            return ASN_PARSE_E;
10373
10374
        ret = GetObjectId(input, inOutIdx, &oid, oidIgnoreType, inSz);
10375
        if (ret != 0)
10376
            return ret;
10377
10378
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
10379
            return ASN_PARSE_E;
10380
10381
        if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
10382
            GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
10383
            GetInt(&key->g,  input, inOutIdx, inSz) < 0)
10384
            return ASN_DH_KEY_E;
10385
10386
        if (CheckBitString(input, inOutIdx, &length, inSz, 0, NULL) < 0)
10387
            return ASN_PARSE_E;
10388
10389
        if (GetInt(&key->y,  input, inOutIdx, inSz) < 0 )
10390
            return ASN_DH_KEY_E;
10391
10392
        ret = 0;
10393
    }
10394
10395
    key->type = DSA_PUBLIC;
10396
    return ret;
10397
#else
10398
    /* dsaPubKeyASN is longer than dsaPublicKeyASN. */
10399
    DECL_ASNGETDATA(dataASN, dsaPubKeyASN_Length);
10400
    int ret = 0;
10401
10402
    /* Validated parameters. */
10403
    if ((input == NULL) || (inOutIdx == NULL) || (key == NULL)) {
10404
        ret = BAD_FUNC_ARG;
10405
    }
10406
10407
    ALLOC_ASNGETDATA(dataASN, dsaPubKeyASN_Length, ret, key->heap);
10408
10409
    if (ret == 0) {
10410
        int i;
10411
10412
        /* Clear dynamic data items. */
10413
        XMEMSET(dataASN, 0, sizeof(ASNGetData) * dsaPublicKeyASN_Length);
10414
        /* seq
10415
         *   p, q, g, y
10416
         * Start DSA ints from DSAKEYASN_IDX_VER instead of DSAKEYASN_IDX_P */
10417
        for (i = 0; i < DSA_INTS - 1; i++)
10418
            GetASN_MP(&dataASN[(int)DSAKEYASN_IDX_VER + i], GetDsaInt(key, i));
10419
        /* Parse as simple form. */
10420
        ret = GetASN_Items(dsaKeyASN, dataASN, dsaPublicKeyASN_Length, 0, input,
10421
                           inOutIdx, inSz);
10422
        if (ret != 0) {
10423
            /* Clear dynamic data items. */
10424
            XMEMSET(dataASN, 0, sizeof(ASNGetData) * dsaPubKeyASN_Length);
10425
            /* Set DSA OID to expect. */
10426
            GetASN_ExpBuffer(&dataASN[DSAPUBKEYASN_IDX_ALGOID_OID],
10427
                    keyDsaOid, sizeof(keyDsaOid));
10428
            /* p, q, g */
10429
            for (i = 0; i < DSA_INTS - 2; i++)
10430
                GetASN_MP(&dataASN[(int)DSAPUBKEYASN_IDX_ALGOID_PARAMS_P + i],
10431
                        GetDsaInt(key, i));
10432
            /* y */
10433
            GetASN_MP(&dataASN[DSAPUBKEYASN_IDX_PUBKEY_Y], GetDsaInt(key, i));
10434
            /* Parse as SubjectPublicKeyInfo. */
10435
            ret = GetASN_Items(dsaPubKeyASN, dataASN, dsaPubKeyASN_Length, 1,
10436
                input, inOutIdx, inSz);
10437
        }
10438
    }
10439
10440
    if (ret == 0) {
10441
        /* Data parsed - set type of key parsed. */
10442
        key->type = DSA_PUBLIC;
10443
    }
10444
10445
    FREE_ASNGETDATA(dataASN, key->heap);
10446
    return ret;
10447
#endif
10448
}
10449
10450
int wc_DsaParamsDecode(const byte* input, word32* inOutIdx, DsaKey* key,
10451
                        word32 inSz)
10452
{
10453
    int    length;
10454
    word32 maxIdx;
10455
10456
    if (input == NULL || inOutIdx == NULL || key == NULL)
10457
        return BAD_FUNC_ARG;
10458
10459
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
10460
        return ASN_PARSE_E;
10461
10462
    maxIdx = (word32)(*inOutIdx + (word32)length);
10463
    if (GetInt(&key->p, input, inOutIdx, maxIdx) < 0 ||
10464
        GetInt(&key->q, input, inOutIdx, maxIdx) < 0 ||
10465
        GetInt(&key->g, input, inOutIdx, maxIdx) < 0)
10466
        return ASN_DH_KEY_E;
10467
10468
    return 0;
10469
}
10470
10471
10472
#ifdef WOLFSSL_ASN_TEMPLATE
10473
/* ASN.1 template for a DSA key holding private key in an OCTET_STRING. */
10474
static const ASNItem dsaKeyOctASN[] = {
10475
/*  SEQ      */ { 0, ASN_SEQUENCE, 1, 1, 0 },
10476
                /* p */
10477
/*  P        */     { 1, ASN_INTEGER, 0, 0, 0 },
10478
                /* q */
10479
/*  Q        */     { 1, ASN_INTEGER, 0, 0, 0 },
10480
                /* g */
10481
/*  G        */     { 1, ASN_INTEGER, 0, 0, 0 },
10482
                /* Private key */
10483
/*  PKEY_STR */     { 1, ASN_OCTET_STRING, 0, 1, 0 },
10484
                    /* x */
10485
/*  X        */         { 2, ASN_INTEGER, 0, 0, 0 },
10486
};
10487
enum {
10488
    DSAKEYOCTASN_IDX_SEQ = 0,
10489
    DSAKEYOCTASN_IDX_P,
10490
    DSAKEYOCTASN_IDX_Q,
10491
    DSAKEYOCTASN_IDX_G,
10492
    DSAKEYOCTASN_IDX_PKEY_STR,
10493
    DSAKEYOCTASN_IDX_X
10494
};
10495
10496
/* Number of items in ASN.1 template for a DSA key (OCTET_STRING version). */
10497
#define dsaKeyOctASN_Length (sizeof(dsaKeyOctASN) / sizeof(ASNItem))
10498
#endif
10499
10500
/* Decode DSA private key.
10501
 *
10502
 * @param [in]      input     Buffer holding BER encoded data.
10503
 * @param [in, out] inOutIdx  On in, start of DSA public key.
10504
 *                            On out, start of ASN.1 item after DSA public key.
10505
 * @param [in, out] key       DSA key object.
10506
 * @param [in]      inSz      Number of bytes in buffer.
10507
 * @return  0 on success.
10508
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
10509
 *          is invalid.
10510
 * @return  BUFFER_E when data in buffer is too small.
10511
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
10512
 *          non-zero length.
10513
 */
10514
int wc_DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
10515
                           word32 inSz)
10516
{
10517
#ifndef WOLFSSL_ASN_TEMPLATE
10518
    int length, version, ret = 0, temp = 0;
10519
    word32 algId = 0;
10520
10521
    /* Sanity checks on input */
10522
    if (input == NULL || inOutIdx == NULL || key == NULL) {
10523
        return BAD_FUNC_ARG;
10524
    }
10525
10526
    /* if has pkcs8 header skip it */
10527
    if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) {
10528
        /* ignore error, did not have pkcs8 header */
10529
    }
10530
10531
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
10532
        return ASN_PARSE_E;
10533
10534
    temp = (int)*inOutIdx;
10535
10536
    /* Default case expects a certificate with OctetString but no version ID */
10537
    ret = GetInt(&key->p, input, inOutIdx, inSz);
10538
    if (ret < 0) {
10539
        mp_clear(&key->p);
10540
        ret = ASN_PARSE_E;
10541
    }
10542
    else {
10543
        ret = GetInt(&key->q, input, inOutIdx, inSz);
10544
        if (ret < 0) {
10545
            mp_clear(&key->p);
10546
            mp_clear(&key->q);
10547
            ret = ASN_PARSE_E;
10548
        }
10549
        else {
10550
            ret = GetInt(&key->g, input, inOutIdx, inSz);
10551
            if (ret < 0) {
10552
                mp_clear(&key->p);
10553
                mp_clear(&key->q);
10554
                mp_clear(&key->g);
10555
                ret = ASN_PARSE_E;
10556
            }
10557
            else {
10558
                ret = GetOctetString(input, inOutIdx, &length, inSz);
10559
                if (ret < 0) {
10560
                    mp_clear(&key->p);
10561
                    mp_clear(&key->q);
10562
                    mp_clear(&key->g);
10563
                    ret = ASN_PARSE_E;
10564
                }
10565
                else {
10566
                    ret = GetInt(&key->y, input, inOutIdx, inSz);
10567
                    if (ret < 0) {
10568
                        mp_clear(&key->p);
10569
                        mp_clear(&key->q);
10570
                        mp_clear(&key->g);
10571
                        mp_clear(&key->y);
10572
                        ret = ASN_PARSE_E;
10573
                    }
10574
                }
10575
            }
10576
        }
10577
    }
10578
    /* An alternate pass if default certificate fails parsing */
10579
    if (ret == ASN_PARSE_E) {
10580
        *inOutIdx = (word32)temp;
10581
        if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
10582
            return ASN_PARSE_E;
10583
10584
        if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
10585
            GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
10586
            GetInt(&key->g,  input, inOutIdx, inSz) < 0 ||
10587
            GetInt(&key->y,  input, inOutIdx, inSz) < 0 ||
10588
            GetInt(&key->x,  input, inOutIdx, inSz) < 0 )
10589
            return ASN_DH_KEY_E;
10590
    }
10591
10592
    key->type = DSA_PRIVATE;
10593
    return 0;
10594
#else
10595
    /* dsaKeyASN is longer than dsaKeyOctASN. */
10596
    DECL_ASNGETDATA(dataASN, dsaKeyASN_Length);
10597
    int ret = 0;
10598
    byte version = 0;
10599
10600
    /* Sanity checks on input */
10601
    if ((input == NULL) || (inOutIdx == NULL) || (key == NULL)) {
10602
        ret = BAD_FUNC_ARG;
10603
    }
10604
10605
    CALLOC_ASNGETDATA(dataASN, dsaKeyASN_Length, ret, key->heap);
10606
10607
    if (ret == 0) {
10608
        int i;
10609
10610
        /* Try dsaKeyOctASN */
10611
        /* Initialize key data and set mp_ints for params */
10612
        for (i = 0; i < DSA_INTS - 2; i++) {
10613
            GetASN_MP(&dataASN[(int)DSAKEYOCTASN_IDX_P + i], GetDsaInt(key, i));
10614
        }
10615
        /* and priv */
10616
        GetASN_MP(&dataASN[DSAKEYOCTASN_IDX_X], GetDsaInt(key, i));
10617
        /* Try simple form. */
10618
        ret = GetASN_Items(dsaKeyOctASN, dataASN, dsaKeyOctASN_Length, 1, input,
10619
                           inOutIdx, inSz);
10620
10621
        if (ret != 0) {
10622
            /* Try dsaKeyASN */
10623
            XMEMSET(dataASN, 0, sizeof(*dataASN) * dsaKeyASN_Length);
10624
            GetASN_Int8Bit(&dataASN[DSAKEYASN_IDX_VER], &version);
10625
            for (i = 0; i < DSA_INTS; i++) {
10626
                mp_int* n = GetDsaInt(key, i);
10627
                mp_clear(n);
10628
                GetASN_MP(&dataASN[(int)DSAKEYASN_IDX_P + i], n);
10629
            }
10630
10631
            /* Try simple OCTET_STRING form. */
10632
            ret = GetASN_Items(dsaKeyASN, dataASN, dsaKeyASN_Length, 1, input,
10633
                               inOutIdx, inSz);
10634
        }
10635
    }
10636
10637
    if (ret == 0) {
10638
        /* Set the contents to be a private key. */
10639
        key->type = DSA_PRIVATE;
10640
    }
10641
10642
    FREE_ASNGETDATA(dataASN, key->heap);
10643
    return ret;
10644
#endif
10645
}
10646
10647
#ifndef WOLFSSL_ASN_TEMPLATE
10648
/* Release Tmp DSA resources */
10649
static WC_INLINE void FreeTmpDsas(byte** tmps, void* heap, int ints)
10650
{
10651
    int i;
10652
10653
    for (i = 0; i < ints; i++)
10654
        XFREE(tmps[i], heap, DYNAMIC_TYPE_DSA);
10655
10656
    (void)heap;
10657
}
10658
#endif /* !WOLFSSL_ASN_TEMPLATE */
10659
10660
#if !defined(HAVE_SELFTEST) && (defined(WOLFSSL_KEY_GEN) || \
10661
        defined(WOLFSSL_CERT_GEN))
10662
/* Encode a DSA public key into buffer.
10663
 *
10664
 * @param [out] output       Buffer to hold encoded data.
10665
 * @param [in]  key          DSA key object.
10666
 * @param [out] outLen       Length of buffer.
10667
 * @param [out] with_header  Whether to encode in SubjectPublicKeyInfo block.
10668
 * @return  Size of encoded data in bytes on success.
10669
 * @return  BAD_FUNC_ARG when output or key is NULL, or buffer size is less
10670
 *          than a minimal size (5 bytes), or buffer size is smaller than
10671
 *          encoding size.
10672
 * @return  MEMORY_E when dynamic memory allocation fails.
10673
 */
10674
int wc_SetDsaPublicKey(byte* output, DsaKey* key, int outLen, int with_header)
10675
{
10676
#ifndef WOLFSSL_ASN_TEMPLATE
10677
    /* p, g, q = DSA params, y = public exponent */
10678
#ifdef WOLFSSL_SMALL_STACK
10679
    byte* p = NULL;
10680
    byte* g = NULL;
10681
    byte* q = NULL;
10682
    byte* y = NULL;
10683
#else
10684
    byte p[MAX_DSA_INT_SZ];
10685
    byte g[MAX_DSA_INT_SZ];
10686
    byte q[MAX_DSA_INT_SZ];
10687
    byte y[MAX_DSA_INT_SZ];
10688
#endif
10689
    byte innerSeq[MAX_SEQ_SZ];
10690
    byte outerSeq[MAX_SEQ_SZ];
10691
    byte bitString[1 + MAX_LENGTH_SZ + 1];
10692
    int pSz, gSz, qSz, ySz;
10693
    word32 idx, innerSeqSz, outerSeqSz, bitStringSz = 0;
10694
    WOLFSSL_ENTER("wc_SetDsaPublicKey");
10695
10696
    if (output == NULL || key == NULL || outLen < MAX_SEQ_SZ) {
10697
        return BAD_FUNC_ARG;
10698
    }
10699
10700
    /* p */
10701
#ifdef WOLFSSL_SMALL_STACK
10702
    p = (byte*)XMALLOC(MAX_DSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10703
    if (p == NULL)
10704
        return MEMORY_E;
10705
#endif
10706
    if ((pSz = SetASNIntMP(&key->p, MAX_DSA_INT_SZ, p)) < 0) {
10707
        WOLFSSL_MSG("SetASNIntMP Error with p");
10708
#ifdef WOLFSSL_SMALL_STACK
10709
        XFREE(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10710
#endif
10711
        return pSz;
10712
    }
10713
10714
    /* q */
10715
#ifdef WOLFSSL_SMALL_STACK
10716
    q = (byte*)XMALLOC(MAX_DSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10717
    if (q == NULL)
10718
        return MEMORY_E;
10719
#endif
10720
    if ((qSz = SetASNIntMP(&key->q, MAX_DSA_INT_SZ, q)) < 0) {
10721
        WOLFSSL_MSG("SetASNIntMP Error with q");
10722
#ifdef WOLFSSL_SMALL_STACK
10723
        XFREE(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10724
        XFREE(q, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10725
#endif
10726
        return qSz;
10727
    }
10728
10729
    /* g */
10730
#ifdef WOLFSSL_SMALL_STACK
10731
    g = (byte*)XMALLOC(MAX_DSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10732
    if (g == NULL)
10733
        return MEMORY_E;
10734
#endif
10735
    if ((gSz = SetASNIntMP(&key->g, MAX_DSA_INT_SZ, g)) < 0) {
10736
        WOLFSSL_MSG("SetASNIntMP Error with g");
10737
#ifdef WOLFSSL_SMALL_STACK
10738
        XFREE(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10739
        XFREE(q, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10740
        XFREE(g, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10741
#endif
10742
        return gSz;
10743
    }
10744
10745
    /* y */
10746
#ifdef WOLFSSL_SMALL_STACK
10747
    y = (byte*)XMALLOC(MAX_DSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10748
    if (y == NULL)
10749
        return MEMORY_E;
10750
#endif
10751
    if ((ySz = SetASNIntMP(&key->y, MAX_DSA_INT_SZ, y)) < 0) {
10752
        WOLFSSL_MSG("SetASNIntMP Error with y");
10753
#ifdef WOLFSSL_SMALL_STACK
10754
        XFREE(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10755
        XFREE(q, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10756
        XFREE(g, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10757
        XFREE(y, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10758
#endif
10759
        return ySz;
10760
    }
10761
10762
    if (with_header) {
10763
        word32 algoSz;
10764
#ifdef WOLFSSL_SMALL_STACK
10765
        byte* algo = NULL;
10766
10767
        algo = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10768
        if (algo == NULL) {
10769
            XFREE(p,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10770
            XFREE(q,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10771
            XFREE(g,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10772
            XFREE(y,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10773
            return MEMORY_E;
10774
        }
10775
#else
10776
        byte algo[MAX_ALGO_SZ];
10777
#endif
10778
        innerSeqSz  = SetSequence((word32)(pSz + qSz + gSz), innerSeq);
10779
        algoSz = SetAlgoID(DSAk, algo, oidKeyType, 0);
10780
        bitStringSz  = SetBitString((word32)ySz, 0, bitString);
10781
        outerSeqSz = SetSequence(algoSz + innerSeqSz +
10782
                                 (word32)(pSz + qSz + gSz), outerSeq);
10783
10784
        idx = SetSequence(algoSz + innerSeqSz + (word32)(pSz + qSz + gSz) +
10785
                          bitStringSz + (word32)ySz + outerSeqSz, output);
10786
10787
        /* check output size */
10788
        if ((idx + algoSz + bitStringSz + innerSeqSz +
10789
             (word32)(pSz + qSz + gSz + ySz)) > (word32)outLen)
10790
        {
10791
            #ifdef WOLFSSL_SMALL_STACK
10792
                XFREE(p,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10793
                XFREE(q,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10794
                XFREE(g,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10795
                XFREE(y,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10796
                XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10797
            #endif
10798
            WOLFSSL_MSG("Error, output size smaller than outlen");
10799
            return BUFFER_E;
10800
        }
10801
10802
        /* outerSeq */
10803
        XMEMCPY(output + idx, outerSeq, outerSeqSz);
10804
        idx += outerSeqSz;
10805
        /* algo */
10806
        XMEMCPY(output + idx, algo, algoSz);
10807
        idx += algoSz;
10808
#ifdef WOLFSSL_SMALL_STACK
10809
        XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10810
#endif
10811
    } else {
10812
        innerSeqSz  = SetSequence((word32)(pSz + qSz + gSz + ySz), innerSeq);
10813
10814
        /* check output size */
10815
        if ((innerSeqSz + (word32)(pSz + qSz + gSz + ySz)) > (word32)outLen) {
10816
    #ifdef WOLFSSL_SMALL_STACK
10817
            XFREE(p,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10818
            XFREE(q,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10819
            XFREE(g,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10820
            XFREE(y,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10821
    #endif
10822
            WOLFSSL_MSG("Error, output size smaller than outlen");
10823
            return BUFFER_E;
10824
        }
10825
10826
        idx = 0;
10827
    }
10828
10829
    /* innerSeq */
10830
    XMEMCPY(output + idx, innerSeq, innerSeqSz);
10831
    idx += innerSeqSz;
10832
    /* p */
10833
    XMEMCPY(output + idx, p, (size_t)pSz);
10834
    idx += (word32)pSz;
10835
    /* q */
10836
    XMEMCPY(output + idx, q, (size_t)qSz);
10837
    idx += (word32)qSz;
10838
    /* g */
10839
    XMEMCPY(output + idx, g, (size_t)gSz);
10840
    idx += (word32)gSz;
10841
    /* bit string */
10842
    if (bitStringSz > 0) {
10843
        XMEMCPY(output + idx, bitString, bitStringSz);
10844
        idx += bitStringSz;
10845
    }
10846
    /* y */
10847
    XMEMCPY(output + idx, y, (size_t)ySz);
10848
    idx += (word32)ySz;
10849
10850
#ifdef WOLFSSL_SMALL_STACK
10851
    XFREE(p,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10852
    XFREE(q,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10853
    XFREE(g,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10854
    XFREE(y,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
10855
#endif
10856
    return (int)idx;
10857
#else
10858
    DECL_ASNSETDATA(dataASN, dsaPubKeyASN_Length);
10859
    int ret = 0;
10860
    int i;
10861
    int sz = 0;
10862
    const ASNItem *data = NULL;
10863
    int count = 0;
10864
10865
    WOLFSSL_ENTER("wc_SetDsaPublicKey");
10866
10867
    if ((output == NULL) || (key == NULL) || (outLen < MAX_SEQ_SZ)) {
10868
        ret = BAD_FUNC_ARG;
10869
    }
10870
10871
    CALLOC_ASNSETDATA(dataASN, dsaPubKeyASN_Length, ret, key->heap);
10872
10873
    if (ret == 0) {
10874
        if (with_header) {
10875
            /* Using dsaPubKeyASN */
10876
            data = dsaPubKeyASN;
10877
            count = dsaPubKeyASN_Length;
10878
            /* Set the algorithm OID to write out. */
10879
            SetASN_OID(&dataASN[DSAPUBKEYASN_IDX_ALGOID_OID], DSAk, oidKeyType);
10880
            /* Set the mp_ints to encode - parameters and public value. */
10881
            for (i = 0; i < DSA_INTS - 2; i++) {
10882
                SetASN_MP(&dataASN[(int)DSAPUBKEYASN_IDX_ALGOID_PARAMS_P + i],
10883
                        GetDsaInt(key, i));
10884
            }
10885
            SetASN_MP(&dataASN[DSAPUBKEYASN_IDX_PUBKEY_Y], GetDsaInt(key, i));
10886
        }
10887
        else {
10888
            /* Using dsaKeyASN */
10889
            data = dsaKeyASN;
10890
            count = dsaPublicKeyASN_Length;
10891
            /* Set the mp_ints to encode - parameters and public value. */
10892
            for (i = 0; i < DSA_INTS - 1; i++) {
10893
                /* Move all DSA ints up one slot (ignore VERSION so now
10894
                 * it means P) */
10895
                SetASN_MP(&dataASN[(int)DSAKEYASN_IDX_VER + i],
10896
                        GetDsaInt(key, i));
10897
            }
10898
        }
10899
        ret = SizeASN_Items(data, dataASN, count, &sz);
10900
    }
10901
    /* Check buffer is big enough for encoding. */
10902
    if ((ret == 0) && (sz > (int)outLen)) {
10903
        ret = BAD_FUNC_ARG;
10904
    }
10905
    /* Encode the DSA public key into output buffer. */
10906
    if (ret == 0) {
10907
        ret = SetASN_Items(data, dataASN, count, output);
10908
    }
10909
10910
    FREE_ASNSETDATA(dataASN, key->heap);
10911
    return ret;
10912
#endif /* WOLFSSL_ASN_TEMPLATE */
10913
}
10914
10915
/* Encode a DSA public key into buffer.
10916
 *
10917
 * @param [out] output       Buffer to hold encoded data.
10918
 * @param [in]  key          DSA key object.
10919
 * @param [out] outLen       Length of buffer.
10920
 * @param [out] with_header  Whether to encode in SubjectPublicKeyInfo block.
10921
 * @return  Size of encoded data in bytes on success.
10922
 * @return  BAD_FUNC_ARG when output or key is NULL, or buffer size is less
10923
 *          than a minimal size (5 bytes), or buffer size is smaller than
10924
 *          encoding size.
10925
 * @return  MEMORY_E when dynamic memory allocation fails.
10926
 */
10927
int wc_DsaKeyToPublicDer(DsaKey* key, byte* output, word32 inLen)
10928
{
10929
    return wc_SetDsaPublicKey(output, key, (int)inLen, 1);
10930
}
10931
#endif /* !HAVE_SELFTEST && (WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN) */
10932
10933
static int DsaKeyIntsToDer(DsaKey* key, byte* output, word32* inLen,
10934
                           int ints, int includeVersion)
10935
{
10936
#ifndef WOLFSSL_ASN_TEMPLATE
10937
    word32 seqSz = 0, verSz = 0, intTotalLen = 0, outLen, j;
10938
    word32 sizes[DSA_INTS];
10939
    int    i, ret = 0;
10940
10941
    byte  seq[MAX_SEQ_SZ];
10942
    byte  ver[MAX_VERSION_SZ];
10943
    byte* tmps[DSA_INTS];
10944
10945
    if (ints > DSA_INTS || inLen == NULL)
10946
        return BAD_FUNC_ARG;
10947
10948
    XMEMSET(sizes, 0, sizeof(sizes));
10949
    for (i = 0; i < ints; i++)
10950
        tmps[i] = NULL;
10951
10952
    /* write all big ints from key to DER tmps */
10953
    for (i = 0; i < ints; i++) {
10954
        int mpSz;
10955
        mp_int* keyInt = GetDsaInt(key, i);
10956
        word32 rawLen = (word32)mp_unsigned_bin_size(keyInt) + 1;
10957
10958
        tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
10959
                                                              DYNAMIC_TYPE_DSA);
10960
        if (tmps[i] == NULL) {
10961
            ret = MEMORY_E;
10962
            break;
10963
        }
10964
10965
        mpSz = SetASNIntMP(keyInt, -1, tmps[i]);
10966
        if (mpSz < 0) {
10967
            ret = mpSz;
10968
            break;
10969
        }
10970
        sizes[i] = (word32)mpSz;
10971
        intTotalLen += (word32)mpSz;
10972
    }
10973
10974
    if (ret != 0) {
10975
        FreeTmpDsas(tmps, key->heap, ints);
10976
        return ret;
10977
    }
10978
10979
    /* make headers */
10980
    if (includeVersion)
10981
        verSz = (word32)SetMyVersion(0, ver, FALSE);
10982
    seqSz = SetSequence(verSz + intTotalLen, seq);
10983
10984
    outLen = seqSz + verSz + intTotalLen;
10985
    *inLen = outLen;
10986
    if (output == NULL) {
10987
        FreeTmpDsas(tmps, key->heap, ints);
10988
        return LENGTH_ONLY_E;
10989
    }
10990
    if (outLen > *inLen) {
10991
        FreeTmpDsas(tmps, key->heap, ints);
10992
        return BAD_FUNC_ARG;
10993
    }
10994
10995
    /* write to output */
10996
    XMEMCPY(output, seq, seqSz);
10997
    j = seqSz;
10998
    if (includeVersion) {
10999
        XMEMCPY(output + j, ver, verSz);
11000
        j += verSz;
11001
    }
11002
11003
    for (i = 0; i < ints; i++) {
11004
        XMEMCPY(output + j, tmps[i], sizes[i]);
11005
        j += sizes[i];
11006
    }
11007
    FreeTmpDsas(tmps, key->heap, ints);
11008
11009
    return (int)outLen;
11010
#else
11011
    DECL_ASNSETDATA(dataASN, dsaKeyASN_Length);
11012
    int ret = 0;
11013
    int sz = 0;
11014
11015
    (void)ints;
11016
11017
    if ((key == NULL) || (inLen == NULL)) {
11018
        ret = BAD_FUNC_ARG;
11019
    }
11020
    if ((ret == 0) && (ints > DSA_INTS)) {
11021
        ret = BAD_FUNC_ARG;
11022
    }
11023
11024
    CALLOC_ASNSETDATA(dataASN, dsaKeyASN_Length, ret, key->heap);
11025
11026
    if (ret == 0) {
11027
        int i;
11028
11029
        if (includeVersion) {
11030
            /* Set the version. */
11031
            SetASN_Int8Bit(&dataASN[DSAKEYASN_IDX_VER], 0);
11032
        }
11033
        else {
11034
            dataASN[DSAKEYASN_IDX_VER].noOut = 1;
11035
        }
11036
        dataASN[DSAKEYASN_IDX_Y].noOut = mp_iszero(&key->y);
11037
        dataASN[DSAKEYASN_IDX_X].noOut = mp_iszero(&key->x);
11038
        /* Set the mp_ints to encode - params, public and private value. */
11039
        for (i = 0; i < DSA_INTS; i++) {
11040
            if (i < ints)
11041
                SetASN_MP(&dataASN[(int)DSAKEYASN_IDX_P + i], GetDsaInt(key, i));
11042
            else
11043
                dataASN[(int)DSAKEYASN_IDX_P + i].noOut = 1;
11044
        }
11045
        /* Calculate size of the encoding. */
11046
        ret = SizeASN_Items(dsaKeyASN, dataASN, dsaKeyASN_Length, &sz);
11047
    }
11048
    if ((ret == 0) && (output == NULL)) {
11049
        *inLen = (word32)sz;
11050
        ret = LENGTH_ONLY_E;
11051
    }
11052
    /* Check buffer is big enough for encoding. */
11053
    if ((ret == 0) && (sz > (int)*inLen)) {
11054
        ret = BAD_FUNC_ARG;
11055
    }
11056
    if (ret == 0) {
11057
        /* Encode the DSA private key into output buffer. */
11058
        SetASN_Items(dsaKeyASN, dataASN, dsaKeyASN_Length, output);
11059
        /* Return the size of the encoding. */
11060
        ret = sz;
11061
    }
11062
11063
    FREE_ASNSETDATA(dataASN, key->heap);
11064
    return ret;
11065
#endif /* WOLFSSL_ASN_TEMPLATE */
11066
}
11067
11068
/* Encode a DSA private key into buffer.
11069
 *
11070
 * @param [in]  key          DSA key object.
11071
 * @param [out] output       Buffer to hold encoded data.
11072
 * @param [out] inLen        Length of buffer.
11073
 * @return  Size of encoded data in bytes on success.
11074
 * @return  BAD_FUNC_ARG when key or output is NULL, or key is not a private key
11075
 *          or, buffer size is smaller than encoding size.
11076
 * @return  MEMORY_E when dynamic memory allocation fails.
11077
 */
11078
int wc_DsaKeyToDer(DsaKey* key, byte* output, word32 inLen)
11079
{
11080
    if (!key || !output)
11081
        return BAD_FUNC_ARG;
11082
11083
    if (key->type != DSA_PRIVATE)
11084
        return BAD_FUNC_ARG;
11085
11086
    return DsaKeyIntsToDer(key, output, &inLen, DSA_INTS, 1);
11087
}
11088
11089
/* Convert DsaKey parameters to DER format, write to output (inLen),
11090
   return bytes written. Version is excluded to be compatible with
11091
   OpenSSL d2i_DSAparams */
11092
int wc_DsaKeyToParamsDer(DsaKey* key, byte* output, word32 inLen)
11093
{
11094
    if (!key || !output)
11095
        return BAD_FUNC_ARG;
11096
11097
    return DsaKeyIntsToDer(key, output, &inLen, DSA_PARAM_INTS, 0);
11098
}
11099
11100
/* This version of the function allows output to be NULL. In that case, the
11101
   DsaKeyIntsToDer will return LENGTH_ONLY_E and the required output buffer
11102
   size will be pointed to by inLen. */
11103
int wc_DsaKeyToParamsDer_ex(DsaKey* key, byte* output, word32* inLen)
11104
{
11105
    if (!key || !inLen)
11106
        return BAD_FUNC_ARG;
11107
11108
    return DsaKeyIntsToDer(key, output, inLen, DSA_PARAM_INTS, 0);
11109
}
11110
11111
#endif /* NO_DSA */
11112
11113
#ifndef NO_CERTS
11114
/* Initialize decoded certificate object with buffer of DER encoding.
11115
 *
11116
 * @param [in, out] cert    Decoded certificate object.
11117
 * @param [in]      source  Buffer containing DER encoded certificate.
11118
 * @param [in]      inSz    Size of DER data in buffer in bytes.
11119
 * @param [in]      heap    Dynamic memory hint.
11120
 */
11121
void InitDecodedCert(DecodedCert* cert,
11122
                     const byte* source, word32 inSz, void* heap)
11123
0
{
11124
0
    InitDecodedCert_ex(cert, source, inSz, heap, INVALID_DEVID);
11125
0
}
11126
11127
11128
/* Initialize decoded certificate object with buffer of DER encoding.
11129
 *
11130
 * @param [in, out] cert    Decoded certificate object.
11131
 * @param [in]      source  Buffer containing DER encoded certificate.
11132
 * @param [in]      inSz    Size of DER data in buffer in bytes.
11133
 * @param [in]      heap    Dynamic memory hint.
11134
 * @param [in]      devId   Crypto callback ID to use.
11135
 */
11136
void InitDecodedCert_ex(DecodedCert* cert,
11137
                     const byte* source, word32 inSz, void* heap, int devId)
11138
0
{
11139
0
    if (cert != NULL) {
11140
0
        XMEMSET(cert, 0, sizeof(DecodedCert));
11141
11142
0
        cert->subjectCNEnc    = CTC_UTF8;
11143
0
        cert->issuer[0]       = '\0';
11144
0
        cert->subject[0]      = '\0';
11145
0
        cert->source          = source;  /* don't own */
11146
0
        cert->maxIdx          = inSz;    /* can't go over this index */
11147
0
        cert->heap            = heap;
11148
0
        cert->maxPathLen      = WOLFSSL_MAX_PATH_LEN;
11149
    #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
11150
        #ifdef WOLFSSL_CERT_NAME_ALL
11151
        cert->subjectNEnc     = CTC_UTF8;
11152
        cert->subjectIEnc     = CTC_UTF8;
11153
        cert->subjectDNQEnc   = CTC_UTF8;
11154
        cert->subjectGNEnc    = CTC_UTF8;
11155
        #endif
11156
        cert->subjectSNEnc    = CTC_UTF8;
11157
        cert->subjectCEnc     = CTC_PRINTABLE;
11158
        cert->subjectLEnc     = CTC_UTF8;
11159
        cert->subjectSTEnc    = CTC_UTF8;
11160
        cert->subjectOEnc     = CTC_UTF8;
11161
        cert->subjectOUEnc    = CTC_UTF8;
11162
    #ifdef WOLFSSL_HAVE_ISSUER_NAMES
11163
        cert->issuerSNEnc    = CTC_UTF8;
11164
        cert->issuerCEnc     = CTC_PRINTABLE;
11165
        cert->issuerLEnc     = CTC_UTF8;
11166
        cert->issuerSTEnc    = CTC_UTF8;
11167
        cert->issuerOEnc     = CTC_UTF8;
11168
        cert->issuerOUEnc    = CTC_UTF8;
11169
    #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
11170
    #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
11171
11172
0
        InitSignatureCtx(&cert->sigCtx, heap, devId);
11173
0
    }
11174
0
}
11175
11176
void wc_InitDecodedCert(DecodedCert* cert, const byte* source, word32 inSz,
11177
                        void* heap)
11178
0
{
11179
0
    InitDecodedCert(cert, source, inSz, heap);
11180
0
}
11181
11182
/* Free the alternative names object.
11183
 *
11184
 * Frees each linked list items and its name.
11185
 *
11186
 * @param [in, out] altNames  Alternative names.
11187
 * @param [in]      heap      Dynamic memory hint.
11188
 */
11189
void FreeAltNames(DNS_entry* altNames, void* heap)
11190
0
{
11191
0
    (void)heap;
11192
11193
0
    while (altNames) {
11194
0
        DNS_entry* tmp = altNames->next;
11195
11196
0
        XFREE(altNames->name, heap, DYNAMIC_TYPE_ALTNAME);
11197
    #if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
11198
        XFREE(altNames->ipString, heap, DYNAMIC_TYPE_ALTNAME);
11199
    #endif
11200
0
        XFREE(altNames,       heap, DYNAMIC_TYPE_ALTNAME);
11201
0
        altNames = tmp;
11202
0
    }
11203
0
}
11204
11205
/* malloc and initialize a new alt name structure */
11206
DNS_entry* AltNameNew(void* heap)
11207
0
{
11208
0
    DNS_entry* ret;
11209
0
    ret = (DNS_entry*)XMALLOC(sizeof(DNS_entry), heap, DYNAMIC_TYPE_ALTNAME);
11210
0
    if (ret != NULL) {
11211
0
        XMEMSET(ret, 0, sizeof(DNS_entry));
11212
0
    }
11213
0
    (void)heap;
11214
0
    return ret;
11215
0
}
11216
11217
11218
#ifndef IGNORE_NAME_CONSTRAINTS
11219
11220
/* Free the subtree names object.
11221
 *
11222
 * Frees each linked list items and its name.
11223
 *
11224
 * @param [in, out] names  Subtree names.
11225
 * @param [in]      heap   Dynamic memory hint.
11226
 */
11227
void FreeNameSubtrees(Base_entry* names, void* heap)
11228
0
{
11229
0
    (void)heap;
11230
11231
0
    while (names) {
11232
0
        Base_entry* tmp = names->next;
11233
11234
0
        XFREE(names->name, heap, DYNAMIC_TYPE_ALTNAME);
11235
0
        XFREE(names,       heap, DYNAMIC_TYPE_ALTNAME);
11236
0
        names = tmp;
11237
0
    }
11238
0
}
11239
11240
#endif /* IGNORE_NAME_CONSTRAINTS */
11241
11242
/* Free the decoded cert object's dynamic data.
11243
 *
11244
 * @param [in, out] cert  Decoded certificate object.
11245
 */
11246
void FreeDecodedCert(DecodedCert* cert)
11247
0
{
11248
0
    if (cert == NULL)
11249
0
        return;
11250
0
    if (cert->subjectCNStored == 1) {
11251
0
        XFREE(cert->subjectCN, cert->heap, DYNAMIC_TYPE_SUBJECT_CN);
11252
0
    }
11253
0
    if (cert->pubKeyStored == 1) {
11254
0
        XFREE((void*)cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
11255
0
    }
11256
0
    if (cert->weOwnAltNames && cert->altNames)
11257
0
        FreeAltNames(cert->altNames, cert->heap);
11258
0
#ifndef IGNORE_NAME_CONSTRAINTS
11259
0
    if (cert->altEmailNames)
11260
0
        FreeAltNames(cert->altEmailNames, cert->heap);
11261
0
    if (cert->altDirNames)
11262
0
        FreeAltNames(cert->altDirNames, cert->heap);
11263
0
    if (cert->permittedNames)
11264
0
        FreeNameSubtrees(cert->permittedNames, cert->heap);
11265
0
    if (cert->excludedNames)
11266
0
        FreeNameSubtrees(cert->excludedNames, cert->heap);
11267
0
#endif /* IGNORE_NAME_CONSTRAINTS */
11268
#ifdef WOLFSSL_SEP
11269
    XFREE(cert->deviceType, cert->heap, DYNAMIC_TYPE_X509_EXT);
11270
    XFREE(cert->hwType, cert->heap, DYNAMIC_TYPE_X509_EXT);
11271
    XFREE(cert->hwSerialNum, cert->heap, DYNAMIC_TYPE_X509_EXT);
11272
#endif /* WOLFSSL_SEP */
11273
#ifdef WOLFSSL_X509_NAME_AVAILABLE
11274
    if (cert->issuerName != NULL)
11275
        wolfSSL_X509_NAME_free((WOLFSSL_X509_NAME*)cert->issuerName);
11276
    if (cert->subjectName != NULL)
11277
        wolfSSL_X509_NAME_free((WOLFSSL_X509_NAME*)cert->subjectName);
11278
#endif /* WOLFSSL_X509_NAME_AVAILABLE */
11279
#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT)
11280
    if (cert->sce_tsip_encRsaKeyIdx != NULL)
11281
        XFREE(cert->sce_tsip_encRsaKeyIdx, cert->heap, DYNAMIC_TYPE_RSA);
11282
#endif
11283
0
    FreeSignatureCtx(&cert->sigCtx);
11284
0
}
11285
11286
void wc_FreeDecodedCert(DecodedCert* cert)
11287
0
{
11288
0
    FreeDecodedCert(cert);
11289
0
}
11290
11291
#ifndef WOLFSSL_ASN_TEMPLATE
11292
static int GetCertHeader(DecodedCert* cert)
11293
{
11294
    int ret = 0, len;
11295
11296
    if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
11297
        return ASN_PARSE_E;
11298
11299
    /* Reset the max index for the size indicated in the outer wrapper. */
11300
    cert->maxIdx = (word32)len + cert->srcIdx;
11301
    cert->certBegin = cert->srcIdx;
11302
11303
    if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
11304
        return ASN_PARSE_E;
11305
11306
    cert->sigIndex = (word32)len + cert->srcIdx;
11307
    if (cert->sigIndex > cert->maxIdx)
11308
        return ASN_PARSE_E;
11309
11310
    if (GetExplicitVersion(cert->source, &cert->srcIdx, &cert->version,
11311
                                                            cert->sigIndex) < 0)
11312
        return ASN_PARSE_E;
11313
11314
    if (wc_GetSerialNumber(cert->source, &cert->srcIdx, cert->serial,
11315
                                           &cert->serialSz, cert->sigIndex) < 0)
11316
        return ASN_PARSE_E;
11317
11318
    return ret;
11319
}
11320
#endif
11321
11322
#if defined(HAVE_ED25519) || defined(HAVE_ED448) || (defined(HAVE_PQC) && \
11323
    defined(HAVE_LIBOQS))
11324
/* Store the key data under the BIT_STRING in dynamicly allocated data.
11325
 *
11326
 * @param [in, out] cert    Certificate object.
11327
 * @param [in]      source  Buffer containing encoded key.
11328
 * @param [in, out] srcIdx  On in, start of key data.
11329
 *                          On out, start of element after key data.
11330
 * @param [in]      maxIdx  Maximum index of certificate data.
11331
 */
11332
static int StoreKey(DecodedCert* cert, const byte* source, word32* srcIdx,
11333
                    word32 maxIdx)
11334
0
{
11335
0
    int ret;
11336
0
    int length;
11337
0
    byte* publicKey;
11338
11339
0
    ret = CheckBitString(source, srcIdx, &length, maxIdx, 1, NULL);
11340
0
    if (ret == 0) {
11341
    #ifdef HAVE_OCSP
11342
        ret = CalcHashId_ex(source + *srcIdx, (word32)length,
11343
            cert->subjectKeyHash, HashIdAlg(cert->signatureOID));
11344
    }
11345
    if (ret == 0) {
11346
    #endif
11347
0
        publicKey = (byte*)XMALLOC((size_t)length, cert->heap,
11348
0
                                   DYNAMIC_TYPE_PUBLIC_KEY);
11349
0
        if (publicKey == NULL) {
11350
0
            ret = MEMORY_E;
11351
0
        }
11352
0
        else {
11353
0
            XMEMCPY(publicKey, &source[*srcIdx], (size_t)length);
11354
0
            cert->publicKey = publicKey;
11355
0
            cert->pubKeyStored = 1;
11356
0
            cert->pubKeySize   = (word32)length;
11357
11358
0
            *srcIdx += (word32)length;
11359
0
        }
11360
0
    }
11361
11362
0
    return ret;
11363
0
}
11364
#endif /* HAVE_ED25519 || HAVE_ED448 */
11365
#endif
11366
11367
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
11368
11369
static int SetCurve(ecc_key* key, byte* output, size_t outSz)
11370
0
{
11371
#ifdef HAVE_OID_ENCODING
11372
    int ret;
11373
#endif
11374
0
    int idx;
11375
0
    word32 oidSz = 0;
11376
11377
    /* validate key */
11378
0
    if (key == NULL || key->dp == NULL) {
11379
0
        return BAD_FUNC_ARG;
11380
0
    }
11381
11382
#ifdef HAVE_OID_ENCODING
11383
    ret = EncodeObjectId(key->dp->oid, key->dp->oidSz, NULL, &oidSz);
11384
    if (ret != 0) {
11385
        return ret;
11386
    }
11387
#else
11388
0
    oidSz = key->dp->oidSz;
11389
0
#endif
11390
11391
0
    idx = SetObjectId((int)oidSz, output);
11392
11393
    /* length only */
11394
0
    if (output == NULL) {
11395
0
        return idx + (int)oidSz;
11396
0
    }
11397
11398
    /* verify output buffer has room */
11399
0
    if (oidSz > outSz)
11400
0
        return BUFFER_E;
11401
11402
#ifdef HAVE_OID_ENCODING
11403
    ret = EncodeObjectId(key->dp->oid, key->dp->oidSz, output+idx, &oidSz);
11404
    if (ret != 0) {
11405
        return ret;
11406
    }
11407
#else
11408
0
    XMEMCPY(output+idx, key->dp->oid, oidSz);
11409
0
#endif
11410
0
    idx += (int)oidSz;
11411
11412
0
    return idx;
11413
0
}
11414
11415
#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */
11416
11417
#ifdef HAVE_ECC
11418
#ifdef WOLFSSL_ASN_TEMPLATE
11419
/* ASN.1 template for ECC public key (SubjectPublicKeyInfo).
11420
 * RFC 5480, 2 - Subject Public Key Information Fields
11421
 *           2.1.1 - Unrestricted Algorithm Identifier and Parameters
11422
 * X9.62 ECC point format.
11423
 * See ASN.1 template 'eccSpecifiedASN' for specifiedCurve.
11424
 */
11425
static const ASNItem eccPublicKeyASN[] = {
11426
/* SEQ            */ { 0, ASN_SEQUENCE, 1, 1, 0 },
11427
                                             /* AlgorithmIdentifier */
11428
/* ALGOID_SEQ     */     { 1, ASN_SEQUENCE, 1, 1, 0 },
11429
                                                 /* algorithm */
11430
/* ALGOID_OID     */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
11431
                                                 /* namedCurve */
11432
/* ALGOID_CURVEID */         { 2, ASN_OBJECT_ID, 0, 0, 2 },
11433
                                                 /* specifiedCurve - explicit parameters */
11434
/* ALGOID_PARAMS  */         { 2, ASN_SEQUENCE, 1, 0, 2 },
11435
                                             /* Public Key */
11436
/* PUBKEY         */     { 1, ASN_BIT_STRING, 0, 0, 0 },
11437
};
11438
enum {
11439
    ECCPUBLICKEYASN_IDX_SEQ = 0,
11440
    ECCPUBLICKEYASN_IDX_ALGOID_SEQ,
11441
    ECCPUBLICKEYASN_IDX_ALGOID_OID,
11442
    ECCPUBLICKEYASN_IDX_ALGOID_CURVEID,
11443
    ECCPUBLICKEYASN_IDX_ALGOID_PARAMS,
11444
    ECCPUBLICKEYASN_IDX_PUBKEY
11445
};
11446
11447
/* Number of items in ASN.1 template for ECC public key. */
11448
0
#define eccPublicKeyASN_Length (sizeof(eccPublicKeyASN) / sizeof(ASNItem))
11449
#endif /* WOLFSSL_ASN_TEMPLATE */
11450
#endif /* HAVE_ECC */
11451
11452
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
11453
11454
/* Encode public ECC key in DER format.
11455
 *
11456
 * RFC 5480, 2 - Subject Public Key Information Fields
11457
 *           2.1.1 - Unrestricted Algorithm Identifier and Parameters
11458
 * X9.62 ECC point format.
11459
 * SEC 1 Ver. 2.0, C.2 - Syntax for Elliptic Curve Domain Parameters
11460
 *
11461
 * @param [out] output       Buffer to put encoded data in.
11462
 * @param [in]  key          ECC key object.
11463
 * @param [in]  outLen       Size of buffer in bytes.
11464
 * @param [in]  with_header  Whether to use SubjectPublicKeyInfo format.
11465
 * @return  Size of encoded data in bytes on success.
11466
 * @return  BAD_FUNC_ARG when key or key's parameters is NULL.
11467
 * @return  MEMORY_E when dynamic memory allocation failed.
11468
 */
11469
static int SetEccPublicKey(byte* output, ecc_key* key, int outLen,
11470
                           int with_header, int comp)
11471
0
{
11472
#ifndef WOLFSSL_ASN_TEMPLATE
11473
    int ret;
11474
    word32 idx = 0, curveSz, algoSz, pubSz, bitStringSz;
11475
    byte bitString[1 + MAX_LENGTH_SZ + 1]; /* 6 */
11476
    byte algo[MAX_ALGO_SZ];  /* 20 */
11477
11478
    /* public size */
11479
    pubSz = key->dp ? (word32)key->dp->size : MAX_ECC_BYTES;
11480
    if (comp)
11481
        pubSz = 1 + pubSz;
11482
    else
11483
        pubSz = 1 + 2 * pubSz;
11484
11485
    /* check for buffer overflow */
11486
    if (output != NULL && pubSz > (word32)outLen) {
11487
        return BUFFER_E;
11488
    }
11489
11490
    /* headers */
11491
    if (with_header) {
11492
        ret = SetCurve(key, NULL, 0);
11493
        if (ret <= 0) {
11494
            return ret;
11495
        }
11496
        curveSz = (word32)ret;
11497
        ret = 0;
11498
11499
        /* calculate size */
11500
        algoSz  = SetAlgoID(ECDSAk, algo, oidKeyType, (int)curveSz);
11501
        bitStringSz = SetBitString(pubSz, 0, bitString);
11502
        idx = SetSequence(pubSz + curveSz + bitStringSz + algoSz, NULL);
11503
11504
        /* check for buffer overflow */
11505
        if (output != NULL &&
11506
                curveSz + algoSz + bitStringSz + idx + pubSz > (word32)outLen) {
11507
            return BUFFER_E;
11508
        }
11509
11510
        idx = SetSequence(pubSz + curveSz + bitStringSz + algoSz,
11511
            output);
11512
        /* algo */
11513
        if (output)
11514
            XMEMCPY(output + idx, algo, algoSz);
11515
        idx += algoSz;
11516
        /* curve */
11517
        if (output)
11518
            (void)SetCurve(key, output + idx, curveSz);
11519
        idx += curveSz;
11520
        /* bit string */
11521
        if (output)
11522
            XMEMCPY(output + idx, bitString, bitStringSz);
11523
        idx += bitStringSz;
11524
    }
11525
11526
    /* pub */
11527
    if (output) {
11528
        PRIVATE_KEY_UNLOCK();
11529
        ret = wc_ecc_export_x963_ex(key, output + idx, &pubSz, comp);
11530
        PRIVATE_KEY_LOCK();
11531
        if (ret != 0) {
11532
            return ret;
11533
        }
11534
    }
11535
    idx += pubSz;
11536
11537
    return (int)idx;
11538
#else
11539
0
    word32 pubSz = 0;
11540
0
    int sz = 0;
11541
0
    int ret = 0;
11542
0
    int curveIdSz = 0;
11543
0
    byte* curveOid = NULL;
11544
11545
    /* Check key validity. */
11546
0
    if ((key == NULL) || (key->dp == NULL)) {
11547
0
        ret = BAD_FUNC_ARG;
11548
0
    }
11549
11550
0
    if (ret == 0) {
11551
        /* Calculate the size of the encoded public point. */
11552
0
        PRIVATE_KEY_UNLOCK();
11553
    #if defined(HAVE_COMP_KEY) && defined(HAVE_FIPS) && \
11554
            defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION == 2)
11555
        /* in earlier versions of FIPS the get length functionality is not
11556
         * available with compressed keys */
11557
        pubSz = key->dp ? key->dp->size : MAX_ECC_BYTES;
11558
        if (comp)
11559
            pubSz = 1 + pubSz;
11560
        else
11561
            pubSz = 1 + 2 * pubSz;
11562
        ret = LENGTH_ONLY_E;
11563
    #else
11564
0
        ret = wc_ecc_export_x963_ex(key, NULL, &pubSz, comp);
11565
0
    #endif
11566
0
        PRIVATE_KEY_LOCK();
11567
        /* LENGTH_ONLY_E on success. */
11568
0
        if (ret == LENGTH_ONLY_E) {
11569
0
            ret = 0;
11570
0
        }
11571
0
    }
11572
0
    if ((ret == 0) && with_header) {
11573
        /* Including SubjectPublicKeyInfo header. */
11574
0
        DECL_ASNSETDATA(dataASN, eccPublicKeyASN_Length);
11575
11576
0
        CALLOC_ASNSETDATA(dataASN, eccPublicKeyASN_Length, ret, key->heap);
11577
11578
        /* Get the length of the named curve OID to put into the encoding. */
11579
0
        curveIdSz = SetCurve(key, NULL, 0);
11580
0
        if (curveIdSz < 0) {
11581
0
            ret = curveIdSz;
11582
0
        }
11583
11584
0
        if (ret == 0) {
11585
            /* Set the key type OID. */
11586
0
            SetASN_OID(&dataASN[ECCPUBLICKEYASN_IDX_ALGOID_OID], ECDSAk,
11587
0
                    oidKeyType);
11588
            /* Set the curve OID. */
11589
0
            SetASN_ReplaceBuffer(&dataASN[ECCPUBLICKEYASN_IDX_ALGOID_CURVEID],
11590
0
                NULL, (word32)curveIdSz);
11591
            /* Don't try to write out explicit parameters. */
11592
0
            dataASN[ECCPUBLICKEYASN_IDX_ALGOID_PARAMS].noOut = 1;
11593
            /* Set size of public point to ensure space is made for it. */
11594
0
            SetASN_Buffer(&dataASN[ECCPUBLICKEYASN_IDX_PUBKEY], NULL, pubSz);
11595
            /* Calculate size of ECC public key. */
11596
0
            ret = SizeASN_Items(eccPublicKeyASN, dataASN,
11597
0
                                eccPublicKeyASN_Length, &sz);
11598
0
        }
11599
11600
        /* Check buffer, if passed in, is big enough for encoded data. */
11601
0
        if ((ret == 0) && (output != NULL) && (sz > outLen)) {
11602
0
            ret = BUFFER_E;
11603
0
        }
11604
0
        if ((ret == 0) && (output != NULL)) {
11605
            /* Encode ECC public key. */
11606
0
            SetASN_Items(eccPublicKeyASN, dataASN, eccPublicKeyASN_Length,
11607
0
                         output);
11608
            /* Skip to where public point is to be encoded. */
11609
0
            output += sz - (int)pubSz;
11610
            /* Cache the location to place the name curve OID. */
11611
0
            curveOid = (byte*)
11612
0
                dataASN[ECCPUBLICKEYASN_IDX_ALGOID_CURVEID].data.buffer.data;
11613
0
        }
11614
11615
0
        FREE_ASNSETDATA(dataASN, key->heap);
11616
0
    }
11617
0
    else if ((ret == 0) && (output != NULL) && (pubSz > (word32)outLen)) {
11618
0
        ret = BUFFER_E;
11619
0
    }
11620
0
    else {
11621
        /* Total size is the public point size. */
11622
0
        sz = (int)pubSz;
11623
0
    }
11624
11625
0
    if ((ret == 0) && (output != NULL)) {
11626
        /* Put named curve OID data into encoding. */
11627
0
        curveIdSz = SetCurve(key, curveOid, (size_t)curveIdSz);
11628
0
        if (curveIdSz < 0) {
11629
0
            ret = curveIdSz;
11630
0
        }
11631
0
    }
11632
0
    if ((ret == 0) && (output != NULL)) {
11633
        /* Encode public point. */
11634
0
        PRIVATE_KEY_UNLOCK();
11635
0
        ret = wc_ecc_export_x963_ex(key, output, &pubSz, comp);
11636
0
        PRIVATE_KEY_LOCK();
11637
0
    }
11638
0
    if (ret == 0) {
11639
        /* Return the size of the encoding. */
11640
0
        ret = sz;
11641
0
    }
11642
11643
0
    return ret;
11644
0
#endif
11645
0
}
11646
11647
11648
/* Encode the public part of an ECC key in a DER.
11649
 *
11650
 * Pass NULL for output to get the size of the encoding.
11651
 *
11652
 * @param [in]  key            ECC key object.
11653
 * @param [out] output         Buffer to hold DER encoding.
11654
 * @param [in]  inLen          Size of buffer in bytes.
11655
 * @param [in]  with_AlgCurve  Whether to use SubjectPublicKeyInfo format.
11656
 * @return  Size of encoded data in bytes on success.
11657
 * @return  BAD_FUNC_ARG when key or key's parameters is NULL.
11658
 * @return  MEMORY_E when dynamic memory allocation failed.
11659
 */
11660
WOLFSSL_ABI
11661
int wc_EccPublicKeyToDer(ecc_key* key, byte* output, word32 inLen,
11662
                                                              int with_AlgCurve)
11663
0
{
11664
0
    return SetEccPublicKey(output, key, (int)inLen, with_AlgCurve, 0);
11665
0
}
11666
11667
int wc_EccPublicKeyToDer_ex(ecc_key* key, byte* output, word32 inLen,
11668
                                                    int with_AlgCurve, int comp)
11669
0
{
11670
0
    return SetEccPublicKey(output, key, (int)inLen, with_AlgCurve, comp);
11671
0
}
11672
11673
int wc_EccPublicKeyDerSize(ecc_key* key, int with_AlgCurve)
11674
0
{
11675
0
    return SetEccPublicKey(NULL, key, 0, with_AlgCurve, 0);
11676
0
}
11677
11678
#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */
11679
11680
#ifdef WOLFSSL_ASN_TEMPLATE
11681
#if defined(WC_ENABLE_ASYM_KEY_EXPORT) || defined(WC_ENABLE_ASYM_KEY_IMPORT)
11682
/* ASN.1 template for Ed25519 and Ed448 public key (SubkectPublicKeyInfo).
11683
 * RFC 8410, 4 - Subject Public Key Fields
11684
 */
11685
static const ASNItem edPubKeyASN[] = {
11686
            /* SubjectPublicKeyInfo */
11687
/* SEQ        */ { 0, ASN_SEQUENCE, 1, 1, 0 },
11688
                                     /* AlgorithmIdentifier */
11689
/* ALGOID_SEQ */     { 1, ASN_SEQUENCE, 1, 1, 0 },
11690
                                         /* Ed25519/Ed448 OID */
11691
/* ALGOID_OID */         { 2, ASN_OBJECT_ID, 0, 0, 1 },
11692
                                     /* Public key stream */
11693
/* PUBKEY     */     { 1, ASN_BIT_STRING, 0, 0, 0 },
11694
};
11695
enum {
11696
    EDPUBKEYASN_IDX_SEQ = 0,
11697
    EDPUBKEYASN_IDX_ALGOID_SEQ,
11698
    EDPUBKEYASN_IDX_ALGOID_OID,
11699
    EDPUBKEYASN_IDX_PUBKEY
11700
};
11701
11702
/* Number of items in ASN.1 template for Ed25519 and Ed448 public key. */
11703
0
#define edPubKeyASN_Length (sizeof(edPubKeyASN) / sizeof(ASNItem))
11704
#endif /* WC_ENABLE_ASYM_KEY_EXPORT || WC_ENABLE_ASYM_KEY_IMPORT */
11705
#endif /* WOLFSSL_ASN_TEMPLATE */
11706
11707
#ifdef WC_ENABLE_ASYM_KEY_EXPORT
11708
11709
/* Build ASN.1 formatted public key based on RFC 8410
11710
 *
11711
 * Pass NULL for output to get the size of the encoding.
11712
 *
11713
 * @param [in]  pubKey       public key buffer
11714
 * @param [in]  pubKeyLen    public ket buffer length
11715
 * @param [out] output       Buffer to put encoded data in (optional)
11716
 * @param [in]  outLen       Size of buffer in bytes
11717
 * @param [in]  keyType      is "enum Key_Sum" like ED25519k
11718
 * @param [in]  withHeader   Whether to include SubjectPublicKeyInfo around key.
11719
 * @return  Size of encoded data in bytes on success
11720
 * @return  BAD_FUNC_ARG when key is NULL.
11721
 * @return  MEMORY_E when dynamic memory allocation failed.
11722
 */
11723
int SetAsymKeyDerPublic(const byte* pubKey, word32 pubKeyLen,
11724
    byte* output, word32 outLen, int keyType, int withHeader)
11725
0
{
11726
0
    int ret = 0;
11727
#ifndef WOLFSSL_ASN_TEMPLATE
11728
    word32 idx = 0;
11729
    word32 seqDataSz = 0;
11730
    word32 sz;
11731
#else
11732
0
    int sz = 0;
11733
0
    DECL_ASNSETDATA(dataASN, edPubKeyASN_Length);
11734
0
#endif
11735
11736
0
    if (pubKey == NULL) {
11737
0
        return BAD_FUNC_ARG;
11738
0
    }
11739
11740
#ifndef WOLFSSL_ASN_TEMPLATE
11741
    /* calculate size */
11742
    if (withHeader) {
11743
        word32 algoSz      = SetAlgoID(keyType, NULL, oidKeyType, 0);
11744
        word32 bitStringSz = SetBitString(pubKeyLen, 0, NULL);
11745
11746
        seqDataSz = algoSz + bitStringSz + pubKeyLen;
11747
        sz = SetSequence(seqDataSz, NULL) + seqDataSz;
11748
    }
11749
    else {
11750
        sz = pubKeyLen;
11751
    }
11752
11753
    /* checkout output size */
11754
    if (output != NULL && sz > outLen) {
11755
        ret = BUFFER_E;
11756
    }
11757
11758
    /* headers */
11759
    if (ret == 0 && output != NULL && withHeader) {
11760
        /* sequence */
11761
        idx = SetSequence(seqDataSz, output);
11762
        /* algo */
11763
        idx += SetAlgoID(keyType, output + idx, oidKeyType, 0);
11764
        /* bit string */
11765
        idx += SetBitString(pubKeyLen, 0, output + idx);
11766
    }
11767
11768
    if (ret == 0 && output != NULL) {
11769
        /* pub */
11770
        XMEMCPY(output + idx, pubKey, pubKeyLen);
11771
        idx += pubKeyLen;
11772
11773
        sz = idx;
11774
    }
11775
11776
    if (ret == 0) {
11777
        ret = (int)sz;
11778
    }
11779
#else
11780
0
    if (withHeader) {
11781
0
        CALLOC_ASNSETDATA(dataASN, edPubKeyASN_Length, ret, NULL);
11782
11783
0
        if (ret == 0) {
11784
            /* Set the OID. */
11785
0
            SetASN_OID(&dataASN[EDPUBKEYASN_IDX_ALGOID_OID], (word32)keyType,
11786
0
                    oidKeyType);
11787
            /* Leave space for public point. */
11788
0
            SetASN_Buffer(&dataASN[EDPUBKEYASN_IDX_PUBKEY], NULL, pubKeyLen);
11789
            /* Calculate size of public key encoding. */
11790
0
            ret = SizeASN_Items(edPubKeyASN, dataASN, edPubKeyASN_Length, &sz);
11791
0
        }
11792
0
        if ((ret == 0) && (output != NULL) && (sz > (int)outLen)) {
11793
0
            ret = BUFFER_E;
11794
0
        }
11795
0
        if ((ret == 0) && (output != NULL)) {
11796
            /* Encode public key. */
11797
0
            SetASN_Items(edPubKeyASN, dataASN, edPubKeyASN_Length, output);
11798
            /* Set location to encode public point. */
11799
0
            output = (byte*)dataASN[EDPUBKEYASN_IDX_PUBKEY].data.buffer.data;
11800
0
        }
11801
11802
0
        FREE_ASNSETDATA(dataASN, NULL);
11803
0
    }
11804
0
    else if ((output != NULL) && (pubKeyLen > outLen)) {
11805
0
        ret = BUFFER_E;
11806
0
    }
11807
0
    else if (ret == 0) {
11808
0
        sz = (int)pubKeyLen;
11809
0
    }
11810
11811
0
    if ((ret == 0) && (output != NULL)) {
11812
        /* Put public key into space provided. */
11813
0
        XMEMCPY(output, pubKey, pubKeyLen);
11814
0
    }
11815
0
    if (ret == 0) {
11816
0
        ret = sz;
11817
0
    }
11818
0
#endif /* WOLFSSL_ASN_TEMPLATE */
11819
0
    return ret;
11820
0
}
11821
#endif /* WC_ENABLE_ASYM_KEY_EXPORT */
11822
11823
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
11824
/* Encode the public part of an Ed25519 key in DER.
11825
 *
11826
 * Pass NULL for output to get the size of the encoding.
11827
 *
11828
 * @param [in]  key       Ed25519 key object.
11829
 * @param [out] output    Buffer to put encoded data in.
11830
 * @param [in]  outLen    Size of buffer in bytes.
11831
 * @param [in]  withAlg   Whether to use SubjectPublicKeyInfo format.
11832
 * @return  Size of encoded data in bytes on success.
11833
 * @return  BAD_FUNC_ARG when key is NULL.
11834
 * @return  MEMORY_E when dynamic memory allocation failed.
11835
 */
11836
int wc_Ed25519PublicKeyToDer(ed25519_key* key, byte* output, word32 inLen,
11837
                             int withAlg)
11838
0
{
11839
0
    int    ret;
11840
0
    byte   pubKey[ED25519_PUB_KEY_SIZE];
11841
0
    word32 pubKeyLen = (word32)sizeof(pubKey);
11842
11843
0
    if (key == NULL) {
11844
0
        return BAD_FUNC_ARG;
11845
0
    }
11846
11847
0
    ret = wc_ed25519_export_public(key, pubKey, &pubKeyLen);
11848
0
    if (ret == 0) {
11849
0
        ret = SetAsymKeyDerPublic(pubKey, pubKeyLen, output, inLen,
11850
0
            ED25519k, withAlg);
11851
0
    }
11852
0
    return ret;
11853
0
}
11854
#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_EXPORT */
11855
11856
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
11857
/* Encode the public part of an Ed448 key in DER.
11858
 *
11859
 * Pass NULL for output to get the size of the encoding.
11860
 *
11861
 * @param [in]  key       Ed448 key object.
11862
 * @param [out] output    Buffer to put encoded data in.
11863
 * @param [in]  outLen    Size of buffer in bytes.
11864
 * @param [in]  withAlg   Whether to use SubjectPublicKeyInfo format.
11865
 * @return  Size of encoded data in bytes on success.
11866
 * @return  BAD_FUNC_ARG when key is NULL.
11867
 * @return  MEMORY_E when dynamic memory allocation failed.
11868
 */
11869
int wc_Ed448PublicKeyToDer(ed448_key* key, byte* output, word32 inLen,
11870
                           int withAlg)
11871
0
{
11872
0
    int    ret;
11873
0
    byte   pubKey[ED448_PUB_KEY_SIZE];
11874
0
    word32 pubKeyLen = (word32)sizeof(pubKey);
11875
11876
0
    if (key == NULL) {
11877
0
        return BAD_FUNC_ARG;
11878
0
    }
11879
11880
0
    ret = wc_ed448_export_public(key, pubKey, &pubKeyLen);
11881
0
    if (ret == 0) {
11882
0
        ret = SetAsymKeyDerPublic(pubKey, pubKeyLen, output, inLen,
11883
0
            ED448k, withAlg);
11884
0
    }
11885
0
    return ret;
11886
0
}
11887
#endif /* HAVE_ED448 && HAVE_ED448_KEY_EXPORT */
11888
#if !defined(NO_RSA) && !defined(NO_CERTS)
11889
#ifdef WOLFSSL_ASN_TEMPLATE
11890
/* ASN.1 template for header before RSA key in certificate. */
11891
static const ASNItem rsaCertKeyASN[] = {
11892
/* STR */ { 0, ASN_BIT_STRING, 0, 1, 0 },
11893
/* SEQ */     { 1, ASN_SEQUENCE, 1, 0, 0 },
11894
};
11895
enum {
11896
    RSACERTKEYASN_IDX_STR = 0,
11897
    RSACERTKEYASN_IDX_SEQ
11898
};
11899
11900
/* Number of items in ASN.1 template for header before RSA key in cert. */
11901
0
#define rsaCertKeyASN_Length (sizeof(rsaCertKeyASN) / sizeof(ASNItem))
11902
#endif
11903
11904
/* Store RSA key pointer and length in certificate object.
11905
 *
11906
 * @param [in, out] cert    Certificate object.
11907
 * @param [in]      source  Buffer containing encoded key.
11908
 * @param [in, out] srcIdx  On in, start of RSA key data.
11909
 *                          On out, start of element after RSA key data.
11910
 * @param [in]      maxIdx  Maximum index of key data.
11911
 * @return  0 on success.
11912
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
11913
 *          is invalid.
11914
 * @return  BUFFER_E when data in buffer is too small.
11915
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
11916
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
11917
 *          non-zero length.
11918
 */
11919
static int StoreRsaKey(DecodedCert* cert, const byte* source, word32* srcIdx,
11920
                       word32 maxIdx)
11921
0
{
11922
#ifndef WOLFSSL_ASN_TEMPLATE
11923
    int    length;
11924
    int    pubLen;
11925
    word32 pubIdx;
11926
11927
    if (CheckBitString(source, srcIdx, &pubLen, maxIdx, 1, NULL) != 0)
11928
        return ASN_PARSE_E;
11929
    pubIdx = *srcIdx;
11930
11931
    if (GetSequence(source, srcIdx, &length, pubIdx + (word32)pubLen) < 0)
11932
        return ASN_PARSE_E;
11933
11934
#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT)
11935
    cert->sigCtx.CertAtt.pubkey_n_start =
11936
            cert->sigCtx.CertAtt.pubkey_e_start = pubIdx;
11937
#endif
11938
    cert->pubKeySize = (word32)pubLen;
11939
    cert->publicKey = source + pubIdx;
11940
#ifdef WOLFSSL_MAXQ10XX_TLS
11941
    cert->publicKeyIndex = pubIdx;
11942
#endif
11943
    *srcIdx += (word32)length;
11944
11945
#ifdef HAVE_OCSP
11946
    return CalcHashId_ex(cert->publicKey, cert->pubKeySize,
11947
        cert->subjectKeyHash, HashIdAlg(cert->signatureOID));
11948
#else
11949
    return 0;
11950
#endif
11951
#else
11952
0
    ASNGetData dataASN[rsaCertKeyASN_Length];
11953
0
    int ret;
11954
11955
    /* No dynamic data. */
11956
0
    XMEMSET(dataASN, 0, sizeof(dataASN));
11957
    /* Decode the header before the key data. */
11958
0
    ret = GetASN_Items(rsaCertKeyASN, dataASN, rsaCertKeyASN_Length, 1, source,
11959
0
                       srcIdx, maxIdx);
11960
0
    if (ret == 0) {
11961
        /* Store the pointer and length in certificate object starting at
11962
         * SEQUENCE. */
11963
0
        GetASN_GetConstRef(&dataASN[RSACERTKEYASN_IDX_STR],
11964
0
                &cert->publicKey, &cert->pubKeySize);
11965
11966
#ifdef WOLFSSL_MAXQ10XX_TLS
11967
    cert->publicKeyIndex = dataASN[RSACERTKEYASN_IDX_SEQ].offset;
11968
#endif
11969
11970
    #if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT)
11971
        /* Start of SEQUENCE. */
11972
        cert->sigCtx.CertAtt.pubkey_n_start =
11973
            cert->sigCtx.CertAtt.pubkey_e_start = dataASN[RSACERTKEYASN_IDX_SEQ].offset;
11974
    #endif
11975
    #ifdef HAVE_OCSP
11976
        /* Calculate the hash of the public key for OCSP. */
11977
        ret = CalcHashId_ex(cert->publicKey, cert->pubKeySize,
11978
                         cert->subjectKeyHash, HashIdAlg(cert->signatureOID));
11979
    #endif
11980
0
    }
11981
11982
0
    return ret;
11983
0
#endif /* WOLFSSL_ASN_TEMPLATE */
11984
0
}
11985
#endif /* !NO_RSA && !NO_CERTS */
11986
11987
#if defined(HAVE_ECC) && !defined(NO_CERTS)
11988
11989
#ifdef WOLFSSL_ASN_TEMPLATE
11990
/* ASN.1 template for header before ECC key in certificate. */
11991
static const ASNItem eccCertKeyASN[] = {
11992
/* OID        */     { 1, ASN_OBJECT_ID, 0, 0, 2 },
11993
                            /* Algo parameters */
11994
/* PARAMS     */     { 1, ASN_SEQUENCE, 1, 0, 2 },
11995
                            /* Subject public key */
11996
/* SUBJPUBKEY */ { 0, ASN_BIT_STRING, 0, 0, 0 },
11997
};
11998
enum {
11999
    ECCCERTKEYASN_IDX_OID = 0,
12000
    ECCCERTKEYASN_IDX_PARAMS,
12001
    ECCCERTKEYASN_IDX_SUBJPUBKEY
12002
};
12003
12004
/* Number of items in ASN.1 template for header before ECC key in cert. */
12005
0
#define eccCertKeyASN_Length (sizeof(eccCertKeyASN) / sizeof(ASNItem))
12006
#endif /* WOLFSSL_ASN_TEMPLATE */
12007
12008
/* Store public ECC key in certificate object.
12009
 *
12010
 * Parse parameters and store public key data.
12011
 *
12012
 * @param [in, out] cert       Certificate object.
12013
 * @param [in]      source     Buffer containing encoded key.
12014
 * @param [in, out] srcIdx     On in, start of ECC key data.
12015
 *                             On out, start of element after ECC key data.
12016
 * @param [in]      maxIdx     Maximum index of key data.
12017
 * @param [in]      pubKey     Buffer holding encoded public key.
12018
 * @param [in]      pubKeyLen  Length of encoded public key in bytes.
12019
 * @return  0 on success.
12020
 * @return  BAD_FUNC_ARG when pubKey is NULL.
12021
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
12022
 *          is invalid.
12023
 * @return  BUFFER_E when data in buffer is too small.
12024
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
12025
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
12026
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
12027
 *          non-zero length.
12028
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
12029
 */
12030
static int StoreEccKey(DecodedCert* cert, const byte* source, word32* srcIdx,
12031
                       word32 maxIdx, const byte* pubKey, word32 pubKeyLen)
12032
0
{
12033
#ifndef WOLFSSL_ASN_TEMPLATE
12034
    int ret;
12035
    word32 localIdx;
12036
    byte* publicKey;
12037
    byte  tag;
12038
    int length;
12039
12040
    if (pubKey == NULL) {
12041
        return BAD_FUNC_ARG;
12042
    }
12043
12044
    localIdx = *srcIdx;
12045
    if (GetASNTag(source, &localIdx, &tag, maxIdx) < 0)
12046
        return ASN_PARSE_E;
12047
12048
    if (tag != (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
12049
        if (GetObjectId(source, srcIdx, &cert->pkCurveOID, oidCurveType,
12050
                                                                    maxIdx) < 0)
12051
            return ASN_PARSE_E;
12052
12053
        if ((ret = CheckCurve(cert->pkCurveOID)) < 0)
12054
            return ECC_CURVE_OID_E;
12055
12056
    #if defined(WOLFSSL_RENESAS_SCEPROTECT) || defined(WOLFSSL_RENESAS_TSIP_TLS)
12057
        cert->sigCtx.CertAtt.curve_id = ret;
12058
    #else
12059
        (void)ret;
12060
    #endif
12061
        /* key header */
12062
        ret = CheckBitString(source, srcIdx, &length, maxIdx, 1, NULL);
12063
        if (ret != 0)
12064
            return ret;
12065
    #if defined(WOLFSSL_RENESAS_SCEPROTECT) || defined(WOLFSSL_RENESAS_TSIP_TLS)
12066
        cert->sigCtx.CertAtt.pubkey_n_start =
12067
                cert->sigCtx.CertAtt.pubkey_e_start = (*srcIdx + 1);
12068
        cert->sigCtx.CertAtt.pubkey_n_len = ((length - 1) >> 1);
12069
        cert->sigCtx.CertAtt.pubkey_e_start +=
12070
                cert->sigCtx.CertAtt.pubkey_n_len;
12071
        cert->sigCtx.CertAtt.pubkey_e_len   =
12072
                cert->sigCtx.CertAtt.pubkey_n_len;
12073
    #endif
12074
    #ifdef WOLFSSL_MAXQ10XX_TLS
12075
        cert->publicKeyIndex = *srcIdx + 1;
12076
    #endif
12077
12078
    #ifdef HAVE_OCSP
12079
        ret = CalcHashId_ex(source + *srcIdx, (word32)length,
12080
            cert->subjectKeyHash, HashIdAlg(cert->signatureOID));
12081
        if (ret != 0)
12082
            return ret;
12083
    #endif
12084
        *srcIdx += (word32)length;
12085
    }
12086
12087
    publicKey = (byte*)XMALLOC(pubKeyLen, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
12088
    if (publicKey == NULL)
12089
        return MEMORY_E;
12090
    XMEMCPY(publicKey, pubKey, pubKeyLen);
12091
    cert->publicKey = publicKey;
12092
    cert->pubKeyStored = 1;
12093
    cert->pubKeySize   = pubKeyLen;
12094
12095
    return 0;
12096
#else
12097
0
    int ret = 0;
12098
0
    DECL_ASNGETDATA(dataASN, eccCertKeyASN_Length);
12099
0
    byte* publicKey;
12100
12101
    /* Validate parameters. */
12102
0
    if (pubKey == NULL) {
12103
0
        ret = BAD_FUNC_ARG;
12104
0
    }
12105
12106
    /* Clear dynamic data and check OID is a curve. */
12107
0
    CALLOC_ASNGETDATA(dataASN, eccCertKeyASN_Length, ret, cert->heap);
12108
0
    if (ret == 0) {
12109
0
        GetASN_OID(&dataASN[ECCCERTKEYASN_IDX_OID], oidCurveType);
12110
        /* Parse ECC public key header. */
12111
0
        ret = GetASN_Items(eccCertKeyASN, dataASN, eccCertKeyASN_Length, 1,
12112
0
                source, srcIdx, maxIdx);
12113
0
    }
12114
0
    if (ret == 0) {
12115
0
        if (dataASN[ECCCERTKEYASN_IDX_OID].tag != 0) {
12116
            /* Store curve OID. */
12117
0
            cert->pkCurveOID = dataASN[ECCCERTKEYASN_IDX_OID].data.oid.sum;
12118
0
        }
12119
        /* Ignore explicit parameters. */
12120
12121
    #ifdef WOLFSSL_MAXQ10XX_TLS
12122
        cert->publicKeyIndex =
12123
            GetASNItem_DataIdx(dataASN[ECCCERTKEYASN_IDX_SUBJPUBKEY], source)
12124
            + 1;
12125
    #endif
12126
12127
    #ifdef HAVE_OCSP
12128
        /* Calculate the hash of the subject public key for OCSP. */
12129
        ret = CalcHashId_ex(dataASN[ECCCERTKEYASN_IDX_SUBJPUBKEY].data.ref.data,
12130
                         dataASN[ECCCERTKEYASN_IDX_SUBJPUBKEY].data.ref.length,
12131
                         cert->subjectKeyHash, HashIdAlg(cert->signatureOID));
12132
    }
12133
    if (ret == 0) {
12134
    #endif
12135
        /* Store public key data length. */
12136
0
        cert->pubKeySize = pubKeyLen;
12137
        /* Must allocated space for key.
12138
         * Don't memcpy into constant pointer so use temp. */
12139
0
        publicKey = (byte*)XMALLOC(cert->pubKeySize, cert->heap,
12140
0
                                   DYNAMIC_TYPE_PUBLIC_KEY);
12141
0
        if (publicKey == NULL) {
12142
0
            ret = MEMORY_E;
12143
0
        }
12144
0
        else {
12145
            /* Copy in whole public key and store pointer. */
12146
0
            XMEMCPY(publicKey, pubKey, cert->pubKeySize);
12147
0
            cert->publicKey = publicKey;
12148
            /* Indicate publicKey needs to be freed. */
12149
0
            cert->pubKeyStored = 1;
12150
0
        }
12151
0
    }
12152
0
    FREE_ASNGETDATA(dataASN, cert->heap);
12153
12154
0
    return ret;
12155
0
#endif /* WOLFSSL_ASN_TEMPLATE */
12156
0
}
12157
#endif /* HAVE_ECC && !NO_CERTS */
12158
12159
#ifndef NO_CERTS
12160
#if !defined(NO_DSA)
12161
#ifdef WOLFSSL_ASN_TEMPLATE
12162
/* ASN.1 template for DSA key in certificate.
12163
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
12164
 * RFC 3279, 2.3.2 - DSA in SubjectPublicKeyInfo
12165
 */
12166
static const ASNItem dsaCertKeyASN[] = {
12167
/*  0 */        { 1, ASN_SEQUENCE, 1, 1, 0 },
12168
/*  1 */            { 2, ASN_INTEGER, 0, 0, 0 },
12169
/*  2 */            { 2, ASN_INTEGER, 0, 0, 0 },
12170
/*  3 */            { 2, ASN_INTEGER, 0, 0, 0 },
12171
/*  4 */    { 0, ASN_BIT_STRING, 0, 1, 0 },
12172
/*  5 */        { 1, ASN_INTEGER, 0, 0, 0 },
12173
};
12174
12175
/* Number of items in ASN.1 template for DSA key in certificate. */
12176
#define dsaCertKeyASN_Length (sizeof(dsaCertKeyASN) / sizeof(ASNItem))
12177
#endif /* WOLFSSL_ASN_TEMPLATE */
12178
12179
/* Parse DSA parameters to ensure valid.
12180
 *
12181
 * @param [in]      source  Buffer containing encoded key.
12182
 * @param [in, out] srcIdx  On in, start of DSA key data.
12183
 *                          On out, start of element after DSA key data.
12184
 * @param [in]      maxIdx  Maximum index of key data.
12185
 * @param [in]      heap    Dynamic memory hint.
12186
 * @return  0 on success.
12187
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
12188
 *          is invalid.
12189
 * @return  BUFFER_E when data in buffer is too small.
12190
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
12191
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
12192
 *          non-zero length.
12193
 */
12194
static int ParseDsaKey(const byte* source, word32* srcIdx, word32 maxIdx,
12195
                       void* heap)
12196
{
12197
#ifndef WOLFSSL_ASN_TEMPLATE
12198
    int ret;
12199
    int length;
12200
12201
    (void)heap;
12202
12203
    ret = GetSequence(source, srcIdx, &length, maxIdx);
12204
    if (ret < 0)
12205
        return ret;
12206
12207
    ret = SkipInt(source, srcIdx, maxIdx);
12208
    if (ret != 0)
12209
        return ret;
12210
    ret = SkipInt(source, srcIdx, maxIdx);
12211
    if (ret != 0)
12212
        return ret;
12213
    ret = SkipInt(source, srcIdx, maxIdx);
12214
    if (ret != 0)
12215
        return ret;
12216
12217
    ret = CheckBitString(source, srcIdx, &length, maxIdx, 1, NULL);
12218
    if (ret != 0)
12219
        return ret;
12220
12221
    ret = GetASNInt(source, srcIdx, &length, maxIdx);
12222
    if (ret != 0)
12223
        return ASN_PARSE_E;
12224
12225
    *srcIdx += (word32)length;
12226
12227
    return 0;
12228
#else
12229
    DECL_ASNGETDATA(dataASN, dsaCertKeyASN_Length);
12230
    int ret = 0;
12231
12232
    (void)heap;
12233
12234
    CALLOC_ASNGETDATA(dataASN, dsaCertKeyASN_Length, ret, heap);
12235
    if (ret == 0) {
12236
        /* Parse the DSA key data to ensure valid. */
12237
        ret = GetASN_Items(dsaCertKeyASN, dataASN, dsaCertKeyASN_Length, 1,
12238
                           source, srcIdx, maxIdx);
12239
    }
12240
12241
    FREE_ASNGETDATA(dataASN, heap);
12242
    return ret;
12243
#endif /* WOLFSSL_ASN_TEMPLATE */
12244
}
12245
#endif /* !NO_DSA */
12246
12247
/* Decode the SubjectPublicKeyInfo block in a certificate.
12248
 *
12249
 * Stores the public key in fields of the certificate object.
12250
 * Validates the BER/DER items and does not store in a key object.
12251
 *
12252
 * @param [in, out] cert      Decoded certificate oject.
12253
 * @param [in]      source    BER/DER encoded SubjectPublicKeyInfo block.
12254
 * @param [in, out] inOutIdx  On in, start of public key.
12255
 *                            On out, start of ASN.1 item after public key.
12256
 * @param [in]      maxIdx    Maximum index of key data.
12257
 * @return  0 on success.
12258
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
12259
 *          is invalid.
12260
 * @return  BUFFER_E when data in buffer is too small.
12261
 */
12262
static int GetCertKey(DecodedCert* cert, const byte* source, word32* inOutIdx,
12263
                      word32 maxIdx)
12264
0
{
12265
0
    word32 srcIdx = *inOutIdx;
12266
0
#if defined(HAVE_ECC) || !defined(NO_DSA)
12267
0
    int pubLen;
12268
0
#endif
12269
0
#if defined(HAVE_ECC) || !defined(NO_DSA)
12270
0
    int pubIdx = (int)srcIdx;
12271
0
#endif
12272
0
    int ret = 0;
12273
0
    int length;
12274
12275
    /* Validate paramaters. */
12276
0
    if (source == NULL) {
12277
0
        return ASN_PARSE_E;
12278
0
    }
12279
12280
#ifndef WOLFSSL_ASN_TEMPLATE
12281
    if (GetSequence(source, &srcIdx, &length, maxIdx) < 0)
12282
#else
12283
    /* Get SEQUENCE and expect all data to be accounted for. */
12284
0
    if (GetASN_Sequence(source, &srcIdx, &length, maxIdx, 1) != 0)
12285
0
#endif
12286
0
    {
12287
0
        return ASN_PARSE_E;
12288
0
    }
12289
12290
0
#if defined(HAVE_ECC) || !defined(NO_DSA)
12291
0
    pubLen = (int)srcIdx - pubIdx + length;
12292
0
#endif
12293
0
    maxIdx = srcIdx + (word32)length;
12294
12295
    /* Decode the algorithm identifier for the key. */
12296
0
    if (GetAlgoId(source, &srcIdx, &cert->keyOID, oidKeyType, maxIdx) < 0) {
12297
0
        return ASN_PARSE_E;
12298
0
    }
12299
12300
0
    (void)length;
12301
12302
    /* Parse each type of public key. */
12303
0
    switch (cert->keyOID) {
12304
0
#ifndef NO_RSA
12305
0
    #ifdef WC_RSA_PSS
12306
0
        case RSAPSSk:
12307
0
            if (srcIdx != maxIdx &&
12308
0
                          source[srcIdx] == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
12309
0
                word32 seqIdx = srcIdx;
12310
0
                int seqLen;
12311
                /* Not set when -1. */
12312
0
                enum wc_HashType hash = WC_HASH_TYPE_NONE;
12313
0
                int mgf = -1;
12314
0
                int saltLen = 0;
12315
                /* Defaults for sig algorithm parameters. */
12316
0
                enum wc_HashType sigHash = WC_HASH_TYPE_SHA;
12317
0
                int sigMgf = WC_MGF1SHA1;
12318
0
                int sigSaltLen = 20;
12319
12320
0
                if (GetSequence(source, &srcIdx, &seqLen, maxIdx) < 0) {
12321
0
                    return ASN_PARSE_E;
12322
0
                }
12323
                /* Get the pubic key parameters. */
12324
0
                ret = DecodeRsaPssParams(source + seqIdx,
12325
0
                    (word32)seqLen + srcIdx - seqIdx, &hash, &mgf, &saltLen);
12326
0
                if (ret != 0) {
12327
0
                    return ASN_PARSE_E;
12328
0
                }
12329
                /* Get the signature parameters. */
12330
0
                ret = DecodeRsaPssParams(source + cert->sigParamsIndex,
12331
0
                    cert->sigParamsLength, &sigHash, &sigMgf, &sigSaltLen);
12332
0
                if (ret != 0) {
12333
0
                    return ASN_PARSE_E;
12334
0
                }
12335
                /* Validated signature params match public key params. */
12336
0
                if (hash != WC_HASH_TYPE_NONE && hash != sigHash) {
12337
0
                    WOLFSSL_MSG("RSA PSS: hash not matching signature hash");
12338
0
                    return ASN_PARSE_E;
12339
0
                }
12340
0
                if (mgf != -1 && mgf != sigMgf) {
12341
0
                    WOLFSSL_MSG("RSA PSS: MGF not matching signature MGF");
12342
0
                    return ASN_PARSE_E;
12343
0
                }
12344
0
                if (saltLen > sigSaltLen) {
12345
0
                    WOLFSSL_MSG("RSA PSS: sig salt length too small");
12346
0
                    return ASN_PARSE_E;
12347
0
                }
12348
0
                srcIdx += (word32)seqLen;
12349
0
            }
12350
0
            FALL_THROUGH;
12351
0
    #endif /* WC_RSA_PSS */
12352
0
        case RSAk:
12353
0
            ret = StoreRsaKey(cert, source, &srcIdx, maxIdx);
12354
0
            break;
12355
0
#endif /* NO_RSA */
12356
0
    #ifdef HAVE_ECC
12357
0
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
12358
0
        case SM2k:
12359
0
    #endif
12360
0
        case ECDSAk:
12361
0
            ret = StoreEccKey(cert, source, &srcIdx, maxIdx, source + pubIdx,
12362
0
                              (word32)pubLen);
12363
0
            break;
12364
0
    #endif /* HAVE_ECC */
12365
0
    #ifdef HAVE_ED25519
12366
0
        case ED25519k:
12367
0
            cert->pkCurveOID = ED25519k;
12368
0
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
12369
0
            break;
12370
0
    #endif /* HAVE_ED25519 */
12371
0
    #ifdef HAVE_ED448
12372
0
        case ED448k:
12373
0
            cert->pkCurveOID = ED448k;
12374
0
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
12375
0
            break;
12376
0
    #endif /* HAVE_ED448 */
12377
    #if defined(HAVE_PQC) && defined(HAVE_LIBOQS)
12378
    #ifdef HAVE_FALCON
12379
        case FALCON_LEVEL1k:
12380
            cert->pkCurveOID = FALCON_LEVEL1k;
12381
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
12382
            break;
12383
        case FALCON_LEVEL5k:
12384
            cert->pkCurveOID = FALCON_LEVEL5k;
12385
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
12386
            break;
12387
    #endif /* HAVE_FALCON */
12388
    #ifdef HAVE_DILITHIUM
12389
        case DILITHIUM_LEVEL2k:
12390
            cert->pkCurveOID = DILITHIUM_LEVEL2k;
12391
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
12392
            break;
12393
        case DILITHIUM_LEVEL3k:
12394
            cert->pkCurveOID = DILITHIUM_LEVEL3k;
12395
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
12396
            break;
12397
        case DILITHIUM_LEVEL5k:
12398
            cert->pkCurveOID = DILITHIUM_LEVEL5k;
12399
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
12400
            break;
12401
    #endif /* HAVE_DILITHIUM */
12402
    #ifdef HAVE_SPHINCS
12403
        case SPHINCS_FAST_LEVEL1k:
12404
            cert->pkCurveOID = SPHINCS_FAST_LEVEL1k;
12405
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
12406
            break;
12407
        case SPHINCS_FAST_LEVEL3k:
12408
            cert->pkCurveOID = SPHINCS_FAST_LEVEL3k;
12409
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
12410
            break;
12411
        case SPHINCS_FAST_LEVEL5k:
12412
            cert->pkCurveOID = SPHINCS_FAST_LEVEL5k;
12413
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
12414
            break;
12415
        case SPHINCS_SMALL_LEVEL1k:
12416
            cert->pkCurveOID = SPHINCS_SMALL_LEVEL1k;
12417
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
12418
            break;
12419
        case SPHINCS_SMALL_LEVEL3k:
12420
            cert->pkCurveOID = SPHINCS_SMALL_LEVEL3k;
12421
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
12422
            break;
12423
        case SPHINCS_SMALL_LEVEL5k:
12424
            cert->pkCurveOID = SPHINCS_SMALL_LEVEL5k;
12425
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
12426
            break;
12427
    #endif /* HAVE_SPHINCS */
12428
    #endif /* HAVE_PQC */
12429
    #ifndef NO_DSA
12430
        case DSAk:
12431
            cert->publicKey = source + pubIdx;
12432
            cert->pubKeySize = (word32)pubLen;
12433
            ret = ParseDsaKey(source, &srcIdx, maxIdx, cert->heap);
12434
            break;
12435
    #endif /* NO_DSA */
12436
0
        default:
12437
0
            WOLFSSL_MSG("Unknown or not compiled in key OID");
12438
0
            WOLFSSL_ERROR_VERBOSE(ASN_UNKNOWN_OID_E);
12439
0
            ret = ASN_UNKNOWN_OID_E;
12440
0
    }
12441
12442
    /* Return index after public key. */
12443
0
    *inOutIdx = srcIdx;
12444
12445
    /* Return error code. */
12446
0
    return ret;
12447
0
}
12448
#endif
12449
12450
/* Return the hash algorithm to use with the signature algorithm.
12451
 *
12452
 * @param [in] oidSum  Signature id.
12453
 * @return  Hash algorithm id.
12454
 */
12455
int HashIdAlg(word32 oidSum)
12456
0
{
12457
0
    (void)oidSum;
12458
12459
0
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
12460
0
    if (oidSum == CTC_SM3wSM2) {
12461
0
        return WC_SM3;
12462
0
    }
12463
0
    if (oidSum == SM2k) {
12464
0
        return WC_SM3;
12465
0
    }
12466
0
#endif
12467
#if defined(NO_SHA) || (!defined(NO_SHA256) && defined(WC_ASN_HASH_SHA256))
12468
    return WC_SHA256;
12469
#else
12470
0
    return WC_SHA;
12471
0
#endif
12472
0
}
12473
12474
/* Calculate hash of the id using the SHA-1 or SHA-256.
12475
 *
12476
 * @param [in]  data  Data to hash.
12477
 * @param [in]  len   Length of data to hash.
12478
 * @param [out] hash  Buffer to hold hash.
12479
 * @return  0 on success.
12480
 * @return  MEMORY_E when dynamic memory allocation fails.
12481
 */
12482
int CalcHashId(const byte* data, word32 len, byte* hash)
12483
0
{
12484
    /* Use default hash algorithm. */
12485
0
    return CalcHashId_ex(data, len, hash,
12486
#if defined(NO_SHA) || (!defined(NO_SHA256) && defined(WC_ASN_HASH_SHA256))
12487
        WC_SHA256
12488
#else
12489
0
        WC_SHA
12490
0
#endif
12491
0
        );
12492
0
}
12493
12494
/* Calculate hash of the id using the SHA-1 or SHA-256.
12495
 *
12496
 * @param [in]  data  Data to hash.
12497
 * @param [in]  len   Length of data to hash.
12498
 * @param [out] hash  Buffer to hold hash.
12499
 * @return  0 on success.
12500
 * @return  MEMORY_E when dynamic memory allocation fails.
12501
 */
12502
int CalcHashId_ex(const byte* data, word32 len, byte* hash, int hashAlg)
12503
0
{
12504
0
    int ret;
12505
12506
0
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
12507
0
    if (hashAlg == WC_SM3) {
12508
0
        ret = wc_Sm3Hash(data, len, hash);
12509
0
    }
12510
0
    else
12511
0
#endif
12512
#if defined(NO_SHA) || (!defined(NO_SHA256) && defined(WC_ASN_HASH_SHA256))
12513
    if (hashAlg == WC_SHA256) {
12514
        ret = wc_Sha256Hash(data, len, hash);
12515
    }
12516
    else
12517
#elif !defined(NO_SHA)
12518
0
    if (hashAlg == WC_SHA) {
12519
0
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
12520
0
        XMEMSET(hash + WC_SHA_DIGEST_SIZE, 0, KEYID_SIZE - WC_SHA_DIGEST_SIZE);
12521
0
    #endif
12522
0
        ret = wc_ShaHash(data, len, hash);
12523
0
    }
12524
0
    else
12525
#else
12526
    (void)data;
12527
    (void)len;
12528
    (void)hash;
12529
#endif
12530
0
    {
12531
0
        ret = NOT_COMPILED_IN;
12532
0
    }
12533
12534
0
    return ret;
12535
0
}
12536
12537
#ifndef NO_CERTS
12538
/* Get the hash of the id using the SHA-1 or SHA-256.
12539
 *
12540
 * If the id is not the length of the hash, then hash it.
12541
 *
12542
 * @param [in]  id    Id to get hash for.
12543
 * @param [in]  len   Length of id in bytes.
12544
 * @param [out] hash  Buffer to hold hash.
12545
 * @return  0 on success.
12546
 * @return  MEMORY_E when dynamic memory allocation fails.
12547
 */
12548
static int GetHashId(const byte* id, int length, byte* hash, int hashAlg)
12549
0
{
12550
0
    int ret;
12551
12552
0
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
12553
0
    if (length == wc_HashGetDigestSize(wc_HashTypeConvert(hashAlg)))
12554
#else
12555
    if (length == KEYID_SIZE)
12556
#endif
12557
0
    {
12558
0
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
12559
0
        XMEMSET(hash + length, 0, KEYID_SIZE - length);
12560
0
    #endif
12561
0
        XMEMCPY(hash, id, (size_t)length);
12562
0
        ret = 0;
12563
0
    }
12564
0
    else {
12565
0
        ret = CalcHashId_ex(id, (word32)length, hash, hashAlg);
12566
0
    }
12567
12568
0
    return ret;
12569
0
}
12570
#endif /* !NO_CERTS */
12571
12572
#ifdef WOLFSSL_ASN_TEMPLATE
12573
/* Id for email address. */
12574
0
#define ASN_EMAIL     0x100
12575
/* Id for domain component. */
12576
0
#define ASN_DC        0x102
12577
/* Id for jurisdiction country. */
12578
#define ASN_JURIS_C   0x203
12579
/* Id for jurisdiction state. */
12580
#define ASN_JURIS_ST  0x202
12581
12582
/* Set the string for a name component into the subject name. */
12583
#define SetCertNameSubject(cert, id, val) \
12584
    *((char**)(((byte *)(cert)) + certNameSubject[(id) - 3].data)) = (val)
12585
/* Set the string length for a name component into the subject name. */
12586
#define SetCertNameSubjectLen(cert, id, val) \
12587
    *((int*)(((byte *)(cert)) + certNameSubject[(id) - 3].len)) = (int)(val)
12588
/* Set the encoding for a name component into the subject name. */
12589
#define SetCertNameSubjectEnc(cert, id, val) \
12590
    *((byte*)(((byte *)(cert)) + certNameSubject[(id) - 3].enc)) = (val)
12591
12592
/* Get the string of a name component from the subject name. */
12593
#define GetCertNameSubjectStr(id) \
12594
0
    (certNameSubject[(id) - 3].str)
12595
/* Get the string length of a name component from the subject name. */
12596
#define GetCertNameSubjectStrLen(id) \
12597
0
    (certNameSubject[(id) - 3].strLen)
12598
/* Get the NID of a name component from the subject name. */
12599
#define GetCertNameSubjectNID(id) \
12600
    (certNameSubject[(id) - 3].nid)
12601
12602
#define ValidCertNameSubject(id) \
12603
0
    (((id) - 3) >= 0 && ((id) - 3) < certNameSubjectSz && \
12604
0
            (certNameSubject[(id) - 3].strLen > 0))
12605
12606
/* Mapping of certificate name component to useful information. */
12607
typedef struct CertNameData {
12608
    /* Type string of name component. */
12609
    const char* str;
12610
    /* Length of type string of name component. */
12611
    byte        strLen;
12612
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12613
    /* Offset of data in subject name component. */
12614
    size_t      data;
12615
    /* Offset of length in subject name component. */
12616
    size_t      len;
12617
    /* Offset of encoding in subject name component. */
12618
    size_t      enc;
12619
#endif
12620
#ifdef WOLFSSL_X509_NAME_AVAILABLE
12621
    /* NID of type for subject name component. */
12622
    int         nid;
12623
#endif
12624
} CertNameData;
12625
12626
/* List of data for common name components. */
12627
static const CertNameData certNameSubject[] = {
12628
    /* Common Name */
12629
    {
12630
        "/CN=", 4,
12631
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12632
        OFFSETOF(DecodedCert, subjectCN),
12633
        OFFSETOF(DecodedCert, subjectCNLen),
12634
        OFFSETOF(DecodedCert, subjectCNEnc),
12635
#endif
12636
#ifdef WOLFSSL_X509_NAME_AVAILABLE
12637
        NID_commonName
12638
#endif
12639
    },
12640
    /* Surname */
12641
    {
12642
        "/SN=", 4,
12643
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12644
        OFFSETOF(DecodedCert, subjectSN),
12645
        OFFSETOF(DecodedCert, subjectSNLen),
12646
        OFFSETOF(DecodedCert, subjectSNEnc),
12647
#endif
12648
#ifdef WOLFSSL_X509_NAME_AVAILABLE
12649
        NID_surname
12650
#endif
12651
    },
12652
    /* Serial Number */
12653
    {
12654
        "/serialNumber=", 14,
12655
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12656
        OFFSETOF(DecodedCert, subjectSND),
12657
        OFFSETOF(DecodedCert, subjectSNDLen),
12658
        OFFSETOF(DecodedCert, subjectSNDEnc),
12659
#endif
12660
#ifdef WOLFSSL_X509_NAME_AVAILABLE
12661
        NID_serialNumber
12662
#endif
12663
    },
12664
    /* Country Name */
12665
    {
12666
        "/C=", 3,
12667
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12668
        OFFSETOF(DecodedCert, subjectC),
12669
        OFFSETOF(DecodedCert, subjectCLen),
12670
        OFFSETOF(DecodedCert, subjectCEnc),
12671
#endif
12672
#ifdef WOLFSSL_X509_NAME_AVAILABLE
12673
        NID_countryName
12674
#endif
12675
    },
12676
    /* Locality Name */
12677
    {
12678
        "/L=", 3,
12679
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12680
        OFFSETOF(DecodedCert, subjectL),
12681
        OFFSETOF(DecodedCert, subjectLLen),
12682
        OFFSETOF(DecodedCert, subjectLEnc),
12683
#endif
12684
#ifdef WOLFSSL_X509_NAME_AVAILABLE
12685
        NID_localityName
12686
#endif
12687
    },
12688
    /* State Name */
12689
    {
12690
        "/ST=", 4,
12691
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12692
        OFFSETOF(DecodedCert, subjectST),
12693
        OFFSETOF(DecodedCert, subjectSTLen),
12694
        OFFSETOF(DecodedCert, subjectSTEnc),
12695
#endif
12696
#ifdef WOLFSSL_X509_NAME_AVAILABLE
12697
        NID_stateOrProvinceName
12698
#endif
12699
    },
12700
    /* Street Address */
12701
    {
12702
        "/street=", 8,
12703
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12704
        OFFSETOF(DecodedCert, subjectStreet),
12705
        OFFSETOF(DecodedCert, subjectStreetLen),
12706
        OFFSETOF(DecodedCert, subjectStreetEnc),
12707
#endif
12708
#ifdef WOLFSSL_X509_NAME_AVAILABLE
12709
        NID_streetAddress
12710
#endif
12711
    },
12712
    /* Organization Name */
12713
    {
12714
        "/O=", 3,
12715
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12716
        OFFSETOF(DecodedCert, subjectO),
12717
        OFFSETOF(DecodedCert, subjectOLen),
12718
        OFFSETOF(DecodedCert, subjectOEnc),
12719
#endif
12720
#ifdef WOLFSSL_X509_NAME_AVAILABLE
12721
        NID_organizationName
12722
#endif
12723
    },
12724
    /* Organization Unit Name */
12725
    {
12726
        "/OU=", 4,
12727
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12728
        OFFSETOF(DecodedCert, subjectOU),
12729
        OFFSETOF(DecodedCert, subjectOULen),
12730
        OFFSETOF(DecodedCert, subjectOUEnc),
12731
#endif
12732
#ifdef WOLFSSL_X509_NAME_AVAILABLE
12733
        NID_organizationalUnitName
12734
#endif
12735
    },
12736
    /* Title */
12737
    {
12738
        NULL, 0,
12739
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12740
        0,
12741
        0,
12742
        0,
12743
#endif
12744
#ifdef WOLFSSL_X509_NAME_AVAILABLE
12745
        0,
12746
#endif
12747
    },
12748
    /* Undefined */
12749
    {
12750
        NULL, 0,
12751
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12752
        0,
12753
        0,
12754
        0,
12755
#endif
12756
#ifdef WOLFSSL_X509_NAME_AVAILABLE
12757
        0,
12758
#endif
12759
    },
12760
    /* Undefined */
12761
    {
12762
        NULL, 0,
12763
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12764
        0,
12765
        0,
12766
        0,
12767
#endif
12768
#ifdef WOLFSSL_X509_NAME_AVAILABLE
12769
        0,
12770
#endif
12771
    },
12772
    /* Business Category */
12773
    {
12774
        "/businessCategory=", 18,
12775
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12776
        OFFSETOF(DecodedCert, subjectBC),
12777
        OFFSETOF(DecodedCert, subjectBCLen),
12778
        OFFSETOF(DecodedCert, subjectBCEnc),
12779
#endif
12780
#ifdef WOLFSSL_X509_NAME_AVAILABLE
12781
        NID_businessCategory
12782
#endif
12783
    },
12784
    /* Undefined */
12785
    {
12786
        NULL, 0,
12787
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12788
        0,
12789
        0,
12790
        0,
12791
#endif
12792
#ifdef WOLFSSL_X509_NAME_AVAILABLE
12793
        0,
12794
#endif
12795
    },
12796
    /* Postal Code */
12797
    {
12798
        "/postalCode=", 12,
12799
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12800
        OFFSETOF(DecodedCert, subjectPC),
12801
        OFFSETOF(DecodedCert, subjectPCLen),
12802
        OFFSETOF(DecodedCert, subjectPCEnc),
12803
#endif
12804
#ifdef WOLFSSL_X509_NAME_AVAILABLE
12805
        NID_postalCode
12806
#endif
12807
    },
12808
    /* User Id */
12809
    {
12810
        "/userid=", 8,
12811
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12812
        OFFSETOF(DecodedCert, subjectUID),
12813
        OFFSETOF(DecodedCert, subjectUIDLen),
12814
        OFFSETOF(DecodedCert, subjectUIDEnc),
12815
#endif
12816
#ifdef WOLFSSL_X509_NAME_AVAILABLE
12817
        NID_userId
12818
#endif
12819
    },
12820
#ifdef WOLFSSL_CERT_NAME_ALL
12821
    /* Name, id 41 */
12822
    {
12823
        "/N=", 3,
12824
    #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12825
        OFFSETOF(DecodedCert, subjectN),
12826
        OFFSETOF(DecodedCert, subjectNLen),
12827
        OFFSETOF(DecodedCert, subjectNEnc),
12828
    #endif
12829
    #ifdef WOLFSSL_X509_NAME_AVAILABLE
12830
        NID_name
12831
    #endif
12832
    },
12833
    /* Given Name, id 42 */
12834
    {
12835
        "/GN=", 4,
12836
    #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12837
        OFFSETOF(DecodedCert, subjectGN),
12838
        OFFSETOF(DecodedCert, subjectGNLen),
12839
        OFFSETOF(DecodedCert, subjectGNEnc),
12840
    #endif
12841
    #ifdef WOLFSSL_X509_NAME_AVAILABLE
12842
        NID_givenName
12843
    #endif
12844
    },
12845
    /* initials, id 43 */
12846
    {
12847
        "/initials=", 10,
12848
    #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12849
        OFFSETOF(DecodedCert, subjectI),
12850
        OFFSETOF(DecodedCert, subjectILen),
12851
        OFFSETOF(DecodedCert, subjectIEnc),
12852
    #endif
12853
    #ifdef WOLFSSL_X509_NAME_AVAILABLE
12854
        NID_initials
12855
    #endif
12856
    },
12857
    /* DN Qualifier Name, id 46 */
12858
    {
12859
        "/dnQualifier=", 13,
12860
    #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12861
        OFFSETOF(DecodedCert, subjectDNQ),
12862
        OFFSETOF(DecodedCert, subjectDNQLen),
12863
        OFFSETOF(DecodedCert, subjectDNQEnc),
12864
    #endif
12865
    #ifdef WOLFSSL_X509_NAME_AVAILABLE
12866
        NID_dnQualifier
12867
    #endif
12868
    },
12869
#endif /* WOLFSSL_CERT_NAME_ALL */
12870
};
12871
12872
static const int certNameSubjectSz =
12873
        (int) (sizeof(certNameSubject) / sizeof(CertNameData));
12874
12875
/* ASN.1 template for an RDN.
12876
 * X.509: RFC 5280, 4.1.2.4 - RelativeDistinguishedName
12877
 */
12878
static const ASNItem rdnASN[] = {
12879
/* SET       */ { 1, ASN_SET, 1, 1, 0 },
12880
                           /* AttributeTypeAndValue */
12881
/* ATTR_SEQ  */     { 2, ASN_SEQUENCE, 1, 1, 0 },
12882
                                   /* AttributeType */
12883
/* ATTR_TYPE */         { 3, ASN_OBJECT_ID, 0, 0, 0 },
12884
                           /* AttributeValue: Choice of tags - rdnChoice. */
12885
/* ATTR_VAL  */         { 3, 0, 0, 0, 0 },
12886
};
12887
enum {
12888
    RDNASN_IDX_SET = 0,
12889
    RDNASN_IDX_ATTR_SEQ,
12890
    RDNASN_IDX_ATTR_TYPE,
12891
    RDNASN_IDX_ATTR_VAL
12892
};
12893
12894
/* Number of items in ASN.1 template for an RDN. */
12895
0
#define rdnASN_Length (sizeof(rdnASN) / sizeof(ASNItem))
12896
12897
/* Supported types of encodings (tags) for RDN strings.
12898
 * X.509: RFC 5280, 4.1.2.4 - DirectoryString
12899
 * (IA5 String not listed in RFC but required for alternative types)
12900
 */
12901
static const byte rdnChoice[] = {
12902
    ASN_PRINTABLE_STRING, ASN_IA5_STRING, ASN_UTF8STRING, ASN_T61STRING,
12903
    ASN_UNIVERSALSTRING, ASN_BMPSTRING, 0
12904
};
12905
#endif
12906
12907
#if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
12908
/* used to set the human readable string for the IP address with a ASN_IP_TYPE
12909
 * DNS entry
12910
 * return 0 on success
12911
 */
12912
static int GenerateDNSEntryIPString(DNS_entry* entry, void* heap)
12913
{
12914
    int ret = 0;
12915
    size_t nameSz;
12916
    char tmpName[WOLFSSL_MAX_IPSTR] = {0};
12917
    unsigned char* ip;
12918
12919
    if (entry == NULL || entry->type != ASN_IP_TYPE) {
12920
        return BAD_FUNC_ARG;
12921
    }
12922
12923
    if (entry->len != WOLFSSL_IP4_ADDR_LEN &&
12924
            entry->len != WOLFSSL_IP6_ADDR_LEN) {
12925
        WOLFSSL_MSG("Unexpected IP size");
12926
        return BAD_FUNC_ARG;
12927
    }
12928
    ip = (unsigned char*)entry->name;
12929
12930
    /* store IP addresses as a string */
12931
    if (entry->len == WOLFSSL_IP4_ADDR_LEN) {
12932
        if (XSNPRINTF(tmpName, sizeof(tmpName), "%u.%u.%u.%u", 0xFFU & ip[0],
12933
                      0xFFU & ip[1], 0xFFU & ip[2], 0xFFU & ip[3])
12934
            >= (int)sizeof(tmpName))
12935
        {
12936
            WOLFSSL_MSG("IP buffer overrun");
12937
            return BUFFER_E;
12938
        }
12939
    }
12940
12941
    if (entry->len == WOLFSSL_IP6_ADDR_LEN) {
12942
        size_t i;
12943
        for (i = 0; i < 8; i++) {
12944
            if (XSNPRINTF(tmpName + i * 5, sizeof(tmpName) - i * 5,
12945
                    "%02X%02X%s", 0xFF & ip[2 * i], 0xFF & ip[2 * i + 1],
12946
                    (i < 7) ? ":" : "")
12947
                >= (int)sizeof(tmpName))
12948
            {
12949
                WOLFSSL_MSG("IPv6 buffer overrun");
12950
                return BUFFER_E;
12951
            }
12952
        }
12953
    }
12954
12955
    nameSz = XSTRLEN(tmpName);
12956
    entry->ipString = (char*)XMALLOC(nameSz + 1, heap,
12957
        DYNAMIC_TYPE_ALTNAME);
12958
    if (entry->ipString == NULL) {
12959
        ret = MEMORY_E;
12960
    }
12961
12962
    if (ret == 0) {
12963
        XMEMCPY(entry->ipString, tmpName, nameSz);
12964
        entry->ipString[nameSz] = '\0';
12965
    }
12966
12967
    (void)heap;
12968
12969
    return ret;
12970
}
12971
#endif /* OPENSSL_ALL || WOLFSSL_IP_ALT_NAME */
12972
12973
#ifdef WOLFSSL_ASN_TEMPLATE
12974
12975
#if defined(WOLFSSL_CERT_GEN) || !defined(NO_CERTS)
12976
12977
/* Adds a DNS entry to a list of DNS entries
12978
 *
12979
 * @param [in, out] lst      Linked list of DNS name entries.
12980
 * @param [in]      entry    Entry to add to the list
12981
 * @return  0 on success.
12982
 */
12983
static int AddDNSEntryToList(DNS_entry** lst, DNS_entry* entry)
12984
0
{
12985
#if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_ALT_NAMES_NO_REV)
12986
    entry->next = NULL;
12987
    if (*lst == NULL) {
12988
        /* First on list */
12989
        *lst = entry;
12990
    }
12991
    else {
12992
        DNS_entry* temp = *lst;
12993
12994
        /* Find end */
12995
        for (; (temp->next != NULL); temp = temp->next);
12996
12997
        /* Add to end */
12998
        temp->next = entry;
12999
    }
13000
#else
13001
    /* Prepend entry to linked list. */
13002
0
    entry->next = *lst;
13003
0
    *lst = entry;
13004
0
#endif
13005
13006
0
    return 0;
13007
0
}
13008
13009
13010
/* Allocate a DNS entry and set the fields.
13011
 *
13012
 * @param [in]      cert     Certificate object.
13013
 * @param [in]      str      DNS name string.
13014
 * @param [in]      strLen   Length of DNS name string.
13015
 * @param [in]      type     Type of DNS name string.
13016
 * @param [in, out] entries  Linked list of DNS name entries.
13017
 * @return  0 on success.
13018
 * @return  MEMORY_E when dynamic memory allocation fails.
13019
 */
13020
static int SetDNSEntry(DecodedCert* cert, const char* str, int strLen,
13021
                       int type, DNS_entry** entries)
13022
0
{
13023
0
    DNS_entry* dnsEntry;
13024
0
    int ret = 0;
13025
13026
    /* Only used for heap. */
13027
0
    (void)cert;
13028
13029
    /* TODO: consider one malloc. */
13030
    /* Allocate DNS Entry object. */
13031
0
    dnsEntry = AltNameNew(cert->heap);
13032
0
    if (dnsEntry == NULL) {
13033
0
        ret = MEMORY_E;
13034
0
    }
13035
0
    if (ret == 0) {
13036
        /* Allocate DNS Entry name - length of string plus 1 for NUL. */
13037
0
        dnsEntry->name = (char*)XMALLOC((size_t)strLen + 1, cert->heap,
13038
0
                                                          DYNAMIC_TYPE_ALTNAME);
13039
0
        if (dnsEntry->name == NULL) {
13040
0
            XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
13041
0
            ret = MEMORY_E;
13042
0
        }
13043
0
    }
13044
0
    if (ret == 0) {
13045
        /* Set tag type, name length, name and NUL terminate name. */
13046
0
        dnsEntry->type = type;
13047
0
        dnsEntry->len = strLen;
13048
0
        XMEMCPY(dnsEntry->name, str, (size_t)strLen);
13049
0
        dnsEntry->name[strLen] = '\0';
13050
13051
#if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
13052
        /* store IP addresses as a string */
13053
        if (type == ASN_IP_TYPE) {
13054
            if ((ret = GenerateDNSEntryIPString(dnsEntry, cert->heap)) != 0) {
13055
                XFREE(dnsEntry->name, cert->heap, DYNAMIC_TYPE_ALTNAME);
13056
                XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
13057
            }
13058
        }
13059
    }
13060
    if (ret == 0) {
13061
#endif
13062
0
        ret = AddDNSEntryToList(entries, dnsEntry);
13063
0
    }
13064
13065
0
    return ret;
13066
0
}
13067
#endif
13068
13069
/* Set the details of a subject name component into a certificate.
13070
 *
13071
 * @param [in, out] cert    Certificate object.
13072
 * @param [in]      id      Id of component.
13073
 * @param [in]      str     String for component.
13074
 * @param [in]      strLen  Length of string.
13075
 * @param [in]      tag     BER tag representing encoding of string.
13076
 * @return  0 on success, negative values on failure.
13077
 */
13078
static int SetSubject(DecodedCert* cert, int id, byte* str, int strLen,
13079
                      byte tag)
13080
0
{
13081
0
    int ret = 0;
13082
13083
    /* Put string and encoding into certificate. */
13084
0
    if (id == ASN_COMMON_NAME) {
13085
0
        cert->subjectCN = (char *)str;
13086
0
        cert->subjectCNLen = (int)strLen;
13087
0
        cert->subjectCNEnc = (char)tag;
13088
0
    }
13089
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
13090
    else if (id > ASN_COMMON_NAME && id <= ASN_USER_ID) {
13091
        /* Use table and offsets to put data into appropriate fields. */
13092
        SetCertNameSubject(cert, id, (char*)str);
13093
        SetCertNameSubjectLen(cert, id, strLen);
13094
        SetCertNameSubjectEnc(cert, id, tag);
13095
    }
13096
#endif
13097
0
#if !defined(IGNORE_NAME_CONSTRAINTS) || \
13098
0
     defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
13099
0
    else if (id == ASN_EMAIL) {
13100
0
        cert->subjectEmail = (char*)str;
13101
0
        cert->subjectEmailLen = strLen;
13102
0
    }
13103
0
#endif
13104
#ifdef WOLFSSL_CERT_EXT
13105
    /* TODO: consider mapping id to an index and using SetCertNameSubect*(). */
13106
    else if (id == ASN_JURIS_C) {
13107
        cert->subjectJC = (char*)str;
13108
        cert->subjectJCLen = strLen;
13109
        cert->subjectJCEnc = (char)tag;
13110
    }
13111
    else if (id == ASN_JURIS_ST) {
13112
        cert->subjectJS = (char*)str;
13113
        cert->subjectJSLen = strLen;
13114
        cert->subjectJSEnc = (char)tag;
13115
    }
13116
#endif
13117
13118
0
    return ret;
13119
0
}
13120
13121
/* Get a RelativeDistinguishedName from the encoding and put in certificate.
13122
 *
13123
 * @param [in, out] cert       Certificate object.
13124
 * @param [in, out] full       Full name string. ([/<type>=<value>]*)
13125
 * @param [in, out] idx        Index int full name to place next component.
13126
 * @param [in, out] nid        NID of component type.
13127
 * @param [in]      isSubject  Whether this data is for a subject name.
13128
 * @param [in]      dataASN    Decoded data of RDN. Expected rdnASN type.
13129
 * @return  0 on success.
13130
 * @return  MEMORY_E when dynamic memory allocation fails.
13131
 * @return  ASN_PARSE_E when type not supported.
13132
 */
13133
static int GetRDN(DecodedCert* cert, char* full, word32* idx, int* nid,
13134
                  int isSubject, ASNGetData* dataASN)
13135
0
{
13136
0
    int         ret = 0;
13137
0
    const char* typeStr = NULL;
13138
0
    byte        typeStrLen = 0;
13139
0
    byte*       oid;
13140
0
    word32      oidSz;
13141
0
    int         id = 0;
13142
13143
0
    (void)nid;
13144
13145
    /* Get name type OID from data items. */
13146
0
    GetASN_OIDData(&dataASN[RDNASN_IDX_ATTR_TYPE], &oid, &oidSz);
13147
13148
    /* v1 name types */
13149
0
    if ((oidSz == 3) && (oid[0] == 0x55) && (oid[1] == 0x04)) {
13150
0
        id = oid[2];
13151
        /* Check range of supported ids in table. */
13152
0
        if (ValidCertNameSubject(id)) {
13153
            /* Get the type string, length and NID from table. */
13154
0
            typeStr = GetCertNameSubjectStr(id);
13155
0
            typeStrLen = GetCertNameSubjectStrLen(id);
13156
        #ifdef WOLFSSL_X509_NAME_AVAILABLE
13157
            *nid = GetCertNameSubjectNID(id);
13158
        #endif
13159
0
        }
13160
0
    }
13161
0
    else if (oidSz == sizeof(attrEmailOid) && XMEMCMP(oid, attrEmailOid, oidSz) == 0) {
13162
        /* Set the email id, type string, length and NID. */
13163
0
        id = ASN_EMAIL;
13164
0
        typeStr =  WOLFSSL_EMAIL_ADDR;
13165
0
        typeStrLen = sizeof(WOLFSSL_EMAIL_ADDR) - 1;
13166
    #ifdef WOLFSSL_X509_NAME_AVAILABLE
13167
        *nid = NID_emailAddress;
13168
    #endif
13169
0
    }
13170
0
    else if (oidSz == sizeof(uidOid) && XMEMCMP(oid, uidOid, oidSz) == 0) {
13171
        /* Set the user id, type string, length and NID. */
13172
0
        id = ASN_USER_ID;
13173
0
        typeStr = WOLFSSL_USER_ID;
13174
0
        typeStrLen = sizeof(WOLFSSL_USER_ID) - 1;
13175
    #ifdef WOLFSSL_X509_NAME_AVAILABLE
13176
        *nid = NID_userId;
13177
    #endif
13178
0
    }
13179
0
    else if (oidSz == sizeof(dcOid) && XMEMCMP(oid, dcOid, oidSz) == 0) {
13180
        /* Set the domain component, type string, length and NID. */
13181
0
        id = ASN_DC;
13182
0
        typeStr = WOLFSSL_DOMAIN_COMPONENT;
13183
0
        typeStrLen = sizeof(WOLFSSL_DOMAIN_COMPONENT) - 1;
13184
    #ifdef WOLFSSL_X509_NAME_AVAILABLE
13185
        *nid = NID_domainComponent;
13186
    #endif
13187
0
    }
13188
0
    else if (oidSz == sizeof(fvrtDrk) && XMEMCMP(oid, fvrtDrk, oidSz) == 0) {
13189
        /* Set the favourite drink, type string, length and NID. */
13190
0
        id = ASN_FAVOURITE_DRINK;
13191
0
        typeStr = WOLFSSL_FAVOURITE_DRINK;
13192
0
        typeStrLen = sizeof(WOLFSSL_FAVOURITE_DRINK) - 1;
13193
    #ifdef WOLFSSL_X509_NAME_AVAILABLE
13194
        *nid = NID_favouriteDrink;
13195
    #endif
13196
0
    }
13197
    /* Other OIDs that start with the same values. */
13198
0
    else if (oidSz == sizeof(dcOid) && XMEMCMP(oid, dcOid, oidSz-1) == 0) {
13199
0
        WOLFSSL_MSG("Unknown pilot attribute type");
13200
0
        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
13201
0
        ret = ASN_PARSE_E;
13202
0
    }
13203
0
    else if (oidSz == ASN_JOI_PREFIX_SZ + 1 &&
13204
0
                         XMEMCMP(oid, ASN_JOI_PREFIX, ASN_JOI_PREFIX_SZ) == 0) {
13205
        /* Set the jurisdiction id. */
13206
0
        id = 0x200 + oid[ASN_JOI_PREFIX_SZ];
13207
13208
        /* Set the jurisdiction type string, length and NID if known. */
13209
0
        if (oid[ASN_JOI_PREFIX_SZ] == ASN_JOI_C) {
13210
0
            typeStr = WOLFSSL_JOI_C;
13211
0
            typeStrLen = sizeof(WOLFSSL_JOI_C) - 1;
13212
        #ifdef WOLFSSL_X509_NAME_AVAILABLE
13213
            *nid = NID_jurisdictionCountryName;
13214
        #endif /* WOLFSSL_X509_NAME_AVAILABLE */
13215
0
        }
13216
0
        else if (oid[ASN_JOI_PREFIX_SZ] == ASN_JOI_ST) {
13217
0
            typeStr = WOLFSSL_JOI_ST;
13218
0
            typeStrLen = sizeof(WOLFSSL_JOI_ST) - 1;
13219
        #ifdef WOLFSSL_X509_NAME_AVAILABLE
13220
            *nid = NID_jurisdictionStateOrProvinceName;
13221
        #endif /* WOLFSSL_X509_NAME_AVAILABLE */
13222
0
        }
13223
0
        else {
13224
0
            WOLFSSL_MSG("Unknown Jurisdiction, skipping");
13225
0
        }
13226
0
    }
13227
13228
0
    if ((ret == 0) && (typeStr != NULL)) {
13229
        /* OID type to store for subject name and add to full string. */
13230
0
        byte*  str;
13231
0
        word32 strLen;
13232
0
        byte   tag = dataASN[RDNASN_IDX_ATTR_VAL].tag;
13233
13234
        /* Get the string reference and length. */
13235
0
        GetASN_GetRef(&dataASN[RDNASN_IDX_ATTR_VAL], &str, &strLen);
13236
13237
0
        if (isSubject) {
13238
            /* Store subject field components. */
13239
0
            ret = SetSubject(cert, id, str, (int)strLen, tag);
13240
0
        }
13241
0
        if (ret == 0) {
13242
            /* Check there is space for this in the full name string and
13243
             * terminating NUL character. */
13244
0
            if ((typeStrLen + strLen) < (word32)(WC_ASN_NAME_MAX - *idx))
13245
0
            {
13246
                /* Add RDN to full string. */
13247
0
                XMEMCPY(&full[*idx], typeStr, typeStrLen);
13248
0
                *idx += typeStrLen;
13249
0
                XMEMCPY(&full[*idx], str, strLen);
13250
0
                *idx += strLen;
13251
0
            }
13252
0
            else {
13253
0
                WOLFSSL_MSG("ASN Name too big, skipping");
13254
0
            }
13255
0
        }
13256
0
    }
13257
13258
0
    return ret;
13259
0
}
13260
#endif /* WOLFSSL_ASN_TEMPLATE */
13261
13262
/* Get a certificate name into the certificate object.
13263
 *
13264
 * @param [in, out] cert      Decoded certificate object.
13265
 * @param [out]     full      Buffer to hold full name as a string.
13266
 * @param [out]     hash      Buffer to hold hash of name.
13267
 * @param [in]      nameType  ISSUER or SUBJECT.
13268
 * @param [in]      input     Buffer holding certificate name.
13269
 * @param [in, out] inOutIdx  On in, start of certificate name.
13270
 *                            On out, start of ASN.1 item after cert name.
13271
 * @param [in]      maxIdx    Index of next item after certificate name.
13272
 * @return  0 on success.
13273
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
13274
 *          is invalid.
13275
 * @return  BUFFER_E when data in buffer is too small.
13276
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
13277
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
13278
 * @return  MEMORY_E when dynamic memory allocation fails.
13279
 */
13280
static int GetCertName(DecodedCert* cert, char* full, byte* hash, int nameType,
13281
                       const byte* input, word32* inOutIdx, word32 maxIdx)
13282
0
{
13283
#ifndef WOLFSSL_ASN_TEMPLATE
13284
    int    length;  /* length of all distinguished names */
13285
    int    dummy;
13286
    int    ret;
13287
    word32 idx;
13288
    word32 srcIdx = *inOutIdx;
13289
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
13290
    !defined(WOLFCRYPT_ONLY)
13291
    WOLFSSL_X509_NAME* dName = NULL;
13292
#endif
13293
13294
    WOLFSSL_MSG("Getting Cert Name");
13295
13296
    /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
13297
     * calculated over the entire DER encoding of the Name field, including
13298
     * the tag and length. */
13299
    if (CalcHashId_ex(input + *inOutIdx, maxIdx - *inOutIdx, hash,
13300
            HashIdAlg(cert->signatureOID)) != 0) {
13301
        return ASN_PARSE_E;
13302
    }
13303
13304
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
13305
    !defined(WOLFCRYPT_ONLY)
13306
    dName = wolfSSL_X509_NAME_new_ex(cert->heap);
13307
    if (dName == NULL) {
13308
        return MEMORY_E;
13309
    }
13310
#endif /* OPENSSL_EXTRA */
13311
13312
    if (GetSequence(input, &srcIdx, &length, maxIdx) < 0) {
13313
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
13314
            !defined(WOLFCRYPT_ONLY)
13315
        wolfSSL_X509_NAME_free(dName);
13316
#endif /* OPENSSL_EXTRA */
13317
        return ASN_PARSE_E;
13318
    }
13319
13320
#if defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT)
13321
    /* store pointer to raw issuer */
13322
    if (nameType == ISSUER) {
13323
        cert->issuerRaw = &input[srcIdx];
13324
        cert->issuerRawLen = length;
13325
    }
13326
#endif
13327
#if !defined(IGNORE_NAME_CONSTRAINTS) || defined(WOLFSSL_CERT_EXT)
13328
    if (nameType == SUBJECT) {
13329
        cert->subjectRaw = &input[srcIdx];
13330
        cert->subjectRawLen = length;
13331
    }
13332
#endif
13333
13334
    length += (int)srcIdx;
13335
    idx = 0;
13336
13337
    while (srcIdx < (word32)length) {
13338
        byte        b       = 0;
13339
        byte        joint[3];
13340
        byte        tooBig  = FALSE;
13341
        int         oidSz;
13342
        const char* copy    = NULL;
13343
        int         copyLen = 0;
13344
        int         strLen  = 0;
13345
        byte        id      = 0;
13346
    #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \
13347
                && !defined(WOLFCRYPT_ONLY)
13348
         int        nid = NID_undef;
13349
         int        enc;
13350
    #endif /* OPENSSL_EXTRA */
13351
13352
        if (GetSet(input, &srcIdx, &dummy, maxIdx) < 0) {
13353
            WOLFSSL_MSG("Cert name lacks set header, trying sequence");
13354
        }
13355
13356
        if (GetSequence(input, &srcIdx, &dummy, maxIdx) <= 0) {
13357
        #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
13358
            !defined(WOLFCRYPT_ONLY)
13359
            wolfSSL_X509_NAME_free(dName);
13360
        #endif /* OPENSSL_EXTRA */
13361
            return ASN_PARSE_E;
13362
        }
13363
13364
        ret = GetASNObjectId(input, &srcIdx, &oidSz, maxIdx);
13365
        if (ret != 0) {
13366
        #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
13367
            !defined(WOLFCRYPT_ONLY)
13368
            wolfSSL_X509_NAME_free(dName);
13369
        #endif /* OPENSSL_EXTRA */
13370
            return ret;
13371
        }
13372
13373
        /* make sure there is room for joint */
13374
        if ((srcIdx + sizeof(joint)) > (word32)maxIdx) {
13375
        #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
13376
            !defined(WOLFCRYPT_ONLY)
13377
            wolfSSL_X509_NAME_free(dName);
13378
        #endif /* OPENSSL_EXTRA */
13379
            return ASN_PARSE_E;
13380
        }
13381
13382
        XMEMCPY(joint, &input[srcIdx], sizeof(joint));
13383
13384
        /* v1 name types */
13385
        if (joint[0] == 0x55 && joint[1] == 0x04) {
13386
            srcIdx += 3;
13387
            id = joint[2];
13388
            if (GetHeader(input, &b, &srcIdx, &strLen, maxIdx, 1) < 0) {
13389
            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
13390
            !defined(WOLFCRYPT_ONLY)
13391
                wolfSSL_X509_NAME_free(dName);
13392
            #endif /* OPENSSL_EXTRA */
13393
                return ASN_PARSE_E;
13394
            }
13395
13396
            if (id == ASN_COMMON_NAME) {
13397
                if (nameType == SUBJECT) {
13398
                    cert->subjectCN = (char *)&input[srcIdx];
13399
                    cert->subjectCNLen = strLen;
13400
                    cert->subjectCNEnc = (char)b;
13401
                }
13402
            #if (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)) && \
13403
                defined(WOLFSSL_HAVE_ISSUER_NAMES)
13404
                else if (nameType == ISSUER) {
13405
                    cert->issuerCN = (char*)&input[srcIdx];
13406
                    cert->issuerCNLen = strLen;
13407
                    cert->issuerCNEnc = (char)b;
13408
                }
13409
            #endif
13410
13411
                copy = WOLFSSL_COMMON_NAME;
13412
                copyLen = sizeof(WOLFSSL_COMMON_NAME) - 1;
13413
            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \
13414
                && !defined(WOLFCRYPT_ONLY)
13415
                nid = NID_commonName;
13416
            #endif /* OPENSSL_EXTRA */
13417
            }
13418
        #ifdef WOLFSSL_CERT_NAME_ALL
13419
            else if (id == ASN_NAME) {
13420
                copy = WOLFSSL_NAME;
13421
                copyLen = sizeof(WOLFSSL_NAME) - 1;
13422
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
13423
                    if (nameType == SUBJECT) {
13424
                        cert->subjectN = (char*)&input[srcIdx];
13425
                        cert->subjectNLen = strLen;
13426
                        cert->subjectNEnc = b;
13427
                    }
13428
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
13429
                #if (defined(OPENSSL_EXTRA) || \
13430
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
13431
                        && !defined(WOLFCRYPT_ONLY)
13432
                    nid = NID_name;
13433
                #endif /* OPENSSL_EXTRA */
13434
            }
13435
            else if (id == ASN_INITIALS) {
13436
                copy = WOLFSSL_INITIALS;
13437
                copyLen = sizeof(WOLFSSL_INITIALS) - 1;
13438
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
13439
                    if (nameType == SUBJECT) {
13440
                        cert->subjectI = (char*)&input[srcIdx];
13441
                        cert->subjectILen = strLen;
13442
                        cert->subjectIEnc = b;
13443
                    }
13444
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
13445
                #if (defined(OPENSSL_EXTRA) || \
13446
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
13447
                        && !defined(WOLFCRYPT_ONLY)
13448
                    nid = NID_initials;
13449
                #endif /* OPENSSL_EXTRA */
13450
            }
13451
            else if (id == ASN_GIVEN_NAME) {
13452
                copy = WOLFSSL_GIVEN_NAME;
13453
                copyLen = sizeof(WOLFSSL_GIVEN_NAME) - 1;
13454
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
13455
                    if (nameType == SUBJECT) {
13456
                        cert->subjectGN = (char*)&input[srcIdx];
13457
                        cert->subjectGNLen = strLen;
13458
                        cert->subjectGNEnc = b;
13459
                    }
13460
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
13461
                #if (defined(OPENSSL_EXTRA) || \
13462
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
13463
                        && !defined(WOLFCRYPT_ONLY)
13464
                    nid = NID_givenName;
13465
                #endif /* OPENSSL_EXTRA */
13466
            }
13467
            else if (id == ASN_DNQUALIFIER) {
13468
                copy = WOLFSSL_DNQUALIFIER;
13469
                copyLen = sizeof(WOLFSSL_DNQUALIFIER) - 1;
13470
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
13471
                    if (nameType == SUBJECT) {
13472
                        cert->subjectDNQ = (char*)&input[srcIdx];
13473
                        cert->subjectDNQLen = strLen;
13474
                        cert->subjectDNQEnc = b;
13475
                    }
13476
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
13477
                #if (defined(OPENSSL_EXTRA) || \
13478
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
13479
                        && !defined(WOLFCRYPT_ONLY)
13480
                    nid = NID_dnQualifier;
13481
                #endif /* OPENSSL_EXTRA */
13482
            }
13483
        #endif /* WOLFSSL_CERT_NAME_ALL */
13484
            else if (id == ASN_SUR_NAME) {
13485
                copy = WOLFSSL_SUR_NAME;
13486
                copyLen = sizeof(WOLFSSL_SUR_NAME) - 1;
13487
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
13488
                    if (nameType == SUBJECT) {
13489
                        cert->subjectSN = (char*)&input[srcIdx];
13490
                        cert->subjectSNLen = strLen;
13491
                        cert->subjectSNEnc = (char)b;
13492
                    }
13493
                #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
13494
                    else if (nameType == ISSUER) {
13495
                        cert->issuerSN = (char*)&input[srcIdx];
13496
                        cert->issuerSNLen = strLen;
13497
                        cert->issuerSNEnc = (char)b;
13498
                    }
13499
                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
13500
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
13501
                #if (defined(OPENSSL_EXTRA) || \
13502
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
13503
                        && !defined(WOLFCRYPT_ONLY)
13504
                    nid = NID_surname;
13505
                #endif /* OPENSSL_EXTRA */
13506
            }
13507
            else if (id == ASN_COUNTRY_NAME) {
13508
                copy = WOLFSSL_COUNTRY_NAME;
13509
                copyLen = sizeof(WOLFSSL_COUNTRY_NAME) - 1;
13510
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
13511
                    if (nameType == SUBJECT) {
13512
                        cert->subjectC = (char*)&input[srcIdx];
13513
                        cert->subjectCLen = strLen;
13514
                        cert->subjectCEnc = (char)b;
13515
                    }
13516
                #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
13517
                    else if (nameType == ISSUER) {
13518
                        cert->issuerC = (char*)&input[srcIdx];
13519
                        cert->issuerCLen = strLen;
13520
                        cert->issuerCEnc = (char)b;
13521
                    }
13522
                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
13523
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
13524
                #if (defined(OPENSSL_EXTRA) || \
13525
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
13526
                        && !defined(WOLFCRYPT_ONLY)
13527
                    nid = NID_countryName;
13528
                #endif /* OPENSSL_EXTRA */
13529
            }
13530
            else if (id == ASN_LOCALITY_NAME) {
13531
                copy = WOLFSSL_LOCALITY_NAME;
13532
                copyLen = sizeof(WOLFSSL_LOCALITY_NAME) - 1;
13533
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
13534
                    if (nameType == SUBJECT) {
13535
                        cert->subjectL = (char*)&input[srcIdx];
13536
                        cert->subjectLLen = strLen;
13537
                        cert->subjectLEnc = (char)b;
13538
                    }
13539
                    #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
13540
                    else if (nameType == ISSUER) {
13541
                        cert->issuerL = (char*)&input[srcIdx];
13542
                        cert->issuerLLen = strLen;
13543
                        cert->issuerLEnc = (char)b;
13544
                    }
13545
                    #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
13546
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
13547
                #if (defined(OPENSSL_EXTRA) || \
13548
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
13549
                        && !defined(WOLFCRYPT_ONLY)
13550
                    nid = NID_localityName;
13551
                #endif /* OPENSSL_EXTRA */
13552
            }
13553
            else if (id == ASN_STATE_NAME) {
13554
                copy = WOLFSSL_STATE_NAME;
13555
                copyLen = sizeof(WOLFSSL_STATE_NAME) - 1;
13556
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
13557
                    if (nameType == SUBJECT) {
13558
                        cert->subjectST = (char*)&input[srcIdx];
13559
                        cert->subjectSTLen = strLen;
13560
                        cert->subjectSTEnc = (char)b;
13561
                    }
13562
                #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
13563
                    else if (nameType == ISSUER) {
13564
                        cert->issuerST = (char*)&input[srcIdx];
13565
                        cert->issuerSTLen = strLen;
13566
                        cert->issuerSTEnc = (char)b;
13567
                    }
13568
                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
13569
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT*/
13570
                #if (defined(OPENSSL_EXTRA) || \
13571
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
13572
                        && !defined(WOLFCRYPT_ONLY)
13573
                    nid = NID_stateOrProvinceName;
13574
                #endif /* OPENSSL_EXTRA */
13575
            }
13576
            else if (id == ASN_ORG_NAME) {
13577
                copy = WOLFSSL_ORG_NAME;
13578
                copyLen = sizeof(WOLFSSL_ORG_NAME) - 1;
13579
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
13580
                    if (nameType == SUBJECT) {
13581
                        cert->subjectO = (char*)&input[srcIdx];
13582
                        cert->subjectOLen = strLen;
13583
                        cert->subjectOEnc = (char)b;
13584
                    }
13585
                #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
13586
                    else if (nameType == ISSUER) {
13587
                        cert->issuerO = (char*)&input[srcIdx];
13588
                        cert->issuerOLen = strLen;
13589
                        cert->issuerOEnc = (char)b;
13590
                    }
13591
                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
13592
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
13593
                #if (defined(OPENSSL_EXTRA) || \
13594
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
13595
                        && !defined(WOLFCRYPT_ONLY)
13596
                    nid = NID_organizationName;
13597
                #endif /* OPENSSL_EXTRA */
13598
            }
13599
            else if (id == ASN_ORGUNIT_NAME) {
13600
                copy = WOLFSSL_ORGUNIT_NAME;
13601
                copyLen = sizeof(WOLFSSL_ORGUNIT_NAME) - 1;
13602
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
13603
                    if (nameType == SUBJECT) {
13604
                        cert->subjectOU = (char*)&input[srcIdx];
13605
                        cert->subjectOULen = strLen;
13606
                        cert->subjectOUEnc = (char)b;
13607
                    }
13608
                #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
13609
                    else if (nameType == ISSUER) {
13610
                        cert->issuerOU = (char*)&input[srcIdx];
13611
                        cert->issuerOULen = strLen;
13612
                        cert->issuerOUEnc = (char)b;
13613
                    }
13614
                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
13615
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
13616
                #if (defined(OPENSSL_EXTRA) || \
13617
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
13618
                        && !defined(WOLFCRYPT_ONLY)
13619
                    nid = NID_organizationalUnitName;
13620
                #endif /* OPENSSL_EXTRA */
13621
            }
13622
            else if (id == ASN_SERIAL_NUMBER) {
13623
                copy = WOLFSSL_SERIAL_NUMBER;
13624
                copyLen = sizeof(WOLFSSL_SERIAL_NUMBER) - 1;
13625
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
13626
                    if (nameType == SUBJECT) {
13627
                        cert->subjectSND = (char*)&input[srcIdx];
13628
                        cert->subjectSNDLen = strLen;
13629
                        cert->subjectSNDEnc = (char)b;
13630
                    }
13631
                #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
13632
                    else if (nameType == ISSUER) {
13633
                        cert->issuerSND = (char*)&input[srcIdx];
13634
                        cert->issuerSNDLen = strLen;
13635
                        cert->issuerSNDEnc = (char)b;
13636
                    }
13637
                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
13638
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
13639
                #if (defined(OPENSSL_EXTRA) || \
13640
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
13641
                        && !defined(WOLFCRYPT_ONLY)
13642
                    nid = NID_serialNumber;
13643
                #endif /* OPENSSL_EXTRA */
13644
            }
13645
            else if (id == ASN_USER_ID) {
13646
                copy = WOLFSSL_USER_ID;
13647
                copyLen = sizeof(WOLFSSL_USER_ID) - 1;
13648
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
13649
                    if (nameType == SUBJECT) {
13650
                        cert->subjectUID = (char*)&input[srcIdx];
13651
                        cert->subjectUIDLen = strLen;
13652
                        cert->subjectUIDEnc = (char)b;
13653
                    }
13654
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
13655
                #if (defined(OPENSSL_EXTRA) || \
13656
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
13657
                        && !defined(WOLFCRYPT_ONLY)
13658
                    nid = NID_userId;
13659
                #endif /* OPENSSL_EXTRA */
13660
            }
13661
        #ifdef WOLFSSL_CERT_EXT
13662
            else if (id == ASN_STREET_ADDR) {
13663
                copy = WOLFSSL_STREET_ADDR_NAME;
13664
                copyLen = sizeof(WOLFSSL_STREET_ADDR_NAME) - 1;
13665
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
13666
                    if (nameType == SUBJECT) {
13667
                        cert->subjectStreet = (char*)&input[srcIdx];
13668
                        cert->subjectStreetLen = strLen;
13669
                        cert->subjectStreetEnc = (char)b;
13670
                    }
13671
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
13672
                #if (defined(OPENSSL_EXTRA) || \
13673
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
13674
                        && !defined(WOLFCRYPT_ONLY)
13675
                    nid = NID_streetAddress;
13676
                #endif /* OPENSSL_EXTRA */
13677
            }
13678
            else if (id == ASN_BUS_CAT) {
13679
                copy = WOLFSSL_BUS_CAT;
13680
                copyLen = sizeof(WOLFSSL_BUS_CAT) - 1;
13681
            #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
13682
                if (nameType == SUBJECT) {
13683
                    cert->subjectBC = (char*)&input[srcIdx];
13684
                    cert->subjectBCLen = strLen;
13685
                    cert->subjectBCEnc = (char)b;
13686
                }
13687
            #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
13688
            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \
13689
                        && !defined(WOLFCRYPT_ONLY)
13690
                nid = NID_businessCategory;
13691
            #endif /* OPENSSL_EXTRA */
13692
            }
13693
            else if (id == ASN_POSTAL_CODE) {
13694
                copy = WOLFSSL_POSTAL_NAME;
13695
                copyLen = sizeof(WOLFSSL_POSTAL_NAME) - 1;
13696
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
13697
                    if (nameType == SUBJECT) {
13698
                        cert->subjectPC = (char*)&input[srcIdx];
13699
                        cert->subjectPCLen = strLen;
13700
                        cert->subjectPCEnc = (char)b;
13701
                    }
13702
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT*/
13703
                #if (defined(OPENSSL_EXTRA) || \
13704
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
13705
                        && !defined(WOLFCRYPT_ONLY)
13706
                    nid = NID_postalCode;
13707
                #endif /* OPENSSL_EXTRA */
13708
            }
13709
        #endif /* WOLFSSL_CERT_EXT */
13710
        }
13711
    #ifdef WOLFSSL_CERT_EXT
13712
        else if ((srcIdx + ASN_JOI_PREFIX_SZ + 2 <= (word32)maxIdx) &&
13713
                 (0 == XMEMCMP(&input[srcIdx], ASN_JOI_PREFIX,
13714
                               ASN_JOI_PREFIX_SZ)) &&
13715
                 ((input[srcIdx+ASN_JOI_PREFIX_SZ] == ASN_JOI_C) ||
13716
                  (input[srcIdx+ASN_JOI_PREFIX_SZ] == ASN_JOI_ST)))
13717
        {
13718
            srcIdx += ASN_JOI_PREFIX_SZ;
13719
            id = input[srcIdx++];
13720
            b = input[srcIdx++]; /* encoding */
13721
13722
            if (GetLength(input, &srcIdx, &strLen,
13723
                          maxIdx) < 0) {
13724
            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
13725
            !defined(WOLFCRYPT_ONLY)
13726
                wolfSSL_X509_NAME_free(dName);
13727
            #endif /* OPENSSL_EXTRA */
13728
                return ASN_PARSE_E;
13729
            }
13730
13731
            /* Check for jurisdiction of incorporation country name */
13732
            if (id == ASN_JOI_C) {
13733
                copy = WOLFSSL_JOI_C;
13734
                copyLen = sizeof(WOLFSSL_JOI_C) - 1;
13735
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
13736
                    if (nameType == SUBJECT) {
13737
                        cert->subjectJC = (char*)&input[srcIdx];
13738
                        cert->subjectJCLen = strLen;
13739
                        cert->subjectJCEnc = (char)b;
13740
                    }
13741
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
13742
                #if (defined(OPENSSL_EXTRA) || \
13743
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
13744
                        && !defined(WOLFCRYPT_ONLY)
13745
                    nid = NID_jurisdictionCountryName;
13746
                #endif /* OPENSSL_EXTRA */
13747
            }
13748
13749
            /* Check for jurisdiction of incorporation state name */
13750
            else if (id == ASN_JOI_ST) {
13751
                copy = WOLFSSL_JOI_ST;
13752
                copyLen = sizeof(WOLFSSL_JOI_ST) - 1;
13753
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
13754
                    if (nameType == SUBJECT) {
13755
                        cert->subjectJS = (char*)&input[srcIdx];
13756
                        cert->subjectJSLen = strLen;
13757
                        cert->subjectJSEnc = (char)b;
13758
                    }
13759
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
13760
                #if (defined(OPENSSL_EXTRA) || \
13761
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
13762
                        && !defined(WOLFCRYPT_ONLY)
13763
                    nid = NID_jurisdictionStateOrProvinceName;
13764
                #endif /* OPENSSL_EXTRA */
13765
            }
13766
13767
            if ((strLen + copyLen) > (int)(WC_ASN_NAME_MAX - idx)) {
13768
                WOLFSSL_MSG("ASN Name too big, skipping");
13769
                tooBig = TRUE;
13770
            }
13771
        }
13772
    #endif /* WOLFSSL_CERT_EXT */
13773
        else {
13774
            /* skip */
13775
            byte email = FALSE;
13776
            byte pilot = FALSE;
13777
13778
            if (joint[0] == 0x2a && joint[1] == 0x86) {  /* email id hdr 42.134.* */
13779
                id = ASN_EMAIL_NAME;
13780
                email = TRUE;
13781
            }
13782
13783
            if (joint[0] == 0x9  && joint[1] == 0x92) { /* uid id hdr 9.146.* */
13784
                /* last value of OID is the type of pilot attribute */
13785
                id    = input[srcIdx + (word32)oidSz - 1];
13786
                if (id == 0x01)
13787
                    id = ASN_USER_ID;
13788
                pilot = TRUE;
13789
            }
13790
13791
            srcIdx += (word32)oidSz + 1;
13792
13793
            if (GetLength(input, &srcIdx, &strLen, maxIdx) < 0) {
13794
            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
13795
            !defined(WOLFCRYPT_ONLY)
13796
                wolfSSL_X509_NAME_free(dName);
13797
            #endif /* OPENSSL_EXTRA */
13798
                return ASN_PARSE_E;
13799
            }
13800
13801
            if (strLen > (int)(WC_ASN_NAME_MAX - idx)) {
13802
                WOLFSSL_MSG("ASN name too big, skipping");
13803
                tooBig = TRUE;
13804
            }
13805
13806
            if (email) {
13807
                copyLen = sizeof(WOLFSSL_EMAIL_ADDR) - 1;
13808
                if ((copyLen + strLen) > (int)(WC_ASN_NAME_MAX - idx)) {
13809
                    WOLFSSL_MSG("ASN name too big, skipping");
13810
                    tooBig = TRUE;
13811
                }
13812
                else {
13813
                    copy = WOLFSSL_EMAIL_ADDR;
13814
                }
13815
13816
                #if !defined(IGNORE_NAME_CONSTRAINTS) || \
13817
                     defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
13818
                    if (nameType == SUBJECT) {
13819
                        cert->subjectEmail = (char*)&input[srcIdx];
13820
                        cert->subjectEmailLen = strLen;
13821
                    }
13822
                #if defined(WOLFSSL_HAVE_ISSUER_NAMES) && \
13823
                    (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT))
13824
                    else if (nameType == ISSUER) {
13825
                        cert->issuerEmail = (char*)&input[srcIdx];
13826
                        cert->issuerEmailLen = strLen;
13827
                    }
13828
                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
13829
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
13830
                #if (defined(OPENSSL_EXTRA) || \
13831
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
13832
                        && !defined(WOLFCRYPT_ONLY)
13833
                    nid = NID_emailAddress;
13834
                #endif /* OPENSSL_EXTRA */
13835
            }
13836
13837
            if (pilot) {
13838
                switch (id) {
13839
                    case ASN_USER_ID:
13840
                        copy = WOLFSSL_USER_ID;
13841
                        copyLen = sizeof(WOLFSSL_USER_ID) - 1;
13842
                    #if (defined(OPENSSL_EXTRA) || \
13843
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
13844
                        && !defined(WOLFCRYPT_ONLY)
13845
                        nid = NID_userId;
13846
                    #endif /* OPENSSL_EXTRA */
13847
                        break;
13848
13849
                    case ASN_DOMAIN_COMPONENT:
13850
                        copy = WOLFSSL_DOMAIN_COMPONENT;
13851
                        copyLen = sizeof(WOLFSSL_DOMAIN_COMPONENT) - 1;
13852
                    #if (defined(OPENSSL_EXTRA) || \
13853
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
13854
                        && !defined(WOLFCRYPT_ONLY)
13855
                        nid = NID_domainComponent;
13856
                    #endif /* OPENSSL_EXTRA */
13857
                        break;
13858
                    case ASN_FAVOURITE_DRINK:
13859
                        copy = WOLFSSL_FAVOURITE_DRINK;
13860
                        copyLen = sizeof(WOLFSSL_FAVOURITE_DRINK) - 1;
13861
                    #if (defined(OPENSSL_EXTRA) || \
13862
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
13863
                        && !defined(WOLFCRYPT_ONLY)
13864
                        nid = NID_favouriteDrink;
13865
                    #endif /* OPENSSL_EXTRA */
13866
                        break;
13867
13868
                    default:
13869
                        WOLFSSL_MSG("Unknown pilot attribute type");
13870
                    #if (defined(OPENSSL_EXTRA) || \
13871
                                defined(OPENSSL_EXTRA_X509_SMALL)) && \
13872
                                !defined(WOLFCRYPT_ONLY)
13873
                        wolfSSL_X509_NAME_free(dName);
13874
                    #endif /* OPENSSL_EXTRA */
13875
                        return ASN_PARSE_E;
13876
                }
13877
            }
13878
        }
13879
        if ((copyLen + strLen) > (int)(WC_ASN_NAME_MAX - idx))
13880
        {
13881
            WOLFSSL_MSG("ASN Name too big, skipping");
13882
            tooBig = TRUE;
13883
        }
13884
        if ((copy != NULL) && !tooBig) {
13885
            XMEMCPY(&full[idx], copy, (size_t)copyLen);
13886
            idx += (word32)copyLen;
13887
            XMEMCPY(&full[idx], &input[srcIdx], (size_t)strLen);
13888
            idx += (word32)strLen;
13889
        }
13890
        #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
13891
            !defined(WOLFCRYPT_ONLY)
13892
        switch (b) {
13893
            case CTC_UTF8:
13894
                enc = MBSTRING_UTF8;
13895
                break;
13896
            case CTC_PRINTABLE:
13897
                enc = V_ASN1_PRINTABLESTRING;
13898
                break;
13899
            default:
13900
                WOLFSSL_MSG("Unknown encoding type, using UTF8 by default");
13901
                enc = MBSTRING_UTF8;
13902
        }
13903
13904
        if (nid != NID_undef) {
13905
            if (wolfSSL_X509_NAME_add_entry_by_NID(dName, nid, enc,
13906
                            &input[srcIdx], strLen, -1, -1) !=
13907
                            WOLFSSL_SUCCESS) {
13908
                wolfSSL_X509_NAME_free(dName);
13909
                return ASN_PARSE_E;
13910
            }
13911
        }
13912
        #endif /* OPENSSL_EXTRA */
13913
        srcIdx += (word32)strLen;
13914
    }
13915
    full[idx++] = 0;
13916
13917
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
13918
            !defined(WOLFCRYPT_ONLY)
13919
    if (nameType == ISSUER) {
13920
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY)) && \
13921
    (defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT))
13922
        dName->rawLen = min(cert->issuerRawLen, WC_ASN_NAME_MAX);
13923
        XMEMCPY(dName->raw, cert->issuerRaw, dName->rawLen);
13924
#endif
13925
        cert->issuerName = dName;
13926
    }
13927
    else {
13928
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
13929
        dName->rawLen = min(cert->subjectRawLen, WC_ASN_NAME_MAX);
13930
        XMEMCPY(dName->raw, cert->subjectRaw, dName->rawLen);
13931
#endif
13932
        cert->subjectName = dName;
13933
    }
13934
#endif
13935
13936
    *inOutIdx = srcIdx;
13937
13938
    return 0;
13939
#else
13940
0
    DECL_ASNGETDATA(dataASN, rdnASN_Length);
13941
0
    int    ret = 0;
13942
0
    word32 idx = 0;
13943
0
    int    len;
13944
0
    word32 srcIdx = *inOutIdx;
13945
#ifdef WOLFSSL_X509_NAME_AVAILABLE
13946
    WOLFSSL_X509_NAME* dName = NULL;
13947
#endif /* WOLFSSL_X509_NAME_AVAILABLE */
13948
13949
0
    WOLFSSL_MSG("Getting Cert Name");
13950
13951
    /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
13952
     * calculated over the entire DER encoding of the Name field, including
13953
     * the tag and length. */
13954
0
    if (CalcHashId_ex(input + srcIdx, maxIdx - srcIdx, hash,
13955
0
            HashIdAlg(cert->signatureOID)) != 0) {
13956
0
        ret = ASN_PARSE_E;
13957
0
    }
13958
13959
0
    CALLOC_ASNGETDATA(dataASN, rdnASN_Length, ret, cert->heap);
13960
13961
#ifdef WOLFSSL_X509_NAME_AVAILABLE
13962
    if (ret == 0) {
13963
        /* Create an X509_NAME to hold data for OpenSSL compatability APIs. */
13964
        dName = wolfSSL_X509_NAME_new_ex(cert->heap);
13965
        if (dName == NULL) {
13966
            ret = MEMORY_E;
13967
        }
13968
    }
13969
#endif /* WOLFSSL_X509_NAME_AVAILABLE */
13970
13971
0
    if (ret == 0) {
13972
        /* Expecting a SEQUENCE using up all data. */
13973
0
        ret = GetASN_Sequence(input, &srcIdx, &len, maxIdx, 1);
13974
0
    }
13975
0
    if (ret == 0) {
13976
    #if defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT)
13977
        /* Store pointer and length to raw issuer. */
13978
        if (nameType == ISSUER) {
13979
            cert->issuerRaw = &input[srcIdx];
13980
            cert->issuerRawLen = len;
13981
        }
13982
    #endif
13983
0
    #if !defined(IGNORE_NAME_CONSTRAINTS) || defined(WOLFSSL_CERT_EXT)
13984
        /* Store pointer and length to raw subject. */
13985
0
        if (nameType == SUBJECT) {
13986
0
            cert->subjectRaw = &input[srcIdx];
13987
0
            cert->subjectRawLen = len;
13988
0
        }
13989
0
    #endif
13990
13991
        /* Process all RDNs in name. */
13992
0
        while ((ret == 0) && (srcIdx < maxIdx)) {
13993
0
            int nid = 0;
13994
13995
            /* Initialize for data and setup RDN choice. */
13996
0
            GetASN_Choice(&dataASN[RDNASN_IDX_ATTR_VAL], rdnChoice);
13997
            /* Ignore type OID as too many to store in table. */
13998
0
            GetASN_OID(&dataASN[RDNASN_IDX_ATTR_TYPE], oidIgnoreType);
13999
            /* Parse RDN. */
14000
0
            ret = GetASN_Items(rdnASN, dataASN, rdnASN_Length, 1, input,
14001
0
                               &srcIdx, maxIdx);
14002
0
            if (ret == 0) {
14003
                /* Put RDN data into certificate. */
14004
0
                ret = GetRDN(cert, full, &idx, &nid, nameType == SUBJECT,
14005
0
                             dataASN);
14006
0
            }
14007
        #ifdef WOLFSSL_X509_NAME_AVAILABLE
14008
            /* TODO: push this back up to ssl.c
14009
             * (do parsing for WOLFSSL_X509_NAME on demand) */
14010
            if (ret == 0) {
14011
                int enc;
14012
                byte*  str;
14013
                word32 strLen;
14014
                byte   tag = dataASN[RDNASN_IDX_ATTR_VAL].tag;
14015
14016
                /* Get string reference. */
14017
                GetASN_GetRef(&dataASN[RDNASN_IDX_ATTR_VAL], &str, &strLen);
14018
14019
                /* Convert BER tag to a OpenSSL type. */
14020
                switch (tag) {
14021
                    case CTC_UTF8:
14022
                        enc = MBSTRING_UTF8;
14023
                        break;
14024
                    case CTC_PRINTABLE:
14025
                        enc = V_ASN1_PRINTABLESTRING;
14026
                        break;
14027
                    default:
14028
                        WOLFSSL_MSG("Unknown encoding type, default UTF8");
14029
                        enc = MBSTRING_UTF8;
14030
                }
14031
                if (nid != 0) {
14032
                    /* Add an entry to the X509_NAME. */
14033
                    if (wolfSSL_X509_NAME_add_entry_by_NID(dName, nid, enc, str,
14034
                            (int)strLen, -1, -1) != WOLFSSL_SUCCESS) {
14035
                        ret = ASN_PARSE_E;
14036
                    }
14037
                }
14038
            }
14039
        #endif
14040
0
        }
14041
0
    }
14042
0
    if (ret == 0) {
14043
        /* Terminate string. */
14044
0
        full[idx] = 0;
14045
        /* Return index into encoding after name. */
14046
0
        *inOutIdx = srcIdx;
14047
14048
#ifdef WOLFSSL_X509_NAME_AVAILABLE
14049
        /* Store X509_NAME in certificate. */
14050
        if (nameType == ISSUER) {
14051
        #if (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
14052
             defined(HAVE_LIGHTY)) && \
14053
            (defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT))
14054
            dName->rawLen = (int)min((word32)cert->issuerRawLen,
14055
                WC_ASN_NAME_MAX);
14056
            XMEMCPY(dName->raw, cert->issuerRaw, (size_t)dName->rawLen);
14057
        #endif
14058
            cert->issuerName = dName;
14059
        }
14060
        else {
14061
        #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
14062
            dName->rawLen = (int)min((word32)cert->subjectRawLen,
14063
                WC_ASN_NAME_MAX);
14064
            XMEMCPY(dName->raw, cert->subjectRaw, (size_t)dName->rawLen);
14065
        #endif
14066
            cert->subjectName = dName;
14067
        }
14068
    }
14069
    else {
14070
        /* Dispose of unused X509_NAME. */
14071
        wolfSSL_X509_NAME_free(dName);
14072
#endif
14073
0
    }
14074
14075
0
    FREE_ASNGETDATA(dataASN, cert->heap);
14076
0
    return ret;
14077
0
#endif /* WOLFSSL_ASN_TEMPLATE */
14078
0
}
14079
14080
#ifdef WOLFSSL_ASN_TEMPLATE
14081
/* ASN.1 template for certificate name. */
14082
static const ASNItem certNameASN[] = {
14083
/* OID  */ { 0, ASN_OBJECT_ID, 0, 0, 1 },
14084
/* NAME */ { 0, ASN_SEQUENCE, 1, 0, 0 },
14085
};
14086
enum {
14087
    CERTNAMEASN_IDX_OID = 0,
14088
    CERTNAMEASN_IDX_NAME
14089
};
14090
14091
/* Number of items in ASN.1 template for certificate name. */
14092
0
#define certNameASN_Length (sizeof(certNameASN) / sizeof(ASNItem))
14093
#endif
14094
14095
/* Get a certificate name into the certificate object.
14096
 *
14097
 * Either the issuer or subject name.
14098
 *
14099
 * @param [in, out] cert      Decoded certificate object.
14100
 * @param [in]      nameType  Type of name being decoded: ISSUER or SUBJECT.
14101
 * @param [in]      maxIdx    Index of next item after certificate name.
14102
 * @return  0 on success.
14103
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
14104
 *          is invalid.
14105
 * @return  BUFFER_E when data in buffer is too small.
14106
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
14107
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
14108
 * @return  MEMORY_E when dynamic memory allocation fails.
14109
 */
14110
int GetName(DecodedCert* cert, int nameType, int maxIdx)
14111
0
{
14112
#ifndef WOLFSSL_ASN_TEMPLATE
14113
    char*  full;
14114
    byte*  hash;
14115
    int    length;
14116
    word32 localIdx;
14117
    byte   tag;
14118
14119
    WOLFSSL_MSG("Getting Name");
14120
14121
    if (nameType == ISSUER) {
14122
        full = cert->issuer;
14123
        hash = cert->issuerHash;
14124
    }
14125
    else {
14126
        full = cert->subject;
14127
        hash = cert->subjectHash;
14128
    }
14129
14130
    if (cert->srcIdx >= (word32)maxIdx) {
14131
        return BUFFER_E;
14132
    }
14133
14134
    localIdx = cert->srcIdx;
14135
    if (GetASNTag(cert->source, &localIdx, &tag, (word32)maxIdx) < 0) {
14136
        return ASN_PARSE_E;
14137
    }
14138
14139
    if (tag == ASN_OBJECT_ID) {
14140
        WOLFSSL_MSG("Trying optional prefix...");
14141
14142
        if (SkipObjectId(cert->source, &cert->srcIdx, (word32)maxIdx) < 0)
14143
            return ASN_PARSE_E;
14144
        WOLFSSL_MSG("Got optional prefix");
14145
    }
14146
14147
    localIdx = cert->srcIdx;
14148
    if (GetASNTag(cert->source, &localIdx, &tag, (word32)maxIdx) < 0) {
14149
        return ASN_PARSE_E;
14150
    }
14151
    localIdx = cert->srcIdx + 1;
14152
    if (GetLength(cert->source, &localIdx, &length, (word32)maxIdx) < 0) {
14153
        return ASN_PARSE_E;
14154
    }
14155
    length += (int)(localIdx - cert->srcIdx);
14156
14157
    return GetCertName(cert, full, hash, nameType, cert->source, &cert->srcIdx,
14158
                       cert->srcIdx + (word32)length);
14159
#else
14160
0
    ASNGetData dataASN[certNameASN_Length];
14161
0
    word32 idx = cert->srcIdx;
14162
0
    int    ret = 0;
14163
14164
0
    WOLFSSL_MSG("Getting Name");
14165
14166
0
    XMEMSET(dataASN, 0, sizeof(dataASN));
14167
    /* Initialize for data and don't check optional prefix OID. */
14168
0
    GetASN_OID(&dataASN[CERTNAMEASN_IDX_OID], oidIgnoreType);
14169
0
    ret = GetASN_Items(certNameASN, dataASN, certNameASN_Length, 0,
14170
0
                       cert->source, &idx, (word32)maxIdx);
14171
0
    if (ret == 0) {
14172
0
        char* full;
14173
0
        byte* hash;
14174
14175
        /* Store offset of SEQUENCE that is start of name. */
14176
0
        cert->srcIdx = dataASN[CERTNAMEASN_IDX_NAME].offset;
14177
14178
        /* Get fields to fill in based on name type. */
14179
0
        if (nameType == ISSUER) {
14180
0
            full = cert->issuer;
14181
0
            hash = cert->issuerHash;
14182
0
        }
14183
0
        else {
14184
0
            full = cert->subject;
14185
0
            hash = cert->subjectHash;
14186
0
        }
14187
14188
        /* Parse certificate name. */
14189
0
        ret = GetCertName(cert, full, hash, nameType, cert->source,
14190
0
                          &cert->srcIdx, idx);
14191
0
    }
14192
14193
0
    return ret;
14194
0
#endif
14195
0
}
14196
14197
#ifndef NO_ASN_TIME
14198
14199
/* two byte date/time, add to value */
14200
static WC_INLINE int GetTime(int* value, const byte* date, int* idx)
14201
0
{
14202
0
    int i = *idx;
14203
14204
0
    if (date[i] < 0x30 || date[i] > 0x39 || date[i+1] < 0x30 ||
14205
0
                                                             date[i+1] > 0x39) {
14206
0
        return ASN_PARSE_E;
14207
0
    }
14208
14209
0
    *value += (int)btoi(date[i++]) * 10;
14210
0
    *value += (int)btoi(date[i++]);
14211
14212
0
    *idx = i;
14213
14214
0
    return 0;
14215
0
}
14216
14217
#ifdef WOLFSSL_LINUXKM
14218
static WC_INLINE int GetTime_Long(long* value, const byte* date, int* idx)
14219
{
14220
    int i = *idx;
14221
14222
    if (date[i] < 0x30 || date[i] > 0x39 || date[i+1] < 0x30 ||
14223
                                                             date[i+1] > 0x39) {
14224
        return ASN_PARSE_E;
14225
    }
14226
14227
    *value += (long)btoi(date[i++]) * 10;
14228
    *value += (long)btoi(date[i++]);
14229
14230
    *idx = i;
14231
14232
    return 0;
14233
}
14234
#endif
14235
14236
int ExtractDate(const unsigned char* date, unsigned char format,
14237
                                                  struct tm* certTime, int* idx)
14238
0
{
14239
0
    XMEMSET(certTime, 0, sizeof(struct tm));
14240
14241
0
    if (format == ASN_UTC_TIME) {
14242
0
        if (btoi(date[*idx]) >= 5)
14243
0
            certTime->tm_year = 1900;
14244
0
        else
14245
0
            certTime->tm_year = 2000;
14246
0
    }
14247
0
    else  { /* format == GENERALIZED_TIME */
14248
#ifdef WOLFSSL_LINUXKM
14249
        if (GetTime_Long(&certTime->tm_year, date, idx) != 0) return 0;
14250
#else
14251
0
        if (GetTime(&certTime->tm_year, date, idx) != 0) return 0;
14252
0
#endif
14253
0
        certTime->tm_year *= 100;
14254
0
    }
14255
14256
#ifdef AVR
14257
    /* Extract the time from the struct tm and adjust tm_year, tm_mon */
14258
    /* AVR libc stores these as uint8_t instead of int */
14259
    /* AVR time_t also offsets from midnight 1 Jan 2000 */
14260
    int tm_year = certTime->tm_year - 2000;
14261
    int tm_mon  = certTime->tm_mon - 1;
14262
    int tm_mday = certTime->tm_mday;
14263
    int tm_hour = certTime->tm_hour;
14264
    int tm_min  = certTime->tm_min;
14265
    int tm_sec  = certTime->tm_sec;
14266
14267
#ifdef WOLFSSL_LINUXKM
14268
    if (GetTime_Long(&tm_year, date, idx) != 0) return 0;
14269
#else
14270
    if (GetTime(&tm_year, date, idx) != 0) return 0;
14271
#endif
14272
    if (GetTime(&tm_mon , date, idx) != 0) return 0;
14273
    if (GetTime(&tm_mday, date, idx) != 0) return 0;
14274
    if (GetTime(&tm_hour, date, idx) != 0) return 0;
14275
    if (GetTime(&tm_min , date, idx) != 0) return 0;
14276
    if (GetTime(&tm_sec , date, idx) != 0) return 0;
14277
14278
    /* Re-populate certTime with computed values */
14279
    certTime->tm_year = tm_year;
14280
    certTime->tm_mon  = tm_mon;
14281
    certTime->tm_mday = tm_mday;
14282
    certTime->tm_hour = tm_hour;
14283
    certTime->tm_min  = tm_min;
14284
    certTime->tm_sec  = tm_sec;
14285
#else
14286
    /* adjust tm_year, tm_mon */
14287
#ifdef WOLFSSL_LINUXKM
14288
    if (GetTime_Long(&certTime->tm_year, date, idx) != 0) return 0;
14289
#else
14290
0
    if (GetTime(&certTime->tm_year, date, idx) != 0) return 0;
14291
0
#endif
14292
0
    certTime->tm_year -= 1900;
14293
0
    if (GetTime(&certTime->tm_mon , date, idx) != 0) return 0;
14294
0
    certTime->tm_mon  -= 1;
14295
0
    if (GetTime(&certTime->tm_mday, date, idx) != 0) return 0;
14296
0
    if (GetTime(&certTime->tm_hour, date, idx) != 0) return 0;
14297
0
    if (GetTime(&certTime->tm_min , date, idx) != 0) return 0;
14298
0
    if (GetTime(&certTime->tm_sec , date, idx) != 0) return 0;
14299
0
#endif
14300
14301
0
    return 1;
14302
0
}
14303
14304
14305
#if defined(OPENSSL_ALL) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
14306
    defined(OPENSSL_EXTRA) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
14307
int GetTimeString(byte* date, int format, char* buf, int len)
14308
{
14309
    struct tm t;
14310
    int idx = 0;
14311
14312
    if (!ExtractDate(date, (unsigned char)format, &t, &idx)) {
14313
        return 0;
14314
    }
14315
14316
    if (date[idx] != 'Z') {
14317
        WOLFSSL_MSG("UTCtime, not Zulu") ;
14318
        return 0;
14319
    }
14320
14321
    /* place month in buffer */
14322
    buf[0] = '\0';
14323
    switch(t.tm_mon) {
14324
        case 0:  XSTRNCAT(buf, "Jan ", 5); break;
14325
        case 1:  XSTRNCAT(buf, "Feb ", 5); break;
14326
        case 2:  XSTRNCAT(buf, "Mar ", 5); break;
14327
        case 3:  XSTRNCAT(buf, "Apr ", 5); break;
14328
        case 4:  XSTRNCAT(buf, "May ", 5); break;
14329
        case 5:  XSTRNCAT(buf, "Jun ", 5); break;
14330
        case 6:  XSTRNCAT(buf, "Jul ", 5); break;
14331
        case 7:  XSTRNCAT(buf, "Aug ", 5); break;
14332
        case 8:  XSTRNCAT(buf, "Sep ", 5); break;
14333
        case 9:  XSTRNCAT(buf, "Oct ", 5); break;
14334
        case 10: XSTRNCAT(buf, "Nov ", 5); break;
14335
        case 11: XSTRNCAT(buf, "Dec ", 5); break;
14336
        default:
14337
            return 0;
14338
14339
    }
14340
    idx = 4; /* use idx now for char buffer */
14341
14342
    if (XSNPRINTF(buf + idx, (size_t)(len - idx), "%2d %02d:%02d:%02d %d GMT",
14343
              t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, (int)t.tm_year + 1900)
14344
        >= len - idx)
14345
    {
14346
        WOLFSSL_MSG("buffer overrun in GetTimeString");
14347
        return 0;
14348
    }
14349
14350
    return 1;
14351
}
14352
#endif /* OPENSSL_ALL || WOLFSSL_MYSQL_COMPATIBLE || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
14353
14354
14355
#if !defined(NO_ASN_TIME) && !defined(USER_TIME) && \
14356
    !defined(TIME_OVERRIDES) && (defined(OPENSSL_EXTRA) || defined(HAVE_PKCS7))
14357
/* Set current time string, either UTC or GeneralizedTime.
14358
 * (void*) tm should be a pointer to time_t, output is placed in buf.
14359
 *
14360
 * Return time string length placed in buf on success, negative on error */
14361
int GetAsnTimeString(void* currTime, byte* buf, word32 len)
14362
{
14363
    byte* data_ptr  = buf;
14364
    byte  uf_time[ASN_GENERALIZED_TIME_SIZE];
14365
    int data_len = 0;
14366
14367
    WOLFSSL_ENTER("GetAsnTimeString");
14368
14369
    if (buf == NULL || len == 0)
14370
        return BAD_FUNC_ARG;
14371
14372
    XMEMSET(uf_time, 0, sizeof(uf_time));
14373
    /* GetFormattedTime returns length with null terminator */
14374
    data_len = GetFormattedTime(currTime, uf_time, (word32)sizeof(uf_time));
14375
    if (data_len <= 0) {
14376
        return ASN_TIME_E;
14377
    }
14378
    /* ensure room to add 2 bytes (ASN type and length) before proceeding */
14379
    else if (len < (word32)data_len + 2) {
14380
        return BUFFER_E;
14381
    }
14382
14383
    if (data_len == ASN_UTC_TIME_SIZE-1) {
14384
        /* increment data_len for ASN length byte after adding the data_ptr */
14385
        *data_ptr = (byte)ASN_UTC_TIME; data_ptr++; data_len++;
14386
        /* -1 below excludes null terminator */
14387
        *data_ptr = (byte)ASN_UTC_TIME_SIZE - 1; data_ptr++; data_len++;
14388
        XMEMCPY(data_ptr, (byte *)uf_time, ASN_UTC_TIME_SIZE - 1);
14389
        data_ptr += ASN_UTC_TIME_SIZE - 1;
14390
    }
14391
    else if (data_len == ASN_GENERALIZED_TIME_SIZE-1) {
14392
        /* increment data_len for ASN length byte after adding the data_ptr */
14393
        *data_ptr = (byte)ASN_GENERALIZED_TIME; data_ptr++; data_len++;
14394
        /* -1 below excludes null terminator */
14395
        *data_ptr = (byte)ASN_GENERALIZED_TIME_SIZE - 1; data_ptr++; data_len++;
14396
        XMEMCPY(data_ptr, (byte*)uf_time, ASN_GENERALIZED_TIME_SIZE - 1);
14397
        data_ptr += ASN_GENERALIZED_TIME_SIZE - 1;
14398
    }
14399
    else {
14400
        WOLFSSL_MSG("Invalid time size returned");
14401
        return ASN_TIME_E;
14402
    }
14403
    /* append null terminator */
14404
    *data_ptr = 0;
14405
14406
    /* return length without null terminator */
14407
    return data_len;
14408
}
14409
14410
/* return just the time string as either UTC or Generalized Time*/
14411
int GetFormattedTime(void* currTime, byte* buf, word32 len)
14412
{
14413
    struct tm* ts      = NULL;
14414
    struct tm* tmpTime = NULL;
14415
    int year, mon, day, hour, mini, sec;
14416
    int ret;
14417
#if defined(NEED_TMP_TIME)
14418
    struct tm tmpTimeStorage;
14419
    tmpTime = &tmpTimeStorage;
14420
#endif
14421
    /* Needed in case XGMTIME does not use the tmpTime argument. */
14422
    (void)tmpTime;
14423
14424
    WOLFSSL_ENTER("GetFormattedTime");
14425
14426
    if (buf == NULL || len == 0)
14427
        return BAD_FUNC_ARG;
14428
14429
    ts = (struct tm *)XGMTIME((time_t*)currTime, tmpTime);
14430
    if (ts == NULL) {
14431
        WOLFSSL_MSG("failed to get time data.");
14432
        return ASN_TIME_E;
14433
    }
14434
14435
    /* Note ASN_UTC_TIME_SIZE and ASN_GENERALIZED_TIME_SIZE include space for
14436
     * the null terminator. ASN encoded values leave off the terminator. */
14437
14438
    if (ts->tm_year >= 50 && ts->tm_year < 150) {
14439
        /* UTC Time */
14440
        if (ts->tm_year >= 50 && ts->tm_year < 100) {
14441
            year = ts->tm_year;
14442
        }
14443
        else {
14444
            year = ts->tm_year - 100;
14445
        }
14446
        mon  = ts->tm_mon + 1;
14447
        day  = ts->tm_mday;
14448
        hour = ts->tm_hour;
14449
        mini = ts->tm_min;
14450
        sec  = ts->tm_sec;
14451
    #if defined(WOLF_C89)
14452
        if (len < ASN_UTC_TIME_SIZE) {
14453
            WOLFSSL_MSG("buffer for GetFormattedTime is too short.");
14454
            return BUFFER_E;
14455
        }
14456
        ret = XSPRINTF((char*)buf,
14457
                        "%02d%02d%02d%02d%02d%02dZ", year, mon, day,
14458
                        hour, mini, sec);
14459
    #else
14460
        ret = XSNPRINTF((char*)buf, len,
14461
                        "%02d%02d%02d%02d%02d%02dZ", year, mon, day,
14462
                        hour, mini, sec);
14463
    #endif
14464
    }
14465
    else {
14466
        /* GeneralizedTime */
14467
        year = ts->tm_year + 1900;
14468
        mon  = ts->tm_mon + 1;
14469
        day  = ts->tm_mday;
14470
        hour = ts->tm_hour;
14471
        mini = ts->tm_min;
14472
        sec  = ts->tm_sec;
14473
    #if defined(WOLF_C89)
14474
        if (len < ASN_GENERALIZED_TIME_SIZE) {
14475
            WOLFSSL_MSG("buffer for GetFormattedTime is too short.");
14476
            return BUFFER_E;
14477
        }
14478
        ret = XSPRINTF((char*)buf,
14479
                        "%4d%02d%02d%02d%02d%02dZ", year, mon, day,
14480
                        hour, mini, sec);
14481
    #else
14482
        ret = XSNPRINTF((char*)buf, len,
14483
                        "%4d%02d%02d%02d%02d%02dZ", year, mon, day,
14484
                        hour, mini, sec);
14485
    #endif
14486
    }
14487
14488
    return ret;
14489
}
14490
14491
#endif /* !NO_ASN_TIME && !USER_TIME && !TIME_OVERRIDES &&
14492
        * (OPENSSL_EXTRA || HAVE_PKCS7) */
14493
14494
#if defined(USE_WOLF_VALIDDATE)
14495
14496
/* to the second */
14497
int DateGreaterThan(const struct tm* a, const struct tm* b)
14498
0
{
14499
0
    if (a->tm_year > b->tm_year)
14500
0
        return 1;
14501
14502
0
    if (a->tm_year == b->tm_year && a->tm_mon > b->tm_mon)
14503
0
        return 1;
14504
14505
0
    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
14506
0
           a->tm_mday > b->tm_mday)
14507
0
        return 1;
14508
14509
0
    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
14510
0
        a->tm_mday == b->tm_mday && a->tm_hour > b->tm_hour)
14511
0
        return 1;
14512
14513
0
    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
14514
0
        a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
14515
0
        a->tm_min > b->tm_min)
14516
0
        return 1;
14517
14518
0
    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
14519
0
        a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
14520
0
        a->tm_min  == b->tm_min  && a->tm_sec > b->tm_sec)
14521
0
        return 1;
14522
14523
0
    return 0; /* false */
14524
0
}
14525
14526
14527
static WC_INLINE int DateLessThan(const struct tm* a, const struct tm* b)
14528
0
{
14529
0
    return DateGreaterThan(b,a);
14530
0
}
14531
14532
/* like atoi but only use first byte */
14533
/* Make sure before and after dates are valid */
14534
int wc_ValidateDate(const byte* date, byte format, int dateType)
14535
0
{
14536
0
    time_t ltime;
14537
0
    struct tm  certTime;
14538
0
    struct tm* localTime;
14539
0
    struct tm* tmpTime;
14540
0
    int    i = 0;
14541
0
    int    timeDiff = 0;
14542
0
    int    diffHH = 0, diffMM = 0;
14543
14544
0
#if defined(NEED_TMP_TIME)
14545
0
    struct tm tmpTimeStorage;
14546
0
    tmpTime = &tmpTimeStorage;
14547
#else
14548
    tmpTime = NULL;
14549
#endif
14550
0
    (void)tmpTime;
14551
14552
0
    ltime = wc_Time(0);
14553
0
    if (sizeof(ltime) == sizeof(word32) && (int)ltime < 0){
14554
        /* A negative response here could be due to a 32-bit time_t
14555
         * where the year is 2038 or later. */
14556
0
        WOLFSSL_MSG("wc_Time failed to return a valid value");
14557
0
        return 0;
14558
0
    }
14559
14560
#ifdef WOLFSSL_BEFORE_DATE_CLOCK_SKEW
14561
    if (dateType == BEFORE) {
14562
        WOLFSSL_MSG("Skewing local time for before date check");
14563
        ltime += WOLFSSL_BEFORE_DATE_CLOCK_SKEW;
14564
    }
14565
#endif
14566
14567
#ifdef WOLFSSL_AFTER_DATE_CLOCK_SKEW
14568
    if (dateType == AFTER) {
14569
        WOLFSSL_MSG("Skewing local time for after date check");
14570
        ltime -= WOLFSSL_AFTER_DATE_CLOCK_SKEW;
14571
    }
14572
#endif
14573
14574
0
    if (!ExtractDate(date, format, &certTime, &i)) {
14575
0
        WOLFSSL_MSG("Error extracting the date");
14576
0
        return 0;
14577
0
    }
14578
14579
0
    if ((date[i] == '+') || (date[i] == '-')) {
14580
0
        int diffSign;
14581
14582
0
        WOLFSSL_MSG("Using time differential, not Zulu") ;
14583
0
        diffSign = date[i++] == '+' ? 1 : -1 ;
14584
0
        if (GetTime(&diffHH, date, &i) != 0)
14585
0
            return 0;
14586
0
        if (GetTime(&diffMM, date, &i) != 0)
14587
0
            return 0;
14588
0
        timeDiff = diffSign * (diffHH*60 + diffMM) * 60 ;
14589
0
    } else if (date[i] != 'Z') {
14590
0
        WOLFSSL_MSG("UTCtime, neither Zulu or time differential") ;
14591
0
        return 0;
14592
0
    }
14593
14594
0
    ltime -= (time_t)timeDiff;
14595
0
    localTime = XGMTIME(&ltime, tmpTime);
14596
14597
0
    if (localTime == NULL) {
14598
0
        WOLFSSL_MSG("XGMTIME failed");
14599
0
        return 0;
14600
0
    }
14601
14602
0
    if (dateType == BEFORE) {
14603
0
        if (DateLessThan(localTime, &certTime)) {
14604
0
            WOLFSSL_MSG("Date BEFORE check failed");
14605
0
            return 0;
14606
0
        }
14607
0
    }
14608
0
    else {  /* dateType == AFTER */
14609
0
        if (DateGreaterThan(localTime, &certTime)) {
14610
0
            WOLFSSL_MSG("Date AFTER check failed");
14611
0
            return 0;
14612
0
        }
14613
0
    }
14614
14615
0
    return 1;
14616
0
}
14617
#endif /* USE_WOLF_VALIDDATE */
14618
14619
int wc_GetTime(void* timePtr, word32 timeSize)
14620
0
{
14621
0
    time_t* ltime = (time_t*)timePtr;
14622
14623
0
    if (timePtr == NULL) {
14624
0
        return BAD_FUNC_ARG;
14625
0
    }
14626
14627
0
    if ((word32)sizeof(time_t) > timeSize) {
14628
0
        return BUFFER_E;
14629
0
    }
14630
14631
0
    *ltime = wc_Time(0);
14632
14633
0
    return 0;
14634
0
}
14635
14636
#ifdef TIME_OVERRIDES
14637
    #ifndef HAVE_TIME_T_TYPE
14638
        typedef long time_t;
14639
    #endif
14640
    extern time_t XTIME(time_t* t);
14641
#endif
14642
14643
static wc_time_cb timeFunc = NULL;
14644
14645
int wc_SetTimeCb(wc_time_cb f)
14646
0
{
14647
0
    timeFunc = f;
14648
0
    return 0;
14649
0
}
14650
14651
time_t wc_Time(time_t* t)
14652
0
{
14653
0
    if (timeFunc != NULL) {
14654
0
        return timeFunc(t);
14655
0
    }
14656
0
    return XTIME(t);
14657
0
}
14658
14659
#endif /* !NO_ASN_TIME */
14660
14661
14662
#ifdef WOLFSSL_ASN_TEMPLATE
14663
/* TODO: use a CHOICE instead of two items? */
14664
/* ASN.1 template for a date - either UTC or Generalized Time. */
14665
static const ASNItem dateASN[] = {
14666
/* UTC */ { 0, ASN_UTC_TIME, 0, 0, 2 },
14667
/* GT  */ { 0, ASN_GENERALIZED_TIME, 0, 0, 2 },
14668
};
14669
enum {
14670
    DATEASN_IDX_UTC = 0,
14671
    DATEASN_IDX_GT
14672
};
14673
14674
/* Number of items in ASN.1 template for a date. */
14675
0
#define dateASN_Length (sizeof(dateASN) / sizeof(ASNItem))
14676
#endif /* WOLFSSL_ASN_TEMPLATE */
14677
14678
/* Get date buffer, format and length. Returns 0=success or error */
14679
/* Decode a DateInfo - choice of UTC TIME or GENERALIZED TIME.
14680
 *
14681
 * @param [in]      source   Buffer containing encoded date.
14682
 * @param [in, out] idx      On in, the index of the date.
14683
 *                           On out, index after date.
14684
 * @param [out]     pDate    Pointer into buffer of data bytes.
14685
 * @param [out]     pFormat  Format of date - BER/DER tag.
14686
 * @param [out]     pLength  Length of date bytes.
14687
 * @param [in]      maxIdx   Index of next item after date.
14688
 * @return  0 on success.
14689
 * @return  BAD_FUNC_ARG when source or idx is NULL.
14690
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
14691
 *          is invalid.
14692
 * @return  BUFFER_E when data in buffer is too small.
14693
 */
14694
static int GetDateInfo(const byte* source, word32* idx, const byte** pDate,
14695
                        byte* pFormat, int* pLength, word32 maxIdx)
14696
0
{
14697
#ifndef WOLFSSL_ASN_TEMPLATE
14698
    int length;
14699
    byte format;
14700
14701
    if (source == NULL || idx == NULL)
14702
        return BAD_FUNC_ARG;
14703
14704
    /* get ASN format header */
14705
    if (*idx+1 > maxIdx)
14706
        return BUFFER_E;
14707
    format = source[*idx];
14708
    *idx += 1;
14709
    if (format != ASN_UTC_TIME && format != ASN_GENERALIZED_TIME) {
14710
        WOLFSSL_ERROR_VERBOSE(ASN_TIME_E);
14711
        return ASN_TIME_E;
14712
    }
14713
14714
    /* get length */
14715
    if (GetLength(source, idx, &length, maxIdx) < 0)
14716
        return ASN_PARSE_E;
14717
    if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
14718
        return ASN_DATE_SZ_E;
14719
14720
    /* return format, date and length */
14721
    if (pFormat)
14722
        *pFormat = format;
14723
    if (pDate)
14724
        *pDate = &source[*idx];
14725
    if (pLength)
14726
        *pLength = length;
14727
14728
    *idx += (word32)length;
14729
14730
    return 0;
14731
#else
14732
0
    ASNGetData dataASN[dateASN_Length];
14733
0
    int ret = 0;
14734
14735
0
    if ((source == NULL) || (idx == NULL)) {
14736
0
        ret = BAD_FUNC_ARG;
14737
0
    }
14738
0
    if (ret == 0) {
14739
        /* Initialize data. */
14740
0
        XMEMSET(dataASN, 0, sizeof(dataASN));
14741
        /* Parse date. */
14742
0
        ret = GetASN_Items(dateASN, dataASN, dateASN_Length, 0, source, idx,
14743
0
                           maxIdx);
14744
0
    }
14745
0
    if (ret == 0) {
14746
        /* Determine which tag was seen. */
14747
0
        int i = (dataASN[DATEASN_IDX_UTC].tag != 0) ? DATEASN_IDX_UTC
14748
0
                                                    : DATEASN_IDX_GT;
14749
        /* Return data from seen item. */
14750
0
        if (pFormat != NULL) {
14751
0
            *pFormat = dataASN[i].tag;
14752
0
        }
14753
0
        if (pDate != NULL) {
14754
0
            *pDate = dataASN[i].data.ref.data;
14755
0
        }
14756
0
        if (pLength != NULL) {
14757
0
            *pLength = (int)dataASN[i].data.ref.length;
14758
0
        }
14759
0
    }
14760
14761
0
    return ret;
14762
0
#endif
14763
0
}
14764
14765
#if !defined(NO_CERTS) && !defined(WOLFSSL_ASN_TEMPLATE)
14766
static int GetDate(DecodedCert* cert, int dateType, int verify, int maxIdx)
14767
{
14768
    int    ret, length;
14769
    const byte *datePtr = NULL;
14770
    byte   date[MAX_DATE_SIZE];
14771
    byte   format;
14772
    word32 startIdx = 0;
14773
14774
    if (dateType == BEFORE)
14775
        cert->beforeDate = &cert->source[cert->srcIdx];
14776
    else
14777
        cert->afterDate = &cert->source[cert->srcIdx];
14778
    startIdx = cert->srcIdx;
14779
14780
    ret = GetDateInfo(cert->source, &cert->srcIdx, &datePtr, &format,
14781
                      &length, (word32)maxIdx);
14782
    if (ret < 0)
14783
        return ret;
14784
14785
    XMEMSET(date, 0, MAX_DATE_SIZE);
14786
    XMEMCPY(date, datePtr, (size_t)length);
14787
14788
    if (dateType == BEFORE)
14789
        cert->beforeDateLen = (int)(cert->srcIdx - startIdx);
14790
    else
14791
        cert->afterDateLen  = (int)(cert->srcIdx - startIdx);
14792
14793
#ifndef NO_ASN_TIME_CHECK
14794
    if (verify != NO_VERIFY && verify != VERIFY_SKIP_DATE &&
14795
            !XVALIDATE_DATE(date, format, dateType)) {
14796
        if (dateType == BEFORE) {
14797
            WOLFSSL_ERROR_VERBOSE(ASN_BEFORE_DATE_E);
14798
            return ASN_BEFORE_DATE_E;
14799
        }
14800
        else {
14801
            WOLFSSL_ERROR_VERBOSE(ASN_AFTER_DATE_E);
14802
            return ASN_AFTER_DATE_E;
14803
        }
14804
    }
14805
#else
14806
    (void)verify;
14807
#endif
14808
14809
    return 0;
14810
}
14811
14812
static int GetValidity(DecodedCert* cert, int verify, int maxIdx)
14813
{
14814
    int length;
14815
    int badDate = 0;
14816
14817
    if (GetSequence(cert->source, &cert->srcIdx, &length, (word32)maxIdx) < 0)
14818
        return ASN_PARSE_E;
14819
14820
    maxIdx = (int)cert->srcIdx + length;
14821
14822
    if (GetDate(cert, BEFORE, verify, maxIdx) < 0)
14823
        badDate = ASN_BEFORE_DATE_E; /* continue parsing */
14824
14825
    if (GetDate(cert, AFTER, verify, maxIdx) < 0)
14826
        return ASN_AFTER_DATE_E;
14827
14828
    if (badDate != 0)
14829
        return badDate;
14830
14831
    return 0;
14832
}
14833
#endif /* !NO_CERTS && !WOLFSSL_ASN_TEMPLATE */
14834
14835
14836
int wc_GetDateInfo(const byte* certDate, int certDateSz, const byte** date,
14837
    byte* format, int* length)
14838
0
{
14839
0
    int ret;
14840
0
    word32 idx = 0;
14841
14842
0
    ret = GetDateInfo(certDate, &idx, date, format, length, (word32)certDateSz);
14843
14844
0
    return ret;
14845
0
}
14846
14847
#ifndef NO_ASN_TIME
14848
int wc_GetDateAsCalendarTime(const byte* date, int length, byte format,
14849
    struct tm* timearg)
14850
0
{
14851
0
    int idx = 0;
14852
0
    (void)length;
14853
0
    if (!ExtractDate(date, format, timearg, &idx))
14854
0
        return ASN_TIME_E;
14855
0
    return 0;
14856
0
}
14857
14858
#if defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_ALT_NAMES)
14859
int wc_GetCertDates(Cert* cert, struct tm* before, struct tm* after)
14860
{
14861
    int ret = 0;
14862
    const byte* date;
14863
    byte format;
14864
    int length;
14865
14866
    if (cert == NULL)
14867
        return BAD_FUNC_ARG;
14868
14869
    if (before && cert->beforeDateSz > 0) {
14870
        ret = wc_GetDateInfo(cert->beforeDate, cert->beforeDateSz, &date,
14871
                             &format, &length);
14872
        if (ret == 0)
14873
            ret = wc_GetDateAsCalendarTime(date, length, format, before);
14874
    }
14875
    if (after && cert->afterDateSz > 0) {
14876
        ret = wc_GetDateInfo(cert->afterDate, cert->afterDateSz, &date,
14877
                             &format, &length);
14878
        if (ret == 0)
14879
            ret = wc_GetDateAsCalendarTime(date, length, format, after);
14880
    }
14881
14882
    return ret;
14883
}
14884
#endif /* WOLFSSL_CERT_GEN && WOLFSSL_ALT_NAMES */
14885
#endif /* !NO_ASN_TIME */
14886
14887
#if !defined(WOLFSSL_ASN_TEMPLATE) && !defined(NO_CERTS)
14888
static int GetSigAlg(DecodedCert* cert, word32* sigOid, word32 maxIdx)
14889
{
14890
    int length;
14891
    word32 endSeqIdx;
14892
14893
    if (GetSequence(cert->source, &cert->srcIdx, &length, maxIdx) < 0)
14894
        return ASN_PARSE_E;
14895
    endSeqIdx = cert->srcIdx + (word32)length;
14896
14897
    if (GetObjectId(cert->source, &cert->srcIdx, sigOid, oidSigType,
14898
                    maxIdx) < 0) {
14899
        return ASN_OBJECT_ID_E;
14900
    }
14901
14902
    if (cert->srcIdx != endSeqIdx) {
14903
#ifdef WC_RSA_PSS
14904
        if (*sigOid == CTC_RSASSAPSS) {
14905
            cert->sigParamsIndex = cert->srcIdx;
14906
            cert->sigParamsLength = endSeqIdx - cert->srcIdx;
14907
        }
14908
        else
14909
#endif
14910
        /* Only allowed a ASN NULL header with zero length. */
14911
        if  (endSeqIdx - cert->srcIdx != 2)
14912
            return ASN_PARSE_E;
14913
        else {
14914
            byte tag;
14915
            if (GetASNTag(cert->source, &cert->srcIdx, &tag, endSeqIdx) != 0)
14916
                return ASN_PARSE_E;
14917
            if (tag != ASN_TAG_NULL)
14918
                return ASN_PARSE_E;
14919
        }
14920
    }
14921
14922
    cert->srcIdx = endSeqIdx;
14923
14924
    return 0;
14925
}
14926
#endif
14927
14928
#ifndef NO_CERTS
14929
#ifdef WOLFSSL_ASN_TEMPLATE
14930
/* TODO: move code around to not require this. */
14931
static int DecodeCertInternal(DecodedCert* cert, int verify, int* criticalExt,
14932
                              int* badDateRet, int stopAtPubKey,
14933
                              int stopAfterPubKey);
14934
#endif
14935
14936
/* Parse the certificate up to the X.509 public key.
14937
 *
14938
 * If cert data is invalid then badDate get set to error value.
14939
 *
14940
 * @param [in, out] cert     Decoded certificate object.
14941
 * @param [in]      verify   Whether to verify dates.
14942
 * @param [out]     badDate  Error code when verify dates.
14943
 * @return  0 on success.
14944
 * @return  BAD_FUNC_ARG when cert or badDate is NULL.
14945
 * @return  ASN_TIME_E when date BER tag is nor UTC or GENERALIZED time.
14946
 * @return  ASN_DATE_SZ_E when time data is not supported.
14947
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
14948
 *          is invalid.
14949
 * @return  BUFFER_E when data in buffer is too small.
14950
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
14951
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set.
14952
 */
14953
int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate)
14954
0
{
14955
#ifndef WOLFSSL_ASN_TEMPLATE
14956
    int ret;
14957
14958
    if (cert == NULL || badDate == NULL)
14959
        return BAD_FUNC_ARG;
14960
14961
    *badDate = 0;
14962
    if ( (ret = GetCertHeader(cert)) < 0)
14963
        return ret;
14964
14965
    WOLFSSL_MSG("Got Cert Header");
14966
14967
#ifdef WOLFSSL_CERT_REQ
14968
    if (!cert->isCSR) {
14969
#endif
14970
        /* Using the sigIndex as the upper bound because that's where the
14971
         * actual certificate data ends. */
14972
        if ((ret = GetSigAlg(cert, &cert->signatureOID, cert->sigIndex)) < 0)
14973
            return ret;
14974
14975
        WOLFSSL_MSG("Got Algo ID");
14976
14977
        if ( (ret = GetName(cert, ISSUER, (int)cert->sigIndex)) < 0)
14978
            return ret;
14979
14980
        if ( (ret = GetValidity(cert, verify, (int)cert->sigIndex)) < 0)
14981
            *badDate = ret;
14982
#ifdef WOLFSSL_CERT_REQ
14983
    }
14984
#endif
14985
14986
    if ( (ret = GetName(cert, SUBJECT, (int)cert->sigIndex)) < 0)
14987
        return ret;
14988
14989
    WOLFSSL_MSG("Got Subject Name");
14990
    return ret;
14991
#else
14992
    /* Use common decode routine and stop at public key. */
14993
0
    int ret;
14994
14995
0
    *badDate = 0;
14996
14997
0
    ret = DecodeCertInternal(cert, verify, NULL, badDate, 1, 0);
14998
0
    if (ret >= 0) {
14999
        /* Store current index: public key. */
15000
0
        cert->srcIdx = (word32)ret;
15001
0
    }
15002
0
    return ret;
15003
0
#endif /* WOLFSSL_ASN_TEMPLATE */
15004
0
}
15005
15006
/* Parse the certificate up to and including X.509 public key.
15007
 *
15008
 * @param [in, out] cert     Decoded certificate object.
15009
 * @param [in]      verify   Whether to verify dates.
15010
 * @return  0 on success.
15011
 * @return  ASN_TIME_E when date BER tag is nor UTC or GENERALIZED time.
15012
 * @return  ASN_DATE_SZ_E when time data is not supported.
15013
 * @return  ASN_BEFORE_DATE_E when BEFORE date is invalid.
15014
 * @return  ASN_AFTER_DATE_E when AFTER date is invalid.
15015
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
15016
 *          is invalid.
15017
 * @return  BUFFER_E when data in buffer is too small.
15018
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
15019
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
15020
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set.
15021
 */
15022
int DecodeToKey(DecodedCert* cert, int verify)
15023
0
{
15024
#ifndef WOLFSSL_ASN_TEMPLATE
15025
    int badDate = 0;
15026
    int ret;
15027
15028
    if ( (ret = wc_GetPubX509(cert, verify, &badDate)) < 0)
15029
        return ret;
15030
15031
    /* Determine if self signed */
15032
#ifdef WOLFSSL_CERT_REQ
15033
    if (cert->isCSR)
15034
        cert->selfSigned = 1;
15035
    else
15036
#endif
15037
    {
15038
        cert->selfSigned = XMEMCMP(cert->issuerHash, cert->subjectHash,
15039
            KEYID_SIZE) == 0 ? 1 : 0;
15040
    }
15041
15042
    ret = GetCertKey(cert, cert->source, &cert->srcIdx, cert->maxIdx);
15043
    if (ret != 0)
15044
        return ret;
15045
15046
    WOLFSSL_MSG("Got Key");
15047
15048
    if (badDate != 0)
15049
        return badDate;
15050
15051
    return ret;
15052
#else
15053
0
    int ret;
15054
0
    int badDate = 0;
15055
15056
    /* Call internal version and stop after public key. */
15057
0
    ret = DecodeCertInternal(cert, verify, NULL, &badDate, 0, 1);
15058
    /* Always return date errors. */
15059
0
    if (ret == 0) {
15060
0
        ret = badDate;
15061
0
    }
15062
0
    return ret;
15063
0
#endif /* WOLFSSL_ASN_TEMPLATE */
15064
0
}
15065
15066
#if !defined(WOLFSSL_ASN_TEMPLATE)
15067
static int GetSignature(DecodedCert* cert)
15068
{
15069
    int length;
15070
    int ret;
15071
15072
    ret = CheckBitString(cert->source, &cert->srcIdx, &length, cert->maxIdx, 1,
15073
                         NULL);
15074
    if (ret != 0)
15075
        return ret;
15076
15077
    cert->sigLength = (word32)length;
15078
    cert->signature = &cert->source[cert->srcIdx];
15079
    cert->srcIdx += cert->sigLength;
15080
15081
    if (cert->srcIdx != cert->maxIdx)
15082
        return ASN_PARSE_E;
15083
15084
    return 0;
15085
}
15086
#endif /* !WOLFSSL_ASN_TEMPLATE */
15087
#endif /* !NO_CERTS */
15088
15089
#ifndef WOLFSSL_ASN_TEMPLATE
15090
static word32 SetOctetString8Bit(word32 len, byte* output)
15091
{
15092
    output[0] = ASN_OCTET_STRING;
15093
    output[1] = (byte)len;
15094
    return 2;
15095
}
15096
static word32 SetDigest(const byte* digest, word32 digSz, byte* output)
15097
{
15098
    word32 idx = SetOctetString8Bit(digSz, output);
15099
    XMEMCPY(&output[idx], digest, digSz);
15100
15101
    return idx + digSz;
15102
}
15103
#endif
15104
15105
15106
/* Encode a length for DER.
15107
 *
15108
 * @param [in]  length  Value to encode.
15109
 * @param [out] output  Buffer to encode into.
15110
 * @return  Number of bytes encoded.
15111
 */
15112
word32 SetLength(word32 length, byte* output)
15113
0
{
15114
    /* Start encoding at start of buffer. */
15115
0
    word32 i = 0;
15116
15117
0
    if (length < ASN_LONG_LENGTH) {
15118
        /* Only one byte needed to encode. */
15119
0
        if (output) {
15120
            /* Write out length value. */
15121
0
            output[i] = (byte)length;
15122
0
        }
15123
        /* Skip over length. */
15124
0
        i++;
15125
0
    }
15126
0
    else {
15127
        /* Calculate the number of bytes required to encode value. */
15128
0
        byte j = (byte)BytePrecision(length);
15129
15130
0
        if (output) {
15131
            /* Encode count byte. */
15132
0
            output[i] = (byte)(j | ASN_LONG_LENGTH);
15133
0
        }
15134
        /* Skip over count byte. */
15135
0
        i++;
15136
15137
        /* Encode value as a big-endian byte array. */
15138
0
        for (; j > 0; --j) {
15139
0
            if (output) {
15140
                /* Encode next most-significant byte. */
15141
0
                output[i] = (byte)(length >> ((j - 1) * WOLFSSL_BIT_SIZE));
15142
0
            }
15143
            /* Skip over byte. */
15144
0
            i++;
15145
0
        }
15146
0
    }
15147
15148
    /* Return number of bytes in encoded length. */
15149
0
    return i;
15150
0
}
15151
15152
/* Encode a DER header - type/tag and length.
15153
 *
15154
 * @param [in]  tag     DER tag of ASN.1 item.
15155
 * @param [in]  len     Length of data in ASN.1 item.
15156
 * @param [out] output  Buffer to encode into.
15157
 * @return  Number of bytes encoded.
15158
 */
15159
static word32 SetHeader(byte tag, word32 len, byte* output)
15160
0
{
15161
0
    if (output) {
15162
        /* Encode tag first. */
15163
0
        output[0] = tag;
15164
0
    }
15165
    /* Encode the length. */
15166
0
    return SetLength(len, output ? output + ASN_TAG_SZ : NULL) + ASN_TAG_SZ;
15167
0
}
15168
15169
/* Encode a SEQUENCE header in DER.
15170
 *
15171
 * @param [in]  len     Length of data in SEQUENCE.
15172
 * @param [out] output  Buffer to encode into.
15173
 * @return  Number of bytes encoded.
15174
 */
15175
word32 SetSequence(word32 len, byte* output)
15176
0
{
15177
0
    return SetHeader(ASN_SEQUENCE | ASN_CONSTRUCTED, len, output);
15178
0
}
15179
15180
/* Encode an OCTET STRING header in DER.
15181
 *
15182
 * @param [in]  len     Length of data in OCTET STRING.
15183
 * @param [out] output  Buffer to encode into.
15184
 * @return  Number of bytes encoded.
15185
 */
15186
word32 SetOctetString(word32 len, byte* output)
15187
0
{
15188
0
    return SetHeader(ASN_OCTET_STRING, len, output);
15189
0
}
15190
15191
/* Encode a SET header in DER.
15192
 *
15193
 * @param [in]  len     Length of data in SET.
15194
 * @param [out] output  Buffer to encode into.
15195
 * @return  Number of bytes encoded.
15196
 */
15197
word32 SetSet(word32 len, byte* output)
15198
0
{
15199
0
    return SetHeader(ASN_SET | ASN_CONSTRUCTED, len, output);
15200
0
}
15201
15202
/* Encode an implicit context specific header in DER.
15203
 *
15204
 * Implicit means that it is constructed only if the included ASN.1 item is.
15205
 *
15206
 * @param [in]  tag     Tag for the implicit ASN.1 item.
15207
 * @param [in]  number  Context specific number.
15208
 * @param [in]  len     Length of data in SET.
15209
 * @param [out] output  Buffer to encode into.
15210
 * @return  Number of bytes encoded.
15211
 */
15212
word32 SetImplicit(byte tag, byte number, word32 len, byte* output)
15213
0
{
15214
0
    tag = (byte)(((tag == ASN_SEQUENCE || tag == ASN_SET) ? ASN_CONSTRUCTED : 0)
15215
0
                 | ASN_CONTEXT_SPECIFIC | number);
15216
0
    return SetHeader(tag, len, output);
15217
0
}
15218
15219
/* Encode an explicit context specific header in DER.
15220
 *
15221
 * Explicit means that there will be an ASN.1 item underneath.
15222
 *
15223
 * @param [in]  number  Context specific number.
15224
 * @param [in]  len     Length of data in SET.
15225
 * @param [out] output  Buffer to encode into.
15226
 * @return  Number of bytes encoded.
15227
 */
15228
word32 SetExplicit(byte number, word32 len, byte* output)
15229
0
{
15230
0
    return SetHeader((byte)(ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | number),
15231
0
                     len, output);
15232
0
}
15233
15234
#if defined(OPENSSL_EXTRA)
15235
/* Encode an Othername into DER.
15236
 *
15237
 * @param [in]  name    Pointer to the WOLFSSL_ASN1_OTHERNAME to be encoded.
15238
 * @param [out] output  Buffer to encode into. If NULL, don't encode.
15239
 * @return  Number of bytes encoded or WOLFSSL_FAILURE if name parameter is bad.
15240
 */
15241
word32 SetOthername(void *name, byte *output)
15242
{
15243
    WOLFSSL_ASN1_OTHERNAME *nm = (WOLFSSL_ASN1_OTHERNAME *)name;
15244
    char *nameStr = NULL;
15245
    word32 nameSz = 0;
15246
    word32 len = 0;
15247
15248
    if ((nm == NULL) || (nm->value == NULL)) {
15249
        WOLFSSL_MSG("otherName value is NULL");
15250
        return WOLFSSL_FAILURE;
15251
    }
15252
15253
    nameStr = nm->value->value.utf8string->data;
15254
    nameSz = (word32)nm->value->value.utf8string->length;
15255
15256
    len = nm->type_id->objSz +
15257
          SetHeader(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC, nameSz + 2, NULL) +
15258
          SetHeader(CTC_UTF8, nameSz, NULL) + nameSz;
15259
15260
    if (output != NULL) {
15261
        /* otherName OID */
15262
        XMEMCPY(output, nm->type_id->obj, nm->type_id->objSz);
15263
        output += nm->type_id->objSz;
15264
15265
        output += SetHeader(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC, nameSz + 2,
15266
                            output);
15267
15268
        output += SetHeader(CTC_UTF8, nameSz, output);
15269
15270
        XMEMCPY(output, nameStr, nameSz);
15271
    }
15272
15273
    return len;
15274
}
15275
#endif /* OPENSSL_EXTRA */
15276
15277
15278
#ifdef HAVE_ECC
15279
/* Determines whether the signature algorithm is using ECDSA.
15280
 *
15281
 * @param [in] algoOID  Signature algorithm identifier.
15282
 * @return  1 when algorithm is using ECDSA.
15283
 * @return  0 otherwise.
15284
 */
15285
static WC_INLINE int IsSigAlgoECDSA(word32 algoOID)
15286
0
{
15287
    /* ECDSA sigAlgo must not have ASN1 NULL parameters */
15288
0
    if (algoOID == CTC_SHAwECDSA || algoOID == CTC_SHA256wECDSA ||
15289
0
        algoOID == CTC_SHA384wECDSA || algoOID == CTC_SHA512wECDSA) {
15290
0
        return 1;
15291
0
    }
15292
15293
0
    return 0;
15294
0
}
15295
#endif
15296
15297
/* Determines if OID is for an EC signing algorithm including ECDSA and EdDSA
15298
 * and post-quantum algorithms.
15299
 *
15300
 * @param [in] algoOID  Algorithm OID.
15301
 * @return  1 when is EC signing algorithm.
15302
 * @return  0 otherwise.
15303
 */
15304
static WC_INLINE int IsSigAlgoECC(word32 algoOID)
15305
0
{
15306
0
    (void)algoOID;
15307
15308
0
    return (0
15309
0
        #ifdef HAVE_ECC
15310
0
              || IsSigAlgoECDSA(algoOID)
15311
0
        #endif
15312
0
        #ifdef WOLFSSL_SM2
15313
0
              || (algoOID == SM2k)
15314
0
        #endif
15315
0
        #ifdef HAVE_ED25519
15316
0
              || (algoOID == ED25519k)
15317
0
        #endif
15318
0
        #ifdef HAVE_CURVE25519
15319
0
              || (algoOID == X25519k)
15320
0
        #endif
15321
0
        #ifdef HAVE_ED448
15322
0
              || (algoOID == ED448k)
15323
0
        #endif
15324
0
        #ifdef HAVE_CURVE448
15325
0
              || (algoOID == X448k)
15326
0
        #endif
15327
        #ifdef HAVE_PQC
15328
        #ifdef HAVE_FACON
15329
              || (algoOID == FALCON_LEVEL1k)
15330
              || (algoOID == FALCON_LEVEL5k)
15331
        #endif
15332
        #ifdef HAVE_DILITHIUM
15333
              || (algoOID == DILITHIUM_LEVEL2k)
15334
              || (algoOID == DILITHIUM_LEVEL3k)
15335
              || (algoOID == DILITHIUM_LEVEL5k)
15336
        #endif
15337
        #ifdef HAVE_SPHINCS
15338
              || (algoOID == SPHINCS_FAST_LEVEL1k)
15339
              || (algoOID == SPHINCS_FAST_LEVEL3k)
15340
              || (algoOID == SPHINCS_FAST_LEVEL5k)
15341
              || (algoOID == SPHINCS_SMALL_LEVEL1k)
15342
              || (algoOID == SPHINCS_SMALL_LEVEL3k)
15343
              || (algoOID == SPHINCS_SMALL_LEVEL5k)
15344
        #endif
15345
        #endif /* HAVE_PQC */
15346
0
    );
15347
0
}
15348
15349
/* Encode an algorithm identifier.
15350
 *
15351
 * [algoOID, type] is unique.
15352
 *
15353
 * @param [in]  algoOID   Algorithm identifier.
15354
 * @param [out] output    Buffer to hold encoding.
15355
 * @param [in]  type      Type of OID being encoded.
15356
 * @param [in]  curveSz   Add extra space for curve data.
15357
 * @return  Encoded data size on success.
15358
 * @return  0 when dynamic memory allocation fails.
15359
 */
15360
word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz)
15361
0
{
15362
#ifndef WOLFSSL_ASN_TEMPLATE
15363
    word32 tagSz, idSz, seqSz, algoSz = 0;
15364
    const  byte* algoName = 0;
15365
    byte   ID_Length[1 + MAX_LENGTH_SZ];
15366
    byte   seqArray[MAX_SEQ_SZ + 1];  /* add object_id to end */
15367
    word32    length = 0;
15368
15369
    tagSz = (type == oidHashType ||
15370
             (type == oidSigType && !IsSigAlgoECC((word32)algoOID)) ||
15371
             (type == oidKeyType && algoOID == RSAk)) ? 2U : 0U;
15372
    algoName = OidFromId((word32)algoOID, (word32)type, &algoSz);
15373
    if (algoName == NULL) {
15374
        WOLFSSL_MSG("Unknown Algorithm");
15375
        return 0;
15376
    }
15377
15378
    idSz  = (word32)SetObjectId((int)algoSz, ID_Length);
15379
    seqSz = SetSequence(idSz + algoSz + tagSz + (word32)curveSz, seqArray);
15380
15381
    /* Copy only algo to output for DSA keys */
15382
    if (algoOID == DSAk && output) {
15383
        XMEMCPY(output, ID_Length, idSz);
15384
        XMEMCPY(output + idSz, algoName, algoSz);
15385
        if (tagSz == 2)
15386
            SetASNNull(&output[seqSz + idSz + algoSz]);
15387
    }
15388
    else if (output) {
15389
        XMEMCPY(output, seqArray, seqSz);
15390
        XMEMCPY(output + seqSz, ID_Length, idSz);
15391
        XMEMCPY(output + seqSz + idSz, algoName, algoSz);
15392
        if (tagSz == 2)
15393
            SetASNNull(&output[seqSz + idSz + algoSz]);
15394
    }
15395
15396
    if (algoOID == DSAk)
15397
        length = idSz + algoSz + tagSz;
15398
    else
15399
        length = seqSz + idSz + algoSz + tagSz;
15400
15401
    return length;
15402
#else
15403
0
    DECL_ASNSETDATA(dataASN, algoIdASN_Length);
15404
0
    int ret = 0;
15405
0
    const byte* algoName = 0;
15406
0
    word32 algoSz = 0;
15407
15408
0
    CALLOC_ASNSETDATA(dataASN, algoIdASN_Length, ret, NULL);
15409
15410
0
    algoName = OidFromId((word32)algoOID, (word32)type, &algoSz);
15411
0
    if (algoName == NULL) {
15412
0
        WOLFSSL_MSG("Unknown Algorithm");
15413
0
    }
15414
0
    else {
15415
0
        int sz;
15416
0
        int o = 0;
15417
15418
        /* Set the OID and OID type to encode. */
15419
0
        SetASN_OID(&dataASN[ALGOIDASN_IDX_OID], (word32)algoOID, (word32)type);
15420
        /* Hashes, signatures not ECC and keys not RSA output NULL tag. */
15421
0
        if (!(type == oidHashType ||
15422
0
                 (type == oidSigType && !IsSigAlgoECC((word32)algoOID)) ||
15423
0
                 (type == oidKeyType && algoOID == RSAk))) {
15424
            /* Don't put out NULL DER item. */
15425
0
            dataASN[ALGOIDASN_IDX_NULL].noOut = 1;
15426
0
        }
15427
0
        if (algoOID == DSAk) {
15428
            /* Don't include SEQUENCE for DSA keys. */
15429
0
            o = 1;
15430
0
        }
15431
0
        else if (curveSz > 0) {
15432
            /* Don't put out NULL DER item. */
15433
0
            dataASN[ALGOIDASN_IDX_NULL].noOut = 0;
15434
            /* Include space for extra data of length curveSz.
15435
             * Subtract 1 for sequence and 1 for length encoding. */
15436
0
            SetASN_Buffer(&dataASN[ALGOIDASN_IDX_NULL], NULL,
15437
0
                          (word32)curveSz - 2);
15438
0
        }
15439
15440
        /* Calculate size of encoding. */
15441
0
        ret = SizeASN_Items(algoIdASN + o, dataASN + o,
15442
0
                            (int)algoIdASN_Length - (int)o, &sz);
15443
0
        if (ret == 0 && output != NULL) {
15444
            /* Encode into buffer. */
15445
0
            SetASN_Items(algoIdASN + o, dataASN + o,
15446
0
                         (int)algoIdASN_Length - (int)o, output);
15447
0
            if (curveSz > 0) {
15448
                /* Return size excluding curve data. */
15449
0
                sz = (int)(dataASN[o].offset -
15450
0
                           dataASN[ALGOIDASN_IDX_NULL].offset);
15451
0
            }
15452
0
        }
15453
15454
0
        if (ret == 0) {
15455
            /* Return encoded size. */
15456
0
            ret = sz;
15457
0
        }
15458
0
        else {
15459
            /* Unsigned return type so 0 indicates error. */
15460
0
            ret = 0;
15461
0
        }
15462
0
    }
15463
15464
0
    FREE_ASNSETDATA(dataASN, NULL);
15465
0
    return (word32)ret;
15466
0
#endif /* WOLFSSL_ASN_TEMPLATE */
15467
0
}
15468
15469
#ifdef WOLFSSL_ASN_TEMPLATE
15470
/* Always encode PKCS#1 v1.5 RSA signature and compare to encoded data. */
15471
/* ASN.1 template for DigestInfo for a PKCS#1 v1.5 RSA signature.
15472
 * PKCS#1 v2.2: RFC 8017, A.2.4 - DigestInfo
15473
 */
15474
static const ASNItem digestInfoASN[] = {
15475
/* SEQ          */ { 0, ASN_SEQUENCE, 1, 1, 0 },
15476
                                         /* digestAlgorithm */
15477
/* DIGALGO_SEQ  */     { 1, ASN_SEQUENCE, 1, 1, 0 },
15478
/* DIGALGO_OID  */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
15479
/* DIGALGO_NULL */         { 2, ASN_TAG_NULL, 0, 0, 0 },
15480
                                         /* digest */
15481
/* DIGEST       */     { 1, ASN_OCTET_STRING, 0, 0, 0 }
15482
};
15483
enum {
15484
    DIGESTINFOASN_IDX_SEQ = 0,
15485
    DIGESTINFOASN_IDX_DIGALGO_SEQ,
15486
    DIGESTINFOASN_IDX_DIGALGO_OID,
15487
    DIGESTINFOASN_IDX_DIGALGO_NULL,
15488
    DIGESTINFOASN_IDX_DIGEST
15489
};
15490
15491
/* Number of items in ASN.1 template for DigestInfo for RSA. */
15492
0
#define digestInfoASN_Length (sizeof(digestInfoASN) / sizeof(ASNItem))
15493
#endif
15494
15495
/* Encode signature.
15496
 *
15497
 * @param [out] out     Buffer to hold encoding.
15498
 * @param [in]  digest  Buffer holding digest.
15499
 * @param [in]  digSz   Length of digest in bytes.
15500
 * @return  Encoded data size on success.
15501
 * @return  0 when dynamic memory allocation fails.
15502
 */
15503
word32 wc_EncodeSignature(byte* out, const byte* digest, word32 digSz,
15504
                          int hashOID)
15505
0
{
15506
#ifndef WOLFSSL_ASN_TEMPLATE
15507
    byte digArray[MAX_ENCODED_DIG_SZ];
15508
    byte algoArray[MAX_ALGO_SZ];
15509
    byte seqArray[MAX_SEQ_SZ];
15510
    word32 encDigSz, algoSz, seqSz;
15511
15512
    encDigSz = SetDigest(digest, digSz, digArray);
15513
    algoSz   = SetAlgoID(hashOID, algoArray, oidHashType, 0);
15514
    seqSz    = SetSequence(encDigSz + algoSz, seqArray);
15515
15516
    XMEMCPY(out, seqArray, seqSz);
15517
    XMEMCPY(out + seqSz, algoArray, algoSz);
15518
    XMEMCPY(out + seqSz + algoSz, digArray, encDigSz);
15519
15520
    return encDigSz + algoSz + seqSz;
15521
#else
15522
0
    DECL_ASNSETDATA(dataASN, digestInfoASN_Length);
15523
0
    int ret = 0;
15524
0
    int sz;
15525
0
    unsigned char dgst[WC_MAX_DIGEST_SIZE];
15526
15527
0
    CALLOC_ASNSETDATA(dataASN, digestInfoASN_Length, ret, NULL);
15528
15529
0
    if (ret == 0) {
15530
        /* Set hash OID and type. */
15531
0
        SetASN_OID(&dataASN[DIGESTINFOASN_IDX_DIGALGO_OID], (word32)hashOID,
15532
0
                   oidHashType);
15533
        /* Set digest. */
15534
0
        if (digest == out) {
15535
0
            XMEMCPY(dgst, digest, digSz);
15536
0
            digest = dgst;
15537
0
        }
15538
0
        SetASN_Buffer(&dataASN[DIGESTINFOASN_IDX_DIGEST], digest, digSz);
15539
15540
        /* Calculate size of encoding. */
15541
0
        ret = SizeASN_Items(digestInfoASN, dataASN, digestInfoASN_Length, &sz);
15542
0
    }
15543
0
    if (ret == 0) {
15544
        /* Encode PKCS#1 v1.5 RSA signature. */
15545
0
        SetASN_Items(digestInfoASN, dataASN, digestInfoASN_Length, out);
15546
0
        ret = sz;
15547
0
    }
15548
0
    else {
15549
        /* Unsigned return type so 0 indicates error. */
15550
0
        ret = 0;
15551
0
    }
15552
15553
0
    FREE_ASNSETDATA(dataASN, NULL);
15554
0
    return (word32)ret;
15555
0
#endif
15556
0
}
15557
15558
15559
#ifndef NO_CERTS
15560
15561
int wc_GetCTC_HashOID(int type)
15562
0
{
15563
0
    int ret;
15564
0
    enum wc_HashType hType;
15565
15566
0
    hType = wc_HashTypeConvert(type);
15567
0
    ret = wc_HashGetOID(hType);
15568
0
    if (ret < 0) {
15569
0
        ret = 0; /* backwards compatibility */
15570
0
    }
15571
15572
0
    return ret;
15573
0
}
15574
15575
/* Initialize a signature context object.
15576
 *
15577
 * Object used for signing and verifying a certificate signature.
15578
 *
15579
 * @param [in, out] sigCtx  Signature context object.
15580
 * @param [in]      heap    Dynamic memory hint.
15581
 * @param [in]      devId   Hardware device identifier.
15582
 */
15583
void InitSignatureCtx(SignatureCtx* sigCtx, void* heap, int devId)
15584
0
{
15585
0
    if (sigCtx) {
15586
0
        XMEMSET(sigCtx, 0, sizeof(SignatureCtx));
15587
0
        sigCtx->devId = devId;
15588
0
        sigCtx->heap = heap;
15589
0
    }
15590
0
}
15591
15592
/* Free dynamic data in a signature context object.
15593
 *
15594
 * @param [in, out] sigCtx  Signature context object.
15595
 */
15596
void FreeSignatureCtx(SignatureCtx* sigCtx)
15597
0
{
15598
0
    if (sigCtx == NULL)
15599
0
        return;
15600
15601
0
    if (sigCtx->digest) {
15602
0
        XFREE(sigCtx->digest, sigCtx->heap, DYNAMIC_TYPE_DIGEST);
15603
0
        sigCtx->digest = NULL;
15604
0
    }
15605
0
#if !(defined(NO_RSA) && defined(NO_DSA))
15606
0
    if (sigCtx->sigCpy) {
15607
0
        XFREE(sigCtx->sigCpy, sigCtx->heap, DYNAMIC_TYPE_SIGNATURE);
15608
0
        sigCtx->sigCpy = NULL;
15609
0
    }
15610
0
#endif
15611
0
#ifndef NO_ASN_CRYPT
15612
0
    if (sigCtx->key.ptr) {
15613
0
        switch (sigCtx->keyOID) {
15614
0
        #ifndef NO_RSA
15615
0
            #ifdef WC_RSA_PSS
15616
0
            case RSAPSSk:
15617
0
            #endif
15618
0
            case RSAk:
15619
0
                wc_FreeRsaKey(sigCtx->key.rsa);
15620
0
                XFREE(sigCtx->key.rsa, sigCtx->heap, DYNAMIC_TYPE_RSA);
15621
0
                sigCtx->key.rsa = NULL;
15622
0
                break;
15623
0
        #endif /* !NO_RSA */
15624
        #ifndef NO_DSA
15625
            case DSAk:
15626
                wc_FreeDsaKey(sigCtx->key.dsa);
15627
                XFREE(sigCtx->key.dsa, sigCtx->heap, DYNAMIC_TYPE_DSA);
15628
                sigCtx->key.dsa = NULL;
15629
                break;
15630
        #endif
15631
0
        #ifdef HAVE_ECC
15632
0
            case ECDSAk:
15633
0
        #ifdef WOLFSSL_SM2
15634
0
            case SM2k:
15635
0
        #endif
15636
            #if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
15637
                defined(WC_ASYNC_ENABLE_ECC)
15638
                if (sigCtx->key.ecc->nb_ctx != NULL) {
15639
                    XFREE(sigCtx->key.ecc->nb_ctx, sigCtx->heap,
15640
                          DYNAMIC_TYPE_TMP_BUFFER);
15641
                }
15642
            #endif /* WC_ECC_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
15643
                      WC_ASYNC_ENABLE_ECC */
15644
0
                wc_ecc_free(sigCtx->key.ecc);
15645
0
                XFREE(sigCtx->key.ecc, sigCtx->heap, DYNAMIC_TYPE_ECC);
15646
0
                sigCtx->key.ecc = NULL;
15647
0
                break;
15648
0
        #endif /* HAVE_ECC */
15649
0
        #ifdef HAVE_ED25519
15650
0
            case ED25519k:
15651
0
                wc_ed25519_free(sigCtx->key.ed25519);
15652
0
                XFREE(sigCtx->key.ed25519, sigCtx->heap, DYNAMIC_TYPE_ED25519);
15653
0
                sigCtx->key.ed25519 = NULL;
15654
0
                break;
15655
0
        #endif /* HAVE_ED25519 */
15656
0
        #ifdef HAVE_ED448
15657
0
            case ED448k:
15658
0
                wc_ed448_free(sigCtx->key.ed448);
15659
0
                XFREE(sigCtx->key.ed448, sigCtx->heap, DYNAMIC_TYPE_ED448);
15660
0
                sigCtx->key.ed448 = NULL;
15661
0
                break;
15662
0
        #endif /* HAVE_ED448 */
15663
        #if defined(HAVE_PQC)
15664
        #if defined(HAVE_FALCON)
15665
            case FALCON_LEVEL1k:
15666
            case FALCON_LEVEL5k:
15667
                wc_falcon_free(sigCtx->key.falcon);
15668
                XFREE(sigCtx->key.falcon, sigCtx->heap,
15669
                      DYNAMIC_TYPE_FALCON);
15670
                sigCtx->key.falcon = NULL;
15671
                break;
15672
        #endif /* HAVE_FALCON */
15673
        #if defined(HAVE_DILITHIUM)
15674
            case DILITHIUM_LEVEL2k:
15675
            case DILITHIUM_LEVEL3k:
15676
            case DILITHIUM_LEVEL5k:
15677
                wc_dilithium_free(sigCtx->key.dilithium);
15678
                XFREE(sigCtx->key.dilithium, sigCtx->heap,
15679
                      DYNAMIC_TYPE_DILITHIUM);
15680
                sigCtx->key.dilithium = NULL;
15681
                break;
15682
        #endif /* HAVE_DILITHIUM */
15683
        #if defined(HAVE_SPHINCS)
15684
            case SPHINCS_FAST_LEVEL1k:
15685
            case SPHINCS_FAST_LEVEL3k:
15686
            case SPHINCS_FAST_LEVEL5k:
15687
            case SPHINCS_SMALL_LEVEL1k:
15688
            case SPHINCS_SMALL_LEVEL3k:
15689
            case SPHINCS_SMALL_LEVEL5k:
15690
                wc_sphincs_free(sigCtx->key.sphincs);
15691
                XFREE(sigCtx->key.sphincs, sigCtx->heap,
15692
                      DYNAMIC_TYPE_SPHINCS);
15693
                sigCtx->key.sphincs = NULL;
15694
                break;
15695
        #endif /* HAVE_SPHINCS */
15696
        #endif /* HAVE_PQC  */
15697
0
            default:
15698
0
                break;
15699
0
        } /* switch (keyOID) */
15700
0
        sigCtx->key.ptr = NULL;
15701
0
    }
15702
0
#endif
15703
15704
    /* reset state, we are done */
15705
0
    sigCtx->state = SIG_STATE_BEGIN;
15706
0
}
15707
15708
#if !defined(NO_ASN_CRYPT) && !defined(NO_HASH_WRAPPER)
15709
static int HashForSignature(const byte* buf, word32 bufSz, word32 sigOID,
15710
                            byte* digest, int* typeH, int* digestSz, int verify)
15711
0
{
15712
0
    int ret = 0;
15713
15714
0
    switch (sigOID) {
15715
0
    #if defined(WOLFSSL_MD2)
15716
0
        case CTC_MD2wRSA:
15717
0
            if (!verify) {
15718
0
                ret = HASH_TYPE_E;
15719
0
                WOLFSSL_MSG("MD2 not supported for signing");
15720
0
            }
15721
0
            else if ((ret = wc_Md2Hash(buf, bufSz, digest)) == 0) {
15722
0
                *typeH    = MD2h;
15723
0
                *digestSz = MD2_DIGEST_SIZE;
15724
0
            }
15725
0
        break;
15726
0
    #endif
15727
0
    #ifndef NO_MD5
15728
0
        case CTC_MD5wRSA:
15729
0
            if ((ret = wc_Md5Hash(buf, bufSz, digest)) == 0) {
15730
0
                *typeH    = MD5h;
15731
0
                *digestSz = WC_MD5_DIGEST_SIZE;
15732
0
            }
15733
0
            break;
15734
0
    #endif
15735
0
    #ifndef NO_SHA
15736
0
        case CTC_SHAwRSA:
15737
0
        case CTC_SHAwDSA:
15738
0
        case CTC_SHAwECDSA:
15739
0
            if ((ret = wc_ShaHash(buf, bufSz, digest)) == 0) {
15740
0
                *typeH    = SHAh;
15741
0
                *digestSz = WC_SHA_DIGEST_SIZE;
15742
0
            }
15743
0
            break;
15744
0
    #endif
15745
0
    #ifdef WOLFSSL_SHA224
15746
0
        case CTC_SHA224wRSA:
15747
0
        case CTC_SHA224wECDSA:
15748
0
            if ((ret = wc_Sha224Hash(buf, bufSz, digest)) == 0) {
15749
0
                *typeH    = SHA224h;
15750
0
                *digestSz = WC_SHA224_DIGEST_SIZE;
15751
0
            }
15752
0
            break;
15753
0
    #endif
15754
0
    #ifndef NO_SHA256
15755
0
        case CTC_SHA256wRSA:
15756
0
        case CTC_SHA256wECDSA:
15757
0
        case CTC_SHA256wDSA:
15758
0
            if ((ret = wc_Sha256Hash(buf, bufSz, digest)) == 0) {
15759
0
                *typeH    = SHA256h;
15760
0
                *digestSz = WC_SHA256_DIGEST_SIZE;
15761
0
            }
15762
0
            break;
15763
0
    #endif
15764
0
    #ifdef WOLFSSL_SHA384
15765
0
        case CTC_SHA384wRSA:
15766
0
        case CTC_SHA384wECDSA:
15767
0
            if ((ret = wc_Sha384Hash(buf, bufSz, digest)) == 0) {
15768
0
                *typeH    = SHA384h;
15769
0
                *digestSz = WC_SHA384_DIGEST_SIZE;
15770
0
            }
15771
0
            break;
15772
0
    #endif
15773
0
    #ifdef WOLFSSL_SHA512
15774
0
        case CTC_SHA512wRSA:
15775
0
        case CTC_SHA512wECDSA:
15776
0
            if ((ret = wc_Sha512Hash(buf, bufSz, digest)) == 0) {
15777
0
                *typeH    = SHA512h;
15778
0
                *digestSz = WC_SHA512_DIGEST_SIZE;
15779
0
            }
15780
0
            break;
15781
0
    #endif
15782
0
    #ifdef WOLFSSL_SHA3
15783
0
    #ifndef WOLFSSL_NOSHA3_224
15784
0
        case CTC_SHA3_224wRSA:
15785
0
        case CTC_SHA3_224wECDSA:
15786
0
            if ((ret = wc_Sha3_224Hash(buf, bufSz, digest)) == 0) {
15787
0
                *typeH    = SHA3_224h;
15788
0
                *digestSz = WC_SHA3_224_DIGEST_SIZE;
15789
0
            }
15790
0
            break;
15791
0
    #endif
15792
0
    #ifndef WOLFSSL_NOSHA3_256
15793
0
        case CTC_SHA3_256wRSA:
15794
0
        case CTC_SHA3_256wECDSA:
15795
0
            if ((ret = wc_Sha3_256Hash(buf, bufSz, digest)) == 0) {
15796
0
                *typeH    = SHA3_256h;
15797
0
                *digestSz = WC_SHA3_256_DIGEST_SIZE;
15798
0
            }
15799
0
            break;
15800
0
    #endif
15801
0
    #ifndef WOLFSSL_NOSHA3_384
15802
0
        case CTC_SHA3_384wRSA:
15803
0
        case CTC_SHA3_384wECDSA:
15804
0
            if ((ret = wc_Sha3_384Hash(buf, bufSz, digest)) == 0) {
15805
0
                *typeH    = SHA3_384h;
15806
0
                *digestSz = WC_SHA3_384_DIGEST_SIZE;
15807
0
            }
15808
0
            break;
15809
0
    #endif
15810
0
    #ifndef WOLFSSL_NOSHA3_512
15811
0
        case CTC_SHA3_512wRSA:
15812
0
        case CTC_SHA3_512wECDSA:
15813
0
            if ((ret = wc_Sha3_512Hash(buf, bufSz, digest)) == 0) {
15814
0
                *typeH    = SHA3_512h;
15815
0
                *digestSz = WC_SHA3_512_DIGEST_SIZE;
15816
0
            }
15817
0
            break;
15818
0
    #endif
15819
0
    #endif
15820
0
    #if defined(WOLFSSL_SM2) & defined(WOLFSSL_SM3)
15821
0
        case CTC_SM3wSM2:
15822
0
            if ((ret = wc_Sm3Hash(buf, bufSz, digest)) == 0) {
15823
0
                *typeH    = SM3h;
15824
0
                *digestSz = WC_SM3_DIGEST_SIZE;
15825
0
            }
15826
0
            break;
15827
0
    #endif
15828
0
    #ifdef HAVE_ED25519
15829
0
        case CTC_ED25519:
15830
            /* Hashes done in signing operation.
15831
             * Two dependent hashes with prefixes performed.
15832
             */
15833
0
            break;
15834
0
    #endif
15835
0
    #ifdef HAVE_ED448
15836
0
        case CTC_ED448:
15837
            /* Hashes done in signing operation.
15838
             * Two dependent hashes with prefixes performed.
15839
             */
15840
0
            break;
15841
0
    #endif
15842
    #ifdef HAVE_PQC
15843
    #ifdef HAVE_FALCON
15844
        case CTC_FALCON_LEVEL1:
15845
        case CTC_FALCON_LEVEL5:
15846
            /* Hashes done in signing operation. */
15847
            break;
15848
    #endif
15849
    #ifdef HAVE_DILITHIUM
15850
        case CTC_DILITHIUM_LEVEL2:
15851
        case CTC_DILITHIUM_LEVEL3:
15852
        case CTC_DILITHIUM_LEVEL5:
15853
            /* Hashes done in signing operation. */
15854
            break;
15855
    #endif
15856
    #ifdef HAVE_SPHINCS
15857
        case CTC_SPHINCS_FAST_LEVEL1:
15858
        case CTC_SPHINCS_FAST_LEVEL3:
15859
        case CTC_SPHINCS_FAST_LEVEL5:
15860
        case CTC_SPHINCS_SMALL_LEVEL1:
15861
        case CTC_SPHINCS_SMALL_LEVEL3:
15862
        case CTC_SPHINCS_SMALL_LEVEL5:
15863
            /* Hashes done in signing operation. */
15864
            break;
15865
    #endif
15866
    #endif /* HAVE_PQC */
15867
15868
0
        default:
15869
0
            ret = HASH_TYPE_E;
15870
0
            WOLFSSL_MSG("Hash for Signature has unsupported type");
15871
0
    }
15872
15873
0
    (void)buf;
15874
0
    (void)bufSz;
15875
0
    (void)sigOID;
15876
0
    (void)digest;
15877
0
    (void)digestSz;
15878
0
    (void)typeH;
15879
0
    (void)verify;
15880
15881
0
    return ret;
15882
0
}
15883
#endif /* !NO_ASN_CRYPT && !NO_HASH_WRAPPER */
15884
15885
/* Return codes: 0=Success, Negative (see error-crypt.h), ASN_SIG_CONFIRM_E */
15886
static int ConfirmSignature(SignatureCtx* sigCtx,
15887
    const byte* buf, word32 bufSz,
15888
    const byte* key, word32 keySz, word32 keyOID,
15889
    const byte* sig, word32 sigSz, word32 sigOID,
15890
    const byte* sigParams, word32 sigParamsSz,
15891
    byte* rsaKeyIdx)
15892
0
{
15893
0
    int ret = 0;
15894
#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT)
15895
    CertAttribute* certatt = NULL;
15896
#endif
15897
15898
0
    if (sigCtx == NULL || buf == NULL || bufSz == 0 || key == NULL ||
15899
0
        keySz == 0 || sig == NULL || sigSz == 0) {
15900
0
        return BAD_FUNC_ARG;
15901
0
    }
15902
15903
0
    (void)key;
15904
0
    (void)keySz;
15905
0
    (void)sig;
15906
0
    (void)sigSz;
15907
0
    (void)sigParams;
15908
0
    (void)sigParamsSz;
15909
15910
0
    WOLFSSL_ENTER("ConfirmSignature");
15911
15912
0
#if !defined(WOLFSSL_RENESAS_TSIP_TLS) && !defined(WOLFSSL_RENESAS_SCEPROTECT)
15913
0
    (void)rsaKeyIdx;
15914
#else
15915
    #if !defined(NO_RSA) || defined(HAVE_ECC)
15916
    certatt = (CertAttribute*)&sigCtx->CertAtt;
15917
    #endif
15918
    if (certatt) {
15919
        certatt->keyIndex = rsaKeyIdx;
15920
        certatt->cert = buf;
15921
        certatt->certSz = bufSz;
15922
    }
15923
#endif
15924
15925
0
#ifndef NO_ASN_CRYPT
15926
0
    switch (sigCtx->state) {
15927
0
        case SIG_STATE_BEGIN:
15928
0
        {
15929
0
            sigCtx->keyOID = keyOID; /* must set early for cleanup */
15930
15931
0
            sigCtx->digest = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, sigCtx->heap,
15932
0
                                                    DYNAMIC_TYPE_DIGEST);
15933
0
            if (sigCtx->digest == NULL) {
15934
0
                ERROR_OUT(MEMORY_E, exit_cs);
15935
0
            }
15936
15937
0
        #if !defined(NO_RSA) && defined(WC_RSA_PSS)
15938
            /* RSA PSS Defaults */
15939
0
            sigCtx->hash = WC_HASH_TYPE_SHA;
15940
0
            sigCtx->mgf = WC_MGF1SHA1;
15941
0
            sigCtx->saltLen = 20;
15942
0
        #endif
15943
15944
0
            sigCtx->state = SIG_STATE_HASH;
15945
0
        } /* SIG_STATE_BEGIN */
15946
0
        FALL_THROUGH;
15947
15948
0
        case SIG_STATE_HASH:
15949
0
        {
15950
0
        #if !defined(NO_RSA) && defined(WC_RSA_PSS)
15951
0
            if (sigOID == RSAPSSk) {
15952
0
                word32 fakeSigOID = 0;
15953
0
                ret = DecodeRsaPssParams(sigParams, sigParamsSz, &sigCtx->hash,
15954
0
                    &sigCtx->mgf, &sigCtx->saltLen);
15955
0
                if (ret != 0) {
15956
0
                    goto exit_cs;
15957
0
                }
15958
0
                ret = RsaPssHashOidToSigOid(sigCtx->hash, &fakeSigOID);
15959
0
                if (ret != 0) {
15960
0
                    goto exit_cs;
15961
0
                }
15962
                /* Decode parameters. */
15963
0
                ret = HashForSignature(buf, bufSz, fakeSigOID, sigCtx->digest,
15964
0
                    &sigCtx->typeH, &sigCtx->digestSz, 1);
15965
0
                if (ret != 0) {
15966
0
                    goto exit_cs;
15967
0
                }
15968
0
            }
15969
0
            else
15970
0
        #endif
15971
0
        #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
15972
0
            if (sigOID == CTC_SM3wSM2) {
15973
0
                ; /* SM2 hash requires public key. Done later. */
15974
0
            }
15975
0
            else
15976
0
        #endif
15977
0
            {
15978
0
                ret = HashForSignature(buf, bufSz, sigOID, sigCtx->digest,
15979
0
                                       &sigCtx->typeH, &sigCtx->digestSz, 1);
15980
0
                if (ret != 0) {
15981
0
                    goto exit_cs;
15982
0
                }
15983
0
            }
15984
15985
0
            sigCtx->state = SIG_STATE_KEY;
15986
0
        } /* SIG_STATE_HASH */
15987
0
        FALL_THROUGH;
15988
15989
0
        case SIG_STATE_KEY:
15990
0
        {
15991
0
            switch (keyOID) {
15992
0
            #ifndef NO_RSA
15993
0
                #ifdef WC_RSA_PSS
15994
0
                case RSAPSSk:
15995
0
                #endif
15996
0
                case RSAk:
15997
0
                {
15998
0
                    word32 idx = 0;
15999
16000
0
                    sigCtx->key.rsa = (RsaKey*)XMALLOC(sizeof(RsaKey),
16001
0
                                                sigCtx->heap, DYNAMIC_TYPE_RSA);
16002
0
                    if (sigCtx->key.rsa == NULL) {
16003
0
                        ERROR_OUT(MEMORY_E, exit_cs);
16004
0
                    }
16005
0
                    if ((ret = wc_InitRsaKey_ex(sigCtx->key.rsa, sigCtx->heap,
16006
0
                                                        sigCtx->devId)) != 0) {
16007
0
                        goto exit_cs;
16008
0
                    }
16009
0
                    sigCtx->sigCpy = (byte*)XMALLOC(sigSz, sigCtx->heap,
16010
0
                                                        DYNAMIC_TYPE_SIGNATURE);
16011
0
                    if (sigCtx->sigCpy == NULL) {
16012
0
                        ERROR_OUT(MEMORY_E, exit_cs);
16013
0
                    }
16014
0
                    if (sigSz > MAX_ENCODED_SIG_SZ) {
16015
0
                        WOLFSSL_MSG("Verify Signature is too big");
16016
0
                        ERROR_OUT(BUFFER_E, exit_cs);
16017
0
                    }
16018
0
                    if ((ret = wc_RsaPublicKeyDecode(key, &idx, sigCtx->key.rsa,
16019
0
                                                                 keySz)) != 0) {
16020
0
                        WOLFSSL_MSG("ASN Key decode error RSA");
16021
0
                        WOLFSSL_ERROR_VERBOSE(ret);
16022
0
                        goto exit_cs;
16023
0
                    }
16024
0
                    XMEMCPY(sigCtx->sigCpy, sig, sigSz);
16025
0
                    sigCtx->out = NULL;
16026
16027
                #ifdef WOLFSSL_ASYNC_CRYPT
16028
                    sigCtx->asyncDev = &sigCtx->key.rsa->asyncDev;
16029
                #endif
16030
0
                    break;
16031
0
                }
16032
0
            #endif /* !NO_RSA */
16033
            #if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
16034
                case DSAk:
16035
                {
16036
                    word32 idx = 0;
16037
16038
                    if (sigSz < DSA_MIN_SIG_SIZE) {
16039
                        WOLFSSL_MSG("Verify Signature is too small");
16040
                        ERROR_OUT(BUFFER_E, exit_cs);
16041
                    }
16042
                    sigCtx->key.dsa = (DsaKey*)XMALLOC(sizeof(DsaKey),
16043
                                                sigCtx->heap, DYNAMIC_TYPE_DSA);
16044
                    if (sigCtx->key.dsa == NULL) {
16045
                        ERROR_OUT(MEMORY_E, exit_cs);
16046
                    }
16047
                    if ((ret = wc_InitDsaKey_h(sigCtx->key.dsa, sigCtx->heap)) != 0) {
16048
                        WOLFSSL_MSG("wc_InitDsaKey_h error");
16049
                        goto exit_cs;
16050
                    }
16051
                    sigCtx->sigCpy = (byte*)XMALLOC(sigSz,
16052
                                         sigCtx->heap, DYNAMIC_TYPE_SIGNATURE);
16053
                    if (sigCtx->sigCpy == NULL) {
16054
                        ERROR_OUT(MEMORY_E, exit_cs);
16055
                    }
16056
                    if ((ret = wc_DsaPublicKeyDecode(key, &idx, sigCtx->key.dsa,
16057
                                                                 keySz)) != 0) {
16058
                        WOLFSSL_MSG("ASN Key decode error DSA");
16059
                        WOLFSSL_ERROR_VERBOSE(ret);
16060
                        goto exit_cs;
16061
                    }
16062
                    if (sigSz != DSA_160_SIG_SIZE &&
16063
                            sigSz != DSA_256_SIG_SIZE) {
16064
                        /* Try to parse it as the contents of a bitstring */
16065
                    #ifdef WOLFSSL_SMALL_STACK
16066
                        mp_int* r;
16067
                        mp_int* s;
16068
                    #else
16069
                        mp_int r[1];
16070
                        mp_int s[1];
16071
                    #endif
16072
                        int rSz;
16073
                        int sSz;
16074
16075
                    #ifdef WOLFSSL_SMALL_STACK
16076
                        r = (mp_int*)XMALLOC(sizeof(*r), sigCtx->heap,
16077
                                                       DYNAMIC_TYPE_TMP_BUFFER);
16078
                        if (r == NULL) {
16079
                            ERROR_OUT(MEMORY_E, exit_cs);
16080
                        }
16081
                        s = (mp_int*)XMALLOC(sizeof(*s), sigCtx->heap,
16082
                                                       DYNAMIC_TYPE_TMP_BUFFER);
16083
                        if (s == NULL) {
16084
                            XFREE(r, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
16085
                            ERROR_OUT(MEMORY_E, exit_cs);
16086
                        }
16087
                    #endif
16088
                        if ((ret = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY) {
16089
                            goto exit_cs;
16090
                        }
16091
16092
                        idx = 0;
16093
                        if (DecodeECC_DSA_Sig(sig + idx, sigSz - idx, r, s)
16094
                                              != 0) {
16095
                            WOLFSSL_MSG("DSA Sig is in unrecognized or "
16096
                                        "incorrect format");
16097
                            mp_free(r);
16098
                            mp_free(s);
16099
                    #ifdef WOLFSSL_SMALL_STACK
16100
                            XFREE(r, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
16101
                            XFREE(s, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
16102
                    #endif
16103
                            ERROR_OUT(ASN_SIG_CONFIRM_E, exit_cs);
16104
                        }
16105
                        rSz = mp_unsigned_bin_size(r);
16106
                        sSz = mp_unsigned_bin_size(s);
16107
                        if (rSz + sSz > (int)sigSz) {
16108
                            WOLFSSL_MSG("DSA Sig is in unrecognized or "
16109
                                        "incorrect format");
16110
                            mp_free(r);
16111
                            mp_free(s);
16112
                    #ifdef WOLFSSL_SMALL_STACK
16113
                            XFREE(r, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
16114
                            XFREE(s, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
16115
                    #endif
16116
                            ERROR_OUT(ASN_SIG_CONFIRM_E, exit_cs);
16117
                        }
16118
                        if (mp_to_unsigned_bin(r, sigCtx->sigCpy) != MP_OKAY ||
16119
                                mp_to_unsigned_bin(s,
16120
                                        sigCtx->sigCpy + rSz) != MP_OKAY) {
16121
                            WOLFSSL_MSG("DSA Sig is in unrecognized or "
16122
                                        "incorrect format");
16123
                            mp_free(r);
16124
                            mp_free(s);
16125
                    #ifdef WOLFSSL_SMALL_STACK
16126
                            XFREE(r, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
16127
                            XFREE(s, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
16128
                    #endif
16129
                            ERROR_OUT(ASN_SIG_CONFIRM_E, exit_cs);
16130
                        }
16131
                        mp_free(r);
16132
                        mp_free(s);
16133
                    #ifdef WOLFSSL_SMALL_STACK
16134
                        XFREE(r, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
16135
                        XFREE(s, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
16136
                    #endif
16137
                    }
16138
                    else {
16139
                        XMEMCPY(sigCtx->sigCpy, sig, sigSz);
16140
                    }
16141
                    break;
16142
                }
16143
            #endif /* !NO_DSA && !HAVE_SELFTEST */
16144
0
            #ifdef HAVE_ECC
16145
0
            #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
16146
0
                case SM2k:
16147
0
            #endif
16148
0
                case ECDSAk:
16149
0
                {
16150
0
                    word32 idx = 0;
16151
            #if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
16152
                defined(WC_ASYNC_ENABLE_ECC)
16153
                    ecc_nb_ctx_t* nbCtx;
16154
            #endif /* WC_ECC_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
16155
                      WC_ASYNC_ENABLE_ECC */
16156
16157
0
                    sigCtx->verify = 0;
16158
0
                    sigCtx->key.ecc = (ecc_key*)XMALLOC(sizeof(ecc_key),
16159
0
                                                sigCtx->heap, DYNAMIC_TYPE_ECC);
16160
0
                    if (sigCtx->key.ecc == NULL) {
16161
0
                        ERROR_OUT(MEMORY_E, exit_cs);
16162
0
                    }
16163
0
                    if ((ret = wc_ecc_init_ex(sigCtx->key.ecc, sigCtx->heap,
16164
0
                                                          sigCtx->devId)) < 0) {
16165
0
                        goto exit_cs;
16166
0
                    }
16167
            #if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
16168
                defined(WC_ASYNC_ENABLE_ECC)
16169
                    nbCtx = (ecc_nb_ctx_t*)XMALLOC(sizeof(ecc_nb_ctx_t),
16170
                                sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
16171
                    if (nbCtx == NULL) {
16172
                        ERROR_OUT(MEMORY_E, exit_cs);
16173
                    }
16174
                    else {
16175
                        ret = wc_ecc_set_nonblock(sigCtx->key.ecc, nbCtx);
16176
                        if (ret != 0) {
16177
                            goto exit_cs;
16178
                        }
16179
                    }
16180
            #endif /* WC_ECC_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
16181
                      WC_ASYNC_ENABLE_ECC */
16182
0
                    ret = wc_EccPublicKeyDecode(key, &idx, sigCtx->key.ecc,
16183
0
                                                                         keySz);
16184
0
                    if (ret < 0) {
16185
0
                        WOLFSSL_MSG("ASN Key import error ECC");
16186
0
                        WOLFSSL_ERROR_VERBOSE(ret);
16187
0
                        goto exit_cs;
16188
0
                    }
16189
                #ifdef WOLFSSL_ASYNC_CRYPT
16190
                    sigCtx->asyncDev = &sigCtx->key.ecc->asyncDev;
16191
                #endif
16192
0
                    break;
16193
0
                }
16194
0
            #endif /* HAVE_ECC */
16195
0
            #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
16196
0
                case ED25519k:
16197
0
                {
16198
0
                    sigCtx->verify = 0;
16199
0
                    sigCtx->key.ed25519 = (ed25519_key*)XMALLOC(
16200
0
                                              sizeof(ed25519_key), sigCtx->heap,
16201
0
                                              DYNAMIC_TYPE_ED25519);
16202
0
                    if (sigCtx->key.ed25519 == NULL) {
16203
0
                        ERROR_OUT(MEMORY_E, exit_cs);
16204
0
                    }
16205
0
                    if ((ret = wc_ed25519_init_ex(sigCtx->key.ed25519,
16206
0
                                            sigCtx->heap, sigCtx->devId)) < 0) {
16207
0
                        goto exit_cs;
16208
0
                    }
16209
0
                    if ((ret = wc_ed25519_import_public(key, keySz,
16210
0
                                                    sigCtx->key.ed25519)) < 0) {
16211
0
                        WOLFSSL_MSG("ASN Key import error ED25519");
16212
0
                        WOLFSSL_ERROR_VERBOSE(ret);
16213
0
                        goto exit_cs;
16214
0
                    }
16215
                #ifdef WOLFSSL_ASYNC_CRYPT
16216
                    sigCtx->asyncDev = &sigCtx->key.ed25519->asyncDev;
16217
                #endif
16218
0
                    break;
16219
0
                }
16220
0
            #endif
16221
0
            #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)
16222
0
                case ED448k:
16223
0
                {
16224
0
                    sigCtx->verify = 0;
16225
0
                    sigCtx->key.ed448 = (ed448_key*)XMALLOC(
16226
0
                                                sizeof(ed448_key), sigCtx->heap,
16227
0
                                                DYNAMIC_TYPE_ED448);
16228
0
                    if (sigCtx->key.ed448 == NULL) {
16229
0
                        ERROR_OUT(MEMORY_E, exit_cs);
16230
0
                    }
16231
0
                    if ((ret = wc_ed448_init(sigCtx->key.ed448)) < 0) {
16232
0
                        goto exit_cs;
16233
0
                    }
16234
0
                    if ((ret = wc_ed448_import_public(key, keySz,
16235
0
                                                      sigCtx->key.ed448)) < 0) {
16236
0
                        WOLFSSL_MSG("ASN Key import error ED448");
16237
0
                        WOLFSSL_ERROR_VERBOSE(ret);
16238
0
                        goto exit_cs;
16239
0
                    }
16240
                #ifdef WOLFSSL_ASYNC_CRYPT
16241
                    sigCtx->asyncDev = &sigCtx->key.ed448->asyncDev;
16242
                #endif
16243
0
                    break;
16244
0
                }
16245
0
            #endif
16246
            #if defined(HAVE_PQC)
16247
            #if defined(HAVE_FALCON)
16248
                case FALCON_LEVEL1k:
16249
                {
16250
                    sigCtx->verify = 0;
16251
                    sigCtx->key.falcon =
16252
                        (falcon_key*)XMALLOC(sizeof(falcon_key),
16253
                                             sigCtx->heap,
16254
                                             DYNAMIC_TYPE_FALCON);
16255
                    if (sigCtx->key.falcon == NULL) {
16256
                        ERROR_OUT(MEMORY_E, exit_cs);
16257
                    }
16258
                    if ((ret = wc_falcon_init(sigCtx->key.falcon)) < 0) {
16259
                        goto exit_cs;
16260
                    }
16261
                    if ((ret = wc_falcon_set_level(sigCtx->key.falcon, 1))
16262
                        < 0) {
16263
                        goto exit_cs;
16264
                    }
16265
                    if ((ret = wc_falcon_import_public(key, keySz,
16266
                        sigCtx->key.falcon)) < 0) {
16267
                        WOLFSSL_MSG("ASN Key import error Falcon Level 1");
16268
                        WOLFSSL_ERROR_VERBOSE(ret);
16269
                        goto exit_cs;
16270
                    }
16271
                    break;
16272
                }
16273
                case FALCON_LEVEL5k:
16274
                {
16275
                    sigCtx->verify = 0;
16276
                    sigCtx->key.falcon =
16277
                        (falcon_key*)XMALLOC(sizeof(falcon_key),
16278
                                             sigCtx->heap,
16279
                                             DYNAMIC_TYPE_FALCON);
16280
                    if (sigCtx->key.falcon == NULL) {
16281
                        ERROR_OUT(MEMORY_E, exit_cs);
16282
                    }
16283
                    if ((ret = wc_falcon_init(sigCtx->key.falcon)) < 0) {
16284
                        goto exit_cs;
16285
                    }
16286
                    if ((ret = wc_falcon_set_level(sigCtx->key.falcon, 5))
16287
                        < 0) {
16288
                        goto exit_cs;
16289
                    }
16290
                    if ((ret = wc_falcon_import_public(key, keySz,
16291
                        sigCtx->key.falcon)) < 0) {
16292
                        WOLFSSL_MSG("ASN Key import error Falcon Level 5");
16293
                        WOLFSSL_ERROR_VERBOSE(ret);
16294
                        goto exit_cs;
16295
                    }
16296
                    break;
16297
                }
16298
            #endif /* HAVE_FALCON */
16299
            #if defined(HAVE_DILITHIUM)
16300
                case DILITHIUM_LEVEL2k:
16301
                {
16302
                    sigCtx->verify = 0;
16303
                    sigCtx->key.dilithium =
16304
                        (dilithium_key*)XMALLOC(sizeof(dilithium_key),
16305
                                             sigCtx->heap,
16306
                                             DYNAMIC_TYPE_DILITHIUM);
16307
                    if (sigCtx->key.dilithium == NULL) {
16308
                        ERROR_OUT(MEMORY_E, exit_cs);
16309
                    }
16310
                    if ((ret = wc_dilithium_init(sigCtx->key.dilithium)) < 0) {
16311
                        goto exit_cs;
16312
                    }
16313
                    if ((ret = wc_dilithium_set_level(
16314
                                   sigCtx->key.dilithium, 2))
16315
                        < 0) {
16316
                        goto exit_cs;
16317
                    }
16318
                    if ((ret = wc_dilithium_import_public(key, keySz,
16319
                        sigCtx->key.dilithium)) < 0) {
16320
                        WOLFSSL_MSG("ASN Key import error Dilithium Level 2");
16321
                        goto exit_cs;
16322
                    }
16323
                    break;
16324
                }
16325
                case DILITHIUM_LEVEL3k:
16326
                {
16327
                    sigCtx->verify = 0;
16328
                    sigCtx->key.dilithium =
16329
                        (dilithium_key*)XMALLOC(sizeof(dilithium_key),
16330
                                             sigCtx->heap,
16331
                                             DYNAMIC_TYPE_DILITHIUM);
16332
                    if (sigCtx->key.dilithium == NULL) {
16333
                        ERROR_OUT(MEMORY_E, exit_cs);
16334
                    }
16335
                    if ((ret = wc_dilithium_init(sigCtx->key.dilithium)) < 0) {
16336
                        goto exit_cs;
16337
                    }
16338
                    if ((ret = wc_dilithium_set_level(
16339
                                   sigCtx->key.dilithium, 3))
16340
                        < 0) {
16341
                        goto exit_cs;
16342
                    }
16343
                    if ((ret = wc_dilithium_import_public(key, keySz,
16344
                        sigCtx->key.dilithium)) < 0) {
16345
                        WOLFSSL_MSG("ASN Key import error Dilithium Level 5");
16346
                        goto exit_cs;
16347
                    }
16348
                    break;
16349
                }
16350
                case DILITHIUM_LEVEL5k:
16351
                {
16352
                    sigCtx->verify = 0;
16353
                    sigCtx->key.dilithium =
16354
                        (dilithium_key*)XMALLOC(sizeof(dilithium_key),
16355
                                             sigCtx->heap,
16356
                                             DYNAMIC_TYPE_DILITHIUM);
16357
                    if (sigCtx->key.dilithium == NULL) {
16358
                        ERROR_OUT(MEMORY_E, exit_cs);
16359
                    }
16360
                    if ((ret = wc_dilithium_init(sigCtx->key.dilithium)) < 0) {
16361
                        goto exit_cs;
16362
                    }
16363
                    if ((ret = wc_dilithium_set_level(
16364
                                   sigCtx->key.dilithium, 5))
16365
                        < 0) {
16366
                        goto exit_cs;
16367
                    }
16368
                    if ((ret = wc_dilithium_import_public(key, keySz,
16369
                        sigCtx->key.dilithium)) < 0) {
16370
                        WOLFSSL_MSG("ASN Key import error Dilithium Level 5");
16371
                        goto exit_cs;
16372
                    }
16373
                    break;
16374
                }
16375
            #endif /* HAVE_DILITHIUM */
16376
            #if defined(HAVE_SPHINCS)
16377
                case SPHINCS_FAST_LEVEL1k:
16378
                {
16379
                    sigCtx->verify = 0;
16380
                    sigCtx->key.sphincs =
16381
                        (sphincs_key*)XMALLOC(sizeof(sphincs_key),
16382
                                             sigCtx->heap,
16383
                                             DYNAMIC_TYPE_SPHINCS);
16384
                    if (sigCtx->key.sphincs == NULL) {
16385
                        ERROR_OUT(MEMORY_E, exit_cs);
16386
                    }
16387
                    if ((ret = wc_sphincs_init(sigCtx->key.sphincs)) < 0) {
16388
                        goto exit_cs;
16389
                    }
16390
                    if ((ret = wc_sphincs_set_level_and_optim(
16391
                                   sigCtx->key.sphincs, 1, FAST_VARIANT))
16392
                        < 0) {
16393
                        goto exit_cs;
16394
                    }
16395
                    if ((ret = wc_sphincs_import_public(key, keySz,
16396
                        sigCtx->key.sphincs)) < 0) {
16397
                        WOLFSSL_MSG("ASN Key import err: Sphincs-fast Level1");
16398
                        goto exit_cs;
16399
                    }
16400
                    break;
16401
                }
16402
                case SPHINCS_FAST_LEVEL3k:
16403
                {
16404
                    sigCtx->verify = 0;
16405
                    sigCtx->key.sphincs =
16406
                        (sphincs_key*)XMALLOC(sizeof(sphincs_key),
16407
                                             sigCtx->heap,
16408
                                             DYNAMIC_TYPE_SPHINCS);
16409
                    if (sigCtx->key.sphincs == NULL) {
16410
                        ERROR_OUT(MEMORY_E, exit_cs);
16411
                    }
16412
                    if ((ret = wc_sphincs_init(sigCtx->key.sphincs)) < 0) {
16413
                        goto exit_cs;
16414
                    }
16415
                    if ((ret = wc_sphincs_set_level_and_optim(
16416
                                   sigCtx->key.sphincs, 3, FAST_VARIANT))
16417
                        < 0) {
16418
                        goto exit_cs;
16419
                    }
16420
                    if ((ret = wc_sphincs_import_public(key, keySz,
16421
                        sigCtx->key.sphincs)) < 0) {
16422
                        WOLFSSL_MSG("ASN Key import err: Sphincs-fast Level3");
16423
                        goto exit_cs;
16424
                    }
16425
                    break;
16426
                }
16427
                case SPHINCS_FAST_LEVEL5k:
16428
                {
16429
                    sigCtx->verify = 0;
16430
                    sigCtx->key.sphincs =
16431
                        (sphincs_key*)XMALLOC(sizeof(sphincs_key),
16432
                                             sigCtx->heap,
16433
                                             DYNAMIC_TYPE_SPHINCS);
16434
                    if (sigCtx->key.sphincs == NULL) {
16435
                        ERROR_OUT(MEMORY_E, exit_cs);
16436
                    }
16437
                    if ((ret = wc_sphincs_init(sigCtx->key.sphincs)) < 0) {
16438
                        goto exit_cs;
16439
                    }
16440
                    if ((ret = wc_sphincs_set_level_and_optim(
16441
                                   sigCtx->key.sphincs, 5, FAST_VARIANT))
16442
                        < 0) {
16443
                        goto exit_cs;
16444
                    }
16445
                    if ((ret = wc_sphincs_import_public(key, keySz,
16446
                        sigCtx->key.sphincs)) < 0) {
16447
                        WOLFSSL_MSG("ASN Key import err: Sphincs-fast Level5");
16448
                        goto exit_cs;
16449
                    }
16450
                    break;
16451
                }
16452
16453
                case SPHINCS_SMALL_LEVEL1k:
16454
                {
16455
                    sigCtx->verify = 0;
16456
                    sigCtx->key.sphincs =
16457
                        (sphincs_key*)XMALLOC(sizeof(sphincs_key),
16458
                                             sigCtx->heap,
16459
                                             DYNAMIC_TYPE_SPHINCS);
16460
                    if (sigCtx->key.sphincs == NULL) {
16461
                        ERROR_OUT(MEMORY_E, exit_cs);
16462
                    }
16463
                    if ((ret = wc_sphincs_init(sigCtx->key.sphincs)) < 0) {
16464
                        goto exit_cs;
16465
                    }
16466
                    if ((ret = wc_sphincs_set_level_and_optim(
16467
                                   sigCtx->key.sphincs, 1, SMALL_VARIANT))
16468
                        < 0) {
16469
                        goto exit_cs;
16470
                    }
16471
                    if ((ret = wc_sphincs_import_public(key, keySz,
16472
                        sigCtx->key.sphincs)) < 0) {
16473
                        WOLFSSL_MSG("ASN Key import err: Sphincs-fast Level1");
16474
                        goto exit_cs;
16475
                    }
16476
                    break;
16477
                }
16478
                case SPHINCS_SMALL_LEVEL3k:
16479
                {
16480
                    sigCtx->verify = 0;
16481
                    sigCtx->key.sphincs =
16482
                        (sphincs_key*)XMALLOC(sizeof(sphincs_key),
16483
                                             sigCtx->heap,
16484
                                             DYNAMIC_TYPE_SPHINCS);
16485
                    if (sigCtx->key.sphincs == NULL) {
16486
                        ERROR_OUT(MEMORY_E, exit_cs);
16487
                    }
16488
                    if ((ret = wc_sphincs_init(sigCtx->key.sphincs)) < 0) {
16489
                        goto exit_cs;
16490
                    }
16491
                    if ((ret = wc_sphincs_set_level_and_optim(
16492
                                   sigCtx->key.sphincs, 3, SMALL_VARIANT))
16493
                        < 0) {
16494
                        goto exit_cs;
16495
                    }
16496
                    if ((ret = wc_sphincs_import_public(key, keySz,
16497
                        sigCtx->key.sphincs)) < 0) {
16498
                        WOLFSSL_MSG("ASN Key import err: Sphincs-fast Level3");
16499
                        goto exit_cs;
16500
                    }
16501
                    break;
16502
                }
16503
                case SPHINCS_SMALL_LEVEL5k:
16504
                {
16505
                    sigCtx->verify = 0;
16506
                    sigCtx->key.sphincs =
16507
                        (sphincs_key*)XMALLOC(sizeof(sphincs_key),
16508
                                             sigCtx->heap,
16509
                                             DYNAMIC_TYPE_SPHINCS);
16510
                    if (sigCtx->key.sphincs == NULL) {
16511
                        ERROR_OUT(MEMORY_E, exit_cs);
16512
                    }
16513
                    if ((ret = wc_sphincs_init(sigCtx->key.sphincs)) < 0) {
16514
                        goto exit_cs;
16515
                    }
16516
                    if ((ret = wc_sphincs_set_level_and_optim(
16517
                                   sigCtx->key.sphincs, 5, SMALL_VARIANT))
16518
                        < 0) {
16519
                        goto exit_cs;
16520
                    }
16521
                    if ((ret = wc_sphincs_import_public(key, keySz,
16522
                        sigCtx->key.sphincs)) < 0) {
16523
                        WOLFSSL_MSG("ASN Key import err: Sphincs-fast Level5");
16524
                        goto exit_cs;
16525
                    }
16526
                    break;
16527
                }
16528
            #endif /* HAVE_SPHINCS */
16529
            #endif /* HAVE_PQC */
16530
0
                default:
16531
0
                    WOLFSSL_MSG("Verify Key type unknown");
16532
0
                    ret = ASN_UNKNOWN_OID_E;
16533
0
                    WOLFSSL_ERROR_VERBOSE(ret);
16534
0
                    break;
16535
0
            } /* switch (keyOID) */
16536
16537
0
            if (ret != 0) {
16538
0
                goto exit_cs;
16539
0
            }
16540
16541
0
            sigCtx->state = SIG_STATE_DO;
16542
16543
        #ifdef WOLFSSL_ASYNC_CRYPT
16544
            if (sigCtx->devId != INVALID_DEVID && sigCtx->asyncDev && sigCtx->asyncCtx) {
16545
                /* make sure event is initialized */
16546
                WOLF_EVENT* event = &sigCtx->asyncDev->event;
16547
                ret = wolfAsync_EventInit(event, WOLF_EVENT_TYPE_ASYNC_WOLFSSL,
16548
                    sigCtx->asyncCtx, WC_ASYNC_FLAG_CALL_AGAIN);
16549
            }
16550
        #endif
16551
0
        } /* SIG_STATE_KEY */
16552
0
        FALL_THROUGH;
16553
16554
0
        case SIG_STATE_DO:
16555
0
        {
16556
0
            switch (keyOID) {
16557
0
            #ifndef NO_RSA
16558
0
                case RSAk:
16559
0
                #ifdef WC_RSA_PSS
16560
0
                case RSAPSSk:
16561
0
                if (sigOID == RSAPSSk) {
16562
                    /* TODO: pkCbRsaPss - RSA PSS callback. */
16563
0
                    ret = wc_RsaPSS_VerifyInline_ex(sigCtx->sigCpy, sigSz,
16564
0
                        &sigCtx->out, sigCtx->hash, sigCtx->mgf,
16565
0
                        sigCtx->saltLen, sigCtx->key.rsa);
16566
0
                }
16567
0
                else
16568
0
                #endif
16569
0
                {
16570
                #if defined(HAVE_PK_CALLBACKS)
16571
                    if (sigCtx->pkCbRsa) {
16572
                        ret = sigCtx->pkCbRsa(
16573
                                sigCtx->sigCpy, sigSz, &sigCtx->out,
16574
                                key, keySz,
16575
                                sigCtx->pkCtxRsa);
16576
                    }
16577
                #if !defined(WOLFSSL_RENESAS_SCEPROTECT) && \
16578
                    !defined(WOLFSSL_RENESAS_TSIP_TLS)
16579
                    else
16580
                #else
16581
                    if (!sigCtx->pkCbRsa || ret == CRYPTOCB_UNAVAILABLE)
16582
                #endif /* WOLFSSL_RENESAS_SCEPROTECT */
16583
                #endif /* HAVE_PK_CALLBACKS */
16584
0
                    {
16585
0
                        ret = wc_RsaSSL_VerifyInline(sigCtx->sigCpy, sigSz,
16586
0
                                                 &sigCtx->out, sigCtx->key.rsa);
16587
0
                    }
16588
0
                }
16589
0
                break;
16590
0
            #endif /* !NO_RSA */
16591
            #if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
16592
                case DSAk:
16593
                {
16594
                    ret = wc_DsaVerify(sigCtx->digest, sigCtx->sigCpy,
16595
                            sigCtx->key.dsa, &sigCtx->verify);
16596
                    break;
16597
                }
16598
            #endif /* !NO_DSA && !HAVE_SELFTEST */
16599
0
            #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
16600
0
                case SM2k:
16601
0
                {
16602
                    /* OpenSSL creates signature without CERT_SIG_ID. */
16603
0
                    ret = wc_ecc_sm2_create_digest(CERT_SIG_ID, 0, buf, bufSz,
16604
0
                        WC_HASH_TYPE_SM3, sigCtx->digest, WC_SM3_DIGEST_SIZE,
16605
0
                        sigCtx->key.ecc);
16606
0
                    if (ret == 0) {
16607
0
                        sigCtx->typeH    = SM3h;
16608
0
                        sigCtx->digestSz = WC_SM3_DIGEST_SIZE;
16609
0
                    }
16610
0
                    else {
16611
0
                        WOLFSSL_MSG("SM2wSM3 create digest failed");
16612
0
                        WOLFSSL_ERROR_VERBOSE(ret);
16613
0
                        goto exit_cs;
16614
0
                    }
16615
0
                    ret = wc_ecc_sm2_verify_hash(sig, sigSz, sigCtx->digest,
16616
0
                        sigCtx->digestSz, &sigCtx->verify, sigCtx->key.ecc);
16617
0
                    break;
16618
0
                }
16619
0
            #endif
16620
0
            #if defined(HAVE_ECC) && defined(HAVE_ECC_VERIFY)
16621
0
                case ECDSAk:
16622
0
                {
16623
0
                #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
16624
0
                    if (sigOID == CTC_SM3wSM2) {
16625
0
                        ret = wc_ecc_sm2_create_digest(CERT_SIG_ID,
16626
0
                            CERT_SIG_ID_SZ, buf, bufSz, WC_HASH_TYPE_SM3,
16627
0
                            sigCtx->digest, WC_SM3_DIGEST_SIZE,
16628
0
                            sigCtx->key.ecc);
16629
0
                        if (ret == 0) {
16630
0
                            sigCtx->typeH    = SM3h;
16631
0
                            sigCtx->digestSz = WC_SM3_DIGEST_SIZE;
16632
0
                        }
16633
0
                        else {
16634
0
                            WOLFSSL_MSG("SM2wSM3 create digest failed");
16635
0
                            WOLFSSL_ERROR_VERBOSE(ret);
16636
0
                            goto exit_cs;
16637
0
                        }
16638
0
                        ret = wc_ecc_sm2_verify_hash(sig, sigSz, sigCtx->digest,
16639
0
                            sigCtx->digestSz, &sigCtx->verify, sigCtx->key.ecc);
16640
0
                    }
16641
0
                    else
16642
0
                #endif
16643
                #if defined(HAVE_PK_CALLBACKS)
16644
                    if (sigCtx->pkCbEcc) {
16645
                        ret = sigCtx->pkCbEcc(
16646
                                sig, sigSz,
16647
                                sigCtx->digest, (unsigned int)sigCtx->digestSz,
16648
                                key, keySz, &sigCtx->verify,
16649
                                sigCtx->pkCtxEcc);
16650
                    }
16651
                #if !defined(WOLFSSL_RENESAS_SCEPROTECT) && \
16652
                    !defined(WOLFSSL_RENESAS_TSIP_TLS)
16653
                    else
16654
                #else
16655
                    if (!sigCtx->pkCbEcc || ret == CRYPTOCB_UNAVAILABLE)
16656
                #endif /* WOLFSSL_RENESAS_SCEPROTECT */
16657
                #endif /* HAVE_PK_CALLBACKS */
16658
0
                    {
16659
0
                        ret = wc_ecc_verify_hash(sig, sigSz, sigCtx->digest,
16660
0
                            (word32)sigCtx->digestSz, &sigCtx->verify,
16661
0
                            sigCtx->key.ecc);
16662
0
                    }
16663
0
                    break;
16664
0
                }
16665
0
            #endif /* HAVE_ECC */
16666
0
            #if defined(HAVE_ED25519) && defined(HAVE_ED25519_VERIFY)
16667
0
                case ED25519k:
16668
0
                {
16669
0
                    ret = wc_ed25519_verify_msg(sig, sigSz, buf, bufSz,
16670
0
                                          &sigCtx->verify, sigCtx->key.ed25519);
16671
0
                    break;
16672
0
                }
16673
0
            #endif
16674
0
            #if defined(HAVE_ED448) && defined(HAVE_ED448_VERIFY)
16675
0
                case ED448k:
16676
0
                {
16677
0
                    ret = wc_ed448_verify_msg(sig, sigSz, buf, bufSz,
16678
0
                                             &sigCtx->verify, sigCtx->key.ed448,
16679
0
                                             NULL, 0);
16680
0
                    break;
16681
0
                }
16682
0
            #endif
16683
            #if defined(HAVE_PQC)
16684
            #if defined(HAVE_FALCON)
16685
                case FALCON_LEVEL1k:
16686
                case FALCON_LEVEL5k:
16687
                {
16688
                    ret = wc_falcon_verify_msg(sig, sigSz, buf, bufSz,
16689
                                               &sigCtx->verify,
16690
                                               sigCtx->key.falcon);
16691
                    break;
16692
                }
16693
            #endif /* HAVE_FALCON */
16694
            #if defined(HAVE_DILITHIUM)
16695
                case DILITHIUM_LEVEL2k:
16696
                case DILITHIUM_LEVEL3k:
16697
                case DILITHIUM_LEVEL5k:
16698
                {
16699
                    ret = wc_dilithium_verify_msg(sig, sigSz, buf, bufSz,
16700
                                               &sigCtx->verify,
16701
                                               sigCtx->key.dilithium);
16702
                    break;
16703
                }
16704
            #endif /* HAVE_DILITHIUM */
16705
            #if defined(HAVE_SPHINCS)
16706
                case SPHINCS_FAST_LEVEL1k:
16707
                case SPHINCS_FAST_LEVEL3k:
16708
                case SPHINCS_FAST_LEVEL5k:
16709
                case SPHINCS_SMALL_LEVEL1k:
16710
                case SPHINCS_SMALL_LEVEL3k:
16711
                case SPHINCS_SMALL_LEVEL5k:
16712
                {
16713
                    ret = wc_sphincs_verify_msg(sig, sigSz, buf, bufSz,
16714
                                                &sigCtx->verify,
16715
                                                sigCtx->key.sphincs);
16716
                    break;
16717
                }
16718
            #endif /* HAVE_SPHINCS */
16719
            #endif /* HAVE_PQC */
16720
0
                default:
16721
0
                    break;
16722
0
            }  /* switch (keyOID) */
16723
16724
        #ifdef WOLFSSL_ASYNC_CRYPT
16725
            if (ret == WC_PENDING_E) {
16726
                goto exit_cs;
16727
            }
16728
        #endif
16729
16730
0
            if (ret < 0) {
16731
                /* treat all errors as ASN_SIG_CONFIRM_E */
16732
0
                ret = ASN_SIG_CONFIRM_E;
16733
0
                WOLFSSL_ERROR_VERBOSE(ret);
16734
0
                goto exit_cs;
16735
0
            }
16736
16737
0
            sigCtx->state = SIG_STATE_CHECK;
16738
0
        } /* SIG_STATE_DO */
16739
0
        FALL_THROUGH;
16740
16741
0
        case SIG_STATE_CHECK:
16742
0
        {
16743
0
            switch (keyOID) {
16744
0
            #ifndef NO_RSA
16745
0
                case RSAk:
16746
0
                #ifdef WC_RSA_PSS
16747
0
                case RSAPSSk:
16748
0
                if (sigOID == RSAPSSk) {
16749
                #if (defined(HAVE_SELFTEST) && \
16750
                     (!defined(HAVE_SELFTEST_VERSION) || \
16751
                      (HAVE_SELFTEST_VERSION < 2))) || \
16752
                    (defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \
16753
                     (HAVE_FIPS_VERSION < 2))
16754
                    ret = wc_RsaPSS_CheckPadding_ex(sigCtx->digest,
16755
                        sigCtx->digestSz, sigCtx->out, ret, sigCtx->hash,
16756
                        sigCtx->saltLen);
16757
                #elif (defined(HAVE_SELFTEST) && \
16758
                       (HAVE_SELFTEST_VERSION == 2)) || \
16759
                      (defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \
16760
                       (HAVE_FIPS_VERSION == 2))
16761
                    ret = wc_RsaPSS_CheckPadding_ex(sigCtx->digest,
16762
                        sigCtx->digestSz, sigCtx->out, ret, sigCtx->hash,
16763
                        sigCtx->saltLen, 0);
16764
                #else
16765
0
                    ret = wc_RsaPSS_CheckPadding_ex2(sigCtx->digest,
16766
0
                        (word32)sigCtx->digestSz, sigCtx->out, (word32)ret, sigCtx->hash,
16767
0
                        sigCtx->saltLen, wc_RsaEncryptSize(sigCtx->key.rsa) * 8,
16768
0
                        sigCtx->heap);
16769
0
                #endif
16770
0
                    break;
16771
0
                }
16772
0
                else
16773
0
                #endif
16774
0
                {
16775
0
                    int encodedSigSz, verifySz;
16776
                #if defined(WOLFSSL_RENESAS_TSIP_TLS) || \
16777
                                            defined(WOLFSSL_RENESAS_SCEPROTECT)
16778
                    if (sigCtx->CertAtt.verifyByTSIP_SCE == 1) break;
16779
                #endif
16780
0
                #ifdef WOLFSSL_SMALL_STACK
16781
0
                    byte* encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ,
16782
0
                                        sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
16783
0
                    if (encodedSig == NULL) {
16784
0
                        ERROR_OUT(MEMORY_E, exit_cs);
16785
0
                    }
16786
                #else
16787
                    byte encodedSig[MAX_ENCODED_SIG_SZ];
16788
                #endif
16789
16790
0
                    verifySz = ret;
16791
16792
                    /* make sure we're right justified */
16793
0
                    encodedSigSz = (int)wc_EncodeSignature(encodedSig,
16794
0
                            sigCtx->digest, (word32)sigCtx->digestSz,
16795
0
                            sigCtx->typeH);
16796
0
                    if (encodedSigSz == verifySz && sigCtx->out != NULL &&
16797
0
                        XMEMCMP(sigCtx->out, encodedSig,
16798
0
                            (size_t)encodedSigSz) == 0) {
16799
0
                        ret = 0;
16800
0
                    }
16801
0
                    else {
16802
0
                        WOLFSSL_MSG("RSA SSL verify match encode error");
16803
0
                        ret = ASN_SIG_CONFIRM_E;
16804
0
                        WOLFSSL_ERROR_VERBOSE(ret);
16805
0
                    }
16806
16807
0
                #ifdef WOLFSSL_SMALL_STACK
16808
0
                    XFREE(encodedSig, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
16809
0
                #endif
16810
0
                    break;
16811
0
                }
16812
0
            #endif /* NO_RSA */
16813
            #if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
16814
                case DSAk:
16815
                {
16816
                    if (sigCtx->verify == 1) {
16817
                        ret = 0;
16818
                    }
16819
                    else {
16820
                        WOLFSSL_MSG("DSA Verify didn't match");
16821
                        ret = ASN_SIG_CONFIRM_E;
16822
                        WOLFSSL_ERROR_VERBOSE(ret);
16823
                    }
16824
                    break;
16825
                }
16826
            #endif /* !NO_DSA && !HAVE_SELFTEST */
16827
0
            #ifdef HAVE_ECC
16828
0
            #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
16829
0
                case SM2k:
16830
0
            #endif
16831
0
                case ECDSAk:
16832
0
                {
16833
0
                    if (sigCtx->verify == 1) {
16834
0
                        ret = 0;
16835
0
                    }
16836
0
                    else {
16837
0
                        WOLFSSL_MSG("ECC Verify didn't match");
16838
0
                        ret = ASN_SIG_CONFIRM_E;
16839
0
                        WOLFSSL_ERROR_VERBOSE(ret);
16840
0
                    }
16841
0
                    break;
16842
0
                }
16843
0
            #endif /* HAVE_ECC */
16844
0
            #ifdef HAVE_ED25519
16845
0
                case ED25519k:
16846
0
                {
16847
0
                    if (sigCtx->verify == 1) {
16848
0
                        ret = 0;
16849
0
                    }
16850
0
                    else {
16851
0
                        WOLFSSL_MSG("ED25519 Verify didn't match");
16852
0
                        ret = ASN_SIG_CONFIRM_E;
16853
0
                        WOLFSSL_ERROR_VERBOSE(ret);
16854
0
                    }
16855
0
                    break;
16856
0
                }
16857
0
            #endif /* HAVE_ED25519 */
16858
0
            #ifdef HAVE_ED448
16859
0
                case ED448k:
16860
0
                {
16861
0
                    if (sigCtx->verify == 1) {
16862
0
                        ret = 0;
16863
0
                    }
16864
0
                    else {
16865
0
                        WOLFSSL_MSG("ED448 Verify didn't match");
16866
0
                        ret = ASN_SIG_CONFIRM_E;
16867
0
                        WOLFSSL_ERROR_VERBOSE(ret);
16868
0
                    }
16869
0
                    break;
16870
0
                }
16871
0
            #endif /* HAVE_ED448 */
16872
            #ifdef HAVE_PQC
16873
            #ifdef HAVE_FALCON
16874
                case FALCON_LEVEL1k:
16875
                {
16876
                    if (sigCtx->verify == 1) {
16877
                        ret = 0;
16878
                    }
16879
                    else {
16880
                        WOLFSSL_MSG("FALCON_LEVEL1 Verify didn't match");
16881
                        ret = ASN_SIG_CONFIRM_E;
16882
                        WOLFSSL_ERROR_VERBOSE(ret);
16883
                    }
16884
                    break;
16885
                }
16886
                case FALCON_LEVEL5k:
16887
                {
16888
                    if (sigCtx->verify == 1) {
16889
                        ret = 0;
16890
                    }
16891
                    else {
16892
                        WOLFSSL_MSG("FALCON_LEVEL5 Verify didn't match");
16893
                        ret = ASN_SIG_CONFIRM_E;
16894
                        WOLFSSL_ERROR_VERBOSE(ret);
16895
                    }
16896
                    break;
16897
                }
16898
            #endif /* HAVE_FALCON */
16899
            #ifdef HAVE_DILITHIUM
16900
                case DILITHIUM_LEVEL2k:
16901
                {
16902
                    if (sigCtx->verify == 1) {
16903
                        ret = 0;
16904
                    }
16905
                    else {
16906
                        WOLFSSL_MSG("DILITHIUM_LEVEL2 Verify didn't match");
16907
                        ret = ASN_SIG_CONFIRM_E;
16908
                    }
16909
                    break;
16910
                }
16911
                case DILITHIUM_LEVEL3k:
16912
                {
16913
                    if (sigCtx->verify == 1) {
16914
                        ret = 0;
16915
                    }
16916
                    else {
16917
                        WOLFSSL_MSG("DILITHIUM_LEVEL3 Verify didn't match");
16918
                        ret = ASN_SIG_CONFIRM_E;
16919
                    }
16920
                    break;
16921
                }
16922
                case DILITHIUM_LEVEL5k:
16923
                {
16924
                    if (sigCtx->verify == 1) {
16925
                        ret = 0;
16926
                    }
16927
                    else {
16928
                        WOLFSSL_MSG("DILITHIUM_LEVEL5 Verify didn't match");
16929
                        ret = ASN_SIG_CONFIRM_E;
16930
                    }
16931
                    break;
16932
                }
16933
            #endif /* HAVE_DILITHIUM */
16934
            #ifdef HAVE_SPHINCS
16935
                case SPHINCS_FAST_LEVEL1k:
16936
                {
16937
                    if (sigCtx->verify == 1) {
16938
                        ret = 0;
16939
                    }
16940
                    else {
16941
                        WOLFSSL_MSG("SPHINCS_FAST_LEVEL1 Verify didn't match");
16942
                        ret = ASN_SIG_CONFIRM_E;
16943
                    }
16944
                    break;
16945
                }
16946
                case SPHINCS_FAST_LEVEL3k:
16947
                {
16948
                    if (sigCtx->verify == 1) {
16949
                        ret = 0;
16950
                    }
16951
                    else {
16952
                        WOLFSSL_MSG("SPHINCS_FAST_LEVEL3 Verify didn't match");
16953
                        ret = ASN_SIG_CONFIRM_E;
16954
                    }
16955
                    break;
16956
                }
16957
                case SPHINCS_FAST_LEVEL5k:
16958
                {
16959
                    if (sigCtx->verify == 1) {
16960
                        ret = 0;
16961
                    }
16962
                    else {
16963
                        WOLFSSL_MSG("SPHINCS_FAST_LEVEL5 Verify didn't match");
16964
                        ret = ASN_SIG_CONFIRM_E;
16965
                    }
16966
                    break;
16967
                }
16968
                case SPHINCS_SMALL_LEVEL1k:
16969
                {
16970
                    if (sigCtx->verify == 1) {
16971
                        ret = 0;
16972
                    }
16973
                    else {
16974
                        WOLFSSL_MSG("SPHINCS_SMALL_LEVEL1 Verify didn't match");
16975
                        ret = ASN_SIG_CONFIRM_E;
16976
                    }
16977
                    break;
16978
                }
16979
                case SPHINCS_SMALL_LEVEL3k:
16980
                {
16981
                    if (sigCtx->verify == 1) {
16982
                        ret = 0;
16983
                    }
16984
                    else {
16985
                        WOLFSSL_MSG("SPHINCS_SMALL_LEVEL3 Verify didn't match");
16986
                        ret = ASN_SIG_CONFIRM_E;
16987
                    }
16988
                    break;
16989
                }
16990
                case SPHINCS_SMALL_LEVEL5k:
16991
                {
16992
                    if (sigCtx->verify == 1) {
16993
                        ret = 0;
16994
                    }
16995
                    else {
16996
                        WOLFSSL_MSG("SPHINCS_SMALL_LEVEL5 Verify didn't match");
16997
                        ret = ASN_SIG_CONFIRM_E;
16998
                    }
16999
                    break;
17000
                }
17001
            #endif /* HAVE_SPHINCS */
17002
            #endif /* HAVE_PQC */
17003
0
                default:
17004
0
                    break;
17005
0
            }  /* switch (keyOID) */
17006
17007
0
            break;
17008
0
        } /* SIG_STATE_CHECK */
17009
17010
0
        default:
17011
0
            break;
17012
0
    } /* switch (sigCtx->state) */
17013
17014
0
exit_cs:
17015
17016
0
#endif /* !NO_ASN_CRYPT */
17017
17018
0
    (void)keyOID;
17019
0
    (void)sigOID;
17020
17021
0
    WOLFSSL_LEAVE("ConfirmSignature", ret);
17022
17023
#ifdef WOLFSSL_ASYNC_CRYPT
17024
    if (ret == WC_PENDING_E)
17025
        return ret;
17026
#endif
17027
17028
0
    FreeSignatureCtx(sigCtx);
17029
17030
0
    return ret;
17031
0
}
17032
17033
17034
#ifndef IGNORE_NAME_CONSTRAINTS
17035
17036
static int MatchBaseName(int type, const char* name, int nameSz,
17037
                         const char* base, int baseSz)
17038
0
{
17039
0
    if (base == NULL || baseSz <= 0 || name == NULL || nameSz <= 0 ||
17040
0
            name[0] == '.' || nameSz < baseSz ||
17041
0
            (type != ASN_RFC822_TYPE && type != ASN_DNS_TYPE &&
17042
0
             type != ASN_DIR_TYPE)) {
17043
0
        return 0;
17044
0
    }
17045
17046
0
    if (type == ASN_DIR_TYPE)
17047
0
        return XMEMCMP(name, base, (size_t)baseSz) == 0;
17048
17049
    /* If an email type, handle special cases where the base is only
17050
     * a domain, or is an email address itself. */
17051
0
    if (type == ASN_RFC822_TYPE) {
17052
0
        const char* p = NULL;
17053
0
        int count = 0;
17054
17055
0
        if (base[0] != '.') {
17056
0
            p = base;
17057
0
            count = 0;
17058
17059
            /* find the '@' in the base */
17060
0
            while (*p != '@' && count < baseSz) {
17061
0
                count++;
17062
0
                p++;
17063
0
            }
17064
17065
            /* No '@' in base, reset p to NULL */
17066
0
            if (count >= baseSz)
17067
0
                p = NULL;
17068
0
        }
17069
17070
0
        if (p == NULL) {
17071
            /* Base isn't an email address, it is a domain name,
17072
             * wind the name forward one character past its '@'. */
17073
0
            p = name;
17074
0
            count = 0;
17075
0
            while (*p != '@' && count < baseSz) {
17076
0
                count++;
17077
0
                p++;
17078
0
            }
17079
17080
0
            if (count < baseSz && *p == '@') {
17081
0
                name = p + 1;
17082
0
                nameSz -= count + 1;
17083
0
            }
17084
0
        }
17085
0
    }
17086
17087
    /* RFC 5280 section 4.2.1.10
17088
     * "...Any DNS name that can be constructed by simply adding zero or more
17089
     *  labels to the left-hand side of the name satisfies the name constraint."
17090
     * i.e www.host.example.com works for host.example.com name constraint and
17091
     * host1.example.com does not. */
17092
0
    if (type == ASN_DNS_TYPE || (type == ASN_RFC822_TYPE && base[0] == '.')) {
17093
0
        int szAdjust = nameSz - baseSz;
17094
0
        name += szAdjust;
17095
0
        nameSz -= szAdjust;
17096
0
    }
17097
17098
0
    while (nameSz > 0) {
17099
0
        if (XTOLOWER((unsigned char)*name++) !=
17100
0
                                               XTOLOWER((unsigned char)*base++))
17101
0
            return 0;
17102
0
        nameSz--;
17103
0
    }
17104
17105
0
    return 1;
17106
0
}
17107
17108
17109
/* Search through the list to find if the name is permitted.
17110
 * name     The DNS name to search for
17111
 * dnsList  The list to search through
17112
 * nameType Type of DNS name to currently searching
17113
 * return 1 if found in list or if not needed
17114
 * return 0 if not found in the list but is needed
17115
 */
17116
static int PermittedListOk(DNS_entry* name, Base_entry* dnsList, byte nameType)
17117
0
{
17118
0
    Base_entry* current = dnsList;
17119
0
    int match = 0;
17120
0
    int need  = 0;
17121
0
    int ret   = 1; /* is ok unless needed and no match found */
17122
17123
0
    while (current != NULL) {
17124
0
        if (current->type == nameType) {
17125
0
            need = 1; /* restriction on permitted names is set for this type */
17126
0
            if (name->len >= current->nameSz &&
17127
0
                MatchBaseName(nameType, name->name, name->len,
17128
0
                              current->name, current->nameSz)) {
17129
0
                match = 1; /* found the current name in the permitted list*/
17130
0
                break;
17131
0
            }
17132
0
        }
17133
0
        current = current->next;
17134
0
    }
17135
17136
    /* check if permitted name restriction was set and no matching name found */
17137
0
    if (need && !match)
17138
0
        ret = 0;
17139
17140
0
    return ret;
17141
0
}
17142
17143
17144
/* Search through the list to find if the name is excluded.
17145
 * name     The DNS name to search for
17146
 * dnsList  The list to search through
17147
 * nameType Type of DNS name to currently searching
17148
 * return 1 if found in list and 0 if not found in the list
17149
 */
17150
static int IsInExcludedList(DNS_entry* name, Base_entry* dnsList, byte nameType)
17151
0
{
17152
0
    int ret = 0; /* default of not found in the list */
17153
0
    Base_entry* current = dnsList;
17154
17155
0
    while (current != NULL) {
17156
0
        if (current->type == nameType) {
17157
0
            if (name->len >= current->nameSz &&
17158
0
                MatchBaseName(nameType, name->name, name->len,
17159
0
                              current->name, current->nameSz)) {
17160
0
                ret = 1;
17161
0
                break;
17162
0
            }
17163
0
        }
17164
0
        current = current->next;
17165
0
    }
17166
17167
0
    return ret;
17168
0
}
17169
17170
17171
static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
17172
0
{
17173
0
    const byte nameTypes[] = {ASN_RFC822_TYPE, ASN_DNS_TYPE, ASN_DIR_TYPE};
17174
0
    int i;
17175
17176
0
    if (signer == NULL || cert == NULL)
17177
0
        return 0;
17178
17179
0
    if (signer->excludedNames == NULL && signer->permittedNames == NULL)
17180
0
        return 1;
17181
17182
0
    for (i=0; i < (int)sizeof(nameTypes); i++) {
17183
0
        byte nameType = nameTypes[i];
17184
0
        DNS_entry* name = NULL;
17185
0
        DNS_entry  subjectDnsName; /* temporary node used for subject name */
17186
17187
0
        XMEMSET(&subjectDnsName, 0, sizeof(DNS_entry));
17188
0
        switch (nameType) {
17189
0
            case ASN_DNS_TYPE:
17190
                /* Should it also consider CN in subject? It could use
17191
                 * subjectDnsName too */
17192
0
                name = cert->altNames;
17193
0
                break;
17194
0
            case ASN_RFC822_TYPE:
17195
                /* Shouldn't it validade E= in subject as well? */
17196
0
                name = cert->altEmailNames;
17197
17198
                /* Add subject email for checking. */
17199
0
                if (cert->subjectEmail != NULL) {
17200
                    /* RFC 5280 section 4.2.1.10
17201
                     * "When constraints are imposed on the rfc822Name name
17202
                     * form, but the certificate does not include a subject
17203
                     * alternative name, the rfc822Name constraint MUST be
17204
                     * applied to the attribute of type emailAddress in the
17205
                     * subject distinguished name" */
17206
0
                    subjectDnsName.next = NULL;
17207
0
                    subjectDnsName.type = ASN_RFC822_TYPE;
17208
0
                    subjectDnsName.len  = cert->subjectEmailLen;
17209
0
                    subjectDnsName.name = (char *)cert->subjectEmail;
17210
0
                }
17211
0
                break;
17212
0
            case ASN_DIR_TYPE:
17213
0
            #ifndef WOLFSSL_NO_ASN_STRICT
17214
0
                name = cert->altDirNames;
17215
0
            #endif
17216
17217
                /* RFC 5280 section 4.2.1.10
17218
                    "Restrictions of the form directoryName MUST be
17219
                    applied to the subject field .... and to any names
17220
                    of type directoryName in the subjectAltName
17221
                    extension"
17222
                */
17223
0
                if (cert->subjectRaw != NULL) {
17224
0
                    subjectDnsName.next = NULL;
17225
0
                    subjectDnsName.type = ASN_DIR_TYPE;
17226
0
                    subjectDnsName.len = cert->subjectRawLen;
17227
0
                    subjectDnsName.name = (char *)cert->subjectRaw;
17228
0
                }
17229
0
                break;
17230
0
            default:
17231
                /* Other types of names are ignored for now.
17232
                 * Shouldn't it be rejected if it there is a altNamesByType[nameType]
17233
                 * and signer->extNameConstraintCrit is set? */
17234
0
                return 0;
17235
0
        }
17236
17237
0
        while (name != NULL) {
17238
0
            if (IsInExcludedList(name, signer->excludedNames, nameType) == 1) {
17239
0
                WOLFSSL_MSG("Excluded name was found!");
17240
0
                return 0;
17241
0
            }
17242
17243
            /* Check against the permitted list */
17244
0
            if (PermittedListOk(name, signer->permittedNames, nameType) != 1) {
17245
0
                WOLFSSL_MSG("Permitted name was not found!");
17246
0
                return 0;
17247
0
            }
17248
17249
0
            name = name->next;
17250
0
        }
17251
17252
        /* handle comparing against subject name too */
17253
0
        if (subjectDnsName.len > 0 && subjectDnsName.name != NULL) {
17254
0
            if (IsInExcludedList(&subjectDnsName, signer->excludedNames,
17255
0
                        nameType) == 1) {
17256
0
                WOLFSSL_MSG("Excluded name was found!");
17257
0
                return 0;
17258
0
            }
17259
17260
            /* Check against the permitted list */
17261
0
            if (PermittedListOk(&subjectDnsName, signer->permittedNames,
17262
0
                        nameType) != 1) {
17263
0
                WOLFSSL_MSG("Permitted name was not found!");
17264
0
                return 0;
17265
0
            }
17266
0
        }
17267
0
    }
17268
17269
0
    return 1;
17270
0
}
17271
17272
#endif /* IGNORE_NAME_CONSTRAINTS */
17273
17274
#ifndef WOLFSSL_ASN_TEMPLATE
17275
static void AddAltName(DecodedCert* cert, DNS_entry* dnsEntry)
17276
{
17277
#if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_ALT_NAMES_NO_REV)
17278
    dnsEntry->next = NULL;
17279
    if (cert->altNames == NULL) {
17280
        /* First on list */
17281
        cert->altNames = dnsEntry;
17282
    }
17283
    else {
17284
        DNS_entry* temp = cert->altNames;
17285
17286
        /* Find end */
17287
        for (; (temp->next != NULL); temp = temp->next);
17288
17289
        /* Add to end */
17290
        temp->next = dnsEntry;
17291
    }
17292
#else
17293
    dnsEntry->next = cert->altNames;
17294
    cert->altNames = dnsEntry;
17295
#endif
17296
}
17297
#endif
17298
17299
#ifdef WOLFSSL_ASN_TEMPLATE
17300
#if defined(WOLFSSL_SEP) || defined(WOLFSSL_FPKI)
17301
/* ASN.1 template for OtherName of an X.509 certificate.
17302
 * X.509: RFC 5280, 4.2.1.6 - OtherName (without implicit outer SEQUENCE).
17303
 * HW Name: RFC 4108, 5 - Hardware Module Name
17304
 * Only support HW Name where the type is a HW serial number.
17305
 *
17306
 * Other Names handled for FPKI (Federal PKI) use:
17307
 * UPN (Universal Principal Name), a non-standard Other Name
17308
 *  (RFC3280 sec 4.2.1.7). Often used with FIPS 201 smartcard login.
17309
 * FASC-N (Federal Agency Smart Credential Number), defined in the document
17310
 *  fpki-x509-cert-policy-common.pdf. Used for a smart card ID.
17311
 */
17312
static const ASNItem otherNameASN[] = {
17313
/* TYPEID   */ { 0, ASN_OBJECT_ID, 0, 0, 0 },
17314
/* VALUE    */ { 0, ASN_CONTEXT_SPECIFIC | ASN_OTHERNAME_VALUE, 1, 1, 0 },
17315
/* UPN      */     { 1, ASN_UTF8STRING, 0, 0, 2 },
17316
/* FASC-N   */     { 1, ASN_OCTET_STRING, 0, 0, 2 },
17317
/* HWN_SEQ  */     { 1, ASN_SEQUENCE, 1, 0, 2 },
17318
/* HWN_TYPE */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
17319
/* HWN_NUM  */         { 2, ASN_OCTET_STRING, 0, 0, 0 }
17320
};
17321
enum {
17322
    OTHERNAMEASN_IDX_TYPEID = 0,
17323
    OTHERNAMEASN_IDX_VALUE,
17324
    OTHERNAMEASN_IDX_UPN,
17325
    OTHERNAMEASN_IDX_FASCN,
17326
    OTHERNAMEASN_IDX_HWN_SEQ,
17327
    OTHERNAMEASN_IDX_HWN_TYPE,
17328
    OTHERNAMEASN_IDX_HWN_NUM
17329
};
17330
17331
/* Number of items in ASN.1 template for OtherName of an X.509 certificate. */
17332
#define otherNameASN_Length (sizeof(otherNameASN) / sizeof(ASNItem))
17333
17334
#ifdef WOLFSSL_SEP
17335
static int DecodeSEP(ASNGetData* dataASN, DecodedCert* cert)
17336
{
17337
    int ret = 0;
17338
    word32 oidLen, serialLen;
17339
17340
    oidLen = dataASN[OTHERNAMEASN_IDX_HWN_TYPE].data.oid.length;
17341
    serialLen = dataASN[OTHERNAMEASN_IDX_HWN_NUM].data.ref.length;
17342
17343
    /* Allocate space for HW type OID. */
17344
    cert->hwType = (byte*)XMALLOC(oidLen, cert->heap,
17345
                                  DYNAMIC_TYPE_X509_EXT);
17346
    if (cert->hwType == NULL)
17347
        ret = MEMORY_E;
17348
17349
    if (ret == 0) {
17350
        /* Copy, into cert HW type OID */
17351
        XMEMCPY(cert->hwType,
17352
                dataASN[OTHERNAMEASN_IDX_HWN_TYPE].data.oid.data, oidLen);
17353
        cert->hwTypeSz = (int)oidLen;
17354
        /* TODO: check this is the HW serial number OID - no test data. */
17355
17356
        /* Allocate space for HW serial number, +1 for null terminator. */
17357
        cert->hwSerialNum = (byte*)XMALLOC(serialLen + 1, cert->heap,
17358
                                           DYNAMIC_TYPE_X509_EXT);
17359
        if (cert->hwSerialNum == NULL) {
17360
            WOLFSSL_MSG("\tOut of Memory");
17361
            ret = MEMORY_E;
17362
        }
17363
    }
17364
    if (ret == 0) {
17365
        /* Copy into cert HW serial number. */
17366
        XMEMCPY(cert->hwSerialNum,
17367
                dataASN[OTHERNAMEASN_IDX_HWN_NUM].data.ref.data, serialLen);
17368
        cert->hwSerialNum[serialLen] = '\0';
17369
        cert->hwSerialNumSz = (int)serialLen;
17370
    }
17371
    return ret;
17372
}
17373
#endif /* WOLFSSL_SEP */
17374
17375
static int DecodeOtherHelper(ASNGetData* dataASN, DecodedCert* cert, int oid)
17376
{
17377
    DNS_entry* entry = NULL;
17378
    int ret = 0;
17379
    word32 bufLen   = 0;
17380
    const char* buf = NULL;
17381
17382
    switch (oid) {
17383
#ifdef WOLFSSL_FPKI
17384
        case FASCN_OID:
17385
            bufLen = dataASN[OTHERNAMEASN_IDX_FASCN].data.ref.length;
17386
            buf    = (const char*)dataASN[OTHERNAMEASN_IDX_FASCN].data.ref.data;
17387
            break;
17388
#endif /* WOLFSSL_FPKI */
17389
        case UPN_OID:
17390
            bufLen = dataASN[OTHERNAMEASN_IDX_UPN].data.ref.length;
17391
            buf    = (const char*)dataASN[OTHERNAMEASN_IDX_UPN].data.ref.data;
17392
            break;
17393
        default:
17394
            WOLFSSL_ERROR_VERBOSE(ASN_UNKNOWN_OID_E);
17395
            ret = ASN_UNKNOWN_OID_E;
17396
            break;
17397
    }
17398
17399
    if (ret == 0) {
17400
        ret = SetDNSEntry(cert, buf, (int)bufLen, ASN_OTHER_TYPE, &entry);
17401
        if (ret == 0) {
17402
        #ifdef WOLFSSL_FPKI
17403
            entry->oidSum = oid;
17404
        #endif
17405
            AddDNSEntryToList(&cert->altNames, entry);
17406
        }
17407
    }
17408
    return ret;
17409
}
17410
17411
/* Decode data with OtherName format from after implicit SEQUENCE.
17412
 *
17413
 * @param [in, out] cert      Certificate object.
17414
 * @param [in]      input     Buffer containing encoded OtherName.
17415
 * @param [in, out] inOutIdx  On in, the index of the start of the OtherName.
17416
 *                            On out, index after OtherName.
17417
 * @param [in]      maxIdx    Maximum index of data in buffer.
17418
 * @return  0 on success.
17419
 * @return  MEMORY_E on dynamic memory allocation failure.
17420
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
17421
 *          is invalid.
17422
 * @return  ASN_PARSE_E when OID does is not HW Name.
17423
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
17424
 * @return  BUFFER_E when data in buffer is too small.
17425
 */
17426
static int DecodeOtherName(DecodedCert* cert, const byte* input,
17427
                           word32* inOutIdx, word32 maxIdx)
17428
{
17429
    DECL_ASNGETDATA(dataASN, otherNameASN_Length);
17430
    int ret = 0;
17431
17432
    CALLOC_ASNGETDATA(dataASN, otherNameASN_Length, ret, cert->heap);
17433
17434
    if (ret == 0) {
17435
        /* Check the first OID is a recognized Alt Cert Name type. */
17436
        GetASN_OID(&dataASN[OTHERNAMEASN_IDX_TYPEID], oidCertAltNameType);
17437
        /* Parse OtherName. */
17438
        ret = GetASN_Items(otherNameASN, dataASN, otherNameASN_Length, 1, input,
17439
                           inOutIdx, maxIdx);
17440
    }
17441
    if (ret == 0) {
17442
        /* Ensure expected OID. */
17443
        switch (dataASN[OTHERNAMEASN_IDX_TYPEID].data.oid.sum) {
17444
        #ifdef WOLFSSL_SEP
17445
            case HW_NAME_OID:
17446
                /* Only support HW serial number. */
17447
                GetASN_OID(&dataASN[OTHERNAMEASN_IDX_HWN_TYPE], oidIgnoreType);
17448
                ret = DecodeSEP(dataASN, cert);
17449
                break;
17450
        #endif /* WOLFSSL_SEP */
17451
        #ifdef WOLFSSL_FPKI
17452
            case FASCN_OID:
17453
        #endif /* WOLFSSL_FPKI */
17454
            case UPN_OID:
17455
                ret = DecodeOtherHelper(dataASN, cert,
17456
                           (int)dataASN[OTHERNAMEASN_IDX_TYPEID].data.oid.sum);
17457
                break;
17458
            default:
17459
                WOLFSSL_MSG("\tunsupported OID skipping");
17460
                break;
17461
        }
17462
    }
17463
17464
    FREE_ASNGETDATA(dataASN, cert->heap);
17465
    return ret;
17466
}
17467
#endif /* WOLFSSL_SEP || WOLFSSL_FPKI */
17468
17469
/* Decode a GeneralName.
17470
 *
17471
 * @param [in]      input     Buffer containing encoded OtherName.
17472
 * @param [in, out] inOutIdx  On in, the index of the start of the OtherName.
17473
 *                            On out, index after OtherName.
17474
 * @param [in]      len       Length of data in buffer.
17475
 * @param [in]      cert      Decoded certificate object.
17476
 * @return  0 on success.
17477
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
17478
 *          is invalid.
17479
 * @return  BUFFER_E when data in buffer is too small.
17480
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
17481
 * @return  MEMORY_E when dynamic memory allocation fails.
17482
 */
17483
static int DecodeGeneralName(const byte* input, word32* inOutIdx, byte tag,
17484
                             int len, DecodedCert* cert)
17485
0
{
17486
0
    int ret = 0;
17487
0
    word32 idx = *inOutIdx;
17488
17489
    /* GeneralName choice: dnsName */
17490
0
    if (tag == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) {
17491
0
        ret = SetDNSEntry(cert, (const char*)(input + idx), len, ASN_DNS_TYPE,
17492
0
                &cert->altNames);
17493
0
        if (ret == 0) {
17494
0
            idx += (word32)len;
17495
0
        }
17496
0
    }
17497
0
#ifndef IGNORE_NAME_CONSTRAINTS
17498
    /* GeneralName choice: directoryName */
17499
0
    else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_DIR_TYPE)) {
17500
0
        int strLen;
17501
0
        word32 idxDir = idx;
17502
17503
        /* Expecting a SEQUENCE using up all data. */
17504
0
        if (GetASN_Sequence(input, &idxDir, &strLen, idx + (word32)len, 1) < 0)
17505
0
        {
17506
0
            WOLFSSL_MSG("\tfail: seq length");
17507
0
            return ASN_PARSE_E;
17508
0
        }
17509
17510
0
        ret = SetDNSEntry(cert, (const char*)(input + idxDir), strLen,
17511
0
                ASN_DIR_TYPE, &cert->altDirNames);
17512
0
        if (ret == 0) {
17513
0
            idx += (word32)len;
17514
0
        }
17515
0
    }
17516
    /* GeneralName choice: rfc822Name */
17517
0
    else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE)) {
17518
0
        ret = SetDNSEntry(cert, (const char*)(input + idx), len,
17519
0
                ASN_RFC822_TYPE, &cert->altEmailNames);
17520
0
        if (ret == 0) {
17521
0
            idx += (word32)len;
17522
0
        }
17523
0
    }
17524
    /* GeneralName choice: uniformResourceIdentifier */
17525
0
    else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_URI_TYPE)) {
17526
0
        WOLFSSL_MSG("\tPutting URI into list but not using");
17527
17528
0
    #if !defined(WOLFSSL_NO_ASN_STRICT) && !defined(WOLFSSL_FPKI)
17529
        /* Verify RFC 5280 Sec 4.2.1.6 rule:
17530
            "The name MUST NOT be a relative URI"
17531
            As per RFC 3986 Sec 4.3, an absolute URI is only required to contain
17532
            a scheme and hier-part.  So the only strict requirement is a ':'
17533
            being present after the scheme.  If a '/' is present as part of the
17534
            hier-part, it must come after the ':' (see RFC 3986 Sec 3). */
17535
0
        {
17536
0
            int i;
17537
17538
            /* skip past scheme (i.e http,ftp,...) finding first ':' char */
17539
0
            for (i = 0; i < len; i++) {
17540
0
                if (input[idx + (word32)i] == ':') {
17541
0
                    break;
17542
0
                }
17543
0
                if (input[idx + (word32)i] == '/') {
17544
0
                    i = len; /* error, found relative path since '/' was
17545
                              * encountered before ':'. Returning error
17546
                              * value in next if statement. */
17547
0
                }
17548
0
            }
17549
17550
            /* test hier-part is empty */
17551
0
            if (i == 0 || i == len) {
17552
0
                WOLFSSL_MSG("\tEmpty or malformed URI");
17553
0
                WOLFSSL_ERROR_VERBOSE(ASN_ALT_NAME_E);
17554
0
                return ASN_ALT_NAME_E;
17555
0
            }
17556
17557
            /* test if scheme is missing  */
17558
0
            if (input[idx + (word32)i] != ':') {
17559
0
                WOLFSSL_MSG("\tAlt Name must be absolute URI");
17560
0
                WOLFSSL_ERROR_VERBOSE(ASN_ALT_NAME_E);
17561
0
                return ASN_ALT_NAME_E;
17562
0
            }
17563
0
        }
17564
0
    #endif
17565
17566
0
        ret = SetDNSEntry(cert, (const char*)(input + idx), len, ASN_URI_TYPE,
17567
0
                &cert->altNames);
17568
0
        if (ret == 0) {
17569
0
            idx += (word32)len;
17570
0
        }
17571
0
    }
17572
    #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || \
17573
                                            defined(WOLFSSL_IP_ALT_NAME)
17574
    /* GeneralName choice: iPAddress */
17575
    else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_IP_TYPE)) {
17576
        ret = SetDNSEntry(cert, (const char*)(input + idx), len, ASN_IP_TYPE,
17577
                &cert->altNames);
17578
        if (ret == 0) {
17579
            idx += (word32)len;
17580
        }
17581
    }
17582
    #endif /* WOLFSSL_QT || OPENSSL_ALL */
17583
0
#endif /* IGNORE_NAME_CONSTRAINTS */
17584
#if defined(WOLFSSL_SEP) || defined(WOLFSSL_FPKI)
17585
    /* GeneralName choice: otherName */
17586
    else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE)) {
17587
        /* TODO: test data for code path */
17588
        ret = DecodeOtherName(cert, input, &idx, idx + (word32)len);
17589
    }
17590
#endif
17591
    /* GeneralName choice: dNSName, x400Address, ediPartyName,
17592
     *                     registeredID */
17593
0
    else {
17594
0
        WOLFSSL_MSG("\tUnsupported name type, skipping");
17595
0
        idx += (word32)len;
17596
0
    }
17597
17598
0
    if (ret == 0) {
17599
        /* Return index of next encoded byte. */
17600
0
        *inOutIdx = idx;
17601
0
    }
17602
0
    return ret;
17603
0
}
17604
17605
/* ASN.1 choices for GeneralName.
17606
 * X.509: RFC 5280, 4.2.1.6 - GeneralName.
17607
 */
17608
static const byte generalNameChoice[] = {
17609
    ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0,
17610
    ASN_CONTEXT_SPECIFIC                   | 1,
17611
    ASN_CONTEXT_SPECIFIC                   | 2,
17612
    ASN_CONTEXT_SPECIFIC                   | 3,
17613
    ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 4,
17614
    ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 5,
17615
    ASN_CONTEXT_SPECIFIC                   | 6,
17616
    ASN_CONTEXT_SPECIFIC                   | 7,
17617
    ASN_CONTEXT_SPECIFIC                   | 8,
17618
    0
17619
};
17620
17621
/* ASN.1 template for GeneralName.
17622
 * X.509: RFC 5280, 4.2.1.6 - GeneralName.
17623
 */
17624
static const ASNItem altNameASN[] = {
17625
    { 0, ASN_CONTEXT_SPECIFIC | 0, 0, 1, 0 }
17626
};
17627
enum {
17628
    ALTNAMEASN_IDX_GN = 0
17629
};
17630
17631
/* Number of items in ASN.1 template for GeneralName. */
17632
0
#define altNameASN_Length (sizeof(altNameASN) / sizeof(ASNItem))
17633
#endif /* WOLFSSL_ASN_TEMPLATE */
17634
17635
#if defined(WOLFSSL_SEP) && !defined(WOLFSSL_ASN_TEMPLATE)
17636
/* return 0 on success */
17637
static int DecodeSepHwAltName(DecodedCert* cert, const byte* input,
17638
    word32* idxIn, word32 sz)
17639
{
17640
    word32 idx = *idxIn;
17641
    int  strLen;
17642
    int  ret;
17643
    byte tag;
17644
17645
    /* Certificates issued with this OID in the subject alt name are for
17646
     * verifying signatures created on a module.
17647
     * RFC 4108 Section 5. */
17648
    if (cert->hwType != NULL) {
17649
        WOLFSSL_MSG("\tAlready seen Hardware Module Name");
17650
        return ASN_PARSE_E;
17651
    }
17652
17653
    if (GetASNTag(input, &idx, &tag, sz) < 0) {
17654
        return ASN_PARSE_E;
17655
    }
17656
17657
    if (tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
17658
        WOLFSSL_MSG("\twrong type");
17659
        return ASN_PARSE_E;
17660
    }
17661
17662
    if (GetLength(input, &idx, &strLen, sz) < 0) {
17663
        WOLFSSL_MSG("\tfail: str len");
17664
        return ASN_PARSE_E;
17665
    }
17666
17667
    if (GetSequence(input, &idx, &strLen, sz) < 0) {
17668
        WOLFSSL_MSG("\tBad Sequence");
17669
        return ASN_PARSE_E;
17670
    }
17671
17672
    ret = GetASNObjectId(input, &idx, &strLen, sz);
17673
    if (ret != 0) {
17674
        WOLFSSL_MSG("\tbad OID");
17675
        return ret;
17676
    }
17677
17678
    cert->hwType = (byte*)XMALLOC((size_t)strLen, cert->heap,
17679
                                  DYNAMIC_TYPE_X509_EXT);
17680
    if (cert->hwType == NULL) {
17681
        WOLFSSL_MSG("\tOut of Memory");
17682
        return MEMORY_E;
17683
    }
17684
17685
    XMEMCPY(cert->hwType, &input[idx], (size_t)strLen);
17686
    cert->hwTypeSz = strLen;
17687
    idx += (word32)strLen;
17688
17689
    ret = GetOctetString(input, &idx, &strLen, sz);
17690
    if (ret < 0) {
17691
        XFREE(cert->hwType, cert->heap, DYNAMIC_TYPE_X509_EXT);
17692
        cert->hwType = NULL;
17693
        return ret;
17694
    }
17695
17696
    cert->hwSerialNum = (byte*)XMALLOC((size_t)strLen + 1, cert->heap,
17697
                                       DYNAMIC_TYPE_X509_EXT);
17698
    if (cert->hwSerialNum == NULL) {
17699
        WOLFSSL_MSG("\tOut of Memory");
17700
        XFREE(cert->hwType, cert->heap, DYNAMIC_TYPE_X509_EXT);
17701
        cert->hwType = NULL;
17702
        return MEMORY_E;
17703
    }
17704
17705
    XMEMCPY(cert->hwSerialNum, &input[idx], (size_t)strLen);
17706
    cert->hwSerialNum[strLen] = '\0';
17707
    cert->hwSerialNumSz = strLen;
17708
    idx += (word32)strLen;
17709
17710
    *idxIn = idx;
17711
    return 0;
17712
}
17713
#endif /* WOLFSSL_SEP */
17714
17715
#if !defined(WOLFSSL_ASN_TEMPLATE)
17716
/* return 0 on success */
17717
static int DecodeConstructedOtherName(DecodedCert* cert, const byte* input,
17718
        word32* idx, word32 sz, int oid)
17719
{
17720
    int ret    = 0;
17721
    int strLen = 0;
17722
    byte tag;
17723
    DNS_entry* dnsEntry = NULL;
17724
17725
    if (GetASNTag(input, idx, &tag, sz) < 0) {
17726
        ret = ASN_PARSE_E;
17727
    }
17728
17729
    if (ret == 0 && (tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))) {
17730
        ret = ASN_PARSE_E;
17731
    }
17732
17733
    if (ret == 0 && (GetLength(input, idx, &strLen, sz) < 0)) {
17734
        ret = ASN_PARSE_E;
17735
    }
17736
17737
    if (ret == 0) {
17738
        dnsEntry = AltNameNew(cert->heap);
17739
        if (dnsEntry == NULL) {
17740
            WOLFSSL_MSG("\tOut of Memory");
17741
            return MEMORY_E;
17742
        }
17743
17744
        switch (oid) {
17745
        #ifdef WOLFSSL_FPKI
17746
            case FASCN_OID:
17747
                ret = GetOctetString(input, idx, &strLen, sz);
17748
                if (ret > 0) {
17749
                    ret = 0;
17750
                }
17751
                break;
17752
        #endif /* WOLFSSL_FPKI */
17753
            case UPN_OID:
17754
                if (GetASNTag(input, idx, &tag, sz) < 0) {
17755
                    ret = ASN_PARSE_E;
17756
                }
17757
17758
                if (ret == 0 &&
17759
                        tag != ASN_PRINTABLE_STRING && tag != ASN_UTF8STRING &&
17760
                                    tag != ASN_IA5_STRING) {
17761
                    WOLFSSL_MSG("Was expecting a string for UPN");
17762
                    ret = ASN_PARSE_E;
17763
                }
17764
17765
                if (ret == 0 && (GetLength(input, idx, &strLen, sz) < 0)) {
17766
                    WOLFSSL_MSG("Was expecting a string for UPN");
17767
                    ret = ASN_PARSE_E;
17768
                }
17769
                break;
17770
17771
            default:
17772
                WOLFSSL_MSG("Unknown constructed other name, skipping");
17773
                XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
17774
                dnsEntry = NULL;
17775
        }
17776
    }
17777
17778
    if (ret == 0 && dnsEntry != NULL) {
17779
        dnsEntry->type = ASN_OTHER_TYPE;
17780
        dnsEntry->len = strLen;
17781
        dnsEntry->name = (char*)XMALLOC((size_t)strLen + 1, cert->heap,
17782
            DYNAMIC_TYPE_ALTNAME);
17783
    #ifdef WOLFSSL_FPKI
17784
        dnsEntry->oidSum = oid;
17785
    #endif /* WOLFSSL_FPKI */
17786
        if (dnsEntry->name == NULL) {
17787
            WOLFSSL_MSG("\tOut of Memory");
17788
            ret = MEMORY_E;
17789
        }
17790
        else {
17791
            XMEMCPY(dnsEntry->name, &input[*idx], (size_t)strLen);
17792
            dnsEntry->name[strLen] = '\0';
17793
            AddAltName(cert, dnsEntry);
17794
        }
17795
    }
17796
17797
    if (ret == 0) {
17798
        *idx += (word32)strLen;
17799
    }
17800
    else {
17801
        XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
17802
    }
17803
17804
    return ret;
17805
}
17806
#endif
17807
17808
/* Decode subject alternative names extension.
17809
 *
17810
 * RFC 5280 4.2.1.6.  Subject Alternative Name
17811
 *
17812
 * @param [in]      input  Buffer holding encoded data.
17813
 * @param [in]      sz     Size of encoded data in bytes.
17814
 * @param [in, out] cert   Decoded certificate object.
17815
 * @return  0 on success.
17816
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
17817
 *          is invalid.
17818
 * @return  BUFFER_E when data in buffer is too small.
17819
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
17820
 * @return  MEMORY_E when dynamic memory allocation fails.
17821
 */
17822
static int DecodeAltNames(const byte* input, word32 sz, DecodedCert* cert)
17823
0
{
17824
#ifndef WOLFSSL_ASN_TEMPLATE
17825
    word32 idx = 0;
17826
    int length = 0;
17827
17828
    WOLFSSL_ENTER("DecodeAltNames");
17829
17830
    if (GetSequence(input, &idx, &length, sz) < 0) {
17831
        WOLFSSL_MSG("\tBad Sequence");
17832
        return ASN_PARSE_E;
17833
    }
17834
17835
    if (length == 0) {
17836
        /* RFC 5280 4.2.1.6.  Subject Alternative Name
17837
           If the subjectAltName extension is present, the sequence MUST
17838
           contain at least one entry. */
17839
        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
17840
        return ASN_PARSE_E;
17841
    }
17842
17843
#ifdef OPENSSL_ALL
17844
    cert->extSubjAltNameSrc = input;
17845
    cert->extSubjAltNameSz = sz;
17846
#endif
17847
17848
    cert->weOwnAltNames = 1;
17849
17850
    while (length > 0) {
17851
        byte current_byte;
17852
17853
        /* Verify idx can't overflow input buffer */
17854
        if (idx >= (word32)sz) {
17855
            WOLFSSL_MSG("\tBad Index");
17856
            return BUFFER_E;
17857
        }
17858
17859
        current_byte = input[idx++];
17860
17861
        length--;
17862
17863
        /* Save DNS Type names in the altNames list. */
17864
        /* Save Other Type names in the cert's OidMap */
17865
        if (current_byte == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) {
17866
            DNS_entry* dnsEntry;
17867
            int strLen;
17868
            word32 lenStartIdx = idx;
17869
17870
            if (GetLength(input, &idx, &strLen, sz) < 0) {
17871
                WOLFSSL_MSG("\tfail: str length");
17872
                return ASN_PARSE_E;
17873
            }
17874
            length -= (int)(idx - lenStartIdx);
17875
17876
            dnsEntry = AltNameNew(cert->heap);
17877
            if (dnsEntry == NULL) {
17878
                WOLFSSL_MSG("\tOut of Memory");
17879
                return MEMORY_E;
17880
            }
17881
17882
            dnsEntry->type = ASN_DNS_TYPE;
17883
            dnsEntry->name = (char*)XMALLOC((size_t)strLen + 1, cert->heap,
17884
                                         DYNAMIC_TYPE_ALTNAME);
17885
            if (dnsEntry->name == NULL) {
17886
                WOLFSSL_MSG("\tOut of Memory");
17887
                XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
17888
                return MEMORY_E;
17889
            }
17890
            dnsEntry->len = strLen;
17891
            XMEMCPY(dnsEntry->name, &input[idx], (size_t)strLen);
17892
            dnsEntry->name[strLen] = '\0';
17893
17894
            AddAltName(cert, dnsEntry);
17895
17896
            length -= strLen;
17897
            idx    += (word32)strLen;
17898
        }
17899
    #ifndef IGNORE_NAME_CONSTRAINTS
17900
        else if (current_byte ==
17901
                (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_DIR_TYPE)) {
17902
            DNS_entry* dirEntry;
17903
            int strLen;
17904
            word32 lenStartIdx = idx;
17905
17906
            if (GetLength(input, &idx, &strLen, sz) < 0) {
17907
                WOLFSSL_MSG("\tfail: str length");
17908
                return ASN_PARSE_E;
17909
            }
17910
17911
            if (GetSequence(input, &idx, &strLen, sz) < 0) {
17912
                WOLFSSL_MSG("\tfail: seq length");
17913
                return ASN_PARSE_E;
17914
            }
17915
            length -= (int)(idx - lenStartIdx);
17916
17917
            dirEntry = AltNameNew(cert->heap);
17918
            if (dirEntry == NULL) {
17919
                WOLFSSL_MSG("\tOut of Memory");
17920
                return MEMORY_E;
17921
            }
17922
17923
            dirEntry->type = ASN_DIR_TYPE;
17924
            dirEntry->name = (char*)XMALLOC((size_t)strLen + 1, cert->heap,
17925
                                         DYNAMIC_TYPE_ALTNAME);
17926
            if (dirEntry->name == NULL) {
17927
                WOLFSSL_MSG("\tOut of Memory");
17928
                XFREE(dirEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
17929
                return MEMORY_E;
17930
            }
17931
            dirEntry->len = strLen;
17932
            XMEMCPY(dirEntry->name, &input[idx], (size_t)strLen);
17933
            dirEntry->name[strLen] = '\0';
17934
            dirEntry->next = cert->altDirNames;
17935
            cert->altDirNames = dirEntry;
17936
17937
            length -= strLen;
17938
            idx    += (word32)strLen;
17939
        }
17940
        else if (current_byte == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE)) {
17941
            DNS_entry* emailEntry;
17942
            int strLen;
17943
            word32 lenStartIdx = idx;
17944
17945
            if (GetLength(input, &idx, &strLen, sz) < 0) {
17946
                WOLFSSL_MSG("\tfail: str length");
17947
                return ASN_PARSE_E;
17948
            }
17949
            length -= (int)(idx - lenStartIdx);
17950
17951
            emailEntry = AltNameNew(cert->heap);
17952
            if (emailEntry == NULL) {
17953
                WOLFSSL_MSG("\tOut of Memory");
17954
                return MEMORY_E;
17955
            }
17956
17957
            emailEntry->type = ASN_RFC822_TYPE;
17958
            emailEntry->name = (char*)XMALLOC((size_t)strLen + 1, cert->heap,
17959
                                         DYNAMIC_TYPE_ALTNAME);
17960
            if (emailEntry->name == NULL) {
17961
                WOLFSSL_MSG("\tOut of Memory");
17962
                XFREE(emailEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
17963
                return MEMORY_E;
17964
            }
17965
            emailEntry->len = strLen;
17966
            XMEMCPY(emailEntry->name, &input[idx], (size_t)strLen);
17967
            emailEntry->name[strLen] = '\0';
17968
17969
            emailEntry->next = cert->altEmailNames;
17970
            cert->altEmailNames = emailEntry;
17971
17972
            length -= strLen;
17973
            idx    += (word32)strLen;
17974
        }
17975
        else if (current_byte == (ASN_CONTEXT_SPECIFIC | ASN_URI_TYPE)) {
17976
            DNS_entry* uriEntry;
17977
            int strLen;
17978
            word32 lenStartIdx = idx;
17979
17980
            WOLFSSL_MSG("\tPutting URI into list but not using");
17981
            if (GetLength(input, &idx, &strLen, sz) < 0) {
17982
                WOLFSSL_MSG("\tfail: str length");
17983
                return ASN_PARSE_E;
17984
            }
17985
            length -= (int)(idx - lenStartIdx);
17986
17987
            /* check that strLen at index is not past input buffer */
17988
            if ((word32)strLen + idx > sz) {
17989
                return BUFFER_E;
17990
            }
17991
17992
        #if !defined(WOLFSSL_NO_ASN_STRICT) && !defined(WOLFSSL_FPKI)
17993
            /* Verify RFC 5280 Sec 4.2.1.6 rule:
17994
                "The name MUST NOT be a relative URI"
17995
                As per RFC 3986 Sec 4.3, an absolute URI is only required to contain
17996
                a scheme and hier-part.  So the only strict requirement is a ':'
17997
                being present after the scheme.  If a '/' is present as part of the
17998
                hier-part, it must come after the ':' (see RFC 3986 Sec 3). */
17999
18000
            {
18001
                word32 i;
18002
18003
                /* skip past scheme (i.e http,ftp,...) finding first ':' char */
18004
                for (i = 0; i < (word32)strLen; i++) {
18005
                    if (input[idx + i] == ':') {
18006
                        break;
18007
                    }
18008
                    if (input[idx + i] == '/') {
18009
                        WOLFSSL_MSG("\tAlt Name must be absolute URI");
18010
                        WOLFSSL_ERROR_VERBOSE(ASN_ALT_NAME_E);
18011
                        return ASN_ALT_NAME_E;
18012
                    }
18013
                }
18014
18015
                /* test hier-part is empty */
18016
                if (i == 0 || i == (word32)strLen) {
18017
                    WOLFSSL_MSG("\tEmpty or malformed URI");
18018
                    WOLFSSL_ERROR_VERBOSE(ASN_ALT_NAME_E);
18019
                    return ASN_ALT_NAME_E;
18020
                }
18021
18022
                /* test if scheme is missing */
18023
                if (input[idx + i] != ':') {
18024
                    WOLFSSL_MSG("\tAlt Name must be absolute URI");
18025
                    WOLFSSL_ERROR_VERBOSE(ASN_ALT_NAME_E);
18026
                    return ASN_ALT_NAME_E;
18027
                }
18028
            }
18029
        #endif
18030
18031
            uriEntry = AltNameNew(cert->heap);
18032
            if (uriEntry == NULL) {
18033
                WOLFSSL_MSG("\tOut of Memory");
18034
                return MEMORY_E;
18035
            }
18036
18037
            uriEntry->type = ASN_URI_TYPE;
18038
            uriEntry->name = (char*)XMALLOC((size_t)strLen + 1, cert->heap,
18039
                                         DYNAMIC_TYPE_ALTNAME);
18040
            if (uriEntry->name == NULL) {
18041
                WOLFSSL_MSG("\tOut of Memory");
18042
                XFREE(uriEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
18043
                return MEMORY_E;
18044
            }
18045
            uriEntry->len = strLen;
18046
            XMEMCPY(uriEntry->name, &input[idx], (size_t)strLen);
18047
            uriEntry->name[strLen] = '\0';
18048
18049
            AddAltName(cert, uriEntry);
18050
18051
            length -= strLen;
18052
            idx    += (word32)strLen;
18053
        }
18054
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
18055
        else if (current_byte == (ASN_CONTEXT_SPECIFIC | ASN_IP_TYPE)) {
18056
            DNS_entry* ipAddr;
18057
            int strLen;
18058
            word32 lenStartIdx = idx;
18059
            WOLFSSL_MSG("Decoding Subject Alt. Name: IP Address");
18060
18061
            if (GetLength(input, &idx, &strLen, sz) < 0) {
18062
                WOLFSSL_MSG("\tfail: str length");
18063
                return ASN_PARSE_E;
18064
            }
18065
            length -= (idx - lenStartIdx);
18066
            /* check that strLen at index is not past input buffer */
18067
            if (strLen + idx > sz) {
18068
                return BUFFER_E;
18069
            }
18070
18071
            ipAddr = AltNameNew(cert->heap);
18072
            if (ipAddr == NULL) {
18073
                WOLFSSL_MSG("\tOut of Memory");
18074
                return MEMORY_E;
18075
            }
18076
18077
            ipAddr->type = ASN_IP_TYPE;
18078
            ipAddr->name = (char*)XMALLOC((size_t)strLen + 1, cert->heap,
18079
                                         DYNAMIC_TYPE_ALTNAME);
18080
            if (ipAddr->name == NULL) {
18081
                WOLFSSL_MSG("\tOut of Memory");
18082
                XFREE(ipAddr, cert->heap, DYNAMIC_TYPE_ALTNAME);
18083
                return MEMORY_E;
18084
            }
18085
            ipAddr->len = strLen;
18086
            XMEMCPY(ipAddr->name, &input[idx], strLen);
18087
            ipAddr->name[strLen] = '\0';
18088
18089
        #if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
18090
            if (GenerateDNSEntryIPString(ipAddr, cert->heap) != 0) {
18091
                WOLFSSL_MSG("\tOut of Memory for IP string");
18092
                XFREE(ipAddr->name, cert->heap, DYNAMIC_TYPE_ALTNAME);
18093
                XFREE(ipAddr, cert->heap, DYNAMIC_TYPE_ALTNAME);
18094
                return MEMORY_E;
18095
            }
18096
        #endif /* OPENSSL_ALL || WOLFSSL_IP_ALT_NAME */
18097
            AddAltName(cert, ipAddr);
18098
18099
            length -= strLen;
18100
            idx    += (word32)strLen;
18101
        }
18102
#endif /* WOLFSSL_QT || OPENSSL_ALL */
18103
#endif /* IGNORE_NAME_CONSTRAINTS */
18104
        else if (current_byte ==
18105
                (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE)) {
18106
            int strLen;
18107
            word32 lenStartIdx = idx;
18108
            word32 oid = 0;
18109
            int    ret = 0;
18110
18111
            if (GetLength(input, &idx, &strLen, sz) < 0) {
18112
                WOLFSSL_MSG("\tfail: other name length");
18113
                return ASN_PARSE_E;
18114
            }
18115
            /* Consume the rest of this sequence. */
18116
            length -= (int)(((word32)strLen + idx - lenStartIdx));
18117
18118
            if (GetObjectId(input, &idx, &oid, oidCertAltNameType, sz) < 0) {
18119
                WOLFSSL_MSG("\tbad OID");
18120
                return ASN_PARSE_E;
18121
            }
18122
18123
            /* handle parsing other type alt names */
18124
            switch (oid) {
18125
            #ifdef WOLFSSL_SEP
18126
                case HW_NAME_OID:
18127
                    ret = DecodeSepHwAltName(cert, input, &idx, sz);
18128
                    if (ret != 0)
18129
                        return ret;
18130
                    break;
18131
            #endif /* WOLFSSL_SEP */
18132
            #ifdef WOLFSSL_FPKI
18133
                case FASCN_OID:
18134
                case UPN_OID:
18135
                    ret = DecodeConstructedOtherName(cert, input, &idx, sz,
18136
                            oid);
18137
                    if (ret != 0)
18138
                        return ret;
18139
                    break;
18140
            #endif /* WOLFSSL_FPKI */
18141
18142
                default:
18143
                    WOLFSSL_MSG("\tUnsupported other name type, skipping");
18144
                    if (GetLength(input, &idx, &strLen, sz) < 0) {
18145
                        /* check to skip constructed other names too */
18146
                        if (DecodeConstructedOtherName(cert, input, &idx, sz,
18147
                                    (int)oid) != 0) {
18148
                            WOLFSSL_MSG("\tfail: unsupported other name length");
18149
                            return ASN_PARSE_E;
18150
                        }
18151
                    }
18152
                    else {
18153
                        idx += (word32)strLen;
18154
                    }
18155
            }
18156
            (void)ret;
18157
        }
18158
        else {
18159
            int strLen;
18160
            word32 lenStartIdx = idx;
18161
18162
            WOLFSSL_MSG("\tUnsupported name type, skipping");
18163
18164
            if (GetLength(input, &idx, &strLen, sz) < 0) {
18165
                WOLFSSL_MSG("\tfail: unsupported name length");
18166
                return ASN_PARSE_E;
18167
            }
18168
            length -= (int)((word32)strLen + idx - lenStartIdx);
18169
            idx += (word32)strLen;
18170
        }
18171
    }
18172
18173
    return 0;
18174
#else
18175
0
    word32 idx = 0;
18176
0
    int length = 0;
18177
0
    int ret = 0;
18178
18179
0
    WOLFSSL_ENTER("DecodeAltNames");
18180
18181
    /* Get SEQUENCE and expect all data to be accounted for. */
18182
0
    if (GetASN_Sequence(input, &idx, &length, sz, 1) != 0) {
18183
0
        WOLFSSL_MSG("\tBad Sequence");
18184
0
        ret = ASN_PARSE_E;
18185
0
    }
18186
18187
0
    if ((ret == 0) && (length == 0)) {
18188
        /* RFC 5280 4.2.1.6.  Subject Alternative Name
18189
           If the subjectAltName extension is present, the sequence MUST
18190
           contain at least one entry. */
18191
0
        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
18192
0
        ret = ASN_PARSE_E;
18193
0
    }
18194
0
    if (ret == 0) {
18195
    #ifdef OPENSSL_ALL
18196
        cert->extSubjAltNameSrc = input;
18197
        cert->extSubjAltNameSz = sz;
18198
    #endif
18199
18200
0
        cert->weOwnAltNames = 1;
18201
18202
0
        if ((word32)length + idx != sz) {
18203
0
            ret = ASN_PARSE_E;
18204
0
        }
18205
0
    }
18206
18207
0
    while ((ret == 0) && (idx < sz)) {
18208
0
        ASNGetData dataASN[altNameASN_Length];
18209
18210
        /* Clear dynamic data items. */
18211
0
        XMEMSET(dataASN, 0, sizeof(dataASN));
18212
        /* Parse GeneralName with the choices supported. */
18213
0
        GetASN_Choice(&dataASN[ALTNAMEASN_IDX_GN], generalNameChoice);
18214
        /* Decode a GeneralName choice. */
18215
0
        ret = GetASN_Items(altNameASN, dataASN, altNameASN_Length, 0, input,
18216
0
                           &idx, sz);
18217
0
        if (ret == 0) {
18218
0
            ret = DecodeGeneralName(input, &idx, dataASN[ALTNAMEASN_IDX_GN].tag,
18219
0
                                  (int)dataASN[ALTNAMEASN_IDX_GN].length, cert);
18220
0
        }
18221
0
    }
18222
18223
0
    return ret;
18224
0
#endif
18225
0
}
18226
18227
#ifdef WOLFSSL_ASN_TEMPLATE
18228
/* ASN.1 template for BasicContraints.
18229
 * X.509: RFC 5280, 4.2.1.9 - BasicConstraints.
18230
 */
18231
static const ASNItem basicConsASN[] = {
18232
/* SEQ  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
18233
/* CA   */     { 1, ASN_BOOLEAN, 0, 0, 1 },
18234
/* PLEN */     { 1, ASN_INTEGER, 0, 0, 1 }
18235
};
18236
enum {
18237
    BASICCONSASN_IDX_SEQ = 0,
18238
    BASICCONSASN_IDX_CA,
18239
    BASICCONSASN_IDX_PLEN
18240
};
18241
18242
/* Number of items in ASN.1 template for BasicContraints. */
18243
0
#define basicConsASN_Length (sizeof(basicConsASN) / sizeof(ASNItem))
18244
#endif
18245
18246
/* Decode basic constraints extension in a certificate.
18247
 *
18248
 * X.509: RFC 5280, 4.2.1.9 - BasicConstraints.
18249
 *
18250
 * @param [in]      input  Buffer holding data.
18251
 * @param [in]      sz     Size of data in buffer.
18252
 * @param [in, out] cert   Certificate object.
18253
 * @return  0 on success.
18254
 * @return  MEMORY_E on dynamic memory allocation failure.
18255
 * @return  ASN_PARSE_E when CA boolean is present and false (default is false).
18256
 * @return  ASN_PARSE_E when CA boolean is not present unless
18257
 *          WOLFSSL_X509_BASICCONS_INT is defined. Only a CA extension.
18258
 * @return  ASN_PARSE_E when path length more than 7 bits.
18259
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
18260
 *          is invalid.
18261
 * @return  BUFFER_E when data in buffer is too small.
18262
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
18263
 *          non-zero length.
18264
 */
18265
static int DecodeBasicCaConstraint(const byte* input, int sz, DecodedCert* cert)
18266
0
{
18267
#ifndef WOLFSSL_ASN_TEMPLATE
18268
    word32 idx = 0;
18269
    int length = 0;
18270
    int ret;
18271
18272
    WOLFSSL_ENTER("DecodeBasicCaConstraint");
18273
18274
    if (GetSequence(input, &idx, &length, (word32)sz) < 0) {
18275
        WOLFSSL_MSG("\tfail: bad SEQUENCE");
18276
        return ASN_PARSE_E;
18277
    }
18278
18279
    if (length == 0)
18280
        return 0;
18281
18282
    /* If the basic ca constraint is false, this extension may be named, but
18283
     * left empty. So, if the length is 0, just return. */
18284
18285
    ret = GetBoolean(input, &idx, (word32)sz);
18286
18287
    /* Removed logic for WOLFSSL_X509_BASICCONS_INT which was mistreating the
18288
     * pathlen value as if it were the CA Boolean value 7/2/2021 - KH.
18289
     * When CA Boolean not asserted use the default value "False" */
18290
    if (ret < 0) {
18291
        WOLFSSL_MSG("\tfail: constraint not valid BOOLEAN, set default FALSE");
18292
        ret = 0;
18293
    }
18294
18295
    cert->isCA = ret ? 1 : 0;
18296
18297
    /* If there isn't any more data, return. */
18298
    if (idx >= (word32)sz) {
18299
        return 0;
18300
    }
18301
18302
    ret = GetInteger7Bit(input, &idx, (word32)sz);
18303
    if (ret < 0)
18304
        return ret;
18305
    cert->pathLength = (byte)ret;
18306
    cert->pathLengthSet = 1;
18307
18308
    return 0;
18309
#else
18310
0
    DECL_ASNGETDATA(dataASN, basicConsASN_Length);
18311
0
    int ret = 0;
18312
0
    word32 idx = 0;
18313
0
    byte isCA = 0;
18314
18315
0
    WOLFSSL_ENTER("DecodeBasicCaConstraints");
18316
18317
0
    CALLOC_ASNGETDATA(dataASN, basicConsASN_Length, ret, cert->heap);
18318
18319
0
    if (ret == 0) {
18320
        /* Get the CA boolean and path length when present. */
18321
0
        GetASN_Boolean(&dataASN[BASICCONSASN_IDX_CA], &isCA);
18322
0
        GetASN_Int8Bit(&dataASN[BASICCONSASN_IDX_PLEN], &cert->pathLength);
18323
18324
0
        ret = GetASN_Items(basicConsASN, dataASN, basicConsASN_Length, 1, input,
18325
0
                           &idx, (word32)sz);
18326
0
    }
18327
18328
    /* Empty SEQUENCE is OK - nothing to store. */
18329
0
    if ((ret == 0) && (dataASN[BASICCONSASN_IDX_SEQ].length != 0)) {
18330
        /* Bad encoding when CA Boolean is false
18331
         * (default when not present). */
18332
0
        if ((dataASN[BASICCONSASN_IDX_CA].length != 0) && (!isCA)) {
18333
0
            WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
18334
0
            ret = ASN_PARSE_E;
18335
0
        }
18336
        /* Path length must be a 7-bit value. */
18337
0
        if ((ret == 0) && (cert->pathLength >= (1 << 7))) {
18338
0
            WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
18339
0
            ret = ASN_PARSE_E;
18340
0
        }
18341
0
        if ((ret == 0) && cert->pathLength > WOLFSSL_MAX_PATH_LEN) {
18342
0
            WOLFSSL_ERROR_VERBOSE(ASN_PATHLEN_SIZE_E);
18343
0
            ret = ASN_PATHLEN_SIZE_E;
18344
0
        }
18345
        /* Store CA boolean and whether a path length was seen. */
18346
0
        if (ret == 0) {
18347
            /* isCA in certificate is a 1 bit of a byte. */
18348
0
            cert->isCA = isCA ? 1 : 0;
18349
0
            cert->pathLengthSet = (dataASN[BASICCONSASN_IDX_PLEN].length > 0);
18350
0
        }
18351
0
    }
18352
18353
0
    FREE_ASNGETDATA(dataASN, cert->heap);
18354
0
    return ret;
18355
0
#endif
18356
0
}
18357
18358
18359
static int DecodePolicyConstraints(const byte* input, int sz, DecodedCert* cert)
18360
0
{
18361
0
    word32 idx = 0;
18362
0
    int length = 0;
18363
0
    int skipLength = 0;
18364
0
    int ret;
18365
0
    byte tag;
18366
18367
0
    WOLFSSL_ENTER("DecodePolicyConstraints");
18368
18369
0
    if (GetSequence(input, &idx, &length, (word32)sz) < 0) {
18370
0
        WOLFSSL_MSG("\tfail: bad SEQUENCE");
18371
0
        return ASN_PARSE_E;
18372
0
    }
18373
18374
0
    if (length == 0)
18375
0
        return ASN_PARSE_E;
18376
18377
0
    if (GetASNTag(input, &idx, &tag, (word32)sz) < 0) {
18378
0
        WOLFSSL_MSG("\tfail: bad TAG");
18379
0
        return ASN_PARSE_E;
18380
0
    }
18381
18382
0
    if (tag == (ASN_CONTEXT_SPECIFIC | 0)) {
18383
        /* requireExplicitPolicy */
18384
0
        cert->extPolicyConstRxpSet = 1;
18385
0
    }
18386
0
    else if (tag == (ASN_CONTEXT_SPECIFIC | 1)) {
18387
        /* inhibitPolicyMapping */
18388
0
        cert->extPolicyConstIpmSet = 1;
18389
0
    }
18390
0
    else {
18391
0
        WOLFSSL_MSG("\tfail: invalid TAG");
18392
0
        return ASN_PARSE_E;
18393
0
    }
18394
18395
0
    ret = GetLength(input, &idx, &skipLength, (word32)sz);
18396
0
    if (ret < 0) {
18397
0
        WOLFSSL_MSG("\tfail: invalid length");
18398
0
        return ret;
18399
0
    }
18400
0
    if (skipLength > 1) {
18401
0
        WOLFSSL_MSG("\tfail: skip value too big");
18402
0
        return BUFFER_E;
18403
0
    }
18404
0
    if (idx >= (word32)sz) {
18405
0
        WOLFSSL_MSG("\tfail: no policy const skip to read");
18406
0
        return BUFFER_E;
18407
0
    }
18408
0
    cert->policyConstSkip = input[idx];
18409
18410
0
    return 0;
18411
0
}
18412
18413
18414
/* Context-Specific value for: DistributionPoint.distributionPoint
18415
 * From RFC5280 SS4.2.1.13, Distribution Point */
18416
#define DISTRIBUTION_POINT  (ASN_CONTEXT_SPECIFIC | 0)
18417
/* Context-Specific value for: DistributionPoint.DistributionPointName.fullName
18418
 *  From RFC3280 SS4.2.1.13, Distribution Point Name */
18419
#define CRLDP_FULL_NAME     (ASN_CONTEXT_SPECIFIC | 0)
18420
/* Context-Specific value for choice: GeneralName.uniformResourceIdentifier
18421
 * From RFC3280 SS4.2.1.7, GeneralName */
18422
0
#define GENERALNAME_URI     (ASN_CONTEXT_SPECIFIC | 6)
18423
18424
#ifdef WOLFSSL_ASN_TEMPLATE
18425
/* ASN.1 template for CRL distribution points.
18426
 * X.509: RFC 5280, 4.2.1.13 - CRL Distribution Points.
18427
 */
18428
static const ASNItem crlDistASN[] = {
18429
/* SEQ                */ { 0, ASN_SEQUENCE, 1, 1, 0 },
18430
/* DP_SEQ             */     { 1, ASN_SEQUENCE, 1, 1, 0 },
18431
                                                /* Distribution point name */
18432
/* DP_DISTPOINT       */         { 2, DISTRIBUTION_POINT, 1, 1, 1 },
18433
                                                    /* fullName */
18434
/* DP_DISTPOINT_FN    */             { 3, CRLDP_FULL_NAME, 1, 1, 2 },
18435
/* DP_DISTPOINT_FN_GN */                 { 4, GENERALNAME_URI, 0, 0, 0 },
18436
                                                    /* nameRelativeToCRLIssuer */
18437
/* DP_DISTPOINT_RN    */             { 3, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 2 },
18438
                                                /* reasons: IMPLICIT BIT STRING */
18439
/* DP_REASONS         */         { 2, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 1 },
18440
                                                /* cRLIssuer */
18441
/* DP_CRLISSUER       */         { 2, ASN_CONTEXT_SPECIFIC | 2, 1, 0, 1 },
18442
};
18443
enum {
18444
    CRLDISTASN_IDX_SEQ = 0,
18445
    CRLDISTASN_IDX_DP_SEQ,
18446
    CRLDISTASN_IDX_DP_DISTPOINT,
18447
    CRLDISTASN_IDX_DP_DISTPOINT_FN,
18448
    CRLDISTASN_IDX_DP_DISTPOINT_FN_GN,
18449
    CRLDISTASN_IDX_DP_DISTPOINT_RN, /* Relative name */
18450
    CRLDISTASN_IDX_DP_REASONS,
18451
    CRLDISTASN_IDX_DP_CRLISSUER
18452
};
18453
18454
/* Number of items in ASN.1 template for CRL distribution points. */
18455
0
#define crlDistASN_Length (sizeof(crlDistASN) / sizeof(ASNItem))
18456
#endif
18457
18458
/* Decode CRL distribution point extension in a certificate.
18459
 *
18460
 * X.509: RFC 5280, 4.2.1.13 - CRL Distribution Points.
18461
 *
18462
 * @param [in]      input  Buffer holding data.
18463
 * @param [in]      sz     Size of data in buffer.
18464
 * @param [in, out] cert   Certificate object.
18465
 * @return  0 on success.
18466
 * @return  MEMORY_E on dynamic memory allocation failure.
18467
 * @return  ASN_PARSE_E when invalid bits of reason are set.
18468
 * @return  ASN_PARSE_E when BITSTRING value is more than 2 bytes.
18469
 * @return  ASN_PARSE_E when unused bits of BITSTRING is invalid.
18470
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
18471
 *          is invalid.
18472
 * @return  BUFFER_E when data in buffer is too small.
18473
 */
18474
static int DecodeCrlDist(const byte* input, word32 sz, DecodedCert* cert)
18475
0
{
18476
#ifndef WOLFSSL_ASN_TEMPLATE
18477
    word32 idx = 0, localIdx;
18478
    int length = 0;
18479
    byte tag   = 0;
18480
18481
    WOLFSSL_ENTER("DecodeCrlDist");
18482
18483
    cert->extCrlInfoRaw = input;
18484
    cert->extCrlInfoRawSz = (int)sz;
18485
18486
    /* Unwrap the list of Distribution Points*/
18487
    if (GetSequence(input, &idx, &length, sz) < 0)
18488
        return ASN_PARSE_E;
18489
18490
    /* Unwrap a single Distribution Point */
18491
    if (GetSequence(input, &idx, &length, sz) < 0)
18492
        return ASN_PARSE_E;
18493
18494
    /* The Distribution Point has three explicit optional members
18495
     *  First check for a DistributionPointName
18496
     */
18497
    localIdx = idx;
18498
    if (GetASNTag(input, &localIdx, &tag, sz) == 0 &&
18499
            tag == (ASN_CONSTRUCTED | DISTRIBUTION_POINT))
18500
    {
18501
        idx++;
18502
        if (GetLength(input, &idx, &length, sz) < 0)
18503
            return ASN_PARSE_E;
18504
18505
        localIdx = idx;
18506
        if (GetASNTag(input, &localIdx, &tag, sz) == 0 &&
18507
                tag == (ASN_CONSTRUCTED | CRLDP_FULL_NAME))
18508
        {
18509
            idx++;
18510
            if (GetLength(input, &idx, &length, sz) < 0)
18511
                return ASN_PARSE_E;
18512
18513
            localIdx = idx;
18514
            if (GetASNTag(input, &localIdx, &tag, sz) == 0 &&
18515
                    tag == GENERALNAME_URI)
18516
            {
18517
                idx++;
18518
                if (GetLength(input, &idx, &length, sz) < 0)
18519
                    return ASN_PARSE_E;
18520
18521
                cert->extCrlInfoSz = length;
18522
                cert->extCrlInfo = input + idx;
18523
                idx += (word32)length;
18524
            }
18525
            else
18526
                /* This isn't a URI, skip it. */
18527
                idx += (word32)length;
18528
        }
18529
        else {
18530
            /* This isn't a FULLNAME, skip it. */
18531
            idx += (word32)length;
18532
        }
18533
    }
18534
18535
    /* Check for reasonFlags */
18536
    localIdx = idx;
18537
    if (idx < (word32)sz &&
18538
        GetASNTag(input, &localIdx, &tag, sz) == 0 &&
18539
        tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
18540
    {
18541
        idx++;
18542
        if (GetLength(input, &idx, &length, sz) < 0)
18543
            return ASN_PARSE_E;
18544
        idx += (word32)length;
18545
    }
18546
18547
    /* Check for cRLIssuer */
18548
    localIdx = idx;
18549
    if (idx < (word32)sz &&
18550
        GetASNTag(input, &localIdx, &tag, sz) == 0 &&
18551
        tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2))
18552
    {
18553
        idx++;
18554
        if (GetLength(input, &idx, &length, sz) < 0)
18555
            return ASN_PARSE_E;
18556
        idx += (word32)length;
18557
    }
18558
18559
    if (idx < (word32)sz)
18560
    {
18561
        WOLFSSL_MSG("\tThere are more CRL Distribution Point records, "
18562
                   "but we only use the first one.");
18563
    }
18564
18565
    return 0;
18566
#else
18567
0
    DECL_ASNGETDATA(dataASN, crlDistASN_Length);
18568
0
    word32 idx = 0;
18569
0
    int ret = 0;
18570
#ifdef CRLDP_VALIDATE_DATA
18571
    word16 reason;
18572
#endif
18573
18574
0
    WOLFSSL_ENTER("DecodeCrlDist");
18575
18576
0
    CALLOC_ASNGETDATA(dataASN, crlDistASN_Length, ret, cert->heap);
18577
18578
0
    cert->extCrlInfoRaw = input;
18579
0
    cert->extCrlInfoRawSz = (int)sz;
18580
18581
0
    if  (ret == 0) {
18582
        /* Get the GeneralName choice */
18583
0
        GetASN_Choice(&dataASN[CRLDISTASN_IDX_DP_DISTPOINT_FN_GN], generalNameChoice);
18584
        /* Parse CRL distribtion point. */
18585
0
        ret = GetASN_Items(crlDistASN, dataASN, crlDistASN_Length, 0, input,
18586
0
                           &idx, sz);
18587
0
    }
18588
0
    if (ret == 0) {
18589
        /* If the choice was a URI, store it in certificate. */
18590
0
        if (dataASN[CRLDISTASN_IDX_DP_DISTPOINT_FN_GN].tag == GENERALNAME_URI) {
18591
0
            word32 sz32;
18592
0
            GetASN_GetConstRef(&dataASN[CRLDISTASN_IDX_DP_DISTPOINT_FN_GN],
18593
0
                    &cert->extCrlInfo, &sz32);
18594
0
            cert->extCrlInfoSz = (int)sz32;
18595
0
        }
18596
18597
    #ifdef CRLDP_VALIDATE_DATA
18598
        if (dataASN[CRLDISTASN_IDX_DP_REASONS].data.ref.data != NULL) {
18599
             /* TODO: test case */
18600
             /* Validate ReasonFlags. */
18601
             ret = GetASN_BitString_Int16Bit(&dataASN[CRLDISTASN_IDX_DP_REASONS],
18602
                     &reason);
18603
             /* First bit (LSB) unused and eight other bits defined. */
18604
             if ((ret == 0) && ((reason >> 9) || (reason & 0x01))) {
18605
                WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
18606
                ret = ASN_PARSE_E;
18607
             }
18608
        }
18609
    #endif
18610
0
    }
18611
18612
    /* Only parsing the first one. */
18613
0
    if (ret == 0 && idx < (word32)sz) {
18614
0
        WOLFSSL_MSG("\tThere are more CRL Distribution Point records, "
18615
0
                    "but we only use the first one.");
18616
0
    }
18617
    /* TODO: validate other points. */
18618
18619
0
    FREE_ASNGETDATA(dataASN, cert->heap);
18620
0
    return ret;
18621
0
#endif /* WOLFSSL_ASN_TEMPLATE */
18622
0
}
18623
18624
#ifdef WOLFSSL_ASN_TEMPLATE
18625
/* ASN.1 template for the access description.
18626
 * X.509: RFC 5280, 4.2.2.1 - Authority Information Access.
18627
 */
18628
static const ASNItem accessDescASN[] = {
18629
/* SEQ  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
18630
                                 /* accessMethod */
18631
/* METH */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
18632
                                 /* accessLocation: GeneralName */
18633
/* LOC  */     { 1, ASN_CONTEXT_SPECIFIC | 0, 0, 0, 0 },
18634
};
18635
enum {
18636
    ACCESSDESCASN_IDX_SEQ = 0,
18637
    ACCESSDESCASN_IDX_METH,
18638
    ACCESSDESCASN_IDX_LOC
18639
};
18640
18641
/* Number of items in ASN.1 template for the access description. */
18642
0
#define accessDescASN_Length (sizeof(accessDescASN) / sizeof(ASNItem))
18643
#endif
18644
18645
/* Decode authority information access extension in a certificate.
18646
 *
18647
 * X.509: RFC 5280, 4.2.2.1 - Authority Information Access.
18648
 *
18649
 * @param [in]      input  Buffer holding data.
18650
 * @param [in]      sz     Size of data in buffer.
18651
 * @param [in, out] cert   Certificate object.
18652
 * @return  0 on success.
18653
 * @return  MEMORY_E on dynamic memory allocation failure.
18654
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
18655
 *          is invalid.
18656
 * @return  BUFFER_E when data in buffer is too small.
18657
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
18658
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
18659
 */
18660
static int DecodeAuthInfo(const byte* input, word32 sz, DecodedCert* cert)
18661
0
{
18662
#ifndef WOLFSSL_ASN_TEMPLATE
18663
    word32 idx = 0;
18664
    int length = 0;
18665
    int count  = 0;
18666
    byte b = 0;
18667
    word32 oid;
18668
18669
    WOLFSSL_ENTER("DecodeAuthInfo");
18670
18671
    /* Unwrap the list of AIAs */
18672
    if (GetSequence(input, &idx, &length, sz) < 0)
18673
        return ASN_PARSE_E;
18674
18675
    while ((idx < (word32)sz) && (count < MAX_AIA_SZ)) {
18676
        /* Unwrap a single AIA */
18677
        if (GetSequence(input, &idx, &length, sz) < 0)
18678
            return ASN_PARSE_E;
18679
18680
        oid = 0;
18681
        if (GetObjectId(input, &idx, &oid, oidCertAuthInfoType, sz) < 0) {
18682
            return ASN_PARSE_E;
18683
        }
18684
18685
        /* Only supporting URIs right now. */
18686
        if (GetASNTag(input, &idx, &b, sz) < 0)
18687
            return ASN_PARSE_E;
18688
18689
        if (GetLength(input, &idx, &length, sz) < 0)
18690
            return ASN_PARSE_E;
18691
18692
        /* Set ocsp entry */
18693
        if (b == GENERALNAME_URI && oid == AIA_OCSP_OID)
18694
        {
18695
            cert->extAuthInfoSz = length;
18696
            cert->extAuthInfo = input + idx;
18697
        #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
18698
            count++;
18699
        #else
18700
            break;
18701
        #endif
18702
        }
18703
        #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
18704
        /* Set CaIssuers entry */
18705
        else if ((b == GENERALNAME_URI) && oid == AIA_CA_ISSUER_OID)
18706
        {
18707
            cert->extAuthInfoCaIssuerSz = length;
18708
            cert->extAuthInfoCaIssuer = input + idx;
18709
            count++;
18710
        }
18711
        #endif
18712
        idx += (word32)length;
18713
    }
18714
18715
    return 0;
18716
#else
18717
0
    word32 idx = 0;
18718
0
    int length = 0;
18719
0
    int count  = 0;
18720
0
    int ret    = 0;
18721
18722
0
    WOLFSSL_ENTER("DecodeAuthInfo");
18723
18724
    /* Unwrap the list of AIAs */
18725
0
    if (GetASN_Sequence(input, &idx, &length, sz, 1) < 0) {
18726
0
        ret = ASN_PARSE_E;
18727
0
    }
18728
18729
0
    while ((ret == 0) && (idx < (word32)sz) && (count < MAX_AIA_SZ)) {
18730
0
        ASNGetData dataASN[accessDescASN_Length];
18731
18732
        /* Clear dynamic data and retrieve OID and name. */
18733
0
        XMEMSET(dataASN, 0, sizeof(dataASN));
18734
0
        GetASN_OID(&dataASN[ACCESSDESCASN_IDX_METH], oidCertAuthInfoType);
18735
0
        GetASN_Choice(&dataASN[ACCESSDESCASN_IDX_LOC], generalNameChoice);
18736
        /* Parse AccessDescription. */
18737
0
        ret = GetASN_Items(accessDescASN, dataASN, accessDescASN_Length, 0,
18738
0
                           input, &idx, sz);
18739
0
        if (ret == 0) {
18740
0
            word32 sz32;
18741
18742
            /* Check we have OCSP and URI. */
18743
0
            if ((dataASN[ACCESSDESCASN_IDX_METH].data.oid.sum == AIA_OCSP_OID) &&
18744
0
                    (dataASN[ACCESSDESCASN_IDX_LOC].tag == GENERALNAME_URI)) {
18745
                /* Store URI for OCSP lookup. */
18746
0
                GetASN_GetConstRef(&dataASN[ACCESSDESCASN_IDX_LOC],
18747
0
                        &cert->extAuthInfo, &sz32);
18748
0
                cert->extAuthInfoSz = (int)sz32;
18749
            #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
18750
                count++;
18751
            #else
18752
0
                break;
18753
0
            #endif
18754
0
            }
18755
            #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
18756
            /* Check we have CA Issuer and URI. */
18757
            else if ((dataASN[ACCESSDESCASN_IDX_METH].data.oid.sum ==
18758
                        AIA_CA_ISSUER_OID) &&
18759
                    (dataASN[ACCESSDESCASN_IDX_LOC].tag == GENERALNAME_URI)) {
18760
                /* Set CaIssuers entry */
18761
                GetASN_GetConstRef(&dataASN[ACCESSDESCASN_IDX_LOC],
18762
                        &cert->extAuthInfoCaIssuer, &sz32);
18763
                cert->extAuthInfoCaIssuerSz = (int)sz32;
18764
                count++;
18765
            }
18766
            #endif
18767
            /* Otherwise skip. */
18768
0
        }
18769
0
    }
18770
18771
0
    return ret;
18772
0
#endif
18773
0
}
18774
18775
18776
#ifdef WOLFSSL_ASN_TEMPLATE
18777
/* ASN.1 template for AuthorityKeyIdentifier.
18778
 * X.509: RFC 5280, 4.2.1.1 - Authority Key Identifier.
18779
 */
18780
static const ASNItem authKeyIdASN[] = {
18781
/* SEQ    */    { 0, ASN_SEQUENCE, 1, 1, 0 },
18782
                                     /* keyIdentifier */
18783
/* KEYID  */        { 1, ASN_CONTEXT_SPECIFIC | ASN_AUTHKEYID_KEYID, 0, 0, 1 },
18784
                                     /* authorityCertIssuer */
18785
/* ISSUER */        { 1, ASN_CONTEXT_SPECIFIC | ASN_AUTHKEYID_ISSUER, 1, 0, 1 },
18786
                                     /* authorityCertSerialNumber */
18787
/* SERIAL */        { 1, ASN_CONTEXT_SPECIFIC | ASN_AUTHKEYID_SERIAL, 0, 0, 1 },
18788
};
18789
enum {
18790
    AUTHKEYIDASN_IDX_SEQ = 0,
18791
    AUTHKEYIDASN_IDX_KEYID,
18792
    AUTHKEYIDASN_IDX_ISSUER,
18793
    AUTHKEYIDASN_IDX_SERIAL
18794
};
18795
18796
/* Number of items in ASN.1 template for AuthorityKeyIdentifier. */
18797
0
#define authKeyIdASN_Length (sizeof(authKeyIdASN) / sizeof(ASNItem))
18798
#endif
18799
18800
/* Decode authority information access extension in a certificate.
18801
 *
18802
 * X.509: RFC 5280, 4.2.2.1 - Authority Information Access.
18803
 *
18804
 * @param [in]      input  Buffer holding data.
18805
 * @param [in]      sz     Size of data in buffer.
18806
 * @param [in, out] cert   Certificate object.
18807
 * @return  0 on success.
18808
 * @return  MEMORY_E on dynamic memory allocation failure.
18809
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
18810
 *          is invalid.
18811
 * @return  BUFFER_E when data in buffer is too small.
18812
 */
18813
static int DecodeAuthKeyId(const byte* input, word32 sz, DecodedCert* cert)
18814
0
{
18815
#ifndef WOLFSSL_ASN_TEMPLATE
18816
    word32 idx = 0;
18817
    int length = 0;
18818
    byte tag;
18819
18820
    WOLFSSL_ENTER("DecodeAuthKeyId");
18821
18822
    if (GetSequence(input, &idx, &length, sz) < 0) {
18823
        WOLFSSL_MSG("\tfail: should be a SEQUENCE");
18824
        return ASN_PARSE_E;
18825
    }
18826
18827
    if (GetASNTag(input, &idx, &tag, sz) < 0) {
18828
        return ASN_PARSE_E;
18829
    }
18830
18831
    if (tag != (ASN_CONTEXT_SPECIFIC | 0)) {
18832
        WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available");
18833
        cert->extAuthKeyIdSet = 0;
18834
        return 0;
18835
    }
18836
18837
    if (GetLength(input, &idx, &length, sz) <= 0) {
18838
        WOLFSSL_MSG("\tfail: extension data length");
18839
        return ASN_PARSE_E;
18840
    }
18841
18842
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
18843
#ifdef WOLFSSL_AKID_NAME
18844
    cert->extRawAuthKeyIdSrc = input;
18845
    cert->extRawAuthKeyIdSz = sz;
18846
#endif
18847
    cert->extAuthKeyIdSrc = &input[idx];
18848
    cert->extAuthKeyIdSz = length;
18849
#endif /* OPENSSL_EXTRA */
18850
18851
    return GetHashId(input + idx, length, cert->extAuthKeyId,
18852
        HashIdAlg(cert->signatureOID));
18853
#else
18854
0
    DECL_ASNGETDATA(dataASN, authKeyIdASN_Length);
18855
0
    int ret = 0;
18856
18857
0
    WOLFSSL_ENTER("DecodeAuthKeyId");
18858
18859
0
    CALLOC_ASNGETDATA(dataASN, authKeyIdASN_Length, ret, cert->heap);
18860
18861
0
    if (ret == 0) {
18862
        /* Parse an authority key identifier. */
18863
0
        word32 idx = 0;
18864
0
        ret = GetASN_Items(authKeyIdASN, dataASN, authKeyIdASN_Length, 1, input,
18865
0
                           &idx, sz);
18866
0
    }
18867
    /* Each field is optional */
18868
0
    if (ret == 0 && dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data != NULL) {
18869
#ifdef OPENSSL_EXTRA
18870
        GetASN_GetConstRef(&dataASN[AUTHKEYIDASN_IDX_KEYID],
18871
                &cert->extAuthKeyIdSrc, &cert->extAuthKeyIdSz);
18872
#endif /* OPENSSL_EXTRA */
18873
        /* Get the hash or hash of the hash if wrong size. */
18874
0
        ret = GetHashId(dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data,
18875
0
                    (int)dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.length,
18876
0
                    cert->extAuthKeyId, HashIdAlg((int)cert->signatureOID));
18877
0
    }
18878
#ifdef WOLFSSL_AKID_NAME
18879
    if (ret == 0 && dataASN[AUTHKEYIDASN_IDX_ISSUER].data.ref.data != NULL) {
18880
        /* We only support using one (first) name. Parse the name to perform
18881
         * a sanity check. */
18882
        word32 idx = 0;
18883
        ASNGetData nameASN[altNameASN_Length];
18884
        XMEMSET(nameASN, 0, sizeof(nameASN));
18885
        /* Parse GeneralName with the choices supported. */
18886
        GetASN_Choice(&nameASN[ALTNAMEASN_IDX_GN], generalNameChoice);
18887
        /* Decode a GeneralName choice. */
18888
        ret = GetASN_Items(altNameASN, nameASN, altNameASN_Length, 0,
18889
                dataASN[AUTHKEYIDASN_IDX_ISSUER].data.ref.data, &idx,
18890
                dataASN[AUTHKEYIDASN_IDX_ISSUER].data.ref.length);
18891
18892
        if (ret == 0) {
18893
            GetASN_GetConstRef(&nameASN[ALTNAMEASN_IDX_GN],
18894
                    &cert->extAuthKeyIdIssuer, &cert->extAuthKeyIdIssuerSz);
18895
        }
18896
    }
18897
    if (ret == 0 && dataASN[AUTHKEYIDASN_IDX_SERIAL].data.ref.data != NULL) {
18898
        GetASN_GetConstRef(&dataASN[AUTHKEYIDASN_IDX_SERIAL],
18899
                &cert->extAuthKeyIdIssuerSN, &cert->extAuthKeyIdIssuerSNSz);
18900
    }
18901
    if (ret == 0) {
18902
        if ((cert->extAuthKeyIdIssuerSz > 0) ^
18903
                (cert->extAuthKeyIdIssuerSNSz > 0)) {
18904
            WOLFSSL_MSG("authorityCertIssuer and authorityCertSerialNumber MUST"
18905
                       " both be present or both be absent");
18906
        }
18907
    }
18908
#endif /* WOLFSSL_AKID_NAME */
18909
0
    if (ret == 0) {
18910
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_AKID_NAME)
18911
        /* Store the raw authority key id. */
18912
        cert->extRawAuthKeyIdSrc = input;
18913
        cert->extRawAuthKeyIdSz = sz;
18914
#endif /* OPENSSL_EXTRA */
18915
0
    }
18916
18917
0
    FREE_ASNGETDATA(dataASN, cert->heap);
18918
0
    return ret;
18919
0
#endif /* WOLFSSL_ASN_TEMPLATE */
18920
0
}
18921
18922
/* Decode subject key id extension in a certificate.
18923
 *
18924
 * X.509: RFC 5280, 4.2.2.1 - Authority Information Access.
18925
 *
18926
 * @param [in]      input  Buffer holding data.
18927
 * @param [in]      sz     Size of data in buffer.
18928
 * @param [in, out] cert   Certificate object.
18929
 * @return  0 on success.
18930
 * @return  ASN_PARSE_E when the OCTET_STRING tag is not found or length is
18931
 *          invalid.
18932
 * @return  MEMORY_E on dynamic memory allocation failure.
18933
 */
18934
static int DecodeSubjKeyId(const byte* input, word32 sz, DecodedCert* cert)
18935
0
{
18936
0
    word32 idx = 0;
18937
0
    int length = 0;
18938
0
    int ret = 0;
18939
18940
0
    WOLFSSL_ENTER("DecodeSubjKeyId");
18941
18942
0
    ret = GetOctetString(input, &idx, &length, sz);
18943
0
    if (ret > 0) {
18944
    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
18945
        cert->extSubjKeyIdSrc = &input[idx];
18946
        cert->extSubjKeyIdSz = (word32)length;
18947
    #endif /* OPENSSL_EXTRA */
18948
18949
        /* Get the hash or hash of the hash if wrong size. */
18950
0
        ret = GetHashId(input + idx, length, cert->extSubjKeyId,
18951
0
            HashIdAlg(cert->signatureOID));
18952
0
    }
18953
18954
0
    return ret;
18955
0
}
18956
18957
#ifdef WOLFSSL_ASN_TEMPLATE
18958
/* ASN.1 template for KeyUsage.
18959
 * X.509: RFC 5280, 4.2.1.3 - Key Usage.
18960
 */
18961
static const ASNItem keyUsageASN[] = {
18962
/* STR */ { 0, ASN_BIT_STRING, 0, 0, 0 },
18963
};
18964
enum {
18965
    KEYUSAGEASN_IDX_STR = 0
18966
};
18967
18968
/* Number of items in ASN.1 template for KeyUsage. */
18969
0
#define keyUsageASN_Length (sizeof(keyUsageASN) / sizeof(ASNItem))
18970
#endif
18971
18972
/* Decode key usage extension in a certificate.
18973
 *
18974
 * X.509: RFC 5280, 4.2.2.1 - Authority Information Access.
18975
 *
18976
 * @param [in]      input  Buffer holding data.
18977
 * @param [in]      sz     Size of data in buffer.
18978
 * @param [in, out] cert   Certificate object.
18979
 * @return  0 on success.
18980
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
18981
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
18982
 *          is invalid.
18983
 * @return  MEMORY_E on dynamic memory allocation failure.
18984
 */
18985
static int DecodeKeyUsage(const byte* input, word32 sz, DecodedCert* cert)
18986
0
{
18987
#ifndef WOLFSSL_ASN_TEMPLATE
18988
    word32 idx = 0;
18989
    int length;
18990
    int ret;
18991
    WOLFSSL_ENTER("DecodeKeyUsage");
18992
18993
    ret = CheckBitString(input, &idx, &length, sz, 0, NULL);
18994
    if (ret != 0)
18995
        return ret;
18996
18997
    if (length == 0 || length > 2)
18998
        return ASN_PARSE_E;
18999
19000
    cert->extKeyUsage = (word16)(input[idx]);
19001
    if (length == 2)
19002
        cert->extKeyUsage |= (word16)(input[idx+1] << 8);
19003
19004
    return 0;
19005
#else
19006
0
    ASNGetData dataASN[keyUsageASN_Length];
19007
0
    word32 idx = 0;
19008
0
    WOLFSSL_ENTER("DecodeKeyUsage");
19009
19010
    /* Clear dynamic data and set where to store extended key usage. */
19011
0
    XMEMSET(dataASN, 0, sizeof(dataASN));
19012
0
    GetASN_Int16Bit(&dataASN[KEYUSAGEASN_IDX_STR], &cert->extKeyUsage);
19013
    /* Parse key usage. */
19014
0
    return GetASN_Items(keyUsageASN, dataASN, keyUsageASN_Length, 0, input,
19015
0
                        &idx, sz);
19016
0
#endif /* WOLFSSL_ASN_TEMPLATE */
19017
0
}
19018
19019
#ifdef WOLFSSL_ASN_TEMPLATE
19020
/* ASN.1 template for KeyPurposeId.
19021
 * X.509: RFC 5280, 4.2.1.12 - Extended Key Usage.
19022
 */
19023
static const ASNItem keyPurposeIdASN[] = {
19024
/* OID */ { 0, ASN_OBJECT_ID, 0, 0, 0 },
19025
};
19026
enum {
19027
    KEYPURPOSEIDASN_IDX_OID = 0
19028
};
19029
19030
/* Number of items in ASN.1 template for KeyPurposeId. */
19031
0
#define keyPurposeIdASN_Length (sizeof(keyPurposeIdASN) / sizeof(ASNItem))
19032
#endif
19033
19034
/* Decode extended key usage extension in a certificate.
19035
 *
19036
 * X.509: RFC 5280, 4.2.1.12 - Extended Key Usage.
19037
 *
19038
 * @param [in]      input  Buffer holding data.
19039
 * @param [in]      sz     Size of data in buffer.
19040
 * @param [in, out] cert   Certificate object.
19041
 * @return  0 on success.
19042
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
19043
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
19044
 *          is invalid.
19045
 * @return  MEMORY_E on dynamic memory allocation failure.
19046
 */
19047
static int DecodeExtKeyUsage(const byte* input, word32 sz, DecodedCert* cert)
19048
0
{
19049
#ifndef WOLFSSL_ASN_TEMPLATE
19050
    word32 idx = 0, oid;
19051
    int length, ret;
19052
19053
    WOLFSSL_ENTER("DecodeExtKeyUsage");
19054
19055
    if (GetSequence(input, &idx, &length, sz) < 0) {
19056
        WOLFSSL_MSG("\tfail: should be a SEQUENCE");
19057
        return ASN_PARSE_E;
19058
    }
19059
19060
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
19061
    cert->extExtKeyUsageSrc = input + idx;
19062
    cert->extExtKeyUsageSz = length;
19063
#endif
19064
19065
    while (idx < (word32)sz) {
19066
        ret = GetObjectId(input, &idx, &oid, oidCertKeyUseType, sz);
19067
        if (ret == ASN_UNKNOWN_OID_E)
19068
            continue;
19069
        else if (ret < 0)
19070
            return ret;
19071
19072
        switch (oid) {
19073
            case EKU_ANY_OID:
19074
                cert->extExtKeyUsage |= EXTKEYUSE_ANY;
19075
                break;
19076
            case EKU_SERVER_AUTH_OID:
19077
                cert->extExtKeyUsage |= EXTKEYUSE_SERVER_AUTH;
19078
                break;
19079
            case EKU_CLIENT_AUTH_OID:
19080
                cert->extExtKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
19081
                break;
19082
            case EKU_CODESIGNING_OID:
19083
                cert->extExtKeyUsage |= EXTKEYUSE_CODESIGN;
19084
                break;
19085
            case EKU_EMAILPROTECT_OID:
19086
                cert->extExtKeyUsage |= EXTKEYUSE_EMAILPROT;
19087
                break;
19088
            case EKU_TIMESTAMP_OID:
19089
                cert->extExtKeyUsage |= EXTKEYUSE_TIMESTAMP;
19090
                break;
19091
            case EKU_OCSP_SIGN_OID:
19092
                cert->extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN;
19093
                break;
19094
            #ifdef WOLFSSL_WOLFSSH
19095
            case EKU_SSH_CLIENT_AUTH_OID:
19096
                cert->extExtKeyUsageSsh |= EXTKEYUSE_SSH_CLIENT_AUTH;
19097
                break;
19098
            case EKU_SSH_MSCL_OID:
19099
                cert->extExtKeyUsageSsh |= EXTKEYUSE_SSH_MSCL;
19100
                break;
19101
            case EKU_SSH_KP_CLIENT_AUTH_OID:
19102
                cert->extExtKeyUsageSsh |= EXTKEYUSE_SSH_KP_CLIENT_AUTH;
19103
                break;
19104
            #endif /* WOLFSSL_WOLFSSH */
19105
            default:
19106
                break;
19107
        }
19108
19109
    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
19110
        cert->extExtKeyUsageCount++;
19111
    #endif
19112
    }
19113
19114
    return 0;
19115
#else
19116
0
    word32 idx = 0;
19117
0
    int length;
19118
0
    int ret = 0;
19119
19120
0
    WOLFSSL_ENTER("DecodeExtKeyUsage");
19121
19122
    /* Strip SEQUENCE OF and expect to account for all the data. */
19123
0
    if (GetASN_Sequence(input, &idx, &length, sz, 1) < 0) {
19124
0
        WOLFSSL_MSG("\tfail: should be a SEQUENCE");
19125
0
        ret = ASN_PARSE_E;
19126
0
    }
19127
19128
0
    if (ret == 0) {
19129
    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
19130
        /* Keep reference for WOLFSSL_X509. */
19131
        cert->extExtKeyUsageSrc = input + idx;
19132
        cert->extExtKeyUsageSz = (word32)length;
19133
    #endif
19134
0
    }
19135
19136
    /* Check all OIDs. */
19137
0
    while ((ret == 0) && (idx < (word32)sz)) {
19138
0
        ASNGetData dataASN[keyPurposeIdASN_Length];
19139
19140
        /* Clear dynamic data items and set OID type expected. */
19141
0
        XMEMSET(dataASN, 0, sizeof(dataASN));
19142
0
        GetASN_OID(&dataASN[KEYPURPOSEIDASN_IDX_OID], oidIgnoreType);
19143
        /* Decode KeyPurposeId. */
19144
0
        ret = GetASN_Items(keyPurposeIdASN, dataASN, keyPurposeIdASN_Length, 0,
19145
0
                           input, &idx, sz);
19146
        /* Skip unknown OIDs. */
19147
0
        if (ret == ASN_UNKNOWN_OID_E) {
19148
0
            ret = 0;
19149
0
        }
19150
0
        else if (ret == 0) {
19151
            /* Store the bit for the OID. */
19152
0
            switch (dataASN[KEYPURPOSEIDASN_IDX_OID].data.oid.sum) {
19153
0
                case EKU_ANY_OID:
19154
0
                    cert->extExtKeyUsage |= EXTKEYUSE_ANY;
19155
0
                    break;
19156
0
                case EKU_SERVER_AUTH_OID:
19157
0
                    cert->extExtKeyUsage |= EXTKEYUSE_SERVER_AUTH;
19158
0
                    break;
19159
0
                case EKU_CLIENT_AUTH_OID:
19160
0
                    cert->extExtKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
19161
0
                    break;
19162
0
                case EKU_CODESIGNING_OID:
19163
0
                    cert->extExtKeyUsage |= EXTKEYUSE_CODESIGN;
19164
0
                    break;
19165
0
                case EKU_EMAILPROTECT_OID:
19166
0
                    cert->extExtKeyUsage |= EXTKEYUSE_EMAILPROT;
19167
0
                    break;
19168
0
                case EKU_TIMESTAMP_OID:
19169
0
                    cert->extExtKeyUsage |= EXTKEYUSE_TIMESTAMP;
19170
0
                    break;
19171
0
                case EKU_OCSP_SIGN_OID:
19172
0
                    cert->extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN;
19173
0
                    break;
19174
0
            }
19175
19176
        #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
19177
            /* Keep count for WOLFSSL_X509. */
19178
            cert->extExtKeyUsageCount++;
19179
        #endif
19180
0
        }
19181
0
    }
19182
19183
0
    return ret;
19184
0
#endif /* WOLFSSL_ASN_TEMPLATE */
19185
0
}
19186
19187
#ifndef IGNORE_NETSCAPE_CERT_TYPE
19188
19189
static int DecodeNsCertType(const byte* input, int sz, DecodedCert* cert)
19190
0
{
19191
0
    word32 idx = 0;
19192
0
    int len = 0;
19193
19194
0
    WOLFSSL_ENTER("DecodeNsCertType");
19195
19196
0
    if (CheckBitString(input, &idx, &len, (word32)sz, 0, NULL) < 0)
19197
0
        return ASN_PARSE_E;
19198
19199
    /* Don't need to worry about unused bits as CheckBitString makes sure
19200
     * they're zero. */
19201
0
    if (idx < (word32)sz)
19202
0
        cert->nsCertType = input[idx];
19203
0
    else
19204
0
        return ASN_PARSE_E;
19205
19206
0
    return 0;
19207
0
}
19208
#endif
19209
19210
19211
#ifndef IGNORE_NAME_CONSTRAINTS
19212
#ifdef WOLFSSL_ASN_TEMPLATE
19213
/* ASN.1 template for GeneralSubtree.
19214
 * X.509: RFC 5280, 4.2.1.10 - Name Constraints.
19215
 */
19216
static const ASNItem subTreeASN[] = {
19217
/* SEQ  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
19218
                              /* base     GeneralName */
19219
/* BASE */     { 1, ASN_CONTEXT_SPECIFIC | 0, 0, 0, 0 },
19220
                              /* minimum  BaseDistance DEFAULT 0*/
19221
/* MIN  */     { 1, ASN_CONTEXT_SPECIFIC | ASN_SUBTREE_MIN, 0, 0, 1 },
19222
                              /* maximum  BaseDistance OPTIONAL  */
19223
/* MAX  */     { 1, ASN_CONTEXT_SPECIFIC | ASN_SUBTREE_MAX, 0, 0, 1 },
19224
};
19225
enum {
19226
    SUBTREEASN_IDX_SEQ = 0,
19227
    SUBTREEASN_IDX_BASE,
19228
    SUBTREEASN_IDX_MIN,
19229
    SUBTREEASN_IDX_MAX
19230
};
19231
19232
/* Number of items in ASN.1 template for GeneralSubtree. */
19233
0
#define subTreeASN_Length (sizeof(subTreeASN) / sizeof(ASNItem))
19234
#endif
19235
19236
#ifdef WOLFSSL_ASN_TEMPLATE
19237
/* Decode the Subtree's GeneralName.
19238
 *
19239
 * @param [in]      input  Buffer holding data.
19240
 * @param [in]      sz     Size of data in buffer.
19241
 * @param [in]      tag    BER tag on GeneralName.
19242
 * @param [in, out] head   Linked list of subtree names.
19243
 * @param [in]      heap   Dynamic memory hint.
19244
 * @return  0 on success.
19245
 * @return  MEMORY_E when dynamic memory allocation fails.
19246
 * @return  ASN_PARSE_E when SEQUENCE is not found as expected.
19247
 */
19248
static int DecodeSubtreeGeneralName(const byte* input, word32 sz, byte tag,
19249
                                    Base_entry** head, void* heap)
19250
0
{
19251
0
    Base_entry* entry;
19252
0
    word32 nameIdx = 0;
19253
0
    word32 len = sz;
19254
0
    int strLen;
19255
0
    int ret = 0;
19256
19257
0
    (void)heap;
19258
19259
    /* if constructed has leading sequence */
19260
0
    if ((tag & ASN_CONSTRUCTED) == ASN_CONSTRUCTED) {
19261
0
        ret = GetASN_Sequence(input, &nameIdx, &strLen, sz, 0);
19262
0
        if (ret < 0) {
19263
0
            ret = ASN_PARSE_E;
19264
0
        }
19265
0
        else {
19266
0
            len = (word32)strLen;
19267
0
            ret = 0;
19268
0
        }
19269
0
    }
19270
0
    if (ret == 0) {
19271
        /* TODO: consider one malloc. */
19272
        /* Allocate Base Entry object. */
19273
0
        entry = (Base_entry*)XMALLOC(sizeof(Base_entry), heap,
19274
0
                                     DYNAMIC_TYPE_ALTNAME);
19275
0
        if (entry == NULL) {
19276
0
            ret = MEMORY_E;
19277
0
        }
19278
0
    }
19279
0
    if (ret == 0) {
19280
        /* Allocate name. */
19281
0
        entry->name = (char*)XMALLOC(len + 1, heap, DYNAMIC_TYPE_ALTNAME);
19282
0
        if (entry->name == NULL) {
19283
0
            XFREE(entry, heap, DYNAMIC_TYPE_ALTNAME);
19284
0
            ret = MEMORY_E;
19285
0
        }
19286
0
    }
19287
0
    if (ret == 0) {
19288
        /* Store name, size and tag in object. */
19289
0
        XMEMCPY(entry->name, &input[nameIdx], len);
19290
0
        entry->name[len] = '\0';
19291
0
        entry->nameSz = (int)len;
19292
0
        entry->type = tag & ASN_TYPE_MASK;
19293
19294
        /* Put entry at front of linked list. */
19295
0
        entry->next = *head;
19296
0
        *head = entry;
19297
0
    }
19298
19299
0
    return ret;
19300
0
}
19301
#endif
19302
19303
/* Decode a subtree of a name constraints in a certificate.
19304
 *
19305
 * X.509: RFC 5280, 4.2.1.10 - Name Contraints.
19306
 *
19307
 * @param [in]      input  Buffer holding data.
19308
 * @param [in]      sz     Size of data in buffer.
19309
 * @param [in, out] head   Linked list of subtree names.
19310
 * @param [in]      heap   Dynamic memory hint.
19311
 * @return  0 on success.
19312
 * @return  MEMORY_E when dynamic memory allocation fails.
19313
 * @return  ASN_PARSE_E when SEQUENCE is not found as expected.
19314
 */
19315
static int DecodeSubtree(const byte* input, word32 sz, Base_entry** head,
19316
                         void* heap)
19317
0
{
19318
#ifndef WOLFSSL_ASN_TEMPLATE
19319
    word32 idx = 0;
19320
    int ret = 0;
19321
19322
    (void)heap;
19323
19324
    while (idx < (word32)sz) {
19325
        int seqLength, strLength;
19326
        word32 nameIdx;
19327
        byte b, bType;
19328
19329
        if (GetSequence(input, &idx, &seqLength, sz) < 0) {
19330
            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
19331
            return ASN_PARSE_E;
19332
        }
19333
19334
        if (idx >= (word32)sz) {
19335
            WOLFSSL_MSG("\tfail: expecting tag");
19336
            return ASN_PARSE_E;
19337
        }
19338
19339
        nameIdx = idx;
19340
        b = input[nameIdx++];
19341
19342
        if (GetLength(input, &nameIdx, &strLength, sz) <= 0) {
19343
            WOLFSSL_MSG("\tinvalid length");
19344
            return ASN_PARSE_E;
19345
        }
19346
19347
        /* Get type, LSB 4-bits */
19348
        bType = (byte)(b & ASN_TYPE_MASK);
19349
19350
        if (bType == ASN_DNS_TYPE || bType == ASN_RFC822_TYPE ||
19351
                                                        bType == ASN_DIR_TYPE) {
19352
            Base_entry* entry;
19353
19354
            /* if constructed has leading sequence */
19355
            if (b & ASN_CONSTRUCTED) {
19356
                if (GetSequence(input, &nameIdx, &strLength, sz) < 0) {
19357
                    WOLFSSL_MSG("\tfail: constructed be a SEQUENCE");
19358
                    return ASN_PARSE_E;
19359
                }
19360
            }
19361
19362
            entry = (Base_entry*)XMALLOC(sizeof(Base_entry), heap,
19363
                                                          DYNAMIC_TYPE_ALTNAME);
19364
            if (entry == NULL) {
19365
                WOLFSSL_MSG("allocate error");
19366
                return MEMORY_E;
19367
            }
19368
19369
            entry->name = (char*)XMALLOC((size_t)strLength+1, heap,
19370
                DYNAMIC_TYPE_ALTNAME);
19371
            if (entry->name == NULL) {
19372
                WOLFSSL_MSG("allocate error");
19373
                XFREE(entry, heap, DYNAMIC_TYPE_ALTNAME);
19374
                return MEMORY_E;
19375
            }
19376
19377
            XMEMCPY(entry->name, &input[nameIdx], (size_t)strLength);
19378
            entry->name[strLength] = '\0';
19379
            entry->nameSz = strLength;
19380
            entry->type = bType;
19381
19382
            entry->next = *head;
19383
            *head = entry;
19384
        }
19385
19386
        idx += (word32)seqLength;
19387
    }
19388
19389
    return ret;
19390
#else
19391
0
    DECL_ASNGETDATA(dataASN, subTreeASN_Length);
19392
0
    word32 idx = 0;
19393
0
    int ret = 0;
19394
19395
0
    (void)heap;
19396
19397
0
    ALLOC_ASNGETDATA(dataASN, subTreeASN_Length, ret, heap);
19398
19399
    /* Process all subtrees. */
19400
0
    while ((ret == 0) && (idx < (word32)sz)) {
19401
0
        byte minVal = 0;
19402
0
        byte maxVal = 0;
19403
19404
        /* Clear dynamic data and set choice for GeneralName and location to
19405
         * store minimum and maximum.
19406
         */
19407
0
        XMEMSET(dataASN, 0, sizeof(*dataASN) * subTreeASN_Length);
19408
0
        GetASN_Choice(&dataASN[SUBTREEASN_IDX_BASE], generalNameChoice);
19409
0
        GetASN_Int8Bit(&dataASN[SUBTREEASN_IDX_MIN], &minVal);
19410
0
        GetASN_Int8Bit(&dataASN[SUBTREEASN_IDX_MAX], &maxVal);
19411
        /* Parse GeneralSubtree. */
19412
0
        ret = GetASN_Items(subTreeASN, dataASN, subTreeASN_Length, 0, input,
19413
0
                           &idx, sz);
19414
0
        if (ret == 0) {
19415
0
            byte t = dataASN[SUBTREEASN_IDX_BASE].tag;
19416
19417
            /* Check GeneralName tag is one of the types we can handle. */
19418
0
            if (t == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE) ||
19419
0
                t == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE) ||
19420
0
                t == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_DIR_TYPE)) {
19421
                /* Parse the general name and store a new entry. */
19422
0
                ret = DecodeSubtreeGeneralName(input +
19423
0
                    GetASNItem_DataIdx(dataASN[SUBTREEASN_IDX_BASE], input),
19424
0
                    dataASN[SUBTREEASN_IDX_BASE].length, t, head, heap);
19425
0
            }
19426
            /* Skip entry. */
19427
0
        }
19428
0
    }
19429
19430
0
    FREE_ASNGETDATA(dataASN, heap);
19431
0
    return ret;
19432
0
#endif
19433
0
}
19434
19435
#ifdef WOLFSSL_ASN_TEMPLATE
19436
/* ASN.1 template for NameConstraints.
19437
 * X.509: RFC 5280, 4.2.1.10 - Name Contraints.
19438
 */
19439
static const ASNItem nameConstraintsASN[] = {
19440
/* SEQ     */ { 0, ASN_SEQUENCE, 1, 1, 0 },
19441
                                         /* permittedSubtrees */
19442
/* PERMIT  */     { 1, ASN_CONTEXT_SPECIFIC | 0, 1, 0, 1 },
19443
                                         /* excludededSubtrees */
19444
/* EXCLUDE */     { 1, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 1 },
19445
};
19446
enum {
19447
    NAMECONSTRAINTSASN_IDX_SEQ = 0,
19448
    NAMECONSTRAINTSASN_IDX_PERMIT,
19449
    NAMECONSTRAINTSASN_IDX_EXCLUDE
19450
};
19451
19452
/* Number of items in ASN.1 template for NameConstraints. */
19453
0
#define nameConstraintsASN_Length (sizeof(nameConstraintsASN) / sizeof(ASNItem))
19454
#endif
19455
19456
/* Decode name constraints extension in a certificate.
19457
 *
19458
 * X.509: RFC 5280, 4.2.1.10 - Name Constraints.
19459
 *
19460
 * @param [in]      input  Buffer holding data.
19461
 * @param [in]      sz     Size of data in buffer.
19462
 * @param [in, out] cert   Certificate object.
19463
 * @return  0 on success.
19464
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
19465
 *          is invalid.
19466
 * @return  MEMORY_E on dynamic memory allocation failure.
19467
 */
19468
static int DecodeNameConstraints(const byte* input, word32 sz,
19469
    DecodedCert* cert)
19470
0
{
19471
#ifndef WOLFSSL_ASN_TEMPLATE
19472
    word32 idx = 0;
19473
    int length = 0;
19474
19475
    WOLFSSL_ENTER("DecodeNameConstraints");
19476
19477
    if (GetSequence(input, &idx, &length, sz) < 0) {
19478
        WOLFSSL_MSG("\tfail: should be a SEQUENCE");
19479
        return ASN_PARSE_E;
19480
    }
19481
19482
    while (idx < (word32)sz) {
19483
        byte b = input[idx++];
19484
        Base_entry** subtree = NULL;
19485
19486
        if (GetLength(input, &idx, &length, sz) <= 0) {
19487
            WOLFSSL_MSG("\tinvalid length");
19488
            return ASN_PARSE_E;
19489
        }
19490
19491
        if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0))
19492
            subtree = &cert->permittedNames;
19493
        else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1))
19494
            subtree = &cert->excludedNames;
19495
        else {
19496
            WOLFSSL_MSG("\tinvalid subtree");
19497
            return ASN_PARSE_E;
19498
        }
19499
19500
        if (DecodeSubtree(input + idx, (word32)length, subtree,
19501
                cert->heap) < 0) {
19502
            WOLFSSL_MSG("\terror parsing subtree");
19503
            return ASN_PARSE_E;
19504
        }
19505
19506
        idx += (word32)length;
19507
    }
19508
19509
    return 0;
19510
#else
19511
0
    DECL_ASNGETDATA(dataASN, nameConstraintsASN_Length);
19512
0
    word32 idx = 0;
19513
0
    int    ret = 0;
19514
19515
0
    CALLOC_ASNGETDATA(dataASN, nameConstraintsASN_Length, ret, cert->heap);
19516
19517
0
    if (ret == 0) {
19518
        /* Parse NameConstraints. */
19519
0
        ret = GetASN_Items(nameConstraintsASN, dataASN,
19520
0
                           nameConstraintsASN_Length, 1, input, &idx, sz);
19521
0
    }
19522
0
    if (ret == 0) {
19523
        /* If there was a permittedSubtrees then parse it. */
19524
0
        if (dataASN[NAMECONSTRAINTSASN_IDX_PERMIT].data.ref.data != NULL) {
19525
0
            ret = DecodeSubtree(
19526
0
                    dataASN[NAMECONSTRAINTSASN_IDX_PERMIT].data.ref.data,
19527
0
                    dataASN[NAMECONSTRAINTSASN_IDX_PERMIT].data.ref.length,
19528
0
                    &cert->permittedNames, cert->heap);
19529
0
        }
19530
0
    }
19531
0
    if (ret == 0) {
19532
        /* If there was a excludedSubtrees then parse it. */
19533
0
        if (dataASN[NAMECONSTRAINTSASN_IDX_EXCLUDE].data.ref.data != NULL) {
19534
0
            ret = DecodeSubtree(
19535
0
                    dataASN[NAMECONSTRAINTSASN_IDX_EXCLUDE].data.ref.data,
19536
0
                    dataASN[NAMECONSTRAINTSASN_IDX_EXCLUDE].data.ref.length,
19537
0
                    &cert->excludedNames, cert->heap);
19538
0
        }
19539
0
    }
19540
19541
0
    FREE_ASNGETDATA(dataASN, cert->heap);
19542
19543
0
    return ret;
19544
0
#endif /* WOLFSSL_ASN_TEMPLATE */
19545
0
}
19546
#endif /* IGNORE_NAME_CONSTRAINTS */
19547
19548
#if (defined(WOLFSSL_CERT_EXT) && !defined(WOLFSSL_SEP)) || \
19549
    defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
19550
19551
/* Decode ITU-T X.690 OID format to a string representation
19552
 * return string length */
19553
int DecodePolicyOID(char *out, word32 outSz, const byte *in, word32 inSz)
19554
{
19555
    word32 val, inIdx = 0, outIdx = 0;
19556
    int w = 0;
19557
19558
    if (out == NULL || in == NULL || outSz < 4 || inSz < 2)
19559
        return BAD_FUNC_ARG;
19560
19561
    /* The first byte expands into b/40 dot b%40. */
19562
    val = in[inIdx++];
19563
19564
    w = XSNPRINTF(out, outSz, "%u.%u", val / 40, val % 40);
19565
    if (w < 0) {
19566
        w = BUFFER_E;
19567
        goto exit;
19568
    }
19569
    outIdx += (word32)w;
19570
    val = 0;
19571
19572
    while (inIdx < inSz && outIdx < outSz) {
19573
        /* extract the next OID digit from in to val */
19574
        /* first bit is used to set if value is coded on 1 or multiple bytes */
19575
        if (in[inIdx] & 0x80) {
19576
            val += in[inIdx] & 0x7F;
19577
            val *= 128;
19578
        }
19579
        else {
19580
            /* write val as text into out */
19581
            val += in[inIdx];
19582
            w = XSNPRINTF(out + outIdx, outSz - outIdx, ".%u", val);
19583
            if (w < 0 || (word32)w > outSz - outIdx) {
19584
                w = BUFFER_E;
19585
                goto exit;
19586
            }
19587
            outIdx += (word32)w;
19588
            val = 0;
19589
        }
19590
        inIdx++;
19591
    }
19592
    if (outIdx == outSz)
19593
        outIdx--;
19594
    out[outIdx] = 0;
19595
19596
    w = (int)outIdx;
19597
19598
exit:
19599
    return w;
19600
}
19601
#endif /* WOLFSSL_CERT_EXT && !WOLFSSL_SEP */
19602
19603
#if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_QT)
19604
    #ifdef WOLFSSL_ASN_TEMPLATE
19605
    /* ASN.1 template for PolicyInformation.
19606
     * X.509: RFC 5280, 4.2.1.4 - Certificate Policies.
19607
     */
19608
    static const ASNItem policyInfoASN[] = {
19609
    /* SEQ   */ { 0, ASN_SEQUENCE, 1, 1, 0 },
19610
                                      /* policyIdentifier */
19611
    /* ID    */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
19612
                                      /* policyQualifiers */
19613
    /* QUALI */     { 1, ASN_SEQUENCE, 1, 0, 1 },
19614
    };
19615
    enum {
19616
        POLICYINFOASN_IDX_SEQ = 0,
19617
        POLICYINFOASN_IDX_ID,
19618
        POLICYINFOASN_IDX_QUALI
19619
    };
19620
19621
    /* Number of items in ASN.1 template for PolicyInformation. */
19622
    #define policyInfoASN_Length (sizeof(policyInfoASN) / sizeof(ASNItem))
19623
    #endif
19624
19625
    /* Reference: https://tools.ietf.org/html/rfc5280#section-4.2.1.4 */
19626
    static int DecodeCertPolicy(const byte* input, word32 sz, DecodedCert* cert)
19627
    {
19628
    #ifndef WOLFSSL_ASN_TEMPLATE
19629
        word32 idx = 0;
19630
        word32 oldIdx;
19631
        int policy_length = 0;
19632
        int ret;
19633
        int total_length = 0;
19634
    #if !defined(WOLFSSL_SEP) && defined(WOLFSSL_CERT_EXT) && \
19635
        !defined(WOLFSSL_DUP_CERTPOL)
19636
        int i;
19637
    #endif
19638
19639
        WOLFSSL_ENTER("DecodeCertPolicy");
19640
19641
    #if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT)
19642
        /* Check if cert is null before dereferencing below */
19643
        if (cert == NULL)
19644
            return BAD_FUNC_ARG;
19645
    #else
19646
        (void)cert;
19647
    #endif
19648
19649
    #if defined(WOLFSSL_CERT_EXT)
19650
         cert->extCertPoliciesNb = 0;
19651
    #endif
19652
19653
        if (GetSequence(input, &idx, &total_length, sz) < 0) {
19654
            WOLFSSL_MSG("\tGet CertPolicy total seq failed");
19655
            return ASN_PARSE_E;
19656
        }
19657
19658
        /* Validate total length */
19659
        if (total_length > (int)(sz - idx)) {
19660
            WOLFSSL_MSG("\tCertPolicy length mismatch");
19661
            return ASN_PARSE_E;
19662
        }
19663
19664
        /* Unwrap certificatePolicies */
19665
        do {
19666
            int length = 0;
19667
19668
            if (GetSequence(input, &idx, &policy_length, sz) < 0) {
19669
                WOLFSSL_MSG("\tGet CertPolicy seq failed");
19670
                return ASN_PARSE_E;
19671
            }
19672
19673
            oldIdx = idx;
19674
            ret = GetASNObjectId(input, &idx, &length, sz);
19675
            if (ret != 0)
19676
                return ret;
19677
            policy_length -= (int)(idx - oldIdx);
19678
19679
            if (length > 0) {
19680
                /* Verify length won't overrun buffer */
19681
                if (length > (int)(sz - idx)) {
19682
                    WOLFSSL_MSG("\tCertPolicy length exceeds input buffer");
19683
                    return ASN_PARSE_E;
19684
                }
19685
19686
        #if defined(WOLFSSL_SEP)
19687
                cert->deviceType = (byte*)XMALLOC((size_t)length, cert->heap,
19688
                                                         DYNAMIC_TYPE_X509_EXT);
19689
                if (cert->deviceType == NULL) {
19690
                    WOLFSSL_MSG("\tCouldn't alloc memory for deviceType");
19691
                    return MEMORY_E;
19692
                }
19693
                cert->deviceTypeSz = length;
19694
                XMEMCPY(cert->deviceType, input + idx, (size_t)length);
19695
                break;
19696
        #elif defined(WOLFSSL_CERT_EXT)
19697
                /* decode cert policy */
19698
                if (DecodePolicyOID(cert->extCertPolicies[
19699
                                       cert->extCertPoliciesNb], MAX_CERTPOL_SZ,
19700
                                       input + idx, length) <= 0) {
19701
                    WOLFSSL_MSG("\tCouldn't decode CertPolicy");
19702
                    WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
19703
                    return ASN_PARSE_E;
19704
                }
19705
            #ifndef WOLFSSL_DUP_CERTPOL
19706
                /* From RFC 5280 section 4.2.1.3 "A certificate policy OID MUST
19707
                 * NOT appear more than once in a certificate policies
19708
                 * extension". This is a sanity check for duplicates.
19709
                 * extCertPolicies should only have OID values, additional
19710
                 * qualifiers need to be stored in a separate array. */
19711
                for (i = 0; i < cert->extCertPoliciesNb; i++) {
19712
                    if (XMEMCMP(cert->extCertPolicies[i],
19713
                            cert->extCertPolicies[cert->extCertPoliciesNb],
19714
                            MAX_CERTPOL_SZ) == 0) {
19715
                            WOLFSSL_MSG("Duplicate policy OIDs not allowed");
19716
                            WOLFSSL_MSG("Use WOLFSSL_DUP_CERTPOL if wanted");
19717
                            WOLFSSL_ERROR_VERBOSE(CERTPOLICIES_E);
19718
                            return CERTPOLICIES_E;
19719
                    }
19720
                }
19721
            #endif /* !WOLFSSL_DUP_CERTPOL */
19722
                cert->extCertPoliciesNb++;
19723
        #else
19724
                WOLFSSL_LEAVE("DecodeCertPolicy : unsupported mode", 0);
19725
                return 0;
19726
        #endif
19727
            }
19728
            idx += (word32)policy_length;
19729
        } while((int)idx < total_length
19730
    #if defined(WOLFSSL_CERT_EXT)
19731
            && cert->extCertPoliciesNb < MAX_CERTPOL_NB
19732
    #endif
19733
        );
19734
19735
        WOLFSSL_LEAVE("DecodeCertPolicy", 0);
19736
        return 0;
19737
    #else /* WOLFSSL_ASN_TEMPLATE */
19738
        word32 idx = 0;
19739
        int ret = 0;
19740
        int total_length = 0;
19741
    #if !defined(WOLFSSL_SEP) && defined(WOLFSSL_CERT_EXT) && \
19742
        !defined(WOLFSSL_DUP_CERTPOL)
19743
        int i;
19744
    #endif
19745
19746
        WOLFSSL_ENTER("DecodeCertPolicy");
19747
        #if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT)
19748
        /* Check if cert is null before dereferencing below */
19749
        if (cert == NULL)
19750
            ret = BAD_FUNC_ARG;
19751
        #endif
19752
19753
        if (ret == 0) {
19754
        #if defined(WOLFSSL_CERT_EXT)
19755
            cert->extCertPoliciesNb = 0;
19756
        #endif
19757
19758
            /* Strip SEQUENCE OF and check using all data. */
19759
            if (GetASN_Sequence(input, &idx, &total_length, (word32)sz, 1) < 0)
19760
            {
19761
               ret = ASN_PARSE_E;
19762
            }
19763
        }
19764
19765
        /* Unwrap certificatePolicies */
19766
        while ((ret == 0) && ((int)idx < total_length)
19767
        #if defined(WOLFSSL_CERT_EXT)
19768
            && (cert->extCertPoliciesNb < MAX_CERTPOL_NB)
19769
        #endif
19770
               ) {
19771
            ASNGetData dataASN[policyInfoASN_Length];
19772
            byte* data = NULL;
19773
            word32 length = 0;
19774
19775
            /* Clear dynamic data and check OID is a cert policy type. */
19776
            XMEMSET(dataASN, 0, sizeof(dataASN));
19777
            GetASN_OID(&dataASN[POLICYINFOASN_IDX_ID], oidCertPolicyType);
19778
            ret = GetASN_Items(policyInfoASN, dataASN, policyInfoASN_Length, 1,
19779
                               input, &idx, (word32)sz);
19780
            if (ret == 0) {
19781
                /* Get the OID. */
19782
                GetASN_OIDData(&dataASN[POLICYINFOASN_IDX_ID], &data, &length);
19783
                if (length == 0) {
19784
                    ret = ASN_PARSE_E;
19785
                }
19786
            }
19787
            #if defined(WOLFSSL_SEP)
19788
            /* Store OID in device type. */
19789
            if (ret == 0) {
19790
                cert->deviceType = (byte*)XMALLOC(length, cert->heap,
19791
                                                  DYNAMIC_TYPE_X509_EXT);
19792
                if (cert->deviceType == NULL) {
19793
                    WOLFSSL_MSG("\tCouldn't alloc memory for deviceType");
19794
                    ret = MEMORY_E;
19795
                }
19796
            }
19797
            if (ret == 0) {
19798
                /* Store device type data and length. */
19799
                cert->deviceTypeSz = (int)length;
19800
                XMEMCPY(cert->deviceType, data, length);
19801
                break;
19802
            }
19803
            #elif defined(WOLFSSL_CERT_EXT)
19804
            if (ret == 0) {
19805
                /* Decode cert policy. */
19806
                if (DecodePolicyOID(
19807
                                 cert->extCertPolicies[cert->extCertPoliciesNb],
19808
                                 MAX_CERTPOL_SZ, data, length) <= 0) {
19809
                    WOLFSSL_MSG("\tCouldn't decode CertPolicy");
19810
                    WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
19811
                    ret = ASN_PARSE_E;
19812
                }
19813
            }
19814
            #ifndef WOLFSSL_DUP_CERTPOL
19815
            /* From RFC 5280 section 4.2.1.3 "A certificate policy OID MUST
19816
             * NOT appear more than once in a certificate policies
19817
             * extension". This is a sanity check for duplicates.
19818
             * extCertPolicies should only have OID values, additional
19819
             * qualifiers need to be stored in a seperate array. */
19820
            for (i = 0; (ret == 0) && (i < cert->extCertPoliciesNb); i++) {
19821
                if (XMEMCMP(cert->extCertPolicies[i],
19822
                            cert->extCertPolicies[cert->extCertPoliciesNb],
19823
                            MAX_CERTPOL_SZ) == 0) {
19824
                    WOLFSSL_MSG("Duplicate policy OIDs not allowed");
19825
                    WOLFSSL_MSG("Use WOLFSSL_DUP_CERTPOL if wanted");
19826
                    WOLFSSL_ERROR_VERBOSE(CERTPOLICIES_E);
19827
                    ret = CERTPOLICIES_E;
19828
                }
19829
            }
19830
            #endif /* !defined(WOLFSSL_DUP_CERTPOL) */
19831
            if (ret == 0) {
19832
                /* Keep count of policies seen. */
19833
                cert->extCertPoliciesNb++;
19834
            }
19835
            #else
19836
                (void)data;
19837
                WOLFSSL_LEAVE("DecodeCertPolicy : unsupported mode", 0);
19838
                break;
19839
            #endif
19840
        }
19841
19842
        WOLFSSL_LEAVE("DecodeCertPolicy", 0);
19843
        return ret;
19844
    #endif /* WOLFSSL_ASN_TEMPLATE */
19845
    }
19846
#endif /* WOLFSSL_SEP */
19847
19848
#ifdef WOLFSSL_SUBJ_DIR_ATTR
19849
#ifdef WOLFSSL_ASN_TEMPLATE
19850
/* ASN.1 template for subject dir attribute.
19851
 * X.509: RFC 5280, 4.2.1.8 - Subject Directory Attributes.
19852
 */
19853
static const ASNItem subjDirAttrASN[] = {
19854
/* SEQ  */     { 1, ASN_SEQUENCE, 1, 1, 0 },
19855
/* OID  */          { 2, ASN_OBJECT_ID, 0, 0, 0 },
19856
/* PLEN */          { 2, ASN_SET, 1, 0, 0 },
19857
};
19858
enum {
19859
    SUBJDIRATTRASN_IDX_SEQ = 0,
19860
    SUBJDIRATTRASN_IDX_OID,
19861
    SUBJDIRATTRASN_IDX_SET,
19862
};
19863
19864
/* Number of items in ASN.1 template for BasicContraints. */
19865
#define subjDirAttrASN_Length (sizeof(subjDirAttrASN) / sizeof(ASNItem))
19866
#endif
19867
/* Decode subject directory attributes extension in a certificate.
19868
 *
19869
 * X.509: RFC 5280, 4.2.1.8 - Subject Directory Attributes.
19870
 *
19871
 * @param [in]      input  Buffer holding data.
19872
 * @param [in]      sz     Size of data in buffer.
19873
 * @param [in, out] cert   Certificate object.
19874
 * @return  0 on success.
19875
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
19876
 *          is invalid.
19877
 */
19878
static int DecodeSubjDirAttr(const byte* input, word32 sz, DecodedCert* cert)
19879
{
19880
#ifndef WOLFSSL_ASN_TEMPLATE
19881
    word32 idx = 0;
19882
    int length = 0;
19883
    int ret = 0;
19884
19885
    WOLFSSL_ENTER("DecodeSubjDirAttr");
19886
19887
#ifdef OPENSSL_ALL
19888
    cert->extSubjDirAttrSrc = input;
19889
    cert->extSubjDirAttrSz = sz;
19890
#endif /* OPENSSL_ALL */
19891
19892
    /* Unwrap the list of Attributes */
19893
    if (GetSequence(input, &idx, &length, sz) < 0)
19894
        return ASN_PARSE_E;
19895
19896
    if (length == 0) {
19897
        /* RFC 5280 4.2.1.8.  Subject Directory Attributes
19898
           If the subjectDirectoryAttributes extension is present, the
19899
           sequence MUST contain at least one entry. */
19900
        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
19901
        return ASN_PARSE_E;
19902
    }
19903
19904
    /* length is the length of the list contents */
19905
    while (idx < (word32)sz) {
19906
        word32 oid;
19907
19908
        if (GetSequence(input, &idx, &length, sz) < 0)
19909
            return ASN_PARSE_E;
19910
19911
        if (GetObjectId(input, &idx, &oid, oidSubjDirAttrType, sz) < 0)
19912
            return ASN_PARSE_E;
19913
19914
        if (GetSet(input, &idx, &length, sz) < 0)
19915
            return ASN_PARSE_E;
19916
19917
        /* There may be more than one countryOfCitizenship, but save the
19918
         * first one for now. */
19919
        if (oid == SDA_COC_OID) {
19920
            byte tag;
19921
19922
            if (GetHeader(input, &tag, &idx, &length, sz, 1) < 0)
19923
                return ASN_PARSE_E;
19924
19925
            if (length != COUNTRY_CODE_LEN)
19926
                return ASN_PARSE_E;
19927
19928
            if (tag == ASN_PRINTABLE_STRING) {
19929
                XMEMCPY(cert->countryOfCitizenship,
19930
                        input + idx, COUNTRY_CODE_LEN);
19931
                cert->countryOfCitizenship[COUNTRY_CODE_LEN] = 0;
19932
            }
19933
        }
19934
        idx += length;
19935
    }
19936
19937
    return ret;
19938
#else
19939
    DECL_ASNGETDATA(dataASN, subjDirAttrASN_Length);
19940
    int ret = 0;
19941
    word32 idx = 0;
19942
    int length;
19943
19944
    WOLFSSL_ENTER("DecodeSubjDirAttr");
19945
19946
    CALLOC_ASNGETDATA(dataASN, subjDirAttrASN_Length, ret, cert->heap);
19947
19948
    /* Strip outer SEQUENCE. */
19949
    if ((ret == 0) && (GetSequence(input, &idx, &length, sz) < 0)) {
19950
        ret = ASN_PARSE_E;
19951
    }
19952
    /* Handle each inner SEQUENCE. */
19953
    while ((ret == 0) && (idx < (word32)sz)) {
19954
        ret = GetASN_Items(subjDirAttrASN, dataASN, subjDirAttrASN_Length, 1,
19955
            input, &idx, sz);
19956
19957
        /* There may be more than one countryOfCitizenship, but save the
19958
         * first one for now. */
19959
        if ((ret == 0) &&
19960
                (dataASN[SUBJDIRATTRASN_IDX_OID].data.oid.sum == SDA_COC_OID)) {
19961
            int cuLen;
19962
            word32 setIdx = 0;
19963
            byte* setData;
19964
            word32 setLen;
19965
19966
            GetASN_GetRef(&dataASN[SUBJDIRATTRASN_IDX_SET], &setData, &setLen);
19967
            if (GetASNHeader(setData, ASN_PRINTABLE_STRING, &setIdx, &cuLen,
19968
                    setLen) < 0) {
19969
                ret = ASN_PARSE_E;
19970
            }
19971
            if ((ret == 0) && (cuLen != COUNTRY_CODE_LEN)) {
19972
                ret = ASN_PARSE_E;
19973
            }
19974
            if (ret == 0) {
19975
                XMEMCPY(cert->countryOfCitizenship, setData + setIdx,
19976
                    (size_t)cuLen);
19977
                cert->countryOfCitizenship[COUNTRY_CODE_LEN] = 0;
19978
            }
19979
        }
19980
    }
19981
    FREE_ASNGETDATA(dataASN, cert->heap);
19982
    return ret;
19983
#endif /* WOLFSSL_ASN_TEMPLATE */
19984
}
19985
#endif /* WOLFSSL_SUBJ_DIR_ATTR */
19986
19987
#ifdef WOLFSSL_SUBJ_INFO_ACC
19988
/* Decode subject infomation access extension in a certificate.
19989
 *
19990
 * X.509: RFC 5280, 4.2.2.2 - Subject Information Access.
19991
 *
19992
 * @param [in]      input  Buffer holding data.
19993
 * @param [in]      sz     Size of data in buffer.
19994
 * @param [in, out] cert   Certificate object.
19995
 * @return  0 on success.
19996
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
19997
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
19998
 *          is invalid.
19999
 * @return  MEMORY_E on dynamic memory allocation failure.
20000
 */
20001
static int DecodeSubjInfoAcc(const byte* input, word32 sz, DecodedCert* cert)
20002
{
20003
    word32 idx = 0;
20004
    int length = 0;
20005
    int ret = 0;
20006
20007
    WOLFSSL_ENTER("DecodeSubjInfoAcc");
20008
20009
#ifdef OPENSSL_ALL
20010
    cert->extSubjAltNameSrc = input;
20011
    cert->extSubjAltNameSz = sz;
20012
#endif /* OPENSSL_ALL */
20013
20014
    /* Unwrap SubjectInfoAccessSyntax, the list of AccessDescriptions */
20015
    if (GetSequence(input, &idx, &length, sz) < 0)
20016
        return ASN_PARSE_E;
20017
20018
    if (length == 0) {
20019
        /* RFC 5280 4.2.2.2.  Subject Information Access
20020
           If the subjectInformationAccess extension is present, the
20021
           sequence MUST contain at least one entry. */
20022
        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
20023
        return ASN_PARSE_E;
20024
    }
20025
20026
    /* Per fpkx-x509-cert-profile-common... section 5.3.
20027
     * [The] subjectInfoAccess extension must contain at least one
20028
     * instance of the id-ad-caRepository access method containing a
20029
     * publicly accessible HTTP URI which returns as certs-only
20030
     * CMS.
20031
     */
20032
20033
    while (idx < (word32)sz) {
20034
        word32 oid = 0;
20035
        byte b;
20036
20037
        /* Unwrap an AccessDescription */
20038
        if (GetSequence(input, &idx, &length, sz) < 0)
20039
            return ASN_PARSE_E;
20040
20041
        /* Get the accessMethod */
20042
        if (GetObjectId(input, &idx, &oid, oidCertAuthInfoType, sz) < 0)
20043
            return ASN_PARSE_E;
20044
20045
        /* Only supporting URIs right now. */
20046
        if (GetASNTag(input, &idx, &b, sz) < 0)
20047
            return ASN_PARSE_E;
20048
20049
        if (GetLength(input, &idx, &length, sz) < 0)
20050
            return ASN_PARSE_E;
20051
20052
        /* Set caRepo entry */
20053
        if (b == GENERALNAME_URI && oid == AIA_CA_REPO_OID) {
20054
            cert->extSubjInfoAccCaRepoSz = (word32)length;
20055
            cert->extSubjInfoAccCaRepo = input + idx;
20056
            break;
20057
        }
20058
        idx += (word32)length;
20059
    }
20060
20061
    if (cert->extSubjInfoAccCaRepo == NULL ||
20062
            cert->extSubjInfoAccCaRepoSz == 0) {
20063
        WOLFSSL_MSG("SubjectInfoAccess missing an URL.");
20064
        ret = ASN_PARSE_E;
20065
    }
20066
20067
    WOLFSSL_LEAVE("DecodeSubjInfoAcc", ret);
20068
    return ret;
20069
}
20070
#endif /* WOLFSSL_SUBJ_INFO_ACC */
20071
20072
/* Macro to check if bit is set, if not sets and return success.
20073
    Otherwise returns failure */
20074
/* Macro required here because bit-field operation */
20075
#ifndef WOLFSSL_NO_ASN_STRICT
20076
    #define VERIFY_AND_SET_OID(bit) \
20077
0
        if ((bit) == 0) \
20078
0
            (bit) = 1; \
20079
0
        else \
20080
0
            return ASN_OBJECT_ID_E;
20081
#else
20082
    /* With no strict defined, the verify is skipped */
20083
#define VERIFY_AND_SET_OID(bit) bit = 1;
20084
#endif
20085
20086
/* Parse extension type specific data based on OID sum.
20087
 *
20088
 * Supported extensions:
20089
 *   Basic Constraints - BASIC_CA_OID
20090
 *   CRL Distribution Points - CRL_DIST_OID
20091
 *   Authority Information Access - AUTH_INFO_OID
20092
 *   Subject Alternative Name - ALT_NAMES_OID
20093
 *   Authority Key Identifier - AUTH_KEY_OID
20094
 *   Subject Key Identifier - SUBJ_KEY_OID
20095
 *   Certificate Policies - CERT_POLICY_OID (conditional parsing)
20096
 *   Key Usage - KEY_USAGE_OID
20097
 *   Extended Key Usage - EXT_KEY_USAGE_OID
20098
 *   Name Constraints - NAME_CONS_OID
20099
 *   Inhibit anyPolicy - INHIBIT_ANY_OID
20100
 *   Netscape Certificate Type - NETSCAPE_CT_OID (able to be excluded)
20101
 *   OCSP no check - OCSP_NOCHECK_OID (when compiling OCSP)
20102
 *   Subject Directory Attributes - SUBJ_DIR_ATTR_OID
20103
 *   Subject Information Access - SUBJ_INFO_ACC_OID
20104
 * Unsupported extensions from RFC 5280:
20105
 *   4.2.1.5 - Policy mappings
20106
 *   4.2.1.7 - Issuer Alternative Name
20107
 *   4.2.1.11 - Policy Constraints
20108
 *   4.2.1.15 - Freshest CRL
20109
 *
20110
 * @param [in]      input     Buffer containing extension type specific data.
20111
 * @param [in]      length    Length of data.
20112
 * @param [in]      oid       OID sum for extension.
20113
 * @param [in]      critical  Whether extension is critical.
20114
 * @param [in, out] cert      Certificate object.
20115
 * @return  0 on success.
20116
 * @return  ASN_PARSE_E when BER encoding is invalid.
20117
 * @return  MEMORY_E on dynamic memory allocation failure.
20118
 * @return  Other negative values on error.
20119
 */
20120
static int DecodeExtensionType(const byte* input, word32 length, word32 oid,
20121
                               byte critical, DecodedCert* cert,
20122
                               int *isUnknownExt)
20123
0
{
20124
0
    int ret = 0;
20125
0
    word32 idx = 0;
20126
20127
0
    if (isUnknownExt != NULL)
20128
0
        *isUnknownExt = 0;
20129
20130
0
    switch (oid) {
20131
        /* Basic Constraints. */
20132
0
        case BASIC_CA_OID:
20133
0
            VERIFY_AND_SET_OID(cert->extBasicConstSet);
20134
0
            cert->extBasicConstCrit = critical ? 1 : 0;
20135
0
            if (DecodeBasicCaConstraint(input, (int)length, cert) < 0) {
20136
0
                ret = ASN_PARSE_E;
20137
0
            }
20138
0
            break;
20139
20140
        /* CRL Distribution point. */
20141
0
        case CRL_DIST_OID:
20142
0
            VERIFY_AND_SET_OID(cert->extCRLdistSet);
20143
0
            cert->extCRLdistCrit = critical ? 1 : 0;
20144
0
            if (DecodeCrlDist(input, length, cert) < 0) {
20145
0
                ret = ASN_PARSE_E;
20146
0
            }
20147
0
            break;
20148
20149
        /* Authority information access. */
20150
0
        case AUTH_INFO_OID:
20151
0
            VERIFY_AND_SET_OID(cert->extAuthInfoSet);
20152
0
            cert->extAuthInfoCrit = critical ? 1 : 0;
20153
0
            if (DecodeAuthInfo(input, length, cert) < 0) {
20154
0
                ret = ASN_PARSE_E;
20155
0
            }
20156
0
            break;
20157
20158
        /* Subject alternative name. */
20159
0
        case ALT_NAMES_OID:
20160
0
            VERIFY_AND_SET_OID(cert->extSubjAltNameSet);
20161
0
            cert->extSubjAltNameCrit = critical ? 1 : 0;
20162
0
            ret = DecodeAltNames(input, length, cert);
20163
0
            break;
20164
20165
        /* Authority Key Identifier. */
20166
0
        case AUTH_KEY_OID:
20167
0
            VERIFY_AND_SET_OID(cert->extAuthKeyIdSet);
20168
0
            cert->extAuthKeyIdCrit = critical ? 1 : 0;
20169
0
            #ifndef WOLFSSL_ALLOW_CRIT_SKID
20170
                /* This check is added due to RFC 5280 section 4.2.1.1
20171
                 * stating that conforming CA's must mark this extension
20172
                 * as non-critical. When parsing extensions check that
20173
                 * certificate was made in compliance with this. */
20174
0
                if (critical) {
20175
0
                    WOLFSSL_MSG("Critical Auth Key ID is not allowed");
20176
0
                    WOLFSSL_MSG("Use macro WOLFSSL_ALLOW_CRIT_SKID if wanted");
20177
0
                    ret = ASN_CRIT_EXT_E;
20178
0
                }
20179
0
            #endif
20180
0
            if ((ret == 0) && (DecodeAuthKeyId(input, length, cert) < 0)) {
20181
0
                ret = ASN_PARSE_E;
20182
0
            }
20183
0
            break;
20184
20185
        /* Subject Key Identifier. */
20186
0
        case SUBJ_KEY_OID:
20187
0
            VERIFY_AND_SET_OID(cert->extSubjKeyIdSet);
20188
0
            cert->extSubjKeyIdCrit = critical ? 1 : 0;
20189
0
            #ifndef WOLFSSL_ALLOW_CRIT_SKID
20190
                /* This check is added due to RFC 5280 section 4.2.1.2
20191
                 * stating that conforming CA's must mark this extension
20192
                 * as non-critical. When parsing extensions check that
20193
                 * certificate was made in compliance with this. */
20194
0
                if (critical) {
20195
0
                    WOLFSSL_MSG("Critical Subject Key ID is not allowed");
20196
0
                    WOLFSSL_MSG("Use macro WOLFSSL_ALLOW_CRIT_SKID if wanted");
20197
0
                    ret = ASN_CRIT_EXT_E;
20198
0
                }
20199
0
            #endif
20200
20201
0
            if ((ret == 0) && (DecodeSubjKeyId(input, length, cert) < 0)) {
20202
0
                ret = ASN_PARSE_E;
20203
0
            }
20204
0
            break;
20205
20206
        /* Certificate policies. */
20207
0
        case CERT_POLICY_OID:
20208
            #if defined(WOLFSSL_SEP) || defined(WOLFSSL_QT)
20209
                VERIFY_AND_SET_OID(cert->extCertPolicySet);
20210
                #if defined(OPENSSL_EXTRA) || \
20211
                    defined(OPENSSL_EXTRA_X509_SMALL)
20212
                    cert->extCertPolicyCrit = critical ? 1 : 0;
20213
                #endif
20214
            #endif
20215
            #if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT) || \
20216
                defined(WOLFSSL_QT)
20217
                if (DecodeCertPolicy(input, length, cert) < 0) {
20218
                    ret = ASN_PARSE_E;
20219
                }
20220
            #else
20221
0
                WOLFSSL_MSG("Certificate Policy extension not supported yet.");
20222
0
            #endif
20223
0
            break;
20224
20225
        /* Key usage. */
20226
0
        case KEY_USAGE_OID:
20227
0
            VERIFY_AND_SET_OID(cert->extKeyUsageSet);
20228
0
            cert->extKeyUsageCrit = critical ? 1 : 0;
20229
0
            if (DecodeKeyUsage(input, length, cert) < 0) {
20230
0
                ret = ASN_PARSE_E;
20231
0
            }
20232
0
            break;
20233
20234
        /* Extended key usage. */
20235
0
        case EXT_KEY_USAGE_OID:
20236
0
            VERIFY_AND_SET_OID(cert->extExtKeyUsageSet);
20237
0
            cert->extExtKeyUsageCrit = critical ? 1 : 0;
20238
0
            if (DecodeExtKeyUsage(input, length, cert) < 0) {
20239
0
                ret = ASN_PARSE_E;
20240
0
            }
20241
0
            break;
20242
20243
0
        #ifndef IGNORE_NAME_CONSTRAINTS
20244
        /* Name constraints. */
20245
0
        case NAME_CONS_OID:
20246
0
        #ifndef WOLFSSL_NO_ASN_STRICT
20247
            /* Verify RFC 5280 Sec 4.2.1.10 rule:
20248
                "The name constraints extension,
20249
                which MUST be used only in a CA certificate" */
20250
0
            if (!cert->isCA) {
20251
0
                WOLFSSL_MSG("Name constraints allowed only for CA certs");
20252
0
                WOLFSSL_ERROR_VERBOSE(ASN_NAME_INVALID_E);
20253
0
                ret = ASN_NAME_INVALID_E;
20254
0
            }
20255
0
        #endif
20256
0
            VERIFY_AND_SET_OID(cert->extNameConstraintSet);
20257
0
            cert->extNameConstraintCrit = critical ? 1 : 0;
20258
0
            if (DecodeNameConstraints(input, length, cert) < 0) {
20259
0
                ret = ASN_PARSE_E;
20260
0
            }
20261
0
            break;
20262
0
        #endif /* IGNORE_NAME_CONSTRAINTS */
20263
20264
        /* Inhibit anyPolicy. */
20265
0
        case INHIBIT_ANY_OID:
20266
0
            VERIFY_AND_SET_OID(cert->inhibitAnyOidSet);
20267
0
            WOLFSSL_MSG("Inhibit anyPolicy extension not supported yet.");
20268
0
            break;
20269
20270
0
   #ifndef IGNORE_NETSCAPE_CERT_TYPE
20271
        /* Netscape's certificate type. */
20272
0
        case NETSCAPE_CT_OID:
20273
0
            if (DecodeNsCertType(input, (int)length, cert) < 0)
20274
0
                ret = ASN_PARSE_E;
20275
0
            break;
20276
0
    #endif
20277
    #ifdef HAVE_OCSP
20278
        /* OCSP no check. */
20279
        case OCSP_NOCHECK_OID:
20280
            VERIFY_AND_SET_OID(cert->ocspNoCheckSet);
20281
            ret = GetASNNull(input, &idx, length);
20282
            if (ret != 0) {
20283
                ret = ASN_PARSE_E;
20284
            }
20285
            break;
20286
    #endif
20287
0
        case POLICY_CONST_OID:
20288
0
            VERIFY_AND_SET_OID(cert->extPolicyConstSet);
20289
0
            cert->extPolicyConstCrit = critical ? 1 : 0;
20290
0
            if (DecodePolicyConstraints(&input[idx], (int)length, cert) < 0)
20291
0
                return ASN_PARSE_E;
20292
0
            break;
20293
    #ifdef WOLFSSL_SUBJ_DIR_ATTR
20294
        case SUBJ_DIR_ATTR_OID:
20295
            VERIFY_AND_SET_OID(cert->extSubjDirAttrSet);
20296
            if (DecodeSubjDirAttr(&input[idx], length, cert) < 0)
20297
                return ASN_PARSE_E;
20298
            break;
20299
    #endif
20300
    #ifdef WOLFSSL_SUBJ_INFO_ACC
20301
        case SUBJ_INFO_ACC_OID:
20302
            VERIFY_AND_SET_OID(cert->extSubjInfoAccSet);
20303
            if (DecodeSubjInfoAcc(&input[idx], length, cert) < 0)
20304
                return ASN_PARSE_E;
20305
            break;
20306
    #endif
20307
0
        default:
20308
0
            if (isUnknownExt != NULL)
20309
0
                *isUnknownExt = 1;
20310
0
        #ifndef WOLFSSL_NO_ASN_STRICT
20311
            /* While it is a failure to not support critical extensions,
20312
             * still parse the certificate ignoring the unsupported
20313
             * extension to allow caller to accept it with the verify
20314
             * callback. */
20315
0
            if (critical) {
20316
0
                WOLFSSL_ERROR_VERBOSE(ASN_CRIT_EXT_E);
20317
0
                ret = ASN_CRIT_EXT_E;
20318
0
            }
20319
0
        #endif
20320
0
            break;
20321
0
    }
20322
20323
0
    return ret;
20324
0
}
20325
20326
#ifdef WOLFSSL_ASN_TEMPLATE
20327
/* ASN.1 template for extensions.
20328
 * X.509: RFC 5280, 4.1 - Basic Certificate Fields.
20329
 */
20330
static const ASNItem certExtHdrASN[] = {
20331
/* EXTTAG */ { 0, ASN_CONTEXT_SPECIFIC | 3, 1, 1, 0 },
20332
/* EXTSEQ */     { 1, ASN_SEQUENCE, 1, 1, 0 },
20333
};
20334
enum {
20335
    CERTEXTHDRASN_IDX_EXTTAG = 0,
20336
    CERTEXTHDRASN_IDX_EXTSEQ
20337
};
20338
20339
/* Number of itesm in ASN.1 template for extensions. */
20340
0
#define certExtHdrASN_Length (sizeof(certExtHdrASN) / sizeof(ASNItem))
20341
20342
/* ASN.1 template for Extension.
20343
 * X.509: RFC 5280, 4.1 - Basic Certificate Fields.
20344
 */
20345
static const ASNItem certExtASN[] = {
20346
/* SEQ  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
20347
                              /* Extension object id */
20348
/* OID  */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
20349
                              /* critical - when true, must be parseable. */
20350
/* CRIT */     { 1, ASN_BOOLEAN, 0, 0, 1 },
20351
                              /* Data for extension - leave index at start of data. */
20352
/* VAL  */     { 1, ASN_OCTET_STRING, 0, 1, 0 },
20353
};
20354
enum {
20355
    CERTEXTASN_IDX_SEQ = 0,
20356
    CERTEXTASN_IDX_OID,
20357
    CERTEXTASN_IDX_CRIT,
20358
    CERTEXTASN_IDX_VAL
20359
};
20360
20361
/* Number of items in ASN.1 template for Extension. */
20362
0
#define certExtASN_Length (sizeof(certExtASN) / sizeof(ASNItem))
20363
#endif
20364
20365
#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_ASN_TEMPLATE) \
20366
    && defined(HAVE_OID_DECODING)
20367
int wc_SetUnknownExtCallback(DecodedCert* cert,
20368
                             wc_UnknownExtCallback cb) {
20369
    if (cert == NULL) {
20370
        return BAD_FUNC_ARG;
20371
    }
20372
20373
    cert->unknownExtCallback = cb;
20374
    return 0;
20375
}
20376
#endif
20377
20378
/*
20379
 *  Processing the Certificate Extensions. This does not modify the current
20380
 *  index. It is works starting with the recorded extensions pointer.
20381
 */
20382
static int DecodeCertExtensions(DecodedCert* cert)
20383
0
{
20384
#ifndef WOLFSSL_ASN_TEMPLATE
20385
    int ret = 0;
20386
    word32 idx = 0;
20387
    word32 sz = (word32)cert->extensionsSz;
20388
    const byte* input = cert->extensions;
20389
    int length;
20390
    word32 oid;
20391
    byte critical = 0;
20392
    byte criticalFail = 0;
20393
    byte tag = 0;
20394
20395
    WOLFSSL_ENTER("DecodeCertExtensions");
20396
20397
    if (input == NULL || sz == 0)
20398
        return BAD_FUNC_ARG;
20399
20400
#ifdef WOLFSSL_CERT_REQ
20401
    if (!cert->isCSR)
20402
#endif
20403
    { /* Not included in CSR */
20404
        if (GetASNTag(input, &idx, &tag, sz) < 0) {
20405
            return ASN_PARSE_E;
20406
        }
20407
20408
        if (tag != ASN_EXTENSIONS) {
20409
            WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
20410
            return ASN_PARSE_E;
20411
        }
20412
20413
        if (GetLength(input, &idx, &length, sz) < 0) {
20414
            WOLFSSL_MSG("\tfail: invalid length");
20415
            return ASN_PARSE_E;
20416
        }
20417
    }
20418
20419
    if (GetSequence(input, &idx, &length, sz) < 0) {
20420
        WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
20421
        return ASN_PARSE_E;
20422
    }
20423
20424
    while (idx < (word32)sz) {
20425
        word32 localIdx;
20426
20427
        if (GetSequence(input, &idx, &length, sz) < 0) {
20428
            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
20429
            return ASN_PARSE_E;
20430
        }
20431
20432
        oid = 0;
20433
        if ((ret = GetObjectId(input, &idx, &oid, oidCertExtType, sz)) < 0) {
20434
            WOLFSSL_MSG("\tfail: OBJECT ID");
20435
            return ret;
20436
        }
20437
20438
        /* check for critical flag */
20439
        critical = 0;
20440
        if ((idx + 1) > (word32)sz) {
20441
            WOLFSSL_MSG("\tfail: malformed buffer");
20442
            return BUFFER_E;
20443
        }
20444
20445
        localIdx = idx;
20446
        if (GetASNTag(input, &localIdx, &tag, sz) == 0) {
20447
            if (tag == ASN_BOOLEAN) {
20448
                ret = GetBoolean(input, &idx, sz);
20449
                if (ret < 0) {
20450
                    WOLFSSL_MSG("\tfail: critical boolean");
20451
                    return ret;
20452
                }
20453
20454
                critical = (byte)ret;
20455
            }
20456
        }
20457
20458
        /* process the extension based on the OID */
20459
        ret = GetOctetString(input, &idx, &length, sz);
20460
        if (ret < 0) {
20461
            WOLFSSL_MSG("\tfail: bad OCTET STRING");
20462
            return ret;
20463
        }
20464
20465
        ret = DecodeExtensionType(input + idx, (word32)length, oid, critical,
20466
            cert, NULL);
20467
        if (ret == ASN_CRIT_EXT_E) {
20468
            ret = 0;
20469
            criticalFail = 1;
20470
        }
20471
        if (ret < 0)
20472
            goto end;
20473
        idx += (word32)length;
20474
    }
20475
20476
    ret = criticalFail ? ASN_CRIT_EXT_E : 0;
20477
end:
20478
    return ret;
20479
#else
20480
0
    DECL_ASNGETDATA(dataASN, certExtASN_Length);
20481
0
    ASNGetData dataExtsASN[certExtHdrASN_Length];
20482
0
    int ret = 0;
20483
0
    const byte* input = cert->extensions;
20484
0
    int sz = cert->extensionsSz;
20485
0
    word32 idx = 0;
20486
0
    int criticalRet = 0;
20487
0
    int offset = 0;
20488
20489
0
    WOLFSSL_ENTER("DecodeCertExtensions");
20490
20491
0
    if (input == NULL || sz == 0)
20492
0
        ret = BAD_FUNC_ARG;
20493
20494
0
    ALLOC_ASNGETDATA(dataASN, certExtASN_Length, ret, cert->heap);
20495
20496
#ifdef WOLFSSL_CERT_REQ
20497
    if (cert->isCSR) {
20498
        offset = CERTEXTHDRASN_IDX_EXTSEQ;
20499
    }
20500
#endif
20501
0
    if (ret == 0) {
20502
        /* Clear dynamic data. */
20503
0
        XMEMSET(dataExtsASN, 0, sizeof(dataExtsASN));
20504
        /* Parse extensions header. */
20505
0
        ret = GetASN_Items(certExtHdrASN + offset, dataExtsASN + offset,
20506
0
                           (int)(certExtHdrASN_Length - (size_t)offset), 0,
20507
0
                           input, &idx, (word32)sz);
20508
0
    }
20509
    /* Parse each extension. */
20510
0
    while ((ret == 0) && (idx < (word32)sz)) {
20511
0
        byte critical = 0;
20512
0
        int isUnknownExt = 0;
20513
20514
        /* Clear dynamic data. */
20515
0
        XMEMSET(dataASN, 0, sizeof(*dataASN) * certExtASN_Length);
20516
        /* Ensure OID is an extention type. */
20517
0
        GetASN_OID(&dataASN[CERTEXTASN_IDX_OID], oidCertExtType);
20518
        /* Set criticality variable. */
20519
0
        GetASN_Int8Bit(&dataASN[CERTEXTASN_IDX_CRIT], &critical);
20520
        /* Parse extension wrapper. */
20521
0
        ret = GetASN_Items(certExtASN, dataASN, certExtASN_Length, 0, input,
20522
0
                           &idx, (word32)sz);
20523
0
        if (ret == 0) {
20524
0
            word32 oid = dataASN[CERTEXTASN_IDX_OID].data.oid.sum;
20525
0
            word32 length = dataASN[CERTEXTASN_IDX_VAL].length;
20526
20527
            /* Decode the extension by type. */
20528
0
            ret = DecodeExtensionType(input + idx, length, oid, critical, cert,
20529
0
                                      &isUnknownExt);
20530
#if defined(WOLFSSL_CUSTOM_OID) && defined(HAVE_OID_DECODING)
20531
            if (isUnknownExt && (cert->unknownExtCallback != NULL)) {
20532
                word16 decOid[MAX_OID_SZ];
20533
                word32 decOidSz = sizeof(decOid);
20534
                ret = DecodeObjectId(
20535
                          dataASN[CERTEXTASN_IDX_OID].data.oid.data,
20536
                          dataASN[CERTEXTASN_IDX_OID].data.oid.length,
20537
                          decOid, &decOidSz);
20538
                if (ret != 0) {
20539
                    /* Should never get here as the extension was successfully
20540
                     * decoded earlier. Something might be corrupted. */
20541
                    WOLFSSL_MSG("DecodeObjectId() failed. Corruption?");
20542
                    WOLFSSL_ERROR(ret);
20543
                }
20544
20545
                ret = cert->unknownExtCallback(decOid, decOidSz, critical,
20546
                          dataASN[CERTEXTASN_IDX_VAL].data.buffer.data,
20547
                          dataASN[CERTEXTASN_IDX_VAL].length);
20548
            }
20549
#endif
20550
0
            (void)isUnknownExt;
20551
20552
            /* Move index on to next extension. */
20553
0
            idx += length;
20554
0
        }
20555
        /* Don't fail criticality until all other extensions have been checked.
20556
         */
20557
0
        if (ret == ASN_CRIT_EXT_E) {
20558
0
            criticalRet = ASN_CRIT_EXT_E;
20559
0
            ret = 0;
20560
0
        }
20561
0
    }
20562
20563
0
    if (ret == 0) {
20564
        /* Use criticality return. */
20565
0
        ret = criticalRet;
20566
0
    }
20567
20568
0
    FREE_ASNGETDATA(dataASN, cert->heap);
20569
0
    return ret;
20570
0
#endif
20571
0
}
20572
20573
#ifdef WOLFSSL_ASN_TEMPLATE
20574
/* ASN template for an X509 certificate.
20575
 * X.509: RFC 5280, 4.1 - Basic Certificate Fields.
20576
 */
20577
static const ASNItem x509CertASN[] = {
20578
        /* Certificate ::= SEQUENCE */
20579
/* SEQ                           */    { 0, ASN_SEQUENCE, 1, 1, 0 },
20580
                                                   /* tbsCertificate       TBSCertificate */
20581
                                                   /* TBSCertificate ::= SEQUENCE */
20582
/* TBS_SEQ                       */        { 1, ASN_SEQUENCE, 1, 1, 0 },
20583
                                                   /* version         [0]  EXPLICT Version DEFAULT v1 */
20584
/* TBS_VER                       */            { 2, ASN_CONTEXT_SPECIFIC | ASN_X509_CERT_VERSION, 1, 1, 1 },
20585
                                                   /* Version ::= INTEGER { v1(0), v2(1), v3(2) */
20586
/* TBS_VER_INT                   */                { 3, ASN_INTEGER, 0, 0, 0 },
20587
                                                   /* serialNumber         CertificateSerialNumber */
20588
                                                   /* CetificateSerialNumber ::= INTEGER */
20589
/* TBS_SERIAL                    */            { 2, ASN_INTEGER, 0, 0, 0 },
20590
                                                   /* signature            AlgorithmIdentifier */
20591
                                                   /* AlgorithmIdentifier ::= SEQUENCE */
20592
/* TBS_ALGOID_SEQ                */            { 2, ASN_SEQUENCE, 1, 1, 0 },
20593
                                                   /* Algorithm    OBJECT IDENTIFIER */
20594
/* TBS_ALGOID_OID                */                { 3, ASN_OBJECT_ID, 0, 0, 0 },
20595
                                                   /* parameters   ANY defined by algorithm OPTIONAL */
20596
/* TBS_ALGOID_PARAMS_NULL        */                { 3, ASN_TAG_NULL, 0, 0, 2 },
20597
#ifdef WC_RSA_PSS
20598
/* TBS_ALGOID_PARAMS             */                { 3, ASN_SEQUENCE, 1, 0, 2 },
20599
#endif
20600
                                                   /* issuer               Name */
20601
/* TBS_ISSUER_SEQ                */            { 2, ASN_SEQUENCE, 1, 0, 0 },
20602
                                                   /* validity             Validity */
20603
                                                   /* Validity ::= SEQUENCE */
20604
/* TBS_VALIDITY_SEQ              */            { 2, ASN_SEQUENCE, 1, 1, 0 },
20605
                                                   /* notBefore   Time */
20606
                                                   /* Time :: CHOICE { UTCTime, GeneralizedTime } */
20607
/* TBS_VALIDITY_NOTB_UTC         */                { 3, ASN_UTC_TIME, 0, 0, 2 },
20608
/* TBS_VALIDITY_NOTB_GT          */                { 3, ASN_GENERALIZED_TIME, 0, 0, 2 },
20609
                                                   /* notAfter   Time */
20610
                                                   /* Time :: CHOICE { UTCTime, GeneralizedTime } */
20611
/* TBS_VALIDITY_NOTA_UTC         */                { 3, ASN_UTC_TIME, 0, 0, 3 },
20612
/* TBS_VALIDITY_NOTA_GT          */                { 3, ASN_GENERALIZED_TIME, 0, 0, 3 },
20613
                                                   /* subject              Name */
20614
/* TBS_SUBJECT_SEQ               */            { 2, ASN_SEQUENCE, 1, 0, 0 },
20615
                                                   /* subjectPublicKeyInfo SubjectPublicKeyInfo */
20616
/* TBS_SPUBKEYINFO_SEQ           */            { 2, ASN_SEQUENCE, 1, 1, 0 },
20617
                                                   /* algorithm          AlgorithmIdentifier */
20618
                                                   /* AlgorithmIdentifier ::= SEQUENCE */
20619
/* TBS_SPUBKEYINFO_ALGO_SEQ      */                { 3, ASN_SEQUENCE, 1, 1, 0 },
20620
                                                   /* Algorithm    OBJECT IDENTIFIER */
20621
/* TBS_SPUBKEYINFO_ALGO_OID      */                    { 4, ASN_OBJECT_ID, 0, 0, 0 },
20622
                                                   /* parameters   ANY defined by algorithm OPTIONAL */
20623
/* TBS_SPUBKEYINFO_ALGO_NULL     */                    { 4, ASN_TAG_NULL, 0, 0, 2 },
20624
/* TBS_SPUBKEYINFO_ALGO_CURVEID  */                    { 4, ASN_OBJECT_ID, 0, 0, 2 },
20625
#ifdef WC_RSA_PSS
20626
/* TBS_SPUBKEYINFO_ALGO_P_SEQ    */                    { 4, ASN_SEQUENCE, 1, 0, 2 },
20627
#endif
20628
                                                   /* subjectPublicKey   BIT STRING */
20629
/* TBS_SPUBKEYINFO_PUBKEY        */                { 3, ASN_BIT_STRING, 0, 0, 0 },
20630
                                                   /* issuerUniqueID       UniqueIdentfier OPTIONAL */
20631
/* TBS_ISSUERUID                 */            { 2, ASN_CONTEXT_SPECIFIC | 1, 0, 0, 1 },
20632
                                                   /* subjectUniqueID      UniqueIdentfier OPTIONAL */
20633
/* TBS_SUBJECTUID                */            { 2, ASN_CONTEXT_SPECIFIC | 2, 0, 0, 1 },
20634
                                                   /* extensions           Extensions OPTIONAL */
20635
/* TBS_EXT                       */            { 2, ASN_CONTEXT_SPECIFIC | 3, 1, 1, 1 },
20636
/* TBS_EXT_SEQ                   */                { 3, ASN_SEQUENCE, 1, 0, 0 },
20637
                                                   /* signatureAlgorithm   AlgorithmIdentifier */
20638
                                                   /* AlgorithmIdentifier ::= SEQUENCE */
20639
/* SIGALGO_SEQ                   */        { 1, ASN_SEQUENCE, 1, 1, 0 },
20640
                                                   /* Algorithm    OBJECT IDENTIFIER */
20641
/* SIGALGO_OID                   */            { 2, ASN_OBJECT_ID, 0, 0, 0 },
20642
                                                   /* parameters   ANY defined by algorithm OPTIONAL */
20643
/* SIGALGO_PARAMS_NULL           */            { 2, ASN_TAG_NULL, 0, 0, 2 },
20644
#ifdef WC_RSA_PSS
20645
/* SIGALGO_PARAMS                */            { 2, ASN_SEQUENCE, 1, 0, 2 },
20646
#endif
20647
                                                   /* signature            BIT STRING */
20648
/* SIGNATURE                     */        { 1, ASN_BIT_STRING, 0, 0, 0 },
20649
};
20650
enum {
20651
    X509CERTASN_IDX_SEQ = 0,
20652
    X509CERTASN_IDX_TBS_SEQ,
20653
    X509CERTASN_IDX_TBS_VER,
20654
    X509CERTASN_IDX_TBS_VER_INT,
20655
    X509CERTASN_IDX_TBS_SERIAL,
20656
    X509CERTASN_IDX_TBS_ALGOID_SEQ,
20657
    X509CERTASN_IDX_TBS_ALGOID_OID,
20658
    X509CERTASN_IDX_TBS_ALGOID_PARAMS_NULL,
20659
#ifdef WC_RSA_PSS
20660
    X509CERTASN_IDX_TBS_ALGOID_PARAMS,
20661
#endif
20662
    X509CERTASN_IDX_TBS_ISSUER_SEQ,
20663
    X509CERTASN_IDX_TBS_VALIDITY_SEQ,
20664
    X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC,
20665
    X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT,
20666
    X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC,
20667
    X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT,
20668
    X509CERTASN_IDX_TBS_SUBJECT_SEQ,
20669
    X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ,
20670
    X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_SEQ,
20671
    X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_OID,
20672
    X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_NULL,
20673
    X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_CURVEID,
20674
#ifdef WC_RSA_PSS
20675
    X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_P_SEQ,
20676
#endif
20677
    X509CERTASN_IDX_TBS_SPUBKEYINFO_PUBKEY,
20678
    X509CERTASN_IDX_TBS_ISSUERUID,
20679
    X509CERTASN_IDX_TBS_SUBJECTUID,
20680
    X509CERTASN_IDX_TBS_EXT,
20681
    X509CERTASN_IDX_TBS_EXT_SEQ,
20682
    X509CERTASN_IDX_SIGALGO_SEQ,
20683
    X509CERTASN_IDX_SIGALGO_OID,
20684
    X509CERTASN_IDX_SIGALGO_PARAMS_NULL,
20685
#ifdef WC_RSA_PSS
20686
    X509CERTASN_IDX_SIGALGO_PARAMS,
20687
#endif
20688
    X509CERTASN_IDX_SIGNATURE,
20689
    WOLF_ENUM_DUMMY_LAST_ELEMENT(X509CERTASN_IDX)
20690
};
20691
20692
/* Number of items in ASN template for an X509 certificate. */
20693
0
#define x509CertASN_Length (sizeof(x509CertASN) / sizeof(ASNItem))
20694
20695
/* Check the data data.
20696
 *
20697
 * @param [in] dataASN   ASN template dynamic data item.
20698
 * @param [in] dataType  BEFORE or AFTER date.
20699
 * @return  0 on success.
20700
 * @return  ASN_TIME_E when BER tag is nor UTC or GENERALIZED time.
20701
 * @return  ASN_DATE_SZ_E when time data is not supported.
20702
 * @return  ASN_BEFORE_DATE_E when BEFORE date is invalid.
20703
 * @return  ASN_AFTER_DATE_E when AFTER date is invalid.
20704
 */
20705
static int CheckDate(ASNGetData *dataASN, int dateType)
20706
0
{
20707
0
    int ret = 0;
20708
20709
    /* Check BER tag is valid. */
20710
0
    if ((dataASN->tag != ASN_UTC_TIME) &&
20711
0
            (dataASN->tag != ASN_GENERALIZED_TIME)) {
20712
0
        ret = ASN_TIME_E;
20713
0
    }
20714
    /* Check date length is valid. */
20715
0
    if ((ret == 0) && ((dataASN->length > MAX_DATE_SIZE) ||
20716
0
                       (dataASN->length < MIN_DATE_SIZE))) {
20717
0
        ret = ASN_DATE_SZ_E;
20718
0
    }
20719
20720
0
#ifndef NO_ASN_TIME_CHECK
20721
    /* Check date is a valid string and BEFORE or AFTER now. */
20722
0
    if ((ret == 0) &&
20723
0
            (!XVALIDATE_DATE(dataASN->data.ref.data, dataASN->tag, dateType))) {
20724
0
        if (dateType == BEFORE) {
20725
0
            ret = ASN_BEFORE_DATE_E;
20726
0
        }
20727
0
        else {
20728
0
            ret = ASN_AFTER_DATE_E;
20729
0
        }
20730
0
    }
20731
0
#endif
20732
0
    (void)dateType;
20733
20734
0
    return ret;
20735
0
}
20736
20737
/* Decode a certificate. Internal/non-public API.
20738
 *
20739
 * @param [in]  cert             Certificate object.
20740
 * @param [in]  verify           Whether to verify dates before and after now.
20741
 * @param [out] criticalExt      Critical extension return code.
20742
 * @param [out] badDateRet       Bad date return code.
20743
 * @param [in]  stopAtPubKey     Stop parsing before subkectPublicKeyInfo.
20744
 * @param [in]  stopAfterPubKey  Stop parsing after subkectPublicKeyInfo.
20745
 * @return  0 on success.
20746
 * @return  ASN_CRIT_EXT_E when a critical extension was not recognized.
20747
 * @return  ASN_TIME_E when date BER tag is nor UTC or GENERALIZED time.
20748
 * @return  ASN_DATE_SZ_E when time data is not supported.
20749
 * @return  ASN_BEFORE_DATE_E when BEFORE date is invalid.
20750
 * @return  ASN_AFTER_DATE_E when AFTER date is invalid.
20751
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
20752
 *          is invalid.
20753
 * @return  BUFFER_E when data in buffer is too small.
20754
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
20755
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
20756
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
20757
 *          non-zero length.
20758
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
20759
 */
20760
static int DecodeCertInternal(DecodedCert* cert, int verify, int* criticalExt,
20761
                              int* badDateRet, int stopAtPubKey,
20762
                              int stopAfterPubKey)
20763
0
{
20764
0
    DECL_ASNGETDATA(dataASN, x509CertASN_Length);
20765
0
    int ret = 0;
20766
0
    int badDate = 0;
20767
0
    byte version;
20768
0
    word32 idx;
20769
0
    word32 serialSz;
20770
0
    const unsigned char* issuer = NULL;
20771
0
    word32 issuerSz = 0;
20772
0
    const unsigned char* subject = NULL;
20773
0
    word32 subjectSz = 0;
20774
0
    word32 pubKeyOffset = 0;
20775
0
    word32 pubKeyEnd = 0;
20776
0
    int done = 0;
20777
20778
0
    CALLOC_ASNGETDATA(dataASN, x509CertASN_Length, ret, cert->heap);
20779
20780
0
    if (ret == 0) {
20781
0
        version = 0;
20782
0
        serialSz = EXTERNAL_SERIAL_SIZE;
20783
20784
        /* Get the version and put the serial number into the buffer. */
20785
0
        GetASN_Int8Bit(&dataASN[X509CERTASN_IDX_TBS_VER_INT], &version);
20786
0
        GetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_SERIAL], cert->serial,
20787
0
                &serialSz);
20788
        /* Check OID types for signature, algorithm, ECC curve and sigAlg. */
20789
0
        GetASN_OID(&dataASN[X509CERTASN_IDX_TBS_ALGOID_OID], oidSigType);
20790
0
        GetASN_OID(&dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_OID],
20791
0
                oidKeyType);
20792
0
        GetASN_OID(&dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_CURVEID],
20793
0
                oidCurveType);
20794
0
        GetASN_OID(&dataASN[X509CERTASN_IDX_SIGALGO_OID], oidSigType);
20795
        /* Parse the X509 certificate. */
20796
0
        ret = GetASN_Items(x509CertASN, dataASN, x509CertASN_Length, 1,
20797
0
                           cert->source, &cert->srcIdx, cert->maxIdx);
20798
#ifdef WOLFSSL_CLANG_TIDY
20799
        /* work around clang-tidy false positive re cert->source. */
20800
        if ((ret == 0) && (cert->source == NULL)) {
20801
            ret = ASN_PARSE_E;
20802
        }
20803
#endif
20804
0
    }
20805
    /* Check version is valid/supported - can't be negative. */
20806
0
    if ((ret == 0) && (version > MAX_X509_VERSION)) {
20807
0
        WOLFSSL_MSG("Unexpected certificate version");
20808
0
        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
20809
0
        ret = ASN_PARSE_E;
20810
0
    }
20811
0
    if (ret == 0) {
20812
0
        int i;
20813
20814
0
        pubKeyOffset = dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ].offset;
20815
        /* Set fields extracted from data. */
20816
0
        cert->version = version;
20817
0
        cert->serialSz = (int)serialSz;
20818
0
        cert->signatureOID = dataASN[X509CERTASN_IDX_TBS_ALGOID_OID].data.oid.sum;
20819
0
        cert->keyOID = dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_OID].data.oid.sum;
20820
0
        cert->certBegin = dataASN[X509CERTASN_IDX_TBS_SEQ].offset;
20821
20822
        /* No bad date error - don't always care. */
20823
0
        badDate = 0;
20824
        /* Find the item with the BEFORE date and check it. */
20825
0
        i = (dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC].tag != 0)
20826
0
                ? X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC
20827
0
                : X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT;
20828
0
        if ((CheckDate(&dataASN[i], BEFORE) < 0) && (verify != NO_VERIFY) &&
20829
0
                (verify != VERIFY_SKIP_DATE)) {
20830
0
            badDate = ASN_BEFORE_DATE_E;
20831
0
        }
20832
        /* Store reference to BEFOREdate. */
20833
0
        cert->beforeDate = GetASNItem_Addr(dataASN[i], cert->source);
20834
0
        cert->beforeDateLen = (int)GetASNItem_Length(dataASN[i], cert->source);
20835
20836
        /* Find the item with the AFTER date and check it. */
20837
0
        i = (dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC].tag != 0)
20838
0
                ? X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC
20839
0
                : X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT;
20840
0
        if ((CheckDate(&dataASN[i], AFTER) < 0) && (verify != NO_VERIFY) &&
20841
0
                (verify != VERIFY_SKIP_DATE)) {
20842
0
            badDate = ASN_AFTER_DATE_E;
20843
0
        }
20844
        /* Store reference to AFTER date. */
20845
0
        cert->afterDate = GetASNItem_Addr(dataASN[i], cert->source);
20846
0
        cert->afterDateLen = (int)GetASNItem_Length(dataASN[i], cert->source);
20847
20848
        /* Get the issuer name. */
20849
0
        issuer = cert->source + dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ].offset;
20850
0
        issuerSz = dataASN[X509CERTASN_IDX_TBS_VALIDITY_SEQ].offset -
20851
0
            dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ].offset;
20852
20853
        /* Get the subject name. */
20854
0
        subject = cert->source +
20855
0
            dataASN[X509CERTASN_IDX_TBS_SUBJECT_SEQ].offset;
20856
0
        subjectSz = dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ].offset -
20857
0
            dataASN[X509CERTASN_IDX_TBS_SUBJECT_SEQ].offset;
20858
0
    }
20859
0
    if ((ret == 0) && stopAtPubKey) {
20860
        /* Return any bad date error through badDateRet and return offset of
20861
         * subjectPublicKeyInfo.
20862
         */
20863
0
        if (badDateRet != NULL) {
20864
0
            *badDateRet = badDate;
20865
0
        }
20866
0
        done = 1;
20867
0
    }
20868
20869
0
    if ((ret == 0) && (!done)) {
20870
        /* Store the signature information. */
20871
0
        cert->sigIndex = dataASN[X509CERTASN_IDX_SIGALGO_SEQ].offset;
20872
0
        GetASN_GetConstRef(&dataASN[X509CERTASN_IDX_SIGNATURE],
20873
0
                &cert->signature, &cert->sigLength);
20874
        /* Make sure 'signature' and 'signatureAlgorithm' are the same. */
20875
0
        if (dataASN[X509CERTASN_IDX_SIGALGO_OID].data.oid.sum
20876
0
                != cert->signatureOID) {
20877
0
            WOLFSSL_ERROR_VERBOSE(ASN_SIG_OID_E);
20878
0
            ret = ASN_SIG_OID_E;
20879
0
        }
20880
        /* Parameters not allowed after ECDSA or EdDSA algorithm OID. */
20881
0
        else if (IsSigAlgoECC(cert->signatureOID)) {
20882
0
            if ((dataASN[X509CERTASN_IDX_SIGALGO_PARAMS_NULL].tag != 0)
20883
0
        #ifdef WC_RSA_PSS
20884
0
                || (dataASN[X509CERTASN_IDX_SIGALGO_PARAMS].tag != 0)
20885
0
        #endif
20886
0
                ) {
20887
0
                WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
20888
0
                ret = ASN_PARSE_E;
20889
0
            }
20890
0
        }
20891
0
        #ifdef WC_RSA_PSS
20892
        /* Check parameters starting with a SEQUENCE. */
20893
0
        else if (dataASN[X509CERTASN_IDX_SIGALGO_PARAMS].tag != 0) {
20894
0
            word32 oid = dataASN[X509CERTASN_IDX_SIGALGO_OID].data.oid.sum;
20895
0
            word32 sigAlgParamsSz = 0;
20896
20897
            /* Parameters only with RSA PSS. */
20898
0
            if (oid != CTC_RSASSAPSS) {
20899
0
                WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
20900
0
                ret = ASN_PARSE_E;
20901
0
            }
20902
0
            if (ret == 0) {
20903
0
                const byte* tbsParams;
20904
0
                word32 tbsParamsSz;
20905
0
                const byte* sigAlgParams;
20906
20907
                /* Check RSA PSS parameters are the same. */
20908
0
                tbsParams =
20909
0
                    GetASNItem_Addr(dataASN[X509CERTASN_IDX_TBS_ALGOID_PARAMS],
20910
0
                        cert->source);
20911
0
                tbsParamsSz =
20912
0
                    GetASNItem_Length(dataASN[X509CERTASN_IDX_TBS_ALGOID_PARAMS],
20913
0
                        cert->source);
20914
0
                sigAlgParams =
20915
0
                    GetASNItem_Addr(dataASN[X509CERTASN_IDX_SIGALGO_PARAMS],
20916
0
                        cert->source);
20917
0
                sigAlgParamsSz =
20918
0
                    GetASNItem_Length(dataASN[X509CERTASN_IDX_SIGALGO_PARAMS],
20919
0
                        cert->source);
20920
0
                if ((tbsParamsSz != sigAlgParamsSz) ||
20921
0
                        (XMEMCMP(tbsParams, sigAlgParams, tbsParamsSz) != 0)) {
20922
0
                    WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
20923
0
                    ret = ASN_PARSE_E;
20924
0
                }
20925
0
            }
20926
0
            if (ret == 0) {
20927
                /* Store parameters for use in signature verification. */
20928
0
                cert->sigParamsIndex =
20929
0
                    dataASN[X509CERTASN_IDX_SIGALGO_PARAMS].offset;
20930
0
                cert->sigParamsLength = sigAlgParamsSz;
20931
0
            }
20932
0
        }
20933
0
        #endif
20934
0
    }
20935
0
    if ((ret == 0) && (!done)) {
20936
0
        pubKeyEnd = dataASN[X509CERTASN_IDX_TBS_ISSUERUID].offset;
20937
0
        if (stopAfterPubKey) {
20938
            /* Return any bad date error through badDateRed and return offset
20939
             * after subjectPublicKeyInfo.
20940
             */
20941
0
            if (badDateRet != NULL) {
20942
0
                *badDateRet = badDate;
20943
0
            }
20944
0
            done = 1;
20945
0
        }
20946
0
    }
20947
0
    if ((ret == 0) && (!done) &&
20948
0
            (dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].data.ref.data != NULL)) {
20949
0
    #ifndef ALLOW_V1_EXTENSIONS
20950
        /* Certificate extensions were only defined in version 2. */
20951
0
        if (cert->version < 2) {
20952
0
            WOLFSSL_MSG("\tv1 and v2 certs not allowed extensions");
20953
0
            WOLFSSL_ERROR_VERBOSE(ASN_VERSION_E);
20954
0
            ret = ASN_VERSION_E;
20955
0
        }
20956
0
    #endif
20957
0
        if (ret == 0) {
20958
            /* Save references to extension data. */
20959
0
            cert->extensions    = GetASNItem_Addr(
20960
0
                    dataASN[X509CERTASN_IDX_TBS_EXT], cert->source);
20961
0
            cert->extensionsSz  = (int)GetASNItem_Length(
20962
0
                    dataASN[X509CERTASN_IDX_TBS_EXT], cert->source);
20963
0
            cert->extensionsIdx = dataASN[X509CERTASN_IDX_TBS_EXT].offset;
20964
            /* Advance past extensions. */
20965
0
            cert->srcIdx = dataASN[X509CERTASN_IDX_SIGALGO_SEQ].offset;
20966
0
        }
20967
0
    }
20968
20969
    /* Dispose of memory before allocating for extension decoding. */
20970
0
    FREE_ASNGETDATA(dataASN, cert->heap);
20971
20972
0
    if ((ret == 0) && (issuer != NULL)) {
20973
0
        idx = 0;
20974
        /* Put issuer into cert and calculate hash. */
20975
0
        ret = GetCertName(cert, cert->issuer, cert->issuerHash, ISSUER, issuer,
20976
0
            &idx, issuerSz);
20977
0
    }
20978
0
    if ((ret == 0) && (subject != NULL)) {
20979
0
        idx = 0;
20980
        /* Put subject into cert and calculate hash. */
20981
0
        ret = GetCertName(cert, cert->subject, cert->subjectHash, SUBJECT,
20982
0
            subject, &idx, subjectSz);
20983
0
    }
20984
0
    if (ret == 0) {
20985
        /* Determine if self signed by comparing issuer and subject hashes. */
20986
    #ifdef WOLFSSL_CERT_REQ
20987
        if (cert->isCSR) {
20988
            cert->selfSigned = 1;
20989
        }
20990
        else
20991
    #endif
20992
0
        {
20993
0
            cert->selfSigned = (XMEMCMP(cert->issuerHash, cert->subjectHash,
20994
0
                                        KEYID_SIZE) == 0);
20995
0
        }
20996
0
        if (stopAtPubKey) {
20997
0
            ret = (int)pubKeyOffset;
20998
0
        }
20999
0
    }
21000
21001
0
    if ((ret == 0) && (!stopAtPubKey)) {
21002
        /* Parse the public key. */
21003
0
        idx = pubKeyOffset;
21004
0
        ret = GetCertKey(cert, cert->source, &idx, pubKeyEnd);
21005
0
    }
21006
0
    if ((ret == 0) && (!stopAtPubKey) && (!stopAfterPubKey) &&
21007
0
            (cert->extensions != NULL)) {
21008
        /* Decode the extension data starting at [3]. */
21009
0
        ret = DecodeCertExtensions(cert);
21010
0
        if (criticalExt != NULL) {
21011
0
            if (ret == ASN_CRIT_EXT_E) {
21012
                /* Return critical extension not recognized. */
21013
0
                *criticalExt = ret;
21014
0
                ret = 0;
21015
0
            }
21016
0
            else {
21017
                /* No critical extension error. */
21018
0
                *criticalExt = 0;
21019
0
            }
21020
0
        }
21021
0
    }
21022
21023
0
    if ((ret == 0) && (!done) && (badDate != 0)) {
21024
        /* Parsed whole certificate fine but return any date errors. */
21025
0
        ret = badDate;
21026
0
    }
21027
21028
0
    return ret;
21029
0
}
21030
21031
/* Decode BER/DER data into certificate object.
21032
 *
21033
 * BER/DER data information held in source, srcIdx and maxIdx fields of
21034
 * certificate object.
21035
 *
21036
 * @param [in] cert         Decoded certificate object.
21037
 * @param [in] verify       Whether to find CA and verify certificate.
21038
 * @param [in] criticalExt  Any error for critical extensions not recognized.
21039
 * @return  0 on success.
21040
 * @return  ASN_CRIT_EXT_E when a critical extension was not recognized.
21041
 * @return  ASN_TIME_E when date BER tag is nor UTC or GENERALIZED time.
21042
 * @return  ASN_DATE_SZ_E when time data is not supported.
21043
 * @return  ASN_BEFORE_DATE_E when BEFORE date is invalid.
21044
 * @return  ASN_AFTER_DATE_E when AFTER date is invalid.
21045
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
21046
 *          is invalid.
21047
 * @return  BUFFER_E when data in buffer is too small.
21048
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
21049
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
21050
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
21051
 *          non-zero length.
21052
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
21053
 */
21054
int DecodeCert(DecodedCert* cert, int verify, int* criticalExt)
21055
0
{
21056
0
    return DecodeCertInternal(cert, verify, criticalExt, NULL, 0, 0);
21057
0
}
21058
21059
#ifdef WOLFSSL_CERT_REQ
21060
/* ASN.1 template for certificate request Attribute.
21061
 * PKCS #10: RFC 2986, 4.1 - CertificationRequestInfo
21062
 */
21063
static const ASNItem reqAttrASN[] = {
21064
/* SEQ  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
21065
                              /* type */
21066
/* TYPE */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
21067
                              /* values */
21068
/* VALS */     { 1, ASN_SET, 1, 0, 0 },
21069
};
21070
enum {
21071
    REQATTRASN_IDX_SEQ = 0,
21072
    REQATTRASN_IDX_TYPE,
21073
    REQATTRASN_IDX_VALS
21074
};
21075
21076
/* Number of items in ASN.1 template for certificate request Attribute. */
21077
#define reqAttrASN_Length (sizeof(reqAttrASN) / sizeof(ASNItem))
21078
21079
/* ASN.1 template for a string choice. */
21080
static const ASNItem strAttrASN[] = {
21081
    { 0, 0, 0, 0, 0 },
21082
};
21083
enum {
21084
    STRATTRASN_IDX_STR = 0
21085
};
21086
21087
/* Number of items in ASN.1 template for a string choice. */
21088
#define strAttrASN_Length (sizeof(strAttrASN) / sizeof(ASNItem))
21089
21090
/* ASN.1 choices for types for a string in an attribute. */
21091
static const byte strAttrChoice[] = {
21092
    ASN_PRINTABLE_STRING, ASN_IA5_STRING, ASN_UTF8STRING, 0
21093
};
21094
21095
/* Decode a certificate request attribute's value.
21096
 *
21097
 * @param [in]  cert         Certificate request object.
21098
 * @param [out] criticalExt  Critical extension return code.
21099
 * @param [in]  oid          OID decribing which attribute was found.
21100
 * @param [in]  aIdx         Index into certificate source to start parsing.
21101
 * @param [in]  input        Attribute value data.
21102
 * @param [in]  maxIdx       Maximum index to parse to.
21103
 * @return  0 on success.
21104
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
21105
 *          is invalid.
21106
 */
21107
static int DecodeCertReqAttrValue(DecodedCert* cert, int* criticalExt,
21108
    word32 oid, word32 aIdx, const byte* input, word32 maxIdx)
21109
{
21110
    int ret = 0;
21111
    word32 idx = 0;
21112
    ASNGetData strDataASN[strAttrASN_Length];
21113
21114
    switch (oid) {
21115
        case PKCS9_CONTENT_TYPE_OID:
21116
            /* Clear dynamic data and specify choices acceptable. */
21117
            XMEMSET(strDataASN, 0, sizeof(strDataASN));
21118
            GetASN_Choice(&strDataASN[STRATTRASN_IDX_STR], strAttrChoice);
21119
            /* Parse a string. */
21120
            ret = GetASN_Items(strAttrASN, strDataASN, strAttrASN_Length,
21121
                               1, input, &idx, maxIdx);
21122
            if (ret == 0) {
21123
                /* Store references to password data. */
21124
                cert->contentType =
21125
                        (char*)strDataASN[STRATTRASN_IDX_STR].data.ref.data;
21126
                cert->contentTypeLen =
21127
                        (int)strDataASN[STRATTRASN_IDX_STR].data.ref.length;
21128
            }
21129
            break;
21130
21131
        /* A password by which the entity may request certificate revocation.
21132
         * PKCS#9: RFC 2985, 5.4.1 - Challenge password
21133
         */
21134
        case CHALLENGE_PASSWORD_OID:
21135
            /* Clear dynamic data and specify choices acceptable. */
21136
            XMEMSET(strDataASN, 0, sizeof(strDataASN));
21137
            GetASN_Choice(&strDataASN[STRATTRASN_IDX_STR], strAttrChoice);
21138
            /* Parse a string. */
21139
            ret = GetASN_Items(strAttrASN, strDataASN, strAttrASN_Length,
21140
                               1, input, &idx, maxIdx);
21141
            if (ret == 0) {
21142
                /* Store references to password data. */
21143
                cert->cPwd =
21144
                        (char*)strDataASN[STRATTRASN_IDX_STR].data.ref.data;
21145
                cert->cPwdLen = (int)strDataASN[STRATTRASN_IDX_STR].
21146
                    data.ref.length;
21147
            }
21148
            break;
21149
21150
        /* Requested serial number to issue with.
21151
         * PKCS#9: RFC 2985, 5.2.10 - Serial Number
21152
         * (References: ISO/IEC 9594-6:1997)
21153
         */
21154
        case SERIAL_NUMBER_OID:
21155
            /* Clear dynamic data and specify choices acceptable. */
21156
            XMEMSET(strDataASN, 0, sizeof(strDataASN));
21157
            GetASN_Choice(&strDataASN[STRATTRASN_IDX_STR], strAttrChoice);
21158
            /* Parse a string. */
21159
            ret = GetASN_Items(strAttrASN, strDataASN, strAttrASN_Length,
21160
                               1, input, &idx, maxIdx);
21161
            if (ret == 0) {
21162
                /* Store references to serial number. */
21163
                cert->sNum =
21164
                        (char*)strDataASN[STRATTRASN_IDX_STR].data.ref.data;
21165
                cert->sNumLen = (int)strDataASN[STRATTRASN_IDX_STR].
21166
                    data.ref.length;
21167
                /* Store serial number if small enough. */
21168
                if (cert->sNumLen <= EXTERNAL_SERIAL_SIZE) {
21169
                    XMEMCPY(cert->serial, cert->sNum, (size_t)cert->sNumLen);
21170
                    cert->serialSz = cert->sNumLen;
21171
                }
21172
            }
21173
            break;
21174
21175
        /* Certificate extensions to be included in generated certificate.
21176
         * PKCS#9: RFC 2985, 5.4.2 - Extension request
21177
         */
21178
        case EXTENSION_REQUEST_OID:
21179
            /* Store references to all extensions. */
21180
            cert->extensions    = input;
21181
            cert->extensionsSz  = (int)maxIdx;
21182
            cert->extensionsIdx = aIdx;
21183
21184
            /* Decode and validate extensions. */
21185
            ret = DecodeCertExtensions(cert);
21186
            if (ret == ASN_CRIT_EXT_E) {
21187
                /* Return critical extension not recognized. */
21188
                *criticalExt = ret;
21189
                ret = 0;
21190
            }
21191
            else {
21192
                /* No critical extension error. */
21193
                *criticalExt = 0;
21194
            }
21195
            break;
21196
21197
        default:
21198
            ret = ASN_PARSE_E;
21199
            break;
21200
    }
21201
21202
    return ret;
21203
}
21204
21205
/* Decode attributes of a BER encoded certificate request.
21206
 *
21207
 * RFC 2986 - PKCS #10: Certification Request Syntax Specification Version 1.7
21208
 *
21209
 * Outer sequence has been removed.
21210
 *
21211
 * @param [in]  cert         Certificate request object.
21212
 * @param [out] criticalExt  Critical extension return code.
21213
 * @param [in]  idx          Index into certificate source to start parsing.
21214
 * @param [in]  maxIdx       Maximum index to parse to.
21215
 * @return  0 on success.
21216
 * @return  ASN_CRIT_EXT_E when a critical extension was not recognized.
21217
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
21218
 *          is invalid.
21219
 * @return  BUFFER_E when data in buffer is too small.
21220
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
21221
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
21222
 *          non-zero length.
21223
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
21224
 */
21225
static int DecodeCertReqAttributes(DecodedCert* cert, int* criticalExt,
21226
                                   word32 idx, word32 maxIdx)
21227
{
21228
    DECL_ASNGETDATA(dataASN, reqAttrASN_Length);
21229
    int ret = 0;
21230
21231
    WOLFSSL_ENTER("DecodeCertReqAttributes");
21232
21233
    ALLOC_ASNGETDATA(dataASN, reqAttrASN_Length, ret, cert->heap);
21234
21235
    /* Parse each attribute until all data used up. */
21236
    while ((ret == 0) && (idx < maxIdx)) {
21237
        /* Clear dynamic data. */
21238
        XMEMSET(dataASN, 0, sizeof(ASNGetData) * reqAttrASN_Length);
21239
        GetASN_OID(&dataASN[REQATTRASN_IDX_TYPE], oidIgnoreType);
21240
21241
        /* Parse an attribute. */
21242
        ret = GetASN_Items(reqAttrASN, dataASN, reqAttrASN_Length, 0,
21243
                           cert->source, &idx, maxIdx);
21244
        /* idx is now at end of attribute data. */
21245
        if (ret == 0) {
21246
            ret = DecodeCertReqAttrValue(cert, criticalExt,
21247
                dataASN[REQATTRASN_IDX_TYPE].data.oid.sum,
21248
                GetASNItem_DataIdx(dataASN[REQATTRASN_IDX_VALS], cert->source),
21249
                dataASN[REQATTRASN_IDX_VALS].data.ref.data,
21250
                dataASN[REQATTRASN_IDX_VALS].data.ref.length);
21251
        }
21252
    }
21253
21254
    FREE_ASNGETDATA(dataASN, cert->heap);
21255
    return ret;
21256
}
21257
21258
/* ASN.1 template for a certificate request.
21259
 * PKCS#10: RFC 2986, 4.1 - CertificationRequestInfo
21260
 * PKCS#10: RFC 2986, 4.2 - CertificationRequest
21261
 */
21262
static const ASNItem certReqASN[] = {
21263
            /* CertificationRequest */
21264
/* SEQ                              */ { 0, ASN_SEQUENCE, 1, 1, 0 },
21265
                                                          /* CertificationRequestInfo */
21266
/* INFO_SEQ                         */     { 1, ASN_SEQUENCE, 1, 1, 0 },
21267
                                                              /* version              INTEGER { v1(0), v2(1), v3(2) */
21268
/* INFO_VER                         */         { 2, ASN_INTEGER, 0, 0, 0 },
21269
                                                              /* subject              Name */
21270
/* INFO_SUBJ_SEQ                    */         { 2, ASN_SEQUENCE, 1, 0, 0 },
21271
                                                              /* subjectPublicKeyInfo SubjectPublicKeyInfo */
21272
/* INFO_SPUBKEYINFO_SEQ             */         { 2, ASN_SEQUENCE, 1, 1, 0 },
21273
                                                                  /* algorithm          AlgorithmIdentifier */
21274
/* INFO_SPUBKEYINFO_ALGOID_SEQ      */             { 3, ASN_SEQUENCE, 1, 1, 0 },
21275
                                                                      /* Algorithm    OBJECT IDENTIFIER */
21276
/* INFO_SPUBKEYINFO_ALGOID_OID      */                 { 4, ASN_OBJECT_ID, 0, 0, 0 },
21277
                                                                      /* parameters   ANY defined by algorithm OPTIONAL */
21278
/* INFO_SPUBKEYINFO_ALGOID_NULL     */                 { 4, ASN_TAG_NULL, 0, 0, 1 },
21279
/* INFO_SPUBKEYINFO_ALGOID_CURVEID  */                 { 4, ASN_OBJECT_ID, 0, 0, 1 },
21280
/* INFO_SPUBKEYINFO_ALGOID_PARAMS   */                 { 4, ASN_SEQUENCE, 1, 0, 1 },
21281
                                                                  /* subjectPublicKey   BIT STRING */
21282
/* INFO_SPUBKEYINFO_PUBKEY          */             { 3, ASN_BIT_STRING, 0, 0, 0 },
21283
                                                              /* attributes       [0] Attributes */
21284
/* INFO_ATTRS                       */         { 2, ASN_CONTEXT_SPECIFIC | 0, 1, 0, 1 },
21285
                                                          /* signatureAlgorithm   AlgorithmIdentifier */
21286
/* INFO_SIGALGO_SEQ                 */     { 1, ASN_SEQUENCE, 1, 1, 0 },
21287
                                                              /* Algorithm    OBJECT IDENTIFIER */
21288
/* INFO_SIGALGO_OID                 */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
21289
                                                              /* parameters   ANY defined by algorithm OPTIONAL */
21290
/* INFO_SIGALGO_NULL                */         { 2, ASN_TAG_NULL, 0, 0, 1 },
21291
                                                          /* signature            BIT STRING */
21292
/* INFO_SIGNATURE                   */     { 1, ASN_BIT_STRING, 0, 0, 0 },
21293
};
21294
enum {
21295
    CERTREQASN_IDX_SEQ = 0,
21296
    CERTREQASN_IDX_INFO_SEQ,
21297
    CERTREQASN_IDX_INFO_VER,
21298
    CERTREQASN_IDX_INFO_SUBJ_SEQ,
21299
    CERTREQASN_IDX_INFO_SPUBKEYINFO_SEQ,
21300
    CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_SEQ,
21301
    CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_OID,
21302
    CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_NULL,
21303
    CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_CURVEID,
21304
    CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_PARAMS,
21305
    CERTREQASN_IDX_INFO_SPUBKEYINFO_PUBKEY,
21306
    CERTREQASN_IDX_INFO_ATTRS,
21307
    CERTREQASN_IDX_INFO_SIGALGO_SEQ,
21308
    CERTREQASN_IDX_INFO_SIGALGO_OID,
21309
    CERTREQASN_IDX_INFO_SIGALGO_NULL,
21310
    CERTREQASN_IDX_INFO_SIGNATURE
21311
};
21312
21313
/* Number of items in ASN.1 template for a certificate request. */
21314
#define certReqASN_Length (sizeof(certReqASN) / sizeof(ASNItem))
21315
21316
/* Parse BER encoded certificate request.
21317
 *
21318
 * RFC 2986 - PKCS #10: Certification Request Syntax Specification Version 1.7
21319
 *
21320
 * @param [in]  cert         Certificate request object.
21321
 * @param [out] criticalExt  Critical extension return code.
21322
 * @return  0 on success.
21323
 * @return  ASN_CRIT_EXT_E when a critical extension was not recognized.
21324
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
21325
 *          is invalid.
21326
 * @return  BUFFER_E when data in buffer is too small.
21327
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
21328
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
21329
 *          non-zero length.
21330
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
21331
 * @return  MEMORY_E on dynamic memory allocation failure.
21332
 */
21333
static int DecodeCertReq(DecodedCert* cert, int* criticalExt)
21334
{
21335
    DECL_ASNGETDATA(dataASN, certReqASN_Length);
21336
    int ret = 0;
21337
    byte version;
21338
    word32 idx;
21339
21340
    CALLOC_ASNGETDATA(dataASN, certReqASN_Length, ret, cert->heap);
21341
21342
    if (ret == 0) {
21343
        /* Default version is 0. */
21344
        version = 0;
21345
21346
        /* Set version var and OID types to expect. */
21347
        GetASN_Int8Bit(&dataASN[CERTREQASN_IDX_INFO_VER], &version);
21348
        GetASN_OID(&dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_OID],
21349
                oidKeyType);
21350
        GetASN_OID(&dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_CURVEID],
21351
                oidCurveType);
21352
        GetASN_OID(&dataASN[CERTREQASN_IDX_INFO_SIGALGO_OID], oidSigType);
21353
        /* Parse a certificate request. */
21354
        ret = GetASN_Items(certReqASN, dataASN, certReqASN_Length, 1,
21355
                           cert->source, &cert->srcIdx, cert->maxIdx);
21356
    }
21357
    /* Check version is valid/supported - can't be negative. */
21358
    if ((ret == 0) && (version > MAX_X509_VERSION)) {
21359
        WOLFSSL_MSG("Unexpected certificate request version");
21360
        ret = ASN_PARSE_E;
21361
    }
21362
    if (ret == 0) {
21363
        /* Set fields of certificate request. */
21364
        cert->version = version;
21365
        cert->signatureOID =
21366
              dataASN[CERTREQASN_IDX_INFO_SIGALGO_OID].data.oid.sum;
21367
        cert->keyOID =
21368
              dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_OID].data.oid.sum;
21369
        cert->certBegin = dataASN[CERTREQASN_IDX_INFO_SEQ].offset;
21370
21371
        /* Parse the subject name. */
21372
        idx = dataASN[CERTREQASN_IDX_INFO_SUBJ_SEQ].offset;
21373
        ret = GetCertName(cert, cert->subject, cert->subjectHash, SUBJECT,
21374
                          cert->source, &idx,
21375
                          dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_SEQ].offset);
21376
    }
21377
    if (ret == 0) {
21378
        /* Parse the certificate request Attributes. */
21379
        ret = DecodeCertReqAttributes(cert, criticalExt,
21380
                GetASNItem_DataIdx(dataASN[CERTREQASN_IDX_INFO_ATTRS],
21381
                        cert->source),
21382
                dataASN[CERTREQASN_IDX_INFO_SIGALGO_SEQ].offset);
21383
    }
21384
    if (ret == 0) {
21385
        /* Parse the certificate request's key. */
21386
        idx = dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_SEQ].offset;
21387
        ret = GetCertKey(cert, cert->source, &idx,
21388
                dataASN[CERTREQASN_IDX_INFO_ATTRS].offset);
21389
    }
21390
    if (ret == 0) {
21391
        /* Store references to signature. */
21392
        cert->sigIndex = dataASN[CERTREQASN_IDX_INFO_SIGALGO_SEQ].offset;
21393
        GetASN_GetConstRef(&dataASN[CERTREQASN_IDX_INFO_SIGNATURE],
21394
                &cert->signature, &cert->sigLength);
21395
    }
21396
21397
    FREE_ASNGETDATA(dataASN, cert->heap);
21398
    return ret;
21399
}
21400
21401
#endif /* WOLFSSL_CERT_REQ */
21402
21403
#endif
21404
21405
int ParseCert(DecodedCert* cert, int type, int verify, void* cm)
21406
0
{
21407
0
    int   ret;
21408
0
#if (!defined(WOLFSSL_NO_MALLOC) && !defined(NO_WOLFSSL_CM_VERIFY)) || \
21409
0
    defined(WOLFSSL_DYN_CERT)
21410
0
    char* ptr;
21411
0
#endif
21412
21413
0
    ret = ParseCertRelative(cert, type, verify, cm);
21414
0
    if (ret < 0)
21415
0
        return ret;
21416
21417
0
#if (!defined(WOLFSSL_NO_MALLOC) && !defined(NO_WOLFSSL_CM_VERIFY)) || \
21418
0
    defined(WOLFSSL_DYN_CERT)
21419
    /* cert->subjectCN not stored as copy of WOLFSSL_NO_MALLOC defind */
21420
0
    if (cert->subjectCNLen > 0) {
21421
0
        ptr = (char*)XMALLOC((size_t)cert->subjectCNLen + 1, cert->heap,
21422
0
                              DYNAMIC_TYPE_SUBJECT_CN);
21423
0
        if (ptr == NULL)
21424
0
            return MEMORY_E;
21425
0
        XMEMCPY(ptr, cert->subjectCN, (size_t)cert->subjectCNLen);
21426
0
        ptr[cert->subjectCNLen] = '\0';
21427
0
        cert->subjectCN = ptr;
21428
0
        cert->subjectCNStored = 1;
21429
0
    }
21430
0
#endif
21431
21432
0
#if (!defined(WOLFSSL_NO_MALLOC) && !defined(NO_WOLFSSL_CM_VERIFY)) || \
21433
0
    defined(WOLFSSL_DYN_CERT)
21434
    /* cert->publicKey not stored as copy if WOLFSSL_NO_MALLOC defined */
21435
0
    if ((cert->keyOID == RSAk
21436
0
    #ifdef WC_RSA_PSS
21437
0
         || cert->keyOID == RSAPSSk
21438
0
    #endif
21439
0
         ) && cert->publicKey != NULL && cert->pubKeySize > 0) {
21440
0
        ptr = (char*)XMALLOC(cert->pubKeySize, cert->heap,
21441
0
                              DYNAMIC_TYPE_PUBLIC_KEY);
21442
0
        if (ptr == NULL)
21443
0
            return MEMORY_E;
21444
0
        XMEMCPY(ptr, cert->publicKey, cert->pubKeySize);
21445
0
        cert->publicKey = (byte *)ptr;
21446
0
        cert->pubKeyStored = 1;
21447
0
    }
21448
0
#endif
21449
21450
0
    return ret;
21451
0
}
21452
21453
int wc_ParseCert(DecodedCert* cert, int type, int verify, void* cm)
21454
0
{
21455
0
    return ParseCert(cert, type, verify, cm);
21456
0
}
21457
21458
#ifdef WOLFCRYPT_ONLY
21459
21460
/* dummy functions, not using wolfSSL so don't need actual ones */
21461
Signer* GetCA(void* signers, byte* hash);
21462
Signer* GetCA(void* signers, byte* hash)
21463
{
21464
    (void)hash;
21465
21466
    return (Signer*)signers;
21467
}
21468
21469
#ifndef NO_SKID
21470
Signer* GetCAByName(void* signers, byte* hash);
21471
Signer* GetCAByName(void* signers, byte* hash)
21472
{
21473
    (void)hash;
21474
21475
    return (Signer*)signers;
21476
}
21477
#endif /* NO_SKID */
21478
21479
#ifdef WOLFSSL_AKID_NAME
21480
Signer* GetCAByAKID(void* vp, const byte* issuer, word32 issuerSz,
21481
        const byte* serial, word32 serialSz);
21482
Signer* GetCAByAKID(void* vp, const byte* issuer, word32 issuerSz,
21483
        const byte* serial, word32 serialSz)
21484
{
21485
    (void)issuer;
21486
    (void)issuerSz;
21487
    (void)serial;
21488
    (void)serialSz;
21489
21490
    return (Signer*)vp;
21491
}
21492
#endif
21493
21494
#endif /* WOLFCRYPT_ONLY */
21495
21496
#if defined(WOLFSSL_NO_TRUSTED_CERTS_VERIFY) && !defined(NO_SKID)
21497
static Signer* GetCABySubjectAndPubKey(DecodedCert* cert, void* cm)
21498
{
21499
    Signer* ca = NULL;
21500
    if (cert->extSubjKeyIdSet)
21501
        ca = GetCA(cm, cert->extSubjKeyId);
21502
    if (ca == NULL)
21503
        ca = GetCAByName(cm, cert->subjectHash);
21504
    if (ca) {
21505
        if ((ca->pubKeySize == cert->pubKeySize) &&
21506
               (XMEMCMP(ca->publicKey, cert->publicKey, ca->pubKeySize) == 0)) {
21507
            return ca;
21508
        }
21509
    }
21510
    return NULL;
21511
}
21512
#endif
21513
21514
#if defined(WOLFSSL_SMALL_CERT_VERIFY) || defined(OPENSSL_EXTRA)
21515
#ifdef WOLFSSL_ASN_TEMPLATE
21516
/* Get the Hash of the Authority Key Identifier from the list of extensions.
21517
 *
21518
 * @param [in]  input   Input data.
21519
 * @param [in]  maxIdx  Maximum index for data.
21520
 * @param [in]  sigOID  Signature OID for determining hash algorithm.
21521
 * @param [out] hash    Hash of AKI.
21522
 * @param [out] set     Whether the hash buffer was set.
21523
 * @param [in]  heap    Dynamic memory allocation hint.
21524
 * @return  0 on success.
21525
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
21526
 *          is invalid.
21527
 * @return  MEMORY_E on dynamic memory allocation failure.
21528
 */
21529
static int GetAKIHash(const byte* input, word32 maxIdx, word32 sigOID,
21530
                      byte* hash, int* set, void* heap)
21531
{
21532
    /* AKI and Certificate Extenion ASN.1 templates are the same length. */
21533
    DECL_ASNGETDATA(dataASN, certExtASN_Length);
21534
    int ret = 0;
21535
    word32 idx = 0;
21536
    word32 extEndIdx;
21537
    byte* extData;
21538
    word32 extDataSz;
21539
    byte critical;
21540
21541
    ALLOC_ASNGETDATA(dataASN, certExtASN_Length, ret, heap);
21542
    (void)heap;
21543
21544
    extEndIdx = idx + maxIdx;
21545
21546
    /* Step through each extension looking for AKI. */
21547
    while ((ret == 0) && (idx < extEndIdx)) {
21548
        /* Clear dynamic data and check for certificate extension type OIDs. */
21549
        XMEMSET(dataASN, 0, sizeof(*dataASN) * certExtASN_Length);
21550
        GetASN_OID(&dataASN[CERTEXTASN_IDX_OID], oidCertExtType);
21551
        /* Set criticality variable. */
21552
        GetASN_Int8Bit(&dataASN[CERTEXTASN_IDX_CRIT], &critical);
21553
        /* Parse an extension. */
21554
        ret = GetASN_Items(certExtASN, dataASN, certExtASN_Length, 0, input,
21555
                &idx, extEndIdx);
21556
        if (ret == 0) {
21557
            /* Get reference to extension data and move index on past this
21558
             * extension. */
21559
            GetASN_GetRef(&dataASN[CERTEXTASN_IDX_VAL], &extData, &extDataSz);
21560
            idx += extDataSz;
21561
21562
            /* Check whether we have the AKI extension. */
21563
            if (dataASN[CERTEXTASN_IDX_OID].data.oid.sum == AUTH_KEY_OID) {
21564
                /* Clear dynamic data. */
21565
                XMEMSET(dataASN, 0, sizeof(*dataASN) * authKeyIdASN_Length);
21566
                /* Start parsing extension data from the start. */
21567
                idx = 0;
21568
                /* Parse AKI extension data. */
21569
                ret = GetASN_Items(authKeyIdASN, dataASN, authKeyIdASN_Length,
21570
                        1, extData, &idx, extDataSz);
21571
                if ((ret == 0) &&
21572
                        (dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data
21573
                                != NULL)) {
21574
                    /* We parsed successfully and have data. */
21575
                    *set = 1;
21576
                    /* Get the hash or hash of the hash if wrong size. */
21577
                    ret = GetHashId(
21578
                        dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data,
21579
                        (int)dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.length,
21580
                        hash, HashIdAlg(sigOID));
21581
                }
21582
                break;
21583
            }
21584
        }
21585
    }
21586
21587
    FREE_ASNGETDATA(dataASN, heap);
21588
    return ret;
21589
}
21590
#endif
21591
21592
/* Only quick step through the certificate to find fields that are then used
21593
 * in certificate signature verification.
21594
 * Must use the signature OID from the signed part of the certificate.
21595
 * Works also on certificate signing requests.
21596
 *
21597
 * This is only for minimizing dynamic memory usage during TLS certificate
21598
 * chain processing.
21599
 * Doesn't support:
21600
 *   OCSP Only: alt lookup using subject and pub key w/o sig check
21601
 */
21602
static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap,
21603
        void* cm, const byte* pubKey, word32 pubKeySz, int pubKeyOID, int req)
21604
{
21605
#ifndef WOLFSSL_ASN_TEMPLATE
21606
#ifndef WOLFSSL_SMALL_STACK
21607
    SignatureCtx  sigCtx[1];
21608
#else
21609
    SignatureCtx* sigCtx;
21610
#endif
21611
    byte          hash[KEYID_SIZE];
21612
    Signer*       ca = NULL;
21613
    word32        idx = 0;
21614
    int           len;
21615
    word32        tbsCertIdx = 0;
21616
    word32        sigIndex   = 0;
21617
    word32        signatureOID = 0;
21618
    word32        oid = 0;
21619
    word32        issuerIdx = 0;
21620
    word32        issuerSz  = 0;
21621
#ifndef NO_SKID
21622
    int           extLen = 0;
21623
    word32        extIdx = 0;
21624
    word32        extEndIdx = 0;
21625
    int           extAuthKeyIdSet = 0;
21626
#endif
21627
    int           ret = 0;
21628
    word32        localIdx;
21629
    byte          tag;
21630
    const byte*   sigParams = NULL;
21631
    word32        sigParamsSz = 0;
21632
21633
21634
    if (cert == NULL) {
21635
        return BAD_FUNC_ARG;
21636
    }
21637
21638
#ifdef WOLFSSL_SMALL_STACK
21639
    sigCtx = (SignatureCtx*)XMALLOC(sizeof(*sigCtx), heap, DYNAMIC_TYPE_SIGNATURE);
21640
    if (sigCtx == NULL)
21641
        return MEMORY_E;
21642
#endif
21643
21644
    InitSignatureCtx(sigCtx, heap, INVALID_DEVID);
21645
21646
    /* Certificate SEQUENCE */
21647
    if (GetSequence(cert, &idx, &len, certSz) < 0)
21648
        ret = ASN_PARSE_E;
21649
    if (ret == 0) {
21650
        tbsCertIdx = idx;
21651
21652
        /* TBSCertificate SEQUENCE */
21653
        if (GetSequence(cert, &idx, &len, certSz) < 0)
21654
            ret = ASN_PARSE_E;
21655
    }
21656
    if (ret == 0) {
21657
        sigIndex = len + idx;
21658
21659
        if ((idx + 1) > certSz)
21660
            ret = BUFFER_E;
21661
    }
21662
    if (ret == 0) {
21663
        /* version - optional */
21664
        localIdx = idx;
21665
        if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) {
21666
            if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
21667
                idx++;
21668
                if (GetLength(cert, &idx, &len, certSz) < 0)
21669
                    ret = ASN_PARSE_E;
21670
                idx += len;
21671
            }
21672
        }
21673
    }
21674
21675
    if (ret == 0) {
21676
        /* serialNumber */
21677
        if (GetASNHeader(cert, ASN_INTEGER, &idx, &len, certSz) < 0)
21678
            ret = ASN_PARSE_E;
21679
    }
21680
    if (ret == 0) {
21681
        idx += len;
21682
21683
        /* signature */
21684
        if (!req) {
21685
            if (GetAlgoId(cert, &idx, &signatureOID, oidSigType, certSz) < 0)
21686
                ret = ASN_PARSE_E;
21687
        #ifdef WC_RSA_PSS
21688
            else if (signatureOID == CTC_RSASSAPSS) {
21689
                int start = idx;
21690
                sigParams = cert + idx;
21691
                if (GetSequence(cert, &idx, &len, certSz) < 0)
21692
                    ret = ASN_PARSE_E;
21693
                if (ret == 0) {
21694
                    idx += len;
21695
                    sigParamsSz = idx - start;
21696
                }
21697
            }
21698
        #endif
21699
        }
21700
    }
21701
21702
    if (ret == 0) {
21703
        issuerIdx = idx;
21704
        /* issuer for cert or subject for csr */
21705
        if (GetSequence(cert, &idx, &len, certSz) < 0)
21706
            ret = ASN_PARSE_E;
21707
    }
21708
    if (ret == 0) {
21709
        issuerSz = len + idx - issuerIdx;
21710
    }
21711
#ifndef NO_SKID
21712
    if (!req && ret == 0) {
21713
        idx += len;
21714
21715
        /* validity */
21716
        if (GetSequence(cert, &idx, &len, certSz) < 0)
21717
            ret = ASN_PARSE_E;
21718
    }
21719
    if (!req && ret == 0) {
21720
        idx += len;
21721
21722
        /* subject */
21723
        if (GetSequence(cert, &idx, &len, certSz) < 0)
21724
            ret = ASN_PARSE_E;
21725
    }
21726
    if (ret == 0) {
21727
        idx += len;
21728
21729
        /* subjectPublicKeyInfo */
21730
        if (GetSequence(cert, &idx, &len, certSz) < 0)
21731
            ret = ASN_PARSE_E;
21732
    }
21733
    if (req && ret == 0) {
21734
        idx += len;
21735
21736
        /* attributes */
21737
        if (GetASNHeader_ex(cert,
21738
                ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED, &idx,
21739
                &len, certSz, 1) < 0)
21740
            ret = ASN_PARSE_E;
21741
    }
21742
    if (!req) {
21743
        if (ret == 0) {
21744
            idx += len;
21745
21746
            if ((idx + 1) > certSz)
21747
                ret = BUFFER_E;
21748
        }
21749
        if (ret == 0) {
21750
            /* issuerUniqueID - optional */
21751
            localIdx = idx;
21752
            if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) {
21753
                if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) {
21754
                    idx++;
21755
                    if (GetLength(cert, &idx, &len, certSz) < 0)
21756
                        ret = ASN_PARSE_E;
21757
                    idx += len;
21758
                }
21759
            }
21760
        }
21761
        if (ret == 0) {
21762
            if ((idx + 1) > certSz)
21763
                ret = BUFFER_E;
21764
        }
21765
        if (ret == 0) {
21766
            /* subjectUniqueID - optional */
21767
            localIdx = idx;
21768
            if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) {
21769
                if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)) {
21770
                    idx++;
21771
                    if (GetLength(cert, &idx, &len, certSz) < 0)
21772
                        ret = ASN_PARSE_E;
21773
                    idx += len;
21774
                }
21775
            }
21776
        }
21777
21778
        if (ret == 0) {
21779
            if ((idx + 1) > certSz)
21780
                ret = BUFFER_E;
21781
        }
21782
        /* extensions - optional */
21783
        localIdx = idx;
21784
        if (ret == 0 && GetASNTag(cert, &localIdx, &tag, certSz) == 0 &&
21785
                tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 3)) {
21786
            idx++;
21787
            if (GetLength(cert, &idx, &extLen, certSz) < 0)
21788
                ret = ASN_PARSE_E;
21789
            if (ret == 0) {
21790
                if (GetSequence(cert, &idx, &extLen, certSz) < 0)
21791
                    ret = ASN_PARSE_E;
21792
            }
21793
            if (ret == 0) {
21794
                extEndIdx = idx + extLen;
21795
21796
                /* Check each extension for the ones we want. */
21797
                while (ret == 0 && idx < extEndIdx) {
21798
                    if (GetSequence(cert, &idx, &len, certSz) < 0)
21799
                        ret = ASN_PARSE_E;
21800
                    if (ret == 0) {
21801
                        extIdx = idx;
21802
                        if (GetObjectId(cert, &extIdx, &oid, oidCertExtType,
21803
                                                                  certSz) < 0) {
21804
                            ret = ASN_PARSE_E;
21805
                        }
21806
21807
                        if (ret == 0) {
21808
                            if ((extIdx + 1) > certSz)
21809
                                ret = BUFFER_E;
21810
                        }
21811
                    }
21812
21813
                    if (ret == 0) {
21814
                        localIdx = extIdx;
21815
                        if (GetASNTag(cert, &localIdx, &tag, certSz) == 0 &&
21816
                                tag == ASN_BOOLEAN) {
21817
                            if (GetBoolean(cert, &extIdx, certSz) < 0)
21818
                                ret = ASN_PARSE_E;
21819
                        }
21820
                    }
21821
                    if (ret == 0) {
21822
                        if (GetOctetString(cert, &extIdx, &extLen, certSz) < 0)
21823
                            ret = ASN_PARSE_E;
21824
                    }
21825
21826
                    if (ret == 0) {
21827
                        switch (oid) {
21828
                        case AUTH_KEY_OID:
21829
                            if (GetSequence(cert, &extIdx, &extLen, certSz) < 0)
21830
                                ret = ASN_PARSE_E;
21831
21832
                            if (ret == 0 && (extIdx + 1) >= certSz)
21833
                                ret = BUFFER_E;
21834
21835
                            if (ret == 0 &&
21836
                                    GetASNTag(cert, &extIdx, &tag, certSz) == 0 &&
21837
                                    tag == (ASN_CONTEXT_SPECIFIC | 0)) {
21838
                                if (GetLength(cert, &extIdx, &extLen, certSz) <= 0)
21839
                                    ret = ASN_PARSE_E;
21840
                                if (ret == 0) {
21841
                                    extAuthKeyIdSet = 1;
21842
                                    /* Get the hash or hash of the hash if wrong
21843
                                     * size. */
21844
                                    ret = GetHashId(cert + extIdx, extLen,
21845
                                        hash, HashIdAlg(signatureOID));
21846
                                }
21847
                            }
21848
                            break;
21849
21850
                        default:
21851
                            break;
21852
                        }
21853
                    }
21854
                    idx += len;
21855
                }
21856
            }
21857
        }
21858
    }
21859
    else if (ret == 0) {
21860
        idx += len;
21861
    }
21862
21863
    if (ret == 0 && pubKey == NULL) {
21864
        if (extAuthKeyIdSet)
21865
            ca = GetCA(cm, hash);
21866
        if (ca == NULL) {
21867
            ret = CalcHashId_ex(cert + issuerIdx, issuerSz, hash,
21868
                HashIdAlg(signatureOID));
21869
            if (ret == 0)
21870
                ca = GetCAByName(cm, hash);
21871
        }
21872
    }
21873
#else
21874
    if (ret == 0 && pubKey == NULL) {
21875
        ret = CalcHashId_ex(cert + issuerIdx, issuerSz, hash,
21876
            HashIdAlg(signatureOID));
21877
        if (ret == 0)
21878
            ca = GetCA(cm, hash);
21879
    }
21880
#endif /* !NO_SKID */
21881
    if (ca == NULL && pubKey == NULL)
21882
        ret = ASN_NO_SIGNER_E;
21883
21884
    if (ret == 0) {
21885
        idx = sigIndex;
21886
        /* signatureAlgorithm */
21887
        if (GetAlgoId(cert, &idx, &oid, oidSigType, certSz) < 0)
21888
            ret = ASN_PARSE_E;
21889
    #ifdef WC_RSA_PSS
21890
        else if (signatureOID == CTC_RSASSAPSS) {
21891
            word32 sz = idx;
21892
            const byte* params = cert + idx;
21893
            if (GetSequence(cert, &idx, &len, certSz) < 0)
21894
                ret = ASN_PARSE_E;
21895
            if (ret == 0) {
21896
                idx += len;
21897
                sz = idx - sz;
21898
21899
                if (req) {
21900
                    if ((sz != sigParamsSz) ||
21901
                                        (XMEMCMP(sigParams, params, sz) != 0)) {
21902
                        ret = ASN_PARSE_E;
21903
                    }
21904
                }
21905
                else {
21906
                    sigParams = params;
21907
                    sigParamsSz = sz;
21908
                }
21909
            }
21910
        }
21911
    #endif
21912
        /* In CSR signature data is not present in body */
21913
        if (req)
21914
            signatureOID = oid;
21915
    }
21916
    if (ret == 0) {
21917
        if (oid != signatureOID)
21918
            ret = ASN_SIG_OID_E;
21919
    }
21920
    if (ret == 0) {
21921
        /* signatureValue */
21922
        if (CheckBitString(cert, &idx, &len, certSz, 1, NULL) < 0)
21923
            ret = ASN_PARSE_E;
21924
    }
21925
21926
    if (ret == 0) {
21927
        if (pubKey != NULL) {
21928
            ret = ConfirmSignature(sigCtx, cert + tbsCertIdx,
21929
                sigIndex - tbsCertIdx, pubKey, pubKeySz, pubKeyOID,
21930
                cert + idx, len, signatureOID, sigParams, sigParamsSz, NULL);
21931
        }
21932
        else {
21933
            ret = ConfirmSignature(sigCtx, cert + tbsCertIdx,
21934
                sigIndex - tbsCertIdx, ca->publicKey, ca->pubKeySize,
21935
                ca->keyOID, cert + idx, len, signatureOID, sigParams,
21936
                sigParamsSz, NULL);
21937
        }
21938
        if (ret != 0) {
21939
            WOLFSSL_ERROR_VERBOSE(ret);
21940
            WOLFSSL_MSG("Confirm signature failed");
21941
        }
21942
    }
21943
21944
    FreeSignatureCtx(sigCtx);
21945
#ifdef WOLFSSL_SMALL_STACK
21946
    if (sigCtx != NULL)
21947
        XFREE(sigCtx, heap, DYNAMIC_TYPE_SIGNATURE);
21948
#endif
21949
    return ret;
21950
#else /* WOLFSSL_ASN_TEMPLATE */
21951
    /* X509 ASN.1 template longer than Certificate Request template. */
21952
    DECL_ASNGETDATA(dataASN, x509CertASN_Length);
21953
#ifndef WOLFSSL_SMALL_STACK
21954
    SignatureCtx  sigCtx[1];
21955
#else
21956
    SignatureCtx* sigCtx = NULL;
21957
#endif
21958
    byte hash[KEYID_SIZE];
21959
    Signer* ca = NULL;
21960
    int ret = 0;
21961
    word32 idx = 0;
21962
#ifndef NO_SKID
21963
    int extAuthKeyIdSet = 0;
21964
#endif
21965
    const byte* tbs = NULL;
21966
    word32 tbsSz = 0;
21967
#ifdef WC_RSA_PSS
21968
    const byte* tbsParams = NULL;
21969
    word32 tbsParamsSz = 0;
21970
#endif
21971
    const byte* sig = NULL;
21972
    word32 sigSz = 0;
21973
    word32 sigOID = 0;
21974
    const byte* sigParams = NULL;
21975
    word32 sigParamsSz = 0;
21976
    const byte* caName = NULL;
21977
    word32 caNameLen = 0;
21978
#ifndef NO_SKID
21979
    const byte* akiData = NULL;
21980
    word32 akiLen = 0;
21981
#endif
21982
21983
    (void)req;
21984
    (void)heap;
21985
21986
    if (cert == NULL) {
21987
        ret = BAD_FUNC_ARG;
21988
    }
21989
21990
    ALLOC_ASNGETDATA(dataASN, x509CertASN_Length, ret, heap);
21991
21992
    if ((ret == 0) && (!req)) {
21993
        /* Clear dynamic data for certificate items. */
21994
        XMEMSET(dataASN, 0, sizeof(ASNGetData) * x509CertASN_Length);
21995
        /* Set OID types expected for signature and public key. */
21996
        GetASN_OID(&dataASN[X509CERTASN_IDX_TBS_ALGOID_OID], oidSigType);
21997
        GetASN_OID(&dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_OID],
21998
                oidKeyType);
21999
        GetASN_OID(&dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_CURVEID],
22000
                oidCurveType);
22001
        GetASN_OID(&dataASN[X509CERTASN_IDX_SIGALGO_OID], oidSigType);
22002
        /* Parse certificate. */
22003
        ret = GetASN_Items(x509CertASN, dataASN, x509CertASN_Length, 1, cert,
22004
                           &idx, certSz);
22005
22006
        /* Check signature OIDs match. */
22007
        if ((ret == 0) && dataASN[X509CERTASN_IDX_TBS_ALGOID_OID].data.oid.sum
22008
                != dataASN[X509CERTASN_IDX_SIGALGO_OID].data.oid.sum) {
22009
            ret = ASN_SIG_OID_E;
22010
        }
22011
        /* Store the data for verification in the certificate. */
22012
        if (ret == 0) {
22013
            tbs = GetASNItem_Addr(dataASN[X509CERTASN_IDX_TBS_SEQ], cert);
22014
            tbsSz = GetASNItem_Length(dataASN[X509CERTASN_IDX_TBS_SEQ], cert);
22015
            caName = GetASNItem_Addr(dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ],
22016
                    cert);
22017
            caNameLen = GetASNItem_Length(dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ],
22018
                    cert);
22019
            sigOID = dataASN[X509CERTASN_IDX_SIGALGO_OID].data.oid.sum;
22020
        #ifdef WC_RSA_PSS
22021
            if (dataASN[X509CERTASN_IDX_TBS_ALGOID_PARAMS].tag != 0) {
22022
                tbsParams =
22023
                    GetASNItem_Addr(dataASN[X509CERTASN_IDX_TBS_ALGOID_PARAMS],
22024
                        cert);
22025
                tbsParamsSz =
22026
                    GetASNItem_Length(dataASN[X509CERTASN_IDX_TBS_ALGOID_PARAMS],
22027
                        cert);
22028
            }
22029
            if (dataASN[X509CERTASN_IDX_SIGALGO_PARAMS].tag != 0) {
22030
                sigParams =
22031
                    GetASNItem_Addr(dataASN[X509CERTASN_IDX_SIGALGO_PARAMS],
22032
                        cert);
22033
                sigParamsSz =
22034
                    GetASNItem_Length(dataASN[X509CERTASN_IDX_SIGALGO_PARAMS],
22035
                        cert);
22036
            }
22037
        #endif
22038
            GetASN_GetConstRef(&dataASN[X509CERTASN_IDX_SIGNATURE], &sig, &sigSz);
22039
        #ifdef WC_RSA_PSS
22040
            if (tbsParamsSz != sigParamsSz) {
22041
                ret = ASN_PARSE_E;
22042
            }
22043
            else if ((tbsParamsSz > 0) && (sigOID != CTC_RSASSAPSS)) {
22044
                ret = ASN_PARSE_E;
22045
            }
22046
            else if ((tbsParamsSz > 0) &&
22047
                     (XMEMCMP(tbsParams, sigParams, tbsParamsSz) != 0)) {
22048
                ret = ASN_PARSE_E;
22049
            }
22050
        #endif
22051
        }
22052
    }
22053
    else if (ret == 0) {
22054
#ifndef WOLFSSL_CERT_REQ
22055
        ret = NOT_COMPILED_IN;
22056
#else
22057
        /* Clear dynamic data for certificate request items. */
22058
        XMEMSET(dataASN, 0, sizeof(ASNGetData) * certReqASN_Length);
22059
        /* Set OID types expected for signature and public key. */
22060
        GetASN_OID(&dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_OID],
22061
                oidKeyType);
22062
        GetASN_OID(&dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_CURVEID],
22063
                oidCurveType);
22064
        GetASN_OID(&dataASN[CERTREQASN_IDX_INFO_SIGALGO_OID], oidSigType);
22065
        /* Parse certificate request. */
22066
        ret = GetASN_Items(certReqASN, dataASN, certReqASN_Length, 1, cert,
22067
                           &idx, certSz);
22068
        if (ret == 0) {
22069
            /* Store the data for verification in the certificate. */
22070
            tbs = GetASNItem_Addr(dataASN[CERTREQASN_IDX_INFO_SEQ], cert);
22071
            tbsSz = GetASNItem_Length(dataASN[CERTREQASN_IDX_INFO_SEQ], cert);
22072
            caName = GetASNItem_Addr(
22073
                    dataASN[CERTREQASN_IDX_INFO_SUBJ_SEQ], cert);
22074
            caNameLen = GetASNItem_Length(
22075
                    dataASN[CERTREQASN_IDX_INFO_SUBJ_SEQ], cert);
22076
            sigOID = dataASN[CERTREQASN_IDX_INFO_SIGALGO_OID].data.oid.sum;
22077
        #ifdef WC_RSA_PSS
22078
            sigParams = GetASNItem_Addr(dataASN[X509CERTASN_IDX_SIGALGO_PARAMS],
22079
                cert);
22080
            sigParamsSz =
22081
                GetASNItem_Length(dataASN[X509CERTASN_IDX_SIGALGO_PARAMS],
22082
                    cert);
22083
        #endif
22084
            GetASN_GetConstRef(&dataASN[CERTREQASN_IDX_INFO_SIGNATURE], &sig,
22085
                    &sigSz);
22086
        }
22087
#endif
22088
    }
22089
22090
#ifndef NO_SKID
22091
    if ((ret == 0) && (pubKey == NULL) && !req) {
22092
        akiData = dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].data.ref.data;
22093
        akiLen = dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].data.ref.length;
22094
    }
22095
#endif
22096
22097
    FREE_ASNGETDATA(dataASN, heap);
22098
22099
    /* If no public passed, then find the CA. */
22100
    if ((ret == 0) && (pubKey == NULL)) {
22101
#ifndef NO_SKID
22102
        /* Find the AKI extension in list of extensions and get hash. */
22103
        if ((!req) && (akiData != NULL)) {
22104
            /* TODO: test case */
22105
            ret = GetAKIHash(akiData, akiLen, sigOID, hash, &extAuthKeyIdSet,
22106
                heap);
22107
        }
22108
22109
        /* Get the CA by hash one was found. */
22110
        if (extAuthKeyIdSet) {
22111
            ca = GetCA(cm, hash);
22112
        }
22113
        if (ca == NULL)
22114
#endif
22115
        {
22116
            /* Try hash of issuer name. */
22117
            ret = CalcHashId_ex(caName, caNameLen, hash, HashIdAlg(sigOID));
22118
            if (ret == 0) {
22119
                ca = GetCAByName(cm, hash);
22120
            }
22121
        }
22122
22123
        if (ca != NULL) {
22124
            /* Extract public key information. */
22125
            pubKey = ca->publicKey;
22126
            pubKeySz = ca->pubKeySize;
22127
            pubKeyOID = (int)ca->keyOID;
22128
        }
22129
        else {
22130
            /* No public key to verify with. */
22131
            ret = ASN_NO_SIGNER_E;
22132
        }
22133
    }
22134
22135
    if (ret == 0) {
22136
    #ifdef WOLFSSL_SMALL_STACK
22137
        sigCtx = (SignatureCtx*)XMALLOC(sizeof(*sigCtx), heap,
22138
            DYNAMIC_TYPE_SIGNATURE);
22139
        if (sigCtx == NULL) {
22140
            ret = MEMORY_E;
22141
        }
22142
        if (ret == 0)
22143
    #endif
22144
        {
22145
            InitSignatureCtx(sigCtx, heap, INVALID_DEVID);
22146
22147
            /* Check signature. */
22148
            ret = ConfirmSignature(sigCtx, tbs, tbsSz, pubKey, pubKeySz,
22149
                (word32)pubKeyOID, sig, sigSz, sigOID, sigParams, sigParamsSz,
22150
                NULL);
22151
            if (ret != 0) {
22152
                WOLFSSL_MSG("Confirm signature failed");
22153
            }
22154
22155
            FreeSignatureCtx(sigCtx);
22156
        #ifdef WOLFSSL_SMALL_STACK
22157
            XFREE(sigCtx, heap, DYNAMIC_TYPE_SIGNATURE);
22158
        #endif
22159
        }
22160
    }
22161
22162
    return ret;
22163
#endif /* WOLFSSL_ASN_TEMPLATE */
22164
}
22165
22166
#ifdef OPENSSL_EXTRA
22167
/* Call CheckCertSignature_ex using a public key buffer for verification
22168
 */
22169
int CheckCertSignaturePubKey(const byte* cert, word32 certSz, void* heap,
22170
        const byte* pubKey, word32 pubKeySz, int pubKeyOID)
22171
{
22172
    return CheckCertSignature_ex(cert, certSz, heap, NULL,
22173
            pubKey, pubKeySz, pubKeyOID, 0);
22174
}
22175
22176
int wc_CheckCertSigPubKey(const byte* cert, word32 certSz, void* heap,
22177
        const byte* pubKey, word32 pubKeySz, int pubKeyOID)
22178
{
22179
        return CheckCertSignaturePubKey(cert, certSz, heap, pubKey, pubKeySz,
22180
                                        pubKeyOID);
22181
}
22182
22183
#ifdef WOLFSSL_CERT_REQ
22184
int CheckCSRSignaturePubKey(const byte* cert, word32 certSz, void* heap,
22185
        const byte* pubKey, word32 pubKeySz, int pubKeyOID)
22186
{
22187
    return CheckCertSignature_ex(cert, certSz, heap, NULL,
22188
            pubKey, pubKeySz, pubKeyOID, 1);
22189
}
22190
#endif /* WOLFSSL_CERT_REQ */
22191
#endif /* OPENSSL_EXTRA */
22192
#ifdef WOLFSSL_SMALL_CERT_VERIFY
22193
/* Call CheckCertSignature_ex using a certificate manager (cm)
22194
 */
22195
int CheckCertSignature(const byte* cert, word32 certSz, void* heap, void* cm)
22196
{
22197
    return CheckCertSignature_ex(cert, certSz, heap, cm, NULL, 0, 0, 0);
22198
}
22199
#endif /* WOLFSSL_SMALL_CERT_VERIFY */
22200
#endif /* WOLFSSL_SMALL_CERT_VERIFY || OPENSSL_EXTRA */
22201
22202
#if (defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) || \
22203
    (defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)))
22204
/* ASN.1 DER decode instruction. */
22205
typedef struct DecodeInstr {
22206
    /* Tag expected. */
22207
    byte tag;
22208
    /* Operation to perform: step in or go over */
22209
    byte op:1;
22210
    /* ASN.1 item is optional. */
22211
    byte optional:1;
22212
} DecodeInstr;
22213
22214
/* Step into ASN.1 item. */
22215
0
#define DECODE_INSTR_IN    0
22216
/* Step over ASN.1 item. */
22217
0
#define DECODE_INSTR_OVER  1
22218
22219
/* Get the public key data from the DER encoded X.509 certificate.
22220
 *
22221
 * Assumes data has previously been parsed for complete validity.
22222
 *
22223
 * @param [in]  cert      DER encoded X.509 certificate data.
22224
 * @param [in]  certSz    Length of DER encoding.
22225
 * @param [out] pubKey    Public key data. (From the BIT_STRING.)
22226
 * @param [out] pubKeySz  Length of public key data in bytes.
22227
 * @return  0 on success.
22228
 * @return  BAD_FUNC_ARG when cert, pubKey or pubKeySz is NULL.
22229
 * @return  ASN_PARSE_E when certificate encoding is invalid.
22230
 */
22231
int wc_CertGetPubKey(const byte* cert, word32 certSz,
22232
    const unsigned char** pubKey, word32* pubKeySz)
22233
0
{
22234
0
    int ret = 0;
22235
0
    int l;
22236
0
    word32 o = 0;
22237
0
    int i;
22238
0
    static DecodeInstr ops[] = {
22239
        /* Outer SEQ */
22240
0
        { ASN_SEQUENCE | ASN_CONSTRUCTED, DECODE_INSTR_IN  , 0 },
22241
        /* TBSCertificate: SEQ */
22242
0
        { ASN_SEQUENCE | ASN_CONSTRUCTED, DECODE_INSTR_IN  , 0 },
22243
        /* Version: [0] */
22244
0
        { ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_X509_CERT_VERSION,
22245
0
          DECODE_INSTR_OVER, 1 },
22246
        /* CertificateSerialNumber: INT  */
22247
0
        { ASN_INTEGER,                    DECODE_INSTR_OVER, 0 },
22248
        /* AlgorithmIdentifier: SEQ */
22249
0
        { ASN_SEQUENCE | ASN_CONSTRUCTED, DECODE_INSTR_OVER, 0 },
22250
        /* issuer: SEQ */
22251
0
        { ASN_SEQUENCE | ASN_CONSTRUCTED, DECODE_INSTR_OVER, 0 },
22252
        /* Validity: SEQ */
22253
0
        { ASN_SEQUENCE | ASN_CONSTRUCTED, DECODE_INSTR_OVER, 0 },
22254
        /* subject: SEQ */
22255
0
        { ASN_SEQUENCE | ASN_CONSTRUCTED, DECODE_INSTR_OVER, 0 },
22256
        /* subjectPublicKeyInfo SEQ */
22257
0
        { ASN_SEQUENCE | ASN_CONSTRUCTED, DECODE_INSTR_IN  , 0 },
22258
        /* AlgorithmIdentifier: SEQ */
22259
0
        { ASN_SEQUENCE | ASN_CONSTRUCTED, DECODE_INSTR_OVER, 0 },
22260
        /* PublicKey: BIT_STRING  */
22261
0
        { ASN_BIT_STRING,                 DECODE_INSTR_IN  , 0 },
22262
0
    };
22263
22264
    /* Validate parameters. */
22265
0
    if ((cert == NULL) || (pubKey == NULL) || (pubKeySz == NULL)) {
22266
0
        ret = BAD_FUNC_ARG;
22267
0
    }
22268
22269
    /* Process each instruction to take us to public key data. */
22270
0
    for (i = 0; (ret == 0) && (i < (int)(sizeof(ops) / sizeof(*ops))); i++) {
22271
0
        DecodeInstr op = ops[i];
22272
22273
        /* Check the current ASN.1 item has the expected tag. */
22274
0
        if (cert[o] != op.tag) {
22275
            /* If not optional then error, otherwise skip op. */
22276
0
            if (!op.optional) {
22277
0
                ret = ASN_PARSE_E;
22278
0
            }
22279
0
        }
22280
0
        else {
22281
            /* Move past tag. */
22282
0
            o++;
22283
            /* Get the length of ASN.1 item and move past length encoding. */
22284
0
            if (GetLength(cert, &o, &l, certSz) < 0) {
22285
0
                ret = ASN_PARSE_E;
22286
0
            }
22287
            /* Skip data if required. */
22288
0
            else if (op.op == DECODE_INSTR_OVER) {
22289
0
                o += (word32)l;
22290
0
            }
22291
0
        }
22292
0
    }
22293
22294
0
    if (ret == 0) {
22295
        /* Return the public key data and length.
22296
         * Skip first byte of BIT_STRING data: unused bits. */
22297
0
        *pubKey = cert + o + 1;
22298
0
        *pubKeySz = (word32)(l - 1);
22299
0
    }
22300
22301
0
    return ret;
22302
0
}
22303
#endif
22304
22305
int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
22306
0
{
22307
0
    int    ret = 0;
22308
#ifndef WOLFSSL_ASN_TEMPLATE
22309
    word32 confirmOID = 0;
22310
#ifdef WOLFSSL_CERT_REQ
22311
    int    len = 0;
22312
#endif
22313
#endif
22314
#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT)
22315
    int    idx = 0;
22316
#endif
22317
0
    byte*  sce_tsip_encRsaKeyIdx;
22318
22319
0
    if (cert == NULL) {
22320
0
        return BAD_FUNC_ARG;
22321
0
    }
22322
22323
#ifdef WOLFSSL_CERT_REQ
22324
    if (type == CERTREQ_TYPE)
22325
        cert->isCSR = 1;
22326
#endif
22327
22328
0
    if (cert->sigCtx.state == SIG_STATE_BEGIN) {
22329
#ifndef WOLFSSL_ASN_TEMPLATE
22330
        cert->badDate = 0;
22331
        cert->criticalExt = 0;
22332
        if ((ret = DecodeToKey(cert, verify)) < 0) {
22333
            if (ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E) {
22334
                cert->badDate = ret;
22335
                if (verify == VERIFY_SKIP_DATE)
22336
                    ret = 0;
22337
            }
22338
            else
22339
                return ret;
22340
        }
22341
22342
        WOLFSSL_MSG("Parsed Past Key");
22343
22344
22345
#ifdef WOLFSSL_CERT_REQ
22346
        /* Read attributes */
22347
        if (cert->isCSR) {
22348
            if (GetASNHeader_ex(cert->source,
22349
                    ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED, &cert->srcIdx,
22350
                    &len, cert->maxIdx, 1) < 0) {
22351
                WOLFSSL_MSG("GetASNHeader_ex error");
22352
                return ASN_PARSE_E;
22353
            }
22354
22355
            if (len) {
22356
                word32 attrMaxIdx = cert->srcIdx + (word32)len;
22357
                word32 oid;
22358
                byte   tag;
22359
22360
                if (attrMaxIdx > cert->maxIdx) {
22361
                    WOLFSSL_MSG("Attribute length greater than CSR length");
22362
                    return ASN_PARSE_E;
22363
                }
22364
22365
                while (cert->srcIdx < attrMaxIdx) {
22366
                    /* Attributes have the structure:
22367
                     * SEQ -> OID -> SET -> ATTRIBUTE */
22368
                    if (GetSequence(cert->source, &cert->srcIdx, &len,
22369
                            attrMaxIdx) < 0) {
22370
                        WOLFSSL_MSG("attr GetSequence error");
22371
                        return ASN_PARSE_E;
22372
                    }
22373
                    if (GetObjectId(cert->source, &cert->srcIdx, &oid,
22374
                            oidCsrAttrType, attrMaxIdx) < 0) {
22375
                        WOLFSSL_MSG("attr GetObjectId error");
22376
                        return ASN_PARSE_E;
22377
                    }
22378
                    if (GetSet(cert->source, &cert->srcIdx, &len,
22379
                            attrMaxIdx) < 0) {
22380
                        WOLFSSL_MSG("attr GetSet error");
22381
                        return ASN_PARSE_E;
22382
                    }
22383
                    switch (oid) {
22384
                    case PKCS9_CONTENT_TYPE_OID:
22385
                        if (GetHeader(cert->source, &tag,
22386
                                &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
22387
                            WOLFSSL_MSG("attr GetHeader error");
22388
                            return ASN_PARSE_E;
22389
                        }
22390
                        if (tag != ASN_PRINTABLE_STRING && tag != ASN_UTF8STRING &&
22391
                                tag != ASN_IA5_STRING) {
22392
                            WOLFSSL_MSG("Unsupported attribute value format");
22393
                            return ASN_PARSE_E;
22394
                        }
22395
                        cert->contentType = (char*)cert->source + cert->srcIdx;
22396
                        cert->contentTypeLen = len;
22397
                        cert->srcIdx += (word32)len;
22398
                        break;
22399
                    case CHALLENGE_PASSWORD_OID:
22400
                        if (GetHeader(cert->source, &tag,
22401
                                &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
22402
                            WOLFSSL_MSG("attr GetHeader error");
22403
                            return ASN_PARSE_E;
22404
                        }
22405
                        if (tag != ASN_PRINTABLE_STRING && tag != ASN_UTF8STRING &&
22406
                                tag != ASN_IA5_STRING) {
22407
                            WOLFSSL_MSG("Unsupported attribute value format");
22408
                            return ASN_PARSE_E;
22409
                        }
22410
                        cert->cPwd = (char*)cert->source + cert->srcIdx;
22411
                        cert->cPwdLen = len;
22412
                        cert->srcIdx += (word32)len;
22413
                        break;
22414
                    case SERIAL_NUMBER_OID:
22415
                        if (GetHeader(cert->source, &tag,
22416
                                &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
22417
                            WOLFSSL_MSG("attr GetHeader error");
22418
                            return ASN_PARSE_E;
22419
                        }
22420
                        if (tag != ASN_PRINTABLE_STRING && tag != ASN_UTF8STRING &&
22421
                                tag != ASN_IA5_STRING) {
22422
                            WOLFSSL_MSG("Unsupported attribute value format");
22423
                            return ASN_PARSE_E;
22424
                        }
22425
                        cert->sNum = (char*)cert->source + cert->srcIdx;
22426
                        cert->sNumLen = len;
22427
                        cert->srcIdx += (word32)len;
22428
                        if (cert->sNumLen <= EXTERNAL_SERIAL_SIZE) {
22429
                            XMEMCPY(cert->serial, cert->sNum,
22430
                                    (size_t)cert->sNumLen);
22431
                            cert->serialSz = cert->sNumLen;
22432
                        }
22433
                        break;
22434
                    case DNQUALIFIER_OID:
22435
                        if (GetHeader(cert->source, &tag,
22436
                                &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
22437
                            WOLFSSL_MSG("attr GetHeader error");
22438
                            return ASN_PARSE_E;
22439
                        }
22440
                        cert->dnQualifier = (char*)cert->source + cert->srcIdx;
22441
                        cert->dnQualifierLen = len;
22442
                        cert->srcIdx += (word32)len;
22443
                        break;
22444
                    case INITIALS_OID:
22445
                        if (GetHeader(cert->source, &tag,
22446
                                &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
22447
                            WOLFSSL_MSG("attr GetHeader error");
22448
                            return ASN_PARSE_E;
22449
                        }
22450
                        cert->initials = (char*)cert->source + cert->srcIdx;
22451
                        cert->initialsLen = len;
22452
                        cert->srcIdx += (word32)len;
22453
                        break;
22454
                    case SURNAME_OID:
22455
                        if (GetHeader(cert->source, &tag,
22456
                                &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
22457
                            WOLFSSL_MSG("attr GetHeader error");
22458
                            return ASN_PARSE_E;
22459
                        }
22460
                        cert->surname = (char*)cert->source + cert->srcIdx;
22461
                        cert->surnameLen = len;
22462
                        cert->srcIdx += (word32)len;
22463
                        break;
22464
                    case GIVEN_NAME_OID:
22465
                        if (GetHeader(cert->source, &tag,
22466
                                &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
22467
                            WOLFSSL_MSG("attr GetHeader error");
22468
                            return ASN_PARSE_E;
22469
                        }
22470
                        cert->givenName = (char*)cert->source + cert->srcIdx;
22471
                        cert->givenNameLen = len;
22472
                        cert->srcIdx += (word32)len;
22473
                        break;
22474
                    case UNSTRUCTURED_NAME_OID:
22475
                        if (GetHeader(cert->source, &tag,
22476
                                &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
22477
                            WOLFSSL_MSG("attr GetHeader error");
22478
                            return ASN_PARSE_E;
22479
                        }
22480
                        cert->unstructuredName =
22481
                            (char*)cert->source + cert->srcIdx;
22482
                        cert->unstructuredNameLen = len;
22483
                        cert->srcIdx += (word32)len;
22484
                        break;
22485
                    case EXTENSION_REQUEST_OID:
22486
                        /* save extensions */
22487
                        cert->extensions    = &cert->source[cert->srcIdx];
22488
                        cert->extensionsSz  = len;
22489
                        cert->extensionsIdx = cert->srcIdx; /* for potential later use */
22490
22491
                        if ((ret = DecodeCertExtensions(cert)) < 0) {
22492
                            if (ret == ASN_CRIT_EXT_E) {
22493
                                cert->criticalExt = ret;
22494
                            }
22495
                            else {
22496
                                return ret;
22497
                            }
22498
                        }
22499
                        cert->srcIdx += (word32)len;
22500
                        break;
22501
                    default:
22502
                        WOLFSSL_MSG("Unsupported attribute type");
22503
                        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
22504
                        return ASN_PARSE_E;
22505
                    }
22506
                }
22507
            }
22508
        }
22509
#endif
22510
22511
        if (cert->srcIdx < cert->sigIndex) {
22512
        #ifndef ALLOW_V1_EXTENSIONS
22513
            if (cert->version < 2) {
22514
                WOLFSSL_MSG("\tv1 and v2 certs not allowed extensions");
22515
                WOLFSSL_ERROR_VERBOSE(ASN_VERSION_E);
22516
                return ASN_VERSION_E;
22517
            }
22518
        #endif
22519
22520
            /* save extensions */
22521
            cert->extensions    = &cert->source[cert->srcIdx];
22522
            cert->extensionsSz  = (int)(cert->sigIndex - cert->srcIdx);
22523
            cert->extensionsIdx = cert->srcIdx;   /* for potential later use */
22524
22525
            if ((ret = DecodeCertExtensions(cert)) < 0) {
22526
                if (ret == ASN_CRIT_EXT_E)
22527
                    cert->criticalExt = ret;
22528
                else
22529
                    return ret;
22530
            }
22531
22532
        #ifdef HAVE_OCSP
22533
            if (verify == VERIFY_OCSP_CERT) {
22534
                /* trust for the lifetime of the responder's cert*/
22535
                if (cert->ocspNoCheckSet)
22536
                    verify = VERIFY;
22537
                else
22538
                    verify = VERIFY_OCSP;
22539
            }
22540
        #endif
22541
            /* advance past extensions */
22542
            cert->srcIdx = cert->sigIndex;
22543
        }
22544
22545
        if ((ret = GetSigAlg(cert,
22546
#ifdef WOLFSSL_CERT_REQ
22547
                !cert->isCSR ? &confirmOID : &cert->signatureOID,
22548
#else
22549
                &confirmOID,
22550
#endif
22551
                cert->maxIdx)) < 0) {
22552
            return ret;
22553
        }
22554
22555
        if ((ret = GetSignature(cert)) < 0) {
22556
            return ret;
22557
        }
22558
22559
        if (confirmOID != cert->signatureOID
22560
#ifdef WOLFSSL_CERT_REQ
22561
                && !cert->isCSR
22562
#endif
22563
                ) {
22564
            WOLFSSL_ERROR_VERBOSE(ASN_SIG_OID_E);
22565
            return ASN_SIG_OID_E;
22566
        }
22567
#else
22568
#ifdef WOLFSSL_CERT_REQ
22569
        if (cert->isCSR) {
22570
            ret = DecodeCertReq(cert, &cert->criticalExt);
22571
            if (ret < 0) {
22572
                return ret;
22573
            }
22574
        }
22575
        else
22576
#endif
22577
0
        {
22578
0
            ret = DecodeCert(cert, verify, &cert->criticalExt);
22579
0
            if (ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E) {
22580
0
                cert->badDate = ret;
22581
0
                if (verify == VERIFY_SKIP_DATE)
22582
0
                    ret = 0;
22583
0
            }
22584
0
            else if (ret < 0) {
22585
0
                WOLFSSL_ERROR_VERBOSE(ret);
22586
0
                return ret;
22587
0
            }
22588
0
        }
22589
0
#endif
22590
22591
0
    #ifndef ALLOW_INVALID_CERTSIGN
22592
        /* https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.9
22593
         *   If the cA boolean is not asserted, then the keyCertSign bit in the
22594
         *   key usage extension MUST NOT be asserted. */
22595
0
        if (!cert->isCA && cert->extKeyUsageSet &&
22596
0
                (cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) != 0) {
22597
0
            WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E);
22598
0
            return KEYUSAGE_E;
22599
0
        }
22600
0
    #endif
22601
22602
0
    #ifndef NO_SKID
22603
0
        if (cert->extSubjKeyIdSet == 0 && cert->publicKey != NULL &&
22604
0
                                                         cert->pubKeySize > 0) {
22605
0
            if (cert->signatureOID == CTC_SM3wSM2) {
22606
                /* TODO: GmSSL creates IDs this way but whole public key info
22607
                 * block should be hashed. */
22608
0
                ret = CalcHashId_ex(cert->publicKey + cert->pubKeySize - 65, 65,
22609
0
                    cert->extSubjKeyId, HashIdAlg(cert->signatureOID));
22610
0
            }
22611
0
            else {
22612
0
                ret = CalcHashId_ex(cert->publicKey, cert->pubKeySize,
22613
0
                    cert->extSubjKeyId, HashIdAlg(cert->signatureOID));
22614
0
            }
22615
0
            if (ret != 0) {
22616
0
                WOLFSSL_ERROR_VERBOSE(ret);
22617
0
                return ret;
22618
0
            }
22619
0
        }
22620
0
    #endif /* !NO_SKID */
22621
22622
0
        if (!cert->selfSigned || (verify != NO_VERIFY && type != CA_TYPE &&
22623
0
                                                   type != TRUSTED_PEER_TYPE)) {
22624
0
            cert->ca = NULL;
22625
0
    #ifndef NO_SKID
22626
0
            if (cert->extAuthKeyIdSet) {
22627
0
                cert->ca = GetCA(cm, cert->extAuthKeyId);
22628
        #ifdef WOLFSSL_AKID_NAME
22629
                if (cert->ca == NULL) {
22630
                    cert->ca = GetCAByAKID(cm, cert->extAuthKeyIdIssuer,
22631
                        cert->extAuthKeyIdIssuerSz, cert->extAuthKeyIdIssuerSN,
22632
                        cert->extAuthKeyIdIssuerSNSz);
22633
                }
22634
        #endif
22635
0
            }
22636
0
            if (cert->ca == NULL && cert->extSubjKeyIdSet
22637
0
                                 && verify != VERIFY_OCSP) {
22638
0
                cert->ca = GetCA(cm, cert->extSubjKeyId);
22639
0
            }
22640
0
            if (cert->ca != NULL && XMEMCMP(cert->issuerHash,
22641
0
                    cert->ca->subjectNameHash, KEYID_SIZE) != 0) {
22642
0
                cert->ca = NULL;
22643
0
            }
22644
0
            if (cert->ca == NULL) {
22645
0
                cert->ca = GetCAByName(cm, cert->issuerHash);
22646
                /* If AKID is available then this CA doesn't have the public
22647
                 * key required */
22648
0
                if (cert->ca && cert->extAuthKeyIdSet) {
22649
0
                    WOLFSSL_MSG("CA SKID doesn't match AKID");
22650
0
                    cert->ca = NULL;
22651
0
                }
22652
0
            }
22653
22654
            /* OCSP Only: alt lookup using subject and pub key w/o sig check */
22655
        #ifdef WOLFSSL_NO_TRUSTED_CERTS_VERIFY
22656
            if (cert->ca == NULL && verify == VERIFY_OCSP) {
22657
                cert->ca = GetCABySubjectAndPubKey(cert, cm);
22658
                if (cert->ca) {
22659
                    ret = 0; /* success */
22660
                    goto exit_pcr;
22661
                }
22662
            }
22663
        #endif /* WOLFSSL_NO_TRUSTED_CERTS_VERIFY */
22664
    #else
22665
            cert->ca = GetCA(cm, cert->issuerHash);
22666
    #endif /* !NO_SKID */
22667
22668
0
            if (cert->ca) {
22669
0
                WOLFSSL_MSG("CA found");
22670
0
            }
22671
0
        }
22672
22673
        /* Set to WOLFSSL_MAX_PATH_LEN by default in InitDecodedCert_ex */
22674
0
        if (cert->pathLengthSet)
22675
0
            cert->maxPathLen = cert->pathLength;
22676
22677
0
        if (!cert->selfSigned) {
22678
            /* Need to perform a pathlen check on anything that will be used
22679
             * to sign certificates later on. Otherwise, pathLen doesn't
22680
             * mean anything.
22681
             * Nothing to check if we don't have the issuer of this cert. */
22682
0
            if (type != CERT_TYPE && cert->isCA && cert->extKeyUsageSet &&
22683
0
                (cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) != 0 && cert->ca) {
22684
0
                if (cert->ca->maxPathLen == 0) {
22685
                    /* This cert CAN NOT be used as an intermediate cert. The
22686
                     * issuer does not allow it. */
22687
0
                    cert->maxPathLen = 0;
22688
0
                    if (verify != NO_VERIFY) {
22689
0
                        WOLFSSL_MSG("\tNon-entity cert, maxPathLen is 0");
22690
0
                        WOLFSSL_MSG("\tmaxPathLen status: ERROR");
22691
0
                        WOLFSSL_ERROR_VERBOSE(ASN_PATHLEN_INV_E);
22692
0
                        return ASN_PATHLEN_INV_E;
22693
0
                    }
22694
0
                }
22695
0
                else {
22696
0
                    cert->maxPathLen = (byte)min(cert->ca->maxPathLen - 1,
22697
0
                                           cert->maxPathLen);
22698
0
                }
22699
0
            }
22700
0
        }
22701
22702
        #ifdef HAVE_OCSP
22703
        if (verify != NO_VERIFY && type != CA_TYPE &&
22704
                                                type != TRUSTED_PEER_TYPE) {
22705
            if (cert->ca) {
22706
                /* Need the CA's public key hash for OCSP */
22707
                XMEMCPY(cert->issuerKeyHash, cert->ca->subjectKeyHash,
22708
                    KEYID_SIZE);
22709
            }
22710
        }
22711
        #endif /* HAVE_OCSP */
22712
0
    }
22713
#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT)
22714
    /* prepare for TSIP TLS cert verification API use */
22715
    if (cert->keyOID == RSAk) {
22716
        /* to call TSIP API, it needs keys position info in bytes */
22717
        if ((ret = RsaPublicKeyDecodeRawIndex(cert->publicKey, (word32*)&idx,
22718
                                   cert->pubKeySize,
22719
                                   &cert->sigCtx.CertAtt.pubkey_n_start,
22720
                                   &cert->sigCtx.CertAtt.pubkey_n_len,
22721
                                   &cert->sigCtx.CertAtt.pubkey_e_start,
22722
                                   &cert->sigCtx.CertAtt.pubkey_e_len)) != 0) {
22723
            WOLFSSL_MSG("Decoding index from cert failed.");
22724
            return ret;
22725
        }
22726
        cert->sigCtx.CertAtt.certBegin = cert->certBegin;
22727
    }
22728
    else if (cert->keyOID == ECDSAk) {
22729
        cert->sigCtx.CertAtt.certBegin = cert->certBegin;
22730
    }
22731
    /* check if we can use TSIP for cert verification */
22732
    /* if the ca is verified as tsip root ca.         */
22733
    /* TSIP can only handle 2048 bits(256 byte) key.  */
22734
    if (cert->ca && Renesas_cmn_checkCA(cert->ca->cm_idx) != 0 &&
22735
        (cert->sigCtx.CertAtt.pubkey_n_len == 256 ||
22736
         cert->sigCtx.CertAtt.curve_id == ECC_SECP256R1)) {
22737
22738
        /* assign memory to encrypted tsip Rsa key index */
22739
        if (!cert->sce_tsip_encRsaKeyIdx)
22740
            cert->sce_tsip_encRsaKeyIdx =
22741
                            (byte*)XMALLOC(TSIP_TLS_ENCPUBKEY_SZ_BY_CERTVRFY,
22742
                             cert->heap, DYNAMIC_TYPE_RSA);
22743
        if (cert->sce_tsip_encRsaKeyIdx == NULL)
22744
                return MEMORY_E;
22745
    }
22746
    else {
22747
        if (cert->ca) {
22748
            /* TSIP isn't usable */
22749
            if (Renesas_cmn_checkCA(cert->ca->cm_idx) == 0)
22750
                WOLFSSL_MSG("SCE-TSIP isn't usable because the ca isn't verified "
22751
                            "by TSIP.");
22752
            else if (cert->sigCtx.CertAtt.pubkey_n_len != 256)
22753
                WOLFSSL_MSG("SCE-TSIP isn't usable because the ca isn't signed by "
22754
                            "RSA 2048.");
22755
            else
22756
                WOLFSSL_MSG("SCE-TSIP isn't usable");
22757
        }
22758
        cert->sce_tsip_encRsaKeyIdx = NULL;
22759
    }
22760
22761
    sce_tsip_encRsaKeyIdx = cert->sce_tsip_encRsaKeyIdx;
22762
22763
#else
22764
0
    sce_tsip_encRsaKeyIdx = NULL;
22765
0
#endif
22766
22767
0
    if (verify != NO_VERIFY && type != CA_TYPE && type != TRUSTED_PEER_TYPE) {
22768
0
        if (cert->ca) {
22769
0
            if (verify == VERIFY || verify == VERIFY_OCSP ||
22770
0
                                                 verify == VERIFY_SKIP_DATE) {
22771
                /* try to confirm/verify signature */
22772
0
                if ((ret = ConfirmSignature(&cert->sigCtx,
22773
0
                        cert->source + cert->certBegin,
22774
0
                        cert->sigIndex - cert->certBegin,
22775
0
                        cert->ca->publicKey, cert->ca->pubKeySize,
22776
0
                        cert->ca->keyOID, cert->signature,
22777
0
                        cert->sigLength, cert->signatureOID,
22778
0
                    #ifdef WC_RSA_PSS
22779
0
                        cert->source + cert->sigParamsIndex,
22780
0
                        cert->sigParamsLength,
22781
                    #else
22782
                        NULL, 0,
22783
                    #endif
22784
0
                        sce_tsip_encRsaKeyIdx)) != 0) {
22785
0
                    if (ret != WC_PENDING_E) {
22786
0
                        WOLFSSL_MSG("Confirm signature failed");
22787
0
                    }
22788
0
                    WOLFSSL_ERROR_VERBOSE(ret);
22789
0
                    return ret;
22790
0
                }
22791
0
            }
22792
0
        #ifndef IGNORE_NAME_CONSTRAINTS
22793
0
            if (verify == VERIFY || verify == VERIFY_OCSP ||
22794
0
                        verify == VERIFY_NAME || verify == VERIFY_SKIP_DATE) {
22795
                /* check that this cert's name is permitted by the signer's
22796
                 * name constraints */
22797
0
                if (!ConfirmNameConstraints(cert->ca, cert)) {
22798
0
                    WOLFSSL_MSG("Confirm name constraint failed");
22799
0
                    WOLFSSL_ERROR_VERBOSE(ASN_NAME_INVALID_E);
22800
0
                    return ASN_NAME_INVALID_E;
22801
0
                }
22802
0
            }
22803
0
        #endif /* IGNORE_NAME_CONSTRAINTS */
22804
0
        }
22805
#ifdef WOLFSSL_CERT_REQ
22806
        else if (type == CERTREQ_TYPE) {
22807
            if ((ret = ConfirmSignature(&cert->sigCtx,
22808
                    cert->source + cert->certBegin,
22809
                    cert->sigIndex - cert->certBegin,
22810
                    cert->publicKey, cert->pubKeySize,
22811
                    cert->keyOID, cert->signature,
22812
                    cert->sigLength, cert->signatureOID,
22813
                #ifdef WC_RSA_PSS
22814
                    cert->source + cert->sigParamsIndex, cert->sigParamsLength,
22815
                #else
22816
                    NULL, 0,
22817
                #endif
22818
                    sce_tsip_encRsaKeyIdx)) != 0) {
22819
                if (ret != WC_PENDING_E) {
22820
                    WOLFSSL_MSG("Confirm signature failed");
22821
                }
22822
                WOLFSSL_ERROR_VERBOSE(ret);
22823
                return ret;
22824
            }
22825
        }
22826
#endif
22827
0
        else {
22828
            /* no signer */
22829
0
            WOLFSSL_MSG("No CA signer to verify with");
22830
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
22831
            /* ret needs to be self-signer error for Qt compat */
22832
            if (cert->selfSigned) {
22833
                WOLFSSL_ERROR_VERBOSE(ASN_SELF_SIGNED_E);
22834
                return ASN_SELF_SIGNED_E;
22835
            }
22836
            else
22837
#endif
22838
0
            {
22839
0
                WOLFSSL_ERROR_VERBOSE(ASN_NO_SIGNER_E);
22840
0
                return ASN_NO_SIGNER_E;
22841
0
            }
22842
0
        }
22843
0
    }
22844
22845
#if defined(WOLFSSL_NO_TRUSTED_CERTS_VERIFY) && !defined(NO_SKID)
22846
exit_pcr:
22847
#endif
22848
22849
0
    if (cert->badDate != 0) {
22850
0
        if (verify != VERIFY_SKIP_DATE) {
22851
0
            return cert->badDate;
22852
0
        }
22853
0
        WOLFSSL_MSG("Date error: Verify option is skipping");
22854
0
    }
22855
22856
0
    if (cert->criticalExt != 0)
22857
0
        return cert->criticalExt;
22858
22859
0
    return ret;
22860
0
}
22861
22862
/* Create and init an new signer */
22863
Signer* MakeSigner(void* heap)
22864
0
{
22865
0
    Signer* signer = (Signer*) XMALLOC(sizeof(Signer), heap,
22866
0
                                       DYNAMIC_TYPE_SIGNER);
22867
0
    if (signer) {
22868
0
        XMEMSET(signer, 0, sizeof(Signer));
22869
0
    }
22870
0
    (void)heap;
22871
22872
0
    return signer;
22873
0
}
22874
22875
22876
/* Free an individual signer.
22877
 *
22878
 * Used by Certificate Manager.
22879
 *
22880
 * @param [in, out] signer  On in, signer object.
22881
 *                          On out, pointer is no longer valid.
22882
 * @param [in]      heap    Dynamic memory hint.
22883
 */
22884
void FreeSigner(Signer* signer, void* heap)
22885
0
{
22886
0
    (void)signer;
22887
0
    (void)heap;
22888
0
    XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
22889
0
    XFREE((void*)signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
22890
0
#ifndef IGNORE_NAME_CONSTRAINTS
22891
0
    if (signer->permittedNames)
22892
0
        FreeNameSubtrees(signer->permittedNames, heap);
22893
0
    if (signer->excludedNames)
22894
0
        FreeNameSubtrees(signer->excludedNames, heap);
22895
0
#endif
22896
#ifdef WOLFSSL_SIGNER_DER_CERT
22897
    FreeDer(&signer->derCert);
22898
#endif
22899
0
    XFREE(signer, heap, DYNAMIC_TYPE_SIGNER);
22900
0
}
22901
22902
22903
/* Free the whole singer table with number of rows.
22904
 *
22905
 * Each table entry is a linked list of signers.
22906
 * Used by Certificate Manager.
22907
 *
22908
 * @param [in, out] table   Array of signer objects.
22909
 * @param [in]      rows    Number of entries in table.
22910
 * @param [in]      heap    Dynamic memory hint.
22911
 */
22912
void FreeSignerTable(Signer** table, int rows, void* heap)
22913
0
{
22914
0
    int i;
22915
22916
0
    for (i = 0; i < rows; i++) {
22917
0
        Signer* signer = table[i];
22918
0
        while (signer) {
22919
0
            Signer* next = signer->next;
22920
0
            FreeSigner(signer, heap);
22921
0
            signer = next;
22922
0
        }
22923
0
        table[i] = NULL;
22924
0
    }
22925
0
}
22926
22927
#ifdef WOLFSSL_TRUST_PEER_CERT
22928
/* Free an individual trusted peer cert.
22929
 *
22930
 * @param [in, out] tp    Trusted peer certificate object.
22931
 * @param [in]      heap  Dynamic memory hint.
22932
 */
22933
void FreeTrustedPeer(TrustedPeerCert* tp, void* heap)
22934
{
22935
    if (tp == NULL) {
22936
        return;
22937
    }
22938
22939
    if (tp->name) {
22940
        XFREE(tp->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
22941
    }
22942
22943
    if (tp->sig) {
22944
        XFREE(tp->sig, heap, DYNAMIC_TYPE_SIGNATURE);
22945
    }
22946
#ifndef IGNORE_NAME_CONSTRAINTS
22947
    if (tp->permittedNames)
22948
        FreeNameSubtrees(tp->permittedNames, heap);
22949
    if (tp->excludedNames)
22950
        FreeNameSubtrees(tp->excludedNames, heap);
22951
#endif
22952
    XFREE(tp, heap, DYNAMIC_TYPE_CERT);
22953
22954
    (void)heap;
22955
}
22956
22957
/* Free the whole Trusted Peer linked list.
22958
 *
22959
 * Each table entry is a linked list of trusted peer certificates.
22960
 * Used by Certificate Manager.
22961
 *
22962
 * @param [in, out] table   Array of trusted peer certificate objects.
22963
 * @param [in]      rows    Number of entries in table.
22964
 * @param [in]      heap    Dynamic memory hint.
22965
 */
22966
void FreeTrustedPeerTable(TrustedPeerCert** table, int rows, void* heap)
22967
{
22968
    int i;
22969
22970
    for (i = 0; i < rows; i++) {
22971
        TrustedPeerCert* tp = table[i];
22972
        while (tp) {
22973
            TrustedPeerCert* next = tp->next;
22974
            FreeTrustedPeer(tp, heap);
22975
            tp = next;
22976
        }
22977
        table[i] = NULL;
22978
    }
22979
}
22980
#endif /* WOLFSSL_TRUST_PEER_CERT */
22981
22982
#if !defined(WOLFSSL_ASN_TEMPLATE) || defined(HAVE_PKCS7)
22983
int SetSerialNumber(const byte* sn, word32 snSz, byte* output,
22984
    word32 outputSz, int maxSnSz)
22985
{
22986
    int i;
22987
    int snSzInt = (int)snSz;
22988
22989
    if (sn == NULL || output == NULL || snSzInt < 0)
22990
        return BAD_FUNC_ARG;
22991
22992
    /* remove leading zeros */
22993
    while (snSzInt > 0 && sn[0] == 0) {
22994
        snSzInt--;
22995
        sn++;
22996
    }
22997
    /* RFC 5280 - 4.1.2.2:
22998
     *   Serial numbers must be a positive value (and not zero) */
22999
    if (snSzInt == 0) {
23000
        WOLFSSL_ERROR_VERBOSE(BAD_FUNC_ARG);
23001
        return BAD_FUNC_ARG;
23002
    }
23003
23004
    if (sn[0] & 0x80)
23005
        maxSnSz--;
23006
    /* truncate if input is too long */
23007
    if (snSzInt > maxSnSz)
23008
        snSzInt = maxSnSz;
23009
23010
    i = SetASNInt(snSzInt, sn[0], NULL);
23011
    /* truncate if input is too long */
23012
    if (snSzInt > (int)outputSz - i)
23013
        snSzInt = (int)outputSz - i;
23014
    /* sanity check number of bytes to copy */
23015
    if (snSzInt <= 0) {
23016
        return BUFFER_E;
23017
    }
23018
23019
    /* write out ASN.1 Integer */
23020
    (void)SetASNInt(snSzInt, sn[0], output);
23021
    XMEMCPY(output + i, sn, (size_t)snSzInt);
23022
23023
    /* compute final length */
23024
    i += snSzInt;
23025
23026
    return i;
23027
}
23028
#endif /* !WOLFSSL_ASN_TEMPLATE */
23029
23030
#endif /* !NO_CERTS */
23031
23032
#if defined(WOLFSSL_ASN_TEMPLATE) || defined(HAVE_PKCS12) || \
23033
    (defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT))
23034
int SetMyVersion(word32 version, byte* output, int header)
23035
0
{
23036
0
    int i = 0;
23037
23038
0
    if (output == NULL)
23039
0
        return BAD_FUNC_ARG;
23040
23041
0
    if (header) {
23042
0
        output[i++] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED;
23043
0
        output[i++] = 3;
23044
0
    }
23045
0
    output[i++] = ASN_INTEGER;
23046
0
    output[i++] = 0x01;
23047
0
    output[i++] = (byte)version;
23048
23049
0
    return i;
23050
0
}
23051
#endif
23052
23053
#ifndef WOLFSSL_ASN_TEMPLATE
23054
int wc_GetSerialNumber(const byte* input, word32* inOutIdx,
23055
    byte* serial, int* serialSz, word32 maxIdx)
23056
{
23057
    int result = 0;
23058
    int ret;
23059
23060
    WOLFSSL_ENTER("wc_GetSerialNumber");
23061
23062
    if (serial == NULL || input == NULL || serialSz == NULL) {
23063
        return BAD_FUNC_ARG;
23064
    }
23065
23066
    /* First byte is ASN type */
23067
    if ((*inOutIdx+1) > maxIdx) {
23068
        WOLFSSL_MSG("Bad idx first");
23069
        return BUFFER_E;
23070
    }
23071
23072
    ret = GetASNInt(input, inOutIdx, serialSz, maxIdx);
23073
    if (ret != 0)
23074
        return ret;
23075
23076
    if (*serialSz > EXTERNAL_SERIAL_SIZE || *serialSz <= 0) {
23077
        WOLFSSL_MSG("Serial size bad");
23078
        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
23079
        return ASN_PARSE_E;
23080
    }
23081
23082
    /* return serial */
23083
    XMEMCPY(serial, &input[*inOutIdx], (size_t)*serialSz);
23084
    *inOutIdx += (word32)*serialSz;
23085
23086
    return result;
23087
}
23088
#endif
23089
23090
#ifndef NO_CERTS
23091
23092
/* TODO: consider moving PEM code out to a different file. */
23093
23094
int AllocDer(DerBuffer** pDer, word32 length, int type, void* heap)
23095
0
{
23096
0
    int ret = BAD_FUNC_ARG;
23097
0
    if (pDer) {
23098
0
        int dynType = 0;
23099
0
        DerBuffer* der;
23100
23101
        /* Determine dynamic type */
23102
0
        switch (type) {
23103
0
            case CA_TYPE:   dynType = DYNAMIC_TYPE_CA;   break;
23104
0
            case CHAIN_CERT_TYPE:
23105
0
            case CERT_TYPE: dynType = DYNAMIC_TYPE_CERT; break;
23106
0
            case CRL_TYPE:  dynType = DYNAMIC_TYPE_CRL;  break;
23107
0
            case DSA_TYPE:  dynType = DYNAMIC_TYPE_DSA;  break;
23108
0
            case ECC_TYPE:  dynType = DYNAMIC_TYPE_ECC;  break;
23109
0
            case RSA_TYPE:  dynType = DYNAMIC_TYPE_RSA;  break;
23110
0
            default:        dynType = DYNAMIC_TYPE_KEY;  break;
23111
0
        }
23112
23113
        /* Setup new buffer */
23114
0
        *pDer = (DerBuffer*)XMALLOC(sizeof(DerBuffer) + length, heap, dynType);
23115
0
        if (*pDer == NULL) {
23116
0
            return MEMORY_E;
23117
0
        }
23118
0
        XMEMSET(*pDer, 0, sizeof(DerBuffer) + length);
23119
23120
0
        der = *pDer;
23121
0
        der->type = type;
23122
0
        der->dynType = dynType; /* Cache this for FreeDer */
23123
0
        der->heap = heap;
23124
0
        der->buffer = (byte*)der + sizeof(DerBuffer);
23125
0
        der->length = length;
23126
0
        ret = 0; /* Success */
23127
0
    }
23128
0
    return ret;
23129
0
}
23130
23131
void FreeDer(DerBuffer** pDer)
23132
0
{
23133
0
    if (pDer && *pDer)
23134
0
    {
23135
0
        DerBuffer* der = (DerBuffer*)*pDer;
23136
23137
        /* ForceZero private keys */
23138
0
        if (der->type == PRIVATEKEY_TYPE && der->buffer != NULL) {
23139
0
            ForceZero(der->buffer, der->length);
23140
0
        }
23141
0
        der->buffer = NULL;
23142
0
        der->length = 0;
23143
0
        XFREE(der, der->heap, der->dynType);
23144
23145
0
        *pDer = NULL;
23146
0
    }
23147
0
}
23148
23149
int wc_AllocDer(DerBuffer** pDer, word32 length, int type, void* heap)
23150
0
{
23151
0
    return AllocDer(pDer, length, type, heap);
23152
0
}
23153
void wc_FreeDer(DerBuffer** pDer)
23154
0
{
23155
0
    FreeDer(pDer);
23156
0
}
23157
23158
23159
#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
23160
23161
/* Note: If items added make sure MAX_X509_HEADER_SZ is
23162
    updated to reflect maximum length and pem_struct_min_sz
23163
    to reflect minimum size */
23164
wcchar BEGIN_CERT           = "-----BEGIN CERTIFICATE-----";
23165
wcchar END_CERT             = "-----END CERTIFICATE-----";
23166
#ifdef WOLFSSL_CERT_REQ
23167
    wcchar BEGIN_CERT_REQ   = "-----BEGIN CERTIFICATE REQUEST-----";
23168
    wcchar END_CERT_REQ     = "-----END CERTIFICATE REQUEST-----";
23169
#endif
23170
#ifndef NO_DH
23171
    wcchar BEGIN_DH_PARAM   = "-----BEGIN DH PARAMETERS-----";
23172
    wcchar END_DH_PARAM     = "-----END DH PARAMETERS-----";
23173
    wcchar BEGIN_X942_PARAM = "-----BEGIN X9.42 DH PARAMETERS-----";
23174
    wcchar END_X942_PARAM   = "-----END X9.42 DH PARAMETERS-----";
23175
#endif
23176
#ifndef NO_DSA
23177
    wcchar BEGIN_DSA_PARAM  = "-----BEGIN DSA PARAMETERS-----";
23178
    wcchar END_DSA_PARAM    = "-----END DSA PARAMETERS-----";
23179
#endif
23180
wcchar BEGIN_X509_CRL       = "-----BEGIN X509 CRL-----";
23181
wcchar END_X509_CRL         = "-----END X509 CRL-----";
23182
wcchar BEGIN_RSA_PRIV       = "-----BEGIN RSA PRIVATE KEY-----";
23183
wcchar END_RSA_PRIV         = "-----END RSA PRIVATE KEY-----";
23184
wcchar BEGIN_RSA_PUB        = "-----BEGIN RSA PUBLIC KEY-----";
23185
wcchar END_RSA_PUB          = "-----END RSA PUBLIC KEY-----";
23186
wcchar BEGIN_PRIV_KEY       = "-----BEGIN PRIVATE KEY-----";
23187
wcchar END_PRIV_KEY         = "-----END PRIVATE KEY-----";
23188
wcchar BEGIN_ENC_PRIV_KEY   = "-----BEGIN ENCRYPTED PRIVATE KEY-----";
23189
wcchar END_ENC_PRIV_KEY     = "-----END ENCRYPTED PRIVATE KEY-----";
23190
#ifdef HAVE_ECC
23191
    wcchar BEGIN_EC_PRIV    = "-----BEGIN EC PRIVATE KEY-----";
23192
    wcchar END_EC_PRIV      = "-----END EC PRIVATE KEY-----";
23193
#ifdef OPENSSL_EXTRA
23194
    wcchar BEGIN_EC_PARAM   = "-----BEGIN EC PARAMETERS-----";
23195
    wcchar END_EC_PARAM     = "-----END EC PARAMETERS-----";
23196
#endif
23197
#endif
23198
#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \
23199
                                                                !defined(NO_DSA)
23200
    wcchar BEGIN_DSA_PRIV   = "-----BEGIN DSA PRIVATE KEY-----";
23201
    wcchar END_DSA_PRIV     = "-----END DSA PRIVATE KEY-----";
23202
#endif
23203
#ifdef OPENSSL_EXTRA
23204
    const char BEGIN_PRIV_KEY_PREFIX[] = "-----BEGIN";
23205
    const char PRIV_KEY_SUFFIX[] = "PRIVATE KEY-----";
23206
    const char END_PRIV_KEY_PREFIX[]   = "-----END";
23207
#endif
23208
wcchar BEGIN_PUB_KEY        = "-----BEGIN PUBLIC KEY-----";
23209
wcchar END_PUB_KEY          = "-----END PUBLIC KEY-----";
23210
#if defined(HAVE_ED25519) || defined(HAVE_ED448)
23211
    wcchar BEGIN_EDDSA_PRIV = "-----BEGIN EDDSA PRIVATE KEY-----";
23212
    wcchar END_EDDSA_PRIV   = "-----END EDDSA PRIVATE KEY-----";
23213
#endif
23214
#if defined(HAVE_PQC)
23215
#if defined(HAVE_FALCON)
23216
    wcchar BEGIN_FALCON_LEVEL1_PRIV  = "-----BEGIN FALCON_LEVEL1 PRIVATE KEY-----";
23217
    wcchar END_FALCON_LEVEL1_PRIV    = "-----END FALCON_LEVEL1 PRIVATE KEY-----";
23218
    wcchar BEGIN_FALCON_LEVEL5_PRIV = "-----BEGIN FALCON_LEVEL5 PRIVATE KEY-----";
23219
    wcchar END_FALCON_LEVEL5_PRIV   = "-----END FALCON_LEVEL5 PRIVATE KEY-----";
23220
#endif /* HAVE_FALCON */
23221
#if defined(HAVE_DILITHIUM)
23222
    wcchar BEGIN_DILITHIUM_LEVEL2_PRIV = "-----BEGIN DILITHIUM_LEVEL2 PRIVATE KEY-----";
23223
    wcchar END_DILITHIUM_LEVEL2_PRIV   = "-----END DILITHIUM_LEVEL2 PRIVATE KEY-----";
23224
    wcchar BEGIN_DILITHIUM_LEVEL3_PRIV = "-----BEGIN DILITHIUM_LEVEL3 PRIVATE KEY-----";
23225
    wcchar END_DILITHIUM_LEVEL3_PRIV   = "-----END DILITHIUM_LEVEL3 PRIVATE KEY-----";
23226
    wcchar BEGIN_DILITHIUM_LEVEL5_PRIV = "-----BEGIN DILITHIUM_LEVEL5 PRIVATE KEY-----";
23227
    wcchar END_DILITHIUM_LEVEL5_PRIV   = "-----END DILITHIUM_LEVEL5 PRIVATE KEY-----";
23228
#endif /* HAVE_DILITHIUM */
23229
#if defined(HAVE_SPHINCS)
23230
    wcchar BEGIN_SPHINCS_FAST_LEVEL1_PRIV = "-----BEGIN SPHINCS_FAST_LEVEL1 PRIVATE KEY-----";
23231
    wcchar END_SPHINCS_FAST_LEVEL1_PRIV   = "-----END SPHINCS_FAST_LEVEL1 PRIVATE KEY-----";
23232
    wcchar BEGIN_SPHINCS_FAST_LEVEL3_PRIV = "-----BEGIN SPHINCS_FAST_LEVEL3 PRIVATE KEY-----";
23233
    wcchar END_SPHINCS_FAST_LEVEL3_PRIV   = "-----END SPHINCS_FAST_LEVEL3 PRIVATE KEY-----";
23234
    wcchar BEGIN_SPHINCS_FAST_LEVEL5_PRIV = "-----BEGIN SPHINCS_FAST_LEVEL5 PRIVATE KEY-----";
23235
    wcchar END_SPHINCS_FAST_LEVEL5_PRIV   = "-----END SPHINCS_FAST_LEVEL5 PRIVATE KEY-----";
23236
23237
    wcchar BEGIN_SPHINCS_SMALL_LEVEL1_PRIV = "-----BEGIN SPHINCS_SMALL_LEVEL1 PRIVATE KEY-----";
23238
    wcchar END_SPHINCS_SMALL_LEVEL1_PRIV   = "-----END SPHINCS_SMALL_LEVEL1 PRIVATE KEY-----";
23239
    wcchar BEGIN_SPHINCS_SMALL_LEVEL3_PRIV = "-----BEGIN SPHINCS_SMALL_LEVEL3 PRIVATE KEY-----";
23240
    wcchar END_SPHINCS_SMALL_LEVEL3_PRIV   = "-----END SPHINCS_SMALL_LEVEL3 PRIVATE KEY-----";
23241
    wcchar BEGIN_SPHINCS_SMALL_LEVEL5_PRIV = "-----BEGIN SPHINCS_SMALL_LEVEL5 PRIVATE KEY-----";
23242
    wcchar END_SPHINCS_SMALL_LEVEL5_PRIV   = "-----END SPHINCS_SMALL_LEVEL5 PRIVATE KEY-----";
23243
#endif /* HAVE_SPHINCS */
23244
#endif /* HAVE_PQC */
23245
23246
const int pem_struct_min_sz = XSTR_SIZEOF("-----BEGIN X509 CRL-----"
23247
                                             "-----END X509 CRL-----");
23248
23249
#ifdef WOLFSSL_PEM_TO_DER
23250
static WC_INLINE const char* SkipEndOfLineChars(const char* line,
23251
                                                const char* endOfLine)
23252
0
{
23253
    /* eat end of line characters */
23254
0
    while (line < endOfLine &&
23255
0
              (line[0] == '\r' || line[0] == '\n')) {
23256
0
        line++;
23257
0
    }
23258
0
    return line;
23259
0
}
23260
#endif
23261
23262
int wc_PemGetHeaderFooter(int type, const char** header, const char** footer)
23263
0
{
23264
0
    int ret = BAD_FUNC_ARG;
23265
23266
0
    switch (type) {
23267
0
        case CA_TYPE:       /* same as below */
23268
0
        case TRUSTED_PEER_TYPE:
23269
0
        case CHAIN_CERT_TYPE:
23270
0
        case CERT_TYPE:
23271
0
            if (header) *header = BEGIN_CERT;
23272
0
            if (footer) *footer = END_CERT;
23273
0
            ret = 0;
23274
0
            break;
23275
23276
0
        case CRL_TYPE:
23277
0
            if (header) *header = BEGIN_X509_CRL;
23278
0
            if (footer) *footer = END_X509_CRL;
23279
0
            ret = 0;
23280
0
            break;
23281
0
    #ifndef NO_DH
23282
0
        case DH_PARAM_TYPE:
23283
0
            if (header) *header = BEGIN_DH_PARAM;
23284
0
            if (footer) *footer = END_DH_PARAM;
23285
0
            ret = 0;
23286
0
            break;
23287
0
        case X942_PARAM_TYPE:
23288
0
            if (header) *header = BEGIN_X942_PARAM;
23289
0
            if (footer) *footer = END_X942_PARAM;
23290
0
            ret = 0;
23291
0
            break;
23292
0
    #endif
23293
    #ifndef NO_DSA
23294
        case DSA_PARAM_TYPE:
23295
            if (header) *header = BEGIN_DSA_PARAM;
23296
            if (footer) *footer = END_DSA_PARAM;
23297
            ret = 0;
23298
            break;
23299
    #endif
23300
    #ifdef WOLFSSL_CERT_REQ
23301
        case CERTREQ_TYPE:
23302
            if (header) *header = BEGIN_CERT_REQ;
23303
            if (footer) *footer = END_CERT_REQ;
23304
            ret = 0;
23305
            break;
23306
    #endif
23307
    #ifndef NO_DSA
23308
        case DSA_TYPE:
23309
        case DSA_PRIVATEKEY_TYPE:
23310
            if (header) *header = BEGIN_DSA_PRIV;
23311
            if (footer) *footer = END_DSA_PRIV;
23312
            ret = 0;
23313
            break;
23314
    #endif
23315
0
    #ifdef HAVE_ECC
23316
0
        case ECC_TYPE:
23317
0
        case ECC_PRIVATEKEY_TYPE:
23318
0
            if (header) *header = BEGIN_EC_PRIV;
23319
0
            if (footer) *footer = END_EC_PRIV;
23320
0
            ret = 0;
23321
0
            break;
23322
    #ifdef OPENSSL_EXTRA
23323
        case ECC_PARAM_TYPE:
23324
            if (header) *header = BEGIN_EC_PARAM;
23325
            if (footer) *footer = END_EC_PARAM;
23326
            ret = 0;
23327
            break;
23328
    #endif
23329
0
    #endif
23330
0
        case RSA_TYPE:
23331
0
        case PRIVATEKEY_TYPE:
23332
0
            if (header) *header = BEGIN_RSA_PRIV;
23333
0
            if (footer) *footer = END_RSA_PRIV;
23334
0
            ret = 0;
23335
0
            break;
23336
0
    #ifdef HAVE_ED25519
23337
0
        case ED25519_TYPE:
23338
0
    #endif
23339
0
    #ifdef HAVE_ED448
23340
0
        case ED448_TYPE:
23341
0
    #endif
23342
0
    #if defined(HAVE_ED25519) || defined(HAVE_ED448)
23343
0
        case EDDSA_PRIVATEKEY_TYPE:
23344
0
            if (header) *header = BEGIN_EDDSA_PRIV;
23345
0
            if (footer) *footer = END_EDDSA_PRIV;
23346
0
            ret = 0;
23347
0
            break;
23348
0
    #endif
23349
#ifdef HAVE_PQC
23350
#ifdef HAVE_FALCON
23351
        case FALCON_LEVEL1_TYPE:
23352
            if (header) *header = BEGIN_FALCON_LEVEL1_PRIV;
23353
            if (footer) *footer = END_FALCON_LEVEL1_PRIV;
23354
            ret = 0;
23355
            break;
23356
        case FALCON_LEVEL5_TYPE:
23357
            if (header) *header = BEGIN_FALCON_LEVEL5_PRIV;
23358
            if (footer) *footer = END_FALCON_LEVEL5_PRIV;
23359
            ret = 0;
23360
            break;
23361
#endif /* HAVE_FALCON */
23362
#ifdef HAVE_DILITHIUM
23363
        case DILITHIUM_LEVEL2_TYPE:
23364
            if (header) *header = BEGIN_DILITHIUM_LEVEL2_PRIV;
23365
            if (footer) *footer = END_DILITHIUM_LEVEL2_PRIV;
23366
            ret = 0;
23367
            break;
23368
        case DILITHIUM_LEVEL3_TYPE:
23369
            if (header) *header = BEGIN_DILITHIUM_LEVEL3_PRIV;
23370
            if (footer) *footer = END_DILITHIUM_LEVEL3_PRIV;
23371
            ret = 0;
23372
            break;
23373
        case DILITHIUM_LEVEL5_TYPE:
23374
            if (header) *header = BEGIN_DILITHIUM_LEVEL5_PRIV;
23375
            if (footer) *footer = END_DILITHIUM_LEVEL5_PRIV;
23376
            ret = 0;
23377
            break;
23378
#endif /* HAVE_DILITHIUM */
23379
#ifdef HAVE_SPHINCS
23380
        case SPHINCS_FAST_LEVEL1_TYPE:
23381
            if (header) *header = BEGIN_SPHINCS_FAST_LEVEL1_PRIV;
23382
            if (footer) *footer = END_SPHINCS_FAST_LEVEL1_PRIV;
23383
            ret = 0;
23384
            break;
23385
        case SPHINCS_FAST_LEVEL3_TYPE:
23386
            if (header) *header = BEGIN_SPHINCS_FAST_LEVEL3_PRIV;
23387
            if (footer) *footer = END_SPHINCS_FAST_LEVEL3_PRIV;
23388
            ret = 0;
23389
            break;
23390
        case SPHINCS_FAST_LEVEL5_TYPE:
23391
            if (header) *header = BEGIN_SPHINCS_FAST_LEVEL5_PRIV;
23392
            if (footer) *footer = END_SPHINCS_FAST_LEVEL5_PRIV;
23393
            ret = 0;
23394
            break;
23395
        case SPHINCS_SMALL_LEVEL1_TYPE:
23396
            if (header) *header = BEGIN_SPHINCS_SMALL_LEVEL1_PRIV;
23397
            if (footer) *footer = END_SPHINCS_SMALL_LEVEL1_PRIV;
23398
            ret = 0;
23399
            break;
23400
        case SPHINCS_SMALL_LEVEL3_TYPE:
23401
            if (header) *header = BEGIN_SPHINCS_SMALL_LEVEL3_PRIV;
23402
            if (footer) *footer = END_SPHINCS_SMALL_LEVEL3_PRIV;
23403
            ret = 0;
23404
            break;
23405
        case SPHINCS_SMALL_LEVEL5_TYPE:
23406
            if (header) *header = BEGIN_SPHINCS_SMALL_LEVEL5_PRIV;
23407
            if (footer) *footer = END_SPHINCS_SMALL_LEVEL5_PRIV;
23408
            ret = 0;
23409
            break;
23410
#endif /* HAVE_SPHINCS */
23411
#endif /* HAVE_PQC */
23412
0
        case PUBLICKEY_TYPE:
23413
0
        case ECC_PUBLICKEY_TYPE:
23414
0
            if (header) *header = BEGIN_PUB_KEY;
23415
0
            if (footer) *footer = END_PUB_KEY;
23416
0
            ret = 0;
23417
0
            break;
23418
0
        case RSA_PUBLICKEY_TYPE:
23419
0
            if (header) *header = BEGIN_RSA_PUB;
23420
0
            if (footer) *footer = END_RSA_PUB;
23421
0
            ret = 0;
23422
0
            break;
23423
0
    #ifndef NO_DH
23424
0
        case DH_PRIVATEKEY_TYPE:
23425
0
    #endif
23426
0
        case PKCS8_PRIVATEKEY_TYPE:
23427
0
            if (header) *header = BEGIN_PRIV_KEY;
23428
0
            if (footer) *footer = END_PRIV_KEY;
23429
0
            ret = 0;
23430
0
            break;
23431
0
        case PKCS8_ENC_PRIVATEKEY_TYPE:
23432
0
            if (header) *header = BEGIN_ENC_PRIV_KEY;
23433
0
            if (footer) *footer = END_ENC_PRIV_KEY;
23434
0
            ret = 0;
23435
0
            break;
23436
0
        default:
23437
0
            break;
23438
0
    }
23439
0
    return ret;
23440
0
}
23441
23442
#ifdef WOLFSSL_ENCRYPTED_KEYS
23443
23444
static wcchar kProcTypeHeader = "Proc-Type";
23445
static wcchar kDecInfoHeader = "DEK-Info";
23446
23447
#ifdef WOLFSSL_PEM_TO_DER
23448
#ifndef NO_DES3
23449
    static wcchar kEncTypeDes = "DES-CBC";
23450
    static wcchar kEncTypeDes3 = "DES-EDE3-CBC";
23451
#endif
23452
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)
23453
    static wcchar kEncTypeAesCbc128 = "AES-128-CBC";
23454
#endif
23455
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_192)
23456
    static wcchar kEncTypeAesCbc192 = "AES-192-CBC";
23457
#endif
23458
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
23459
    static wcchar kEncTypeAesCbc256 = "AES-256-CBC";
23460
#endif
23461
23462
int wc_EncryptedInfoGet(EncryptedInfo* info, const char* cipherInfo)
23463
{
23464
    int ret = 0;
23465
23466
    if (info == NULL || cipherInfo == NULL)
23467
        return BAD_FUNC_ARG;
23468
23469
    /* determine cipher information */
23470
#ifndef NO_DES3
23471
    if (XSTRCMP(cipherInfo, kEncTypeDes) == 0) {
23472
        info->cipherType = WC_CIPHER_DES;
23473
        info->keySz = DES_KEY_SIZE;
23474
/* DES_IV_SIZE is incorrectly 16 in FIPS v2. It should be 8, same as the
23475
 * block size. */
23476
#if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION == 2)
23477
        if (info->ivSz == 0) info->ivSz  = DES_BLOCK_SIZE;
23478
#else
23479
        if (info->ivSz == 0) info->ivSz  = DES_IV_SIZE;
23480
#endif
23481
    }
23482
    else if (XSTRCMP(cipherInfo, kEncTypeDes3) == 0) {
23483
        info->cipherType = WC_CIPHER_DES3;
23484
        info->keySz = DES3_KEY_SIZE;
23485
#if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION == 2)
23486
        if (info->ivSz == 0) info->ivSz  = DES_BLOCK_SIZE;
23487
#else
23488
        if (info->ivSz == 0) info->ivSz  = DES_IV_SIZE;
23489
#endif
23490
    }
23491
    else
23492
#endif /* !NO_DES3 */
23493
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)
23494
    if (XSTRCMP(cipherInfo, kEncTypeAesCbc128) == 0) {
23495
        info->cipherType = WC_CIPHER_AES_CBC;
23496
        info->keySz = AES_128_KEY_SIZE;
23497
        if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;
23498
    }
23499
    else
23500
#endif
23501
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_192)
23502
    if (XSTRCMP(cipherInfo, kEncTypeAesCbc192) == 0) {
23503
        info->cipherType = WC_CIPHER_AES_CBC;
23504
        info->keySz = AES_192_KEY_SIZE;
23505
        if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;
23506
    }
23507
    else
23508
#endif
23509
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
23510
    if (XSTRCMP(cipherInfo, kEncTypeAesCbc256) == 0) {
23511
        info->cipherType = WC_CIPHER_AES_CBC;
23512
        info->keySz = AES_256_KEY_SIZE;
23513
        if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;
23514
    }
23515
    else
23516
#endif
23517
    {
23518
        ret = NOT_COMPILED_IN;
23519
    }
23520
    return ret;
23521
}
23522
23523
int wc_EncryptedInfoParse(EncryptedInfo* info, const char** pBuffer,
23524
                          size_t bufSz)
23525
{
23526
    int         err = 0;
23527
    const char* bufferStart;
23528
    const char* bufferEnd;
23529
    char*       line;
23530
23531
    if (info == NULL || pBuffer == NULL || bufSz == 0)
23532
        return BAD_FUNC_ARG;
23533
23534
    bufferStart = *pBuffer;
23535
    bufferEnd = bufferStart + bufSz;
23536
23537
    /* find encrypted info marker */
23538
    line = XSTRNSTR(bufferStart, kProcTypeHeader,
23539
                    min((word32)bufSz, PEM_LINE_LEN));
23540
    if (line != NULL) {
23541
        word32      lineSz;
23542
        char*       finish;
23543
        char*       start;
23544
        word32      startSz;
23545
        const char* newline = NULL;
23546
23547
        if (line >= bufferEnd) {
23548
            return BUFFER_E;
23549
        }
23550
23551
        lineSz = (word32)(bufferEnd - line);
23552
23553
        /* find DEC-Info marker */
23554
        start = XSTRNSTR(line, kDecInfoHeader, min(lineSz, PEM_LINE_LEN));
23555
23556
        if (start == NULL)
23557
            return BUFFER_E;
23558
23559
        /* skip dec-info and ": " */
23560
        start += XSTRLEN(kDecInfoHeader);
23561
        if (start >= bufferEnd)
23562
            return BUFFER_E;
23563
23564
        if (start[0] == ':') {
23565
            start++;
23566
            if (start >= bufferEnd)
23567
                return BUFFER_E;
23568
        }
23569
        if (start[0] == ' ')
23570
            start++;
23571
23572
        startSz = (word32)(bufferEnd - start);
23573
        finish = XSTRNSTR(start, ",", min(startSz, PEM_LINE_LEN));
23574
23575
        if ((start != NULL) && (finish != NULL) && (start < finish)) {
23576
            word32 finishSz;
23577
23578
            if (finish >= bufferEnd) {
23579
                return BUFFER_E;
23580
            }
23581
23582
            finishSz = (word32)(bufferEnd - finish);
23583
            newline = XSTRNSTR(finish, "\r", min(finishSz, PEM_LINE_LEN));
23584
23585
            /* get cipher name */
23586
            if (NAME_SZ < (finish - start)) /* buffer size of info->name */
23587
                return BUFFER_E;
23588
            if (XMEMCPY(info->name, start, (size_t)(finish - start)) == NULL)
23589
                return BUFFER_E;
23590
            info->name[finish - start] = '\0'; /* null term */
23591
23592
            /* populate info */
23593
            err = wc_EncryptedInfoGet(info, info->name);
23594
            if (err != 0)
23595
                return err;
23596
23597
            /* get IV */
23598
            if (finishSz < info->ivSz + 1)
23599
                return BUFFER_E;
23600
23601
            if (newline == NULL) {
23602
                newline = XSTRNSTR(finish, "\n", min(finishSz,
23603
                                                     PEM_LINE_LEN));
23604
            }
23605
            if ((newline != NULL) && (newline > finish)) {
23606
                finish++;
23607
                info->ivSz = (word32)(newline - finish);
23608
                if (info->ivSz > IV_SZ)
23609
                    return BUFFER_E;
23610
                if (XMEMCPY(info->iv, finish, info->ivSz) == NULL)
23611
                    return BUFFER_E;
23612
                info->set = 1;
23613
            }
23614
            else
23615
                return BUFFER_E;
23616
        }
23617
        else
23618
            return BUFFER_E;
23619
23620
        /* eat end of line characters */
23621
        newline = SkipEndOfLineChars(newline, bufferEnd);
23622
23623
        /* return new headerEnd */
23624
23625
        *pBuffer = newline;
23626
    }
23627
23628
    return err;
23629
}
23630
#endif /* WOLFSSL_PEM_TO_DER */
23631
23632
#ifdef WOLFSSL_DER_TO_PEM
23633
static int wc_EncryptedInfoAppend(char* dest, int destSz, char* cipherInfo)
23634
{
23635
    if (cipherInfo != NULL) {
23636
        int cipherInfoStrLen = (int)XSTRLEN((char*)cipherInfo);
23637
23638
        if (cipherInfoStrLen > HEADER_ENCRYPTED_KEY_SIZE - (9+14+10+3))
23639
            cipherInfoStrLen = HEADER_ENCRYPTED_KEY_SIZE - (9+14+10+3);
23640
23641
        if (destSz - (int)XSTRLEN(dest) >= cipherInfoStrLen + (9+14+8+2+2+1)) {
23642
            /* strncat's src length needs to include the NULL */
23643
            XSTRNCAT(dest, kProcTypeHeader, 10);
23644
            XSTRNCAT(dest, ": 4,ENCRYPTED\n", 15);
23645
            XSTRNCAT(dest, kDecInfoHeader, 9);
23646
            XSTRNCAT(dest, ": ", 3);
23647
            XSTRNCAT(dest, cipherInfo, (size_t)destSz - XSTRLEN(dest) - 1);
23648
            XSTRNCAT(dest, "\n\n", 4);
23649
        }
23650
    }
23651
    return 0;
23652
}
23653
#endif /* WOLFSSL_DER_TO_PEM */
23654
#endif /* WOLFSSL_ENCRYPTED_KEYS */
23655
23656
#ifdef WOLFSSL_DER_TO_PEM
23657
23658
/* Used for compatibility API */
23659
WOLFSSL_ABI
23660
int wc_DerToPem(const byte* der, word32 derSz,
23661
                byte* output, word32 outSz, int type)
23662
0
{
23663
0
    return wc_DerToPemEx(der, derSz, output, outSz, NULL, type);
23664
0
}
23665
23666
/* convert der buffer to pem into output, can't do inplace, der and output
23667
   need to be different */
23668
int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz,
23669
             byte *cipher_info, int type)
23670
0
{
23671
0
    const char* headerStr = NULL;
23672
0
    const char* footerStr = NULL;
23673
0
#ifdef WOLFSSL_SMALL_STACK
23674
0
    char* header = NULL;
23675
0
    char* footer = NULL;
23676
#else
23677
    char header[MAX_X509_HEADER_SZ + HEADER_ENCRYPTED_KEY_SIZE];
23678
    char footer[MAX_X509_HEADER_SZ];
23679
#endif
23680
0
    int headerLen = MAX_X509_HEADER_SZ + HEADER_ENCRYPTED_KEY_SIZE;
23681
0
    int footerLen = MAX_X509_HEADER_SZ;
23682
0
    int i;
23683
0
    int err;
23684
0
    int outLen;   /* return length or error */
23685
23686
0
    (void)cipher_info;
23687
23688
0
    if (der == output)      /* no in place conversion */
23689
0
        return BAD_FUNC_ARG;
23690
23691
0
    err = wc_PemGetHeaderFooter(type, &headerStr, &footerStr);
23692
0
    if (err != 0)
23693
0
        return err;
23694
23695
0
#ifdef WOLFSSL_SMALL_STACK
23696
0
    header = (char*)XMALLOC(headerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
23697
0
    if (header == NULL)
23698
0
        return MEMORY_E;
23699
23700
0
    footer = (char*)XMALLOC(footerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
23701
0
    if (footer == NULL) {
23702
0
        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
23703
0
        return MEMORY_E;
23704
0
    }
23705
0
#endif
23706
23707
    /* build header and footer based on type */
23708
0
    XSTRNCPY(header, headerStr, (size_t)headerLen - 1);
23709
0
    header[headerLen - 2] = 0;
23710
0
    XSTRNCPY(footer, footerStr, (size_t)footerLen - 1);
23711
0
    footer[footerLen - 2] = 0;
23712
23713
    /* add new line to end */
23714
0
    XSTRNCAT(header, "\n", 2);
23715
0
    XSTRNCAT(footer, "\n", 2);
23716
23717
#ifdef WOLFSSL_ENCRYPTED_KEYS
23718
    err = wc_EncryptedInfoAppend(header, headerLen, (char*)cipher_info);
23719
    if (err != 0) {
23720
    #ifdef WOLFSSL_SMALL_STACK
23721
        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
23722
        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
23723
    #endif
23724
        return err;
23725
    }
23726
#endif
23727
23728
0
    headerLen = (int)XSTRLEN(header);
23729
0
    footerLen = (int)XSTRLEN(footer);
23730
23731
    /* if null output and 0 size passed in then return size needed */
23732
0
    if (!output && outSz == 0) {
23733
0
#ifdef WOLFSSL_SMALL_STACK
23734
0
        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
23735
0
        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
23736
0
#endif
23737
0
        outLen = 0;
23738
0
        if ((err = Base64_Encode(der, derSz, NULL, (word32*)&outLen))
23739
0
                != LENGTH_ONLY_E) {
23740
0
            WOLFSSL_ERROR_VERBOSE(err);
23741
0
            return err;
23742
0
        }
23743
0
        return headerLen + footerLen + outLen;
23744
0
    }
23745
23746
0
    if (!der || !output) {
23747
0
#ifdef WOLFSSL_SMALL_STACK
23748
0
        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
23749
0
        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
23750
0
#endif
23751
0
        return BAD_FUNC_ARG;
23752
0
    }
23753
23754
    /* don't even try if outSz too short */
23755
0
    if (outSz < (word32)headerLen + (word32)footerLen + derSz) {
23756
0
#ifdef WOLFSSL_SMALL_STACK
23757
0
        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
23758
0
        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
23759
0
#endif
23760
0
        return BAD_FUNC_ARG;
23761
0
    }
23762
23763
    /* header */
23764
0
    XMEMCPY(output, header, (size_t)headerLen);
23765
0
    i = headerLen;
23766
23767
0
#ifdef WOLFSSL_SMALL_STACK
23768
0
    XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
23769
0
#endif
23770
23771
    /* body */
23772
0
    outLen = (int)outSz - (headerLen + footerLen);  /* input to Base64_Encode */
23773
0
    if ( (err = Base64_Encode(der, derSz, output + i, (word32*)&outLen)) < 0) {
23774
0
#ifdef WOLFSSL_SMALL_STACK
23775
0
        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
23776
0
#endif
23777
0
        WOLFSSL_ERROR_VERBOSE(err);
23778
0
        return err;
23779
0
    }
23780
0
    i += outLen;
23781
23782
    /* footer */
23783
0
    if ( (i + footerLen) > (int)outSz) {
23784
0
#ifdef WOLFSSL_SMALL_STACK
23785
0
        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
23786
0
#endif
23787
0
        return BAD_FUNC_ARG;
23788
0
    }
23789
0
    XMEMCPY(output + i, footer, (size_t)footerLen);
23790
23791
0
#ifdef WOLFSSL_SMALL_STACK
23792
0
    XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
23793
0
#endif
23794
23795
0
    return outLen + headerLen + footerLen;
23796
0
}
23797
23798
#endif /* WOLFSSL_DER_TO_PEM */
23799
23800
#ifdef WOLFSSL_PEM_TO_DER
23801
23802
/* Remove PEM header/footer, convert to ASN1, store any encrypted data
23803
   info->consumed tracks of PEM bytes consumed in case multiple parts */
23804
int PemToDer(const unsigned char* buff, long longSz, int type,
23805
              DerBuffer** pDer, void* heap, EncryptedInfo* info, int* keyFormat)
23806
0
{
23807
0
    const char* header      = NULL;
23808
0
    const char* footer      = NULL;
23809
0
    const char* headerEnd;
23810
0
    const char* footerEnd;
23811
0
    const char* consumedEnd;
23812
0
    const char* bufferEnd   = (const char*)(buff + longSz);
23813
0
    long        neededSz;
23814
0
    int         ret         = 0;
23815
0
    word32      sz          = (word32)longSz;
23816
0
    int         encrypted_key = 0;
23817
0
    DerBuffer*  der;
23818
0
    word32      algId = 0;
23819
0
    word32      idx;
23820
#ifdef OPENSSL_EXTRA
23821
    char        beginBuf[PEM_LINE_LEN + 1]; /* add 1 for null terminator */
23822
    char        endBuf[PEM_LINE_LEN + 1];   /* add 1 for null terminator */
23823
#endif
23824
23825
0
    WOLFSSL_ENTER("PemToDer");
23826
23827
    /* get PEM header and footer based on type */
23828
0
    ret = wc_PemGetHeaderFooter(type, &header, &footer);
23829
0
    if (ret != 0)
23830
0
        return ret;
23831
23832
    /* map header if not found for type */
23833
0
    for (;;) {
23834
0
        headerEnd = XSTRNSTR((char*)buff, header, sz);
23835
0
        if (headerEnd) {
23836
0
            break;
23837
0
        }
23838
23839
0
        if (type == PRIVATEKEY_TYPE) {
23840
0
            if (header == BEGIN_RSA_PRIV) {
23841
0
                header = BEGIN_PRIV_KEY;
23842
0
                footer = END_PRIV_KEY;
23843
0
            }
23844
0
            else if (header == BEGIN_PRIV_KEY) {
23845
0
                header = BEGIN_ENC_PRIV_KEY;
23846
0
                footer = END_ENC_PRIV_KEY;
23847
0
            }
23848
0
#ifdef HAVE_ECC
23849
0
            else if (header == BEGIN_ENC_PRIV_KEY) {
23850
0
                header = BEGIN_EC_PRIV;
23851
0
                footer = END_EC_PRIV;
23852
0
            }
23853
0
            else if (header == BEGIN_EC_PRIV) {
23854
0
                header = BEGIN_DSA_PRIV;
23855
0
                footer = END_DSA_PRIV;
23856
0
            }
23857
0
#endif
23858
0
#if defined(HAVE_ED25519) || defined(HAVE_ED448)
23859
0
    #ifdef HAVE_ECC
23860
0
            else if (header == BEGIN_DSA_PRIV) {
23861
    #else
23862
            else if (header == BEGIN_ENC_PRIV_KEY) {
23863
    #endif
23864
0
                header = BEGIN_EDDSA_PRIV;
23865
0
                footer = END_EDDSA_PRIV;
23866
0
            }
23867
0
#endif
23868
0
            else {
23869
0
            #ifdef WOLF_PRIVATE_KEY_ID
23870
                /* allow loading a public key for use with crypto or PK callbacks */
23871
0
                type = PUBLICKEY_TYPE;
23872
0
                header = BEGIN_PUB_KEY;
23873
0
                footer = END_PUB_KEY;
23874
            #else
23875
                break;
23876
            #endif
23877
0
            }
23878
0
        }
23879
0
        else if (type == PUBLICKEY_TYPE) {
23880
0
            if (header == BEGIN_PUB_KEY) {
23881
0
                header = BEGIN_RSA_PUB;
23882
0
                footer = END_RSA_PUB;
23883
0
            }
23884
0
            else {
23885
0
                break;
23886
0
            }
23887
0
        }
23888
#if defined(HAVE_ECC) && defined(OPENSSL_EXTRA)
23889
        else if (type == ECC_PARAM_TYPE) {
23890
            if (header == BEGIN_EC_PARAM) {
23891
                header = BEGIN_EC_PARAM;
23892
                footer = END_EC_PARAM;
23893
            }
23894
            else {
23895
                break;
23896
            }
23897
        }
23898
#endif
23899
#ifdef HAVE_CRL
23900
        else if ((type == CRL_TYPE) && (header != BEGIN_X509_CRL)) {
23901
            header =  BEGIN_X509_CRL;
23902
            footer = END_X509_CRL;
23903
        }
23904
#endif
23905
0
        else {
23906
0
            break;
23907
0
        }
23908
0
    }
23909
23910
0
    if (!headerEnd) {
23911
#ifdef OPENSSL_EXTRA
23912
        if (type == PRIVATEKEY_TYPE) {
23913
            /* see if there is a -----BEGIN * PRIVATE KEY----- header */
23914
            headerEnd = XSTRNSTR((char*)buff, PRIV_KEY_SUFFIX, sz);
23915
            if (headerEnd) {
23916
                const char* beginEnd;
23917
                unsigned int endLen;
23918
23919
                beginEnd = headerEnd + XSTR_SIZEOF(PRIV_KEY_SUFFIX);
23920
                if (beginEnd >= (char*)buff + sz) {
23921
                    return BUFFER_E;
23922
                }
23923
23924
                /* back up to BEGIN_PRIV_KEY_PREFIX */
23925
                while (headerEnd > (char*)buff &&
23926
                        XSTRNCMP(headerEnd, BEGIN_PRIV_KEY_PREFIX,
23927
                                XSTR_SIZEOF(BEGIN_PRIV_KEY_PREFIX)) != 0 &&
23928
                        *headerEnd != '\n') {
23929
                    headerEnd--;
23930
                }
23931
                if (headerEnd <= (char*)buff ||
23932
                        XSTRNCMP(headerEnd, BEGIN_PRIV_KEY_PREFIX,
23933
                        XSTR_SIZEOF(BEGIN_PRIV_KEY_PREFIX)) != 0 ||
23934
                        beginEnd - headerEnd > PEM_LINE_LEN) {
23935
                    WOLFSSL_MSG("Couldn't find PEM header");
23936
                    WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
23937
                    return ASN_NO_PEM_HEADER;
23938
                }
23939
23940
                /* headerEnd now points to beginning of header */
23941
                XMEMCPY(beginBuf, headerEnd, (size_t)(beginEnd - headerEnd));
23942
                beginBuf[beginEnd - headerEnd] = '\0';
23943
                /* look for matching footer */
23944
                footer = XSTRNSTR(beginEnd,
23945
                                beginBuf + XSTR_SIZEOF(BEGIN_PRIV_KEY_PREFIX),
23946
                                (unsigned int)((char*)buff + sz - beginEnd));
23947
                if (!footer) {
23948
                    WOLFSSL_MSG("Couldn't find PEM footer");
23949
                    WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
23950
                    return ASN_NO_PEM_HEADER;
23951
                }
23952
23953
                footer -= XSTR_SIZEOF(END_PRIV_KEY_PREFIX);
23954
                if (footer > (char*)buff + sz - XSTR_SIZEOF(END_PRIV_KEY_PREFIX)
23955
                        || XSTRNCMP(footer, END_PRIV_KEY_PREFIX,
23956
                            XSTR_SIZEOF(END_PRIV_KEY_PREFIX)) != 0) {
23957
                    WOLFSSL_MSG("Unexpected footer for PEM");
23958
                    return BUFFER_E;
23959
                }
23960
23961
                endLen = (unsigned int)((size_t)(beginEnd - headerEnd) -
23962
                            (XSTR_SIZEOF(BEGIN_PRIV_KEY_PREFIX) -
23963
                                    XSTR_SIZEOF(END_PRIV_KEY_PREFIX)));
23964
                XMEMCPY(endBuf, footer, (size_t)endLen);
23965
                endBuf[endLen] = '\0';
23966
23967
                header = beginBuf;
23968
                footer = endBuf;
23969
                headerEnd = beginEnd;
23970
            }
23971
        }
23972
23973
        if (!headerEnd) {
23974
            WOLFSSL_MSG("Couldn't find PEM header");
23975
            WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
23976
            return ASN_NO_PEM_HEADER;
23977
        }
23978
#else
23979
0
        WOLFSSL_MSG("Couldn't find PEM header");
23980
0
        return ASN_NO_PEM_HEADER;
23981
0
#endif
23982
0
    } else {
23983
0
        headerEnd += XSTRLEN(header);
23984
0
    }
23985
23986
    /* eat end of line characters */
23987
0
    headerEnd = SkipEndOfLineChars(headerEnd, bufferEnd);
23988
23989
0
    if (keyFormat) {
23990
        /* keyFormat is Key_Sum enum */
23991
0
        if (type == PRIVATEKEY_TYPE) {
23992
0
        #ifndef NO_RSA
23993
0
            if (header == BEGIN_RSA_PRIV)
23994
0
                *keyFormat = RSAk;
23995
0
        #endif
23996
0
        #ifdef HAVE_ECC
23997
0
            if (header == BEGIN_EC_PRIV)
23998
0
                *keyFormat = ECDSAk;
23999
0
        #endif
24000
        #ifndef NO_DSA
24001
            if (header == BEGIN_DSA_PRIV)
24002
                *keyFormat = DSAk;
24003
        #endif
24004
0
        }
24005
0
    #ifdef WOLF_PRIVATE_KEY_ID
24006
0
        else if (type == PUBLICKEY_TYPE) {
24007
0
        #ifndef NO_RSA
24008
0
            if (header == BEGIN_RSA_PUB)
24009
0
                *keyFormat = RSAk;
24010
0
        #endif
24011
0
        }
24012
0
    #endif
24013
0
    }
24014
24015
#ifdef WOLFSSL_ENCRYPTED_KEYS
24016
    if (info) {
24017
        ret = wc_EncryptedInfoParse(info, &headerEnd,
24018
                                    (size_t)(bufferEnd - headerEnd));
24019
        if (ret < 0)
24020
            return ret;
24021
        if (info->set)
24022
            encrypted_key = 1;
24023
    }
24024
#endif /* WOLFSSL_ENCRYPTED_KEYS */
24025
24026
    /* find footer */
24027
0
    footerEnd = XSTRNSTR(headerEnd, footer, (unsigned int)((char*)buff +
24028
0
        sz - headerEnd));
24029
0
    if (!footerEnd) {
24030
0
        if (info)
24031
0
            info->consumed = longSz; /* No more certs if no footer */
24032
0
        return BUFFER_E;
24033
0
    }
24034
24035
0
    consumedEnd = footerEnd + XSTRLEN(footer);
24036
24037
0
    if (consumedEnd < bufferEnd) { /* handle no end of line on last line */
24038
        /* eat end of line characters */
24039
0
        consumedEnd = SkipEndOfLineChars(consumedEnd, bufferEnd);
24040
        /* skip possible null term */
24041
0
        if (consumedEnd < bufferEnd && consumedEnd[0] == '\0')
24042
0
            consumedEnd++;
24043
0
    }
24044
24045
0
    if (info)
24046
0
        info->consumed = (long)(consumedEnd - (const char*)buff);
24047
24048
    /* set up der buffer */
24049
0
    neededSz = (long)(footerEnd - headerEnd);
24050
0
    if (neededSz > (long)sz || neededSz <= 0)
24051
0
        return BUFFER_E;
24052
24053
0
    ret = AllocDer(pDer, (word32)neededSz, type, heap);
24054
0
    if (ret < 0) {
24055
0
        return ret;
24056
0
    }
24057
0
    der = *pDer;
24058
24059
0
    if (Base64_Decode((byte*)headerEnd, (word32)neededSz,
24060
0
                      der->buffer, &der->length) < 0) {
24061
0
        WOLFSSL_ERROR(BUFFER_E);
24062
0
        return BUFFER_E;
24063
0
    }
24064
24065
0
    if ((header == BEGIN_PRIV_KEY
24066
#ifdef OPENSSL_EXTRA
24067
         || header == beginBuf
24068
#endif
24069
0
#ifdef HAVE_ECC
24070
0
         || header == BEGIN_EC_PRIV
24071
0
#endif
24072
0
        ) && !encrypted_key)
24073
0
    {
24074
        /* detect pkcs8 key and get alg type */
24075
        /* keep PKCS8 header */
24076
0
        idx = 0;
24077
0
        ret = ToTraditionalInline_ex(der->buffer, &idx, der->length, &algId);
24078
0
        if (ret > 0) {
24079
0
            if (keyFormat)
24080
0
                *keyFormat = (int)algId;
24081
0
        }
24082
0
        else {
24083
            /* ignore failure here and assume key is not pkcs8 wrapped */
24084
0
        }
24085
0
        return 0;
24086
0
    }
24087
24088
#ifdef WOLFSSL_ENCRYPTED_KEYS
24089
    if (encrypted_key || header == BEGIN_ENC_PRIV_KEY) {
24090
        int   passwordSz = NAME_SZ;
24091
    #ifdef WOLFSSL_SMALL_STACK
24092
        char* password = NULL;
24093
    #else
24094
        char  password[NAME_SZ];
24095
    #endif
24096
24097
        if (!info || !info->passwd_cb) {
24098
            WOLFSSL_MSG("No password callback set");
24099
            WOLFSSL_ERROR_VERBOSE(NO_PASSWORD);
24100
            return NO_PASSWORD;
24101
        }
24102
24103
    #ifdef WOLFSSL_SMALL_STACK
24104
        password = (char*)XMALLOC(passwordSz, heap, DYNAMIC_TYPE_STRING);
24105
        if (password == NULL) {
24106
            return MEMORY_E;
24107
        }
24108
    #endif
24109
24110
        /* get password */
24111
        ret = info->passwd_cb(password, passwordSz, PEM_PASS_READ,
24112
            info->passwd_userdata);
24113
        if (ret >= 0) {
24114
            passwordSz = ret;
24115
        #ifdef WOLFSSL_CHECK_MEM_ZERO
24116
            wc_MemZero_Add("PEM password", password, passwordSz);
24117
        #endif
24118
24119
            /* convert and adjust length */
24120
            if (header == BEGIN_ENC_PRIV_KEY) {
24121
            #ifndef NO_PWDBASED
24122
                ret = wc_DecryptPKCS8Key(der->buffer, der->length,
24123
                    password, passwordSz);
24124
                if (ret > 0) {
24125
                    /* update length by decrypted content */
24126
                    der->length = (word32)ret;
24127
                    idx = 0;
24128
                    /* detect pkcs8 key and get alg type */
24129
                    /* keep PKCS8 header */
24130
                    ret = ToTraditionalInline_ex(der->buffer, &idx, der->length,
24131
                        &algId);
24132
                    if (ret >= 0) {
24133
                        if (keyFormat)
24134
                            *keyFormat = (int)algId;
24135
                        ret = 0;
24136
                    }
24137
                }
24138
            #else
24139
                WOLFSSL_ERROR_VERBOSE(NOT_COMPILED_IN);
24140
                ret = NOT_COMPILED_IN;
24141
            #endif
24142
            }
24143
            /* decrypt the key */
24144
            else {
24145
                if (passwordSz == 0) {
24146
                    /* The key is encrypted but does not have a password */
24147
                    WOLFSSL_MSG("No password for encrypted key");
24148
                    WOLFSSL_ERROR_VERBOSE(NO_PASSWORD);
24149
                    ret = NO_PASSWORD;
24150
                }
24151
                else {
24152
                #if ((defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_DES3)) || \
24153
                         (!defined(NO_AES) && defined(HAVE_AES_CBC) && \
24154
                          defined(HAVE_AES_DECRYPT))) && \
24155
                        !defined(NO_WOLFSSL_SKIP_TRAILING_PAD)
24156
                    int     padVal = 0;
24157
                #endif
24158
24159
                    ret = wc_BufferKeyDecrypt(info, der->buffer, der->length,
24160
                        (byte*)password, passwordSz, WC_MD5);
24161
24162
#ifndef NO_WOLFSSL_SKIP_TRAILING_PAD
24163
                #ifndef NO_DES3
24164
                    if (info->cipherType == WC_CIPHER_DES3) {
24165
                        /* Assuming there is padding:
24166
                         *      (der->length > 0 && der->length > DES_BLOCK_SIZE &&
24167
                         *       (der->length % DES_BLOCK_SIZE) != 0)
24168
                         * and assuming the last value signifies the number of
24169
                         * padded bytes IE if last value is 0x08 then there are
24170
                         * 8 bytes of padding:
24171
                         *      padVal = der->buffer[der->length-1];
24172
                         * then strip this padding before proceeding:
24173
                         * der->length -= padVal;
24174
                         */
24175
                        if (der->length > DES_BLOCK_SIZE &&
24176
                            (der->length % DES_BLOCK_SIZE) != 0) {
24177
                            padVal = der->buffer[der->length-1];
24178
                            if (padVal < DES_BLOCK_SIZE) {
24179
                                der->length -= (word32)padVal;
24180
                            }
24181
                        }
24182
                    }
24183
                #endif /* !NO_DES3 */
24184
                #if !defined(NO_AES) && defined(HAVE_AES_CBC) && \
24185
                    defined(HAVE_AES_DECRYPT)
24186
                    if (info->cipherType == WC_CIPHER_AES_CBC) {
24187
                        if (der->length > AES_BLOCK_SIZE) {
24188
                            padVal = der->buffer[der->length-1];
24189
                            if (padVal <= AES_BLOCK_SIZE) {
24190
                                der->length -= (word32)padVal;
24191
                            }
24192
                        }
24193
                    }
24194
                #endif
24195
#endif /* !NO_WOLFSSL_SKIP_TRAILING_PAD */
24196
                }
24197
            }
24198
#ifdef OPENSSL_EXTRA
24199
            if (ret) {
24200
                PEMerr(0, PEM_R_BAD_DECRYPT);
24201
            }
24202
#endif
24203
            ForceZero(password, (word32)passwordSz);
24204
        }
24205
#ifdef OPENSSL_EXTRA
24206
        else {
24207
            PEMerr(0, PEM_R_BAD_PASSWORD_READ);
24208
        }
24209
#endif
24210
24211
    #ifdef WOLFSSL_SMALL_STACK
24212
        XFREE(password, heap, DYNAMIC_TYPE_STRING);
24213
    #elif defined(WOLFSSL_CHECK_MEM_ZERO)
24214
        wc_MemZero_Check(password, NAME_SZ);
24215
    #endif
24216
    }
24217
#endif /* WOLFSSL_ENCRYPTED_KEYS */
24218
24219
0
    return ret;
24220
0
}
24221
24222
int wc_PemToDer(const unsigned char* buff, long longSz, int type,
24223
              DerBuffer** pDer, void* heap, EncryptedInfo* info, int* keyFormat)
24224
0
{
24225
0
    int ret = PemToDer(buff, longSz, type, pDer, heap, info, keyFormat);
24226
0
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
24227
0
    if (ret == 0 && type == PRIVATEKEY_TYPE) {
24228
0
        DerBuffer* der = *pDer;
24229
        /* if a PKCS8 key header exists remove it */
24230
0
        ret = ToTraditional(der->buffer, der->length);
24231
0
        if (ret > 0) {
24232
0
            der->length = (word32)ret;
24233
0
        }
24234
0
        ret = 0; /* ignore error removing PKCS8 header */
24235
0
    }
24236
0
#endif
24237
0
    return ret;
24238
0
}
24239
24240
#ifdef WOLFSSL_ENCRYPTED_KEYS
24241
/* our KeyPemToDer password callback, password in userData */
24242
static int KeyPemToDerPassCb(char* passwd, int sz, int rw, void* userdata)
24243
{
24244
    (void)rw;
24245
24246
    if (userdata == NULL)
24247
        return 0;
24248
24249
    XSTRNCPY(passwd, (char*)userdata, (size_t)sz);
24250
    return (int)min((word32)sz, (word32)XSTRLEN((char*)userdata));
24251
}
24252
#endif
24253
24254
/* Return bytes written to buff or < 0 for error */
24255
int wc_KeyPemToDer(const unsigned char* pem, int pemSz,
24256
                        unsigned char* buff, int buffSz, const char* pass)
24257
0
{
24258
0
    int ret;
24259
0
    DerBuffer* der = NULL;
24260
0
#ifdef WOLFSSL_SMALL_STACK
24261
0
    EncryptedInfo* info = NULL;
24262
#else
24263
    EncryptedInfo  info[1];
24264
#endif
24265
24266
0
    WOLFSSL_ENTER("wc_KeyPemToDer");
24267
24268
0
    if (pem == NULL || (buff != NULL && buffSz <= 0)) {
24269
0
        WOLFSSL_MSG("Bad pem der args");
24270
0
        return BAD_FUNC_ARG;
24271
0
    }
24272
24273
0
#ifdef WOLFSSL_SMALL_STACK
24274
0
    info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
24275
0
                                   DYNAMIC_TYPE_ENCRYPTEDINFO);
24276
0
    if (info == NULL)
24277
0
        return MEMORY_E;
24278
0
#endif
24279
24280
0
    XMEMSET(info, 0, sizeof(EncryptedInfo));
24281
#ifdef WOLFSSL_ENCRYPTED_KEYS
24282
    info->passwd_cb = KeyPemToDerPassCb;
24283
    info->passwd_userdata = (void*)pass;
24284
#else
24285
0
    (void)pass;
24286
0
#endif
24287
24288
0
    ret = PemToDer(pem, pemSz, PRIVATEKEY_TYPE, &der, NULL, info, NULL);
24289
24290
0
#ifdef WOLFSSL_SMALL_STACK
24291
0
    XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
24292
0
#endif
24293
24294
0
    if (ret < 0 || der == NULL) {
24295
0
        WOLFSSL_MSG("Bad Pem To Der");
24296
0
    }
24297
0
    else if (buff == NULL) {
24298
0
        WOLFSSL_MSG("Return needed der buff length");
24299
0
        ret = (int)der->length;
24300
0
    }
24301
0
    else if (der->length <= (word32)buffSz) {
24302
0
        XMEMCPY(buff, der->buffer, der->length);
24303
0
        ret = (int)der->length;
24304
0
    }
24305
0
    else {
24306
0
        WOLFSSL_MSG("Bad der length");
24307
0
        ret = BAD_FUNC_ARG;
24308
0
    }
24309
24310
0
    FreeDer(&der);
24311
0
    return ret;
24312
0
}
24313
24314
24315
/* Return bytes written to buff or < 0 for error */
24316
int wc_CertPemToDer(const unsigned char* pem, int pemSz,
24317
                        unsigned char* buff, int buffSz, int type)
24318
0
{
24319
0
    int ret;
24320
0
    DerBuffer* der = NULL;
24321
24322
0
    WOLFSSL_ENTER("wc_CertPemToDer");
24323
24324
0
    if (pem == NULL || buff == NULL || buffSz <= 0) {
24325
0
        WOLFSSL_MSG("Bad pem der args");
24326
0
        return BAD_FUNC_ARG;
24327
0
    }
24328
24329
0
    if (type != CERT_TYPE && type != CHAIN_CERT_TYPE && type != CA_TYPE &&
24330
0
            type != CERTREQ_TYPE) {
24331
0
        WOLFSSL_MSG("Bad cert type");
24332
0
        return BAD_FUNC_ARG;
24333
0
    }
24334
24335
24336
0
    ret = PemToDer(pem, pemSz, type, &der, NULL, NULL, NULL);
24337
0
    if (ret < 0 || der == NULL) {
24338
0
        WOLFSSL_MSG("Bad Pem To Der");
24339
0
    }
24340
0
    else {
24341
0
        if (der->length <= (word32)buffSz) {
24342
0
            XMEMCPY(buff, der->buffer, der->length);
24343
0
            ret = (int)der->length;
24344
0
        }
24345
0
        else {
24346
0
            WOLFSSL_MSG("Bad der length");
24347
0
            ret = BAD_FUNC_ARG;
24348
0
        }
24349
0
    }
24350
24351
0
    FreeDer(&der);
24352
0
    return ret;
24353
0
}
24354
24355
#endif /* WOLFSSL_PEM_TO_DER */
24356
#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
24357
24358
24359
#ifdef WOLFSSL_PEM_TO_DER
24360
#if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER)
24361
/* Return bytes written to buff, needed buff size if buff is NULL, or less than
24362
   zero for error */
24363
int wc_PubKeyPemToDer(const unsigned char* pem, int pemSz,
24364
                           unsigned char* buff, int buffSz)
24365
{
24366
    int ret;
24367
    DerBuffer* der = NULL;
24368
24369
    WOLFSSL_ENTER("wc_PubKeyPemToDer");
24370
24371
    if (pem == NULL || (buff != NULL && buffSz <= 0)) {
24372
        WOLFSSL_MSG("Bad pem der args");
24373
        return BAD_FUNC_ARG;
24374
    }
24375
24376
    ret = PemToDer(pem, pemSz, PUBLICKEY_TYPE, &der, NULL, NULL, NULL);
24377
    if (ret < 0 || der == NULL) {
24378
        WOLFSSL_MSG("Bad Pem To Der");
24379
    }
24380
    else if (buff == NULL) {
24381
        WOLFSSL_MSG("Return needed der buff length");
24382
        ret = (int)der->length;
24383
    }
24384
    else if (der->length <= (word32)buffSz) {
24385
        XMEMCPY(buff, der->buffer, der->length);
24386
        ret = (int)der->length;
24387
    }
24388
    else {
24389
        WOLFSSL_MSG("Bad der length");
24390
        ret = BAD_FUNC_ARG;
24391
    }
24392
24393
    FreeDer(&der);
24394
    return ret;
24395
}
24396
#endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */
24397
#endif /* WOLFSSL_PEM_TO_DER */
24398
24399
#if !defined(NO_FILESYSTEM) && defined(WOLFSSL_PEM_TO_DER)
24400
24401
#ifdef WOLFSSL_CERT_GEN
24402
int wc_PemCertToDer_ex(const char* fileName, DerBuffer** der)
24403
{
24404
#ifndef WOLFSSL_SMALL_STACK
24405
    byte   staticBuffer[FILE_BUFFER_SIZE];
24406
#endif
24407
    byte*  fileBuf = NULL;
24408
    int    ret     = 0;
24409
    XFILE  file    = XBADFILE;
24410
    int    dynamic = 0;
24411
    long   sz      = 0;
24412
24413
    WOLFSSL_ENTER("wc_PemCertToDer");
24414
24415
    if (fileName == NULL) {
24416
        ret = BAD_FUNC_ARG;
24417
    }
24418
    else {
24419
        file = XFOPEN(fileName, "rb");
24420
        if (file == XBADFILE) {
24421
            ret = IO_FAILED_E;
24422
        }
24423
    }
24424
24425
    if (ret == 0) {
24426
        if (XFSEEK(file, 0, XSEEK_END) != 0) {
24427
            ret = IO_FAILED_E;
24428
        }
24429
    }
24430
    if (ret == 0) {
24431
        sz = XFTELL(file);
24432
        if (sz <= 0) {
24433
            ret = IO_FAILED_E;
24434
        }
24435
    }
24436
    if (ret == 0) {
24437
        if (XFSEEK(file, 0, XSEEK_SET) != 0) {
24438
            ret = IO_FAILED_E;
24439
        }
24440
    }
24441
    if (ret == 0) {
24442
#ifndef WOLFSSL_SMALL_STACK
24443
        if (sz <= (long)sizeof(staticBuffer))
24444
            fileBuf = staticBuffer;
24445
        else
24446
#endif
24447
        {
24448
            fileBuf = (byte*)XMALLOC((size_t)sz, NULL, DYNAMIC_TYPE_FILE);
24449
            if (fileBuf == NULL)
24450
                ret = MEMORY_E;
24451
            else
24452
                dynamic = 1;
24453
        }
24454
    }
24455
    if (ret == 0) {
24456
        if ((size_t)XFREAD(fileBuf, 1, (size_t)sz, file) != (size_t)sz) {
24457
            ret = IO_FAILED_E;
24458
        }
24459
        else {
24460
            ret = PemToDer(fileBuf, sz, CA_TYPE, der,  0, NULL,NULL);
24461
        }
24462
    }
24463
24464
    if (file != XBADFILE)
24465
        XFCLOSE(file);
24466
    if (dynamic)
24467
        XFREE(fileBuf, NULL, DYNAMIC_TYPE_FILE);
24468
24469
    return ret;
24470
}
24471
/* load pem cert from file into der buffer, return der size or error */
24472
int wc_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz)
24473
{
24474
    int ret;
24475
    DerBuffer* converted = NULL;
24476
    ret = wc_PemCertToDer_ex(fileName, &converted);
24477
    if (ret == 0) {
24478
        if (converted->length < (word32)derSz) {
24479
            XMEMCPY(derBuf, converted->buffer, converted->length);
24480
            ret = (int)converted->length;
24481
        }
24482
        else
24483
            ret = BUFFER_E;
24484
24485
        FreeDer(&converted);
24486
    }
24487
    return ret;
24488
}
24489
#endif /* WOLFSSL_CERT_GEN */
24490
24491
#if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER)
24492
/* load pem public key from file into der buffer, return der size or error */
24493
int wc_PemPubKeyToDer_ex(const char* fileName, DerBuffer** der)
24494
{
24495
#ifndef WOLFSSL_SMALL_STACK
24496
    byte   staticBuffer[FILE_BUFFER_SIZE];
24497
#endif
24498
    byte*  fileBuf = NULL;
24499
    int    dynamic = 0;
24500
    int    ret     = 0;
24501
    long   sz      = 0;
24502
    XFILE  file    = XBADFILE;
24503
24504
    WOLFSSL_ENTER("wc_PemPubKeyToDer");
24505
24506
    if (fileName == NULL) {
24507
        ret = BAD_FUNC_ARG;
24508
    }
24509
    else {
24510
        file = XFOPEN(fileName, "rb");
24511
        if (file == XBADFILE) {
24512
            ret = IO_FAILED_E;
24513
        }
24514
    }
24515
24516
    if (ret == 0) {
24517
        if (XFSEEK(file, 0, XSEEK_END) != 0) {
24518
            ret = IO_FAILED_E;
24519
        }
24520
    }
24521
    if (ret == 0) {
24522
        sz = XFTELL(file);
24523
        if (sz <= 0) {
24524
            ret = IO_FAILED_E;
24525
        }
24526
    }
24527
    if (ret == 0) {
24528
        if (XFSEEK(file, 0, XSEEK_SET) != 0) {
24529
            ret = IO_FAILED_E;
24530
        }
24531
    }
24532
    if (ret == 0) {
24533
#ifndef WOLFSSL_SMALL_STACK
24534
        if (sz <= (long)sizeof(staticBuffer))
24535
            fileBuf = staticBuffer;
24536
        else
24537
#endif
24538
        {
24539
            fileBuf = (byte*)XMALLOC((size_t)sz, NULL, DYNAMIC_TYPE_FILE);
24540
            if (fileBuf == NULL)
24541
                ret = MEMORY_E;
24542
            else
24543
                dynamic = 1;
24544
        }
24545
    }
24546
    if (ret == 0) {
24547
        if ((size_t)XFREAD(fileBuf, 1, (size_t)sz, file) != (size_t)sz) {
24548
            ret = BUFFER_E;
24549
        }
24550
        else {
24551
            ret = PemToDer(fileBuf, sz, PUBLICKEY_TYPE, der,
24552
                           0, NULL, NULL);
24553
        }
24554
    }
24555
24556
    if (file != XBADFILE)
24557
        XFCLOSE(file);
24558
    if (dynamic)
24559
        XFREE(fileBuf, NULL, DYNAMIC_TYPE_FILE);
24560
24561
    return ret;
24562
}
24563
/* load pem public key from file into der buffer, return der size or error */
24564
int wc_PemPubKeyToDer(const char* fileName,
24565
                           unsigned char* derBuf, int derSz)
24566
{
24567
    int ret;
24568
    DerBuffer* converted = NULL;
24569
    ret = wc_PemPubKeyToDer_ex(fileName, &converted);
24570
    if (ret == 0) {
24571
        if (converted->length < (word32)derSz) {
24572
            XMEMCPY(derBuf, converted->buffer, converted->length);
24573
            ret = (int)converted->length;
24574
        }
24575
        else
24576
            ret = BUFFER_E;
24577
24578
        FreeDer(&converted);
24579
    }
24580
    return ret;
24581
}
24582
#endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */
24583
24584
#endif /* !NO_FILESYSTEM && WOLFSSL_PEM_TO_DER */
24585
24586
/* Get public key in DER format from a populated DecodedCert struct.
24587
 *
24588
 * Users must call wc_InitDecodedCert() and wc_ParseCert() before calling
24589
 * this API. wc_InitDecodedCert() accepts a DER/ASN.1 encoded certificate.
24590
 * To convert a PEM cert to DER first use wc_CertPemToDer() before calling
24591
 * wc_InitDecodedCert().
24592
 *
24593
 * cert   - populated DecodedCert struct holding X.509 certificate
24594
 * derKey - output buffer to place DER/ASN.1 encoded public key
24595
 * derKeySz [IN/OUT] - size of derKey buffer on input, size of public key
24596
 *                     on return. If derKey is passed in as NULL, derKeySz
24597
 *                     will be set to required buffer size for public key
24598
 *                     and LENGTH_ONLY_E will be returned from function.
24599
 * Returns 0 on success, or negative error code on failure. LENGTH_ONLY_E
24600
 * if derKey is NULL and returning length only.
24601
 */
24602
int wc_GetPubKeyDerFromCert(struct DecodedCert* cert,
24603
                            byte* derKey, word32* derKeySz)
24604
0
{
24605
0
    int ret = 0;
24606
24607
    /* derKey may be NULL to return length only */
24608
0
    if (cert == NULL || derKeySz == NULL ||
24609
0
        (derKey != NULL && *derKeySz == 0)) {
24610
0
        return BAD_FUNC_ARG;
24611
0
    }
24612
24613
0
    if (cert->publicKey == NULL) {
24614
0
        WOLFSSL_MSG("DecodedCert does not contain public key\n");
24615
0
        return BAD_FUNC_ARG;
24616
0
    }
24617
24618
    /* if derKey is NULL, return required output buffer size in derKeySz */
24619
0
    if (derKey == NULL) {
24620
0
        *derKeySz = cert->pubKeySize;
24621
0
        ret = LENGTH_ONLY_E;
24622
0
    }
24623
24624
0
    if (ret == 0) {
24625
0
        if (cert->pubKeySize > *derKeySz) {
24626
0
            WOLFSSL_MSG("Output buffer not large enough for public key DER");
24627
0
            ret = BAD_FUNC_ARG;
24628
0
        }
24629
0
        else {
24630
0
            XMEMCPY(derKey, cert->publicKey, cert->pubKeySize);
24631
0
            *derKeySz = cert->pubKeySize;
24632
0
        }
24633
0
    }
24634
24635
0
    return ret;
24636
0
}
24637
24638
#ifdef WOLFSSL_FPKI
24639
/* Search through list for first matching alt name of the same type
24640
 * If 'current' is null then the search starts at the head of the list
24641
 * otherwise the search starts from the node after 'current' alt name.
24642
 * Returns 0 on success
24643
 */
24644
static DNS_entry* FindAltName(struct DecodedCert* cert, int nameType,
24645
    DNS_entry* current)
24646
{
24647
    DNS_entry* entry;
24648
24649
    if (current == NULL) {
24650
        entry = cert->altNames;
24651
    }
24652
    else {
24653
        entry = current->next;
24654
    }
24655
24656
    /* cycle through alt names to check for needed types */
24657
    while (entry != NULL) {
24658
        if (entry->type == nameType) {
24659
            break;
24660
        }
24661
        entry = entry->next;
24662
    }
24663
24664
    return entry;
24665
}
24666
24667
24668
/* returns 0 on success */
24669
int wc_GetUUIDFromCert(struct DecodedCert* cert, byte* uuid, word32* uuidSz)
24670
{
24671
    int ret = ALT_NAME_E;
24672
    DNS_entry* id = NULL;
24673
24674
    do {
24675
        id = FindAltName(cert, ASN_URI_TYPE, id);
24676
        if (id != NULL) {
24677
            /* check if URI string matches expected format for UUID */
24678
            if (id->len != DEFAULT_UUID_SZ) {
24679
                continue; /* size not right not a UUID URI */
24680
            }
24681
24682
            if (XMEMCMP(id->name, "urn:uuid:", 9) != 0) {
24683
                continue; /* beginning text not right for a UUID URI */
24684
            }
24685
24686
            if (uuid == NULL) {
24687
                *uuidSz = (word32)id->len;
24688
                return LENGTH_ONLY_E;
24689
            }
24690
24691
            if ((int)*uuidSz < id->len) {
24692
                return BUFFER_E;
24693
            }
24694
24695
            XMEMCPY(uuid, id->name, (size_t)id->len);
24696
            ret = 0; /* success */
24697
            break;
24698
        }
24699
    } while (id != NULL);
24700
24701
    return ret;
24702
}
24703
24704
24705
/* reutrns 0 on success */
24706
int wc_GetFASCNFromCert(struct DecodedCert* cert, byte* fascn, word32* fascnSz)
24707
{
24708
    int ret = ALT_NAME_E;
24709
    DNS_entry* id = NULL;
24710
24711
    do {
24712
        id = FindAltName(cert, ASN_OTHER_TYPE, id);
24713
        if (id != NULL && id->oidSum == FASCN_OID) {
24714
            if (fascn == NULL) {
24715
                *fascnSz = (word32)id->len;
24716
                return LENGTH_ONLY_E;
24717
            }
24718
24719
            if ((int)*fascnSz < id->len) {
24720
                return BUFFER_E;
24721
            }
24722
24723
            XMEMCPY(fascn, id->name, (size_t)id->len);
24724
            ret = 0; /* success */
24725
        }
24726
    } while (id != NULL);
24727
24728
    return ret;
24729
}
24730
#endif /* WOLFSSL_FPKI */
24731
24732
#if !defined(NO_RSA) && (defined(WOLFSSL_CERT_GEN) || \
24733
    defined(WOLFSSL_KCAPI_RSA) || \
24734
    ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(HAVE_USER_RSA)))
24735
/* USER RSA ifdef portions used instead of refactor in consideration for
24736
   possible fips build */
24737
/* Encode a public RSA key to output.
24738
 *
24739
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
24740
 * PKCS #1: RFC 8017, A.1.1 - RSAPublicKey
24741
 *
24742
 * Encoded data can either be SubjectPublicKeyInfo (with header) or just the key
24743
 * (RSAPublicKey).
24744
 *
24745
 * @param [out] output       Buffer to put encoded data in.
24746
 * @param [in]  key          RSA key object.
24747
 * @param [in]  outLen       Size of the output buffer in bytes.
24748
 * @param [in]  with_header  Whether to include SubjectPublicKeyInfo around key.
24749
 * @return  Size of encoded data in bytes on success.
24750
 * @return  BAD_FUNC_ARG when output or key is NULL, or outLen is less than
24751
 *          minimum length (5 bytes).
24752
 * @return  MEMORY_E when dynamic memory allocation failed.
24753
 */
24754
static int SetRsaPublicKey(byte* output, RsaKey* key, int outLen,
24755
                           int with_header)
24756
0
{
24757
#ifndef WOLFSSL_ASN_TEMPLATE
24758
    int  nSz, eSz;
24759
    word32 seqSz, algoSz = 0, headSz = 0, bitStringSz = 0, idx;
24760
    byte seq[MAX_SEQ_SZ];
24761
    byte headSeq[MAX_SEQ_SZ];
24762
    byte bitString[1 + MAX_LENGTH_SZ + 1];
24763
    byte algo[MAX_ALGO_SZ]; /* 20 bytes */
24764
24765
    if (key == NULL) {
24766
        return BAD_FUNC_ARG;
24767
    }
24768
24769
#ifdef HAVE_USER_RSA
24770
    nSz = SetASNIntRSA(key->n, NULL);
24771
#else
24772
    nSz = SetASNIntMP(&key->n, MAX_RSA_INT_SZ, NULL);
24773
#endif
24774
    if (nSz < 0)
24775
        return nSz;
24776
24777
#ifdef HAVE_USER_RSA
24778
    eSz = SetASNIntRSA(key->e, NULL);
24779
#else
24780
    eSz = SetASNIntMP(&key->e, MAX_RSA_INT_SZ, NULL);
24781
#endif
24782
    if (eSz < 0)
24783
        return eSz;
24784
    seqSz = SetSequence((word32)(nSz + eSz), seq);
24785
24786
    /* headers */
24787
    if (with_header) {
24788
        algoSz = SetAlgoID(RSAk, algo, oidKeyType, 0);
24789
        bitStringSz = SetBitString(seqSz + (word32)(nSz + eSz), 0, bitString);
24790
        headSz = SetSequence((word32)(nSz + eSz) + seqSz + bitStringSz + algoSz,
24791
                             headSeq);
24792
    }
24793
24794
    /* if getting length only */
24795
    if (output == NULL) {
24796
        return (int)(headSz + algoSz + bitStringSz + seqSz) + nSz + eSz;
24797
    }
24798
24799
    /* check output size */
24800
    if (((int)(headSz + algoSz + bitStringSz + seqSz) + nSz + eSz) > outLen) {
24801
        return BUFFER_E;
24802
    }
24803
24804
    /* write output */
24805
    idx = 0;
24806
    if (with_header) {
24807
        /* header size */
24808
        XMEMCPY(output + idx, headSeq, headSz);
24809
        idx += headSz;
24810
        /* algo */
24811
        XMEMCPY(output + idx, algo, algoSz);
24812
        idx += algoSz;
24813
        /* bit string */
24814
        XMEMCPY(output + idx, bitString, bitStringSz);
24815
        idx += bitStringSz;
24816
    }
24817
24818
    /* seq */
24819
    XMEMCPY(output + idx, seq, seqSz);
24820
    idx += seqSz;
24821
    /* n */
24822
#ifdef HAVE_USER_RSA
24823
    nSz = SetASNIntRSA(key->n, output + idx);
24824
#else
24825
    nSz = SetASNIntMP(&key->n, nSz, output + idx);
24826
#endif
24827
    idx += (word32)nSz;
24828
    /* e */
24829
#ifdef HAVE_USER_RSA
24830
    eSz = SetASNIntRSA(key->e, output + idx);
24831
#else
24832
    eSz = SetASNIntMP(&key->e, eSz, output + idx);
24833
#endif
24834
    idx += (word32)eSz;
24835
24836
    return (int)idx;
24837
#else
24838
0
    DECL_ASNSETDATA(dataASN, rsaPublicKeyASN_Length);
24839
0
    int sz = 0;
24840
0
    int ret = 0;
24841
0
    int o = 0;
24842
24843
    /* Check parameter validity. */
24844
0
    if ((key == NULL) || ((output != NULL) && (outLen < MAX_SEQ_SZ))) {
24845
0
        ret = BAD_FUNC_ARG;
24846
0
    }
24847
24848
0
    CALLOC_ASNSETDATA(dataASN, rsaPublicKeyASN_Length, ret, key->heap);
24849
24850
0
    if (ret == 0) {
24851
0
        if (!with_header) {
24852
            /* Start encoding with items after header. */
24853
0
            o = RSAPUBLICKEYASN_IDX_PUBKEY_RSA_SEQ;
24854
0
        }
24855
        /* Set OID for RSA key. */
24856
0
        SetASN_OID(&dataASN[RSAPUBLICKEYASN_IDX_ALGOID_OID], RSAk, oidKeyType);
24857
0
    #ifdef WC_RSA_PSS
24858
0
        dataASN[RSAPUBLICKEYASN_IDX_ALGOID_P_SEQ].noOut = 1;
24859
0
    #endif
24860
        /* Set public key mp_ints. */
24861
    #ifdef HAVE_USER_RSA
24862
        SetASN_MP(&dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_N], key->n);
24863
        SetASN_MP(&dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_E], key->e);
24864
    #else
24865
0
        SetASN_MP(&dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_N], &key->n);
24866
0
        SetASN_MP(&dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_E], &key->e);
24867
0
    #endif
24868
        /* Calculate size of RSA public key. */
24869
0
        ret = SizeASN_Items(rsaPublicKeyASN + o, dataASN + o,
24870
0
                            (int)rsaPublicKeyASN_Length - o, &sz);
24871
0
    }
24872
    /* Check output buffer is big enough for encoding. */
24873
0
    if ((ret == 0) && (output != NULL) && (sz > outLen)) {
24874
0
        ret = BUFFER_E;
24875
0
    }
24876
0
    if ((ret == 0) && (output != NULL)) {
24877
        /* Encode RSA public key. */
24878
0
        SetASN_Items(rsaPublicKeyASN + o, dataASN + o,
24879
0
                     (int)rsaPublicKeyASN_Length - o, output);
24880
0
    }
24881
0
    if (ret == 0) {
24882
        /* Return size of encoding. */
24883
0
        ret = sz;
24884
0
    }
24885
24886
0
    FREE_ASNSETDATA(dataASN, key->heap);
24887
0
    return ret;
24888
0
#endif /* WOLFSSL_ASN_TEMPLATE */
24889
0
}
24890
24891
/* Calculate size of encoded public RSA key in bytes.
24892
 *
24893
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
24894
 * PKCS #1: RFC 8017, A.1.1 - RSAPublicKey
24895
 *
24896
 * Encoded data can either be SubjectPublicKeyInfo (with header) or just the key
24897
 * (RSAPublicKey).
24898
 *
24899
 * @param [in]  key          RSA key object.
24900
 * @param [in]  with_header  Whether to include SubjectPublicKeyInfo around key.
24901
 * @return  Size of encoded data in bytes on success.
24902
 * @return  BAD_FUNC_ARG when key is NULL.
24903
 * @return  MEMORY_E when dynamic memory allocation failed.
24904
 */
24905
int wc_RsaPublicKeyDerSize(RsaKey* key, int with_header)
24906
0
{
24907
0
    return SetRsaPublicKey(NULL, key, 0, with_header);
24908
0
}
24909
24910
/* Encode public RSA key in DER format.
24911
 *
24912
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
24913
 * PKCS #1: RFC 8017, A.1.1 - RSAPublicKey
24914
 *
24915
 * @param [in]  key     RSA key object.
24916
 * @param [out] output  Buffer to put encoded data in.
24917
 * @param [in]  inLen   Size of buffer in bytes.
24918
 * @return  Size of encoded data in bytes on success.
24919
 * @return  BAD_FUNC_ARG when key or output is NULL.
24920
 * @return  MEMORY_E when dynamic memory allocation failed.
24921
 */
24922
int wc_RsaKeyToPublicDer(RsaKey* key, byte* output, word32 inLen)
24923
0
{
24924
0
    return SetRsaPublicKey(output, key, (int)inLen, 1);
24925
0
}
24926
24927
/* Returns public DER version of the RSA key. If with_header is 0 then only a
24928
 * seq + n + e is returned in ASN.1 DER format */
24929
int wc_RsaKeyToPublicDer_ex(RsaKey* key, byte* output, word32 inLen,
24930
    int with_header)
24931
0
{
24932
0
    return SetRsaPublicKey(output, key, (int)inLen, with_header);
24933
0
}
24934
24935
#endif /* !NO_RSA && (WOLFSSL_CERT_GEN || WOLFSSL_KCAPI_RSA ||
24936
            ((OPENSSL_EXTRA || WOLFSSL_KEY_GEN) && !HAVE_USER_RSA))) */
24937
24938
#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || \
24939
     defined(WOLFSSL_KCAPI_RSA) || defined(WOLFSSL_SE050)) && \
24940
     !defined(NO_RSA) && !defined(HAVE_USER_RSA)
24941
24942
/* Encode private RSA key in DER format.
24943
 *
24944
 * PKCS #1: RFC 8017, A.1.2 - RSAPrivateKey
24945
 *
24946
 * @param [in]  key     RSA key object.
24947
 * @param [out] output  Buffer to put encoded data in.
24948
 * @param [in]  inLen   Size of buffer in bytes.
24949
 * @return  Size of encoded data in bytes on success.
24950
 * @return  BAD_FUNC_ARG when key is NULL or not a private key.
24951
 * @return  MEMORY_E when dynamic memory allocation failed.
24952
 */
24953
int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)
24954
0
{
24955
#ifndef WOLFSSL_ASN_TEMPLATE
24956
    int ret = 0, i;
24957
    word32 seqSz = 0, verSz = 0, intTotalLen = 0, outLen = 0;
24958
    word32 sizes[RSA_INTS];
24959
    byte  seq[MAX_SEQ_SZ];
24960
    byte  ver[MAX_VERSION_SZ];
24961
    byte* tmps[RSA_INTS];
24962
24963
    if (key == NULL)
24964
        return BAD_FUNC_ARG;
24965
24966
    if (key->type != RSA_PRIVATE)
24967
        return BAD_FUNC_ARG;
24968
24969
    for (i = 0; i < RSA_INTS; i++)
24970
        tmps[i] = NULL;
24971
24972
    /* write all big ints from key to DER tmps */
24973
    for (i = 0; i < RSA_INTS; i++) {
24974
        mp_int* keyInt = GetRsaInt(key, i);
24975
        int mpSz;
24976
        word32 rawLen;
24977
24978
        ret = mp_unsigned_bin_size(keyInt);
24979
        if (ret < 0)
24980
            return ret;
24981
        rawLen = (word32)ret + 1;
24982
        ret = 0;
24983
        if (output != NULL) {
24984
            tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
24985
                                 DYNAMIC_TYPE_RSA);
24986
            if (tmps[i] == NULL) {
24987
                ret = MEMORY_E;
24988
                break;
24989
            }
24990
        }
24991
24992
        mpSz = SetASNIntMP(keyInt, MAX_RSA_INT_SZ, tmps[i]);
24993
        if (mpSz < 0) {
24994
            ret = mpSz;
24995
            break;
24996
        }
24997
        sizes[i] = (word32)mpSz;
24998
        intTotalLen += (word32)mpSz;
24999
    }
25000
25001
    if (ret == 0) {
25002
        /* make headers */
25003
        ret = SetMyVersion(0, ver, FALSE);
25004
    }
25005
25006
    if (ret >= 0) {
25007
        verSz = (word32)ret;
25008
        ret = 0;
25009
        seqSz = SetSequence(verSz + intTotalLen, seq);
25010
        outLen = seqSz + verSz + intTotalLen;
25011
        if (output != NULL && outLen > inLen)
25012
            ret = BUFFER_E;
25013
    }
25014
    if (ret == 0 && output != NULL) {
25015
        word32 j;
25016
25017
        /* write to output */
25018
        XMEMCPY(output, seq, seqSz);
25019
        j = seqSz;
25020
        XMEMCPY(output + j, ver, verSz);
25021
        j += verSz;
25022
25023
        for (i = 0; i < RSA_INTS; i++) {
25024
            XMEMCPY(output + j, tmps[i], sizes[i]);
25025
            j += sizes[i];
25026
        }
25027
    }
25028
25029
    for (i = 0; i < RSA_INTS; i++) {
25030
        if (tmps[i])
25031
            XFREE(tmps[i], key->heap, DYNAMIC_TYPE_RSA);
25032
    }
25033
25034
    if (ret == 0)
25035
        ret = (int)outLen;
25036
    return ret;
25037
#else
25038
0
    DECL_ASNSETDATA(dataASN, rsaKeyASN_Length);
25039
0
    int i;
25040
0
    int sz = 0;
25041
0
    int ret = 0;
25042
25043
0
    if ((key == NULL) || (key->type != RSA_PRIVATE)) {
25044
0
        ret = BAD_FUNC_ARG;
25045
0
    }
25046
25047
0
    CALLOC_ASNSETDATA(dataASN, rsaKeyASN_Length, ret, key->heap);
25048
25049
0
    if (ret == 0) {
25050
        /* Set the version. */
25051
0
        SetASN_Int8Bit(&dataASN[RSAKEYASN_IDX_VER], 0);
25052
        /* Set all the mp_ints in private key. */
25053
0
        for (i = 0; i < RSA_INTS; i++) {
25054
0
            SetASN_MP(&dataASN[(byte)RSAKEYASN_IDX_N + i], GetRsaInt(key, i));
25055
0
        }
25056
25057
        /* Calculate size of RSA private key encoding. */
25058
0
        ret = SizeASN_Items(rsaKeyASN, dataASN, rsaKeyASN_Length, &sz);
25059
0
    }
25060
    /* Check output buffer has enough space for encoding. */
25061
0
    if ((ret == 0) && (output != NULL) && (sz > (int)inLen)) {
25062
0
        ret = BAD_FUNC_ARG;
25063
0
    }
25064
0
    if ((ret == 0) && (output != NULL)) {
25065
        /* Encode RSA private key. */
25066
0
        SetASN_Items(rsaKeyASN, dataASN, rsaKeyASN_Length, output);
25067
0
    }
25068
25069
0
    if (ret == 0) {
25070
        /* Return size of encoding. */
25071
0
        ret = sz;
25072
0
    }
25073
25074
0
    FREE_ASNSETDATA(dataASN, key->heap);
25075
0
    return ret;
25076
0
#endif
25077
0
}
25078
25079
#endif /* (WOLFSSL_KEY_GEN || OPENSSL_EXTRA) && !NO_RSA && !HAVE_USER_RSA */
25080
25081
25082
#ifdef WOLFSSL_CERT_GEN
25083
25084
/* Initialize and Set Certificate defaults:
25085
   version    = 3 (0x2)
25086
   serial     = 0
25087
   sigType    = SHA_WITH_RSA
25088
   issuer     = blank
25089
   daysValid  = 500
25090
   selfSigned = 1 (true) use subject as issuer
25091
   subject    = blank
25092
*/
25093
int wc_InitCert_ex(Cert* cert, void* heap, int devId)
25094
{
25095
#ifdef WOLFSSL_MULTI_ATTRIB
25096
    int i = 0;
25097
#endif
25098
    if (cert == NULL) {
25099
        return BAD_FUNC_ARG;
25100
    }
25101
25102
    XMEMSET(cert, 0, sizeof(Cert));
25103
25104
    cert->version    = 2;   /* version 3 is hex 2 */
25105
#ifndef NO_SHA
25106
    cert->sigType    = CTC_SHAwRSA;
25107
#elif !defined(NO_SHA256)
25108
    cert->sigType    = CTC_SHA256wRSA;
25109
#else
25110
    cert->sigType    = 0;
25111
#endif
25112
    cert->daysValid  = 500;
25113
    cert->selfSigned = 1;
25114
    cert->keyType    = RSA_KEY;
25115
25116
    cert->issuer.countryEnc = CTC_PRINTABLE;
25117
    cert->issuer.stateEnc = CTC_UTF8;
25118
    cert->issuer.streetEnc = CTC_UTF8;
25119
    cert->issuer.localityEnc = CTC_UTF8;
25120
    cert->issuer.surEnc = CTC_UTF8;
25121
#ifdef WOLFSSL_CERT_NAME_ALL
25122
    cert->issuer.givenNameEnc = CTC_UTF8;
25123
    cert->issuer.initialsEnc = CTC_UTF8;
25124
    cert->issuer.dnQualifierEnc = CTC_UTF8;
25125
    cert->issuer.dnNameEnc = CTC_UTF8;
25126
#endif
25127
    cert->issuer.orgEnc = CTC_UTF8;
25128
    cert->issuer.unitEnc = CTC_UTF8;
25129
    cert->issuer.commonNameEnc = CTC_UTF8;
25130
    cert->issuer.serialDevEnc = CTC_PRINTABLE;
25131
    cert->issuer.userIdEnc = CTC_UTF8;
25132
    cert->issuer.postalCodeEnc = CTC_UTF8;
25133
#ifdef WOLFSSL_CERT_EXT
25134
    cert->issuer.busCatEnc = CTC_UTF8;
25135
    cert->issuer.joiCEnc = CTC_UTF8;
25136
    cert->issuer.joiStEnc = CTC_UTF8;
25137
#endif
25138
25139
    cert->subject.countryEnc = CTC_PRINTABLE;
25140
    cert->subject.stateEnc = CTC_UTF8;
25141
    cert->subject.streetEnc = CTC_UTF8;
25142
    cert->subject.localityEnc = CTC_UTF8;
25143
    cert->subject.surEnc = CTC_UTF8;
25144
#ifdef WOLFSSL_CERT_NAME_ALL
25145
    cert->subject.givenNameEnc = CTC_UTF8;
25146
    cert->subject.initialsEnc = CTC_UTF8;
25147
    cert->subject.dnQualifierEnc = CTC_UTF8;
25148
    cert->subject.dnNameEnc = CTC_UTF8;
25149
#endif
25150
    cert->subject.orgEnc = CTC_UTF8;
25151
    cert->subject.unitEnc = CTC_UTF8;
25152
    cert->subject.commonNameEnc = CTC_UTF8;
25153
    cert->subject.serialDevEnc = CTC_PRINTABLE;
25154
    cert->subject.userIdEnc = CTC_UTF8;
25155
    cert->subject.postalCodeEnc = CTC_UTF8;
25156
#ifdef WOLFSSL_CERT_EXT
25157
    cert->subject.busCatEnc = CTC_UTF8;
25158
    cert->subject.joiCEnc = CTC_UTF8;
25159
    cert->subject.joiStEnc = CTC_UTF8;
25160
#endif
25161
25162
#ifdef WOLFSSL_MULTI_ATTRIB
25163
    for (i = 0; i < CTC_MAX_ATTRIB; i++) {
25164
        cert->issuer.name[i].type   = CTC_UTF8;
25165
        cert->subject.name[i].type  = CTC_UTF8;
25166
    }
25167
#endif /* WOLFSSL_MULTI_ATTRIB */
25168
25169
    cert->heap = heap;
25170
    (void)devId; /* future */
25171
25172
    return 0;
25173
}
25174
25175
WOLFSSL_ABI
25176
int wc_InitCert(Cert* cert)
25177
{
25178
    return wc_InitCert_ex(cert, NULL, INVALID_DEVID);
25179
}
25180
25181
WOLFSSL_ABI
25182
Cert* wc_CertNew(void* heap)
25183
{
25184
    Cert* certNew;
25185
25186
    certNew = (Cert*)XMALLOC(sizeof(Cert), heap, DYNAMIC_TYPE_CERT);
25187
25188
    if (certNew) {
25189
        if (wc_InitCert_ex(certNew, heap, INVALID_DEVID) != 0) {
25190
            XFREE(certNew, heap, DYNAMIC_TYPE_CERT);
25191
            certNew = NULL;
25192
        }
25193
    }
25194
25195
    return certNew;
25196
}
25197
25198
WOLFSSL_ABI
25199
void  wc_CertFree(Cert* cert)
25200
{
25201
    if (cert) {
25202
         void* heap = cert->heap;
25203
25204
         ForceZero(cert, sizeof(Cert));
25205
         XFREE(cert, heap, DYNAMIC_TYPE_CERT);
25206
         (void)heap;
25207
     }
25208
}
25209
25210
/* DER encoded x509 Certificate */
25211
typedef struct DerCert {
25212
    byte size[MAX_LENGTH_SZ];          /* length encoded */
25213
    byte version[MAX_VERSION_SZ];      /* version encoded */
25214
    byte serial[(int)CTC_SERIAL_SIZE + (int)MAX_LENGTH_SZ]; /* serial number encoded */
25215
    byte sigAlgo[MAX_ALGO_SZ];         /* signature algo encoded */
25216
    byte issuer[WC_ASN_NAME_MAX];         /* issuer  encoded */
25217
    byte subject[WC_ASN_NAME_MAX];        /* subject encoded */
25218
    byte validity[MAX_DATE_SIZE*2 + MAX_SEQ_SZ*2];  /* before and after dates */
25219
    byte publicKey[MAX_PUBLIC_KEY_SZ]; /* rsa public key encoded */
25220
    byte ca[MAX_CA_SZ];                /* basic constraint CA true size */
25221
    byte extensions[MAX_EXTENSIONS_SZ]; /* all extensions */
25222
#ifdef WOLFSSL_CERT_EXT
25223
    byte skid[MAX_KID_SZ];             /* Subject Key Identifier extension */
25224
    byte akid[MAX_KID_SZ
25225
#ifdef WOLFSSL_AKID_NAME
25226
              + sizeof(CertName) + CTC_SERIAL_SIZE
25227
#endif
25228
              ]; /* Authority Key Identifier extension */
25229
    byte keyUsage[MAX_KEYUSAGE_SZ];    /* Key Usage extension */
25230
    byte extKeyUsage[MAX_EXTKEYUSAGE_SZ]; /* Extended Key Usage extension */
25231
#ifndef IGNORE_NETSCAPE_CERT_TYPE
25232
    byte nsCertType[MAX_NSCERTTYPE_SZ]; /* Extended Key Usage extension */
25233
#endif
25234
    byte certPolicies[MAX_CERTPOL_NB*MAX_CERTPOL_SZ]; /* Certificate Policies */
25235
    byte crlInfo[CTC_MAX_CRLINFO_SZ];  /* CRL Distribution Points */
25236
#endif
25237
#ifdef WOLFSSL_CERT_REQ
25238
    byte attrib[MAX_ATTRIB_SZ];        /* Cert req attributes encoded */
25239
    #ifdef WOLFSSL_CUSTOM_OID
25240
    byte extCustom[MAX_ATTRIB_SZ];     /* Encoded user oid and value */
25241
    #endif
25242
#endif
25243
#ifdef WOLFSSL_ALT_NAMES
25244
    byte altNames[CTC_MAX_ALT_SIZE];   /* Alternative Names encoded */
25245
#endif
25246
    int  sizeSz;                       /* encoded size length */
25247
    int  versionSz;                    /* encoded version length */
25248
    int  serialSz;                     /* encoded serial length */
25249
    int  sigAlgoSz;                    /* encoded sig algo length */
25250
    int  issuerSz;                     /* encoded issuer length */
25251
    int  subjectSz;                    /* encoded subject length */
25252
    int  validitySz;                   /* encoded validity length */
25253
    int  publicKeySz;                  /* encoded public key length */
25254
    int  caSz;                         /* encoded CA extension length */
25255
#ifdef WOLFSSL_CERT_EXT
25256
    int  skidSz;                       /* encoded SKID extension length */
25257
    int  akidSz;                       /* encoded SKID extension length */
25258
    int  keyUsageSz;                   /* encoded KeyUsage extension length */
25259
    int  extKeyUsageSz;                /* encoded ExtendedKeyUsage extension length */
25260
#ifndef IGNORE_NETSCAPE_CERT_TYPE
25261
    int  nsCertTypeSz;                 /* encoded Netscape Certifcate Type
25262
                                        * extension length */
25263
#endif
25264
    int  certPoliciesSz;               /* encoded CertPolicies extension length*/
25265
    int  crlInfoSz;                    /* encoded CRL Dist Points length */
25266
#endif
25267
#ifdef WOLFSSL_ALT_NAMES
25268
    int  altNamesSz;                   /* encoded AltNames extension length */
25269
#endif
25270
    int  extensionsSz;                 /* encoded extensions total length */
25271
    int  total;                        /* total encoded lengths */
25272
#ifdef WOLFSSL_CERT_REQ
25273
    int  attribSz;
25274
    #ifdef WOLFSSL_CUSTOM_OID
25275
    int  extCustomSz;
25276
    #endif
25277
#endif
25278
} DerCert;
25279
25280
25281
#ifdef WOLFSSL_CERT_REQ
25282
#ifndef WOLFSSL_ASN_TEMPLATE
25283
25284
/* Write a set header to output */
25285
static word32 SetPrintableString(word32 len, byte* output)
25286
{
25287
    output[0] = ASN_PRINTABLE_STRING;
25288
    return SetLength(len, output + 1) + 1;
25289
}
25290
25291
static word32 SetUTF8String(word32 len, byte* output)
25292
{
25293
    output[0] = ASN_UTF8STRING;
25294
    return SetLength(len, output + 1) + 1;
25295
}
25296
25297
#endif
25298
#endif /* WOLFSSL_CERT_REQ */
25299
25300
25301
#ifndef WOLFSSL_CERT_GEN_CACHE
25302
/* wc_SetCert_Free is only public when WOLFSSL_CERT_GEN_CACHE is not defined */
25303
static
25304
#endif
25305
WOLFSSL_ABI
25306
void wc_SetCert_Free(Cert* cert)
25307
{
25308
    if (cert != NULL) {
25309
        cert->der = NULL;
25310
        if (cert->decodedCert) {
25311
            FreeDecodedCert((DecodedCert*)cert->decodedCert);
25312
25313
            XFREE(cert->decodedCert, cert->heap, DYNAMIC_TYPE_DCERT);
25314
            cert->decodedCert = NULL;
25315
        }
25316
    }
25317
}
25318
25319
static int wc_SetCert_LoadDer(Cert* cert, const byte* der, word32 derSz,
25320
    int devId)
25321
{
25322
    int ret;
25323
25324
    if (cert == NULL) {
25325
        ret = BAD_FUNC_ARG;
25326
    }
25327
    else {
25328
        /* Allocate DecodedCert struct and Zero */
25329
        cert->decodedCert = (void*)XMALLOC(sizeof(DecodedCert), cert->heap,
25330
            DYNAMIC_TYPE_DCERT);
25331
25332
        if (cert->decodedCert == NULL) {
25333
            ret = MEMORY_E;
25334
        }
25335
        else {
25336
            XMEMSET(cert->decodedCert, 0, sizeof(DecodedCert));
25337
25338
            InitDecodedCert_ex((DecodedCert*)cert->decodedCert, der, derSz,
25339
                    cert->heap, devId);
25340
            ret = ParseCertRelative((DecodedCert*)cert->decodedCert,
25341
                    CERT_TYPE, 0, NULL);
25342
            if (ret >= 0) {
25343
                cert->der = (byte*)der;
25344
            }
25345
            else {
25346
                wc_SetCert_Free(cert);
25347
            }
25348
        }
25349
    }
25350
25351
    return ret;
25352
}
25353
25354
#endif /* WOLFSSL_CERT_GEN */
25355
25356
#ifdef WOLFSSL_CERT_GEN
25357
25358
#ifndef NO_ASN_TIME
25359
static WC_INLINE byte itob(int number)
25360
{
25361
    return (byte)number + 0x30;
25362
}
25363
25364
25365
/* write time to output, format */
25366
static void SetTime(struct tm* date, byte* output)
25367
{
25368
    int i = 0;
25369
25370
    output[i++] = itob((date->tm_year % 10000) / 1000);
25371
    output[i++] = itob((date->tm_year % 1000)  /  100);
25372
    output[i++] = itob((date->tm_year % 100)   /   10);
25373
    output[i++] = itob( date->tm_year % 10);
25374
25375
    output[i++] = itob(date->tm_mon / 10);
25376
    output[i++] = itob(date->tm_mon % 10);
25377
25378
    output[i++] = itob(date->tm_mday / 10);
25379
    output[i++] = itob(date->tm_mday % 10);
25380
25381
    output[i++] = itob(date->tm_hour / 10);
25382
    output[i++] = itob(date->tm_hour % 10);
25383
25384
    output[i++] = itob(date->tm_min / 10);
25385
    output[i++] = itob(date->tm_min % 10);
25386
25387
    output[i++] = itob(date->tm_sec / 10);
25388
    output[i++] = itob(date->tm_sec % 10);
25389
25390
    output[i] = 'Z';  /* Zulu profile */
25391
}
25392
#endif
25393
25394
#ifndef WOLFSSL_ASN_TEMPLATE
25395
25396
/* Copy Dates from cert, return bytes written */
25397
static int CopyValidity(byte* output, Cert* cert)
25398
{
25399
    word32 seqSz;
25400
25401
    WOLFSSL_ENTER("CopyValidity");
25402
25403
    /* headers and output */
25404
    seqSz = SetSequence((word32)(cert->beforeDateSz + cert->afterDateSz),
25405
                        output);
25406
    if (output) {
25407
        XMEMCPY(output + seqSz, cert->beforeDate, (size_t)cert->beforeDateSz);
25408
        XMEMCPY(output + seqSz + cert->beforeDateSz, cert->afterDate,
25409
                (size_t)cert->afterDateSz);
25410
    }
25411
    return (int)seqSz + cert->beforeDateSz + cert->afterDateSz;
25412
}
25413
25414
#endif /* !WOLFSSL_ASN_TEMPLATE */
25415
25416
25417
/* Simple name OID size. */
25418
#define NAME_OID_SZ     3
25419
25420
/* Domain name OIDs. */
25421
static const byte nameOid[][NAME_OID_SZ] = {
25422
    { 0x55, 0x04, ASN_COUNTRY_NAME },
25423
    { 0x55, 0x04, ASN_STATE_NAME },
25424
    { 0x55, 0x04, ASN_STREET_ADDR },
25425
    { 0x55, 0x04, ASN_LOCALITY_NAME },
25426
#ifdef WOLFSSL_CERT_NAME_ALL
25427
    { 0x55, 0x04, ASN_NAME },
25428
    { 0x55, 0x04, ASN_GIVEN_NAME },
25429
    { 0x55, 0x04, ASN_INITIALS },
25430
    { 0x55, 0x04, ASN_DNQUALIFIER },
25431
#endif
25432
    { 0x55, 0x04, ASN_SUR_NAME },
25433
    { 0x55, 0x04, ASN_ORG_NAME },
25434
    { 0x00, 0x00, ASN_DOMAIN_COMPONENT}, /* not actual OID - see dcOid */
25435
                                         /* list all DC values before OUs */
25436
    { 0x55, 0x04, ASN_ORGUNIT_NAME },
25437
    { 0x55, 0x04, ASN_COMMON_NAME },
25438
    { 0x55, 0x04, ASN_SERIAL_NUMBER },
25439
#ifdef WOLFSSL_CERT_EXT
25440
    { 0x55, 0x04, ASN_BUS_CAT },
25441
#endif
25442
    { 0x55, 0x04, ASN_POSTAL_CODE },
25443
    { 0x00, 0x00, ASN_EMAIL_NAME},       /* not actual OID - see attrEmailOid */
25444
    { 0x00, 0x00, ASN_USER_ID},          /* not actual OID - see uidOid */
25445
#ifdef WOLFSSL_CUSTOM_OID
25446
    { 0x00, 0x00, ASN_CUSTOM_NAME} /* OID comes from CertOidField */
25447
#endif
25448
};
25449
#define NAME_ENTRIES (int)(sizeof(nameOid)/NAME_OID_SZ)
25450
25451
25452
/* Get ASN Name from index */
25453
byte GetCertNameId(int idx)
25454
{
25455
    if (idx < NAME_ENTRIES)
25456
        return nameOid[idx][2];
25457
    return 0;
25458
}
25459
25460
/* Get Which Name from index */
25461
const char* GetOneCertName(CertName* name, int idx)
25462
{
25463
    byte type = GetCertNameId(idx);
25464
    switch (type) {
25465
    case ASN_COUNTRY_NAME:
25466
       return name->country;
25467
    case ASN_STATE_NAME:
25468
       return name->state;
25469
    case ASN_STREET_ADDR:
25470
       return name->street;
25471
    case ASN_LOCALITY_NAME:
25472
       return name->locality;
25473
#ifdef WOLFSSL_CERT_NAME_ALL
25474
    case ASN_NAME:
25475
       return name->dnName;
25476
    case ASN_GIVEN_NAME:
25477
       return name->givenName;
25478
    case ASN_INITIALS:
25479
       return name->initials;
25480
    case ASN_DNQUALIFIER:
25481
       return name->dnQualifier;
25482
#endif /* WOLFSSL_CERT_NAME_ALL */
25483
    case ASN_SUR_NAME:
25484
       return name->sur;
25485
    case ASN_ORG_NAME:
25486
       return name->org;
25487
    case ASN_ORGUNIT_NAME:
25488
       return name->unit;
25489
    case ASN_COMMON_NAME:
25490
       return name->commonName;
25491
    case ASN_SERIAL_NUMBER:
25492
       return name->serialDev;
25493
    case ASN_USER_ID:
25494
       return name->userId;
25495
    case ASN_POSTAL_CODE:
25496
       return name->postalCode;
25497
    case ASN_EMAIL_NAME:
25498
       return name->email;
25499
#ifdef WOLFSSL_CERT_EXT
25500
    case ASN_BUS_CAT:
25501
       return name->busCat;
25502
#endif
25503
#ifdef WOLFSSL_CUSTOM_OID
25504
    case ASN_CUSTOM_NAME:
25505
        return (const char*)name->custom.val;
25506
#endif
25507
    default:
25508
       return NULL;
25509
    }
25510
}
25511
25512
25513
/* Get Which Name Encoding from index */
25514
static char GetNameType(CertName* name, int idx)
25515
{
25516
    byte type = GetCertNameId(idx);
25517
    switch (type) {
25518
    case ASN_COUNTRY_NAME:
25519
       return name->countryEnc;
25520
    case ASN_STATE_NAME:
25521
       return name->stateEnc;
25522
    case ASN_STREET_ADDR:
25523
       return name->streetEnc;
25524
    case ASN_LOCALITY_NAME:
25525
       return name->localityEnc;
25526
#ifdef WOLFSSL_CERT_NAME_ALL
25527
    case ASN_NAME:
25528
       return name->dnNameEnc;
25529
    case ASN_GIVEN_NAME:
25530
       return name->givenNameEnc;
25531
    case ASN_INITIALS:
25532
       return name->initialsEnc;
25533
    case ASN_DNQUALIFIER:
25534
       return name->dnQualifierEnc;
25535
#endif /* WOLFSSL_CERT_NAME_ALL */
25536
    case ASN_SUR_NAME:
25537
       return name->surEnc;
25538
    case ASN_ORG_NAME:
25539
       return name->orgEnc;
25540
    case ASN_ORGUNIT_NAME:
25541
       return name->unitEnc;
25542
    case ASN_COMMON_NAME:
25543
       return name->commonNameEnc;
25544
    case ASN_SERIAL_NUMBER:
25545
       return name->serialDevEnc;
25546
    case ASN_USER_ID:
25547
       return name->userIdEnc;
25548
    case ASN_POSTAL_CODE:
25549
       return name->postalCodeEnc;
25550
    case ASN_EMAIL_NAME:
25551
       return 0; /* special */
25552
#ifdef WOLFSSL_CERT_EXT
25553
    case ASN_BUS_CAT:
25554
       return name->busCatEnc;
25555
#endif
25556
#ifdef WOLFSSL_CUSTOM_OID
25557
    case ASN_CUSTOM_NAME:
25558
        return name->custom.enc;
25559
#endif
25560
    default:
25561
       return 0;
25562
    }
25563
}
25564
25565
#ifndef WOLFSSL_ASN_TEMPLATE
25566
/*
25567
 Extensions ::= SEQUENCE OF Extension
25568
25569
 Extension ::= SEQUENCE {
25570
 extnId     OBJECT IDENTIFIER,
25571
 critical   BOOLEAN DEFAULT FALSE,
25572
 extnValue  OCTET STRING }
25573
 */
25574
25575
/* encode all extensions, return total bytes written */
25576
static int SetExtensions(byte* out, word32 outSz, int *IdxInOut,
25577
                         const byte* ext, int extSz)
25578
{
25579
    if (out == NULL || IdxInOut == NULL || ext == NULL)
25580
        return BAD_FUNC_ARG;
25581
25582
    if (outSz < (word32)(*IdxInOut+extSz))
25583
        return BUFFER_E;
25584
25585
    XMEMCPY(&out[*IdxInOut], ext, (size_t)extSz);  /* extensions */
25586
    *IdxInOut += extSz;
25587
25588
    return *IdxInOut;
25589
}
25590
25591
/* encode extensions header, return total bytes written */
25592
static int SetExtensionsHeader(byte* out, word32 outSz, word32 extSz)
25593
{
25594
    byte sequence[MAX_SEQ_SZ];
25595
    byte len[MAX_LENGTH_SZ];
25596
    word32 seqSz, lenSz, idx = 0;
25597
25598
    if (out == NULL)
25599
        return BAD_FUNC_ARG;
25600
25601
    if (outSz < 3)
25602
        return BUFFER_E;
25603
25604
    seqSz = SetSequence(extSz, sequence);
25605
25606
    /* encode extensions length provided */
25607
    lenSz = SetLength(extSz+seqSz, len);
25608
25609
    if (outSz < (word32)(lenSz+seqSz+1))
25610
        return BUFFER_E;
25611
25612
    out[idx++] = ASN_EXTENSIONS; /* extensions id */
25613
    XMEMCPY(&out[idx], len, lenSz);  /* length */
25614
    idx += lenSz;
25615
25616
    XMEMCPY(&out[idx], sequence, seqSz);  /* sequence */
25617
    idx += seqSz;
25618
25619
    return (int)idx;
25620
}
25621
25622
25623
/* encode CA basic constraints true with path length
25624
 * return total bytes written */
25625
static int SetCaWithPathLen(byte* out, word32 outSz, byte pathLen)
25626
{
25627
    /* ASN1->DER sequence for Basic Constraints True and path length */
25628
    const byte caPathLenBasicConstASN1[] = {
25629
        0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x04,
25630
        0x08, 0x30, 0x06, 0x01, 0x01, 0xFF, 0x02, 0x01,
25631
        0x00
25632
    };
25633
25634
    if (out == NULL)
25635
        return BAD_FUNC_ARG;
25636
25637
    if (outSz < sizeof(caPathLenBasicConstASN1))
25638
        return BUFFER_E;
25639
25640
    XMEMCPY(out, caPathLenBasicConstASN1, sizeof(caPathLenBasicConstASN1));
25641
25642
    out[sizeof(caPathLenBasicConstASN1)-1] = pathLen;
25643
25644
    return (int)sizeof(caPathLenBasicConstASN1);
25645
}
25646
25647
25648
/* encode CA basic constraints true
25649
 * return total bytes written */
25650
static int SetCa(byte* out, word32 outSz)
25651
{
25652
    /* ASN1->DER sequence for Basic Constraints True */
25653
    const byte caBasicConstASN1[] = {
25654
        0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,
25655
        0x05, 0x30, 0x03, 0x01, 0x01, 0xff
25656
    };
25657
25658
    if (out == NULL)
25659
        return BAD_FUNC_ARG;
25660
25661
    if (outSz < sizeof(caBasicConstASN1))
25662
        return BUFFER_E;
25663
25664
    XMEMCPY(out, caBasicConstASN1, sizeof(caBasicConstASN1));
25665
25666
    return (int)sizeof(caBasicConstASN1);
25667
}
25668
25669
/* encode basic constraints without CA Boolean
25670
 * return total bytes written */
25671
static int SetBC(byte* out, word32 outSz)
25672
{
25673
    /* ASN1->DER sequence for Basic Constraint without CA Boolean */
25674
 const byte BasicConstASN1[] = {
25675
        0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,
25676
        0x02, 0x30, 0x00
25677
    };
25678
25679
    if (out == NULL)
25680
        return BAD_FUNC_ARG;
25681
25682
    if (outSz < sizeof(BasicConstASN1))
25683
        return BUFFER_E;
25684
25685
    XMEMCPY(out, BasicConstASN1, sizeof(BasicConstASN1));
25686
25687
    return (int)sizeof(BasicConstASN1);
25688
}
25689
#endif
25690
25691
25692
#ifdef WOLFSSL_CERT_EXT
25693
#ifndef WOLFSSL_ASN_TEMPLATE
25694
/* encode OID and associated value, return total bytes written */
25695
static int SetOidValue(byte* out, word32 outSz, const byte *oid, word32 oidSz,
25696
                       byte *in, word32 inSz)
25697
{
25698
    word32 idx = 0;
25699
25700
    if (out == NULL || oid == NULL || in == NULL)
25701
        return BAD_FUNC_ARG;
25702
25703
    if (outSz < 3)
25704
        return BUFFER_E;
25705
25706
    /* sequence,  + 1 => byte to put value size */
25707
    idx = SetSequence(inSz + oidSz + 1, out);
25708
25709
    if ((idx + inSz + oidSz + 1) > outSz)
25710
        return BUFFER_E;
25711
25712
    XMEMCPY(out+idx, oid, oidSz);
25713
    idx += oidSz;
25714
    out[idx++] = (byte)inSz;
25715
    XMEMCPY(out+idx, in, inSz);
25716
25717
    return (int)(idx+inSz);
25718
}
25719
25720
/* encode Subject Key Identifier, return total bytes written
25721
 * RFC5280 : non-critical */
25722
static int SetSKID(byte* output, word32 outSz, const byte *input, word32 length)
25723
{
25724
    byte skid_len[1 + MAX_LENGTH_SZ];
25725
    byte skid_enc_len[MAX_LENGTH_SZ];
25726
    word32 idx = 0, skid_lenSz, skid_enc_lenSz;
25727
    const byte skid_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04 };
25728
25729
    if (output == NULL || input == NULL)
25730
        return BAD_FUNC_ARG;
25731
25732
    /* Octet String header */
25733
    skid_lenSz = SetOctetString(length, skid_len);
25734
25735
    /* length of encoded value */
25736
    skid_enc_lenSz = SetLength(length + skid_lenSz, skid_enc_len);
25737
25738
    if (outSz < 3)
25739
        return BUFFER_E;
25740
25741
    idx = SetSequence(length + (word32)sizeof(skid_oid) + skid_lenSz +
25742
                      skid_enc_lenSz, output);
25743
25744
    if ((length + sizeof(skid_oid) + skid_lenSz + skid_enc_lenSz) > outSz)
25745
        return BUFFER_E;
25746
25747
    /* put oid */
25748
    XMEMCPY(output+idx, skid_oid, sizeof(skid_oid));
25749
    idx += sizeof(skid_oid);
25750
25751
    /* put encoded len */
25752
    XMEMCPY(output+idx, skid_enc_len, skid_enc_lenSz);
25753
    idx += skid_enc_lenSz;
25754
25755
    /* put octet header */
25756
    XMEMCPY(output+idx, skid_len, skid_lenSz);
25757
    idx += skid_lenSz;
25758
25759
    /* put value */
25760
    XMEMCPY(output+idx, input, length);
25761
    idx += length;
25762
25763
    return (int)idx;
25764
}
25765
25766
/* encode Authority Key Identifier, return total bytes written
25767
 * RFC5280 : non-critical */
25768
static int SetAKID(byte* output, word32 outSz, byte *input, word32 length,
25769
                   byte rawAkid)
25770
{
25771
    int     enc_valSz;
25772
    byte enc_val_buf[MAX_KID_SZ];
25773
    byte* enc_val;
25774
    const byte akid_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x23 };
25775
    const byte akid_cs[] = { 0x80 };
25776
    word32 inSeqSz, idx;
25777
25778
    (void)rawAkid;
25779
25780
    if (output == NULL || input == NULL)
25781
        return BAD_FUNC_ARG;
25782
25783
#ifdef WOLFSSL_AKID_NAME
25784
    if (rawAkid) {
25785
        enc_val = input;
25786
        enc_valSz = length;
25787
    }
25788
    else
25789
#endif
25790
    {
25791
        enc_val = enc_val_buf;
25792
        enc_valSz = (int)length + 3 + (int)sizeof(akid_cs);
25793
        if (enc_valSz > (int)sizeof(enc_val_buf))
25794
            return BAD_FUNC_ARG;
25795
25796
        /* sequence for ContentSpec & value */
25797
        enc_valSz = SetOidValue(enc_val, (word32)enc_valSz, akid_cs,
25798
                                sizeof(akid_cs), input, length);
25799
        if (enc_valSz <= 0)
25800
            return enc_valSz;
25801
    }
25802
25803
    /* The size of the extension sequence contents */
25804
    inSeqSz = (word32)sizeof(akid_oid) +
25805
        SetOctetString((word32)enc_valSz, NULL) + (word32)enc_valSz;
25806
25807
    if (SetSequence(inSeqSz, NULL) + inSeqSz > outSz)
25808
        return BAD_FUNC_ARG;
25809
25810
    /* Write out the sequence header */
25811
    idx = SetSequence(inSeqSz, output);
25812
25813
    /* Write out OID */
25814
    XMEMCPY(output + idx, akid_oid, sizeof(akid_oid));
25815
    idx += sizeof(akid_oid);
25816
25817
    /* Write out AKID */
25818
    idx += SetOctetString((word32)enc_valSz, output + idx);
25819
    XMEMCPY(output + idx, enc_val, (size_t)enc_valSz);
25820
25821
    return (int)idx + enc_valSz;
25822
}
25823
25824
/* encode Key Usage, return total bytes written
25825
 * RFC5280 : critical */
25826
static int SetKeyUsage(byte* output, word32 outSz, word16 input)
25827
{
25828
    byte ku[5];
25829
    word32 idx;
25830
    const byte keyusage_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x0f,
25831
                                         0x01, 0x01, 0xff, 0x04};
25832
    if (output == NULL)
25833
        return BAD_FUNC_ARG;
25834
25835
    idx = SetBitString16Bit(input, ku);
25836
    return SetOidValue(output, outSz, keyusage_oid, sizeof(keyusage_oid),
25837
                       ku, idx);
25838
}
25839
25840
static int SetOjectIdValue(byte* output, word32 outSz, word32* idx,
25841
    const byte* oid, word32 oidSz)
25842
{
25843
    /* verify room */
25844
    if (*idx + 2 + oidSz >= outSz)
25845
        return ASN_PARSE_E;
25846
25847
    *idx += (word32)SetObjectId((int)oidSz, &output[*idx]);
25848
    XMEMCPY(&output[*idx], oid, oidSz);
25849
    *idx += oidSz;
25850
25851
    return 0;
25852
}
25853
#endif
25854
25855
#ifdef WOLFSSL_ASN_TEMPLATE
25856
/* ASN.1 template for extended key usage.
25857
 * X.509: RFC 5280, 4.2.12 - Extended Key Usage
25858
 * Dynamic creation of template for encoding.
25859
 */
25860
static const ASNItem ekuASN[] = {
25861
/* SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 },
25862
/* OID */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
25863
};
25864
enum {
25865
    EKUASN_IDX_SEQ = 0,
25866
    EKUASN_IDX_OID
25867
};
25868
25869
/* OIDs corresponding to extended key usage. */
25870
struct {
25871
    const byte* oid;
25872
    word32 oidSz;
25873
} ekuOid[] = {
25874
    { extExtKeyUsageServerAuthOid,   sizeof(extExtKeyUsageServerAuthOid) },
25875
    { extExtKeyUsageClientAuthOid,   sizeof(extExtKeyUsageClientAuthOid) },
25876
    { extExtKeyUsageCodeSigningOid,  sizeof(extExtKeyUsageCodeSigningOid) },
25877
    { extExtKeyUsageEmailProtectOid, sizeof(extExtKeyUsageEmailProtectOid) },
25878
    { extExtKeyUsageTimestampOid,    sizeof(extExtKeyUsageTimestampOid) },
25879
    { extExtKeyUsageOcspSignOid,     sizeof(extExtKeyUsageOcspSignOid) },
25880
};
25881
25882
#define EKU_OID_LO      1
25883
#define EKU_OID_HI      6
25884
#endif /* WOLFSSL_ASN_TEMPLATE */
25885
25886
/* encode Extended Key Usage (RFC 5280 4.2.1.12), return total bytes written */
25887
static int SetExtKeyUsage(Cert* cert, byte* output, word32 outSz, byte input)
25888
{
25889
#ifndef WOLFSSL_ASN_TEMPLATE
25890
    word32 idx = 0, oidListSz = 0, totalSz;
25891
    int ret = 0;
25892
    const byte extkeyusage_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x25 };
25893
25894
    if (output == NULL)
25895
        return BAD_FUNC_ARG;
25896
25897
    /* Skip to OID List */
25898
    totalSz = 2 + sizeof(extkeyusage_oid) + 4;
25899
    idx = totalSz;
25900
25901
    /* Build OID List */
25902
    /* If any set, then just use it */
25903
    if (input & EXTKEYUSE_ANY) {
25904
        ret |= SetOjectIdValue(output, outSz, &idx,
25905
            extExtKeyUsageAnyOid, sizeof(extExtKeyUsageAnyOid));
25906
    }
25907
    else {
25908
        if (input & EXTKEYUSE_SERVER_AUTH)
25909
            ret |= SetOjectIdValue(output, outSz, &idx,
25910
                extExtKeyUsageServerAuthOid, sizeof(extExtKeyUsageServerAuthOid));
25911
        if (input & EXTKEYUSE_CLIENT_AUTH)
25912
            ret |= SetOjectIdValue(output, outSz, &idx,
25913
                extExtKeyUsageClientAuthOid, sizeof(extExtKeyUsageClientAuthOid));
25914
        if (input & EXTKEYUSE_CODESIGN)
25915
            ret |= SetOjectIdValue(output, outSz, &idx,
25916
                extExtKeyUsageCodeSigningOid, sizeof(extExtKeyUsageCodeSigningOid));
25917
        if (input & EXTKEYUSE_EMAILPROT)
25918
            ret |= SetOjectIdValue(output, outSz, &idx,
25919
                extExtKeyUsageEmailProtectOid, sizeof(extExtKeyUsageEmailProtectOid));
25920
        if (input & EXTKEYUSE_TIMESTAMP)
25921
            ret |= SetOjectIdValue(output, outSz, &idx,
25922
                extExtKeyUsageTimestampOid, sizeof(extExtKeyUsageTimestampOid));
25923
        if (input & EXTKEYUSE_OCSP_SIGN)
25924
            ret |= SetOjectIdValue(output, outSz, &idx,
25925
                extExtKeyUsageOcspSignOid, sizeof(extExtKeyUsageOcspSignOid));
25926
    #ifdef WOLFSSL_EKU_OID
25927
        /* iterate through OID values */
25928
        if (input & EXTKEYUSE_USER) {
25929
            int i, sz;
25930
            for (i = 0; i < CTC_MAX_EKU_NB; i++) {
25931
                sz = cert->extKeyUsageOIDSz[i];
25932
                if (sz > 0) {
25933
                    ret |= SetOjectIdValue(output, outSz, &idx,
25934
                        cert->extKeyUsageOID[i], sz);
25935
                }
25936
            }
25937
        }
25938
    #endif /* WOLFSSL_EKU_OID */
25939
    }
25940
    if (ret != 0)
25941
        return ASN_PARSE_E;
25942
25943
    /* Calculate Sizes */
25944
    oidListSz = idx - totalSz;
25945
    totalSz = idx - 2; /* exclude first seq/len (2) */
25946
25947
    /* 1. Seq + Total Len (2) */
25948
    idx = SetSequence(totalSz, output);
25949
25950
    /* 2. Object ID (2) */
25951
    XMEMCPY(&output[idx], extkeyusage_oid, sizeof(extkeyusage_oid));
25952
    idx += sizeof(extkeyusage_oid);
25953
25954
    /* 3. Octet String (2) */
25955
    idx += SetOctetString(totalSz - idx, &output[idx]);
25956
25957
    /* 4. Seq + OidListLen (2) */
25958
    idx += SetSequence(oidListSz, &output[idx]);
25959
25960
    /* 5. Oid List (already set in-place above) */
25961
    idx += oidListSz;
25962
25963
    (void)cert;
25964
    return (int)idx;
25965
#else
25966
    /* TODO: consider calculating size of OBJECT_IDs, setting length into
25967
     * SEQUENCE, encode SEQUENCE, encode OBJECT_IDs into buffer.  */
25968
    ASNSetData* dataASN;
25969
    ASNItem* extKuASN = NULL;
25970
    int asnIdx = 1;
25971
    size_t cnt = 1 + EKU_OID_HI;
25972
    int i;
25973
    int ret = 0;
25974
    int sz = 0;
25975
25976
#ifdef WOLFSSL_EKU_OID
25977
    cnt += CTC_MAX_EKU_NB;
25978
#endif
25979
25980
    /* Allocate memory for dynamic data items. */
25981
    dataASN = (ASNSetData*)XMALLOC(cnt * sizeof(ASNSetData), cert->heap,
25982
                                                       DYNAMIC_TYPE_TMP_BUFFER);
25983
    if (dataASN == NULL) {
25984
        ret = MEMORY_E;
25985
    }
25986
    if (ret == 0) {
25987
        /* Allocate memory for dynamic ASN.1 template. */
25988
        extKuASN = (ASNItem*)XMALLOC(cnt * sizeof(ASNItem), cert->heap,
25989
                                                       DYNAMIC_TYPE_TMP_BUFFER);
25990
        if (extKuASN == NULL) {
25991
            ret = MEMORY_E;
25992
        }
25993
    }
25994
25995
    if (ret == 0) {
25996
        /* Copy Sequence into dynamic ASN.1 template. */
25997
        XMEMCPY(&extKuASN[EKUASN_IDX_SEQ], ekuASN, sizeof(ASNItem));
25998
        /* Clear dynamic data. */
25999
        XMEMSET(dataASN, 0, cnt * sizeof(ASNSetData));
26000
26001
        /* Build up the template and data. */
26002
        /* If 'any' set, then just use it. */
26003
        if ((input & EXTKEYUSE_ANY) == EXTKEYUSE_ANY) {
26004
            /* Set template item. */
26005
            XMEMCPY(&extKuASN[EKUASN_IDX_OID], &ekuASN[EKUASN_IDX_OID],
26006
                    sizeof(ASNItem));
26007
            /* Set data item. */
26008
            SetASN_Buffer(&dataASN[asnIdx], extExtKeyUsageAnyOid,
26009
                sizeof(extExtKeyUsageAnyOid));
26010
            asnIdx++;
26011
        }
26012
        else {
26013
            /* Step through the flagged purposes. */
26014
            for (i = EKU_OID_LO; i <= EKU_OID_HI; i++) {
26015
                if ((input & (1 << i)) != 0) {
26016
                    /* Set template item. */
26017
                    XMEMCPY(&extKuASN[asnIdx], &ekuASN[EKUASN_IDX_OID],
26018
                            sizeof(ASNItem));
26019
                    /* Set data item. */
26020
                    SetASN_Buffer(&dataASN[asnIdx], ekuOid[i - 1].oid,
26021
                        ekuOid[i - 1].oidSz);
26022
                    asnIdx++;
26023
                }
26024
            }
26025
        #ifdef WOLFSSL_EKU_OID
26026
            if (input & EXTKEYUSE_USER) {
26027
                /* Iterate through OID values */
26028
                for (i = 0; i < CTC_MAX_EKU_NB; i++) {
26029
                    sz = cert->extKeyUsageOIDSz[i];
26030
                    if (sz > 0) {
26031
                        /* Set template item. */
26032
                        XMEMCPY(&extKuASN[asnIdx], &ekuASN[EKUASN_IDX_OID],
26033
                                sizeof(ASNItem));
26034
                        /* Set data item. */
26035
                        SetASN_Buffer(&dataASN[asnIdx], cert->extKeyUsageOID[i],
26036
                            sz);
26037
                        asnIdx++;
26038
                    }
26039
                }
26040
            }
26041
        #endif /* WOLFSSL_EKU_OID */
26042
            (void)cert;
26043
        }
26044
26045
        /* Calculate size of encoding. */
26046
        sz = 0;
26047
        ret = SizeASN_Items(extKuASN, dataASN, asnIdx, &sz);
26048
    }
26049
    /* When buffer to write to, ensure it's big enough. */
26050
    if ((ret == 0) && (output != NULL) && (sz > (int)outSz)) {
26051
        ret = BUFFER_E;
26052
    }
26053
    if ((ret == 0) && (output != NULL)) {
26054
        /* Encode extended key usage. */
26055
        SetASN_Items(extKuASN, dataASN, asnIdx, output);
26056
    }
26057
    if (ret == 0) {
26058
        /* Return the encoding size. */
26059
        ret = sz;
26060
    }
26061
26062
    /* Dispose of allocated data. */
26063
    if (extKuASN != NULL) {
26064
        XFREE(extKuASN, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
26065
    }
26066
    if (dataASN != NULL) {
26067
        XFREE(dataASN, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
26068
    }
26069
26070
    return ret;
26071
#endif
26072
}
26073
26074
#ifndef IGNORE_NETSCAPE_CERT_TYPE
26075
#ifndef WOLFSSL_ASN_TEMPLATE
26076
static int SetNsCertType(Cert* cert, byte* output, word32 outSz, byte input)
26077
{
26078
    word32 idx;
26079
    byte unusedBits = 0;
26080
    byte nsCertType = input;
26081
    word32 totalSz;
26082
    word32 bitStrSz;
26083
    const byte nscerttype_oid[] = { 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
26084
                                    0x86, 0xF8, 0x42, 0x01, 0x01 };
26085
26086
    if (cert == NULL || output == NULL ||
26087
            input == 0)
26088
        return BAD_FUNC_ARG;
26089
26090
    totalSz = sizeof(nscerttype_oid);
26091
26092
    /* Get amount of lsb zero's */
26093
    for (;(input & 1) == 0; input >>= 1)
26094
        unusedBits++;
26095
26096
    /* 1 byte of NS Cert Type extension */
26097
    bitStrSz = SetBitString(1, unusedBits, NULL) + 1;
26098
    totalSz += SetOctetString(bitStrSz, NULL) + bitStrSz;
26099
26100
    if (SetSequence(totalSz, NULL) + totalSz > outSz)
26101
        return BAD_FUNC_ARG;
26102
26103
    /* 1. Seq + Total Len */
26104
    idx = SetSequence(totalSz, output);
26105
26106
    /* 2. Object ID */
26107
    XMEMCPY(&output[idx], nscerttype_oid, sizeof(nscerttype_oid));
26108
    idx += sizeof(nscerttype_oid);
26109
26110
    /* 3. Octet String */
26111
    idx += SetOctetString(bitStrSz, &output[idx]);
26112
26113
    /* 4. Bit String */
26114
    idx += SetBitString(1, unusedBits, &output[idx]);
26115
    output[idx++] = nsCertType;
26116
26117
    return (int)idx;
26118
}
26119
#endif
26120
#endif
26121
26122
#ifndef WOLFSSL_ASN_TEMPLATE
26123
static int SetCRLInfo(Cert* cert, byte* output, word32 outSz, byte* input,
26124
                      int inSz)
26125
{
26126
    word32 idx;
26127
    word32 totalSz;
26128
    const byte crlinfo_oid[] = { 0x06, 0x03, 0x55, 0x1D, 0x1F };
26129
26130
    if (cert == NULL || output == NULL ||
26131
            input == 0 || inSz <= 0)
26132
        return BAD_FUNC_ARG;
26133
26134
    totalSz = (word32)sizeof(crlinfo_oid) + SetOctetString((word32)inSz, NULL) +
26135
        (word32)inSz;
26136
26137
    if (SetSequence(totalSz, NULL) + totalSz > outSz)
26138
        return BAD_FUNC_ARG;
26139
26140
    /* 1. Seq + Total Len */
26141
    idx = SetSequence(totalSz, output);
26142
26143
    /* 2. Object ID */
26144
    XMEMCPY(&output[idx], crlinfo_oid, sizeof(crlinfo_oid));
26145
    idx += sizeof(crlinfo_oid);
26146
26147
    /* 3. Octet String */
26148
    idx += SetOctetString((word32)inSz, &output[idx]);
26149
26150
    /* 4. CRL Info */
26151
    XMEMCPY(&output[idx], input, (size_t)inSz);
26152
    idx += (word32)inSz;
26153
26154
    return (int)idx;
26155
}
26156
#endif
26157
26158
/* encode Certificate Policies, return total bytes written
26159
 * each input value must be ITU-T X.690 formatted : a.b.c...
26160
 * input must be an array of values with a NULL terminated for the latest
26161
 * RFC5280 : non-critical */
26162
static int SetCertificatePolicies(byte *output,
26163
                                  word32 outputSz,
26164
                                  char input[MAX_CERTPOL_NB][MAX_CERTPOL_SZ],
26165
                                  word16 nb_certpol,
26166
                                  void* heap)
26167
{
26168
#ifndef WOLFSSL_ASN_TEMPLATE
26169
    byte    oid[MAX_OID_SZ];
26170
    byte    der_oid[MAX_CERTPOL_NB][MAX_OID_SZ];
26171
    byte    out[MAX_CERTPOL_SZ];
26172
    word32  oidSz;
26173
    word32  outSz;
26174
    word32  i = 0;
26175
    word32  der_oidSz[MAX_CERTPOL_NB];
26176
    int     ret;
26177
26178
    const byte certpol_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04 };
26179
    const byte oid_oid[] = { 0x06 };
26180
26181
    if (output == NULL || input == NULL || nb_certpol > MAX_CERTPOL_NB)
26182
        return BAD_FUNC_ARG;
26183
26184
    for (i = 0; i < nb_certpol; i++) {
26185
        oidSz = sizeof(oid);
26186
        XMEMSET(oid, 0, oidSz);
26187
26188
        ret = EncodePolicyOID(oid, &oidSz, input[i], heap);
26189
        if (ret != 0)
26190
            return ret;
26191
26192
        /* compute sequence value for the oid */
26193
        ret = SetOidValue(der_oid[i], MAX_OID_SZ, oid_oid,
26194
                          sizeof(oid_oid), oid, oidSz);
26195
        if (ret <= 0)
26196
            return ret;
26197
        else
26198
            der_oidSz[i] = (word32)ret;
26199
    }
26200
26201
    /* concatenate oid, keep two byte for sequence/size of the created value */
26202
    for (i = 0, outSz = 2; i < nb_certpol; i++) {
26203
        XMEMCPY(out+outSz, der_oid[i], der_oidSz[i]);
26204
        outSz += der_oidSz[i];
26205
    }
26206
26207
    /* add sequence */
26208
    ret = (int)SetSequence(outSz-2, out);
26209
    if (ret <= 0)
26210
        return ret;
26211
26212
    /* add Policy OID to compute final value */
26213
    return SetOidValue(output, outputSz, certpol_oid, sizeof(certpol_oid),
26214
                      out, outSz);
26215
#else
26216
    int    i;
26217
    int    ret = 0;
26218
    byte   oid[MAX_OID_SZ];
26219
    word32 oidSz;
26220
    word32 sz = 0;
26221
    int    piSz;
26222
26223
    if ((input == NULL) || (nb_certpol > MAX_CERTPOL_NB)) {
26224
        ret = BAD_FUNC_ARG;
26225
    }
26226
    /* Put in policyIdentifier but not policyQualifiers. */
26227
    for (i = 0; (ret == 0) && (i < nb_certpol); i++) {
26228
        ASNSetData dataASN[policyInfoASN_Length];
26229
26230
        oidSz = sizeof(oid);
26231
        XMEMSET(oid, 0, oidSz);
26232
        dataASN[POLICYINFOASN_IDX_QUALI].noOut = 1;
26233
26234
        ret = EncodePolicyOID(oid, &oidSz, input[i], heap);
26235
        if (ret == 0) {
26236
            XMEMSET(dataASN, 0, sizeof(dataASN));
26237
            SetASN_Buffer(&dataASN[POLICYINFOASN_IDX_ID], oid, oidSz);
26238
            ret = SizeASN_Items(policyInfoASN, dataASN, policyInfoASN_Length,
26239
                                &piSz);
26240
        }
26241
        if ((ret == 0) && (output != NULL) && (sz + (word32)piSz > outputSz)) {
26242
            ret = BUFFER_E;
26243
        }
26244
        if (ret == 0) {
26245
            if (output != NULL) {
26246
                SetASN_Items(policyInfoASN, dataASN, policyInfoASN_Length,
26247
                    output);
26248
                output += piSz;
26249
            }
26250
            sz += (word32)piSz;
26251
        }
26252
    }
26253
26254
    if (ret == 0) {
26255
        ret = (int)sz;
26256
    }
26257
    return ret;
26258
#endif
26259
}
26260
#endif /* WOLFSSL_CERT_EXT */
26261
26262
26263
#ifdef WOLFSSL_ALT_NAMES
26264
26265
#ifndef WOLFSSL_ASN_TEMPLATE
26266
/* encode Alternative Names, return total bytes written */
26267
static int SetAltNames(byte *output, word32 outSz,
26268
        const byte *input, word32 length, int critical)
26269
{
26270
    byte san_len[1 + MAX_LENGTH_SZ];
26271
    const byte san_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x11 };
26272
    const byte san_crit[] = { 0x01, 0x01, 0xff };
26273
    word32 seqSz, san_lenSz, idx = 0;
26274
26275
    if (output == NULL || input == NULL)
26276
        return BAD_FUNC_ARG;
26277
26278
    if (outSz < length)
26279
        return BUFFER_E;
26280
26281
    /* Octet String header */
26282
    san_lenSz = SetOctetString(length, san_len);
26283
26284
    if (outSz < MAX_SEQ_SZ)
26285
        return BUFFER_E;
26286
26287
    seqSz = length + (word32)sizeof(san_oid) + san_lenSz;
26288
    if (critical)
26289
        seqSz += sizeof(san_crit);
26290
    idx = SetSequence(seqSz, output);
26291
26292
    if (seqSz > outSz)
26293
        return BUFFER_E;
26294
26295
    /* put oid */
26296
    XMEMCPY(output+idx, san_oid, sizeof(san_oid));
26297
    idx += sizeof(san_oid);
26298
26299
    if (critical) {
26300
        XMEMCPY(output+idx, san_crit, sizeof(san_crit));
26301
        idx += sizeof(san_crit);
26302
    }
26303
26304
    /* put octet header */
26305
    XMEMCPY(output+idx, san_len, san_lenSz);
26306
    idx += san_lenSz;
26307
26308
    /* put value */
26309
    XMEMCPY(output+idx, input, length);
26310
    idx += length;
26311
26312
    return (int)idx;
26313
}
26314
#endif /* WOLFSSL_ASN_TEMPLATE */
26315
26316
26317
int FlattenAltNames(byte* output, word32 outputSz, const DNS_entry* names)
26318
{
26319
    word32 idx;
26320
    const DNS_entry* curName;
26321
    word32 namesSz = 0;
26322
#ifdef WOLFSSL_ALT_NAMES_NO_REV
26323
    word32 i;
26324
#endif
26325
26326
    if (output == NULL)
26327
        return BAD_FUNC_ARG;
26328
26329
    if (names == NULL)
26330
        return 0;
26331
26332
    curName = names;
26333
    do {
26334
        namesSz += (word32)curName->len + 2 +
26335
            ((curName->len < ASN_LONG_LENGTH) ? 0
26336
             : BytePrecision((word32)curName->len));
26337
        curName = curName->next;
26338
    } while (curName != NULL);
26339
26340
    if (outputSz < MAX_SEQ_SZ + namesSz)
26341
        return BUFFER_E;
26342
26343
    idx = SetSequence(namesSz, output);
26344
#ifdef WOLFSSL_ALT_NAMES_NO_REV
26345
    namesSz += idx;
26346
    i = namesSz;
26347
#endif
26348
26349
    curName = names;
26350
    do {
26351
#ifdef WOLFSSL_ALT_NAMES_NO_REV
26352
        word32 len = SetLength(curName->len, NULL);
26353
        idx = i - curName->len - len - 1;
26354
        i = idx;
26355
#endif
26356
        output[idx] = (byte) (ASN_CONTEXT_SPECIFIC | curName->type);
26357
        if (curName->type == ASN_DIR_TYPE || curName->type == ASN_OTHER_TYPE) {
26358
            output[idx] |= ASN_CONSTRUCTED;
26359
        }
26360
        idx++;
26361
        idx += SetLength((word32)curName->len, output + idx);
26362
        XMEMCPY(output + idx, curName->name, (size_t)curName->len);
26363
#ifndef WOLFSSL_ALT_NAMES_NO_REV
26364
        idx += (word32)curName->len;
26365
#endif
26366
        curName = curName->next;
26367
    } while (curName != NULL);
26368
26369
#ifdef WOLFSSL_ALT_NAMES_NO_REV
26370
    idx = namesSz;
26371
#endif
26372
    return (int)idx;
26373
}
26374
26375
#endif /* WOLFSSL_ALT_NAMES */
26376
#endif /* WOLFSSL_CERT_GEN */
26377
26378
#if defined(WOLFSSL_CERT_GEN) || defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
26379
/* Simple domain name OID size. */
26380
#define DN_OID_SZ     3
26381
26382
/* Encodes one attribute of the name (issuer/subject)
26383
 *
26384
 * name     structure to hold result of encoding
26385
 * nameStr  value to be encoded
26386
 * nameTag  tag of encoding i.e CTC_UTF8
26387
 * type     id of attribute i.e ASN_COMMON_NAME
26388
 * emailTag tag of email i.e CTC_UTF8
26389
 * returns length on success
26390
 */
26391
static int EncodeName(EncodedName* name, const char* nameStr,
26392
                    byte nameTag, byte type, byte emailTag, CertName* cname)
26393
{
26394
#if !defined(WOLFSSL_ASN_TEMPLATE)
26395
    word32 idx = 0;
26396
    /* bottom up */
26397
    byte firstLen[1 + MAX_LENGTH_SZ];
26398
    byte secondLen[MAX_LENGTH_SZ];
26399
    byte sequence[MAX_SEQ_SZ];
26400
    byte set[MAX_SET_SZ];
26401
26402
    word32 strLen;
26403
    word32 thisLen;
26404
    word32 firstSz, secondSz, seqSz, setSz;
26405
26406
    if (nameStr == NULL) {
26407
        name->used = 0;
26408
        return 0;
26409
    }
26410
26411
    thisLen = strLen = (word32)XSTRLEN(nameStr);
26412
#ifdef WOLFSSL_CUSTOM_OID
26413
    if (type == ASN_CUSTOM_NAME) {
26414
        if (cname == NULL || cname->custom.oidSz == 0) {
26415
            name->used = 0;
26416
            return 0;
26417
        }
26418
        thisLen = strLen = (word32)cname->custom.valSz;
26419
    }
26420
#else
26421
    (void)cname;
26422
#endif
26423
26424
    if (strLen == 0) { /* no user data for this item */
26425
        name->used = 0;
26426
        return 0;
26427
    }
26428
26429
    /* Restrict country code size */
26430
    if (type == ASN_COUNTRY_NAME && strLen != CTC_COUNTRY_SIZE) {
26431
        WOLFSSL_MSG("Country code size error");
26432
        WOLFSSL_ERROR_VERBOSE(ASN_COUNTRY_SIZE_E);
26433
        return ASN_COUNTRY_SIZE_E;
26434
    }
26435
26436
    secondSz = SetLength(strLen, secondLen);
26437
    thisLen += secondSz;
26438
    switch (type) {
26439
        case ASN_EMAIL_NAME: /* email */
26440
            thisLen += (int)sizeof(attrEmailOid);
26441
            firstSz  = (int)sizeof(attrEmailOid);
26442
            break;
26443
        case ASN_DOMAIN_COMPONENT:
26444
            thisLen += (int)sizeof(dcOid);
26445
            firstSz  = (int)sizeof(dcOid);
26446
            break;
26447
        case ASN_USER_ID:
26448
            thisLen += (int)sizeof(uidOid);
26449
            firstSz  = (int)sizeof(uidOid);
26450
            break;
26451
        case ASN_FAVOURITE_DRINK:
26452
            thisLen += (int)sizeof(fvrtDrk);
26453
            firstSz  = (int)sizeof(fvrtDrk);
26454
            break;
26455
    #ifdef WOLFSSL_CUSTOM_OID
26456
        case ASN_CUSTOM_NAME:
26457
            thisLen += cname->custom.oidSz;
26458
            firstSz = cname->custom.oidSz;
26459
            break;
26460
    #endif
26461
        default:
26462
            thisLen += DN_OID_SZ;
26463
            firstSz  = DN_OID_SZ;
26464
    }
26465
    thisLen++; /* id  type */
26466
    firstSz  = (word32)SetObjectId((int)firstSz, firstLen);
26467
    thisLen += firstSz;
26468
26469
    seqSz = SetSequence(thisLen, sequence);
26470
    thisLen += seqSz;
26471
    setSz = SetSet(thisLen, set);
26472
    thisLen += setSz;
26473
26474
    if (thisLen > (int)sizeof(name->encoded)) {
26475
        return BUFFER_E;
26476
    }
26477
26478
    /* store it */
26479
    idx = 0;
26480
    /* set */
26481
    XMEMCPY(name->encoded, set, setSz);
26482
    idx += setSz;
26483
    /* seq */
26484
    XMEMCPY(name->encoded + idx, sequence, seqSz);
26485
    idx += seqSz;
26486
    /* asn object id */
26487
    XMEMCPY(name->encoded + idx, firstLen, firstSz);
26488
    idx += firstSz;
26489
    switch (type) {
26490
        case ASN_EMAIL_NAME:
26491
            /* email joint id */
26492
            XMEMCPY(name->encoded + idx, attrEmailOid, sizeof(attrEmailOid));
26493
            idx += (int)sizeof(attrEmailOid);
26494
            name->encoded[idx++] = emailTag;
26495
            break;
26496
        case ASN_DOMAIN_COMPONENT:
26497
            XMEMCPY(name->encoded + idx, dcOid, sizeof(dcOid)-1);
26498
            idx += (int)sizeof(dcOid)-1;
26499
            /* id type */
26500
            name->encoded[idx++] = type;
26501
            /* str type */
26502
            name->encoded[idx++] = nameTag;
26503
            break;
26504
        case ASN_USER_ID:
26505
            XMEMCPY(name->encoded + idx, uidOid, sizeof(uidOid));
26506
            idx += (int)sizeof(uidOid);
26507
            /* str type */
26508
            name->encoded[idx++] = nameTag;
26509
            break;
26510
        case ASN_FAVOURITE_DRINK:
26511
            XMEMCPY(name->encoded + idx, fvrtDrk, sizeof(fvrtDrk));
26512
            idx += (int)sizeof(fvrtDrk);
26513
            /* str type */
26514
            name->encoded[idx++] = nameTag;
26515
            break;
26516
    #ifdef WOLFSSL_CUSTOM_OID
26517
        case ASN_CUSTOM_NAME:
26518
            XMEMCPY(name->encoded + idx, cname->custom.oid,
26519
                    cname->custom.oidSz);
26520
            idx += cname->custom.oidSz;
26521
            /* str type */
26522
            name->encoded[idx++] = nameTag;
26523
            break;
26524
    #endif
26525
        default:
26526
            name->encoded[idx++] = 0x55;
26527
            name->encoded[idx++] = 0x04;
26528
            /* id type */
26529
            name->encoded[idx++] = type;
26530
            /* str type */
26531
            name->encoded[idx++] = nameTag;
26532
    }
26533
    /* second length */
26534
    XMEMCPY(name->encoded + idx, secondLen, secondSz);
26535
    idx += secondSz;
26536
    /* str value */
26537
    XMEMCPY(name->encoded + idx, nameStr, strLen);
26538
    idx += strLen;
26539
26540
    name->type = type;
26541
    name->totalLen = (int)idx;
26542
    name->used = 1;
26543
26544
    return (int)idx;
26545
#else
26546
    DECL_ASNSETDATA(dataASN, rdnASN_Length);
26547
    ASNItem namesASN[rdnASN_Length];
26548
    byte dnOid[DN_OID_SZ] = { 0x55, 0x04, 0x00 };
26549
    int ret = 0;
26550
    int sz = 0;
26551
    const byte* oid;
26552
    word32 oidSz;
26553
    word32 nameSz;
26554
26555
    /* Validate input parameters. */
26556
    if ((name == NULL) || (nameStr == NULL)) {
26557
        ret = BAD_FUNC_ARG;
26558
    }
26559
26560
    CALLOC_ASNSETDATA(dataASN, rdnASN_Length, ret, NULL);
26561
    if (ret == 0) {
26562
        nameSz = (word32)XSTRLEN(nameStr);
26563
        /* Copy the RDN encoding template. ASN.1 tag for the name string is set
26564
         * based on type. */
26565
        XMEMCPY(namesASN, rdnASN, sizeof(namesASN));
26566
26567
        /* Set OID and ASN.1 tag for name depending on type. */
26568
        switch (type) {
26569
            case ASN_EMAIL_NAME:
26570
                /* email OID different to standard types. */
26571
                oid = attrEmailOid;
26572
                oidSz = sizeof(attrEmailOid);
26573
                /* Use email specific type/tag. */
26574
                nameTag = emailTag;
26575
                break;
26576
            case ASN_DOMAIN_COMPONENT:
26577
                /* Domain component OID different to standard types. */
26578
                oid = dcOid;
26579
                oidSz = sizeof(dcOid);
26580
                break;
26581
            case ASN_USER_ID:
26582
                /* Domain component OID different to standard types. */
26583
                oid = uidOid;
26584
                oidSz = sizeof(uidOid);
26585
                break;
26586
            case ASN_FAVOURITE_DRINK:
26587
                oid = fvrtDrk;
26588
                oidSz = sizeof(fvrtDrk);
26589
                break;
26590
        #ifdef WOLFSSL_CUSTOM_OID
26591
            case ASN_CUSTOM_NAME:
26592
                nameSz = cname->custom.valSz;
26593
                oid = cname->custom.oid;
26594
                oidSz = cname->custom.oidSz;
26595
                break;
26596
        #endif
26597
            default:
26598
                /* Construct OID using type. */
26599
                dnOid[2] = type;
26600
                oid = dnOid;
26601
                oidSz = DN_OID_SZ;
26602
                break;
26603
        }
26604
26605
        /* Set OID corresponding to the name type. */
26606
        SetASN_Buffer(&dataASN[RDNASN_IDX_ATTR_TYPE], oid, oidSz);
26607
        /* Set name string. */
26608
        SetASN_Buffer(&dataASN[RDNASN_IDX_ATTR_VAL], (const byte *)nameStr, nameSz);
26609
        /* Set the ASN.1 tag for the name string. */
26610
        namesASN[RDNASN_IDX_ATTR_VAL].tag = nameTag;
26611
26612
        /* Calculate size of encoded name and indexes of components. */
26613
        ret = SizeASN_Items(namesASN, dataASN, rdnASN_Length, &sz);
26614
    }
26615
    /* Check if name's buffer is big enough. */
26616
    if ((ret == 0) && (sz > (int)sizeof(name->encoded))) {
26617
        ret = BUFFER_E;
26618
    }
26619
    if (ret == 0) {
26620
        /* Encode name into the buffer. */
26621
        SetASN_Items(namesASN, dataASN, rdnASN_Length, name->encoded);
26622
        /* Cache the type and size, and set that it is used. */
26623
        name->type = type;
26624
        name->totalLen = sz;
26625
        name->used = 1;
26626
26627
        /* Return size of encoding. */
26628
        ret = sz;
26629
    }
26630
    (void)cname;
26631
26632
    FREE_ASNSETDATA(dataASN, NULL);
26633
    return ret;
26634
#endif /* WOLFSSL_ASN_TEMPLATE */
26635
}
26636
26637
/* canonical encoding one attribute of the name (issuer/subject)
26638
 * call EncodeName with CTC_UTF8 for email type
26639
 *
26640
 * name     structure to hold result of encoding
26641
 * nameStr  value to be encoded
26642
 * nameType type of encoding i.e CTC_UTF8
26643
 * type     id of attribute i.e ASN_COMMON_NAME
26644
 *
26645
 * returns length on success
26646
 */
26647
int wc_EncodeNameCanonical(EncodedName* name, const char* nameStr,
26648
                           char nameType, byte type)
26649
{
26650
    return EncodeName(name, nameStr, (byte)nameType, type,
26651
        ASN_UTF8STRING, NULL);
26652
}
26653
#endif /* WOLFSSL_CERT_GEN || OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
26654
26655
#if (defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT)) || \
26656
    (defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA))
26657
26658
/* Convert key usage string (comma delimited, null terminated) to word16
26659
 * Returns 0 on success, negative on error */
26660
int ParseKeyUsageStr(const char* value, word16* keyUsage, void* heap)
26661
{
26662
    int ret = 0;
26663
    char *token, *str, *ptr;
26664
    word32 len = 0;
26665
    word16 usage = 0;
26666
26667
    if (value == NULL || keyUsage == NULL) {
26668
        return BAD_FUNC_ARG;
26669
    }
26670
26671
    /* duplicate string (including terminator) */
26672
    len = (word32)XSTRLEN(value);
26673
    str = (char*)XMALLOC(len + 1, heap, DYNAMIC_TYPE_TMP_BUFFER);
26674
    if (str == NULL) {
26675
        return MEMORY_E;
26676
    }
26677
    XMEMCPY(str, value, len + 1);
26678
26679
    /* parse value, and set corresponding Key Usage value */
26680
    if ((token = XSTRTOK(str, ",", &ptr)) == NULL) {
26681
        XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
26682
        return KEYUSAGE_E;
26683
    }
26684
    while (token != NULL) {
26685
        if (!XSTRCASECMP(token, "digitalSignature"))
26686
            usage |= KEYUSE_DIGITAL_SIG;
26687
        else if (!XSTRCASECMP(token, "nonRepudiation") ||
26688
                 !XSTRCASECMP(token, "contentCommitment"))
26689
            usage |= KEYUSE_CONTENT_COMMIT;
26690
        else if (!XSTRCASECMP(token, "keyEncipherment"))
26691
            usage |= KEYUSE_KEY_ENCIPHER;
26692
        else if (!XSTRCASECMP(token, "dataEncipherment"))
26693
            usage |= KEYUSE_DATA_ENCIPHER;
26694
        else if (!XSTRCASECMP(token, "keyAgreement"))
26695
            usage |= KEYUSE_KEY_AGREE;
26696
        else if (!XSTRCASECMP(token, "keyCertSign"))
26697
            usage |= KEYUSE_KEY_CERT_SIGN;
26698
        else if (!XSTRCASECMP(token, "cRLSign"))
26699
            usage |= KEYUSE_CRL_SIGN;
26700
        else if (!XSTRCASECMP(token, "encipherOnly"))
26701
            usage |= KEYUSE_ENCIPHER_ONLY;
26702
        else if (!XSTRCASECMP(token, "decipherOnly"))
26703
            usage |= KEYUSE_DECIPHER_ONLY;
26704
        else {
26705
            ret = KEYUSAGE_E;
26706
            break;
26707
        }
26708
26709
        token = XSTRTOK(NULL, ",", &ptr);
26710
    }
26711
26712
    XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
26713
26714
    if (ret == 0) {
26715
        *keyUsage = usage;
26716
    }
26717
26718
    return ret;
26719
}
26720
26721
/* Convert extended key usage string (comma delimited, null terminated) to byte
26722
 * Returns 0 on success, negative on error */
26723
int ParseExtKeyUsageStr(const char* value, byte* extKeyUsage, void* heap)
26724
{
26725
    int ret = 0;
26726
    char *token, *str, *ptr;
26727
    word32 len = 0;
26728
    byte usage = 0;
26729
26730
    if (value == NULL || extKeyUsage == NULL) {
26731
        return BAD_FUNC_ARG;
26732
    }
26733
26734
    /* duplicate string (including terminator) */
26735
    len = (word32)XSTRLEN(value);
26736
    str = (char*)XMALLOC(len + 1, heap, DYNAMIC_TYPE_TMP_BUFFER);
26737
    if (str == NULL) {
26738
        return MEMORY_E;
26739
    }
26740
    XMEMCPY(str, value, len + 1);
26741
26742
    /* parse value, and set corresponding Key Usage value */
26743
    if ((token = XSTRTOK(str, ",", &ptr)) == NULL) {
26744
        XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
26745
        return EXTKEYUSAGE_E;
26746
    }
26747
    while (token != NULL) {
26748
        if (!XSTRCASECMP(token, "any"))
26749
            usage |= EXTKEYUSE_ANY;
26750
        else if (!XSTRCASECMP(token, "serverAuth"))
26751
            usage |= EXTKEYUSE_SERVER_AUTH;
26752
        else if (!XSTRCASECMP(token, "clientAuth"))
26753
            usage |= EXTKEYUSE_CLIENT_AUTH;
26754
        else if (!XSTRCASECMP(token, "codeSigning"))
26755
            usage |= EXTKEYUSE_CODESIGN;
26756
        else if (!XSTRCASECMP(token, "emailProtection"))
26757
            usage |= EXTKEYUSE_EMAILPROT;
26758
        else if (!XSTRCASECMP(token, "timeStamping"))
26759
            usage |= EXTKEYUSE_TIMESTAMP;
26760
        else if (!XSTRCASECMP(token, "OCSPSigning"))
26761
            usage |= EXTKEYUSE_OCSP_SIGN;
26762
        else {
26763
            ret = EXTKEYUSAGE_E;
26764
            break;
26765
        }
26766
26767
        token = XSTRTOK(NULL, ",", &ptr);
26768
    }
26769
26770
    XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
26771
26772
    if (ret == 0) {
26773
        *extKeyUsage = usage;
26774
    }
26775
26776
    return ret;
26777
}
26778
26779
#endif /* (CERT_GEN && CERT_EXT) || (OPENSSL_ALL || OPENSSL_EXTRA) */
26780
26781
#ifdef WOLFSSL_CERT_GEN
26782
/* Encodes one attribute of the name (issuer/subject)
26783
 * call we_EncodeName_ex with 0x16, IA5String for email type
26784
 * name     structure to hold result of encoding
26785
 * nameStr  value to be encoded
26786
 * nameType type of encoding i.e CTC_UTF8
26787
 * type     id of attribute i.e ASN_COMMON_NAME
26788
 *
26789
 * returns length on success
26790
 */
26791
int wc_EncodeName(EncodedName* name, const char* nameStr, char nameType,
26792
                  byte type)
26793
{
26794
    return EncodeName(name, nameStr, (byte)nameType, type,
26795
        ASN_IA5_STRING, NULL);
26796
}
26797
26798
#ifdef WOLFSSL_ASN_TEMPLATE
26799
static void SetRdnItems(ASNItem* namesASN, ASNSetData* dataASN, const byte* oid,
26800
    word32 oidSz, byte tag, const byte* data, word32 sz)
26801
{
26802
    XMEMCPY(namesASN, rdnASN, sizeof(rdnASN));
26803
    SetASN_Buffer(&dataASN[RDNASN_IDX_ATTR_TYPE], oid, oidSz);
26804
    namesASN[RDNASN_IDX_ATTR_VAL].tag = tag;
26805
    SetASN_Buffer(&dataASN[RDNASN_IDX_ATTR_VAL], data, sz);
26806
}
26807
26808
#ifdef WOLFSSL_MULTI_ATTRIB
26809
static int FindMultiAttrib(CertName* name, int id, int* idx)
26810
{
26811
    int i;
26812
    for (i = *idx + 1; i < CTC_MAX_ATTRIB; i++) {
26813
        if (name->name[i].sz > 0 && name->name[i].id == id) {
26814
            break;
26815
        }
26816
    }
26817
    if (i == CTC_MAX_ATTRIB) {
26818
        i = -1;
26819
    }
26820
    *idx = i;
26821
    return i >= 0;
26822
}
26823
#endif
26824
26825
/* ASN.1 template for the SEQUENCE around the RDNs.
26826
 * X.509: RFC 5280, 4.1.2.4 - RDNSequence
26827
 */
26828
static const ASNItem nameASN[] = {
26829
    { 0, ASN_SEQUENCE, 1, 1, 0 },
26830
};
26831
enum {
26832
    NAMEASN_IDX_SEQ = 0
26833
};
26834
26835
/* Number of items in ASN.1 template for the SEQUENCE around the RDNs. */
26836
#define nameASN_Length (sizeof(nameASN) / sizeof(ASNItem))
26837
26838
static int SetNameRdnItems(ASNSetData* dataASN, ASNItem* namesASN,
26839
        int maxIdx, CertName* name)
26840
{
26841
    int         i;
26842
    int         idx;
26843
    int         ret = 0;
26844
    word32      nameLen[NAME_ENTRIES];
26845
#ifdef WOLFSSL_MULTI_ATTRIB
26846
    int         j;
26847
#endif
26848
26849
    for (i = 0; i < NAME_ENTRIES; i++) {
26850
        /* Keep name length to identify component is to be encoded. */
26851
        const char* nameStr = GetOneCertName(name, i);
26852
        nameLen[i] = nameStr ? (word32)XSTRLEN(nameStr) : 0;
26853
    }
26854
26855
    idx = nameASN_Length;
26856
    for (i = 0; i < NAME_ENTRIES; i++) {
26857
        int type = GetCertNameId(i);
26858
26859
    #ifdef WOLFSSL_MULTI_ATTRIB
26860
        j = -1;
26861
        /* Put DomainComponents before OrgUnitName. */
26862
        while (FindMultiAttrib(name, type, &j)) {
26863
            if (GetCertNameId(i) != ASN_DOMAIN_COMPONENT) {
26864
                continue;
26865
            }
26866
            if (dataASN != NULL && namesASN != NULL) {
26867
                if (idx > maxIdx - (int)rdnASN_Length) {
26868
                    WOLFSSL_MSG("Wanted to write more ASN than allocated");
26869
                    ret = BUFFER_E;
26870
                    break;
26871
                }
26872
                /* Copy data into dynamic vars. */
26873
                SetRdnItems(namesASN + idx, dataASN + idx, dcOid,
26874
                            sizeof(dcOid), (byte)name->name[j].type,
26875
                            (byte*)name->name[j].value,
26876
                            (word32)name->name[j].sz);
26877
            }
26878
            idx += (int)rdnASN_Length;
26879
        }
26880
        if (ret != 0)
26881
            break;
26882
    #endif
26883
26884
        if (nameLen[i] > 0) {
26885
            if (dataASN != NULL) {
26886
                if (idx > maxIdx - (int)rdnASN_Length) {
26887
                    WOLFSSL_MSG("Wanted to write more ASN than allocated");
26888
                    ret = BUFFER_E;
26889
                    break;
26890
                }
26891
                /* Write out first instance of attribute type. */
26892
                if (type == ASN_EMAIL_NAME) {
26893
                    /* Copy email data into dynamic vars. */
26894
                    SetRdnItems(namesASN + idx, dataASN + idx, attrEmailOid,
26895
                        sizeof(attrEmailOid), ASN_IA5_STRING,
26896
                        (const byte*)GetOneCertName(name, i), nameLen[i]);
26897
                }
26898
                else if (type == ASN_USER_ID) {
26899
                    /* Copy userID data into dynamic vars. */
26900
                    SetRdnItems(namesASN + idx, dataASN + idx, uidOid,
26901
                                sizeof(uidOid), (byte)GetNameType(name, i),
26902
                        (const byte*)GetOneCertName(name, i), nameLen[i]);
26903
                }
26904
                else if (type == ASN_FAVOURITE_DRINK) {
26905
                    /* Copy favourite drink data into dynamic vars. */
26906
                    SetRdnItems(namesASN + idx, dataASN + idx, fvrtDrk,
26907
                                sizeof(fvrtDrk), (byte)GetNameType(name, i),
26908
                        (const byte*)GetOneCertName(name, i), nameLen[i]);
26909
                }
26910
                else if (type == ASN_CUSTOM_NAME) {
26911
                #ifdef WOLFSSL_CUSTOM_OID
26912
                    SetRdnItems(namesASN + idx, dataASN + idx, name->custom.oid,
26913
                        name->custom.oidSz, name->custom.enc,
26914
                        name->custom.val, name->custom.valSz);
26915
                #endif
26916
                }
26917
                else {
26918
                    /* Copy name data into dynamic vars. */
26919
                    SetRdnItems(namesASN + idx, dataASN + idx, nameOid[i],
26920
                        NAME_OID_SZ, (byte)GetNameType(name, i),
26921
                        (const byte*)GetOneCertName(name, i), nameLen[i]);
26922
                }
26923
            }
26924
            idx += (int)rdnASN_Length;
26925
        }
26926
26927
    #ifdef WOLFSSL_MULTI_ATTRIB
26928
        j = -1;
26929
        /* Write all other attributes of this type. */
26930
        while (FindMultiAttrib(name, type, &j)) {
26931
            if (GetCertNameId(i) == ASN_DOMAIN_COMPONENT) {
26932
                continue;
26933
            }
26934
            if (dataASN != NULL && namesASN != NULL) {
26935
                if (idx > maxIdx - (int)rdnASN_Length) {
26936
                    WOLFSSL_MSG("Wanted to write more ASN than allocated");
26937
                    ret = BUFFER_E;
26938
                    break;
26939
                }
26940
                /* Copy data into dynamic vars. */
26941
                SetRdnItems(namesASN + idx, dataASN + idx, nameOid[i],
26942
                    NAME_OID_SZ, (byte)name->name[j].type,
26943
                    (byte*)name->name[j].value, (word32)name->name[j].sz);
26944
            }
26945
            idx += (int)rdnASN_Length;
26946
        }
26947
        if (ret != 0)
26948
            break;
26949
    #endif
26950
    }
26951
    if (ret == 0)
26952
        ret = idx;
26953
    return ret;
26954
}
26955
#endif
26956
26957
/* encode CertName into output, return total bytes written */
26958
int SetNameEx(byte* output, word32 outputSz, CertName* name, void* heap)
26959
{
26960
#ifndef WOLFSSL_ASN_TEMPLATE
26961
    int ret;
26962
    int i;
26963
    word32 idx, totalBytes = 0;
26964
#ifdef WOLFSSL_SMALL_STACK
26965
    EncodedName* names = NULL;
26966
#else
26967
    EncodedName  names[NAME_ENTRIES];
26968
#endif
26969
#ifdef WOLFSSL_MULTI_ATTRIB
26970
    EncodedName addNames[CTC_MAX_ATTRIB];
26971
    int j, type;
26972
#endif
26973
26974
    if (output == NULL || name == NULL)
26975
        return BAD_FUNC_ARG;
26976
26977
    if (outputSz < 3)
26978
        return BUFFER_E;
26979
26980
#ifdef WOLFSSL_SMALL_STACK
26981
    names = (EncodedName*)XMALLOC(sizeof(EncodedName) * NAME_ENTRIES, NULL,
26982
                                                       DYNAMIC_TYPE_TMP_BUFFER);
26983
    if (names == NULL)
26984
        return MEMORY_E;
26985
#endif
26986
26987
    for (i = 0; i < NAME_ENTRIES; i++) {
26988
        const char* nameStr = GetOneCertName(name, i);
26989
26990
        ret = EncodeName(&names[i], nameStr, (byte)GetNameType(name, i),
26991
                          GetCertNameId(i), ASN_IA5_STRING, name);
26992
        if (ret < 0) {
26993
        #ifdef WOLFSSL_SMALL_STACK
26994
            XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
26995
        #endif
26996
            WOLFSSL_MSG("EncodeName failed");
26997
            return BUFFER_E;
26998
        }
26999
        totalBytes += (word32)ret;
27000
    }
27001
#ifdef WOLFSSL_MULTI_ATTRIB
27002
    for (i = 0; i < CTC_MAX_ATTRIB; i++) {
27003
        if (name->name[i].sz > 0) {
27004
            ret = EncodeName(&addNames[i], name->name[i].value,
27005
                             (byte)name->name[i].type, (byte)name->name[i].id,
27006
                        ASN_IA5_STRING, NULL);
27007
            if (ret < 0) {
27008
            #ifdef WOLFSSL_SMALL_STACK
27009
                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
27010
            #endif
27011
                WOLFSSL_MSG("EncodeName on multiple attributes failed");
27012
                return BUFFER_E;
27013
            }
27014
            totalBytes += (word32)ret;
27015
        }
27016
        else {
27017
            addNames[i].used = 0;
27018
        }
27019
    }
27020
#endif /* WOLFSSL_MULTI_ATTRIB */
27021
27022
    /* header */
27023
    idx = SetSequence(totalBytes, output);
27024
    totalBytes += idx;
27025
    if (totalBytes > WC_ASN_NAME_MAX) {
27026
#ifdef WOLFSSL_SMALL_STACK
27027
        XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
27028
#endif
27029
        WOLFSSL_MSG("Total Bytes is greater than WC_ASN_NAME_MAX");
27030
        return BUFFER_E;
27031
    }
27032
27033
    for (i = 0; i < NAME_ENTRIES; i++) {
27034
    #ifdef WOLFSSL_MULTI_ATTRIB
27035
        type = GetCertNameId(i);
27036
        for (j = 0; j < CTC_MAX_ATTRIB; j++) {
27037
            if (name->name[j].sz > 0 && type == name->name[j].id) {
27038
                if (outputSz < idx + (word32)addNames[j].totalLen) {
27039
                #ifdef WOLFSSL_SMALL_STACK
27040
                    XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
27041
                #endif
27042
                    WOLFSSL_MSG("Not enough space left for DC value");
27043
                    return BUFFER_E;
27044
                }
27045
27046
                XMEMCPY(output + idx, addNames[j].encoded,
27047
                        (size_t)addNames[j].totalLen);
27048
                idx += (word32)addNames[j].totalLen;
27049
            }
27050
        }
27051
    #endif /* WOLFSSL_MULTI_ATTRIB */
27052
27053
        if (names[i].used) {
27054
            if (outputSz < idx + (word32)names[i].totalLen) {
27055
#ifdef WOLFSSL_SMALL_STACK
27056
                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
27057
#endif
27058
                return BUFFER_E;
27059
            }
27060
27061
            XMEMCPY(output + idx, names[i].encoded, (size_t)names[i].totalLen);
27062
            idx += (word32)names[i].totalLen;
27063
        }
27064
    }
27065
27066
#ifdef WOLFSSL_SMALL_STACK
27067
    XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
27068
#endif
27069
    (void)heap;
27070
27071
    return (int)totalBytes;
27072
#else
27073
    /* TODO: consider calculating size of entries, putting length into
27074
     * SEQUENCE, encode SEQUENCE, encode entries into buffer.  */
27075
    ASNSetData* dataASN = NULL; /* Can't use DECL_ASNSETDATA. Always dynamic. */
27076
    ASNItem*    namesASN = NULL;
27077
    word32      items = 0;
27078
    int         ret = 0;
27079
    int         sz = 0;
27080
27081
    /* Calculate length of name entries and size for allocating. */
27082
    ret = SetNameRdnItems(NULL, NULL, 0, name);
27083
    if (ret > 0) {
27084
        items = (word32)ret;
27085
        ret = 0;
27086
    }
27087
27088
    /* Allocate dynamic data items. */
27089
    dataASN = (ASNSetData*)XMALLOC(items * sizeof(ASNSetData), heap,
27090
                                   DYNAMIC_TYPE_TMP_BUFFER);
27091
    if (dataASN == NULL) {
27092
        ret = MEMORY_E;
27093
    }
27094
    else {
27095
        /* Allocate dynamic ASN.1 template items. */
27096
        namesASN = (ASNItem*)XMALLOC(items * sizeof(ASNItem), heap,
27097
                                     DYNAMIC_TYPE_TMP_BUFFER);
27098
        if (namesASN == NULL) {
27099
            ret = MEMORY_E;
27100
        }
27101
    }
27102
27103
    if (ret == 0) {
27104
        /* Clear the dynamic data. */
27105
        XMEMSET(dataASN, 0, items * sizeof(ASNSetData));
27106
        /* Copy in the outer sequence. */
27107
        XMEMCPY(namesASN, nameASN, sizeof(nameASN));
27108
27109
        ret = SetNameRdnItems(dataASN, namesASN, (int)items, name);
27110
        if (ret == (int)items)
27111
            ret = 0;
27112
        else if (ret > 0) {
27113
            WOLFSSL_MSG("SetNameRdnItems returned different length");
27114
            ret = BUFFER_E;
27115
        }
27116
    }
27117
    if (ret == 0) {
27118
        /* Calculate size of encoding. */
27119
        ret = SizeASN_Items(namesASN, dataASN, (int)items, &sz);
27120
    }
27121
    /* Check buffer size if passed in. */
27122
    if (ret == 0 && output != NULL && sz > (int)outputSz) {
27123
        ret = BUFFER_E;
27124
    }
27125
    if (ret == 0) {
27126
        if (output != NULL) {
27127
            /* Encode Name. */
27128
            ret = SetASN_Items(namesASN, dataASN, (int)items, output);
27129
        }
27130
        else {
27131
            /* Return the encoding size. */
27132
            ret = sz;
27133
        }
27134
    }
27135
27136
    if (namesASN != NULL)
27137
        XFREE(namesASN, heap, DYNAMIC_TYPE_TMP_BUFFER);
27138
    if (dataASN != NULL)
27139
        XFREE(dataASN, heap, DYNAMIC_TYPE_TMP_BUFFER);
27140
    (void)heap;
27141
    return ret;
27142
#endif
27143
}
27144
int SetName(byte* output, word32 outputSz, CertName* name)
27145
{
27146
    return SetNameEx(output, outputSz, name, NULL);
27147
}
27148
27149
#ifdef WOLFSSL_ASN_TEMPLATE
27150
static int EncodePublicKey(int keyType, byte* output, int outLen,
27151
                           RsaKey* rsaKey, ecc_key* eccKey,
27152
                           ed25519_key* ed25519Key, ed448_key* ed448Key,
27153
                           DsaKey* dsaKey)
27154
{
27155
    int ret = 0;
27156
27157
    (void)outLen;
27158
    (void)rsaKey;
27159
    (void)eccKey;
27160
    (void)ed25519Key;
27161
    (void)ed448Key;
27162
    (void)dsaKey;
27163
27164
    switch (keyType) {
27165
    #ifndef NO_RSA
27166
        case RSA_KEY:
27167
            ret = SetRsaPublicKey(output, rsaKey, outLen, 1);
27168
            if (ret <= 0) {
27169
                ret = PUBLIC_KEY_E;
27170
            }
27171
            break;
27172
    #endif
27173
    #ifdef HAVE_ECC
27174
        case ECC_KEY:
27175
            ret = SetEccPublicKey(output, eccKey, outLen, 1, 0);
27176
            if (ret <= 0) {
27177
                ret = PUBLIC_KEY_E;
27178
            }
27179
            break;
27180
    #endif /* HAVE_ECC */
27181
    #ifdef HAVE_ED25519
27182
        case ED25519_KEY:
27183
            ret = wc_Ed25519PublicKeyToDer(ed25519Key, output,
27184
                                           (word32)outLen, 1);
27185
            if (ret <= 0) {
27186
                ret = PUBLIC_KEY_E;
27187
            }
27188
            break;
27189
    #endif
27190
    #ifdef HAVE_ED448
27191
        case ED448_KEY:
27192
            ret = wc_Ed448PublicKeyToDer(ed448Key, output, (word32)outLen, 1);
27193
            if (ret <= 0) {
27194
                ret = PUBLIC_KEY_E;
27195
            }
27196
            break;
27197
    #endif
27198
        default:
27199
            ret = PUBLIC_KEY_E;
27200
            break;
27201
    }
27202
27203
    return ret;
27204
}
27205
27206
/* ASN.1 template for certificate extensions.
27207
 * X.509: RFC 5280, 4.1 - Basic Certificate Fields.
27208
 * All extensions supported for encoding are described.
27209
 */
27210
static const ASNItem static_certExtsASN[] = {
27211
            /* Basic Constraints Extension - 4.2.1.9 */
27212
/* BC_SEQ        */    { 0, ASN_SEQUENCE, 1, 1, 0 },
27213
/* BC_OID        */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
27214
/* BC_STR        */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
27215
/* BC_STR_SEQ    */            { 2, ASN_SEQUENCE, 1, 1, 0 },
27216
                                                   /* cA */
27217
/* BC_CA         */                { 3, ASN_BOOLEAN, 0, 0, 0 },
27218
                                                   /* pathLenConstraint */
27219
/* BC_PATHLEN    */                { 3, ASN_INTEGER, 0, 0, 1 },
27220
                                       /* Subject Alternative Name - 4.2.1.6  */
27221
/* SAN_SEQ       */    { 0, ASN_SEQUENCE, 1, 1, 0 },
27222
/* SAN_OID       */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
27223
/* SAN_CRIT      */        { 1, ASN_BOOLEAN, 0, 0, 0 },
27224
/* SAN_STR       */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
27225
            /* Subject Key Identifier - 4.2.1.2 */
27226
/* SKID_SEQ      */    { 0, ASN_SEQUENCE, 1, 1, 0 },
27227
/* SKID_OID      */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
27228
/* SKID_STR      */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
27229
/* SKID_KEYID    */            { 2, ASN_OCTET_STRING, 0, 0, 0 },
27230
                                       /* Authority Key Identifier - 4.2.1.1 */
27231
/* AKID_SEQ      */    { 0, ASN_SEQUENCE, 1, 1, 0 },
27232
/* AKID_OID      */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
27233
/* AKID_STR      */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
27234
/* AKID_STR_SEQ, */            { 2, ASN_SEQUENCE, 1, 1, 0 },
27235
/* AKID_KEYID    */                { 3, ASN_CONTEXT_SPECIFIC | 0, 0, 0, 0 },
27236
                                       /* Key Usage - 4.2.1.3 */
27237
/* KU_SEQ        */    { 0, ASN_SEQUENCE, 1, 1, 0 },
27238
/* KU_OID        */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
27239
/* KU_CRIT       */        { 1, ASN_BOOLEAN, 0, 0, 0 },
27240
/* KU_STR        */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
27241
/* KU_USAGE      */            { 2, ASN_BIT_STRING, 0, 0, 0 },
27242
                                       /* Extended Key Usage - 4,2,1,12 */
27243
/* EKU_SEQ       */    { 0, ASN_SEQUENCE, 1, 1, 0 },
27244
/* EKU_OID       */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
27245
/* EKU_STR       */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
27246
                                       /* Certificate Policies - 4.2.1.4 */
27247
/* POLICIES_SEQ, */    { 0, ASN_SEQUENCE, 1, 1, 0 },
27248
/* POLICIES_OID, */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
27249
/* POLICIES_STR, */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
27250
/* POLICIES_INFO */            { 2, ASN_SEQUENCE, 1, 0, 0 },
27251
                                       /* Netscape Certificate Type */
27252
/* NSTYPE_SEQ    */    { 0, ASN_SEQUENCE, 1, 1, 0 },
27253
/* NSTYPE_OID    */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
27254
/* NSTYPE_STR    */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
27255
/* NSTYPE_USAGE, */            { 2, ASN_BIT_STRING, 0, 0, 0 },
27256
/* CRLINFO_SEQ   */    { 0, ASN_SEQUENCE, 1, 1, 0 },
27257
/* CRLINFO_OID   */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
27258
/* CRLINFO_STR   */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
27259
/* CUSTOM_SEQ    */    { 0, ASN_SEQUENCE, 1, 1, 0 },
27260
/* CUSTOM_OID    */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
27261
/* CUSTOM_STR    */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
27262
};
27263
enum {
27264
    CERTEXTSASN_IDX_BC_SEQ = 0,
27265
    CERTEXTSASN_IDX_BC_OID,
27266
    CERTEXTSASN_IDX_BC_STR,
27267
    CERTEXTSASN_IDX_BC_STR_SEQ,
27268
    CERTEXTSASN_IDX_BC_CA,
27269
    CERTEXTSASN_IDX_BC_PATHLEN,
27270
    CERTEXTSASN_IDX_SAN_SEQ,
27271
    CERTEXTSASN_IDX_SAN_OID,
27272
    CERTEXTSASN_IDX_SAN_CRIT,
27273
    CERTEXTSASN_IDX_SAN_STR,
27274
    CERTEXTSASN_IDX_SKID_SEQ,
27275
    CERTEXTSASN_IDX_SKID_OID,
27276
    CERTEXTSASN_IDX_SKID_STR,
27277
    CERTEXTSASN_IDX_SKID_KEYID,
27278
    CERTEXTSASN_IDX_AKID_SEQ,
27279
    CERTEXTSASN_IDX_AKID_OID,
27280
    CERTEXTSASN_IDX_AKID_STR,
27281
    CERTEXTSASN_IDX_AKID_STR_SEQ,
27282
    CERTEXTSASN_IDX_AKID_KEYID,
27283
    CERTEXTSASN_IDX_KU_SEQ,
27284
    CERTEXTSASN_IDX_KU_OID,
27285
    CERTEXTSASN_IDX_KU_CRIT,
27286
    CERTEXTSASN_IDX_KU_STR,
27287
    CERTEXTSASN_IDX_KU_USAGE,
27288
    CERTEXTSASN_IDX_EKU_SEQ,
27289
    CERTEXTSASN_IDX_EKU_OID,
27290
    CERTEXTSASN_IDX_EKU_STR,
27291
    CERTEXTSASN_IDX_POLICIES_SEQ,
27292
    CERTEXTSASN_IDX_POLICIES_OID,
27293
    CERTEXTSASN_IDX_POLICIES_STR,
27294
    CERTEXTSASN_IDX_POLICIES_INFO,
27295
    CERTEXTSASN_IDX_NSTYPE_SEQ,
27296
    CERTEXTSASN_IDX_NSTYPE_OID,
27297
    CERTEXTSASN_IDX_NSTYPE_STR,
27298
    CERTEXTSASN_IDX_NSTYPE_USAGE,
27299
    CERTEXTSASN_IDX_CRLINFO_SEQ,
27300
    CERTEXTSASN_IDX_CRLINFO_OID,
27301
    CERTEXTSASN_IDX_CRLINFO_STR,
27302
    CERTEXTSASN_IDX_CUSTOM_SEQ,
27303
    CERTEXTSASN_IDX_CUSTOM_OID,
27304
    CERTEXTSASN_IDX_CUSTOM_STR,
27305
    CERTEXTSASN_IDX_START_CUSTOM
27306
};
27307
27308
/* Number of items in ASN.1 template for certificate extensions. We multiply
27309
 * by 4 because there are 4 things (seq, OID, crit flag, octet string). */
27310
#define certExtsASN_Length ((sizeof(static_certExtsASN) / sizeof(ASNItem)) \
27311
                            + (NUM_CUSTOM_EXT * 4))
27312
27313
static const ASNItem customExtASN[] = {
27314
/* CUSTOM_SEQ    */    { 0, ASN_SEQUENCE, 1, 1, 0 },
27315
/* CUSTOM_OID    */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
27316
/* CUSTOM_CRIT   */        { 1, ASN_BOOLEAN, 0, 0, 0 },
27317
/* CUSTOM_STR    */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
27318
};
27319
27320
static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz,
27321
                            int forRequest)
27322
{
27323
    DECL_ASNSETDATA(dataASN, certExtsASN_Length);
27324
    int sz;
27325
    int ret = 0;
27326
    int i = 0;
27327
    static const byte bcOID[]   = { 0x55, 0x1d, 0x13 };
27328
#ifdef WOLFSSL_ALT_NAMES
27329
    static const byte sanOID[]  = { 0x55, 0x1d, 0x11 };
27330
#endif
27331
#ifdef WOLFSSL_CERT_EXT
27332
    static const byte skidOID[] = { 0x55, 0x1d, 0x0e };
27333
    static const byte akidOID[] = { 0x55, 0x1d, 0x23 };
27334
    static const byte kuOID[]   = { 0x55, 0x1d, 0x0f };
27335
    static const byte ekuOID[]  = { 0x55, 0x1d, 0x25 };
27336
    static const byte cpOID[]   = { 0x55, 0x1d, 0x20 };
27337
    static const byte nsCertOID[] = { 0x60, 0x86, 0x48, 0x01,
27338
                                      0x86, 0xF8, 0x42, 0x01, 0x01 };
27339
    static const byte crlInfoOID[] = { 0x55, 0x1D, 0x1F };
27340
#endif
27341
27342
#ifdef WOLFSSL_SMALL_STACK
27343
#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_CERT_EXT)
27344
    byte *encodedOids;
27345
#endif
27346
    ASNItem *certExtsASN = (ASNItem *)XMALLOC(certExtsASN_Length *
27347
                                              sizeof(ASNItem), cert->heap,
27348
                                              DYNAMIC_TYPE_TMP_BUFFER);
27349
    if (certExtsASN == NULL) {
27350
        return MEMORY_E;
27351
    }
27352
27353
#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_CERT_EXT)
27354
    encodedOids = (byte *)XMALLOC(NUM_CUSTOM_EXT * MAX_OID_SZ, cert->heap,
27355
                                  DYNAMIC_TYPE_TMP_BUFFER);
27356
    if (encodedOids == NULL) {
27357
        XFREE(certExtsASN, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
27358
        return MEMORY_E;
27359
    }
27360
#endif
27361
#else
27362
    ASNItem certExtsASN[certExtsASN_Length];
27363
#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_CERT_EXT)
27364
    byte encodedOids[NUM_CUSTOM_EXT * MAX_OID_SZ];
27365
#endif
27366
#endif
27367
27368
    /* Clone static_certExtsASN into a certExtsASN and then fill the rest of it
27369
     * with (NUM_CUSTOM_EXT*4) more ASNItems specifying extensions. See comment
27370
     * above definition of certExtsASN_Length. */
27371
    XMEMCPY(certExtsASN, static_certExtsASN, sizeof(static_certExtsASN));
27372
    for (i = sizeof(static_certExtsASN) / sizeof(ASNItem);
27373
         i < (int)certExtsASN_Length; i += 4) {
27374
        XMEMCPY(&certExtsASN[i], customExtASN, sizeof(customExtASN));
27375
    }
27376
27377
    (void)forRequest;
27378
27379
    CALLOC_ASNSETDATA(dataASN, certExtsASN_Length, ret, cert->heap);
27380
27381
    if (ret == 0) {
27382
        if (cert->isCA) {
27383
            /* Set Basic Constraints to be a Certificate Authority. */
27384
            SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_BC_CA], 1);
27385
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_BC_OID], bcOID, sizeof(bcOID));
27386
            if (cert->pathLenSet
27387
            #ifdef WOLFSSL_CERT_EXT
27388
                && ((cert->keyUsage & KEYUSE_KEY_CERT_SIGN) || (!cert->keyUsage))
27389
            #endif
27390
            ) {
27391
                SetASN_Int8Bit(&dataASN[CERTEXTSASN_IDX_BC_PATHLEN],
27392
                        cert->pathLen);
27393
            }
27394
            else {
27395
                dataASN[CERTEXTSASN_IDX_BC_PATHLEN].noOut = 1;
27396
            }
27397
        }
27398
        else if (cert->basicConstSet) {
27399
            /* Set Basic Constraints to be a non Certificate Authority. */
27400
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_BC_OID], bcOID, sizeof(bcOID));
27401
            dataASN[CERTEXTSASN_IDX_BC_CA].noOut = 1;
27402
            dataASN[CERTEXTSASN_IDX_BC_PATHLEN].noOut = 1;
27403
        }
27404
        else {
27405
            /* Don't write out Basic Constraints extension items. */
27406
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_BC_SEQ,
27407
                    CERTEXTSASN_IDX_BC_PATHLEN);
27408
        }
27409
    #ifdef WOLFSSL_ALT_NAMES
27410
        if (cert->altNamesSz > 0) {
27411
            /* Set Subject Alternative Name OID and data. */
27412
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_SAN_OID],
27413
                    sanOID, sizeof(sanOID));
27414
            if (cert->altNamesCrit) {
27415
                SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_SAN_CRIT], 1);
27416
            }
27417
            else {
27418
                dataASN[CERTEXTSASN_IDX_SAN_CRIT].noOut = 1;
27419
            }
27420
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_SAN_STR],
27421
                          cert->altNames, (word32)cert->altNamesSz);
27422
        }
27423
        else
27424
    #endif
27425
        {
27426
            /* Don't write out Subject Alternative Name extension items. */
27427
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_SAN_SEQ,
27428
                    CERTEXTSASN_IDX_SAN_STR);
27429
        }
27430
    #ifdef WOLFSSL_CERT_EXT
27431
        if (cert->skidSz > 0) {
27432
            /* Set Subject Key Identifier OID and data. */
27433
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_SKID_OID],
27434
                    skidOID, sizeof(skidOID));
27435
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_SKID_KEYID],
27436
                          cert->skid, (word32)cert->skidSz);
27437
        }
27438
        else
27439
    #endif
27440
        {
27441
            /* Don't write out Subject Key Identifier extension items. */
27442
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_SKID_SEQ,
27443
                    CERTEXTSASN_IDX_SKID_KEYID);
27444
        }
27445
    #ifdef WOLFSSL_CERT_EXT
27446
        if (cert->akidSz > 0) {
27447
            /* Set Authority Key Identifier OID and data. */
27448
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_AKID_OID],
27449
                    akidOID, sizeof(akidOID));
27450
        #ifdef WOLFSSL_AKID_NAME
27451
            if (cert->rawAkid) {
27452
                SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_AKID_STR],
27453
                        cert->akid, (word32)cert->akidSz);
27454
                /* cert->akid contains the internal ext structure */
27455
                SetASNItem_NoOutBelow(dataASN, certExtsASN,
27456
                        CERTEXTSASN_IDX_AKID_STR, certExtsASN_Length);
27457
            }
27458
            else
27459
        #endif
27460
            {
27461
                SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_AKID_KEYID],
27462
                        cert->akid, (word32)cert->akidSz);
27463
            }
27464
        }
27465
        else
27466
    #endif
27467
        {
27468
            /* Don't write out Authority Key Identifier extension items. */
27469
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_AKID_SEQ,
27470
                    CERTEXTSASN_IDX_AKID_KEYID);
27471
        }
27472
    #ifdef WOLFSSL_CERT_EXT
27473
        if (cert->keyUsage != 0) {
27474
            /* Set Key Usage OID, critical and value. */
27475
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_KU_OID],
27476
                    kuOID, sizeof(kuOID));
27477
            SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_KU_CRIT], 1);
27478
            SetASN_Int16Bit(&dataASN[CERTEXTSASN_IDX_KU_USAGE],
27479
                    cert->keyUsage);
27480
        }
27481
        else
27482
    #endif
27483
        {
27484
            /* Don't write out Key Usage extension items. */
27485
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_KU_SEQ,
27486
                    CERTEXTSASN_IDX_KU_USAGE);
27487
        }
27488
    #ifdef WOLFSSL_CERT_EXT
27489
        if (cert->extKeyUsage != 0) {
27490
            /* Calculate size of Extended Key Usage data. */
27491
            sz = SetExtKeyUsage(cert, NULL, 0, cert->extKeyUsage);
27492
            if (sz <= 0) {
27493
                ret = KEYUSAGE_E;
27494
            }
27495
            /* Set Extended Key Usage OID and data. */
27496
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_EKU_OID],
27497
                    ekuOID, sizeof(ekuOID));
27498
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_EKU_STR],
27499
                    NULL, (word32)sz);
27500
        }
27501
        else
27502
    #endif
27503
        {
27504
            /* Don't write out Extended Key Usage extension items. */
27505
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_EKU_SEQ,
27506
                    CERTEXTSASN_IDX_EKU_STR);
27507
        }
27508
27509
    #ifdef WOLFSSL_CERT_EXT
27510
        if ((!forRequest) && (cert->certPoliciesNb > 0)) {
27511
            /* Calculate size of certificate policies. */
27512
            sz = SetCertificatePolicies(NULL, 0, cert->certPolicies,
27513
                    cert->certPoliciesNb, cert->heap);
27514
            if (sz > 0) {
27515
                /* Set Certificate Policies OID. */
27516
                SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_POLICIES_OID],
27517
                        cpOID, sizeof(cpOID));
27518
                /* Make space for data. */
27519
                SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_POLICIES_INFO],
27520
                        NULL, (word32)sz);
27521
            }
27522
            else {
27523
                ret = CERTPOLICIES_E;
27524
            }
27525
        }
27526
        else
27527
    #endif
27528
        {
27529
            /* Don't write out Certificate Policies extension items. */
27530
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_POLICIES_SEQ,
27531
                    CERTEXTSASN_IDX_POLICIES_INFO);
27532
        }
27533
    #if defined(WOLFSSL_CERT_EXT) && !defined(IGNORE_NETSCAPE_CERT_TYPE)
27534
        /* Netscape Certificate Type */
27535
        if (cert->nsCertType != 0) {
27536
            /* Set Netscape Certificate Type OID and data. */
27537
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_NSTYPE_OID],
27538
                    nsCertOID, sizeof(nsCertOID));
27539
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_NSTYPE_USAGE],
27540
                    &cert->nsCertType, 1);
27541
        }
27542
        else
27543
    #endif
27544
        {
27545
            /* Don't write out Netscape Certificate Type. */
27546
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_NSTYPE_SEQ,
27547
                    CERTEXTSASN_IDX_NSTYPE_USAGE);
27548
        }
27549
    #ifdef WOLFSSL_CERT_EXT
27550
        if (cert->crlInfoSz > 0) {
27551
            /* Set CRL Distribution Points OID and data. */
27552
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_CRLINFO_OID],
27553
                    crlInfoOID, sizeof(crlInfoOID));
27554
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_CRLINFO_STR],
27555
                    cert->crlInfo, (word32)cert->crlInfoSz);
27556
        }
27557
        else
27558
    #endif
27559
        {
27560
            /* Don't write out CRL Distribution Points. */
27561
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_CRLINFO_SEQ,
27562
                    CERTEXTSASN_IDX_CRLINFO_STR);
27563
        }
27564
27565
    #if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CUSTOM_OID)
27566
        /* encode a custom oid and value */
27567
        if (cert->extCustom.oidSz > 0) {
27568
            /* Set CRL Distribution Points OID and data. */
27569
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_CUSTOM_OID],
27570
                    cert->extCustom.oid, cert->extCustom.oidSz);
27571
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_CUSTOM_STR],
27572
                    cert->extCustom.val, cert->extCustom.valSz);
27573
        }
27574
        else
27575
    #endif
27576
        {
27577
            /* Don't write out custom OID. */
27578
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_CUSTOM_SEQ,
27579
                    CERTEXTSASN_IDX_CUSTOM_STR);
27580
        }
27581
27582
        i = 0;
27583
    #if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CUSTOM_OID)
27584
        for (; i < cert->customCertExtCount; i++) {
27585
             int idx = CERTEXTSASN_IDX_START_CUSTOM + (i * 4);
27586
             word32 encodedOidSz = MAX_OID_SZ;
27587
             idx++; /* Skip one for for SEQ. */
27588
             /* EncodePolicyOID() will never return error since we parsed this
27589
              * OID when it was set. */
27590
             EncodePolicyOID(&encodedOids[i * MAX_OID_SZ], &encodedOidSz,
27591
                             cert->customCertExt[i].oid, NULL);
27592
             SetASN_Buffer(&dataASN[idx], &encodedOids[i * MAX_OID_SZ],
27593
                           encodedOidSz);
27594
             idx++;
27595
             if (cert->customCertExt[i].crit) {
27596
                 SetASN_Boolean(&dataASN[idx], 1);
27597
             } else {
27598
                 dataASN[idx].noOut = 1;
27599
             }
27600
             idx++;
27601
             SetASN_Buffer(&dataASN[idx], cert->customCertExt[i].val,
27602
                           cert->customCertExt[i].valSz);
27603
        }
27604
    #endif
27605
27606
        while (i < NUM_CUSTOM_EXT) {
27607
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_START_CUSTOM + (i * 4),
27608
                             CERTEXTSASN_IDX_START_CUSTOM + (i * 4) + 3);
27609
            i++;
27610
        }
27611
    }
27612
27613
    if (ret == 0) {
27614
        /* Calculate size of encoded extensions. */
27615
        ret = SizeASN_Items(certExtsASN, dataASN, certExtsASN_Length, &sz);
27616
    }
27617
    if (ret == 0) {
27618
        /* Only SEQUENCE - don't encode extensions. */
27619
        if (sz == 2) {
27620
            sz = 0;
27621
        }
27622
        /* Check buffer is big enough. */
27623
        else if ((output != NULL) && (sz > (int)maxSz)) {
27624
            ret = BUFFER_E;
27625
        }
27626
    }
27627
27628
    if ((ret == 0) && (output != NULL) && (sz > 0)) {
27629
        /* Encode certificate extensions into buffer. */
27630
        SetASN_Items(certExtsASN, dataASN, certExtsASN_Length, output);
27631
27632
    #ifdef WOLFSSL_CERT_EXT
27633
        if (cert->extKeyUsage != 0){
27634
            /* Encode Extended Key Usage into space provided. */
27635
            if (SetExtKeyUsage(cert,
27636
                    (byte*)dataASN[CERTEXTSASN_IDX_EKU_STR].data.buffer.data,
27637
                    dataASN[CERTEXTSASN_IDX_EKU_STR].data.buffer.length,
27638
                    cert->extKeyUsage) <= 0) {
27639
                ret = KEYUSAGE_E;
27640
            }
27641
        }
27642
        if ((!forRequest) && (cert->certPoliciesNb > 0)) {
27643
            /* Encode Certificate Policies into space provided. */
27644
            if (SetCertificatePolicies(
27645
                    (byte*)dataASN[CERTEXTSASN_IDX_POLICIES_INFO].data.buffer.data,
27646
                    dataASN[CERTEXTSASN_IDX_POLICIES_INFO].data.buffer.length,
27647
                    cert->certPolicies, cert->certPoliciesNb, cert->heap) <= 0) {
27648
                ret = CERTPOLICIES_E;
27649
            }
27650
        }
27651
    #endif
27652
    }
27653
    if (ret == 0) {
27654
        /* Return the encoding size. */
27655
        ret = sz;
27656
    }
27657
27658
    FREE_ASNSETDATA(dataASN, cert->heap);
27659
#ifdef WOLFSSL_SMALL_STACK
27660
#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_CERT_EXT)
27661
    XFREE(encodedOids, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
27662
#endif
27663
    XFREE(certExtsASN, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
27664
#endif
27665
27666
    return ret;
27667
}
27668
#endif /* WOLFSSL_ASN_TEMPLATE */
27669
27670
#ifndef WOLFSSL_ASN_TEMPLATE
27671
/* Set Date validity from now until now + daysValid
27672
 * return size in bytes written to output, 0 on error */
27673
/* TODO https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.5
27674
 * "MUST always encode certificate validity dates through the year 2049 as
27675
 *  UTCTime; certificate validity dates in 2050 or later MUST be encoded as
27676
 *  GeneralizedTime." */
27677
static int SetValidity(byte* output, int daysValid)
27678
{
27679
#ifndef NO_ASN_TIME
27680
    byte before[MAX_DATE_SIZE];
27681
    byte  after[MAX_DATE_SIZE];
27682
27683
    word32 beforeSz, afterSz, seqSz;
27684
27685
    time_t now;
27686
    time_t then;
27687
    struct tm* tmpTime;
27688
    struct tm* expandedTime;
27689
    struct tm localTime;
27690
27691
#if defined(NEED_TMP_TIME)
27692
    /* for use with gmtime_r */
27693
    struct tm tmpTimeStorage;
27694
    tmpTime = &tmpTimeStorage;
27695
#else
27696
    tmpTime = NULL;
27697
#endif
27698
    (void)tmpTime;
27699
27700
    now = wc_Time(0);
27701
27702
    /* before now */
27703
    before[0] = ASN_GENERALIZED_TIME;
27704
    beforeSz = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1;  /* gen tag */
27705
27706
    /* subtract 1 day of seconds for more compliance */
27707
    then = now - 86400;
27708
    expandedTime = XGMTIME(&then, tmpTime);
27709
    if (expandedTime == NULL) {
27710
        WOLFSSL_MSG("XGMTIME failed");
27711
        return 0;   /* error */
27712
    }
27713
    localTime = *expandedTime;
27714
27715
    /* adjust */
27716
    localTime.tm_year += 1900;
27717
    localTime.tm_mon +=    1;
27718
27719
    SetTime(&localTime, before + beforeSz);
27720
    beforeSz += ASN_GEN_TIME_SZ;
27721
27722
    after[0] = ASN_GENERALIZED_TIME;
27723
    afterSz  = SetLength(ASN_GEN_TIME_SZ, after + 1) + 1;  /* gen tag */
27724
27725
    /* add daysValid of seconds */
27726
    then = now + (daysValid * (time_t)86400);
27727
    expandedTime = XGMTIME(&then, tmpTime);
27728
    if (expandedTime == NULL) {
27729
        WOLFSSL_MSG("XGMTIME failed");
27730
        return 0;   /* error */
27731
    }
27732
    localTime = *expandedTime;
27733
27734
    /* adjust */
27735
    localTime.tm_year += 1900;
27736
    localTime.tm_mon  +=    1;
27737
27738
    SetTime(&localTime, after + afterSz);
27739
    afterSz += ASN_GEN_TIME_SZ;
27740
27741
    /* headers and output */
27742
    seqSz = SetSequence(beforeSz + afterSz, output);
27743
    XMEMCPY(output + seqSz, before, beforeSz);
27744
    XMEMCPY(output + seqSz + beforeSz, after, afterSz);
27745
27746
    return (int)(seqSz + beforeSz + afterSz);
27747
#else
27748
    (void)output;
27749
    (void)daysValid;
27750
    return NOT_COMPILED_IN;
27751
#endif
27752
}
27753
#else
27754
static int SetValidity(byte* before, byte* after, int daysValid)
27755
{
27756
#ifndef NO_ASN_TIME
27757
    int ret = 0;
27758
    time_t now;
27759
    time_t then;
27760
    struct tm* tmpTime;
27761
    struct tm* expandedTime;
27762
    struct tm localTime;
27763
#if defined(NEED_TMP_TIME)
27764
    /* for use with gmtime_r */
27765
    struct tm tmpTimeStorage;
27766
    tmpTime = &tmpTimeStorage;
27767
#else
27768
    tmpTime = NULL;
27769
#endif
27770
    (void)tmpTime;
27771
27772
    now = wc_Time(0);
27773
27774
    /* subtract 1 day of seconds for more compliance */
27775
    then = now - 86400;
27776
    expandedTime = XGMTIME(&then, tmpTime);
27777
    if (expandedTime == NULL) {
27778
        WOLFSSL_MSG("XGMTIME failed");
27779
        ret = DATE_E;
27780
    }
27781
    if (ret == 0) {
27782
        localTime = *expandedTime;
27783
27784
        /* adjust */
27785
        localTime.tm_year += 1900;
27786
        localTime.tm_mon +=    1;
27787
27788
        SetTime(&localTime, before);
27789
27790
        /* add daysValid of seconds */
27791
        then = now + (daysValid * (time_t)86400);
27792
        expandedTime = XGMTIME(&then, tmpTime);
27793
        if (expandedTime == NULL) {
27794
            WOLFSSL_MSG("XGMTIME failed");
27795
            ret = DATE_E;
27796
        }
27797
    }
27798
    if (ret == 0) {
27799
        localTime = *expandedTime;
27800
27801
        /* adjust */
27802
        localTime.tm_year += 1900;
27803
        localTime.tm_mon  +=    1;
27804
27805
        SetTime(&localTime, after);
27806
    }
27807
27808
    return ret;
27809
#else
27810
    (void)before;
27811
    (void)after;
27812
    (void)daysValid;
27813
    return NOT_COMPILED_IN;
27814
#endif
27815
}
27816
#endif /* WOLFSSL_ASN_TEMPLATE */
27817
27818
27819
#ifndef WOLFSSL_ASN_TEMPLATE
27820
/* encode info from cert into DER encoded format */
27821
static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
27822
                      WC_RNG* rng, DsaKey* dsaKey, ed25519_key* ed25519Key,
27823
                      ed448_key* ed448Key, falcon_key* falconKey,
27824
                      dilithium_key* dilithiumKey, sphincs_key* sphincsKey)
27825
{
27826
    int ret;
27827
27828
    if (cert == NULL || der == NULL || rng == NULL)
27829
        return BAD_FUNC_ARG;
27830
27831
    /* make sure at least one key type is provided */
27832
    if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL &&
27833
        dsaKey == NULL && ed448Key == NULL && falconKey == NULL &&
27834
        dilithiumKey == NULL && sphincsKey == NULL) {
27835
        return PUBLIC_KEY_E;
27836
    }
27837
27838
    /* init */
27839
    XMEMSET(der, 0, sizeof(DerCert));
27840
27841
    /* version */
27842
    der->versionSz = SetMyVersion((word32)cert->version, der->version, TRUE);
27843
27844
    /* serial number (must be positive) */
27845
    if (cert->serialSz == 0) {
27846
        /* generate random serial */
27847
        cert->serialSz = CTC_GEN_SERIAL_SZ;
27848
        ret = wc_RNG_GenerateBlock(rng, cert->serial, (word32)cert->serialSz);
27849
        if (ret != 0)
27850
            return ret;
27851
        /* Clear the top bit to avoid a negative value */
27852
        cert->serial[0] &= 0x7f;
27853
    }
27854
    der->serialSz = SetSerialNumber(cert->serial, (word32)cert->serialSz,
27855
                                    der->serial, sizeof(der->serial),
27856
                                    CTC_SERIAL_SIZE);
27857
    if (der->serialSz < 0)
27858
        return der->serialSz;
27859
27860
    /* signature algo */
27861
    der->sigAlgoSz = (int)SetAlgoID(cert->sigType, der->sigAlgo, oidSigType, 0);
27862
    if (der->sigAlgoSz <= 0)
27863
        return ALGO_ID_E;
27864
27865
    /* public key */
27866
#ifndef NO_RSA
27867
    if (cert->keyType == RSA_KEY) {
27868
        if (rsaKey == NULL)
27869
            return PUBLIC_KEY_E;
27870
        der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey,
27871
                                           sizeof(der->publicKey), 1);
27872
    }
27873
#endif
27874
27875
#ifdef HAVE_ECC
27876
    if (cert->keyType == ECC_KEY) {
27877
        if (eccKey == NULL)
27878
            return PUBLIC_KEY_E;
27879
        der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey,
27880
                                           sizeof(der->publicKey), 1, 0);
27881
    }
27882
#endif
27883
27884
#if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
27885
    if (cert->keyType == DSA_KEY) {
27886
        if (dsaKey == NULL)
27887
            return PUBLIC_KEY_E;
27888
        der->publicKeySz = wc_SetDsaPublicKey(der->publicKey, dsaKey,
27889
                                              sizeof(der->publicKey), 1);
27890
    }
27891
#endif
27892
27893
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
27894
    if (cert->keyType == ED25519_KEY) {
27895
        if (ed25519Key == NULL)
27896
            return PUBLIC_KEY_E;
27897
        der->publicKeySz = wc_Ed25519PublicKeyToDer(ed25519Key, der->publicKey,
27898
            (word32)sizeof(der->publicKey), 1);
27899
    }
27900
#endif
27901
27902
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
27903
    if (cert->keyType == ED448_KEY) {
27904
        if (ed448Key == NULL)
27905
            return PUBLIC_KEY_E;
27906
        der->publicKeySz = wc_Ed448PublicKeyToDer(ed448Key, der->publicKey,
27907
            (word32)sizeof(der->publicKey), 1);
27908
    }
27909
#endif
27910
27911
#if defined(HAVE_PQC)
27912
#if defined(HAVE_FALCON)
27913
    if ((cert->keyType == FALCON_LEVEL1_KEY) ||
27914
        (cert->keyType == FALCON_LEVEL5_KEY)) {
27915
        if (falconKey == NULL)
27916
            return PUBLIC_KEY_E;
27917
27918
        der->publicKeySz =
27919
            wc_Falcon_PublicKeyToDer(falconKey, der->publicKey,
27920
                                     (word32)sizeof(der->publicKey), 1);
27921
    }
27922
#endif /* HAVE_FALCON */
27923
#if defined(HAVE_DILITHIUM)
27924
    if ((cert->keyType == DILITHIUM_LEVEL2_KEY) ||
27925
        (cert->keyType == DILITHIUM_LEVEL3_KEY) ||
27926
        (cert->keyType == DILITHIUM_LEVEL5_KEY)) {
27927
        if (dilithiumKey == NULL)
27928
            return PUBLIC_KEY_E;
27929
27930
        der->publicKeySz =
27931
            wc_Dilithium_PublicKeyToDer(dilithiumKey, der->publicKey,
27932
                                     (word32)sizeof(der->publicKey), 1);
27933
    }
27934
#endif /* HAVE_DILITHIUM */
27935
#if defined(HAVE_SPHINCS)
27936
    if ((cert->keyType == SPHINCS_FAST_LEVEL1_KEY) ||
27937
        (cert->keyType == SPHINCS_FAST_LEVEL3_KEY) ||
27938
        (cert->keyType == SPHINCS_FAST_LEVEL5_KEY) ||
27939
        (cert->keyType == SPHINCS_SMALL_LEVEL1_KEY) ||
27940
        (cert->keyType == SPHINCS_SMALL_LEVEL3_KEY) ||
27941
        (cert->keyType == SPHINCS_SMALL_LEVEL5_KEY)) {
27942
        if (sphincsKey == NULL)
27943
            return PUBLIC_KEY_E;
27944
27945
        der->publicKeySz =
27946
            wc_Sphincs_PublicKeyToDer(sphincsKey, der->publicKey,
27947
                                      (word32)sizeof(der->publicKey), 1);
27948
    }
27949
#endif /* HAVE_SPHINCS */
27950
#endif /* HAVE_PQC */
27951
27952
    if (der->publicKeySz <= 0)
27953
        return PUBLIC_KEY_E;
27954
27955
    der->validitySz = 0;
27956
    /* copy date validity if already set in cert struct */
27957
    if (cert->beforeDateSz && cert->afterDateSz) {
27958
        der->validitySz = CopyValidity(der->validity, cert);
27959
        if (der->validitySz <= 0)
27960
            return DATE_E;
27961
    }
27962
27963
    /* set date validity using daysValid if not set already */
27964
    if (der->validitySz == 0) {
27965
        der->validitySz = SetValidity(der->validity, cert->daysValid);
27966
        if (der->validitySz <= 0)
27967
            return DATE_E;
27968
    }
27969
27970
    /* subject name */
27971
#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
27972
    if (XSTRLEN((const char*)cert->sbjRaw) > 0) {
27973
        /* Use the raw subject */
27974
        word32 idx;
27975
27976
        der->subjectSz = (int)min((word32)sizeof(der->subject),
27977
                                  (word32)XSTRLEN((const char*)cert->sbjRaw));
27978
        /* header */
27979
        idx = SetSequence((word32)der->subjectSz, der->subject);
27980
        if ((word32)der->subjectSz + idx > (word32)sizeof(der->subject)) {
27981
            return SUBJECT_E;
27982
        }
27983
27984
        XMEMCPY((char*)der->subject + idx, (const char*)cert->sbjRaw,
27985
                (size_t)der->subjectSz);
27986
        der->subjectSz += (int)idx;
27987
    }
27988
    else
27989
#endif
27990
    {
27991
        /* Use the name structure */
27992
        der->subjectSz = SetNameEx(der->subject, sizeof(der->subject),
27993
                &cert->subject, cert->heap);
27994
    }
27995
    if (der->subjectSz <= 0)
27996
        return SUBJECT_E;
27997
27998
    /* issuer name */
27999
#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
28000
    if (XSTRLEN((const char*)cert->issRaw) > 0) {
28001
        /* Use the raw issuer */
28002
        word32 idx;
28003
28004
        der->issuerSz = (int)min((word32)sizeof(der->issuer),
28005
                                 (word32)XSTRLEN((const char*)cert->issRaw));
28006
28007
        /* header */
28008
        idx = SetSequence((word32)der->issuerSz, der->issuer);
28009
        if ((word32)der->issuerSz + idx > (word32)sizeof(der->issuer)) {
28010
            return ISSUER_E;
28011
        }
28012
28013
        XMEMCPY((char*)der->issuer + idx, (const char*)cert->issRaw,
28014
                (size_t)der->issuerSz);
28015
        der->issuerSz += (int)idx;
28016
    }
28017
    else
28018
#endif
28019
    {
28020
        /* Use the name structure */
28021
        der->issuerSz = SetNameEx(der->issuer, sizeof(der->issuer),
28022
                cert->selfSigned ? &cert->subject : &cert->issuer, cert->heap);
28023
    }
28024
    if (der->issuerSz <= 0)
28025
        return ISSUER_E;
28026
28027
    /* set the extensions */
28028
    der->extensionsSz = 0;
28029
28030
    /* RFC 5280 : 4.2.1.9. Basic Constraints
28031
     * The pathLenConstraint field is meaningful only if the CA boolean is
28032
     * asserted and the key usage extension, if present, asserts the
28033
     * keyCertSign bit */
28034
    /* Set CA and path length */
28035
    if ((cert->isCA) && (cert->pathLenSet)
28036
#ifdef WOLFSSL_CERT_EXT
28037
        && ((cert->keyUsage & KEYUSE_KEY_CERT_SIGN) || (!cert->keyUsage))
28038
#endif
28039
        ) {
28040
        der->caSz = SetCaWithPathLen(der->ca, sizeof(der->ca), cert->pathLen);
28041
        if (der->caSz <= 0)
28042
            return CA_TRUE_E;
28043
28044
        der->extensionsSz += der->caSz;
28045
    }
28046
    /* Set CA */
28047
    else if (cert->isCA) {
28048
        der->caSz = SetCa(der->ca, sizeof(der->ca));
28049
        if (der->caSz <= 0)
28050
            return CA_TRUE_E;
28051
28052
        der->extensionsSz += der->caSz;
28053
    }
28054
    /* Set Basic Constraint */
28055
    else if (cert->basicConstSet) {
28056
        der->caSz = SetBC(der->ca, sizeof(der->ca));
28057
        if (der->caSz <= 0)
28058
            return EXTENSIONS_E;
28059
28060
        der->extensionsSz += der->caSz;
28061
    }
28062
    else
28063
        der->caSz = 0;
28064
28065
#ifdef WOLFSSL_ALT_NAMES
28066
    /* Alternative Name */
28067
    if (cert->altNamesSz) {
28068
        der->altNamesSz = SetAltNames(der->altNames, sizeof(der->altNames),
28069
                                      cert->altNames, (word32)cert->altNamesSz,
28070
                                      cert->altNamesCrit);
28071
        if (der->altNamesSz <= 0)
28072
            return ALT_NAME_E;
28073
28074
        der->extensionsSz += der->altNamesSz;
28075
    }
28076
    else
28077
        der->altNamesSz = 0;
28078
#endif
28079
28080
#ifdef WOLFSSL_CERT_EXT
28081
    /* SKID */
28082
    if (cert->skidSz) {
28083
        /* check the provided SKID size */
28084
        if (cert->skidSz > (int)min(CTC_MAX_SKID_SIZE, sizeof(der->skid)))
28085
            return SKID_E;
28086
28087
        /* Note: different skid buffers sizes for der (MAX_KID_SZ) and
28088
            cert (CTC_MAX_SKID_SIZE). */
28089
        der->skidSz = SetSKID(der->skid, sizeof(der->skid),
28090
                              cert->skid, (word32)cert->skidSz);
28091
        if (der->skidSz <= 0)
28092
            return SKID_E;
28093
28094
        der->extensionsSz += der->skidSz;
28095
    }
28096
    else
28097
        der->skidSz = 0;
28098
28099
    /* AKID */
28100
    if (cert->akidSz) {
28101
        /* check the provided AKID size */
28102
        if ((
28103
#ifdef WOLFSSL_AKID_NAME
28104
             !cert->rawAkid &&
28105
#endif
28106
              cert->akidSz > (int)min(CTC_MAX_AKID_SIZE, sizeof(der->akid)))
28107
#ifdef WOLFSSL_AKID_NAME
28108
          || (cert->rawAkid && cert->akidSz > (int)sizeof(der->akid))
28109
#endif
28110
             )
28111
            return AKID_E;
28112
28113
        der->akidSz = SetAKID(der->akid, sizeof(der->akid), cert->akid,
28114
                              (word32)cert->akidSz,
28115
#ifdef WOLFSSL_AKID_NAME
28116
                              cert->rawAkid
28117
#else
28118
                              0
28119
#endif
28120
                              );
28121
        if (der->akidSz <= 0)
28122
            return AKID_E;
28123
28124
        der->extensionsSz += der->akidSz;
28125
    }
28126
    else
28127
        der->akidSz = 0;
28128
28129
    /* Key Usage */
28130
    if (cert->keyUsage != 0){
28131
        der->keyUsageSz = SetKeyUsage(der->keyUsage, sizeof(der->keyUsage),
28132
                                      cert->keyUsage);
28133
        if (der->keyUsageSz <= 0)
28134
            return KEYUSAGE_E;
28135
28136
        der->extensionsSz += der->keyUsageSz;
28137
    }
28138
    else
28139
        der->keyUsageSz = 0;
28140
28141
    /* Extended Key Usage */
28142
    if (cert->extKeyUsage != 0){
28143
        der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage,
28144
                                sizeof(der->extKeyUsage), cert->extKeyUsage);
28145
        if (der->extKeyUsageSz <= 0)
28146
            return EXTKEYUSAGE_E;
28147
28148
        der->extensionsSz += der->extKeyUsageSz;
28149
    }
28150
    else
28151
        der->extKeyUsageSz = 0;
28152
28153
#ifndef IGNORE_NETSCAPE_CERT_TYPE
28154
    /* Netscape Certificate Type */
28155
    if (cert->nsCertType != 0) {
28156
        der->nsCertTypeSz = SetNsCertType(cert, der->nsCertType,
28157
                                sizeof(der->nsCertType), cert->nsCertType);
28158
        if (der->nsCertTypeSz <= 0)
28159
            return EXTENSIONS_E;
28160
28161
        der->extensionsSz += der->nsCertTypeSz;
28162
    }
28163
    else
28164
        der->nsCertTypeSz = 0;
28165
#endif
28166
28167
    if (cert->crlInfoSz > 0) {
28168
        der->crlInfoSz = SetCRLInfo(cert, der->crlInfo, sizeof(der->crlInfo),
28169
                                cert->crlInfo, cert->crlInfoSz);
28170
        if (der->crlInfoSz <= 0)
28171
            return EXTENSIONS_E;
28172
28173
        der->extensionsSz += der->crlInfoSz;
28174
    }
28175
    else
28176
        der->crlInfoSz = 0;
28177
28178
    /* Certificate Policies */
28179
    if (cert->certPoliciesNb != 0) {
28180
        der->certPoliciesSz = SetCertificatePolicies(der->certPolicies,
28181
                                                     sizeof(der->certPolicies),
28182
                                                     cert->certPolicies,
28183
                                                     cert->certPoliciesNb,
28184
                                                     cert->heap);
28185
        if (der->certPoliciesSz <= 0)
28186
            return CERTPOLICIES_E;
28187
28188
        der->extensionsSz += der->certPoliciesSz;
28189
    }
28190
    else
28191
        der->certPoliciesSz = 0;
28192
#endif /* WOLFSSL_CERT_EXT */
28193
28194
    /* put extensions */
28195
    if (der->extensionsSz > 0) {
28196
28197
        /* put the start of extensions sequence (ID, Size) */
28198
        der->extensionsSz = SetExtensionsHeader(der->extensions,
28199
                                                sizeof(der->extensions),
28200
                                                (word32)der->extensionsSz);
28201
        if (der->extensionsSz <= 0)
28202
            return EXTENSIONS_E;
28203
28204
        /* put CA */
28205
        if (der->caSz) {
28206
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
28207
                                &der->extensionsSz,
28208
                                der->ca, der->caSz);
28209
            if (ret == 0)
28210
                return EXTENSIONS_E;
28211
        }
28212
28213
#ifdef WOLFSSL_ALT_NAMES
28214
        /* put Alternative Names */
28215
        if (der->altNamesSz) {
28216
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
28217
                                &der->extensionsSz,
28218
                                der->altNames, der->altNamesSz);
28219
            if (ret <= 0)
28220
                return EXTENSIONS_E;
28221
        }
28222
#endif
28223
28224
#ifdef WOLFSSL_CERT_EXT
28225
        /* put SKID */
28226
        if (der->skidSz) {
28227
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
28228
                                &der->extensionsSz,
28229
                                der->skid, der->skidSz);
28230
            if (ret <= 0)
28231
                return EXTENSIONS_E;
28232
        }
28233
28234
        /* put AKID */
28235
        if (der->akidSz) {
28236
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
28237
                                &der->extensionsSz,
28238
                                der->akid, der->akidSz);
28239
            if (ret <= 0)
28240
                return EXTENSIONS_E;
28241
        }
28242
28243
        /* put CRL Distribution Points */
28244
        if (der->crlInfoSz) {
28245
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
28246
                                &der->extensionsSz,
28247
                                der->crlInfo, der->crlInfoSz);
28248
            if (ret <= 0)
28249
                return EXTENSIONS_E;
28250
        }
28251
28252
        /* put KeyUsage */
28253
        if (der->keyUsageSz) {
28254
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
28255
                                &der->extensionsSz,
28256
                                der->keyUsage, der->keyUsageSz);
28257
            if (ret <= 0)
28258
                return EXTENSIONS_E;
28259
        }
28260
28261
        /* put ExtendedKeyUsage */
28262
        if (der->extKeyUsageSz) {
28263
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
28264
                                &der->extensionsSz,
28265
                                der->extKeyUsage, der->extKeyUsageSz);
28266
            if (ret <= 0)
28267
                return EXTENSIONS_E;
28268
        }
28269
28270
        /* put Netscape Cert Type */
28271
#ifndef IGNORE_NETSCAPE_CERT_TYPE
28272
        if (der->nsCertTypeSz) {
28273
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
28274
                                &der->extensionsSz,
28275
                                der->nsCertType, der->nsCertTypeSz);
28276
            if (ret <= 0)
28277
                return EXTENSIONS_E;
28278
        }
28279
#endif
28280
28281
        /* put Certificate Policies */
28282
        if (der->certPoliciesSz) {
28283
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
28284
                                &der->extensionsSz,
28285
                                der->certPolicies, der->certPoliciesSz);
28286
            if (ret <= 0)
28287
                return EXTENSIONS_E;
28288
        }
28289
#endif /* WOLFSSL_CERT_EXT */
28290
    }
28291
28292
    der->total = der->versionSz + der->serialSz + der->sigAlgoSz +
28293
        der->publicKeySz + der->validitySz + der->subjectSz + der->issuerSz +
28294
        der->extensionsSz;
28295
28296
    return 0;
28297
}
28298
28299
28300
/* write DER encoded cert to buffer, size already checked */
28301
static int WriteCertBody(DerCert* der, byte* buf)
28302
{
28303
    word32 idx;
28304
28305
    /* signed part header */
28306
    idx = SetSequence((word32)der->total, buf);
28307
    /* version */
28308
    XMEMCPY(buf + idx, der->version, (size_t)der->versionSz);
28309
    idx += (word32)der->versionSz;
28310
    /* serial */
28311
    XMEMCPY(buf + idx, der->serial, (size_t)der->serialSz);
28312
    idx += (word32)der->serialSz;
28313
    /* sig algo */
28314
    XMEMCPY(buf + idx, der->sigAlgo, (size_t)der->sigAlgoSz);
28315
    idx += (word32)der->sigAlgoSz;
28316
    /* issuer */
28317
    XMEMCPY(buf + idx, der->issuer, (size_t)der->issuerSz);
28318
    idx += (word32)der->issuerSz;
28319
    /* validity */
28320
    XMEMCPY(buf + idx, der->validity, (size_t)der->validitySz);
28321
    idx += (word32)der->validitySz;
28322
    /* subject */
28323
    XMEMCPY(buf + idx, der->subject, (size_t)der->subjectSz);
28324
    idx += (word32)der->subjectSz;
28325
    /* public key */
28326
    XMEMCPY(buf + idx, der->publicKey, (size_t)der->publicKeySz);
28327
    idx += (word32)der->publicKeySz;
28328
    if (der->extensionsSz) {
28329
        /* extensions */
28330
        XMEMCPY(buf + idx, der->extensions,
28331
                min((word32)der->extensionsSz,
28332
                    (word32)sizeof(der->extensions)));
28333
        idx += (word32)der->extensionsSz;
28334
    }
28335
28336
    return (int)idx;
28337
}
28338
#endif /* !WOLFSSL_ASN_TEMPLATE */
28339
28340
28341
/* Make signature from buffer (sz), write to sig (sigSz) */
28342
static int MakeSignature(CertSignCtx* certSignCtx, const byte* buf, word32 sz,
28343
    byte* sig, word32 sigSz, RsaKey* rsaKey, ecc_key* eccKey,
28344
    ed25519_key* ed25519Key, ed448_key* ed448Key, falcon_key* falconKey,
28345
    dilithium_key* dilithiumKey, sphincs_key* sphincsKey, WC_RNG* rng,
28346
    word32 sigAlgoType, void* heap)
28347
{
28348
    int digestSz = 0, typeH = 0, ret = 0;
28349
28350
    (void)digestSz;
28351
    (void)typeH;
28352
    (void)buf;
28353
    (void)sz;
28354
    (void)sig;
28355
    (void)sigSz;
28356
    (void)rsaKey;
28357
    (void)eccKey;
28358
    (void)ed25519Key;
28359
    (void)ed448Key;
28360
    (void)falconKey;
28361
    (void)dilithiumKey;
28362
    (void)sphincsKey;
28363
    (void)rng;
28364
    (void)heap;
28365
28366
    switch (certSignCtx->state) {
28367
    case CERTSIGN_STATE_BEGIN:
28368
    case CERTSIGN_STATE_DIGEST:
28369
28370
        certSignCtx->state = CERTSIGN_STATE_DIGEST;
28371
        certSignCtx->digest = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap,
28372
            DYNAMIC_TYPE_TMP_BUFFER);
28373
        if (certSignCtx->digest == NULL) {
28374
            ret = MEMORY_E; goto exit_ms;
28375
        }
28376
28377
        ret = HashForSignature(buf, sz, sigAlgoType, certSignCtx->digest,
28378
                               &typeH, &digestSz, 0);
28379
        /* set next state, since WC_PENDING_E rentry for these are not "call again" */
28380
        certSignCtx->state = CERTSIGN_STATE_ENCODE;
28381
        if (ret != 0) {
28382
            goto exit_ms;
28383
        }
28384
        FALL_THROUGH;
28385
28386
    case CERTSIGN_STATE_ENCODE:
28387
    #ifndef NO_RSA
28388
        if (rsaKey) {
28389
            certSignCtx->encSig = (byte*)XMALLOC(MAX_DER_DIGEST_SZ, heap,
28390
                DYNAMIC_TYPE_TMP_BUFFER);
28391
            if (certSignCtx->encSig == NULL) {
28392
                ret = MEMORY_E; goto exit_ms;
28393
            }
28394
28395
            /* signature */
28396
            certSignCtx->encSigSz = (int)wc_EncodeSignature(certSignCtx->encSig,
28397
                                  certSignCtx->digest, (word32)digestSz, typeH);
28398
        }
28399
    #endif /* !NO_RSA */
28400
        FALL_THROUGH;
28401
28402
    case CERTSIGN_STATE_DO:
28403
        certSignCtx->state = CERTSIGN_STATE_DO;
28404
        ret = ALGO_ID_E; /* default to error */
28405
28406
    #ifndef NO_RSA
28407
        if (rsaKey) {
28408
            /* signature */
28409
            ret = wc_RsaSSL_Sign(certSignCtx->encSig,
28410
                                 (word32)certSignCtx->encSigSz,
28411
                                 sig, sigSz, rsaKey, rng);
28412
        }
28413
    #endif /* !NO_RSA */
28414
28415
    #if defined(HAVE_ECC) && defined(HAVE_ECC_SIGN)
28416
        if (!rsaKey && eccKey) {
28417
            word32 outSz = sigSz;
28418
28419
            ret = wc_ecc_sign_hash(certSignCtx->digest, (word32)digestSz,
28420
                                   sig, &outSz, rng, eccKey);
28421
            if (ret == 0)
28422
                ret = (int)outSz;
28423
        }
28424
    #endif /* HAVE_ECC && HAVE_ECC_SIGN */
28425
28426
    #if defined(HAVE_ED25519) && defined(HAVE_ED25519_SIGN)
28427
        if (!rsaKey && !eccKey && ed25519Key) {
28428
            word32 outSz = sigSz;
28429
28430
            ret = wc_ed25519_sign_msg(buf, sz, sig, &outSz, ed25519Key);
28431
            if (ret == 0)
28432
                ret = (int)outSz;
28433
        }
28434
    #endif /* HAVE_ED25519 && HAVE_ED25519_SIGN */
28435
28436
    #if defined(HAVE_ED448) && defined(HAVE_ED448_SIGN)
28437
        if (!rsaKey && !eccKey && !ed25519Key && ed448Key) {
28438
            word32 outSz = sigSz;
28439
28440
            ret = wc_ed448_sign_msg(buf, sz, sig, &outSz, ed448Key, NULL, 0);
28441
            if (ret == 0)
28442
                ret = (int)outSz;
28443
        }
28444
    #endif /* HAVE_ED448 && HAVE_ED448_SIGN */
28445
28446
    #if defined(HAVE_PQC)
28447
    #if defined(HAVE_FALCON)
28448
        if (!rsaKey && !eccKey && !ed25519Key && !ed448Key && falconKey) {
28449
            word32 outSz = sigSz;
28450
            ret = wc_falcon_sign_msg(buf, sz, sig, &outSz, falconKey);
28451
            if (ret == 0)
28452
                ret = outSz;
28453
        }
28454
    #endif /* HAVE_FALCON */
28455
    #if defined(HAVE_DILITHIUM)
28456
        if (!rsaKey && !eccKey && !ed25519Key && !ed448Key && !falconKey &&
28457
            dilithiumKey) {
28458
            word32 outSz = sigSz;
28459
            ret = wc_dilithium_sign_msg(buf, sz, sig, &outSz, dilithiumKey);
28460
            if (ret == 0)
28461
                ret = outSz;
28462
        }
28463
    #endif /* HAVE_DILITHIUM */
28464
    #if defined(HAVE_SPHINCS)
28465
        if (!rsaKey && !eccKey && !ed25519Key && !ed448Key && !falconKey &&
28466
            !dilithiumKey && sphincsKey) {
28467
            word32 outSz = sigSz;
28468
            ret = wc_sphincs_sign_msg(buf, sz, sig, &outSz, sphincsKey);
28469
            if (ret == 0)
28470
                ret = outSz;
28471
        }
28472
    #endif /* HAVE_SPHINCS */
28473
    #endif /* HAVE_PQC */
28474
28475
        break;
28476
    }
28477
28478
exit_ms:
28479
28480
#ifdef WOLFSSL_ASYNC_CRYPT
28481
    if (ret == WC_PENDING_E) {
28482
        return ret;
28483
    }
28484
#endif
28485
28486
#ifndef NO_RSA
28487
    if (rsaKey) {
28488
        XFREE(certSignCtx->encSig, heap, DYNAMIC_TYPE_TMP_BUFFER);
28489
    }
28490
#endif /* !NO_RSA */
28491
28492
    XFREE(certSignCtx->digest, heap, DYNAMIC_TYPE_TMP_BUFFER);
28493
    certSignCtx->digest = NULL;
28494
28495
    /* reset state */
28496
    certSignCtx->state = CERTSIGN_STATE_BEGIN;
28497
28498
    if (ret < 0) {
28499
        WOLFSSL_ERROR_VERBOSE(ret);
28500
    }
28501
28502
    return ret;
28503
}
28504
28505
28506
#ifdef WOLFSSL_ASN_TEMPLATE
28507
/* Generate a random integer value of at most len bytes.
28508
 *
28509
 * Most-significant bit will not be set when maximum size.
28510
 * Random value may be smaller than maximum size in bytes.
28511
 *
28512
 * @param [in]  rng  Random number generator.
28513
 * @param [out] out  Buffer to hold integer value.
28514
 * @param [in]  len  Maximum number of bytes of integer.
28515
 * @return  0 on success.
28516
 * @return  -ve when random number generation failed.
28517
 */
28518
static int GenerateInteger(WC_RNG* rng, byte* out, word32 len)
28519
{
28520
    int ret;
28521
28522
    /* Generate random number. */
28523
    ret = wc_RNG_GenerateBlock(rng, out, len);
28524
    if (ret == 0) {
28525
        int i;
28526
28527
        /* Clear the top bit to make positive. */
28528
        out[0] &= 0x7f;
28529
28530
        /* Find first non-zero byte. One zero byte is valid though. */
28531
        for (i = 0; i < (int)len - 1; i++) {
28532
            if (out[i] != 0) {
28533
                break;
28534
            }
28535
        }
28536
        if (i != 0) {
28537
            /* Remove leading zeros. */
28538
            XMEMMOVE(out, out + i, (size_t)len - (size_t)i);
28539
        }
28540
    }
28541
28542
    return ret;
28543
}
28544
28545
/* ASN.1 template for a Certificate.
28546
 * X.509: RFC 5280, 4.1 - Basic Certificate Fields.
28547
 */
28548
static const ASNItem sigASN[] = {
28549
/* SEQ          */    { 0, ASN_SEQUENCE, 1, 1, 0 },
28550
                                     /* tbsCertificate */
28551
/* TBS_SEQ      */        { 1, ASN_SEQUENCE, 1, 0, 0 },
28552
                                     /* signatureAlgorithm */
28553
/* SIGALGO_SEQ  */        { 1, ASN_SEQUENCE, 1, 1, 0 },
28554
/* SIGALGO_OID  */            { 2, ASN_OBJECT_ID, 0, 0, 0 },
28555
/* SIGALGO_NULL */            { 2, ASN_TAG_NULL, 0, 0, 0 },
28556
                                     /* signatureValue */
28557
/* SIGNATURE    */        { 1, ASN_BIT_STRING, 0, 0, 0 },
28558
};
28559
enum {
28560
    SIGASN_IDX_SEQ = 0,
28561
    SIGASN_IDX_TBS_SEQ,
28562
    SIGASN_IDX_SIGALGO_SEQ,
28563
    SIGASN_IDX_SIGALGO_OID,
28564
    SIGASN_IDX_SIGALGO_NULL,
28565
    SIGASN_IDX_SIGNATURE
28566
};
28567
28568
/* Number of items in ASN.1 template for a Certificate. */
28569
#define sigASN_Length (sizeof(sigASN) / sizeof(ASNItem))
28570
#endif
28571
28572
/* add signature to end of buffer, size of buffer assumed checked, return
28573
   new length */
28574
int AddSignature(byte* buf, int bodySz, const byte* sig, int sigSz,
28575
                        int sigAlgoType)
28576
{
28577
#ifndef WOLFSSL_ASN_TEMPLATE
28578
    byte seq[MAX_SEQ_SZ];
28579
    word32 idx, seqSz;
28580
28581
    if ((bodySz < 0) || (sigSz < 0))
28582
        return BUFFER_E;
28583
28584
    idx = (word32)bodySz;
28585
28586
    /* algo */
28587
    idx += SetAlgoID(sigAlgoType, buf ? buf + idx : NULL, oidSigType, 0);
28588
    /* bit string */
28589
    idx += SetBitString((word32)sigSz, 0, buf ? buf + idx : NULL);
28590
    /* signature */
28591
    if (buf)
28592
        XMEMCPY(buf + idx, sig, (size_t)sigSz);
28593
    idx += (word32)sigSz;
28594
28595
    /* make room for overall header */
28596
    seqSz = SetSequence(idx, seq);
28597
    if (buf) {
28598
        XMEMMOVE(buf + seqSz, buf, idx);
28599
        XMEMCPY(buf, seq, seqSz);
28600
    }
28601
28602
    return (int)(idx + seqSz);
28603
#else
28604
    DECL_ASNSETDATA(dataASN, sigASN_Length);
28605
    word32 seqSz;
28606
    int sz;
28607
    int ret = 0;
28608
28609
    CALLOC_ASNSETDATA(dataASN, sigASN_Length, ret, NULL);
28610
28611
    /* In place, put body between SEQUENCE and signature. */
28612
    if (ret == 0) {
28613
        /* Set sigature OID and signature data. */
28614
        SetASN_OID(&dataASN[SIGASN_IDX_SIGALGO_OID], (word32)sigAlgoType,
28615
                   oidSigType);
28616
        if (IsSigAlgoECC((word32)sigAlgoType)) {
28617
            /* ECDSA and EdDSA doesn't have NULL tagged item. */
28618
            dataASN[SIGASN_IDX_SIGALGO_NULL].noOut = 1;
28619
        }
28620
        SetASN_Buffer(&dataASN[SIGASN_IDX_SIGNATURE], sig, (word32)sigSz);
28621
        /* Calculate size of signature data. */
28622
        ret = SizeASN_Items(&sigASN[SIGASN_IDX_SIGALGO_SEQ],
28623
                &dataASN[SIGASN_IDX_SIGALGO_SEQ], sigASN_Length - 2, &sz);
28624
    }
28625
    if (ret == 0) {
28626
        /* Calculate size of outer sequence by calculating size of the encoded
28627
         * length and adding 1 for tag. */
28628
        seqSz = SizeASNHeader((word32)bodySz + (word32)sz);
28629
        if (buf != NULL) {
28630
            /* Move body to after sequence. */
28631
            XMEMMOVE(buf + seqSz, buf, (size_t)bodySz);
28632
        }
28633
        /* Leave space for body in encoding. */
28634
        SetASN_ReplaceBuffer(&dataASN[SIGASN_IDX_TBS_SEQ], NULL,
28635
                             (word32)bodySz);
28636
28637
        /* Calculate overall size and put in offsets and lengths. */
28638
        ret = SizeASN_Items(sigASN, dataASN, sigASN_Length, &sz);
28639
    }
28640
    if ((ret == 0) && (buf != NULL)) {
28641
        /* Write SEQUENCE and signature around body. */
28642
        SetASN_Items(sigASN, dataASN, sigASN_Length, buf);
28643
    }
28644
28645
    if (ret == 0) {
28646
        /* Return the encoding size. */
28647
        ret = sz;
28648
    }
28649
28650
    FREE_ASNSETDATA(dataASN, NULL);
28651
    return ret;
28652
#endif /* WOLFSSL_ASN_TEMPLATE */
28653
}
28654
28655
28656
/* Make an x509 Certificate v3 any key type from cert input, write to buffer */
28657
static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
28658
                       RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng,
28659
                       DsaKey* dsaKey, ed25519_key* ed25519Key,
28660
                       ed448_key* ed448Key, falcon_key* falconKey,
28661
                       dilithium_key* dilithiumKey, sphincs_key* sphincsKey)
28662
{
28663
#ifndef WOLFSSL_ASN_TEMPLATE
28664
    int ret;
28665
#ifdef WOLFSSL_SMALL_STACK
28666
    DerCert* der;
28667
#else
28668
    DerCert der[1];
28669
#endif
28670
28671
    if (derBuffer == NULL)
28672
        return BAD_FUNC_ARG;
28673
28674
    if (eccKey)
28675
        cert->keyType = ECC_KEY;
28676
    else if (rsaKey)
28677
        cert->keyType = RSA_KEY;
28678
    else if (dsaKey)
28679
        cert->keyType = DSA_KEY;
28680
    else if (ed25519Key)
28681
        cert->keyType = ED25519_KEY;
28682
    else if (ed448Key)
28683
        cert->keyType = ED448_KEY;
28684
#ifdef HAVE_PQC
28685
#ifdef HAVE_FALCON
28686
    else if ((falconKey != NULL) && (falconKey->level == 1))
28687
        cert->keyType = FALCON_LEVEL1_KEY;
28688
    else if ((falconKey != NULL) && (falconKey->level == 5))
28689
        cert->keyType = FALCON_LEVEL5_KEY;
28690
#endif /* HAVE_FALCON */
28691
#ifdef HAVE_DILITHIUM
28692
    else if ((dilithiumKey != NULL) && (dilithiumKey->level == 2))
28693
        cert->keyType = DILITHIUM_LEVEL2_KEY;
28694
    else if ((dilithiumKey != NULL) && (dilithiumKey->level == 3))
28695
        cert->keyType = DILITHIUM_LEVEL3_KEY;
28696
    else if ((dilithiumKey != NULL) && (dilithiumKey->level == 5))
28697
        cert->keyType = DILITHIUM_LEVEL5_KEY;
28698
#endif /* HAVE_DILITHIUM */
28699
#ifdef HAVE_SPHINCS
28700
    else if ((sphincsKey != NULL) && (sphincsKey->level == 1)
28701
             && (sphincsKey->optim == FAST_VARIANT))
28702
        cert->keyType = SPHINCS_FAST_LEVEL1_KEY;
28703
    else if ((sphincsKey != NULL) && (sphincsKey->level == 3)
28704
             && (sphincsKey->optim == FAST_VARIANT))
28705
        cert->keyType = SPHINCS_FAST_LEVEL3_KEY;
28706
    else if ((sphincsKey != NULL) && (sphincsKey->level == 5)
28707
             && (sphincsKey->optim == FAST_VARIANT))
28708
        cert->keyType = SPHINCS_FAST_LEVEL5_KEY;
28709
    else if ((sphincsKey != NULL) && (sphincsKey->level == 1)
28710
             && (sphincsKey->optim == SMALL_VARIANT))
28711
        cert->keyType = SPHINCS_SMALL_LEVEL1_KEY;
28712
    else if ((sphincsKey != NULL) && (sphincsKey->level == 3)
28713
             && (sphincsKey->optim == SMALL_VARIANT))
28714
        cert->keyType = SPHINCS_SMALL_LEVEL3_KEY;
28715
    else if ((sphincsKey != NULL) && (sphincsKey->level == 5)
28716
             && (sphincsKey->optim == SMALL_VARIANT))
28717
        cert->keyType = SPHINCS_SMALL_LEVEL5_KEY;
28718
#endif /* HAVE_SPHINCS */
28719
#endif /* HAVE_PQC */
28720
    else
28721
        return BAD_FUNC_ARG;
28722
28723
#ifdef WOLFSSL_SMALL_STACK
28724
    der = (DerCert*)XMALLOC(sizeof(DerCert), cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
28725
    if (der == NULL)
28726
        return MEMORY_E;
28727
#endif
28728
28729
    ret = EncodeCert(cert, der, rsaKey, eccKey, rng, dsaKey, ed25519Key,
28730
                     ed448Key, falconKey, dilithiumKey, sphincsKey);
28731
    if (ret == 0) {
28732
        if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
28733
            ret = BUFFER_E;
28734
        else
28735
            ret = cert->bodySz = WriteCertBody(der, derBuffer);
28736
    }
28737
28738
#ifdef WOLFSSL_SMALL_STACK
28739
    XFREE(der, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
28740
#endif
28741
28742
    return ret;
28743
#else
28744
    /* TODO: issRaw and sbjRaw should be NUL terminated. */
28745
    DECL_ASNSETDATA(dataASN, x509CertASN_Length);
28746
    word32 publicKeySz = 0;
28747
    word32 issuerSz = 0;
28748
    word32 subjectSz = 0;
28749
    word32 extSz = 0;
28750
    int sz = 0;
28751
    int ret = 0;
28752
    word32 issRawLen = 0;
28753
    word32 sbjRawLen = 0;
28754
28755
    /* Unused without OQS */
28756
    (void)falconKey;
28757
    (void)dilithiumKey;
28758
    (void)sphincsKey;
28759
28760
    CALLOC_ASNSETDATA(dataASN, x509CertASN_Length, ret, cert->heap);
28761
28762
    if (ret == 0) {
28763
        /* Set key type into certificate object based on key passed in. */
28764
        if (rsaKey) {
28765
            cert->keyType = RSA_KEY;
28766
        }
28767
        else if (eccKey) {
28768
            cert->keyType = ECC_KEY;
28769
        }
28770
        else if (dsaKey) {
28771
            cert->keyType = DSA_KEY;
28772
        }
28773
        else if (ed25519Key) {
28774
            cert->keyType = ED25519_KEY;
28775
        }
28776
        else if (ed448Key) {
28777
            cert->keyType = ED448_KEY;
28778
        }
28779
#ifdef HAVE_PQC
28780
#ifdef HAVE_FALCON
28781
        else if ((falconKey != NULL) && (falconKey->level == 1)) {
28782
            cert->keyType = FALCON_LEVEL1_KEY;
28783
        }
28784
        else if ((falconKey != NULL) && (falconKey->level == 5)) {
28785
            cert->keyType = FALCON_LEVEL5_KEY;
28786
        }
28787
#endif /* HAVE_FALCON */
28788
#ifdef HAVE_DILITHIUM
28789
        else if ((dilithiumKey != NULL) && (dilithiumKey->level == 2)) {
28790
            cert->keyType = DILITHIUM_LEVEL2_KEY;
28791
        }
28792
        else if ((dilithiumKey != NULL) && (dilithiumKey->level == 3)) {
28793
            cert->keyType = DILITHIUM_LEVEL3_KEY;
28794
        }
28795
        else if ((dilithiumKey != NULL) && (dilithiumKey->level == 5)) {
28796
            cert->keyType = DILITHIUM_LEVEL5_KEY;
28797
        }
28798
#endif /* HAVE_DILITHIUM */
28799
#ifdef HAVE_SPHINCS
28800
        else if ((sphincsKey != NULL) && (sphincsKey->level == 1)
28801
                 && (sphincsKey->optim == FAST_VARIANT)) {
28802
            cert->keyType = SPHINCS_FAST_LEVEL1_KEY;
28803
        }
28804
        else if ((sphincsKey != NULL) && (sphincsKey->level == 3)
28805
                 && (sphincsKey->optim == FAST_VARIANT)) {
28806
            cert->keyType = SPHINCS_FAST_LEVEL3_KEY;
28807
        }
28808
        else if ((sphincsKey != NULL) && (sphincsKey->level == 5)
28809
                 && (sphincsKey->optim == FAST_VARIANT)) {
28810
            cert->keyType = SPHINCS_FAST_LEVEL5_KEY;
28811
        }
28812
        else if ((sphincsKey != NULL) && (sphincsKey->level == 1)
28813
                 && (sphincsKey->optim == SMALL_VARIANT)) {
28814
            cert->keyType = SPHINCS_SMALL_LEVEL1_KEY;
28815
        }
28816
        else if ((sphincsKey != NULL) && (sphincsKey->level == 3)
28817
                 && (sphincsKey->optim == SMALL_VARIANT)) {
28818
            cert->keyType = SPHINCS_SMALL_LEVEL3_KEY;
28819
        }
28820
        else if ((sphincsKey != NULL) && (sphincsKey->level == 5)
28821
                 && (sphincsKey->optim == SMALL_VARIANT)) {
28822
            cert->keyType = SPHINCS_SMALL_LEVEL5_KEY;
28823
        }
28824
#endif /* HAVE_SPHINCS */
28825
#endif /* HAVE_PQC */
28826
        else {
28827
            ret = BAD_FUNC_ARG;
28828
        }
28829
    }
28830
    if ((ret == 0) && (cert->serialSz == 0)) {
28831
        /* Generate random serial number. */
28832
        cert->serialSz = CTC_GEN_SERIAL_SZ;
28833
        ret = GenerateInteger(rng, cert->serial, CTC_GEN_SERIAL_SZ);
28834
    }
28835
    if (ret == 0) {
28836
        /* Determine issuer name size. */
28837
    #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) || \
28838
        defined(WOLFSSL_CERT_REQ)
28839
        issRawLen = (word32)XSTRLEN((const char*)cert->issRaw);
28840
        if (issRawLen > 0) {
28841
            issuerSz = min(sizeof(cert->issRaw), issRawLen);
28842
        }
28843
        else
28844
    #endif
28845
        {
28846
            /* Calculate issuer name encoding size. If the cert is self-signed
28847
             * use the subject instead of the issuer. */
28848
            ret = SetNameEx(NULL, WC_ASN_NAME_MAX, cert->selfSigned ?
28849
                                 &cert->subject : &cert->issuer, cert->heap);
28850
            issuerSz = (word32)ret;
28851
        }
28852
    }
28853
    if (ret >= 0) {
28854
        /* Determine subject name size. */
28855
    #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) || \
28856
        defined(WOLFSSL_CERT_REQ)
28857
        sbjRawLen = (word32)XSTRLEN((const char*)cert->sbjRaw);
28858
        if (sbjRawLen > 0) {
28859
            subjectSz = min(sizeof(cert->sbjRaw), sbjRawLen);
28860
        }
28861
        else
28862
    #endif
28863
        {
28864
            /* Calculate subject name encoding size. */
28865
            ret = SetNameEx(NULL, WC_ASN_NAME_MAX, &cert->subject,
28866
                                  cert->heap);
28867
            subjectSz = (word32)ret;
28868
        }
28869
    }
28870
    if (ret >= 0) {
28871
        /* Calculate public key encoding size. */
28872
        ret = EncodePublicKey(cert->keyType, NULL, 0, rsaKey,
28873
            eccKey, ed25519Key, ed448Key, dsaKey);
28874
        publicKeySz = (word32)ret;
28875
    }
28876
    if (ret >= 0) {
28877
        /* Calculate extensions encoding size - may be 0. */
28878
        ret = EncodeExtensions(cert, NULL, 0, 0);
28879
        extSz = (word32)ret;
28880
    }
28881
    if (ret >= 0) {
28882
        /* Don't write out outer sequence - only doing body. */
28883
        dataASN[X509CERTASN_IDX_SEQ].noOut = 1;
28884
        /* Set version, serial number and signature OID */
28885
        SetASN_Int8Bit(&dataASN[X509CERTASN_IDX_TBS_VER_INT],
28886
                       (byte)cert->version);
28887
        SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_SERIAL], cert->serial,
28888
                (word32)cert->serialSz);
28889
        SetASN_OID(&dataASN[X509CERTASN_IDX_TBS_ALGOID_OID],
28890
                   (word32)cert->sigType, oidSigType);
28891
        if (IsSigAlgoECC((word32)cert->sigType)) {
28892
            /* No NULL tagged item with ECDSA and EdDSA signature OIDs. */
28893
            dataASN[X509CERTASN_IDX_TBS_ALGOID_PARAMS_NULL].noOut = 1;
28894
        }
28895
    #ifdef WC_RSA_PSS
28896
        /* TODO: Encode RSA PSS parameters. */
28897
        dataASN[X509CERTASN_IDX_TBS_ALGOID_PARAMS].noOut = 1;
28898
    #endif
28899
        if (issRawLen > 0) {
28900
    #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) || \
28901
        defined(WOLFSSL_CERT_REQ)
28902
            /* Put in encoded issuer name. */
28903
            SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ],
28904
                    cert->issRaw, issuerSz);
28905
    #endif
28906
        }
28907
        else {
28908
            /* Leave space for issuer name. */
28909
            SetASN_ReplaceBuffer(&dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ],
28910
                    NULL, issuerSz);
28911
        }
28912
28913
        if (cert->beforeDateSz && cert->afterDateSz) {
28914
            if (cert->beforeDate[0] == ASN_UTC_TIME) {
28915
                /* Make space for before date data. */
28916
                SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC],
28917
                        cert->beforeDate + 2, ASN_UTC_TIME_SIZE - 1);
28918
                /* Don't put out Generalized Time before data. */
28919
                dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT].noOut = 1;
28920
            }
28921
            else {
28922
                /* Don't put out UTC before data. */
28923
                dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC].noOut = 1;
28924
                /* Make space for before date data. */
28925
                SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT],
28926
                        cert->beforeDate + 2, ASN_GEN_TIME_SZ);
28927
            }
28928
            if (cert->afterDate[0] == ASN_UTC_TIME) {
28929
                /* Make space for after date data. */
28930
                SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC],
28931
                        cert->afterDate + 2, ASN_UTC_TIME_SIZE - 1);
28932
                /* Don't put out UTC Generalized Time after data. */
28933
                dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT].noOut = 1;
28934
            }
28935
            else {
28936
                /* Don't put out UTC after data. */
28937
                dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC].noOut = 1;
28938
                /* Make space for after date data. */
28939
                SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT],
28940
                        cert->afterDate + 2, ASN_GEN_TIME_SZ);
28941
            }
28942
        }
28943
        else
28944
        {
28945
            /* Don't put out UTC before data. */
28946
            dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC].noOut = 1;
28947
            /* Make space for before date data. */
28948
            SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT],
28949
                    NULL, ASN_GEN_TIME_SZ);
28950
            /* Don't put out UTC after data. */
28951
            dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC].noOut = 1;
28952
            /* Make space for after date data. */
28953
            SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT],
28954
                    NULL, ASN_GEN_TIME_SZ);
28955
        }
28956
        if (sbjRawLen > 0) {
28957
            /* Put in encoded subject name. */
28958
    #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) || \
28959
        defined(WOLFSSL_CERT_REQ)
28960
            SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_SUBJECT_SEQ],
28961
                    cert->sbjRaw, subjectSz);
28962
    #endif
28963
        }
28964
        else {
28965
            /* Leave space for subject name. */
28966
            SetASN_ReplaceBuffer(&dataASN[X509CERTASN_IDX_TBS_SUBJECT_SEQ],
28967
                    NULL, subjectSz);
28968
        }
28969
        /* Leave space for public key. */
28970
        SetASN_ReplaceBuffer(&dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ],
28971
                NULL, publicKeySz);
28972
        /* Replacement buffer instead of algorithm identifier items. */
28973
        SetASNItem_NoOut(dataASN,
28974
                X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_SEQ,
28975
                X509CERTASN_IDX_TBS_SPUBKEYINFO_PUBKEY);
28976
        /* issuerUniqueID and subjectUniqueID not supported. */
28977
        dataASN[X509CERTASN_IDX_TBS_ISSUERUID].noOut = 1;
28978
        dataASN[X509CERTASN_IDX_TBS_SUBJECTUID].noOut = 1;
28979
        /* Leave space for extensions if any set into certificate object. */
28980
        if (extSz > 0) {
28981
            SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_EXT_SEQ], NULL, extSz);
28982
        }
28983
        else {
28984
            SetASNItem_NoOutNode(dataASN, x509CertASN,
28985
                    X509CERTASN_IDX_TBS_EXT, x509CertASN_Length);
28986
        }
28987
        /* No signature - added later. */
28988
        SetASNItem_NoOut(dataASN, X509CERTASN_IDX_SIGALGO_SEQ,
28989
                X509CERTASN_IDX_SIGNATURE);
28990
28991
        /* Calculate encoded certificate body size. */
28992
        ret = SizeASN_Items(x509CertASN, dataASN, x509CertASN_Length, &sz);
28993
    }
28994
    /* Check buffer is big enough for encoded data. */
28995
    if ((ret == 0) && (sz > (int)derSz)) {
28996
        ret = BUFFER_E;
28997
    }
28998
    if (ret == 0) {
28999
        /* Encode certificate body into buffer. */
29000
        SetASN_Items(x509CertASN, dataASN, x509CertASN_Length, derBuffer);
29001
29002
        if (issRawLen == 0) {
29003
            /* Encode issuer name into buffer. Use the subject as the issuer
29004
             * if it is self-signed. Size will be correct because we did the
29005
             * same for size. */
29006
            ret = SetNameEx(
29007
                (byte*)dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ].data.buffer.data,
29008
                dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ].data.buffer.length,
29009
                cert->selfSigned ? &cert->subject : &cert->issuer, cert->heap);
29010
        }
29011
    }
29012
    if ((ret >= 0) && (sbjRawLen == 0)) {
29013
        /* Encode subject name into buffer. */
29014
        ret = SetNameEx(
29015
            (byte*)dataASN[X509CERTASN_IDX_TBS_SUBJECT_SEQ].data.buffer.data,
29016
            dataASN[X509CERTASN_IDX_TBS_SUBJECT_SEQ].data.buffer.length,
29017
            &cert->subject, cert->heap);
29018
    }
29019
    if (ret >= 0) {
29020
        if (cert->beforeDateSz == 0 || cert->afterDateSz == 0)
29021
        {
29022
            /* Encode validity into buffer. */
29023
            ret = SetValidity(
29024
                (byte*)dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT]
29025
                               .data.buffer.data,
29026
                (byte*)dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT]
29027
                               .data.buffer.data, cert->daysValid);
29028
        }
29029
    }
29030
    if (ret >= 0) {
29031
        /* Encode public key into buffer. */
29032
        ret = EncodePublicKey(cert->keyType,
29033
            (byte*)dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ]
29034
                           .data.buffer.data,
29035
            (int)dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ]
29036
                           .data.buffer.length,
29037
            rsaKey, eccKey, ed25519Key, ed448Key, dsaKey);
29038
    }
29039
    if ((ret >= 0) && (!dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].noOut)) {
29040
        /* Encode extensions into buffer. */
29041
        ret = EncodeExtensions(cert,
29042
                (byte*)dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].data.buffer.data,
29043
                dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].data.buffer.length, 0);
29044
    }
29045
    if (ret >= 0) {
29046
        /* Store encoded certifcate body size. */
29047
        cert->bodySz = sz;
29048
        /* Return the encoding size. */
29049
        ret = sz;
29050
    }
29051
29052
    FREE_ASNSETDATA(dataASN, cert->heap);
29053
    return ret;
29054
#endif
29055
}
29056
29057
29058
/* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */
29059
int wc_MakeCert_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType,
29060
                   void* key, WC_RNG* rng)
29061
{
29062
    RsaKey*            rsaKey = NULL;
29063
    DsaKey*            dsaKey = NULL;
29064
    ecc_key*           eccKey = NULL;
29065
    ed25519_key*       ed25519Key = NULL;
29066
    ed448_key*         ed448Key = NULL;
29067
    falcon_key*        falconKey = NULL;
29068
    dilithium_key*     dilithiumKey = NULL;
29069
    sphincs_key*       sphincsKey = NULL;
29070
29071
    if (keyType == RSA_TYPE)
29072
        rsaKey = (RsaKey*)key;
29073
    else if (keyType == DSA_TYPE)
29074
        dsaKey = (DsaKey*)key;
29075
    else if (keyType == ECC_TYPE)
29076
        eccKey = (ecc_key*)key;
29077
    else if (keyType == ED25519_TYPE)
29078
        ed25519Key = (ed25519_key*)key;
29079
    else if (keyType == ED448_TYPE)
29080
        ed448Key = (ed448_key*)key;
29081
    else if (keyType == FALCON_LEVEL1_TYPE)
29082
        falconKey = (falcon_key*)key;
29083
    else if (keyType == FALCON_LEVEL5_TYPE)
29084
        falconKey = (falcon_key*)key;
29085
    else if (keyType == DILITHIUM_LEVEL2_TYPE)
29086
        dilithiumKey = (dilithium_key*)key;
29087
    else if (keyType == DILITHIUM_LEVEL3_TYPE)
29088
        dilithiumKey = (dilithium_key*)key;
29089
    else if (keyType == DILITHIUM_LEVEL5_TYPE)
29090
        dilithiumKey = (dilithium_key*)key;
29091
    else if (keyType == SPHINCS_FAST_LEVEL1_TYPE)
29092
        sphincsKey = (sphincs_key*)key;
29093
    else if (keyType == SPHINCS_FAST_LEVEL3_TYPE)
29094
        sphincsKey = (sphincs_key*)key;
29095
    else if (keyType == SPHINCS_FAST_LEVEL5_TYPE)
29096
        sphincsKey = (sphincs_key*)key;
29097
    else if (keyType == SPHINCS_SMALL_LEVEL1_TYPE)
29098
        sphincsKey = (sphincs_key*)key;
29099
    else if (keyType == SPHINCS_SMALL_LEVEL3_TYPE)
29100
        sphincsKey = (sphincs_key*)key;
29101
    else if (keyType == SPHINCS_SMALL_LEVEL5_TYPE)
29102
        sphincsKey = (sphincs_key*)key;
29103
29104
    return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, dsaKey,
29105
                       ed25519Key, ed448Key, falconKey, dilithiumKey,
29106
                       sphincsKey);
29107
}
29108
29109
/* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */
29110
WOLFSSL_ABI
29111
int wc_MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey,
29112
             ecc_key* eccKey, WC_RNG* rng)
29113
{
29114
    return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, NULL,
29115
                       NULL, NULL, NULL, NULL);
29116
}
29117
29118
#ifdef WOLFSSL_CERT_REQ
29119
29120
#ifndef WOLFSSL_ASN_TEMPLATE
29121
/* return size of data set on success
29122
 * if getting size only then attr and oid should be NULL
29123
 */
29124
static word32 SetReqAttribSingle(byte* output, word32* idx, char* attr,
29125
        word32 attrSz, const byte* oid, word32 oidSz, byte printable,
29126
        word32 extSz)
29127
{
29128
    word32 totalSz = 0;
29129
    word32 seqSz = 0;
29130
    word32 setSz = 0;
29131
    word32 strSz = 0;
29132
    byte seq[MAX_SEQ_SZ];
29133
    byte set[MAX_SET_SZ];
29134
    byte str[MAX_PRSTR_SZ];
29135
29136
    totalSz = (word32)SetObjectId((int)oidSz, NULL);
29137
    totalSz += oidSz;
29138
    if (extSz > 0) {
29139
        totalSz += setSz = SetSet(extSz, set);
29140
        totalSz += seqSz = SetSequence(totalSz + extSz, seq);
29141
        totalSz += extSz;
29142
    }
29143
    else {
29144
        if (printable) {
29145
            strSz = SetPrintableString(attrSz, str);
29146
            totalSz += strSz;
29147
        }
29148
        else {
29149
            totalSz += strSz = SetUTF8String(attrSz, str);
29150
        }
29151
        totalSz += setSz = SetSet(strSz + attrSz, set);
29152
        totalSz += seqSz = SetSequence(totalSz + attrSz, seq);
29153
        totalSz += attrSz;
29154
    }
29155
29156
    if (oid) {
29157
        XMEMCPY(&output[*idx], seq, seqSz);
29158
        *idx += seqSz;
29159
        *idx += (word32)SetObjectId((int)oidSz, output + *idx);
29160
        XMEMCPY(&output[*idx], oid, oidSz);
29161
        *idx += oidSz;
29162
        XMEMCPY(&output[*idx], set, setSz);
29163
        *idx += setSz;
29164
        if (strSz > 0) {
29165
            XMEMCPY(&output[*idx], str, strSz);
29166
            *idx += strSz;
29167
            if (attrSz > 0) {
29168
                XMEMCPY(&output[*idx], attr, attrSz);
29169
                *idx += attrSz;
29170
            }
29171
        }
29172
    }
29173
    return totalSz;
29174
}
29175
29176
29177
29178
static int SetReqAttrib(byte* output, Cert* cert, word32 extSz)
29179
{
29180
    word32 sz      = 0; /* overall size */
29181
    word32 setSz   = 0;
29182
29183
    output[0] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED;
29184
    sz++;
29185
29186
    if (cert->challengePw[0]) {
29187
        setSz += SetReqAttribSingle(output, &sz, NULL,
29188
                (word32)XSTRLEN(cert->challengePw), NULL,
29189
                sizeof(attrChallengePasswordOid),
29190
                (byte)cert->challengePwPrintableString, 0);
29191
    }
29192
29193
    if (cert->unstructuredName[0]) {
29194
        setSz += SetReqAttribSingle(output, &sz, NULL,
29195
                (word32)XSTRLEN(cert->unstructuredName), NULL,
29196
                sizeof(attrUnstructuredNameOid), 1, 0);
29197
    }
29198
29199
    if (extSz) {
29200
        setSz += SetReqAttribSingle(output, &sz, NULL, 0, NULL,
29201
                sizeof(attrExtensionRequestOid), 1, extSz);
29202
    }
29203
29204
    /* Put the pieces together. */
29205
    sz += SetLength(setSz, &output[sz]);
29206
    if (sz + setSz - extSz > MAX_ATTRIB_SZ) {
29207
        WOLFSSL_MSG("Attribute Buffer is not big enough!");
29208
        return REQ_ATTRIBUTE_E;
29209
    }
29210
29211
    if (cert->challengePw[0]) {
29212
        SetReqAttribSingle(output, &sz, cert->challengePw,
29213
                (word32)XSTRLEN(cert->challengePw),
29214
                &attrChallengePasswordOid[0],
29215
                sizeof(attrChallengePasswordOid),
29216
                (byte)cert->challengePwPrintableString, 0);
29217
    }
29218
29219
    if (cert->unstructuredName[0]) {
29220
        SetReqAttribSingle(output, &sz, cert->unstructuredName,
29221
                (word32)XSTRLEN(cert->unstructuredName),
29222
                &attrUnstructuredNameOid[0],
29223
                sizeof(attrUnstructuredNameOid), 1, 0);
29224
    }
29225
29226
    if (extSz) {
29227
        SetReqAttribSingle(output, &sz, NULL, 0, &attrExtensionRequestOid[0],
29228
                sizeof(attrExtensionRequestOid), 1, extSz);
29229
        /* The actual extension data will be tacked onto the output later. */
29230
    }
29231
29232
    return (int)sz;
29233
}
29234
29235
#ifdef WOLFSSL_CUSTOM_OID
29236
/* encode a custom oid and value */
29237
static int SetCustomObjectId(Cert* cert, byte* output, word32 outSz,
29238
    CertOidField* custom)
29239
{
29240
    int idx = 0, cust_lenSz, cust_oidSz;
29241
29242
    if (cert == NULL || output == NULL || custom == NULL) {
29243
        return BAD_FUNC_ARG;
29244
    }
29245
    if (custom->oid == NULL || custom->oidSz <= 0) {
29246
        return 0; /* none set */
29247
    }
29248
29249
    /* Octet String header */
29250
    cust_lenSz = SetOctetString(custom->valSz, NULL);
29251
    cust_oidSz = SetObjectId(custom->oidSz, NULL);
29252
29253
    /* check for output buffer room */
29254
    if ((word32)(custom->valSz + custom->oidSz + cust_lenSz + cust_oidSz) >
29255
                                                                        outSz) {
29256
        return BUFFER_E;
29257
    }
29258
29259
    /* put sequence with total */
29260
    idx = SetSequence(custom->valSz + custom->oidSz + cust_lenSz + cust_oidSz,
29261
                      output);
29262
29263
    /* put oid header */
29264
    idx += SetObjectId(custom->oidSz, output+idx);
29265
    XMEMCPY(output+idx, custom->oid, custom->oidSz);
29266
    idx += custom->oidSz;
29267
29268
    /* put value */
29269
    idx += SetOctetString(custom->valSz, output+idx);
29270
    XMEMCPY(output+idx, custom->val, custom->valSz);
29271
    idx += custom->valSz;
29272
29273
    return idx;
29274
}
29275
#endif /* WOLFSSL_CUSTOM_OID */
29276
29277
29278
/* encode info from cert into DER encoded format */
29279
static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
29280
                         DsaKey* dsaKey, ecc_key* eccKey,
29281
                         ed25519_key* ed25519Key, ed448_key* ed448Key,
29282
                         falcon_key* falconKey, dilithium_key* dilithiumKey,
29283
                         sphincs_key* sphincsKey)
29284
{
29285
    int ret;
29286
29287
    (void)eccKey;
29288
    (void)ed25519Key;
29289
    (void)ed448Key;
29290
    (void)falconKey;
29291
    (void)dilithiumKey;
29292
    (void)sphincsKey;
29293
29294
    if (cert == NULL || der == NULL)
29295
        return BAD_FUNC_ARG;
29296
29297
    if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL &&
29298
        dsaKey == NULL && ed448Key == NULL && falconKey == NULL &&
29299
        falconKey == NULL) {
29300
        return PUBLIC_KEY_E;
29301
    }
29302
29303
    /* init */
29304
    XMEMSET(der, 0, sizeof(DerCert));
29305
29306
    /* version */
29307
    der->versionSz = SetMyVersion((word32)cert->version, der->version, FALSE);
29308
29309
    /* subject name */
29310
#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
29311
    if (XSTRLEN((const char*)cert->sbjRaw) > 0) {
29312
        /* Use the raw subject */
29313
        int idx;
29314
29315
        der->subjectSz = (int)min(sizeof(der->subject),
29316
                (word32)XSTRLEN((const char*)cert->sbjRaw));
29317
        /* header */
29318
        idx = (int)SetSequence((word32)der->subjectSz, der->subject);
29319
        if (der->subjectSz + idx > (int)sizeof(der->subject)) {
29320
            return SUBJECT_E;
29321
        }
29322
29323
        XMEMCPY((char*)der->subject + idx, (const char*)cert->sbjRaw,
29324
                (size_t)der->subjectSz);
29325
        der->subjectSz += idx;
29326
    }
29327
    else
29328
#endif
29329
    {
29330
        der->subjectSz = SetNameEx(der->subject, sizeof(der->subject),
29331
                &cert->subject, cert->heap);
29332
    }
29333
    if (der->subjectSz <= 0)
29334
        return SUBJECT_E;
29335
29336
    /* public key */
29337
#ifndef NO_RSA
29338
    if (cert->keyType == RSA_KEY) {
29339
        if (rsaKey == NULL)
29340
            return PUBLIC_KEY_E;
29341
        der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey,
29342
                                           sizeof(der->publicKey), 1);
29343
    }
29344
#endif
29345
29346
#if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
29347
    if (cert->keyType == DSA_KEY) {
29348
        if (dsaKey == NULL)
29349
            return PUBLIC_KEY_E;
29350
        der->publicKeySz = wc_SetDsaPublicKey(der->publicKey, dsaKey,
29351
                                           sizeof(der->publicKey), 1);
29352
    }
29353
#endif
29354
29355
#ifdef HAVE_ECC
29356
    if (cert->keyType == ECC_KEY) {
29357
        if (eccKey == NULL)
29358
            return PUBLIC_KEY_E;
29359
        der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey,
29360
                                           sizeof(der->publicKey), 1, 0);
29361
    }
29362
#endif
29363
29364
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
29365
    if (cert->keyType == ED25519_KEY) {
29366
        if (ed25519Key == NULL)
29367
            return PUBLIC_KEY_E;
29368
        der->publicKeySz = wc_Ed25519PublicKeyToDer(ed25519Key, der->publicKey,
29369
            (word32)sizeof(der->publicKey), 1);
29370
    }
29371
#endif
29372
29373
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
29374
    if (cert->keyType == ED448_KEY) {
29375
        if (ed448Key == NULL)
29376
            return PUBLIC_KEY_E;
29377
        der->publicKeySz = wc_Ed448PublicKeyToDer(ed448Key, der->publicKey,
29378
            (word32)sizeof(der->publicKey), 1);
29379
    }
29380
#endif
29381
#if defined(HAVE_PQC)
29382
#if defined(HAVE_FALCON)
29383
    if ((cert->keyType == FALCON_LEVEL1_KEY) ||
29384
        (cert->keyType == FALCON_LEVEL5_KEY)) {
29385
        if (falconKey == NULL)
29386
            return PUBLIC_KEY_E;
29387
        der->publicKeySz = wc_Falcon_PublicKeyToDer(falconKey,
29388
            der->publicKey, (word32)sizeof(der->publicKey), 1);
29389
    }
29390
#endif
29391
#if defined(HAVE_DILITHIUM)
29392
    if ((cert->keyType == DILITHIUM_LEVEL2_KEY) ||
29393
        (cert->keyType == DILITHIUM_LEVEL3_KEY) ||
29394
        (cert->keyType == DILITHIUM_LEVEL5_KEY)) {
29395
        if (dilithiumKey == NULL)
29396
            return PUBLIC_KEY_E;
29397
        der->publicKeySz = wc_Dilithium_PublicKeyToDer(dilithiumKey,
29398
            der->publicKey, (word32)sizeof(der->publicKey), 1);
29399
    }
29400
#endif
29401
#if defined(HAVE_SPHINCS)
29402
    if ((cert->keyType == SPHINCS_FAST_LEVEL1_KEY) ||
29403
        (cert->keyType == SPHINCS_FAST_LEVEL3_KEY) ||
29404
        (cert->keyType == SPHINCS_FAST_LEVEL5_KEY) ||
29405
        (cert->keyType == SPHINCS_SMALL_LEVEL1_KEY) ||
29406
        (cert->keyType == SPHINCS_SMALL_LEVEL3_KEY) ||
29407
        (cert->keyType == SPHINCS_SMALL_LEVEL5_KEY)) {
29408
        if (sphincsKey == NULL)
29409
            return PUBLIC_KEY_E;
29410
        der->publicKeySz = wc_Sphincs_PublicKeyToDer(sphincsKey,
29411
            der->publicKey, (word32)sizeof(der->publicKey), 1);
29412
    }
29413
#endif
29414
#endif /* HAVE_PQC */
29415
29416
    if (der->publicKeySz <= 0)
29417
        return PUBLIC_KEY_E;
29418
29419
    /* set the extensions */
29420
    der->extensionsSz = 0;
29421
29422
    /* RFC 5280 : 4.2.1.9. Basic Constraints
29423
     * The pathLenConstraint field is meaningful only if the CA boolean is
29424
     * asserted and the key usage extension, if present, asserts the
29425
     * keyCertSign bit */
29426
    /* Set CA and path length */
29427
    if ((cert->isCA) && (cert->pathLenSet)
29428
#ifdef WOLFSSL_CERT_EXT
29429
        && ((cert->keyUsage & KEYUSE_KEY_CERT_SIGN) || (!cert->keyUsage))
29430
#endif
29431
        ) {
29432
        der->caSz = SetCaWithPathLen(der->ca, sizeof(der->ca), cert->pathLen);
29433
        if (der->caSz <= 0)
29434
            return CA_TRUE_E;
29435
29436
        der->extensionsSz += der->caSz;
29437
    }
29438
    /* Set CA */
29439
    else if (cert->isCA) {
29440
        der->caSz = SetCa(der->ca, sizeof(der->ca));
29441
        if (der->caSz <= 0)
29442
            return CA_TRUE_E;
29443
29444
        der->extensionsSz += der->caSz;
29445
    }
29446
    /* Set Basic Constraint */
29447
    else if (cert->basicConstSet) {
29448
        der->caSz = SetBC(der->ca, sizeof(der->ca));
29449
        if (der->caSz <= 0)
29450
            return EXTENSIONS_E;
29451
29452
        der->extensionsSz += der->caSz;
29453
    }
29454
    else
29455
        der->caSz = 0;
29456
29457
#ifdef WOLFSSL_ALT_NAMES
29458
    /* Alternative Name */
29459
    if (cert->altNamesSz) {
29460
        der->altNamesSz = SetAltNames(der->altNames, sizeof(der->altNames),
29461
                                      cert->altNames, (word32)cert->altNamesSz,
29462
                                      cert->altNamesCrit);
29463
        if (der->altNamesSz <= 0)
29464
            return ALT_NAME_E;
29465
29466
        der->extensionsSz += der->altNamesSz;
29467
    }
29468
    else
29469
        der->altNamesSz = 0;
29470
#endif
29471
29472
#ifdef WOLFSSL_CERT_EXT
29473
    /* SKID */
29474
    if (cert->skidSz) {
29475
        /* check the provided SKID size */
29476
        if (cert->skidSz > (int)min(CTC_MAX_SKID_SIZE, sizeof(der->skid)))
29477
            return SKID_E;
29478
29479
        der->skidSz = SetSKID(der->skid, sizeof(der->skid),
29480
                              cert->skid, (word32)cert->skidSz);
29481
        if (der->skidSz <= 0)
29482
            return SKID_E;
29483
29484
        der->extensionsSz += der->skidSz;
29485
    }
29486
    else
29487
        der->skidSz = 0;
29488
29489
    /* Key Usage */
29490
    if (cert->keyUsage != 0) {
29491
        der->keyUsageSz = SetKeyUsage(der->keyUsage, sizeof(der->keyUsage),
29492
                                      cert->keyUsage);
29493
        if (der->keyUsageSz <= 0)
29494
            return KEYUSAGE_E;
29495
29496
        der->extensionsSz += der->keyUsageSz;
29497
    }
29498
    else
29499
        der->keyUsageSz = 0;
29500
29501
    /* Extended Key Usage */
29502
    if (cert->extKeyUsage != 0) {
29503
        der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage,
29504
                                sizeof(der->extKeyUsage), cert->extKeyUsage);
29505
        if (der->extKeyUsageSz <= 0)
29506
            return EXTKEYUSAGE_E;
29507
29508
        der->extensionsSz += der->extKeyUsageSz;
29509
    }
29510
    else
29511
        der->extKeyUsageSz = 0;
29512
29513
#endif /* WOLFSSL_CERT_EXT */
29514
29515
#ifdef WOLFSSL_CUSTOM_OID
29516
    /* encode a custom oid and value */
29517
    /* zero returns, means none set */
29518
    ret = SetCustomObjectId(cert, der->extCustom,
29519
        sizeof(der->extCustom), &cert->extCustom);
29520
    if (ret < 0)
29521
        return ret;
29522
    der->extCustomSz = ret;
29523
    der->extensionsSz += der->extCustomSz;
29524
#endif
29525
29526
    /* put extensions */
29527
    if (der->extensionsSz > 0) {
29528
        /* put the start of sequence (ID, Size) */
29529
        der->extensionsSz = (int)SetSequence((word32)der->extensionsSz,
29530
                                             der->extensions);
29531
        if (der->extensionsSz <= 0)
29532
            return EXTENSIONS_E;
29533
29534
        /* put CA */
29535
        if (der->caSz) {
29536
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
29537
                                &der->extensionsSz,
29538
                                der->ca, der->caSz);
29539
            if (ret <= 0)
29540
                return EXTENSIONS_E;
29541
        }
29542
29543
#ifdef WOLFSSL_ALT_NAMES
29544
        /* put Alternative Names */
29545
        if (der->altNamesSz) {
29546
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
29547
                                &der->extensionsSz,
29548
                                der->altNames, der->altNamesSz);
29549
            if (ret <= 0)
29550
                return EXTENSIONS_E;
29551
        }
29552
#endif
29553
29554
#ifdef WOLFSSL_CERT_EXT
29555
        /* put SKID */
29556
        if (der->skidSz) {
29557
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
29558
                                &der->extensionsSz,
29559
                                der->skid, der->skidSz);
29560
            if (ret <= 0)
29561
                return EXTENSIONS_E;
29562
        }
29563
29564
        /* put AKID */
29565
        if (der->akidSz) {
29566
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
29567
                                &der->extensionsSz,
29568
                                der->akid, der->akidSz);
29569
            if (ret <= 0)
29570
                return EXTENSIONS_E;
29571
        }
29572
29573
        /* put KeyUsage */
29574
        if (der->keyUsageSz) {
29575
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
29576
                                &der->extensionsSz,
29577
                                der->keyUsage, der->keyUsageSz);
29578
            if (ret <= 0)
29579
                return EXTENSIONS_E;
29580
        }
29581
29582
        /* put ExtendedKeyUsage */
29583
        if (der->extKeyUsageSz) {
29584
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
29585
                                &der->extensionsSz,
29586
                                der->extKeyUsage, der->extKeyUsageSz);
29587
            if (ret <= 0)
29588
                return EXTENSIONS_E;
29589
        }
29590
29591
    #ifdef WOLFSSL_CUSTOM_OID
29592
        if (der->extCustomSz) {
29593
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
29594
                                &der->extensionsSz,
29595
                                der->extCustom, der->extCustomSz);
29596
            if (ret <= 0)
29597
                return EXTENSIONS_E;
29598
        }
29599
    #endif
29600
#endif /* WOLFSSL_CERT_EXT */
29601
    }
29602
29603
    der->attribSz = SetReqAttrib(der->attrib, cert, (word32)der->extensionsSz);
29604
    if (der->attribSz <= 0)
29605
        return REQ_ATTRIBUTE_E;
29606
29607
    der->total = der->versionSz + der->subjectSz + der->publicKeySz +
29608
        der->extensionsSz + der->attribSz;
29609
29610
    return 0;
29611
}
29612
29613
29614
/* write DER encoded cert req to buffer, size already checked */
29615
static int WriteCertReqBody(DerCert* der, byte* buf)
29616
{
29617
    int idx;
29618
29619
    /* signed part header */
29620
    idx = (int)SetSequence((word32)der->total, buf);
29621
    /* version */
29622
    if (buf)
29623
        XMEMCPY(buf + idx, der->version, (size_t)der->versionSz);
29624
    idx += der->versionSz;
29625
    /* subject */
29626
    if (buf)
29627
        XMEMCPY(buf + idx, der->subject, (size_t)der->subjectSz);
29628
    idx += der->subjectSz;
29629
    /* public key */
29630
    if (buf)
29631
        XMEMCPY(buf + idx, der->publicKey, (size_t)der->publicKeySz);
29632
    idx += der->publicKeySz;
29633
    /* attributes */
29634
    if (buf)
29635
        XMEMCPY(buf + idx, der->attrib, (size_t)der->attribSz);
29636
    idx += der->attribSz;
29637
    /* extensions */
29638
    if (der->extensionsSz) {
29639
        if (buf)
29640
            XMEMCPY(buf + idx, der->extensions, min((word32)der->extensionsSz,
29641
                                               sizeof(der->extensions)));
29642
        idx += der->extensionsSz;
29643
    }
29644
29645
    return idx;
29646
}
29647
#endif
29648
29649
#ifdef WOLFSSL_ASN_TEMPLATE
29650
/* ASN.1 template for Certificate Request body.
29651
 * PKCS #10: RFC 2986, 4.1 - CertificationRequestInfo
29652
 */
29653
static const ASNItem certReqBodyASN[] = {
29654
/* SEQ             */ { 0, ASN_SEQUENCE, 1, 1, 0 },
29655
                                             /* version */
29656
/* VER             */     { 1, ASN_INTEGER, 0, 0, 0 },
29657
                                             /* subject */
29658
/* SUBJ_SEQ        */     { 1, ASN_SEQUENCE, 1, 0, 0 },
29659
                                             /* subjectPKInfo */
29660
/* SPUBKEYINFO_SEQ */     { 1, ASN_SEQUENCE, 1, 0, 0 },
29661
                                             /*  attributes*/
29662
/* ATTRS           */     { 1, ASN_CONTEXT_SPECIFIC | 0, 1, 1, 1 },
29663
                                                 /* Challenge Password Attribute */
29664
/* ATTRS_CPW_SEQ   */         { 2, ASN_SEQUENCE, 1, 1, 1 },
29665
/* ATTRS_CPW_OID   */             { 3, ASN_OBJECT_ID, 0, 0, 0 },
29666
/* ATTRS_CPW_SET   */             { 3, ASN_SET, 1, 1, 0 },
29667
/* ATTRS_CPW_PS    */                 { 4, ASN_PRINTABLE_STRING, 0, 0, 0 },
29668
/* ATTRS_CPW_UTF   */                 { 4, ASN_UTF8STRING, 0, 0, 0 },
29669
                                                 /* Extensions Attribute */
29670
/* EXT_SEQ         */         { 2, ASN_SEQUENCE, 1, 1, 1 },
29671
/* EXT_OID         */             { 3, ASN_OBJECT_ID, 0, 0, 0 },
29672
/* EXT_SET         */             { 3, ASN_SET, 1, 1, 0 },
29673
/* EXT_BODY        */                 { 4, ASN_SEQUENCE, 1, 0, 0 },
29674
};
29675
enum {
29676
    CERTREQBODYASN_IDX_SEQ = 0,
29677
    CERTREQBODYASN_IDX_VER,
29678
    CERTREQBODYASN_IDX_SUBJ_SEQ,
29679
    CERTREQBODYASN_IDX_SPUBKEYINFO_SEQ,
29680
    CERTREQBODYASN_IDX_ATTRS,
29681
    CERTREQBODYASN_IDX_ATTRS_CPW_SEQ,
29682
    CERTREQBODYASN_IDX_ATTRS_CPW_OID,
29683
    CERTREQBODYASN_IDX_ATTRS_CPW_SET,
29684
    CERTREQBODYASN_IDX_ATTRS_CPW_PS,
29685
    CERTREQBODYASN_IDX_ATTRS_CPW_UTF,
29686
    CERTREQBODYASN_IDX_EXT_SEQ,
29687
    CERTREQBODYASN_IDX_EXT_OID,
29688
    CERTREQBODYASN_IDX_EXT_SET,
29689
    CERTREQBODYASN_IDX_EXT_BODY
29690
};
29691
29692
/* Number of items in ASN.1 template for Certificate Request body. */
29693
#define certReqBodyASN_Length (sizeof(certReqBodyASN) / sizeof(ASNItem))
29694
#endif
29695
29696
static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
29697
                   RsaKey* rsaKey, DsaKey* dsaKey, ecc_key* eccKey,
29698
                   ed25519_key* ed25519Key, ed448_key* ed448Key,
29699
                   falcon_key* falconKey, dilithium_key* dilithiumKey,
29700
                   sphincs_key* sphincsKey)
29701
{
29702
#ifndef WOLFSSL_ASN_TEMPLATE
29703
    int ret;
29704
#ifdef WOLFSSL_SMALL_STACK
29705
    DerCert* der;
29706
#else
29707
    DerCert der[1];
29708
#endif
29709
29710
    if (eccKey)
29711
        cert->keyType = ECC_KEY;
29712
    else if (rsaKey)
29713
        cert->keyType = RSA_KEY;
29714
    else if (dsaKey)
29715
        cert->keyType = DSA_KEY;
29716
    else if (ed25519Key)
29717
        cert->keyType = ED25519_KEY;
29718
    else if (ed448Key)
29719
        cert->keyType = ED448_KEY;
29720
#ifdef HAVE_PQC
29721
#ifdef HAVE_FALCON
29722
    else if ((falconKey != NULL) && (falconKey->level == 1))
29723
        cert->keyType = FALCON_LEVEL1_KEY;
29724
    else if ((falconKey != NULL) && (falconKey->level == 5))
29725
        cert->keyType = FALCON_LEVEL5_KEY;
29726
#endif /* HAVE_FALCON */
29727
#ifdef HAVE_DILITHIUM
29728
    else if ((dilithiumKey != NULL) && (dilithiumKey->level == 2))
29729
        cert->keyType = DILITHIUM_LEVEL2_KEY;
29730
    else if ((dilithiumKey != NULL) && (dilithiumKey->level == 3))
29731
        cert->keyType = DILITHIUM_LEVEL3_KEY;
29732
    else if ((dilithiumKey != NULL) && (dilithiumKey->level == 5))
29733
        cert->keyType = DILITHIUM_LEVEL5_KEY;
29734
#endif /* HAVE_DILITHIUM */
29735
#ifdef HAVE_SPHINCS
29736
    else if ((sphincsKey != NULL) && (sphincsKey->level == 1)
29737
             && (sphincsKey->optim == FAST_VARIANT))
29738
        cert->keyType = SPHINCS_FAST_LEVEL1_KEY;
29739
    else if ((sphincsKey != NULL) && (sphincsKey->level == 3)
29740
             && (sphincsKey->optim == FAST_VARIANT))
29741
        cert->keyType = SPHINCS_FAST_LEVEL3_KEY;
29742
    else if ((sphincsKey != NULL) && (sphincsKey->level == 5)
29743
             && (sphincsKey->optim == FAST_VARIANT))
29744
        cert->keyType = SPHINCS_FAST_LEVEL5_KEY;
29745
    else if ((sphincsKey != NULL) && (sphincsKey->level == 1)
29746
             && (sphincsKey->optim == SMALL_VARIANT))
29747
        cert->keyType = SPHINCS_SMALL_LEVEL1_KEY;
29748
    else if ((sphincsKey != NULL) && (sphincsKey->level == 3)
29749
             && (sphincsKey->optim == SMALL_VARIANT))
29750
        cert->keyType = SPHINCS_SMALL_LEVEL3_KEY;
29751
    else if ((sphincsKey != NULL) && (sphincsKey->level == 5)
29752
             && (sphincsKey->optim == SMALL_VARIANT))
29753
        cert->keyType = SPHINCS_SMALL_LEVEL5_KEY;
29754
#endif /* HAVE_SPHINCS */
29755
#endif /* HAVE_PQC */
29756
    else
29757
        return BAD_FUNC_ARG;
29758
29759
#ifdef WOLFSSL_SMALL_STACK
29760
    der = (DerCert*)XMALLOC(sizeof(DerCert), cert->heap,
29761
                                                    DYNAMIC_TYPE_TMP_BUFFER);
29762
    if (der == NULL)
29763
        return MEMORY_E;
29764
#endif
29765
29766
    ret = EncodeCertReq(cert, der, rsaKey, dsaKey, eccKey, ed25519Key, ed448Key,
29767
                        falconKey, dilithiumKey, sphincsKey);
29768
29769
    if (ret == 0) {
29770
        if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
29771
            ret = BUFFER_E;
29772
        else
29773
            ret = cert->bodySz = WriteCertReqBody(der, derBuffer);
29774
    }
29775
29776
#ifdef WOLFSSL_SMALL_STACK
29777
    XFREE(der, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
29778
#endif
29779
29780
    return ret;
29781
#else
29782
    DECL_ASNSETDATA(dataASN, certReqBodyASN_Length);
29783
    word32 publicKeySz = 0;
29784
    word32 subjectSz = 0;
29785
    word32 extSz = 0;
29786
    int sz = 0;
29787
    int ret = 0;
29788
#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
29789
    word32 sbjRawSz = 0;
29790
#endif
29791
29792
    /* Unused without OQS */
29793
    (void)falconKey;
29794
    (void)dilithiumKey;
29795
    (void)sphincsKey;
29796
29797
    CALLOC_ASNSETDATA(dataASN, certReqBodyASN_Length, ret, cert->heap);
29798
29799
    if (ret == 0) {
29800
        /* Set key type into certificate object based on key passed in. */
29801
        if (rsaKey != NULL) {
29802
            cert->keyType = RSA_KEY;
29803
        }
29804
        else if (eccKey != NULL) {
29805
            cert->keyType = ECC_KEY;
29806
        }
29807
        else if (dsaKey != NULL) {
29808
            cert->keyType = DSA_KEY;
29809
        }
29810
        else if (ed25519Key != NULL) {
29811
            cert->keyType = ED25519_KEY;
29812
        }
29813
        else if (ed448Key != NULL) {
29814
            cert->keyType = ED448_KEY;
29815
        }
29816
#ifdef HAVE_PQC
29817
#ifdef HAVE_FALCON
29818
        else if ((falconKey != NULL) && (falconKey->level == 1)) {
29819
            cert->keyType = FALCON_LEVEL1_KEY;
29820
        }
29821
        else if ((falconKey != NULL) && (falconKey->level == 5)) {
29822
            cert->keyType = FALCON_LEVEL5_KEY;
29823
        }
29824
#endif /* HAVE_FALCON */
29825
#ifdef HAVE_DILITHIUM
29826
        else if ((dilithiumKey != NULL) && (dilithiumKey->level == 2)) {
29827
            cert->keyType = DILITHIUM_LEVEL2_KEY;
29828
        }
29829
        else if ((dilithiumKey != NULL) && (dilithiumKey->level == 3)) {
29830
            cert->keyType = DILITHIUM_LEVEL3_KEY;
29831
        }
29832
        else if ((dilithiumKey != NULL) && (dilithiumKey->level == 5)) {
29833
            cert->keyType = DILITHIUM_LEVEL5_KEY;
29834
        }
29835
#endif /* HAVE_DILITHIUM */
29836
#ifdef HAVE_SPHINCS
29837
        else if ((sphincsKey != NULL) && (sphincsKey->level == 1)
29838
                 && (sphincsKey->optim == FAST_VARIANT)) {
29839
            cert->keyType = SPHINCS_FAST_LEVEL1_KEY;
29840
        }
29841
        else if ((sphincsKey != NULL) && (sphincsKey->level == 3)
29842
                 && (sphincsKey->optim == FAST_VARIANT)) {
29843
            cert->keyType = SPHINCS_FAST_LEVEL3_KEY;
29844
        }
29845
        else if ((sphincsKey != NULL) && (sphincsKey->level == 5)
29846
                 && (sphincsKey->optim == FAST_VARIANT)) {
29847
            cert->keyType = SPHINCS_FAST_LEVEL5_KEY;
29848
        }
29849
        else if ((sphincsKey != NULL) && (sphincsKey->level == 1)
29850
                 && (sphincsKey->optim == SMALL_VARIANT)) {
29851
            cert->keyType = SPHINCS_SMALL_LEVEL1_KEY;
29852
        }
29853
        else if ((sphincsKey != NULL) && (sphincsKey->level == 3)
29854
                 && (sphincsKey->optim == SMALL_VARIANT)) {
29855
            cert->keyType = SPHINCS_SMALL_LEVEL3_KEY;
29856
        }
29857
        else if ((sphincsKey != NULL) && (sphincsKey->level == 5)
29858
                 && (sphincsKey->optim == SMALL_VARIANT)) {
29859
            cert->keyType = SPHINCS_SMALL_LEVEL5_KEY;
29860
        }
29861
#endif /* HAVE_SPHINCS */
29862
#endif /* HAVE_PQC */
29863
        else {
29864
            ret = BAD_FUNC_ARG;
29865
        }
29866
    }
29867
    if (ret == 0) {
29868
        /* Determine subject name size. */
29869
    #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
29870
        sbjRawSz = (word32)XSTRLEN((const char*)cert->sbjRaw);
29871
        if (sbjRawSz > 0) {
29872
            subjectSz = min(sizeof(cert->sbjRaw), sbjRawSz);
29873
        }
29874
        else
29875
    #endif
29876
        {
29877
            ret = SetNameEx(NULL, WC_ASN_NAME_MAX, &cert->subject, cert->heap);
29878
            subjectSz = (word32)ret;
29879
        }
29880
    }
29881
    if (ret >= 0) {
29882
        /* Determine encode public key size. */
29883
         ret = EncodePublicKey(cert->keyType, NULL, 0, rsaKey,
29884
             eccKey, ed25519Key, ed448Key, dsaKey);
29885
         publicKeySz = (word32)ret;
29886
    }
29887
    if (ret >= 0) {
29888
        /* Determine encode extensions size. */
29889
        ret = EncodeExtensions(cert, NULL, 0, 1);
29890
        extSz = (word32)ret;
29891
    }
29892
    if (ret >= 0) {
29893
        /* Set version. */
29894
        SetASN_Int8Bit(&dataASN[CERTREQBODYASN_IDX_VER], (byte)cert->version);
29895
    #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
29896
        if (sbjRawSz > 0) {
29897
            /* Put in encoded subject name. */
29898
            SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_SUBJ_SEQ], cert->sbjRaw,
29899
                    subjectSz);
29900
        }
29901
        else
29902
    #endif
29903
        {
29904
            /* Leave space for subject name. */
29905
            SetASN_ReplaceBuffer(&dataASN[CERTREQBODYASN_IDX_SUBJ_SEQ], NULL,
29906
                    subjectSz);
29907
        }
29908
        /* Leave space for public key. */
29909
        SetASN_ReplaceBuffer(&dataASN[CERTREQBODYASN_IDX_SPUBKEYINFO_SEQ],
29910
                NULL, publicKeySz);
29911
        if (cert->challengePw[0] != '\0') {
29912
            /* Add challenge password attribute. */
29913
            /* Set challenge password OID. */
29914
            SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_ATTRS_CPW_OID],
29915
                attrChallengePasswordOid, sizeof(attrChallengePasswordOid));
29916
            /* Enable the ASN template item with the appropriate tag. */
29917
            if (cert->challengePwPrintableString) {
29918
                /* PRINTABLE_STRING - set buffer */
29919
                SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_ATTRS_CPW_PS],
29920
                        (byte*)cert->challengePw,
29921
                        (word32)XSTRLEN(cert->challengePw));
29922
                /* UTF8STRING - don't encode */
29923
                dataASN[CERTREQBODYASN_IDX_ATTRS_CPW_UTF].noOut = 1;
29924
            }
29925
            else {
29926
                /* PRINTABLE_STRING - don't encode */
29927
                dataASN[CERTREQBODYASN_IDX_ATTRS_CPW_PS].noOut = 1;
29928
                /* UTF8STRING - set buffer */
29929
                SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_ATTRS_CPW_UTF],
29930
                        (byte*)cert->challengePw,
29931
                        (word32)XSTRLEN(cert->challengePw));
29932
            }
29933
        }
29934
        else {
29935
            /* Leave out challenge password attribute items. */
29936
            SetASNItem_NoOutNode(dataASN, certReqBodyASN,
29937
                    CERTREQBODYASN_IDX_ATTRS_CPW_SEQ, certReqBodyASN_Length);
29938
        }
29939
        if (extSz > 0) {
29940
            /* Set extension attribute OID. */
29941
            SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_EXT_OID], attrExtensionRequestOid,
29942
                sizeof(attrExtensionRequestOid));
29943
            /* Leave space for data. */
29944
            SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_EXT_BODY], NULL, extSz);
29945
        }
29946
        else {
29947
            /* Leave out extension attribute items. */
29948
            SetASNItem_NoOutNode(dataASN, certReqBodyASN,
29949
                    CERTREQBODYASN_IDX_EXT_SEQ, certReqBodyASN_Length);
29950
        }
29951
29952
        /* Calculate size of encoded certificate request body. */
29953
        ret = SizeASN_Items(certReqBodyASN, dataASN, certReqBodyASN_Length,
29954
                            &sz);
29955
    }
29956
    /* Check buffer is big enough for encoded data. */
29957
    if ((ret == 0) && (sz > (int)derSz)) {
29958
        ret = BUFFER_E;
29959
    }
29960
    if (ret == 0 && derBuffer != NULL) {
29961
        /* Encode certificate request body into buffer. */
29962
        SetASN_Items(certReqBodyASN, dataASN, certReqBodyASN_Length, derBuffer);
29963
29964
        /* Put in generated data */
29965
    #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
29966
        if (sbjRawSz == 0)
29967
    #endif
29968
        {
29969
            /* Encode subject name into space in buffer. */
29970
            ret = SetNameEx(
29971
                (byte*)dataASN[CERTREQBODYASN_IDX_SUBJ_SEQ].data.buffer.data,
29972
                dataASN[CERTREQBODYASN_IDX_SUBJ_SEQ].data.buffer.length,
29973
                &cert->subject, cert->heap);
29974
        }
29975
    }
29976
    if (ret >= 0 && derBuffer != NULL) {
29977
        /* Encode public key into space in buffer. */
29978
        ret = EncodePublicKey(cert->keyType,
29979
            (byte*)dataASN[CERTREQBODYASN_IDX_SPUBKEYINFO_SEQ].data.buffer.data,
29980
            (int)dataASN[CERTREQBODYASN_IDX_SPUBKEYINFO_SEQ].data.buffer.length,
29981
            rsaKey, eccKey, ed25519Key, ed448Key, dsaKey);
29982
    }
29983
    if ((ret >= 0 && derBuffer != NULL) &&
29984
            (!dataASN[CERTREQBODYASN_IDX_EXT_BODY].noOut)) {
29985
        /* Encode extensions into space in buffer. */
29986
        ret = EncodeExtensions(cert,
29987
                (byte*)dataASN[CERTREQBODYASN_IDX_EXT_BODY].data.buffer.data,
29988
                dataASN[CERTREQBODYASN_IDX_EXT_BODY].data.buffer.length, 1);
29989
    }
29990
    if (ret >= 0) {
29991
        /* Store encoded certifcate request body size. */
29992
        cert->bodySz = sz;
29993
        /* Return the encoding size. */
29994
        ret = sz;
29995
    }
29996
29997
    FREE_ASNSETDATA(dataASN, cert->heap);
29998
    return ret;
29999
#endif /* WOLFSSL_ASN_TEMPLATE */
30000
}
30001
30002
int wc_MakeCertReq_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType,
30003
                      void* key)
30004
{
30005
    RsaKey*        rsaKey = NULL;
30006
    DsaKey*        dsaKey = NULL;
30007
    ecc_key*       eccKey = NULL;
30008
    ed25519_key*   ed25519Key = NULL;
30009
    ed448_key*     ed448Key = NULL;
30010
    falcon_key*    falconKey = NULL;
30011
    dilithium_key* dilithiumKey = NULL;
30012
    sphincs_key*   sphincsKey = NULL;
30013
30014
    if (keyType == RSA_TYPE)
30015
        rsaKey = (RsaKey*)key;
30016
    else if (keyType == DSA_TYPE)
30017
        dsaKey = (DsaKey*)key;
30018
    else if (keyType == ECC_TYPE)
30019
        eccKey = (ecc_key*)key;
30020
    else if (keyType == ED25519_TYPE)
30021
        ed25519Key = (ed25519_key*)key;
30022
    else if (keyType == ED448_TYPE)
30023
        ed448Key = (ed448_key*)key;
30024
    else if (keyType == FALCON_LEVEL1_TYPE)
30025
        falconKey = (falcon_key*)key;
30026
    else if (keyType == FALCON_LEVEL5_TYPE)
30027
        falconKey = (falcon_key*)key;
30028
    else if (keyType == DILITHIUM_LEVEL2_TYPE)
30029
        dilithiumKey = (dilithium_key*)key;
30030
    else if (keyType == DILITHIUM_LEVEL3_TYPE)
30031
        dilithiumKey = (dilithium_key*)key;
30032
    else if (keyType == DILITHIUM_LEVEL5_TYPE)
30033
        dilithiumKey = (dilithium_key*)key;
30034
    else if (keyType == SPHINCS_FAST_LEVEL1_TYPE)
30035
        sphincsKey = (sphincs_key*)key;
30036
    else if (keyType == SPHINCS_FAST_LEVEL3_TYPE)
30037
        sphincsKey = (sphincs_key*)key;
30038
    else if (keyType == SPHINCS_FAST_LEVEL5_TYPE)
30039
        sphincsKey = (sphincs_key*)key;
30040
    else if (keyType == SPHINCS_SMALL_LEVEL1_TYPE)
30041
        sphincsKey = (sphincs_key*)key;
30042
    else if (keyType == SPHINCS_SMALL_LEVEL3_TYPE)
30043
        sphincsKey = (sphincs_key*)key;
30044
    else if (keyType == SPHINCS_SMALL_LEVEL5_TYPE)
30045
        sphincsKey = (sphincs_key*)key;
30046
30047
    return MakeCertReq(cert, derBuffer, derSz, rsaKey, dsaKey, eccKey,
30048
                       ed25519Key, ed448Key, falconKey, dilithiumKey,
30049
                       sphincsKey);
30050
}
30051
30052
WOLFSSL_ABI
30053
int wc_MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
30054
                   RsaKey* rsaKey, ecc_key* eccKey)
30055
{
30056
    return MakeCertReq(cert, derBuffer, derSz, rsaKey, NULL, eccKey, NULL,
30057
                       NULL, NULL, NULL, NULL);
30058
}
30059
#endif /* WOLFSSL_CERT_REQ */
30060
30061
30062
static int SignCert(int requestSz, int sType, byte* buf, word32 buffSz,
30063
                    RsaKey* rsaKey, ecc_key* eccKey, ed25519_key* ed25519Key,
30064
                    ed448_key* ed448Key, falcon_key* falconKey,
30065
                    dilithium_key* dilithiumKey, sphincs_key* sphincsKey,
30066
                    WC_RNG* rng)
30067
{
30068
    int sigSz = 0;
30069
    void* heap = NULL;
30070
    CertSignCtx  certSignCtx_lcl;
30071
    CertSignCtx* certSignCtx = &certSignCtx_lcl;
30072
30073
    XMEMSET(certSignCtx, 0, sizeof(*certSignCtx));
30074
30075
    if (requestSz < 0)
30076
        return requestSz;
30077
30078
    /* locate ctx */
30079
    if (rsaKey) {
30080
    #ifndef NO_RSA
30081
    #ifdef WOLFSSL_ASYNC_CRYPT
30082
        certSignCtx = &rsaKey->certSignCtx;
30083
    #endif
30084
        heap = rsaKey->heap;
30085
    #else
30086
        return NOT_COMPILED_IN;
30087
    #endif /* NO_RSA */
30088
    }
30089
    else if (eccKey) {
30090
    #ifdef HAVE_ECC
30091
    #ifdef WOLFSSL_ASYNC_CRYPT
30092
        certSignCtx = &eccKey->certSignCtx;
30093
    #endif
30094
        heap = eccKey->heap;
30095
    #else
30096
        return NOT_COMPILED_IN;
30097
    #endif /* HAVE_ECC */
30098
    }
30099
30100
    if (certSignCtx->sig == NULL) {
30101
        certSignCtx->sig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, heap,
30102
            DYNAMIC_TYPE_TMP_BUFFER);
30103
        if (certSignCtx->sig == NULL)
30104
            return MEMORY_E;
30105
    }
30106
30107
    sigSz = MakeSignature(certSignCtx, buf, (word32)requestSz, certSignCtx->sig,
30108
        MAX_ENCODED_SIG_SZ, rsaKey, eccKey, ed25519Key, ed448Key,
30109
        falconKey, dilithiumKey, sphincsKey, rng, (word32)sType, heap);
30110
#ifdef WOLFSSL_ASYNC_CRYPT
30111
    if (sigSz == WC_PENDING_E) {
30112
        /* Not free'ing certSignCtx->sig here because it could still be in use
30113
         * with async operations. */
30114
        return sigSz;
30115
    }
30116
#endif
30117
30118
    if (sigSz >= 0) {
30119
        if (requestSz + MAX_SEQ_SZ * 2 + sigSz > (int)buffSz)
30120
            sigSz = BUFFER_E;
30121
        else
30122
            sigSz = AddSignature(buf, requestSz, certSignCtx->sig, sigSz,
30123
                                 sType);
30124
    }
30125
30126
    XFREE(certSignCtx->sig, heap, DYNAMIC_TYPE_TMP_BUFFER);
30127
    certSignCtx->sig = NULL;
30128
30129
    return sigSz;
30130
}
30131
30132
int wc_SignCert_ex(int requestSz, int sType, byte* buf, word32 buffSz,
30133
                   int keyType, void* key, WC_RNG* rng)
30134
{
30135
    RsaKey*            rsaKey = NULL;
30136
    ecc_key*           eccKey = NULL;
30137
    ed25519_key*       ed25519Key = NULL;
30138
    ed448_key*         ed448Key = NULL;
30139
    falcon_key*        falconKey = NULL;
30140
    dilithium_key*     dilithiumKey = NULL;
30141
    sphincs_key*       sphincsKey = NULL;
30142
30143
    if (keyType == RSA_TYPE)
30144
        rsaKey = (RsaKey*)key;
30145
    else if (keyType == ECC_TYPE)
30146
        eccKey = (ecc_key*)key;
30147
    else if (keyType == ED25519_TYPE)
30148
        ed25519Key = (ed25519_key*)key;
30149
    else if (keyType == ED448_TYPE)
30150
        ed448Key = (ed448_key*)key;
30151
    else if (keyType == FALCON_LEVEL1_TYPE)
30152
        falconKey = (falcon_key*)key;
30153
    else if (keyType == FALCON_LEVEL5_TYPE)
30154
        falconKey = (falcon_key*)key;
30155
    else if (keyType == DILITHIUM_LEVEL2_TYPE)
30156
        dilithiumKey = (dilithium_key*)key;
30157
    else if (keyType == DILITHIUM_LEVEL3_TYPE)
30158
        dilithiumKey = (dilithium_key*)key;
30159
    else if (keyType == DILITHIUM_LEVEL5_TYPE)
30160
        dilithiumKey = (dilithium_key*)key;
30161
    else if (keyType == SPHINCS_FAST_LEVEL1_TYPE)
30162
        sphincsKey = (sphincs_key*)key;
30163
    else if (keyType == SPHINCS_FAST_LEVEL3_TYPE)
30164
        sphincsKey = (sphincs_key*)key;
30165
    else if (keyType == SPHINCS_FAST_LEVEL5_TYPE)
30166
        sphincsKey = (sphincs_key*)key;
30167
    else if (keyType == SPHINCS_SMALL_LEVEL1_TYPE)
30168
        sphincsKey = (sphincs_key*)key;
30169
    else if (keyType == SPHINCS_SMALL_LEVEL3_TYPE)
30170
        sphincsKey = (sphincs_key*)key;
30171
    else if (keyType == SPHINCS_SMALL_LEVEL5_TYPE)
30172
        sphincsKey = (sphincs_key*)key;
30173
30174
    return SignCert(requestSz, sType, buf, buffSz, rsaKey, eccKey, ed25519Key,
30175
                    ed448Key, falconKey, dilithiumKey, sphincsKey, rng);
30176
}
30177
30178
int wc_SignCert(int requestSz, int sType, byte* buf, word32 buffSz,
30179
                RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng)
30180
{
30181
    return SignCert(requestSz, sType, buf, buffSz, rsaKey, eccKey, NULL, NULL,
30182
                    NULL, NULL, NULL, rng);
30183
}
30184
30185
WOLFSSL_ABI
30186
int wc_MakeSelfCert(Cert* cert, byte* buf, word32 buffSz,
30187
                    RsaKey* key, WC_RNG* rng)
30188
{
30189
    int ret;
30190
30191
    ret = wc_MakeCert(cert, buf, buffSz, key, NULL, rng);
30192
    if (ret < 0)
30193
        return ret;
30194
30195
    return wc_SignCert(cert->bodySz, cert->sigType,
30196
                       buf, buffSz, key, NULL, rng);
30197
}
30198
30199
30200
#ifdef WOLFSSL_CERT_EXT
30201
30202
/* Get raw subject from cert, which may contain OIDs not parsed by Decode.
30203
   The raw subject pointer will only be valid while "cert" is valid. */
30204
WOLFSSL_ABI
30205
int wc_GetSubjectRaw(byte **subjectRaw, Cert *cert)
30206
{
30207
    int rc = BAD_FUNC_ARG;
30208
    if ((subjectRaw != NULL) && (cert != NULL)) {
30209
        *subjectRaw = cert->sbjRaw;
30210
        rc = 0;
30211
    }
30212
    return rc;
30213
}
30214
30215
/* Set KID from public key */
30216
static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey,
30217
                                 ed25519_key* ed25519Key, ed448_key* ed448Key,
30218
                                 falcon_key* falconKey,
30219
                                 dilithium_key* dilithiumKey,
30220
                                 sphincs_key *sphincsKey, int kid_type)
30221
{
30222
    byte *buf;
30223
    int   bufferSz, ret;
30224
30225
    if (cert == NULL ||
30226
        (rsakey == NULL && eckey == NULL && ed25519Key == NULL &&
30227
         ed448Key == NULL && falconKey == NULL && dilithiumKey == NULL &&
30228
         sphincsKey == NULL) ||
30229
        (kid_type != SKID_TYPE && kid_type != AKID_TYPE))
30230
        return BAD_FUNC_ARG;
30231
30232
    buf = (byte *)XMALLOC(MAX_PUBLIC_KEY_SZ, cert->heap,
30233
                                                       DYNAMIC_TYPE_TMP_BUFFER);
30234
    if (buf == NULL)
30235
        return MEMORY_E;
30236
30237
    /* Public Key */
30238
    bufferSz = -1;
30239
#ifndef NO_RSA
30240
    /* RSA public key */
30241
    if (rsakey != NULL)
30242
        bufferSz = SetRsaPublicKey(buf, rsakey, MAX_PUBLIC_KEY_SZ, 0);
30243
#endif
30244
#ifdef HAVE_ECC
30245
    /* ECC public key */
30246
    if (eckey != NULL)
30247
        bufferSz = SetEccPublicKey(buf, eckey, MAX_PUBLIC_KEY_SZ, 0, 0);
30248
#endif
30249
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
30250
    /* ED25519 public key */
30251
    if (ed25519Key != NULL) {
30252
        bufferSz = wc_Ed25519PublicKeyToDer(ed25519Key, buf, MAX_PUBLIC_KEY_SZ, 0);
30253
    }
30254
#endif
30255
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
30256
    /* ED448 public key */
30257
    if (ed448Key != NULL) {
30258
        bufferSz = wc_Ed448PublicKeyToDer(ed448Key, buf, MAX_PUBLIC_KEY_SZ, 0);
30259
    }
30260
#endif
30261
#if defined(HAVE_PQC)
30262
#if defined(HAVE_FALCON)
30263
    if (falconKey != NULL) {
30264
        bufferSz = wc_Falcon_PublicKeyToDer(falconKey, buf, MAX_PUBLIC_KEY_SZ,
30265
                                            0);
30266
    }
30267
#endif
30268
#if defined(HAVE_DILITHIUM)
30269
    if (dilithiumKey != NULL) {
30270
        bufferSz = wc_Dilithium_PublicKeyToDer(dilithiumKey, buf,
30271
                                               MAX_PUBLIC_KEY_SZ, 0);
30272
    }
30273
#endif
30274
#if defined(HAVE_SPHINCS)
30275
    if (sphincsKey != NULL) {
30276
        bufferSz = wc_Sphincs_PublicKeyToDer(sphincsKey, buf,
30277
                                               MAX_PUBLIC_KEY_SZ, 0);
30278
    }
30279
#endif
30280
#endif /* HAVE_PQC */
30281
30282
    if (bufferSz <= 0) {
30283
        XFREE(buf, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
30284
        return PUBLIC_KEY_E;
30285
    }
30286
30287
    /* Compute SKID by hashing public key */
30288
    if (kid_type == SKID_TYPE) {
30289
        int hashId = HashIdAlg((word32)cert->sigType);
30290
        ret = CalcHashId_ex(buf, (word32)bufferSz, cert->skid, hashId);
30291
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
30292
        cert->skidSz = wc_HashGetDigestSize(wc_HashTypeConvert(hashId));
30293
    #else
30294
        cert->skidSz = KEYID_SIZE;
30295
    #endif
30296
    }
30297
    else if (kid_type == AKID_TYPE) {
30298
        int hashId = HashIdAlg((word32)cert->sigType);
30299
        ret = CalcHashId_ex(buf, (word32)bufferSz, cert->akid, hashId);
30300
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
30301
        cert->akidSz = wc_HashGetDigestSize(wc_HashTypeConvert(hashId));
30302
    #else
30303
        cert->akidSz = KEYID_SIZE;
30304
    #endif
30305
    }
30306
    else
30307
        ret = BAD_FUNC_ARG;
30308
30309
    XFREE(buf, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
30310
    return ret;
30311
}
30312
30313
int wc_SetSubjectKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key)
30314
{
30315
    RsaKey*            rsaKey = NULL;
30316
    ecc_key*           eccKey = NULL;
30317
    ed25519_key*       ed25519Key = NULL;
30318
    ed448_key*         ed448Key = NULL;
30319
    falcon_key*        falconKey = NULL;
30320
    dilithium_key*     dilithiumKey = NULL;
30321
    sphincs_key*       sphincsKey = NULL;
30322
30323
    if (keyType == RSA_TYPE)
30324
        rsaKey = (RsaKey*)key;
30325
    else if (keyType == ECC_TYPE)
30326
        eccKey = (ecc_key*)key;
30327
    else if (keyType == ED25519_TYPE)
30328
        ed25519Key = (ed25519_key*)key;
30329
    else if (keyType == ED448_TYPE)
30330
        ed448Key = (ed448_key*)key;
30331
    else if (keyType == FALCON_LEVEL1_TYPE)
30332
        falconKey = (falcon_key*)key;
30333
    else if (keyType == FALCON_LEVEL5_TYPE)
30334
        falconKey = (falcon_key*)key;
30335
    else if (keyType == DILITHIUM_LEVEL2_TYPE)
30336
        dilithiumKey = (dilithium_key*)key;
30337
    else if (keyType == DILITHIUM_LEVEL3_TYPE)
30338
        dilithiumKey = (dilithium_key*)key;
30339
    else if (keyType == DILITHIUM_LEVEL5_TYPE)
30340
        dilithiumKey = (dilithium_key*)key;
30341
    else if (keyType == SPHINCS_FAST_LEVEL1_TYPE)
30342
        sphincsKey = (sphincs_key*)key;
30343
    else if (keyType == SPHINCS_FAST_LEVEL3_TYPE)
30344
        sphincsKey = (sphincs_key*)key;
30345
    else if (keyType == SPHINCS_FAST_LEVEL5_TYPE)
30346
        sphincsKey = (sphincs_key*)key;
30347
    else if (keyType == SPHINCS_SMALL_LEVEL1_TYPE)
30348
        sphincsKey = (sphincs_key*)key;
30349
    else if (keyType == SPHINCS_SMALL_LEVEL3_TYPE)
30350
        sphincsKey = (sphincs_key*)key;
30351
    else if (keyType == SPHINCS_SMALL_LEVEL5_TYPE)
30352
        sphincsKey = (sphincs_key*)key;
30353
30354
    return SetKeyIdFromPublicKey(cert, rsaKey, eccKey, ed25519Key, ed448Key,
30355
                                 falconKey, dilithiumKey, sphincsKey,
30356
                                 SKID_TYPE);
30357
}
30358
30359
/* Set SKID from RSA or ECC public key */
30360
int wc_SetSubjectKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey)
30361
{
30362
    return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, NULL, NULL, NULL,
30363
                                 NULL, SKID_TYPE);
30364
}
30365
30366
int wc_SetAuthKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key)
30367
{
30368
    RsaKey*            rsaKey = NULL;
30369
    ecc_key*           eccKey = NULL;
30370
    ed25519_key*       ed25519Key = NULL;
30371
    ed448_key*         ed448Key = NULL;
30372
    falcon_key*        falconKey = NULL;
30373
    dilithium_key*     dilithiumKey = NULL;
30374
    sphincs_key*       sphincsKey = NULL;
30375
30376
    if (keyType == RSA_TYPE)
30377
        rsaKey = (RsaKey*)key;
30378
    else if (keyType == ECC_TYPE)
30379
        eccKey = (ecc_key*)key;
30380
    else if (keyType == ED25519_TYPE)
30381
        ed25519Key = (ed25519_key*)key;
30382
    else if (keyType == ED448_TYPE)
30383
        ed448Key = (ed448_key*)key;
30384
    else if (keyType == FALCON_LEVEL1_TYPE)
30385
        falconKey = (falcon_key*)key;
30386
    else if (keyType == FALCON_LEVEL5_TYPE)
30387
        falconKey = (falcon_key*)key;
30388
    else if (keyType == DILITHIUM_LEVEL2_TYPE)
30389
        dilithiumKey = (dilithium_key*)key;
30390
    else if (keyType == DILITHIUM_LEVEL3_TYPE)
30391
        dilithiumKey = (dilithium_key*)key;
30392
    else if (keyType == DILITHIUM_LEVEL5_TYPE)
30393
        dilithiumKey = (dilithium_key*)key;
30394
    else if (keyType == SPHINCS_FAST_LEVEL1_TYPE)
30395
        sphincsKey = (sphincs_key*)key;
30396
    else if (keyType == SPHINCS_FAST_LEVEL3_TYPE)
30397
        sphincsKey = (sphincs_key*)key;
30398
    else if (keyType == SPHINCS_FAST_LEVEL5_TYPE)
30399
        sphincsKey = (sphincs_key*)key;
30400
    else if (keyType == SPHINCS_SMALL_LEVEL1_TYPE)
30401
        sphincsKey = (sphincs_key*)key;
30402
    else if (keyType == SPHINCS_SMALL_LEVEL3_TYPE)
30403
        sphincsKey = (sphincs_key*)key;
30404
    else if (keyType == SPHINCS_SMALL_LEVEL5_TYPE)
30405
        sphincsKey = (sphincs_key*)key;
30406
30407
    return SetKeyIdFromPublicKey(cert, rsaKey, eccKey, ed25519Key, ed448Key,
30408
                                 falconKey, dilithiumKey, sphincsKey,
30409
                                 AKID_TYPE);
30410
}
30411
30412
/* Set SKID from RSA or ECC public key */
30413
int wc_SetAuthKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey)
30414
{
30415
    return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, NULL, NULL, NULL,
30416
                                 NULL, AKID_TYPE);
30417
}
30418
30419
30420
#if !defined(NO_FILESYSTEM) && !defined(NO_ASN_CRYPT)
30421
30422
/* Set SKID from public key file in PEM */
30423
int wc_SetSubjectKeyId(Cert *cert, const char* file)
30424
{
30425
    int     ret, derSz;
30426
    byte*   der;
30427
    word32  idx;
30428
    RsaKey  *rsakey = NULL;
30429
    ecc_key *eckey = NULL;
30430
30431
    if (cert == NULL || file == NULL)
30432
        return BAD_FUNC_ARG;
30433
30434
    der = (byte*)XMALLOC(MAX_PUBLIC_KEY_SZ, cert->heap, DYNAMIC_TYPE_CERT);
30435
    if (der == NULL) {
30436
        WOLFSSL_MSG("wc_SetSubjectKeyId memory Problem");
30437
        return MEMORY_E;
30438
    }
30439
    derSz = MAX_PUBLIC_KEY_SZ;
30440
30441
    XMEMSET(der, 0, (size_t)derSz);
30442
    derSz = wc_PemPubKeyToDer(file, der, derSz);
30443
    if (derSz <= 0) {
30444
        XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
30445
        return derSz;
30446
    }
30447
30448
    /* Load PubKey in internal structure */
30449
#ifndef NO_RSA
30450
    rsakey = (RsaKey*) XMALLOC(sizeof(RsaKey), cert->heap, DYNAMIC_TYPE_RSA);
30451
    if (rsakey == NULL) {
30452
        XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
30453
        return MEMORY_E;
30454
    }
30455
30456
    if (wc_InitRsaKey(rsakey, cert->heap) != 0) {
30457
        WOLFSSL_MSG("wc_InitRsaKey failure");
30458
        XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);
30459
        XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
30460
        return MEMORY_E;
30461
    }
30462
30463
    idx = 0;
30464
    ret = wc_RsaPublicKeyDecode(der, &idx, rsakey, (word32)derSz);
30465
    if (ret != 0)
30466
#endif
30467
    {
30468
#ifndef NO_RSA
30469
        WOLFSSL_MSG("wc_RsaPublicKeyDecode failed");
30470
        wc_FreeRsaKey(rsakey);
30471
        XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);
30472
        rsakey = NULL;
30473
#endif
30474
#ifdef HAVE_ECC
30475
        /* Check to load ecc public key */
30476
        eckey = (ecc_key*) XMALLOC(sizeof(ecc_key), cert->heap,
30477
                                                              DYNAMIC_TYPE_ECC);
30478
        if (eckey == NULL) {
30479
            XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
30480
            return MEMORY_E;
30481
        }
30482
30483
        if (wc_ecc_init(eckey) != 0) {
30484
            WOLFSSL_MSG("wc_ecc_init failure");
30485
            wc_ecc_free(eckey);
30486
            XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);
30487
            XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
30488
            return MEMORY_E;
30489
        }
30490
30491
        idx = 0;
30492
        ret = wc_EccPublicKeyDecode(der, &idx, eckey, (word32)derSz);
30493
        if (ret != 0) {
30494
            WOLFSSL_MSG("wc_EccPublicKeyDecode failed");
30495
            XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
30496
            wc_ecc_free(eckey);
30497
            XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);
30498
            return PUBLIC_KEY_E;
30499
        }
30500
#else
30501
        XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
30502
        return PUBLIC_KEY_E;
30503
#endif /* HAVE_ECC */
30504
    }
30505
30506
    XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
30507
30508
    ret = wc_SetSubjectKeyIdFromPublicKey(cert, rsakey, eckey);
30509
30510
#ifndef NO_RSA
30511
    wc_FreeRsaKey(rsakey);
30512
    XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);
30513
#endif
30514
#ifdef HAVE_ECC
30515
    wc_ecc_free(eckey);
30516
    XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);
30517
#endif
30518
    return ret;
30519
}
30520
30521
#endif /* !NO_FILESYSTEM && !NO_ASN_CRYPT */
30522
30523
static int SetAuthKeyIdFromDcert(Cert* cert, DecodedCert* decoded)
30524
{
30525
    int ret = 0;
30526
30527
    /* Subject Key Id not found !! */
30528
    if (decoded->extSubjKeyIdSet == 0) {
30529
        ret = ASN_NO_SKID;
30530
    }
30531
30532
    /* SKID invalid size */
30533
    else if (sizeof(cert->akid) < sizeof(decoded->extSubjKeyId)) {
30534
        ret = MEMORY_E;
30535
    }
30536
30537
    else {
30538
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
30539
        cert->akidSz = wc_HashGetDigestSize(wc_HashTypeConvert(HashIdAlg(
30540
            cert->sigType)));
30541
    #else
30542
        cert->akidSz = KEYID_SIZE;
30543
    #endif
30544
        /* Put the SKID of CA to AKID of certificate */
30545
        XMEMCPY(cert->akid, decoded->extSubjKeyId, (size_t)cert->akidSz);
30546
    }
30547
30548
    return ret;
30549
}
30550
30551
/* Set AKID from certificate contains in buffer (DER encoded) */
30552
int wc_SetAuthKeyIdFromCert(Cert *cert, const byte *der, int derSz)
30553
{
30554
    int ret = 0;
30555
30556
    if (cert == NULL) {
30557
        ret = BAD_FUNC_ARG;
30558
    }
30559
    else {
30560
        /* Check if decodedCert is cached */
30561
        if (cert->der != der) {
30562
            /* Allocate cache for the decoded cert */
30563
            ret = wc_SetCert_LoadDer(cert, der, (word32)derSz, INVALID_DEVID);
30564
        }
30565
30566
        if (ret >= 0) {
30567
            ret = SetAuthKeyIdFromDcert(cert, (DecodedCert*)cert->decodedCert);
30568
#ifndef WOLFSSL_CERT_GEN_CACHE
30569
            wc_SetCert_Free(cert);
30570
#endif
30571
        }
30572
    }
30573
30574
    return ret;
30575
}
30576
30577
30578
#ifndef NO_FILESYSTEM
30579
30580
/* Set AKID from certificate file in PEM */
30581
int wc_SetAuthKeyId(Cert *cert, const char* file)
30582
{
30583
    int         ret;
30584
    DerBuffer*  der = NULL;
30585
30586
    if (cert == NULL || file == NULL)
30587
        return BAD_FUNC_ARG;
30588
30589
    ret = wc_PemCertToDer_ex(file, &der);
30590
    if (ret == 0)
30591
    {
30592
        ret = wc_SetAuthKeyIdFromCert(cert, der->buffer, (int)der->length);
30593
        FreeDer(&der);
30594
    }
30595
30596
    return ret;
30597
}
30598
30599
#endif /* !NO_FILESYSTEM */
30600
30601
/* Set KeyUsage from human readable string */
30602
int wc_SetKeyUsage(Cert *cert, const char *value)
30603
{
30604
    int ret = 0;
30605
30606
    if (cert == NULL || value == NULL)
30607
        return BAD_FUNC_ARG;
30608
30609
    cert->keyUsage = 0;
30610
30611
    ret = ParseKeyUsageStr(value, &cert->keyUsage, cert->heap);
30612
30613
    return ret;
30614
}
30615
30616
/* Set ExtendedKeyUsage from human readable string */
30617
int wc_SetExtKeyUsage(Cert *cert, const char *value)
30618
{
30619
    int ret = 0;
30620
30621
    if (cert == NULL || value == NULL)
30622
        return BAD_FUNC_ARG;
30623
30624
    cert->extKeyUsage = 0;
30625
30626
    ret = ParseExtKeyUsageStr(value, &cert->extKeyUsage, cert->heap);
30627
30628
    return ret;
30629
}
30630
30631
#ifdef WOLFSSL_EKU_OID
30632
/*
30633
 * cert structure to set EKU oid in
30634
 * oid  the oid in byte representation
30635
 * sz   size of oid buffer
30636
 * idx  index of array to place oid
30637
 *
30638
 * returns 0 on success
30639
 */
30640
int wc_SetExtKeyUsageOID(Cert *cert, const char *in, word32 sz, byte idx,
30641
        void* heap)
30642
{
30643
    byte oid[MAX_OID_SZ];
30644
    word32 oidSz = MAX_OID_SZ;
30645
30646
    if (idx >= CTC_MAX_EKU_NB || sz >= CTC_MAX_EKU_OID_SZ) {
30647
        WOLFSSL_MSG("Either idx or sz was too large");
30648
        return BAD_FUNC_ARG;
30649
    }
30650
30651
    if (EncodePolicyOID(oid, &oidSz, in, heap) != 0) {
30652
        return BUFFER_E;
30653
    }
30654
30655
    XMEMCPY(cert->extKeyUsageOID[idx], oid, oidSz);
30656
    cert->extKeyUsageOIDSz[idx] = oidSz;
30657
    cert->extKeyUsage |= EXTKEYUSE_USER;
30658
30659
    return 0;
30660
}
30661
#endif /* WOLFSSL_EKU_OID */
30662
30663
#if defined(WOLFSSL_ASN_TEMPLATE) && defined(WOLFSSL_CERT_GEN) && \
30664
    defined(WOLFSSL_CUSTOM_OID) && defined(HAVE_OID_ENCODING) && \
30665
    defined(WOLFSSL_CERT_EXT)
30666
int wc_SetCustomExtension(Cert *cert, int critical, const char *oid,
30667
                          const byte *der, word32 derSz) {
30668
    CertExtension *ext;
30669
    byte encodedOid[MAX_OID_SZ];
30670
    word32 encodedOidSz = MAX_OID_SZ;
30671
    int ret;
30672
30673
    if (cert == NULL || oid == NULL || der == NULL || derSz == 0) {
30674
        return BAD_FUNC_ARG;
30675
    }
30676
30677
    if (cert->customCertExtCount >= NUM_CUSTOM_EXT) {
30678
        return MEMORY_E;
30679
    }
30680
30681
    /* Make sure we can properly parse the OID. */
30682
    ret = EncodePolicyOID(encodedOid, &encodedOidSz, oid, NULL);
30683
    if (ret != 0) {
30684
        return ret;
30685
    }
30686
30687
    ext = &cert->customCertExt[cert->customCertExtCount];
30688
30689
    ext->oid = oid;
30690
    ext->crit = (critical == 0) ? 0 : 1;
30691
    ext->val = der;
30692
    ext->valSz = derSz;
30693
30694
    cert->customCertExtCount++;
30695
    return 0;
30696
}
30697
#endif
30698
30699
#endif /* WOLFSSL_CERT_EXT */
30700
30701
30702
#ifdef WOLFSSL_ALT_NAMES
30703
30704
static int SetAltNamesFromDcert(Cert* cert, DecodedCert* decoded)
30705
{
30706
    int ret = 0;
30707
30708
    cert->altNamesSz = 0;
30709
    if (decoded->altNames) {
30710
        ret = FlattenAltNames(cert->altNames,
30711
            sizeof(cert->altNames), decoded->altNames);
30712
        if (ret >= 0) {
30713
            cert->altNamesSz = ret;
30714
            ret = 0;
30715
        }
30716
    }
30717
30718
    return ret;
30719
}
30720
30721
#ifndef NO_FILESYSTEM
30722
30723
/* Set Alt Names from der cert, return 0 on success */
30724
static int SetAltNamesFromCert(Cert* cert, const byte* der, int derSz,
30725
    int devId)
30726
{
30727
    int ret;
30728
#ifdef WOLFSSL_SMALL_STACK
30729
    DecodedCert* decoded;
30730
#else
30731
    DecodedCert decoded[1];
30732
#endif
30733
30734
    if (derSz < 0)
30735
        return derSz;
30736
30737
#ifdef WOLFSSL_SMALL_STACK
30738
    decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cert->heap,
30739
                                                       DYNAMIC_TYPE_TMP_BUFFER);
30740
    if (decoded == NULL)
30741
        return MEMORY_E;
30742
#endif
30743
30744
    InitDecodedCert_ex(decoded, der, (word32)derSz, NULL, devId);
30745
    ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
30746
30747
    if (ret < 0) {
30748
        WOLFSSL_MSG("ParseCertRelative error");
30749
    }
30750
    else {
30751
        ret = SetAltNamesFromDcert(cert, decoded);
30752
    }
30753
30754
    FreeDecodedCert(decoded);
30755
#ifdef WOLFSSL_SMALL_STACK
30756
    XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
30757
#endif
30758
30759
    return ret < 0 ? ret : 0;
30760
}
30761
30762
#endif
30763
30764
static int SetDatesFromDcert(Cert* cert, DecodedCert* decoded)
30765
{
30766
    int ret = 0;
30767
30768
    if (decoded->beforeDate == NULL || decoded->afterDate == NULL) {
30769
        WOLFSSL_MSG("Couldn't extract dates");
30770
        ret = -1;
30771
    }
30772
    else if (decoded->beforeDateLen > MAX_DATE_SIZE ||
30773
                                        decoded->afterDateLen > MAX_DATE_SIZE) {
30774
        WOLFSSL_MSG("Bad date size");
30775
        ret = -1;
30776
    }
30777
    else {
30778
        XMEMCPY(cert->beforeDate, decoded->beforeDate,
30779
                (size_t)decoded->beforeDateLen);
30780
        XMEMCPY(cert->afterDate,  decoded->afterDate,
30781
                (size_t)decoded->afterDateLen);
30782
30783
        cert->beforeDateSz = decoded->beforeDateLen;
30784
        cert->afterDateSz  = decoded->afterDateLen;
30785
    }
30786
30787
    return ret;
30788
}
30789
30790
#endif /* WOLFSSL_ALT_NAMES */
30791
30792
static void SetNameFromDcert(CertName* cn, DecodedCert* decoded)
30793
{
30794
    int sz;
30795
30796
    if (decoded->subjectCN) {
30797
        sz = (decoded->subjectCNLen < CTC_NAME_SIZE) ? decoded->subjectCNLen
30798
                                                     : CTC_NAME_SIZE - 1;
30799
        XSTRNCPY(cn->commonName, decoded->subjectCN, (size_t)sz);
30800
        cn->commonName[sz] = '\0';
30801
        cn->commonNameEnc = decoded->subjectCNEnc;
30802
    }
30803
    if (decoded->subjectC) {
30804
        sz = (decoded->subjectCLen < CTC_NAME_SIZE) ? decoded->subjectCLen
30805
                                                    : CTC_NAME_SIZE - 1;
30806
        XSTRNCPY(cn->country, decoded->subjectC, (size_t)sz);
30807
        cn->country[sz] = '\0';
30808
        cn->countryEnc = decoded->subjectCEnc;
30809
    }
30810
    if (decoded->subjectST) {
30811
        sz = (decoded->subjectSTLen < CTC_NAME_SIZE) ? decoded->subjectSTLen
30812
                                                     : CTC_NAME_SIZE - 1;
30813
        XSTRNCPY(cn->state, decoded->subjectST, (size_t)sz);
30814
        cn->state[sz] = '\0';
30815
        cn->stateEnc = decoded->subjectSTEnc;
30816
    }
30817
    if (decoded->subjectL) {
30818
        sz = (decoded->subjectLLen < CTC_NAME_SIZE) ? decoded->subjectLLen
30819
                                                    : CTC_NAME_SIZE - 1;
30820
        XSTRNCPY(cn->locality, decoded->subjectL, (size_t)sz);
30821
        cn->locality[sz] = '\0';
30822
        cn->localityEnc = decoded->subjectLEnc;
30823
    }
30824
    if (decoded->subjectO) {
30825
        sz = (decoded->subjectOLen < CTC_NAME_SIZE) ? decoded->subjectOLen
30826
                                                    : CTC_NAME_SIZE - 1;
30827
        XSTRNCPY(cn->org, decoded->subjectO, (size_t)sz);
30828
        cn->org[sz] = '\0';
30829
        cn->orgEnc = decoded->subjectOEnc;
30830
    }
30831
    if (decoded->subjectOU) {
30832
        sz = (decoded->subjectOULen < CTC_NAME_SIZE) ? decoded->subjectOULen
30833
                                                     : CTC_NAME_SIZE - 1;
30834
        XSTRNCPY(cn->unit, decoded->subjectOU, (size_t)sz);
30835
        cn->unit[sz] = '\0';
30836
        cn->unitEnc = decoded->subjectOUEnc;
30837
    }
30838
    if (decoded->subjectSN) {
30839
        sz = (decoded->subjectSNLen < CTC_NAME_SIZE) ? decoded->subjectSNLen
30840
                                                     : CTC_NAME_SIZE - 1;
30841
        XSTRNCPY(cn->sur, decoded->subjectSN, (size_t)sz);
30842
        cn->sur[sz] = '\0';
30843
        cn->surEnc = decoded->subjectSNEnc;
30844
    }
30845
    if (decoded->subjectSND) {
30846
        sz = (decoded->subjectSNDLen < CTC_NAME_SIZE) ? decoded->subjectSNDLen
30847
                                                     : CTC_NAME_SIZE - 1;
30848
        XSTRNCPY(cn->serialDev, decoded->subjectSND, (size_t)sz);
30849
        cn->serialDev[sz] = '\0';
30850
        cn->serialDevEnc = decoded->subjectSNDEnc;
30851
    }
30852
    if (decoded->subjectUID) {
30853
        sz = (decoded->subjectUIDLen < CTC_NAME_SIZE) ? decoded->subjectUIDLen
30854
                                                     : CTC_NAME_SIZE - 1;
30855
        XSTRNCPY(cn->userId, decoded->subjectUID, (size_t)sz);
30856
        cn->userId[sz] = '\0';
30857
        cn->userIdEnc = decoded->subjectUIDEnc;
30858
    }
30859
#ifdef WOLFSSL_CERT_EXT
30860
    if (decoded->subjectBC) {
30861
        sz = (decoded->subjectBCLen < CTC_NAME_SIZE) ? decoded->subjectBCLen
30862
                                                     : CTC_NAME_SIZE - 1;
30863
        XSTRNCPY(cn->busCat, decoded->subjectBC, (size_t)sz);
30864
        cn->busCat[sz] = '\0';
30865
        cn->busCatEnc = decoded->subjectBCEnc;
30866
    }
30867
    if (decoded->subjectJC) {
30868
        sz = (decoded->subjectJCLen < CTC_NAME_SIZE) ? decoded->subjectJCLen
30869
                                                     : CTC_NAME_SIZE - 1;
30870
        XSTRNCPY(cn->joiC, decoded->subjectJC, (size_t)sz);
30871
        cn->joiC[sz] = '\0';
30872
        cn->joiCEnc = decoded->subjectJCEnc;
30873
    }
30874
    if (decoded->subjectJS) {
30875
        sz = (decoded->subjectJSLen < CTC_NAME_SIZE) ? decoded->subjectJSLen
30876
                                                     : CTC_NAME_SIZE - 1;
30877
        XSTRNCPY(cn->joiSt, decoded->subjectJS, (size_t)sz);
30878
        cn->joiSt[sz] = '\0';
30879
        cn->joiStEnc = decoded->subjectJSEnc;
30880
    }
30881
#endif
30882
    if (decoded->subjectEmail) {
30883
        sz = (decoded->subjectEmailLen < CTC_NAME_SIZE)
30884
           ?  decoded->subjectEmailLen : CTC_NAME_SIZE - 1;
30885
        XSTRNCPY(cn->email, decoded->subjectEmail, (size_t)sz);
30886
        cn->email[sz] = '\0';
30887
    }
30888
#if defined(WOLFSSL_CERT_NAME_ALL) && \
30889
    (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT))
30890
    if (decoded->subjectN) {
30891
        sz = (decoded->subjectNLen < CTC_NAME_SIZE) ? decoded->subjectNLen
30892
                                                     : CTC_NAME_SIZE - 1;
30893
        XSTRNCPY(cn->dnName, decoded->subjectN, (size_t)sz);
30894
        cn->dnName[sz] = '\0';
30895
        cn->dnNameEnc = decoded->subjectNEnc;
30896
    }
30897
    if (decoded->subjectI) {
30898
        sz = (decoded->subjectILen < CTC_NAME_SIZE) ? decoded->subjectILen
30899
                                                     : CTC_NAME_SIZE - 1;
30900
        XSTRNCPY(cn->initials, decoded->subjectI, (size_t)sz);
30901
        cn->initials[sz] = '\0';
30902
        cn->initialsEnc = decoded->subjectIEnc;
30903
    }
30904
    if (decoded->subjectGN) {
30905
        sz = (decoded->subjectGNLen < CTC_NAME_SIZE) ? decoded->subjectGNLen
30906
                                                     : CTC_NAME_SIZE - 1;
30907
        XSTRNCPY(cn->givenName, decoded->subjectGN, (size_t)sz);
30908
        cn->givenName[sz] = '\0';
30909
        cn->givenNameEnc = decoded->subjectGNEnc;
30910
    }
30911
    if (decoded->subjectDNQ) {
30912
        sz = (decoded->subjectDNQLen < CTC_NAME_SIZE) ? decoded->subjectDNQLen
30913
                                                     : CTC_NAME_SIZE - 1;
30914
        XSTRNCPY(cn->dnQualifier, decoded->subjectDNQ, (size_t)sz);
30915
        cn->dnQualifier[sz] = '\0';
30916
        cn->dnQualifierEnc = decoded->subjectDNQEnc;
30917
    }
30918
#endif /* WOLFSSL_CERT_NAME_ALL */
30919
}
30920
30921
#ifndef NO_FILESYSTEM
30922
30923
/* Set cn name from der buffer, return 0 on success */
30924
static int SetNameFromCert(CertName* cn, const byte* der, int derSz, int devId)
30925
{
30926
    int ret;
30927
#ifdef WOLFSSL_SMALL_STACK
30928
    DecodedCert* decoded;
30929
#else
30930
    DecodedCert decoded[1];
30931
#endif
30932
30933
    if (derSz < 0)
30934
        return derSz;
30935
30936
#ifdef WOLFSSL_SMALL_STACK
30937
    decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
30938
                                                       DYNAMIC_TYPE_TMP_BUFFER);
30939
    if (decoded == NULL)
30940
        return MEMORY_E;
30941
#endif
30942
30943
    InitDecodedCert_ex(decoded, der, (word32)derSz, NULL, devId);
30944
    ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
30945
30946
    if (ret < 0) {
30947
        WOLFSSL_MSG("ParseCertRelative error");
30948
    }
30949
    else {
30950
        SetNameFromDcert(cn, decoded);
30951
    }
30952
30953
    FreeDecodedCert(decoded);
30954
30955
#ifdef WOLFSSL_SMALL_STACK
30956
    XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
30957
#endif
30958
30959
    return ret < 0 ? ret : 0;
30960
}
30961
30962
/* Set cert issuer from issuerFile in PEM */
30963
WOLFSSL_ABI
30964
int wc_SetIssuer(Cert* cert, const char* issuerFile)
30965
{
30966
    int         ret;
30967
    DerBuffer*  der = NULL;
30968
30969
    if (cert == NULL || issuerFile == NULL)
30970
        return BAD_FUNC_ARG;
30971
30972
    ret = wc_PemCertToDer_ex(issuerFile, &der);
30973
    if (ret == 0) {
30974
        cert->selfSigned = 0;
30975
        ret = SetNameFromCert(&cert->issuer, der->buffer, (int)der->length,
30976
            INVALID_DEVID);
30977
30978
        FreeDer(&der);
30979
    }
30980
30981
    return ret;
30982
}
30983
30984
30985
/* Set cert subject from subjectFile in PEM */
30986
WOLFSSL_ABI
30987
int wc_SetSubject(Cert* cert, const char* subjectFile)
30988
{
30989
    int         ret;
30990
    DerBuffer*  der = NULL;
30991
30992
    if (cert == NULL || subjectFile == NULL)
30993
        return BAD_FUNC_ARG;
30994
30995
    ret = wc_PemCertToDer_ex(subjectFile, &der);
30996
    if (ret == 0) {
30997
        ret = SetNameFromCert(&cert->subject, der->buffer, (int)der->length,
30998
            INVALID_DEVID);
30999
31000
        FreeDer(&der);
31001
    }
31002
31003
    return ret;
31004
}
31005
31006
#ifdef WOLFSSL_ALT_NAMES
31007
31008
/* Set alt names from file in PEM */
31009
WOLFSSL_ABI
31010
int wc_SetAltNames(Cert* cert, const char* file)
31011
{
31012
    int         ret;
31013
    DerBuffer*  der = NULL;
31014
31015
    if (cert == NULL) {
31016
        return BAD_FUNC_ARG;
31017
    }
31018
31019
    ret = wc_PemCertToDer_ex(file, &der);
31020
    if (ret == 0) {
31021
        ret = SetAltNamesFromCert(cert, der->buffer, (int)der->length,
31022
            INVALID_DEVID);
31023
31024
        FreeDer(&der);
31025
    }
31026
31027
    return ret;
31028
}
31029
31030
#endif /* WOLFSSL_ALT_NAMES */
31031
31032
#endif /* !NO_FILESYSTEM */
31033
31034
/* Set cert issuer from DER buffer */
31035
WOLFSSL_ABI
31036
int wc_SetIssuerBuffer(Cert* cert, const byte* der, int derSz)
31037
{
31038
    int ret = 0;
31039
31040
    if (cert == NULL) {
31041
        ret = BAD_FUNC_ARG;
31042
    }
31043
    else {
31044
        cert->selfSigned = 0;
31045
31046
        /* Check if decodedCert is cached */
31047
        if (cert->der != der) {
31048
            /* Allocate cache for the decoded cert */
31049
            ret = wc_SetCert_LoadDer(cert, der, (word32)derSz, INVALID_DEVID);
31050
        }
31051
31052
        if (ret >= 0) {
31053
            SetNameFromDcert(&cert->issuer, (DecodedCert*)cert->decodedCert);
31054
#ifndef WOLFSSL_CERT_GEN_CACHE
31055
            wc_SetCert_Free(cert);
31056
#endif
31057
        }
31058
    }
31059
31060
    return ret;
31061
}
31062
31063
/* Set cert subject from DER buffer */
31064
WOLFSSL_ABI
31065
int wc_SetSubjectBuffer(Cert* cert, const byte* der, int derSz)
31066
{
31067
    int ret = 0;
31068
31069
    if (cert == NULL) {
31070
        ret = BAD_FUNC_ARG;
31071
    }
31072
    else {
31073
        /* Check if decodedCert is cached */
31074
        if (cert->der != der) {
31075
            /* Allocate cache for the decoded cert */
31076
            ret = wc_SetCert_LoadDer(cert, der, (word32)derSz, INVALID_DEVID);
31077
        }
31078
31079
        if (ret >= 0) {
31080
            SetNameFromDcert(&cert->subject, (DecodedCert*)cert->decodedCert);
31081
#ifndef WOLFSSL_CERT_GEN_CACHE
31082
            wc_SetCert_Free(cert);
31083
#endif
31084
        }
31085
    }
31086
31087
    return ret;
31088
}
31089
#ifdef WOLFSSL_CERT_EXT
31090
/* Set cert raw subject from DER buffer */
31091
WOLFSSL_ABI
31092
int wc_SetSubjectRaw(Cert* cert, const byte* der, int derSz)
31093
{
31094
    int ret = 0;
31095
31096
    if (cert == NULL) {
31097
        ret = BAD_FUNC_ARG;
31098
    }
31099
    else {
31100
        /* Check if decodedCert is cached */
31101
        if (cert->der != der) {
31102
            /* Allocate cache for the decoded cert */
31103
            ret = wc_SetCert_LoadDer(cert, der, (word32)derSz, INVALID_DEVID);
31104
        }
31105
31106
        if (ret >= 0) {
31107
            if ((((DecodedCert*)cert->decodedCert)->subjectRaw) &&
31108
                (((DecodedCert*)cert->decodedCert)->subjectRawLen <=
31109
                        (int)sizeof(CertName))) {
31110
                XMEMCPY(cert->sbjRaw,
31111
                        ((DecodedCert*)cert->decodedCert)->subjectRaw,
31112
                        (size_t)((DecodedCert*)cert->decodedCert)->
31113
                        subjectRawLen);
31114
            }
31115
#ifndef WOLFSSL_CERT_GEN_CACHE
31116
            wc_SetCert_Free(cert);
31117
#endif
31118
        }
31119
    }
31120
31121
    return ret;
31122
}
31123
31124
/* Set cert raw issuer from DER buffer */
31125
WOLFSSL_ABI
31126
int wc_SetIssuerRaw(Cert* cert, const byte* der, int derSz)
31127
{
31128
    int ret = 0;
31129
31130
    if (cert == NULL) {
31131
        ret = BAD_FUNC_ARG;
31132
    }
31133
    else {
31134
        /* Check if decodedCert is cached */
31135
        if (cert->der != der) {
31136
            /* Allocate cache for the decoded cert */
31137
            ret = wc_SetCert_LoadDer(cert, der, (word32)derSz, INVALID_DEVID);
31138
        }
31139
31140
        if (ret >= 0) {
31141
            if ((((DecodedCert*)cert->decodedCert)->subjectRaw) &&
31142
                (((DecodedCert*)cert->decodedCert)->subjectRawLen <=
31143
                        (int)sizeof(CertName))) {
31144
                /* Copy the subject to the issuer field */
31145
                XMEMCPY(cert->issRaw,
31146
                        ((DecodedCert*)cert->decodedCert)->subjectRaw,
31147
                        (size_t)((DecodedCert*)cert->decodedCert)->
31148
                        subjectRawLen);
31149
            }
31150
#ifndef WOLFSSL_CERT_GEN_CACHE
31151
            wc_SetCert_Free(cert);
31152
#endif
31153
        }
31154
    }
31155
    return ret;
31156
}
31157
#endif
31158
31159
#ifdef WOLFSSL_ALT_NAMES
31160
31161
/* Set cert alt names from DER buffer */
31162
WOLFSSL_ABI
31163
int wc_SetAltNamesBuffer(Cert* cert, const byte* der, int derSz)
31164
{
31165
    int ret = 0;
31166
31167
    if (cert == NULL) {
31168
       ret = BAD_FUNC_ARG;
31169
    }
31170
    else {
31171
        /* Check if decodedCert is cached */
31172
        if (cert->der != der) {
31173
            /* Allocate cache for the decoded cert */
31174
            ret = wc_SetCert_LoadDer(cert, der, (word32)derSz, INVALID_DEVID);
31175
        }
31176
31177
        if (ret >= 0) {
31178
            ret = SetAltNamesFromDcert(cert, (DecodedCert*)cert->decodedCert);
31179
#ifndef WOLFSSL_CERT_GEN_CACHE
31180
            wc_SetCert_Free(cert);
31181
#endif
31182
       }
31183
    }
31184
31185
    return(ret);
31186
}
31187
31188
/* Set cert dates from DER buffer */
31189
WOLFSSL_ABI
31190
int wc_SetDatesBuffer(Cert* cert, const byte* der, int derSz)
31191
{
31192
    int ret = 0;
31193
31194
    if (cert == NULL) {
31195
     ret = BAD_FUNC_ARG;
31196
    }
31197
    else {
31198
        /* Check if decodedCert is cached */
31199
        if (cert->der != der) {
31200
            /* Allocate cache for the decoded cert */
31201
            ret = wc_SetCert_LoadDer(cert, der, (word32)derSz, INVALID_DEVID);
31202
        }
31203
31204
        if (ret >= 0) {
31205
            ret = SetDatesFromDcert(cert, (DecodedCert*)cert->decodedCert);
31206
#ifndef WOLFSSL_CERT_GEN_CACHE
31207
            wc_SetCert_Free(cert);
31208
#endif
31209
        }
31210
    }
31211
31212
    return(ret);
31213
}
31214
31215
#endif /* WOLFSSL_ALT_NAMES */
31216
31217
#endif /* WOLFSSL_CERT_GEN */
31218
31219
#if (defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT)) \
31220
        || defined(OPENSSL_EXTRA)
31221
/* Encode OID string representation to ITU-T X.690 format */
31222
int EncodePolicyOID(byte *out, word32 *outSz, const char *in, void* heap)
31223
{
31224
    word32 idx = 0, nb_val;
31225
    char *token, *str, *ptr;
31226
    word32 len;
31227
31228
    (void)heap;
31229
31230
    if (out == NULL || outSz == NULL || *outSz < 2 || in == NULL)
31231
        return BAD_FUNC_ARG;
31232
31233
    /* duplicate string (including terminator) */
31234
    len = (word32)XSTRLEN(in);
31235
    str = (char *)XMALLOC(len+1, heap, DYNAMIC_TYPE_TMP_BUFFER);
31236
    if (str == NULL)
31237
        return MEMORY_E;
31238
    XMEMCPY(str, in, len+1);
31239
31240
    nb_val = 0;
31241
31242
    /* parse value, and set corresponding Policy OID value */
31243
    token = XSTRTOK(str, ".", &ptr);
31244
    while (token != NULL)
31245
    {
31246
        word32 val = (word32)XATOI(token);
31247
31248
        if (nb_val == 0) {
31249
            if (val > 2) {
31250
                XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
31251
                return ASN_OBJECT_ID_E;
31252
            }
31253
31254
            out[idx] = (byte)(40 * val);
31255
        }
31256
        else if (nb_val == 1) {
31257
            if (val > 127) {
31258
                XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
31259
                return ASN_OBJECT_ID_E;
31260
            }
31261
31262
            if (idx > *outSz) {
31263
                XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
31264
                return BUFFER_E;
31265
            }
31266
31267
            out[idx++] += (byte)val;
31268
        }
31269
        else {
31270
            word32  tb = 0;
31271
            int     i = 0;
31272
            byte    oid[MAX_OID_SZ];
31273
31274
            while (val >= 128) {
31275
                word32 x = val % 128;
31276
                val /= 128;
31277
                oid[i++] = (byte) (((tb++) ? 0x80 : 0) | x);
31278
            }
31279
31280
            if ((idx+(word32)i) >= *outSz) {
31281
                XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
31282
                return BUFFER_E;
31283
            }
31284
31285
            oid[i] = (byte) (((tb++) ? 0x80 : 0) | val);
31286
31287
            /* push value in the right order */
31288
            while (i >= 0)
31289
                out[idx++] = oid[i--];
31290
        }
31291
31292
        token = XSTRTOK(NULL, ".", &ptr);
31293
        nb_val++;
31294
    }
31295
31296
    *outSz = idx;
31297
31298
    XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
31299
    return 0;
31300
}
31301
#endif /* WOLFSSL_CERT_EXT || OPENSSL_EXTRA */
31302
31303
#endif /* !NO_CERTS */
31304
31305
#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL))
31306
/* Helper function for wolfSSL_i2d_DHparams */
31307
int StoreDHparams(byte* out, word32* outLen, mp_int* p, mp_int* g)
31308
{
31309
#ifndef WOLFSSL_ASN_TEMPLATE
31310
    word32 idx = 0;
31311
    word32 total;
31312
31313
    WOLFSSL_ENTER("StoreDHparams");
31314
31315
    if (out == NULL) {
31316
        WOLFSSL_MSG("Null buffer error");
31317
        return BUFFER_E;
31318
    }
31319
31320
    /* determine size */
31321
    /* integer - g */
31322
    idx = SetASNIntMP(g, -1, NULL);
31323
    /* integer - p */
31324
    idx += SetASNIntMP(p, -1, NULL);
31325
    total = idx;
31326
     /* sequence */
31327
    idx += SetSequence(idx, NULL);
31328
31329
    /* make sure output fits in buffer */
31330
    if (idx > *outLen) {
31331
        return BUFFER_E;
31332
    }
31333
31334
    /* write DH parameters */
31335
    /* sequence - for P and G only */
31336
    idx = SetSequence(total, out);
31337
    /* integer - p */
31338
    idx += SetASNIntMP(p, -1, out + idx);
31339
    /* integer - g */
31340
    idx += SetASNIntMP(g, -1, out + idx);
31341
    *outLen = idx;
31342
31343
    return 0;
31344
#else
31345
    ASNSetData dataASN[dhParamASN_Length];
31346
    int ret = 0;
31347
    int sz = 0;
31348
31349
    WOLFSSL_ENTER("StoreDHparams");
31350
    if (out == NULL) {
31351
        ret = BUFFER_E;
31352
    }
31353
    if (ret == 0) {
31354
        XMEMSET(dataASN, 0, sizeof(dataASN));
31355
        /* Set mp_int containing p and g. */
31356
        SetASN_MP(&dataASN[DHPARAMASN_IDX_PRIME], p);
31357
        SetASN_MP(&dataASN[DHPARAMASN_IDX_BASE], g);
31358
        /* privateValueLength not encoded. */
31359
        dataASN[DHPARAMASN_IDX_PRIVLEN].noOut = 1;
31360
31361
        /* Calculate the size of the DH parameters. */
31362
        ret = SizeASN_Items(dhParamASN, dataASN, dhParamASN_Length, &sz);
31363
    }
31364
    /* Check buffer is big enough for encoding. */
31365
    if ((ret == 0) && ((int)*outLen < sz)) {
31366
        ret = BUFFER_E;
31367
    }
31368
    if (ret == 0) {
31369
        /* Encode the DH parameters into buffer. */
31370
        SetASN_Items(dhParamASN, dataASN, dhParamASN_Length, out);
31371
        /* Set the actual encoding size. */
31372
        *outLen = (word32)sz;
31373
    }
31374
31375
    return ret;
31376
#endif /* WOLFSSL_ASN_TEMPLATE */
31377
}
31378
#endif /* !NO_DH && (WOLFSSL_QT || OPENSSL_ALL) */
31379
31380
#if defined(HAVE_ECC) || !defined(NO_DSA)
31381
31382
#ifdef WOLFSSL_ASN_TEMPLATE
31383
/* ASN.1 template for DSA signature.
31384
 * RFC 5912, 6 - DSA-Sig-Value
31385
 */
31386
static const ASNItem dsaSigASN[] = {
31387
/* SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 },
31388
                            /* r */
31389
/* R   */     { 1, ASN_INTEGER, 0, 0, 0 },
31390
                            /* s */
31391
/* S   */     { 1, ASN_INTEGER, 0, 0, 0 },
31392
};
31393
enum {
31394
    DSASIGASN_IDX_SEQ = 0,
31395
    DSASIGASN_IDX_R,
31396
    DSASIGASN_IDX_S
31397
};
31398
31399
1.87k
#define dsaSigASN_Length (sizeof(dsaSigASN) / sizeof(ASNItem))
31400
#endif
31401
31402
/* Der Encode r & s ints into out, outLen is (in/out) size */
31403
int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s)
31404
562
{
31405
#ifndef WOLFSSL_ASN_TEMPLATE
31406
    word32 idx = 0;
31407
    int    rSz;                           /* encoding size */
31408
    int    sSz;
31409
    int    headerSz = 4;   /* 2*ASN_TAG + 2*LEN(ENUM) */
31410
31411
    /* If the leading bit on the INTEGER is a 1, add a leading zero */
31412
    int rLeadingZero = mp_leading_bit(r);
31413
    int sLeadingZero = mp_leading_bit(s);
31414
    int rLen = mp_unsigned_bin_size(r);   /* big int size */
31415
    int sLen = mp_unsigned_bin_size(s);
31416
31417
    if (*outLen < (word32)((rLen + rLeadingZero + sLen + sLeadingZero +
31418
            headerSz + 2)))  /* SEQ_TAG + LEN(ENUM) */
31419
        return BUFFER_E;
31420
31421
    idx = SetSequence((word32)(rLen + rLeadingZero + sLen + sLeadingZero +
31422
        headerSz), out);
31423
31424
    /* store r */
31425
    rSz = SetASNIntMP(r, (int)(*outLen - idx), &out[idx]);
31426
    if (rSz < 0)
31427
        return rSz;
31428
    idx += (word32)rSz;
31429
31430
    /* store s */
31431
    sSz = SetASNIntMP(s, (int)(*outLen - idx), &out[idx]);
31432
    if (sSz < 0)
31433
        return sSz;
31434
    idx += (word32)sSz;
31435
31436
    *outLen = idx;
31437
31438
    return 0;
31439
#else
31440
562
    ASNSetData dataASN[dsaSigASN_Length];
31441
562
    int ret;
31442
562
    int sz;
31443
31444
    /* Clear dynamic data and set mp_ints r and s */
31445
562
    XMEMSET(dataASN, 0, sizeof(dataASN));
31446
562
    SetASN_MP(&dataASN[DSASIGASN_IDX_R], r);
31447
562
    SetASN_MP(&dataASN[DSASIGASN_IDX_S], s);
31448
31449
    /* Calculate size of encoding. */
31450
562
    ret = SizeASN_Items(dsaSigASN, dataASN, dsaSigASN_Length, &sz);
31451
    /* Check buffer is big enough for encoding. */
31452
562
    if ((ret == 0) && ((int)*outLen < sz)) {
31453
21
       ret = BUFFER_E;
31454
21
    }
31455
562
    if (ret == 0) {
31456
        /* Encode DSA signature into buffer. */
31457
541
        SetASN_Items(dsaSigASN, dataASN, dsaSigASN_Length, out);
31458
        /* Set the actual encoding size. */
31459
541
        *outLen = (word32)sz;
31460
541
    }
31461
31462
562
    return ret;
31463
562
#endif /* WOLFSSL_ASN_TEMPLATE */
31464
562
}
31465
31466
#ifndef WOLFSSL_ASN_TEMPLATE
31467
/* determine if leading bit is set */
31468
static word32 is_leading_bit_set(const byte* input, word32 sz)
31469
{
31470
    byte c = 0;
31471
    if (sz > 0)
31472
        c = input[0];
31473
    return (c & 0x80) != 0;
31474
}
31475
static word32 trim_leading_zeros(const byte** input, word32 sz)
31476
{
31477
    int i;
31478
    word32 leadingZeroCount = 0;
31479
    const byte* tmp = *input;
31480
    for (i=0; i<(int)sz; i++) {
31481
        if (tmp[i] != 0)
31482
            break;
31483
        leadingZeroCount++;
31484
    }
31485
    /* catch all zero case */
31486
    if (sz > 0 && leadingZeroCount == sz) {
31487
        leadingZeroCount--;
31488
    }
31489
    *input += leadingZeroCount;
31490
    sz -= leadingZeroCount;
31491
    return sz;
31492
}
31493
#endif
31494
31495
/* Der Encode r & s ints into out, outLen is (in/out) size */
31496
/* All input/outputs are assumed to be big-endian */
31497
int StoreECC_DSA_Sig_Bin(byte* out, word32* outLen, const byte* r, word32 rLen,
31498
    const byte* s, word32 sLen)
31499
0
{
31500
#ifndef WOLFSSL_ASN_TEMPLATE
31501
    int ret;
31502
    word32 idx;
31503
    word32 headerSz = 4;   /* 2*ASN_TAG + 2*LEN(ENUM) */
31504
    word32 rAddLeadZero, sAddLeadZero;
31505
31506
    if ((out == NULL) || (outLen == NULL) || (r == NULL) || (s == NULL))
31507
        return BAD_FUNC_ARG;
31508
31509
    /* Trim leading zeros */
31510
    rLen = trim_leading_zeros(&r, rLen);
31511
    sLen = trim_leading_zeros(&s, sLen);
31512
    /* If the leading bit on the INTEGER is a 1, add a leading zero */
31513
    /* Add leading zero if MSB is set */
31514
    rAddLeadZero = is_leading_bit_set(r, rLen);
31515
    sAddLeadZero = is_leading_bit_set(s, sLen);
31516
31517
    if (*outLen < (rLen + rAddLeadZero + sLen + sAddLeadZero +
31518
                   headerSz + 2))  /* SEQ_TAG + LEN(ENUM) */
31519
        return BUFFER_E;
31520
31521
    idx = SetSequence(rLen+rAddLeadZero + sLen+sAddLeadZero + headerSz, out);
31522
31523
    /* store r */
31524
    ret = SetASNInt((int)rLen, (byte)(rAddLeadZero ? 0x80U : 0x00U), &out[idx]);
31525
    if (ret < 0)
31526
        return ret;
31527
    idx += (word32)ret;
31528
    XMEMCPY(&out[idx], r, rLen);
31529
    idx += rLen;
31530
31531
    /* store s */
31532
    ret = SetASNInt((int)sLen, (byte)(sAddLeadZero ? 0x80U : 0x00U), &out[idx]);
31533
    if (ret < 0)
31534
        return ret;
31535
    idx += (word32)ret;
31536
    XMEMCPY(&out[idx], s, sLen);
31537
    idx += sLen;
31538
31539
    *outLen = idx;
31540
31541
    return 0;
31542
#else
31543
0
    ASNSetData dataASN[dsaSigASN_Length];
31544
0
    int ret;
31545
0
    int sz;
31546
31547
    /* Clear dynamic data and set buffers for r and s */
31548
0
    XMEMSET(dataASN, 0, sizeof(dataASN));
31549
0
    SetASN_Buffer(&dataASN[DSASIGASN_IDX_R], r, rLen);
31550
0
    SetASN_Buffer(&dataASN[DSASIGASN_IDX_S], s, sLen);
31551
31552
    /* Calculate size of encoding. */
31553
0
    ret = SizeASN_Items(dsaSigASN, dataASN, dsaSigASN_Length, &sz);
31554
    /* Check buffer is big enough for encoding. */
31555
0
    if ((ret == 0) && ((int)*outLen < sz)) {
31556
0
       ret = BUFFER_E;
31557
0
    }
31558
0
    if (ret == 0) {
31559
        /* Encode DSA signature into buffer. */
31560
0
        SetASN_Items(dsaSigASN, dataASN, dsaSigASN_Length, out);
31561
        /* Set the actual encoding size. */
31562
0
        *outLen = (word32)sz;
31563
0
    }
31564
31565
0
    return ret;
31566
0
#endif /* WOLFSSL_ASN_TEMPLATE */
31567
0
}
31568
31569
/* Der Decode ECC-DSA Signature with R/S as unsigned bin */
31570
/* All input/outputs are assumed to be big-endian */
31571
int DecodeECC_DSA_Sig_Bin(const byte* sig, word32 sigLen, byte* r, word32* rLen,
31572
    byte* s, word32* sLen)
31573
0
{
31574
#ifndef WOLFSSL_ASN_TEMPLATE
31575
    int    ret;
31576
    word32 idx = 0;
31577
    int    len = 0;
31578
31579
    if (GetSequence(sig, &idx, &len, sigLen) < 0) {
31580
        return ASN_ECC_KEY_E;
31581
    }
31582
31583
#ifndef NO_STRICT_ECDSA_LEN
31584
    /* enable strict length checking for signature */
31585
    if (sigLen != idx + (word32)len) {
31586
        return ASN_ECC_KEY_E;
31587
    }
31588
#else
31589
    /* allow extra signature bytes at end */
31590
    if ((word32)len > (sigLen - idx)) {
31591
        return ASN_ECC_KEY_E;
31592
    }
31593
#endif
31594
31595
    ret = GetASNInt(sig, &idx, &len, sigLen);
31596
    if (ret != 0)
31597
        return ret;
31598
    if (rLen)
31599
        *rLen = (word32)len;
31600
    if (r)
31601
        XMEMCPY(r, (byte*)sig + idx, (size_t)len);
31602
    idx += (word32)len;
31603
31604
    ret = GetASNInt(sig, &idx, &len, sigLen);
31605
    if (ret != 0)
31606
        return ret;
31607
    if (sLen)
31608
        *sLen = (word32)len;
31609
    if (s)
31610
        XMEMCPY(s, (byte*)sig + idx, (size_t)len);
31611
31612
#ifndef NO_STRICT_ECDSA_LEN
31613
    /* sanity check that the index has been advanced all the way to the end of
31614
     * the buffer */
31615
    if (idx + (word32)len != sigLen) {
31616
        ret = ASN_ECC_KEY_E;
31617
    }
31618
#endif
31619
31620
    return ret;
31621
#else
31622
0
    ASNGetData dataASN[dsaSigASN_Length];
31623
0
    word32 idx = 0;
31624
31625
    /* Clear dynamic data and set buffers to put r and s into. */
31626
0
    XMEMSET(dataASN, 0, sizeof(dataASN));
31627
0
    GetASN_Buffer(&dataASN[DSASIGASN_IDX_R], r, rLen);
31628
0
    GetASN_Buffer(&dataASN[DSASIGASN_IDX_S], s, sLen);
31629
31630
    /* Decode the DSA signature. */
31631
0
    return GetASN_Items(dsaSigASN, dataASN, dsaSigASN_Length, 1, sig, &idx,
31632
0
                        sigLen);
31633
0
#endif /* WOLFSSL_ASN_TEMPLATE */
31634
0
}
31635
31636
int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s)
31637
240
{
31638
240
    return DecodeECC_DSA_Sig_Ex(sig, sigLen, r, s, 1);
31639
240
}
31640
31641
int DecodeECC_DSA_Sig_Ex(const byte* sig, word32 sigLen, mp_int* r, mp_int* s,
31642
    int init)
31643
769
{
31644
#ifndef WOLFSSL_ASN_TEMPLATE
31645
    word32 idx = 0;
31646
    int    len = 0;
31647
31648
    if (GetSequence(sig, &idx, &len, sigLen) < 0) {
31649
        return ASN_ECC_KEY_E;
31650
    }
31651
31652
#ifndef NO_STRICT_ECDSA_LEN
31653
    /* enable strict length checking for signature */
31654
    if (sigLen != idx + (word32)len) {
31655
        return ASN_ECC_KEY_E;
31656
    }
31657
#else
31658
    /* allow extra signature bytes at end */
31659
    if ((word32)len > (sigLen - idx)) {
31660
        return ASN_ECC_KEY_E;
31661
    }
31662
#endif
31663
31664
    if (GetIntPositive(r, sig, &idx, sigLen, init) < 0) {
31665
        return ASN_ECC_KEY_E;
31666
    }
31667
31668
    if (GetIntPositive(s, sig, &idx, sigLen, init) < 0) {
31669
        mp_clear(r);
31670
        return ASN_ECC_KEY_E;
31671
    }
31672
31673
#ifndef NO_STRICT_ECDSA_LEN
31674
    /* sanity check that the index has been advanced all the way to the end of
31675
     * the buffer */
31676
    if (idx != sigLen) {
31677
        mp_clear(r);
31678
        mp_clear(s);
31679
        return ASN_ECC_KEY_E;
31680
    }
31681
#endif
31682
31683
    return 0;
31684
#else
31685
769
    ASNGetData dataASN[dsaSigASN_Length];
31686
769
    word32 idx = 0;
31687
769
    int ret;
31688
31689
    /* Clear dynamic data and set mp_ints to put r and s into. */
31690
769
    XMEMSET(dataASN, 0, sizeof(dataASN));
31691
769
    if (init) {
31692
240
        GetASN_MP(&dataASN[DSASIGASN_IDX_R], r);
31693
240
        GetASN_MP(&dataASN[DSASIGASN_IDX_S], s);
31694
240
    }
31695
529
    else {
31696
529
        GetASN_MP_Inited(&dataASN[DSASIGASN_IDX_R], r);
31697
529
        GetASN_MP_Inited(&dataASN[DSASIGASN_IDX_S], s);
31698
529
    }
31699
31700
    /* Decode the DSA signature. */
31701
769
    ret = GetASN_Items(dsaSigASN, dataASN, dsaSigASN_Length, 0, sig, &idx,
31702
769
                       sigLen);
31703
769
#ifndef NO_STRICT_ECDSA_LEN
31704
    /* sanity check that the index has been advanced all the way to the end of
31705
     * the buffer */
31706
769
    if ((ret == 0) && (idx != sigLen)) {
31707
0
        ret = ASN_ECC_KEY_E;
31708
0
    }
31709
769
#endif
31710
769
    if (ret != 0) {
31711
3
        mp_clear(r);
31712
3
        mp_clear(s);
31713
3
    }
31714
31715
769
    return ret;
31716
769
#endif /* WOLFSSL_ASN_TEMPLATE */
31717
769
}
31718
#endif
31719
31720
31721
#ifdef WOLFSSL_ASN_TEMPLATE
31722
#ifdef WOLFSSL_CUSTOM_CURVES
31723
/* Convert data to hex string.
31724
 *
31725
 * Big-endian byte array is converted to big-endian hexadecimal string.
31726
 *
31727
 * @param [in]  input  Buffer containing data.
31728
 * @param [in]  inSz   Size of data in buffer.
31729
 * @param [out] out    Buffer to hold hex string.
31730
 */
31731
static void DataToHexString(const byte* input, word32 inSz, char* out)
31732
0
{
31733
0
    static const char hexChar[] = { '0', '1', '2', '3', '4', '5', '6', '7',
31734
0
                                    '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
31735
0
    word32 i;
31736
31737
    /* Converting a byte of data at a time to two hex characters. */
31738
0
    for (i = 0; i < inSz; i++) {
31739
0
        out[i*2 + 0] = hexChar[input[i] >> 4];
31740
0
        out[i*2 + 1] = hexChar[input[i] & 0xf];
31741
0
    }
31742
    /* NUL terminate string. */
31743
0
    out[i * 2] = '\0';
31744
0
}
31745
31746
#ifndef WOLFSSL_ECC_CURVE_STATIC
31747
/* Convert data to hex string and place in allocated buffer.
31748
 *
31749
 * Big-endian byte array is converted to big-endian hexadecimal string.
31750
 *
31751
 * @param [in]  input     Buffer containing data.
31752
 * @param [in]  inSz      Size of data in buffer.
31753
 * @param [out] out       Allocated buffer holding hex string.
31754
 * @param [in]  heap      Dynamic memory allocation hint.
31755
 * @param [in]  heapType  Type of heap to use.
31756
 * @return  0 on succcess.
31757
 * @return  MEMORY_E when dynamic memory allocation fails.
31758
 */
31759
static int DataToHexStringAlloc(const byte* input, word32 inSz, char** out,
31760
                                void* heap, int heapType)
31761
0
{
31762
0
    int ret = 0;
31763
0
    char* str;
31764
31765
    /* Allocate for 2 string characters ber byte plus NUL. */
31766
0
    str = (char*)XMALLOC(inSz * 2 + 1, heap, heapType);
31767
0
    if (str == NULL) {
31768
0
        ret = MEMORY_E;
31769
0
    }
31770
0
    else {
31771
        /* Convert to hex string. */
31772
0
        DataToHexString(input, inSz, str);
31773
0
        *out = str;
31774
0
    }
31775
31776
0
    (void)heap;
31777
0
    (void)heapType;
31778
31779
0
    return ret;
31780
0
}
31781
#endif /* WOLFSSL_ECC_CURVE_STATIC */
31782
31783
/* ASN.1 template for SpecifiedECDomain.
31784
 * SEC 1 Ver. 2.0, C.2 - Syntax for Elliptic Curve Domain Parameters
31785
 * NOTE: characteristic-two-field not supported. */
31786
static const ASNItem eccSpecifiedASN[] = {
31787
            /* version */
31788
/* VER        */ { 0, ASN_INTEGER, 0, 0, 0 },
31789
                                     /* fieldID */
31790
/* PRIME_SEQ  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
31791
                                         /* prime-field or characteristic-two-field */
31792
/* PRIME_OID  */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
31793
                                         /* Prime-p */
31794
/* PRIME_P    */     { 1, ASN_INTEGER, 0, 0, 0 },
31795
                                     /* fieldID */
31796
/* PARAM_SEQ, */ { 0, ASN_SEQUENCE, 1, 1, 0 },
31797
                                         /* a */
31798
/* PARAM_A    */     { 1, ASN_OCTET_STRING, 0, 0, 0 },
31799
                                         /* b */
31800
/* PARAM_B    */     { 1, ASN_OCTET_STRING, 0, 0, 0 },
31801
                                         /* seed */
31802
/* PARAM_SEED */     { 1, ASN_BIT_STRING, 0, 0, 1 },
31803
                                     /* base */
31804
/* BASE       */ { 0, ASN_OCTET_STRING, 0, 0, 0 },
31805
                                     /* order */
31806
/* ORDER      */ { 0, ASN_INTEGER, 0, 0, 0 },
31807
                                     /* cofactor */
31808
/* COFACTOR   */ { 0, ASN_INTEGER, 0, 0, 1 },
31809
                                     /* hash */
31810
/* HASH_SEQ   */ { 0, ASN_SEQUENCE, 0, 0, 1 },
31811
};
31812
enum {
31813
    ECCSPECIFIEDASN_IDX_VER = 0,
31814
    ECCSPECIFIEDASN_IDX_PRIME_SEQ,
31815
    ECCSPECIFIEDASN_IDX_PRIME_OID,
31816
    ECCSPECIFIEDASN_IDX_PRIME_P,
31817
    ECCSPECIFIEDASN_IDX_PARAM_SEQ,
31818
    ECCSPECIFIEDASN_IDX_PARAM_A,
31819
    ECCSPECIFIEDASN_IDX_PARAM_B,
31820
    ECCSPECIFIEDASN_IDX_PARAM_SEED,
31821
    ECCSPECIFIEDASN_IDX_BASE,
31822
    ECCSPECIFIEDASN_IDX_ORDER,
31823
    ECCSPECIFIEDASN_IDX_COFACTOR,
31824
    ECCSPECIFIEDASN_IDX_HASH_SEQ
31825
};
31826
31827
/* Number of items in ASN.1 template for SpecifiedECDomain. */
31828
0
#define eccSpecifiedASN_Length (sizeof(eccSpecifiedASN) / sizeof(ASNItem))
31829
31830
/* OID indicating the prime field is explicity defined. */
31831
static const byte primeFieldOID[] = {
31832
    0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01
31833
};
31834
static const char ecSetCustomName[] = "Custom";
31835
31836
/* Explicit EC parameter values. */
31837
static int EccSpecifiedECDomainDecode(const byte* input, word32 inSz,
31838
                                      ecc_key* key)
31839
0
{
31840
0
    DECL_ASNGETDATA(dataASN, eccSpecifiedASN_Length);
31841
0
    int ret = 0;
31842
0
    ecc_set_type* curve;
31843
0
    word32 idx = 0;
31844
0
    byte version;
31845
0
    byte cofactor;
31846
0
    const byte *base;
31847
0
    word32 baseLen;
31848
31849
    /* Allocate a new parameter set. */
31850
0
    curve = (ecc_set_type*)XMALLOC(sizeof(*curve), key->heap,
31851
0
                                                       DYNAMIC_TYPE_ECC_BUFFER);
31852
0
    if (curve == NULL) {
31853
0
        ret = MEMORY_E;
31854
0
    }
31855
0
    else {
31856
        /* Clear out parameters and set fields to indicate it is custom. */
31857
0
        XMEMSET(curve, 0, sizeof(*curve));
31858
0
    }
31859
31860
0
    CALLOC_ASNGETDATA(dataASN, eccSpecifiedASN_Length, ret, key->heap);
31861
31862
0
    if (ret == 0) {
31863
        /* Set name to be: "Custom" */
31864
0
    #ifndef WOLFSSL_ECC_CURVE_STATIC
31865
0
        curve->name = ecSetCustomName;
31866
    #else
31867
        XMEMCPY((void*)curve->name, ecSetCustomName, sizeof(ecSetCustomName));
31868
    #endif
31869
0
        curve->id = ECC_CURVE_CUSTOM;
31870
31871
        /* Get version, must have prime field OID and get co-factor. */
31872
0
        GetASN_Int8Bit(&dataASN[ECCSPECIFIEDASN_IDX_VER], &version);
31873
0
        GetASN_ExpBuffer(&dataASN[ECCSPECIFIEDASN_IDX_PRIME_OID],
31874
0
                primeFieldOID, sizeof(primeFieldOID));
31875
0
        GetASN_Int8Bit(&dataASN[ECCSPECIFIEDASN_IDX_COFACTOR], &cofactor);
31876
        /* Decode the explicit parameters. */
31877
0
        ret = GetASN_Items(eccSpecifiedASN, dataASN, eccSpecifiedASN_Length, 1,
31878
0
                           input, &idx, inSz);
31879
0
    }
31880
    /* Version must be 1 or 2 for supporting explicit parameters. */
31881
0
    if ((ret == 0) && (version < 1 || version > 3)) {
31882
0
        ret = ASN_PARSE_E;
31883
0
    }
31884
0
#ifndef WOLFSSL_NO_ASN_STRICT
31885
    /* Only version 2 and above can have a seed. */
31886
0
    if ((ret == 0) && (dataASN[ECCSPECIFIEDASN_IDX_PARAM_SEED].tag != 0) &&
31887
0
            (version < 2)) {
31888
0
        ret = ASN_PARSE_E;
31889
0
    }
31890
0
#endif
31891
    /* Only version 2 and above can have a hash algorithm. */
31892
0
    if ((ret == 0) && (dataASN[ECCSPECIFIEDASN_IDX_HASH_SEQ].tag != 0) &&
31893
0
            (version < 2)) {
31894
0
        ret = ASN_PARSE_E;
31895
0
    }
31896
0
    if ((ret == 0) && (dataASN[ECCSPECIFIEDASN_IDX_COFACTOR].tag != 0)) {
31897
        /* Store optional co-factor. */
31898
0
        curve->cofactor = cofactor;
31899
0
    }
31900
0
    if (ret == 0) {
31901
        /* Length of the prime in bytes is the curve size. */
31902
0
        curve->size =
31903
0
                (int)dataASN[ECCSPECIFIEDASN_IDX_PRIME_P].data.ref.length;
31904
        /* Base point: 0x04 <x> <y> (must be uncompressed). */
31905
0
        GetASN_GetConstRef(&dataASN[ECCSPECIFIEDASN_IDX_BASE], &base,
31906
0
                &baseLen);
31907
0
        if ((baseLen < (word32)curve->size * 2 + 1) || (base[0] != 0x4)) {
31908
0
            ret = ASN_PARSE_E;
31909
0
        }
31910
0
    }
31911
    /* Put the curve parameters into the set.
31912
     * Convert the big-endian number byte array to a big-endian string.
31913
     */
31914
0
    #ifndef WOLFSSL_ECC_CURVE_STATIC
31915
    /* Allocate buffer to put hex strings into. */
31916
0
    if (ret == 0) {
31917
        /* Base X-ordinate */
31918
0
        ret = DataToHexStringAlloc(base + 1, (word32)curve->size,
31919
0
                                   (char**)&curve->Gx, key->heap,
31920
0
                                   DYNAMIC_TYPE_ECC_BUFFER);
31921
0
    }
31922
0
    if (ret == 0) {
31923
        /* Base Y-ordinate */
31924
0
        ret = DataToHexStringAlloc(base + 1 + curve->size, (word32)curve->size,
31925
0
                                   (char**)&curve->Gy, key->heap,
31926
0
                                   DYNAMIC_TYPE_ECC_BUFFER);
31927
0
    }
31928
0
    if (ret == 0) {
31929
        /* Prime */
31930
0
        ret = DataToHexStringAlloc(
31931
0
                dataASN[ECCSPECIFIEDASN_IDX_PRIME_P].data.ref.data,
31932
0
                dataASN[ECCSPECIFIEDASN_IDX_PRIME_P].data.ref.length,
31933
0
                (char**)&curve->prime, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
31934
0
    }
31935
0
    if (ret == 0) {
31936
        /* Parameter A */
31937
0
        ret = DataToHexStringAlloc(
31938
0
                dataASN[ECCSPECIFIEDASN_IDX_PARAM_A].data.ref.data,
31939
0
                dataASN[ECCSPECIFIEDASN_IDX_PARAM_A].data.ref.length,
31940
0
                (char**)&curve->Af, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
31941
0
    }
31942
0
    if (ret == 0) {
31943
        /* Parameter B */
31944
0
        ret = DataToHexStringAlloc(
31945
0
                dataASN[ECCSPECIFIEDASN_IDX_PARAM_B].data.ref.data,
31946
0
                dataASN[ECCSPECIFIEDASN_IDX_PARAM_B].data.ref.length,
31947
0
                (char**)&curve->Bf, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
31948
0
    }
31949
0
    if (ret == 0) {
31950
        /* Order of curve */
31951
0
        ret = DataToHexStringAlloc(
31952
0
                dataASN[ECCSPECIFIEDASN_IDX_ORDER].data.ref.data,
31953
0
                dataASN[ECCSPECIFIEDASN_IDX_ORDER].data.ref.length,
31954
0
                (char**)&curve->order, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
31955
0
    }
31956
    #else
31957
    if (ret == 0) {
31958
        /* Base X-ordinate */
31959
        DataToHexString(base + 1, curve->size, curve->Gx);
31960
        /* Base Y-ordinate */
31961
        DataToHexString(base + 1 + curve->size, curve->size, curve->Gy);
31962
        /* Prime */
31963
        DataToHexString(dataASN[ECCSPECIFIEDASN_IDX_PRIME_P].data.ref.data,
31964
                        dataASN[ECCSPECIFIEDASN_IDX_PRIME_P].data.ref.length,
31965
                        curve->prime);
31966
        /* Parameter A */
31967
        DataToHexString(dataASN[ECCSPECIFIEDASN_IDX_PARAM_A].data.ref.data,
31968
                        dataASN[ECCSPECIFIEDASN_IDX_PARAM_A].data.ref.length,
31969
                        curve->Af);
31970
        /* Parameter B */
31971
        DataToHexString(dataASN[ECCSPECIFIEDASN_IDX_PARAM_B].data.ref.data,
31972
                        dataASN[ECCSPECIFIEDASN_IDX_PARAM_B].data.ref.length,
31973
                        curve->Bf);
31974
        /* Order of curve */
31975
        DataToHexString(dataASN[ECCSPECIFIEDASN_IDX_ORDER].data.ref.data,
31976
                        dataASN[ECCSPECIFIEDASN_IDX_ORDER].data.ref.length,
31977
                        curve->order);
31978
    }
31979
    #endif /* WOLFSSL_ECC_CURVE_STATIC */
31980
31981
    /* Store parameter set in key. */
31982
0
    if ((ret == 0) && (wc_ecc_set_custom_curve(key, curve) < 0)) {
31983
0
        ret = ASN_PARSE_E;
31984
0
    }
31985
0
    if (ret == 0) {
31986
        /* The parameter set was allocated.. */
31987
0
        key->deallocSet = 1;
31988
0
    }
31989
31990
0
    if ((ret != 0) && (curve != NULL)) {
31991
        /* Failed to set parameters so free paramter set. */
31992
0
        wc_ecc_free_curve(curve, key->heap);
31993
0
    }
31994
31995
0
    FREE_ASNGETDATA(dataASN, key->heap);
31996
0
    return ret;
31997
0
}
31998
#endif /* WOLFSSL_CUSTOM_CURVES */
31999
#endif /* WOLFSSL_ASN_TEMPLATE */
32000
32001
#ifdef HAVE_ECC
32002
32003
#ifdef WOLFSSL_ASN_TEMPLATE
32004
/* ASN.1 template for ECC private key.
32005
 * SEC.1 Ver 2.0, C.4 - Syntax for Elliptic Curve Private Keys
32006
 */
32007
static const ASNItem eccKeyASN[] = {
32008
/* SEQ         */    { 0, ASN_SEQUENCE, 1, 1, 0 },
32009
                                       /* version */
32010
/* VER         */        { 1, ASN_INTEGER, 0, 0, 0 },
32011
                                       /* privateKey */
32012
/* PKEY        */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
32013
                                       /* parameters */
32014
/* PARAMS      */        { 1, ASN_CONTEXT_SPECIFIC | ASN_ECC_PARAMS, 1, 1, 1 },
32015
                                           /* named */
32016
/* CURVEID     */            { 2, ASN_OBJECT_ID, 0, 0, 2 },
32017
                                           /* specified */
32018
/* CURVEPARAMS */            { 2, ASN_SEQUENCE, 1, 0, 2 },
32019
                                       /* publicKey */
32020
/* PUBKEY      */        { 1, ASN_CONTEXT_SPECIFIC | ASN_ECC_PUBKEY, 1, 1, 1 },
32021
                                           /* Uncompressed point - X9.62. */
32022
/* PUBKEY_VAL, */            { 2, ASN_BIT_STRING, 0, 0, 0 },
32023
};
32024
enum {
32025
    ECCKEYASN_IDX_SEQ = 0,
32026
    ECCKEYASN_IDX_VER,
32027
    ECCKEYASN_IDX_PKEY,
32028
    ECCKEYASN_IDX_PARAMS,
32029
    ECCKEYASN_IDX_CURVEID,
32030
    ECCKEYASN_IDX_CURVEPARAMS,
32031
    ECCKEYASN_IDX_PUBKEY,
32032
    ECCKEYASN_IDX_PUBKEY_VAL
32033
};
32034
32035
/* Number of items in ASN.1 template for ECC private key. */
32036
0
#define eccKeyASN_Length (sizeof(eccKeyASN) / sizeof(ASNItem))
32037
#endif
32038
32039
WOLFSSL_ABI
32040
int wc_EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key,
32041
                        word32 inSz)
32042
0
{
32043
#ifndef WOLFSSL_ASN_TEMPLATE
32044
    word32 oidSum;
32045
    int    version, length;
32046
    int    privSz, pubSz = 0;
32047
    byte   b;
32048
    int    ret = 0;
32049
    int    curve_id = ECC_CURVE_DEF;
32050
#ifdef WOLFSSL_SMALL_STACK
32051
    byte* priv;
32052
    byte* pub = NULL;
32053
#else
32054
    byte priv[ECC_MAXSIZE+1];
32055
    byte pub[2*(ECC_MAXSIZE+1)]; /* public key has two parts plus header */
32056
#endif
32057
    word32 algId = 0;
32058
    byte* pubData = NULL;
32059
32060
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
32061
        return BAD_FUNC_ARG;
32062
32063
    /* if has pkcs8 header skip it */
32064
    if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) {
32065
        /* ignore error, did not have pkcs8 header */
32066
    }
32067
    else {
32068
        curve_id = wc_ecc_get_oid(algId, NULL, NULL);
32069
    }
32070
32071
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
32072
        return ASN_PARSE_E;
32073
32074
    if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
32075
        return ASN_PARSE_E;
32076
32077
    if (*inOutIdx >= inSz)
32078
        return ASN_PARSE_E;
32079
32080
    b = input[*inOutIdx];
32081
    *inOutIdx += 1;
32082
32083
    /* priv type */
32084
    if (b != 4 && b != 6 && b != 7)
32085
        return ASN_PARSE_E;
32086
32087
    if (GetLength(input, inOutIdx, &length, inSz) < 0)
32088
        return ASN_PARSE_E;
32089
    privSz = length;
32090
32091
    if (privSz > ECC_MAXSIZE)
32092
        return BUFFER_E;
32093
32094
#ifdef WOLFSSL_SMALL_STACK
32095
    priv = (byte*)XMALLOC(privSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
32096
    if (priv == NULL)
32097
        return MEMORY_E;
32098
#endif
32099
32100
    /* priv key */
32101
    XMEMCPY(priv, &input[*inOutIdx], (size_t)privSz);
32102
    *inOutIdx += (word32)length;
32103
32104
    if ((*inOutIdx + 1) < inSz) {
32105
        /* prefix 0, may have */
32106
        b = input[*inOutIdx];
32107
        if (b == ECC_PREFIX_0) {
32108
            *inOutIdx += 1;
32109
32110
            if (GetLength(input, inOutIdx, &length, inSz) <= 0)
32111
                ret = ASN_PARSE_E;
32112
            else {
32113
                ret = GetObjectId(input, inOutIdx, &oidSum, oidIgnoreType,
32114
                                  inSz);
32115
                if (ret == 0) {
32116
                    if ((ret = CheckCurve(oidSum)) < 0)
32117
                        ret = ECC_CURVE_OID_E;
32118
                    else {
32119
                        curve_id = ret;
32120
                        ret = 0;
32121
                    }
32122
                }
32123
            }
32124
        }
32125
    }
32126
32127
    if (ret == 0 && (*inOutIdx + 1) < inSz) {
32128
        /* prefix 1 */
32129
        b = input[*inOutIdx];
32130
        *inOutIdx += 1;
32131
32132
        if (b != ECC_PREFIX_1) {
32133
            ret = ASN_ECC_KEY_E;
32134
        }
32135
        else if (GetLength(input, inOutIdx, &length, inSz) <= 0) {
32136
            ret = ASN_PARSE_E;
32137
        }
32138
        else {
32139
            /* key header */
32140
            ret = CheckBitString(input, inOutIdx, &length, inSz, 0, NULL);
32141
            if (ret == 0) {
32142
                /* pub key */
32143
                pubSz = length;
32144
                if (pubSz > 2*(ECC_MAXSIZE+1))
32145
                    ret = BUFFER_E;
32146
                else {
32147
            #ifdef WOLFSSL_SMALL_STACK
32148
                    pub = (byte*)XMALLOC(pubSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
32149
                    if (pub == NULL)
32150
                        ret = MEMORY_E;
32151
                    else
32152
            #endif
32153
                    {
32154
                        XMEMCPY(pub, &input[*inOutIdx], (size_t)pubSz);
32155
                        *inOutIdx += (word32)length;
32156
                        pubData = pub;
32157
                    }
32158
                }
32159
            }
32160
        }
32161
    }
32162
32163
    if (ret == 0) {
32164
        ret = wc_ecc_import_private_key_ex(priv, (word32)privSz, pubData,
32165
            (word32)pubSz, key, curve_id);
32166
    }
32167
32168
#ifdef WOLFSSL_SMALL_STACK
32169
    XFREE(priv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
32170
    XFREE(pub,  key->heap, DYNAMIC_TYPE_TMP_BUFFER);
32171
#endif
32172
32173
    return ret;
32174
#else
32175
0
    DECL_ASNGETDATA(dataASN, eccKeyASN_Length);
32176
0
    byte version;
32177
0
    int ret = 0;
32178
0
    int curve_id = ECC_CURVE_DEF;
32179
0
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12) || defined(SM2)
32180
0
    word32 algId = 0;
32181
0
#endif
32182
32183
    /* Validate parameters. */
32184
0
    if ((input == NULL) || (inOutIdx == NULL) || (key == NULL) || (inSz == 0)) {
32185
0
        ret = BAD_FUNC_ARG;
32186
0
    }
32187
32188
0
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12) || defined(SM2)
32189
    /* if has pkcs8 header skip it */
32190
0
    if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) {
32191
        /* ignore error, did not have pkcs8 header */
32192
0
    }
32193
0
    else {
32194
0
        curve_id = wc_ecc_get_oid(algId, NULL, NULL);
32195
0
    }
32196
0
#endif
32197
32198
0
    CALLOC_ASNGETDATA(dataASN, eccKeyASN_Length, ret, key->heap);
32199
32200
0
    if (ret == 0) {
32201
        /* Get the version and set the expected OID type. */
32202
0
        GetASN_Int8Bit(&dataASN[ECCKEYASN_IDX_VER], &version);
32203
0
        GetASN_OID(&dataASN[ECCKEYASN_IDX_CURVEID], oidCurveType);
32204
        /* Decode the private ECC key. */
32205
0
        ret = GetASN_Items(eccKeyASN, dataASN, eccKeyASN_Length, 1, input,
32206
0
                           inOutIdx, inSz);
32207
0
    }
32208
    /* Only version 1 supported. */
32209
0
    if ((ret == 0) && (version != 1)) {
32210
0
        ret = ASN_PARSE_E;
32211
0
    }
32212
    /* Curve Parameters are optional. */
32213
0
    if ((ret == 0) && (dataASN[ECCKEYASN_IDX_PARAMS].tag != 0)) {
32214
0
        if (dataASN[ECCKEYASN_IDX_CURVEID].tag != 0) {
32215
            /* Named curve - check and get id. */
32216
0
            curve_id = CheckCurve(dataASN[ECCKEYASN_IDX_CURVEID].data.oid.sum);
32217
0
            if (curve_id < 0) {
32218
0
                ret = ECC_CURVE_OID_E;
32219
0
            }
32220
0
        }
32221
0
        else {
32222
0
    #ifdef WOLFSSL_CUSTOM_CURVES
32223
            /* Parse explicit parameters. */
32224
0
            ret = EccSpecifiedECDomainDecode(
32225
0
                    dataASN[ECCKEYASN_IDX_CURVEPARAMS].data.ref.data,
32226
0
                    dataASN[ECCKEYASN_IDX_CURVEPARAMS].data.ref.length, key);
32227
    #else
32228
            /* Explicit parameters not supported in build configuration. */
32229
            ret = ASN_PARSE_E;
32230
    #endif
32231
0
        }
32232
0
    }
32233
0
    if (ret == 0) {
32234
        /* Import private key value and public point (may be NULL). */
32235
0
        ret = wc_ecc_import_private_key_ex(
32236
0
                dataASN[ECCKEYASN_IDX_PKEY].data.ref.data,
32237
0
                dataASN[ECCKEYASN_IDX_PKEY].data.ref.length,
32238
0
                dataASN[ECCKEYASN_IDX_PUBKEY_VAL].data.ref.data,
32239
0
                dataASN[ECCKEYASN_IDX_PUBKEY_VAL].data.ref.length,
32240
0
                key, curve_id);
32241
0
    }
32242
32243
0
    FREE_ASNGETDATA(dataASN, key->heap);
32244
0
    return ret;
32245
0
#endif
32246
0
}
32247
32248
32249
#ifdef WOLFSSL_CUSTOM_CURVES
32250
#ifndef WOLFSSL_ASN_TEMPLATE
32251
/* returns 0 on success */
32252
static int ASNToHexString(const byte* input, word32* inOutIdx, char** out,
32253
                          word32 inSz, void* heap, int heapType)
32254
{
32255
    int len;
32256
    int i;
32257
    char* str;
32258
    word32 localIdx;
32259
    byte   tag;
32260
32261
    if (*inOutIdx >= inSz) {
32262
        return BUFFER_E;
32263
    }
32264
32265
    localIdx = *inOutIdx;
32266
    if (GetASNTag(input, &localIdx, &tag, inSz) == 0 && tag == ASN_INTEGER) {
32267
        if (GetASNInt(input, inOutIdx, &len, inSz) < 0)
32268
            return ASN_PARSE_E;
32269
    }
32270
    else {
32271
        if (GetOctetString(input, inOutIdx, &len, inSz) < 0)
32272
            return ASN_PARSE_E;
32273
    }
32274
32275
    str = (char*)XMALLOC((size_t)len * 2 + 1, heap, heapType);
32276
    if (str == NULL) {
32277
        return MEMORY_E;
32278
    }
32279
32280
    for (i=0; i<len; i++)
32281
        ByteToHexStr(input[*inOutIdx + (word32)i], str + i*2);
32282
    str[len*2] = '\0';
32283
32284
    *inOutIdx += (word32)len;
32285
    *out = str;
32286
32287
    (void)heap;
32288
    (void)heapType;
32289
32290
    return 0;
32291
}
32292
32293
static int EccKeyParamCopy(char** dst, char* src)
32294
{
32295
    int ret = 0;
32296
#ifdef WOLFSSL_ECC_CURVE_STATIC
32297
    word32 length;
32298
#endif
32299
32300
    if (dst == NULL || src == NULL)
32301
        return BAD_FUNC_ARG;
32302
32303
#ifndef WOLFSSL_ECC_CURVE_STATIC
32304
    *dst = src;
32305
#else
32306
    length = (int)XSTRLEN(src) + 1;
32307
    if (length > MAX_ECC_STRING) {
32308
        WOLFSSL_MSG("ECC Param too large for buffer");
32309
        ret = BUFFER_E;
32310
    }
32311
    else {
32312
        XSTRNCPY(*dst, src, MAX_ECC_STRING);
32313
    }
32314
    XFREE(src, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
32315
#endif
32316
32317
    return ret;
32318
}
32319
#endif /* !WOLFSSL_ASN_TEMPLATE */
32320
#endif /* WOLFSSL_CUSTOM_CURVES */
32321
32322
WOLFSSL_ABI
32323
int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx,
32324
                          ecc_key* key, word32 inSz)
32325
0
{
32326
#ifndef WOLFSSL_ASN_TEMPLATE
32327
    int    ret;
32328
    int    version, length;
32329
    int    curve_id = ECC_CURVE_DEF;
32330
    word32 oidSum, localIdx;
32331
    byte   tag, isPrivFormat = 0;
32332
32333
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
32334
        return BAD_FUNC_ARG;
32335
32336
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
32337
        return ASN_PARSE_E;
32338
32339
    /* Check if ECC private key is being used and skip private portion */
32340
    if (GetMyVersion(input, inOutIdx, &version, inSz) >= 0) {
32341
        isPrivFormat = 1;
32342
32343
        /* Type private key */
32344
        if (*inOutIdx >= inSz)
32345
            return ASN_PARSE_E;
32346
        tag = input[*inOutIdx];
32347
        *inOutIdx += 1;
32348
        if (tag != 4 && tag != 6 && tag != 7)
32349
            return ASN_PARSE_E;
32350
32351
        /* Skip Private Key */
32352
        if (GetLength(input, inOutIdx, &length, inSz) < 0)
32353
            return ASN_PARSE_E;
32354
        if (length > ECC_MAXSIZE)
32355
            return BUFFER_E;
32356
        *inOutIdx += (word32)length;
32357
32358
        /* Private Curve Header */
32359
        if (*inOutIdx >= inSz)
32360
            return ASN_PARSE_E;
32361
        tag = input[*inOutIdx];
32362
        *inOutIdx += 1;
32363
        if (tag != ECC_PREFIX_0)
32364
            return ASN_ECC_KEY_E;
32365
        if (GetLength(input, inOutIdx, &length, inSz) <= 0)
32366
            return ASN_PARSE_E;
32367
    }
32368
    /* Standard ECC public key */
32369
    else {
32370
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
32371
            return ASN_PARSE_E;
32372
32373
        ret = SkipObjectId(input, inOutIdx, inSz);
32374
        if (ret != 0)
32375
            return ret;
32376
    }
32377
32378
    if (*inOutIdx >= inSz) {
32379
        return BUFFER_E;
32380
    }
32381
32382
    localIdx = *inOutIdx;
32383
    if (GetASNTag(input, &localIdx, &tag, inSz) == 0 &&
32384
            tag == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
32385
#ifdef WOLFSSL_CUSTOM_CURVES
32386
        ecc_set_type* curve;
32387
        int len;
32388
        char* point = NULL;
32389
32390
        ret = 0;
32391
32392
        curve = (ecc_set_type*)XMALLOC(sizeof(*curve), key->heap,
32393
                                                       DYNAMIC_TYPE_ECC_BUFFER);
32394
        if (curve == NULL)
32395
            ret = MEMORY_E;
32396
32397
        if (ret == 0) {
32398
            static const char customName[] = "Custom";
32399
            XMEMSET(curve, 0, sizeof(*curve));
32400
        #ifndef WOLFSSL_ECC_CURVE_STATIC
32401
            curve->name = customName;
32402
        #else
32403
            XMEMCPY((void*)curve->name, customName, sizeof(customName));
32404
        #endif
32405
            curve->id = ECC_CURVE_CUSTOM;
32406
32407
            if (GetSequence(input, inOutIdx, &length, inSz) < 0)
32408
                ret = ASN_PARSE_E;
32409
        }
32410
32411
        if (ret == 0) {
32412
            GetInteger7Bit(input, inOutIdx, inSz);
32413
            if (GetSequence(input, inOutIdx, &length, inSz) < 0)
32414
                ret = ASN_PARSE_E;
32415
        }
32416
        if (ret == 0) {
32417
            char* p = NULL;
32418
            SkipObjectId(input, inOutIdx, inSz);
32419
            ret = ASNToHexString(input, inOutIdx, &p, inSz,
32420
                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
32421
            if (ret == 0) {
32422
#ifndef WOLFSSL_ECC_CURVE_STATIC
32423
                ret = EccKeyParamCopy((char**)&curve->prime, p);
32424
#else
32425
                const char *_tmp_ptr = &curve->prime[0];
32426
                ret = EccKeyParamCopy((char**)&_tmp_ptr, p);
32427
#endif
32428
            }
32429
        }
32430
        if (ret == 0) {
32431
            curve->size = (int)XSTRLEN(curve->prime) / 2;
32432
32433
            if (GetSequence(input, inOutIdx, &length, inSz) < 0)
32434
                ret = ASN_PARSE_E;
32435
        }
32436
        if (ret == 0) {
32437
            char* af = NULL;
32438
            ret = ASNToHexString(input, inOutIdx, &af, inSz,
32439
                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
32440
            if (ret == 0) {
32441
#ifndef WOLFSSL_ECC_CURVE_STATIC
32442
                ret = EccKeyParamCopy((char**)&curve->Af, af);
32443
#else
32444
                const char *_tmp_ptr = &curve->Af[0];
32445
                ret = EccKeyParamCopy((char**)&_tmp_ptr, af);
32446
#endif
32447
            }
32448
        }
32449
        if (ret == 0) {
32450
            char* bf = NULL;
32451
            ret = ASNToHexString(input, inOutIdx, &bf, inSz,
32452
                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
32453
            if (ret == 0) {
32454
#ifndef WOLFSSL_ECC_CURVE_STATIC
32455
                ret = EccKeyParamCopy((char**)&curve->Bf, bf);
32456
#else
32457
                const char *_tmp_ptr = &curve->Bf[0];
32458
                ret = EccKeyParamCopy((char**)&_tmp_ptr, bf);
32459
#endif
32460
            }
32461
        }
32462
        if (ret == 0) {
32463
            localIdx = *inOutIdx;
32464
            if (*inOutIdx < inSz && GetASNTag(input, &localIdx, &tag, inSz)
32465
                    == 0 && tag == ASN_BIT_STRING) {
32466
                len = 0;
32467
                ret = GetASNHeader(input, ASN_BIT_STRING, inOutIdx, &len, inSz);
32468
                if (ret > 0)
32469
                    ret = 0; /* reset on success */
32470
                *inOutIdx += (word32)len;
32471
            }
32472
        }
32473
        if (ret == 0) {
32474
            ret = ASNToHexString(input, inOutIdx, (char**)&point, inSz,
32475
                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
32476
32477
            /* sanity check that point buffer is not smaller than the expected
32478
             * size to hold ( 0 4 || Gx || Gy )
32479
             * where Gx and Gy are each the size of curve->size * 2 */
32480
            if (ret == 0 && (int)XSTRLEN(point) < (curve->size * 4) + 2) {
32481
                XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
32482
                ret = BUFFER_E;
32483
            }
32484
        }
32485
        if (ret == 0) {
32486
        #ifndef WOLFSSL_ECC_CURVE_STATIC
32487
            curve->Gx = (const char*)XMALLOC((size_t)curve->size * 2 + 2,
32488
                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
32489
            curve->Gy = (const char*)XMALLOC((size_t)curve->size * 2 + 2,
32490
                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
32491
            if (curve->Gx == NULL || curve->Gy == NULL) {
32492
                XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
32493
                ret = MEMORY_E;
32494
            }
32495
        #else
32496
            if (curve->size * 2 + 2 > MAX_ECC_STRING) {
32497
                WOLFSSL_MSG("curve size is too large to fit in buffer");
32498
                ret = BUFFER_E;
32499
            }
32500
        #endif
32501
        }
32502
        if (ret == 0) {
32503
            char* o = NULL;
32504
32505
            XMEMCPY((char*)curve->Gx, point + 2, (size_t)curve->size * 2);
32506
            XMEMCPY((char*)curve->Gy, point + curve->size * 2 + 2,
32507
                                                 (size_t)curve->size * 2);
32508
            ((char*)curve->Gx)[curve->size * 2] = '\0';
32509
            ((char*)curve->Gy)[curve->size * 2] = '\0';
32510
            XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
32511
            ret = ASNToHexString(input, inOutIdx, &o, inSz,
32512
                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
32513
            if (ret == 0) {
32514
#ifndef WOLFSSL_ECC_CURVE_STATIC
32515
                ret = EccKeyParamCopy((char**)&curve->order, o);
32516
#else
32517
                const char *_tmp_ptr = &curve->order[0];
32518
                ret = EccKeyParamCopy((char**)&_tmp_ptr, o);
32519
#endif
32520
            }
32521
        }
32522
        if (ret == 0) {
32523
            curve->cofactor = GetInteger7Bit(input, inOutIdx, inSz);
32524
32525
        #ifndef WOLFSSL_ECC_CURVE_STATIC
32526
            curve->oid = NULL;
32527
        #else
32528
            XMEMSET((void*)curve->oid, 0, sizeof(curve->oid));
32529
        #endif
32530
            curve->oidSz = 0;
32531
            curve->oidSum = 0;
32532
32533
            if (wc_ecc_set_custom_curve(key, curve) < 0) {
32534
                ret = ASN_PARSE_E;
32535
            }
32536
32537
            key->deallocSet = 1;
32538
32539
            curve = NULL;
32540
        }
32541
        if (curve != NULL)
32542
            wc_ecc_free_curve(curve, key->heap);
32543
32544
        if (ret < 0)
32545
            return ret;
32546
#else
32547
        return ASN_PARSE_E;
32548
#endif /* WOLFSSL_CUSTOM_CURVES */
32549
    }
32550
    else {
32551
        /* ecc params information */
32552
        ret = GetObjectId(input, inOutIdx, &oidSum, oidIgnoreType, inSz);
32553
        if (ret != 0)
32554
            return ret;
32555
32556
        /* get curve id */
32557
        if ((ret = CheckCurve(oidSum)) < 0)
32558
            return ECC_CURVE_OID_E;
32559
        else {
32560
            curve_id = ret;
32561
        }
32562
    }
32563
32564
    if (isPrivFormat) {
32565
        /* Public Curve Header - skip */
32566
        if (*inOutIdx >= inSz)
32567
            return ASN_PARSE_E;
32568
        tag = input[*inOutIdx];
32569
        *inOutIdx += 1;
32570
        if (tag != ECC_PREFIX_1)
32571
            return ASN_ECC_KEY_E;
32572
        if (GetLength(input, inOutIdx, &length, inSz) <= 0)
32573
            return ASN_PARSE_E;
32574
    }
32575
32576
    /* key header */
32577
    ret = CheckBitString(input, inOutIdx, &length, inSz, 1, NULL);
32578
    if (ret != 0)
32579
        return ret;
32580
32581
    /* This is the raw point data compressed or uncompressed. */
32582
    if (wc_ecc_import_x963_ex(input + *inOutIdx, (word32)length, key,
32583
                                                            curve_id) != 0) {
32584
        return ASN_ECC_KEY_E;
32585
    }
32586
32587
    *inOutIdx += (word32)length;
32588
32589
    return 0;
32590
#else
32591
    /* eccKeyASN is longer than eccPublicKeyASN. */
32592
0
    DECL_ASNGETDATA(dataASN, eccKeyASN_Length);
32593
0
    int ret = 0;
32594
0
    int curve_id = ECC_CURVE_DEF;
32595
0
    int oidIdx = ECCPUBLICKEYASN_IDX_ALGOID_CURVEID;
32596
0
#ifdef WOLFSSL_CUSTOM_CURVES
32597
0
    int specIdx = ECCPUBLICKEYASN_IDX_ALGOID_PARAMS;
32598
0
#endif
32599
0
    int pubIdx = ECCPUBLICKEYASN_IDX_PUBKEY;
32600
32601
0
    if ((input == NULL) || (inOutIdx == NULL) || (key == NULL) || (inSz == 0)) {
32602
0
        ret = BAD_FUNC_ARG;
32603
0
    }
32604
32605
0
    ALLOC_ASNGETDATA(dataASN, eccKeyASN_Length, ret, key->heap);
32606
32607
0
    if (ret == 0) {
32608
        /* Clear dynamic data for ECC public key. */
32609
0
        XMEMSET(dataASN, 0, sizeof(*dataASN) * eccPublicKeyASN_Length);
32610
#if !defined(WOLFSSL_SM2) || !defined(WOLFSSL_SM3)
32611
        /* Set required ECDSA OID and ignore the curve OID type. */
32612
        GetASN_ExpBuffer(&dataASN[ECCPUBLICKEYASN_IDX_ALGOID_OID], keyEcdsaOid,
32613
                sizeof(keyEcdsaOid));
32614
#else
32615
0
        GetASN_OID(&dataASN[ECCPUBLICKEYASN_IDX_ALGOID_OID], oidKeyType);
32616
0
#endif
32617
0
        GetASN_OID(&dataASN[oidIdx], oidCurveType);
32618
        /* Decode the public ECC key. */
32619
0
        ret = GetASN_Items(eccPublicKeyASN, dataASN, eccPublicKeyASN_Length, 1,
32620
0
                           input, inOutIdx, inSz);
32621
0
        if (ret != 0) {
32622
0
            oidIdx = ECCKEYASN_IDX_CURVEID;
32623
0
        #ifdef WOLFSSL_CUSTOM_CURVES
32624
0
            specIdx = ECCKEYASN_IDX_CURVEPARAMS;
32625
0
        #endif
32626
0
            pubIdx = ECCKEYASN_IDX_PUBKEY_VAL;
32627
32628
            /* Clear dynamic data for ECC private key. */
32629
0
            XMEMSET(dataASN, 0, sizeof(*dataASN) * eccKeyASN_Length);
32630
            /* Check named curve OID type. */
32631
0
            GetASN_OID(&dataASN[oidIdx], oidCurveType);
32632
            /* Try private key format .*/
32633
0
            ret = GetASN_Items(eccKeyASN, dataASN, eccKeyASN_Length, 1, input,
32634
0
                               inOutIdx, inSz);
32635
0
            if (ret != 0) {
32636
0
                ret = ASN_PARSE_E;
32637
0
            }
32638
0
        }
32639
0
    }
32640
32641
0
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
32642
0
    if ((ret == 0) && (oidIdx == ECCPUBLICKEYASN_IDX_ALGOID_CURVEID)) {
32643
0
        int oidSum = dataASN[ECCPUBLICKEYASN_IDX_ALGOID_OID].data.oid.sum;
32644
0
        if ((oidSum != ECDSAk) && (oidSum != SM2k)) {
32645
0
            ret = ASN_PARSE_E;
32646
0
        }
32647
0
    }
32648
0
#endif
32649
0
    if (ret == 0) {
32650
0
        if (dataASN[oidIdx].tag != 0) {
32651
            /* Named curve - check and get id. */
32652
0
            curve_id = CheckCurve(dataASN[oidIdx].data.oid.sum);
32653
0
            if (curve_id < 0) {
32654
0
                ret = ASN_OBJECT_ID_E;
32655
0
            }
32656
0
        }
32657
0
        else {
32658
0
        #ifdef WOLFSSL_CUSTOM_CURVES
32659
            /* Parse explicit parameters. */
32660
0
            ret = EccSpecifiedECDomainDecode(dataASN[specIdx].data.ref.data,
32661
0
                                         dataASN[specIdx].data.ref.length, key);
32662
        #else
32663
            /* Explicit parameters not supported in build configuration. */
32664
            ret = ASN_PARSE_E;
32665
        #endif
32666
0
        }
32667
0
    }
32668
0
    if (ret == 0) {
32669
        /* Import public point. */
32670
0
        ret = wc_ecc_import_x963_ex(dataASN[pubIdx].data.ref.data,
32671
0
                dataASN[pubIdx].data.ref.length, key, curve_id);
32672
0
        if (ret != 0) {
32673
0
            ret = ASN_ECC_KEY_E;
32674
0
        }
32675
0
    }
32676
32677
0
    FREE_ASNGETDATA(dataASN, key->heap);
32678
0
    return ret;
32679
0
#endif /* WOLFSSL_ASN_TEMPLATE */
32680
0
}
32681
32682
#if defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT)
32683
/* build DER formatted ECC key, include optional public key if requested,
32684
 * return length on success, negative on error */
32685
int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 *inLen,
32686
                             int pubIn, int curveIn)
32687
0
{
32688
#ifndef WOLFSSL_ASN_TEMPLATE
32689
    byte   curve[MAX_ALGO_SZ+2];
32690
    byte   ver[MAX_VERSION_SZ];
32691
    byte   seq[MAX_SEQ_SZ];
32692
    int    ret, curveSz, verSz;
32693
    word32 totalSz;
32694
    int    privHdrSz  = ASN_ECC_HEADER_SZ;
32695
    int    pubHdrSz   = ASN_ECC_CONTEXT_SZ + ASN_ECC_HEADER_SZ;
32696
#ifdef WOLFSSL_NO_MALLOC
32697
    byte   prv[MAX_ECC_BYTES + ASN_ECC_HEADER_SZ + MAX_SEQ_SZ];
32698
    byte   pub[(MAX_ECC_BYTES * 2) + 1 + ASN_ECC_CONTEXT_SZ +
32699
                              ASN_ECC_HEADER_SZ + MAX_SEQ_SZ];
32700
#else
32701
    byte   *prv = NULL, *pub = NULL;
32702
#endif
32703
32704
    word32 idx = 0, prvidx = 0, pubidx = 0, curveidx = 0;
32705
    word32 seqSz, privSz, pubSz = ECC_BUFSIZE;
32706
32707
    if (key == NULL || (output == NULL && inLen == NULL))
32708
        return BAD_FUNC_ARG;
32709
32710
    if (curveIn) {
32711
        /* curve */
32712
        curve[curveidx++] = ECC_PREFIX_0;
32713
        curveidx++ /* to put the size after computation */;
32714
        curveSz = SetCurve(key, curve+curveidx, MAX_ALGO_SZ);
32715
        if (curveSz < 0)
32716
            return curveSz;
32717
        /* set computed size */
32718
        curve[1] = (byte)curveSz;
32719
        curveidx += (word32)curveSz;
32720
    }
32721
32722
    /* private */
32723
    privSz = (word32)key->dp->size;
32724
32725
#ifdef WOLFSSL_QNX_CAAM
32726
    /* check if is a black key, and add MAC size if needed */
32727
    if (key->blackKey > 0 && key->blackKey != CAAM_BLACK_KEY_ECB) {
32728
        privSz = privSz + WC_CAAM_MAC_SZ;
32729
    }
32730
#endif
32731
32732
#ifndef WOLFSSL_NO_MALLOC
32733
    prv = (byte*)XMALLOC(privSz + (word32)privHdrSz + MAX_SEQ_SZ,
32734
                         key->heap, DYNAMIC_TYPE_TMP_BUFFER);
32735
    if (prv == NULL) {
32736
        return MEMORY_E;
32737
    }
32738
#else
32739
    if (sizeof(prv) < privSz + privHdrSz + MAX_SEQ_SZ) {
32740
        return BUFFER_E;
32741
    }
32742
#endif
32743
    if (privSz < ASN_LONG_LENGTH) {
32744
        prvidx += SetOctetString8Bit(privSz, &prv[prvidx]);
32745
    }
32746
    else {
32747
        prvidx += SetOctetString(privSz, &prv[prvidx]);
32748
    }
32749
    ret = wc_ecc_export_private_only(key, prv + prvidx, &privSz);
32750
    if (ret < 0) {
32751
    #ifndef WOLFSSL_NO_MALLOC
32752
        XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
32753
    #endif
32754
        return ret;
32755
    }
32756
    prvidx += privSz;
32757
32758
    /* pubIn */
32759
    if (pubIn) {
32760
        PRIVATE_KEY_UNLOCK();
32761
        ret = wc_ecc_export_x963(key, NULL, &pubSz);
32762
        PRIVATE_KEY_LOCK();
32763
        if (ret != LENGTH_ONLY_E) {
32764
        #ifndef WOLFSSL_NO_MALLOC
32765
            XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
32766
        #endif
32767
            return ret;
32768
        }
32769
32770
    #ifndef WOLFSSL_NO_MALLOC
32771
        pub = (byte*)XMALLOC(pubSz + (word32)pubHdrSz + MAX_SEQ_SZ,
32772
                             key->heap, DYNAMIC_TYPE_TMP_BUFFER);
32773
        if (pub == NULL) {
32774
            XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
32775
            return MEMORY_E;
32776
        }
32777
    #else
32778
        if (sizeof(pub) < pubSz + pubHdrSz + MAX_SEQ_SZ) {
32779
            return BUFFER_E;
32780
        }
32781
    #endif
32782
32783
        pub[pubidx++] = ECC_PREFIX_1;
32784
        if (pubSz > 128) /* leading zero + extra size byte */
32785
            pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 2, pub+pubidx);
32786
        else /* leading zero */
32787
            pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 1, pub+pubidx);
32788
32789
        /* SetBitString adds leading zero */
32790
        pubidx += SetBitString(pubSz, 0, pub + pubidx);
32791
        PRIVATE_KEY_UNLOCK();
32792
        ret = wc_ecc_export_x963(key, pub + pubidx, &pubSz);
32793
        PRIVATE_KEY_LOCK();
32794
        if (ret != 0) {
32795
        #ifndef WOLFSSL_NO_MALLOC
32796
            XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
32797
            XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
32798
        #endif
32799
            return ret;
32800
        }
32801
        pubidx += pubSz;
32802
    }
32803
32804
    /* make headers */
32805
    verSz = SetMyVersion(1, ver, FALSE);
32806
    seqSz = SetSequence((word32)verSz + prvidx + pubidx + curveidx, seq);
32807
32808
    totalSz = prvidx + pubidx + curveidx + (word32)verSz + seqSz;
32809
    if (output == NULL) {
32810
        *inLen = totalSz;
32811
    #ifndef WOLFSSL_NO_MALLOC
32812
        XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
32813
        if (pubIn) {
32814
            XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
32815
        }
32816
    #endif
32817
        return LENGTH_ONLY_E;
32818
    }
32819
    if (inLen != NULL && totalSz > *inLen) {
32820
        #ifndef WOLFSSL_NO_MALLOC
32821
        XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
32822
        if (pubIn) {
32823
            XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
32824
        }
32825
        #endif
32826
        return BAD_FUNC_ARG;
32827
    }
32828
32829
    /* write out */
32830
    /* seq */
32831
    XMEMCPY(output + idx, seq, seqSz);
32832
    idx = seqSz;
32833
32834
    /* ver */
32835
    XMEMCPY(output + idx, ver, (size_t)verSz);
32836
    idx += (word32)verSz;
32837
32838
    /* private */
32839
    XMEMCPY(output + idx, prv, prvidx);
32840
    idx += prvidx;
32841
#ifndef WOLFSSL_NO_MALLOC
32842
    XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
32843
#endif
32844
32845
    /* curve */
32846
    XMEMCPY(output + idx, curve, curveidx);
32847
    idx += curveidx;
32848
32849
    /* pubIn */
32850
    if (pubIn) {
32851
        XMEMCPY(output + idx, pub, pubidx);
32852
        /* idx += pubidx;  not used after write, if more data remove comment */
32853
    #ifndef WOLFSSL_NO_MALLOC
32854
        XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
32855
    #endif
32856
    }
32857
32858
    return (int)totalSz;
32859
#else
32860
0
    DECL_ASNSETDATA(dataASN, eccKeyASN_Length);
32861
0
    word32 privSz, pubSz;
32862
0
    int sz = 0;
32863
0
    int ret = 0;
32864
0
    int curveIdSz = 0;
32865
32866
    /* Check validity of parameters. */
32867
0
    if ((key == NULL) || ((output == NULL) && (inLen == NULL))) {
32868
0
        ret = BAD_FUNC_ARG;
32869
0
    }
32870
32871
    /* Check key has parameters when encoding curve. */
32872
0
    if ((ret == 0) && curveIn && (key->dp == NULL)) {
32873
0
        ret = BAD_FUNC_ARG;
32874
0
    }
32875
32876
0
    CALLOC_ASNSETDATA(dataASN, eccKeyASN_Length, ret, key->heap);
32877
32878
0
    if (ret == 0) {
32879
        /* Private key size is the curve size. */
32880
0
        privSz = (word32)key->dp->size;
32881
0
        if (pubIn) {
32882
            /* Get the length of the public key. */
32883
0
            PRIVATE_KEY_UNLOCK();
32884
0
            ret = wc_ecc_export_x963(key, NULL, &pubSz);
32885
0
            PRIVATE_KEY_LOCK();
32886
0
            if (ret == LENGTH_ONLY_E)
32887
0
                ret = 0;
32888
0
        }
32889
0
    }
32890
0
    if (ret == 0) {
32891
        /* Version: 1 */
32892
0
        SetASN_Int8Bit(&dataASN[ECCKEYASN_IDX_VER], 1);
32893
        /* Leave space for private key. */
32894
0
        SetASN_Buffer(&dataASN[ECCKEYASN_IDX_PKEY], NULL, privSz);
32895
0
        if (curveIn) {
32896
            /* Get length of the named curve OID to put into the encoding. */
32897
0
            curveIdSz = SetCurve(key, NULL, 0);
32898
0
            if (curveIdSz < 0) {
32899
0
                ret = curveIdSz;
32900
0
            }
32901
            /* Curve OID */
32902
0
            SetASN_ReplaceBuffer(&dataASN[ECCKEYASN_IDX_CURVEID], NULL,
32903
0
                (word32)curveIdSz);
32904
            /* TODO: add support for SpecifiedECDomain curve. */
32905
0
            dataASN[ECCKEYASN_IDX_CURVEPARAMS].noOut = 1;
32906
0
        }
32907
0
        else {
32908
0
            SetASNItem_NoOutNode(dataASN, eccKeyASN, ECCKEYASN_IDX_PARAMS,
32909
0
                    eccKeyASN_Length);
32910
0
        }
32911
0
        if (ret == 0) {
32912
0
            if (pubIn) {
32913
                /* Leave space for public key. */
32914
0
                SetASN_Buffer(&dataASN[ECCKEYASN_IDX_PUBKEY_VAL], NULL, pubSz);
32915
0
            }
32916
0
            else {
32917
                /* Don't write out public key. */
32918
0
                SetASNItem_NoOutNode(dataASN, eccKeyASN, ECCKEYASN_IDX_PUBKEY,
32919
0
                                     eccKeyASN_Length);
32920
0
            }
32921
            /* Calculate size of the private key encoding. */
32922
0
            ret = SizeASN_Items(eccKeyASN, dataASN, eccKeyASN_Length, &sz);
32923
0
        }
32924
0
    }
32925
    /* Return the size if no buffer. */
32926
0
    if ((ret == 0) && (output == NULL)) {
32927
0
        *inLen = (word32)sz;
32928
0
        ret = LENGTH_ONLY_E;
32929
0
    }
32930
    /* Check the buffer is big enough. */
32931
0
    if ((ret == 0) && (inLen != NULL) && (sz > (int)*inLen)) {
32932
0
        ret = BAD_FUNC_ARG;
32933
0
    }
32934
0
    if ((ret == 0) && (output != NULL)) {
32935
        /* Encode the private key. */
32936
0
        SetASN_Items(eccKeyASN, dataASN, eccKeyASN_Length, output);
32937
32938
0
        if (curveIn) {
32939
            /* Put named curve OID data into encoding. */
32940
0
            curveIdSz = SetCurve(key,
32941
0
                (byte*)dataASN[ECCKEYASN_IDX_CURVEID].data.buffer.data,
32942
0
                (size_t)curveIdSz);
32943
0
            if (curveIdSz < 0) {
32944
0
                ret = curveIdSz;
32945
0
            }
32946
0
        }
32947
0
        if (ret == 0) {
32948
            /* Export the private value into the buffer. */
32949
0
            ret = wc_ecc_export_private_only(key,
32950
0
                (byte*)dataASN[ECCKEYASN_IDX_PKEY].data.buffer.data, &privSz);
32951
0
        }
32952
0
        if ((ret == 0) && pubIn) {
32953
            /* Export the public point into the buffer. */
32954
0
            PRIVATE_KEY_UNLOCK();
32955
0
            ret = wc_ecc_export_x963(key,
32956
0
                    (byte*)dataASN[ECCKEYASN_IDX_PUBKEY_VAL].data.buffer.data,
32957
0
                    &pubSz);
32958
0
            PRIVATE_KEY_LOCK();
32959
0
        }
32960
0
    }
32961
0
    if (ret == 0) {
32962
        /* Return the encoding size. */
32963
0
        ret = sz;
32964
0
    }
32965
32966
0
    FREE_ASNSETDATA(dataASN, key->heap);
32967
0
    return ret;
32968
0
#endif
32969
0
}
32970
32971
/* Write a Private ecc key, including public to DER format,
32972
 * length on success else < 0 */
32973
WOLFSSL_ABI
32974
int wc_EccKeyToDer(ecc_key* key, byte* output, word32 inLen)
32975
0
{
32976
0
    return wc_BuildEccKeyDer(key, output, &inLen, 1, 1);
32977
0
}
32978
32979
/* Write only private ecc key to DER format,
32980
 * length on success else < 0 */
32981
int wc_EccKeyDerSize(ecc_key* key, int pub)
32982
0
{
32983
0
    word32 sz = 0;
32984
0
    int ret;
32985
32986
0
    ret = wc_BuildEccKeyDer(key, NULL, &sz, pub, 1);
32987
32988
0
    if (ret != LENGTH_ONLY_E) {
32989
0
        return ret;
32990
0
    }
32991
0
    return (int)sz;
32992
0
 }
32993
32994
/* Write only private ecc key to DER format,
32995
 * length on success else < 0 */
32996
int wc_EccPrivateKeyToDer(ecc_key* key, byte* output, word32 inLen)
32997
0
{
32998
0
    return wc_BuildEccKeyDer(key, output, &inLen, 0, 1);
32999
0
}
33000
33001
#ifdef HAVE_PKCS8
33002
33003
/* Write only private ecc key or both private and public parts to unencrypted
33004
 * PKCS#8 format.
33005
 *
33006
 * If output is NULL, places required PKCS#8 buffer size in outLen and
33007
 * returns LENGTH_ONLY_E.
33008
 *
33009
 * return length on success else < 0 */
33010
static int eccToPKCS8(ecc_key* key, byte* output, word32* outLen,
33011
        int includePublic)
33012
0
{
33013
0
    int ret;
33014
0
    word32 tmpDerSz;
33015
0
    int algoID = 0;
33016
0
    word32 oidSz = 0;
33017
0
    word32 pkcs8Sz = 0;
33018
0
    const byte* curveOID = NULL;
33019
#ifdef WOLFSSL_NO_MALLOC
33020
    byte  tmpDer[ECC_BUFSIZE];
33021
#else
33022
0
    byte* tmpDer = NULL;
33023
0
#endif
33024
0
    word32 sz = ECC_BUFSIZE;
33025
33026
0
    if (key == NULL || key->dp == NULL || outLen == NULL)
33027
0
        return BAD_FUNC_ARG;
33028
33029
    /* set algoID, get curve OID */
33030
0
    algoID = ECDSAk;
33031
0
    ret = wc_ecc_get_oid(key->dp->oidSum, &curveOID, &oidSz);
33032
0
    if (ret < 0)
33033
0
        return ret;
33034
33035
0
#ifndef WOLFSSL_NO_MALLOC
33036
    /* temp buffer for plain DER key */
33037
0
    tmpDer = (byte*)XMALLOC(ECC_BUFSIZE, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
33038
0
    if (tmpDer == NULL)
33039
0
        return MEMORY_E;
33040
0
#endif
33041
0
    XMEMSET(tmpDer, 0, ECC_BUFSIZE);
33042
33043
0
    ret = wc_BuildEccKeyDer(key, tmpDer, &sz, includePublic, 0);
33044
0
    if (ret < 0) {
33045
0
    #ifndef WOLFSSL_NO_MALLOC
33046
0
        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
33047
0
    #endif
33048
0
        return ret;
33049
0
    }
33050
0
    tmpDerSz = (word32)ret;
33051
33052
    /* get pkcs8 expected output size */
33053
0
    ret = wc_CreatePKCS8Key(NULL, &pkcs8Sz, tmpDer, tmpDerSz, algoID,
33054
0
                            curveOID, oidSz);
33055
0
    if (ret != LENGTH_ONLY_E) {
33056
0
    #ifndef WOLFSSL_NO_MALLOC
33057
0
        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
33058
0
    #endif
33059
0
        return ret;
33060
0
    }
33061
33062
0
    if (output == NULL) {
33063
0
    #ifndef WOLFSSL_NO_MALLOC
33064
0
        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
33065
0
    #endif
33066
0
        *outLen = pkcs8Sz;
33067
0
        return LENGTH_ONLY_E;
33068
33069
0
    }
33070
0
    else if (*outLen < pkcs8Sz) {
33071
0
    #ifndef WOLFSSL_NO_MALLOC
33072
0
        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
33073
0
    #endif
33074
0
        WOLFSSL_MSG("Input buffer too small for ECC PKCS#8 key");
33075
0
        return BUFFER_E;
33076
0
    }
33077
33078
0
    ret = wc_CreatePKCS8Key(output, &pkcs8Sz, tmpDer, tmpDerSz,
33079
0
                            algoID, curveOID, oidSz);
33080
0
    if (ret < 0) {
33081
0
    #ifndef WOLFSSL_NO_MALLOC
33082
0
        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
33083
0
    #endif
33084
0
        return ret;
33085
0
    }
33086
33087
0
#ifndef WOLFSSL_NO_MALLOC
33088
0
    XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
33089
0
#endif
33090
33091
0
    *outLen = (word32)ret;
33092
0
    return ret;
33093
0
}
33094
33095
/* Write only private ecc key to unencrypted PKCS#8 format.
33096
 *
33097
 * return length on success else < 0 */
33098
int wc_EccPrivateKeyToPKCS8(ecc_key* key, byte* output, word32* outLen)
33099
0
{
33100
0
    return eccToPKCS8(key, output, outLen, 0);
33101
0
}
33102
33103
/* Write both private and public ecc keys to unencrypted PKCS#8 format.
33104
 *
33105
 * return length on success else < 0 */
33106
int wc_EccKeyToPKCS8(ecc_key* key, byte* output,
33107
                     word32* outLen)
33108
0
{
33109
0
    return eccToPKCS8(key, output, outLen, 1);
33110
0
}
33111
#endif /* HAVE_PKCS8 */
33112
#endif /* HAVE_ECC_KEY_EXPORT && !NO_ASN_CRYPT */
33113
#endif /* HAVE_ECC */
33114
33115
#ifdef WC_ENABLE_ASYM_KEY_IMPORT
33116
#ifdef WOLFSSL_ASN_TEMPLATE
33117
/* ASN.1 template for Ed25519 and Ed448 private key.
33118
 * RFC 8410, 7 - Private Key Format (but public value is EXPLICIT OCTET_STRING)
33119
 */
33120
static const ASNItem edKeyASN[] = {
33121
/* SEQ            */    { 0, ASN_SEQUENCE, 1, 1, 0 },
33122
                                         /* Version */
33123
/* VER            */        { 1, ASN_INTEGER, 0, 0, 0 },
33124
                                         /* privateKeyAlgorithm */
33125
/* PKEYALGO_SEQ   */        { 1, ASN_SEQUENCE, 1, 1, 0 },
33126
/* PKEYALGO_OID   */            { 2, ASN_OBJECT_ID, 0, 0, 1 },
33127
                                         /* privateKey */
33128
/* PKEY           */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
33129
                                             /* CurvePrivateKey */
33130
/* PKEY_CURVEPKEY */            { 2, ASN_OCTET_STRING, 0, 0, 0 },
33131
                                         /* attributes */
33132
/* ATTRS          */        { 1, ASN_CONTEXT_SPECIFIC | ASN_ASYMKEY_ATTRS, 1, 1, 1 },
33133
                                         /* publicKey */
33134
/* PUBKEY         */        { 1, ASN_CONTEXT_SPECIFIC | ASN_ASYMKEY_PUBKEY, 0, 0, 1 },
33135
};
33136
enum {
33137
    EDKEYASN_IDX_SEQ = 0,
33138
    EDKEYASN_IDX_VER,
33139
    EDKEYASN_IDX_PKEYALGO_SEQ,
33140
    EDKEYASN_IDX_PKEYALGO_OID,
33141
    EDKEYASN_IDX_PKEY,
33142
    EDKEYASN_IDX_PKEY_CURVEPKEY,
33143
    EDKEYASN_IDX_ATTRS,
33144
    EDKEYASN_IDX_PUBKEY
33145
};
33146
33147
/* Number of items in ASN.1 template for Ed25519 and Ed448 private key. */
33148
0
#define edKeyASN_Length (sizeof(edKeyASN) / sizeof(ASNItem))
33149
#endif
33150
33151
#if ((defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)) \
33152
    || (defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_KEY_IMPORT)) \
33153
    || (defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)) \
33154
    || (defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_IMPORT)) \
33155
    || (defined(HAVE_PQC) && defined(HAVE_FALCON)) \
33156
    || (defined(HAVE_PQC) && defined(HAVE_DILITHIUM)) \
33157
    || (defined(HAVE_PQC) && defined(HAVE_SPHINCS)))
33158
33159
int DecodeAsymKey(const byte* input, word32* inOutIdx, word32 inSz,
33160
    byte* privKey, word32* privKeyLen,
33161
    byte* pubKey, word32* pubKeyLen, int keyType)
33162
0
{
33163
#ifndef WOLFSSL_ASN_TEMPLATE
33164
    word32 oid;
33165
    int version, length, endKeyIdx, privSz, pubSz;
33166
    const byte* priv;
33167
    const byte* pub;
33168
#else
33169
0
    int ret = 0;
33170
0
    DECL_ASNGETDATA(dataASN, edKeyASN_Length);
33171
0
    CALLOC_ASNGETDATA(dataASN, edKeyASN_Length, ret, NULL);
33172
0
#endif
33173
33174
0
    if (input == NULL || inOutIdx == NULL || inSz == 0 ||
33175
0
        privKey == NULL || privKeyLen == NULL) {
33176
0
        return BAD_FUNC_ARG;
33177
0
    }
33178
33179
#ifndef WOLFSSL_ASN_TEMPLATE
33180
    if (GetSequence(input, inOutIdx, &length, inSz) >= 0) {
33181
        endKeyIdx = (int)*inOutIdx + length;
33182
33183
        if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
33184
            return ASN_PARSE_E;
33185
        if (version != 0) {
33186
            WOLFSSL_MSG("Unrecognized version of ED25519 private key");
33187
            return ASN_PARSE_E;
33188
        }
33189
33190
        if (GetAlgoId(input, inOutIdx, &oid, oidKeyType, inSz) < 0)
33191
            return ASN_PARSE_E;
33192
        if (oid != (word32)keyType)
33193
            return ASN_PARSE_E;
33194
33195
        if (GetOctetString(input, inOutIdx, &length, inSz) < 0)
33196
            return ASN_PARSE_E;
33197
33198
        if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0)
33199
            return ASN_PARSE_E;
33200
33201
        priv = input + *inOutIdx;
33202
        *inOutIdx += (word32)privSz;
33203
    }
33204
    else {
33205
        if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0)
33206
            return ASN_PARSE_E;
33207
33208
        priv = input + *inOutIdx;
33209
        *inOutIdx += (word32)privSz;
33210
        endKeyIdx = (int)*inOutIdx;
33211
    }
33212
33213
    if ((word32)privSz > *privKeyLen)
33214
        return BUFFER_E;
33215
33216
    if (endKeyIdx == (int)*inOutIdx) {
33217
        *privKeyLen = (word32)privSz;
33218
        XMEMCPY(privKey, priv, *privKeyLen);
33219
        if (pubKeyLen != NULL)
33220
            *pubKeyLen = 0;
33221
    }
33222
    else {
33223
        if (pubKeyLen == NULL) {
33224
            return BAD_FUNC_ARG;
33225
        }
33226
33227
        if (GetASNHeader(input, ASN_CONTEXT_SPECIFIC | ASN_ASYMKEY_PUBKEY | 1,
33228
                         inOutIdx, &pubSz, inSz) < 0) {
33229
            return ASN_PARSE_E;
33230
        }
33231
33232
        if ((word32)pubSz > *pubKeyLen)
33233
            return BUFFER_E;
33234
33235
        pub = input + *inOutIdx;
33236
        *inOutIdx += (word32)pubSz;
33237
33238
        *privKeyLen = (word32)privSz;
33239
        XMEMCPY(privKey, priv, *privKeyLen);
33240
        *pubKeyLen = (word32)pubSz;
33241
        if (pubKey != NULL)
33242
            XMEMCPY(pubKey, pub, *pubKeyLen);
33243
    }
33244
    if (endKeyIdx != (int)*inOutIdx)
33245
        return ASN_PARSE_E;
33246
    return 0;
33247
#else
33248
0
    if (ret == 0) {
33249
        /* Require OID. */
33250
0
        word32 oidSz;
33251
0
        const byte* oid = OidFromId((word32)keyType, oidKeyType, &oidSz);
33252
0
        GetASN_ExpBuffer(&dataASN[EDKEYASN_IDX_PKEYALGO_OID], oid, oidSz);
33253
        /* Parse full private key. */
33254
0
        ret = GetASN_Items(edKeyASN, dataASN, edKeyASN_Length, 1, input,
33255
0
                inOutIdx, inSz);
33256
0
        if (ret != 0) {
33257
            /* Parse just the OCTET_STRING. */
33258
0
            ret = GetASN_Items(&edKeyASN[EDKEYASN_IDX_PKEY_CURVEPKEY],
33259
0
                    &dataASN[EDKEYASN_IDX_PKEY_CURVEPKEY], 1, 0, input,
33260
0
                    inOutIdx, inSz);
33261
0
            if (ret != 0) {
33262
0
                ret = ASN_PARSE_E;
33263
0
            }
33264
0
        }
33265
0
    }
33266
    /* Check the private value length is correct. */
33267
0
    if ((ret == 0) && dataASN[EDKEYASN_IDX_PKEY_CURVEPKEY].data.ref.length
33268
0
            > *privKeyLen) {
33269
0
        ret = ASN_PARSE_E;
33270
0
    }
33271
0
    if ((ret == 0) && dataASN[EDKEYASN_IDX_PUBKEY].tag == 0) {
33272
0
        *privKeyLen = dataASN[EDKEYASN_IDX_PKEY_CURVEPKEY].data.ref.length;
33273
0
        XMEMCPY(privKey, dataASN[EDKEYASN_IDX_PKEY_CURVEPKEY].data.ref.data,
33274
0
                *privKeyLen);
33275
0
        if (pubKeyLen != NULL)
33276
0
            *pubKeyLen = 0;
33277
0
    }
33278
0
    else if ((ret == 0) &&
33279
0
             (pubKeyLen != NULL) &&
33280
0
             (dataASN[EDKEYASN_IDX_PUBKEY].data.ref.length > *pubKeyLen)) {
33281
0
        ret = ASN_PARSE_E;
33282
0
    }
33283
0
    else if (ret == 0) {
33284
        /* Import private and public value. */
33285
0
        *privKeyLen = dataASN[EDKEYASN_IDX_PKEY_CURVEPKEY].data.ref.length;
33286
0
        XMEMCPY(privKey, dataASN[EDKEYASN_IDX_PKEY_CURVEPKEY].data.ref.data,
33287
0
                *privKeyLen);
33288
0
        if (pubKeyLen != NULL)
33289
0
            *pubKeyLen = dataASN[EDKEYASN_IDX_PUBKEY].data.ref.length;
33290
0
        if (pubKey != NULL && pubKeyLen != NULL)
33291
0
            XMEMCPY(pubKey, dataASN[EDKEYASN_IDX_PUBKEY].data.ref.data,
33292
0
                    *pubKeyLen);
33293
0
    }
33294
33295
0
    FREE_ASNGETDATA(dataASN, NULL);
33296
0
    return ret;
33297
0
#endif /* WOLFSSL_ASN_TEMPLATE */
33298
0
}
33299
33300
int DecodeAsymKeyPublic(const byte* input, word32* inOutIdx, word32 inSz,
33301
    byte* pubKey, word32* pubKeyLen, int keyType)
33302
0
{
33303
0
    int ret = 0;
33304
#ifndef WOLFSSL_ASN_TEMPLATE
33305
    int length;
33306
    word32 oid;
33307
#else
33308
0
    word32 len;
33309
0
    DECL_ASNGETDATA(dataASN, edPubKeyASN_Length);
33310
0
#endif
33311
33312
0
    if (input == NULL || inSz == 0 || inOutIdx == NULL ||
33313
0
        pubKey == NULL || pubKeyLen == NULL) {
33314
0
        return BAD_FUNC_ARG;
33315
0
    }
33316
33317
#ifndef WOLFSSL_ASN_TEMPLATE
33318
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
33319
        return ASN_PARSE_E;
33320
33321
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
33322
        return ASN_PARSE_E;
33323
33324
    if (GetObjectId(input, inOutIdx, &oid, oidKeyType, inSz) < 0)
33325
        return ASN_PARSE_E;
33326
    if (oid != (word32)keyType)
33327
        return ASN_PARSE_E;
33328
33329
    /* key header */
33330
    ret = CheckBitString(input, inOutIdx, &length, inSz, 1, NULL);
33331
    if (ret != 0)
33332
        return ret;
33333
33334
    /* check that the value found is not too large for pubKey buffer */
33335
    if ((word32)length > *pubKeyLen)
33336
        return ASN_PARSE_E;
33337
33338
    /* check that input buffer is exhausted */
33339
    if (*inOutIdx + (word32)length != inSz)
33340
        return ASN_PARSE_E;
33341
33342
    /* This is the raw point data compressed or uncompressed. */
33343
    *pubKeyLen = (word32)length;
33344
    XMEMCPY(pubKey, input + *inOutIdx, *pubKeyLen);
33345
#else
33346
0
    len = inSz - *inOutIdx;
33347
33348
0
    CALLOC_ASNGETDATA(dataASN, edPubKeyASN_Length, ret, NULL);
33349
33350
0
    if (ret == 0) {
33351
        /* Require OID. */
33352
0
        word32 oidSz;
33353
0
        const byte* oid = OidFromId((word32)keyType, oidKeyType, &oidSz);
33354
33355
0
        GetASN_ExpBuffer(&dataASN[EDPUBKEYASN_IDX_ALGOID_OID], oid, oidSz);
33356
        /* Decode Ed25519 private key. */
33357
0
        ret = GetASN_Items(edPubKeyASN, dataASN, edPubKeyASN_Length, 1, input,
33358
0
                inOutIdx, inSz);
33359
0
        if (ret != 0)
33360
0
            ret = ASN_PARSE_E;
33361
        /* check that input buffer is exhausted */
33362
0
        if (*inOutIdx != inSz)
33363
0
            ret = ASN_PARSE_E;
33364
0
    }
33365
    /* Check the public value length is correct. */
33366
0
    if ((ret == 0) &&
33367
0
            (dataASN[EDPUBKEYASN_IDX_PUBKEY].data.ref.length > *pubKeyLen)) {
33368
0
        ret = ASN_PARSE_E;
33369
0
    }
33370
    /* Check that the all the buffer was used. */
33371
0
    if ((ret == 0) &&
33372
0
            (GetASNItem_Length(dataASN[EDPUBKEYASN_IDX_SEQ], input) != len)) {
33373
0
        ret = ASN_PARSE_E;
33374
0
    }
33375
0
    if (ret == 0) {
33376
0
        *pubKeyLen = dataASN[EDPUBKEYASN_IDX_PUBKEY].data.ref.length;
33377
0
        XMEMCPY(pubKey, dataASN[EDPUBKEYASN_IDX_PUBKEY].data.ref.data,
33378
0
                *pubKeyLen);
33379
0
    }
33380
33381
0
    FREE_ASNGETDATA(dataASN, NULL);
33382
0
#endif /* WOLFSSL_ASN_TEMPLATE */
33383
0
    return ret;
33384
0
}
33385
#endif
33386
#endif /* WC_ENABLE_ASYM_KEY_IMPORT */
33387
33388
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
33389
int wc_Ed25519PrivateKeyDecode(const byte* input, word32* inOutIdx,
33390
                               ed25519_key* key, word32 inSz)
33391
0
{
33392
0
    int ret;
33393
0
    byte privKey[ED25519_KEY_SIZE], pubKey[ED25519_PUB_KEY_SIZE];
33394
0
    word32 privKeyLen = (word32)sizeof(privKey);
33395
0
    word32 pubKeyLen = (word32)sizeof(pubKey);
33396
33397
0
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
33398
0
        return BAD_FUNC_ARG;
33399
0
    }
33400
33401
0
    ret = DecodeAsymKey(input, inOutIdx, inSz, privKey, &privKeyLen,
33402
0
        pubKey, &pubKeyLen, ED25519k);
33403
0
    if (ret == 0) {
33404
0
        if (pubKeyLen == 0) {
33405
0
            ret = wc_ed25519_import_private_only(privKey, privKeyLen, key);
33406
0
        }
33407
0
        else {
33408
0
            ret = wc_ed25519_import_private_key(privKey, privKeyLen,
33409
0
                pubKey, pubKeyLen, key);
33410
0
        }
33411
0
    }
33412
0
    return ret;
33413
0
}
33414
33415
int wc_Ed25519PublicKeyDecode(const byte* input, word32* inOutIdx,
33416
                              ed25519_key* key, word32 inSz)
33417
0
{
33418
0
    int ret;
33419
0
    byte pubKey[ED25519_PUB_KEY_SIZE];
33420
0
    word32 pubKeyLen = (word32)sizeof(pubKey);
33421
33422
0
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
33423
0
        return BAD_FUNC_ARG;
33424
0
    }
33425
33426
0
    ret = DecodeAsymKeyPublic(input, inOutIdx, inSz,
33427
0
        pubKey, &pubKeyLen, ED25519k);
33428
0
    if (ret == 0) {
33429
0
        ret = wc_ed25519_import_public(pubKey, pubKeyLen, key);
33430
0
    }
33431
0
    return ret;
33432
0
}
33433
#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT */
33434
33435
#if defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_KEY_IMPORT)
33436
int wc_Curve25519PrivateKeyDecode(const byte* input, word32* inOutIdx,
33437
                               curve25519_key* key, word32 inSz)
33438
0
{
33439
0
    int ret;
33440
0
    byte privKey[CURVE25519_KEYSIZE];
33441
0
    word32 privKeyLen = CURVE25519_KEYSIZE;
33442
33443
0
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
33444
0
        return BAD_FUNC_ARG;
33445
0
    }
33446
33447
0
    ret = DecodeAsymKey(input, inOutIdx, inSz, privKey, &privKeyLen,
33448
0
        NULL, NULL, X25519k);
33449
0
    if (ret == 0) {
33450
0
        ret = wc_curve25519_import_private(privKey, privKeyLen, key);
33451
0
    }
33452
0
    return ret;
33453
0
}
33454
33455
int wc_Curve25519PublicKeyDecode(const byte* input, word32* inOutIdx,
33456
                              curve25519_key* key, word32 inSz)
33457
0
{
33458
0
    int ret;
33459
0
    byte pubKey[CURVE25519_KEYSIZE];
33460
0
    word32 pubKeyLen = (word32)sizeof(pubKey);
33461
33462
0
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
33463
0
        return BAD_FUNC_ARG;
33464
0
    }
33465
33466
0
    ret = DecodeAsymKeyPublic(input, inOutIdx, inSz,
33467
0
        pubKey, &pubKeyLen, X25519k);
33468
0
    if (ret == 0) {
33469
0
        ret = wc_curve25519_import_public(pubKey, pubKeyLen, key);
33470
0
    }
33471
0
    return ret;
33472
0
}
33473
#endif /* HAVE_CURVE25519 && HAVE_ED25519_KEY_IMPORT */
33474
33475
33476
#ifdef WC_ENABLE_ASYM_KEY_EXPORT
33477
33478
/* Build ASN.1 formatted key based on RFC 5958 (Asymmetric Key Packages)
33479
 *
33480
 * Pass NULL for output to get the size of the encoding.
33481
 *
33482
 * @param [in]  privKey      private key buffer
33483
 * @param [in]  privKeyLen   private ket buffer length
33484
 * @param [in]  pubKey       public key buffer (optional)
33485
 * @param [in]  pubKeyLen    public ket buffer length
33486
 * @param [out] output       Buffer to put encoded data in (optional)
33487
 * @param [in]  outLen       Size of buffer in bytes
33488
 * @param [in]  keyType      is "enum Key_Sum" like ED25519k
33489
 * @return  Size of encoded data in bytes on success
33490
 * @return  BAD_FUNC_ARG when key is NULL.
33491
 * @return  MEMORY_E when dynamic memory allocation failed.
33492
 */
33493
int SetAsymKeyDer(const byte* privKey, word32 privKeyLen,
33494
    const byte* pubKey, word32 pubKeyLen,
33495
    byte* output, word32 outLen, int keyType)
33496
0
{
33497
0
    int ret = 0;
33498
#ifndef WOLFSSL_ASN_TEMPLATE
33499
    word32 idx = 0, seqSz, verSz, algoSz, privSz, pubSz = 0, sz;
33500
#else
33501
0
    DECL_ASNSETDATA(dataASN, edKeyASN_Length);
33502
0
    int sz;
33503
0
#endif
33504
33505
    /* Validate parameters. */
33506
0
    if (privKey == NULL || outLen == 0) {
33507
0
        return BAD_FUNC_ARG;
33508
0
    }
33509
33510
#ifndef WOLFSSL_ASN_TEMPLATE
33511
    /* calculate size */
33512
    if (pubKey) {
33513
        pubSz = 2 + pubKeyLen;
33514
    }
33515
    privSz = 2 + 2 + privKeyLen;
33516
    algoSz = SetAlgoID(keyType, NULL, oidKeyType, 0);
33517
    verSz  = 3; /* version is 3 bytes (enum + id + version(byte)) */
33518
    seqSz  = SetSequence(verSz + algoSz + privSz + pubSz, NULL);
33519
    sz = seqSz + verSz + algoSz + privSz + pubSz;
33520
33521
    /* checkout output size */
33522
    if (output != NULL && sz > outLen) {
33523
        ret = BAD_FUNC_ARG;
33524
    }
33525
33526
    if (ret == 0 && output != NULL) {
33527
        /* write out */
33528
        /* seq */
33529
        seqSz = SetSequence(verSz + algoSz + privSz + pubSz, output);
33530
        idx = seqSz;
33531
        /* ver */
33532
        SetMyVersion(0, output + idx, FALSE);
33533
        idx += verSz;
33534
        /* algo */
33535
        algoSz = SetAlgoID(keyType, output + idx, oidKeyType, 0);
33536
        idx += algoSz;
33537
        /* privKey */
33538
        idx += SetOctetString(2 + privKeyLen, output + idx);
33539
        idx += SetOctetString(privKeyLen, output + idx);
33540
        XMEMCPY(output + idx, privKey, privKeyLen);
33541
        idx += privKeyLen;
33542
        /* pubKey */
33543
        if (pubKey) {
33544
            idx += SetHeader(ASN_CONTEXT_SPECIFIC | ASN_ASYMKEY_PUBKEY |
33545
                             1, pubKeyLen, output + idx);
33546
            XMEMCPY(output + idx, pubKey, pubKeyLen);
33547
            idx += pubKeyLen;
33548
        }
33549
        sz = idx;
33550
    }
33551
    if (ret == 0) {
33552
        /* Return size of encoding. */
33553
        ret = (int)sz;
33554
    }
33555
#else
33556
33557
0
    CALLOC_ASNSETDATA(dataASN, edKeyASN_Length, ret, NULL);
33558
33559
0
    if (ret == 0) {
33560
        /* Set version = 0 */
33561
0
        SetASN_Int8Bit(&dataASN[EDKEYASN_IDX_VER], 0);
33562
        /* Set OID. */
33563
0
        SetASN_OID(&dataASN[EDKEYASN_IDX_PKEYALGO_OID], (word32)keyType,
33564
0
                   oidKeyType);
33565
        /* Leave space for private key. */
33566
0
        SetASN_Buffer(&dataASN[EDKEYASN_IDX_PKEY_CURVEPKEY], NULL, privKeyLen);
33567
        /* Don't write out attributes. */
33568
0
        dataASN[EDKEYASN_IDX_ATTRS].noOut = 1;
33569
0
        if (pubKey) {
33570
            /* Leave space for public key. */
33571
0
            SetASN_Buffer(&dataASN[EDKEYASN_IDX_PUBKEY], NULL, pubKeyLen);
33572
0
        }
33573
0
        else {
33574
            /* Don't put out public part. */
33575
0
            SetASNItem_NoOutNode(dataASN, edKeyASN, EDKEYASN_IDX_PUBKEY,
33576
0
                    edKeyASN_Length);
33577
0
        }
33578
33579
        /* Calculate the size of encoding. */
33580
0
        ret = SizeASN_Items(edKeyASN, dataASN, edKeyASN_Length, &sz);
33581
0
    }
33582
33583
    /* Check buffer is big enough. */
33584
0
    if ((ret == 0) && (output != NULL) && (sz > (int)outLen)) {
33585
0
        ret = BAD_FUNC_ARG;
33586
0
    }
33587
0
    if ((ret == 0) && (output != NULL)) {
33588
        /* Encode private key. */
33589
0
        SetASN_Items(edKeyASN, dataASN, edKeyASN_Length, output);
33590
33591
        /* Put private value into space provided. */
33592
0
        XMEMCPY((byte*)dataASN[EDKEYASN_IDX_PKEY_CURVEPKEY].data.buffer.data,
33593
0
                privKey, privKeyLen);
33594
33595
0
        if (pubKey != NULL) {
33596
            /* Put public value into space provided. */
33597
0
            XMEMCPY((byte*)dataASN[EDKEYASN_IDX_PUBKEY].data.buffer.data,
33598
0
                    pubKey, pubKeyLen);
33599
0
        }
33600
0
    }
33601
0
    if (ret == 0) {
33602
        /* Return size of encoding. */
33603
0
        ret = sz;
33604
0
    }
33605
33606
0
    FREE_ASNSETDATA(dataASN, NULL);
33607
0
#endif
33608
0
    return ret;
33609
0
}
33610
#endif /* WC_ENABLE_ASYM_KEY_EXPORT */
33611
33612
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
33613
/* Write a Private ED25519 key, including public to DER format,
33614
 * length on success else < 0 */
33615
int wc_Ed25519KeyToDer(ed25519_key* key, byte* output, word32 inLen)
33616
0
{
33617
0
    if (key == NULL) {
33618
0
        return BAD_FUNC_ARG;
33619
0
    }
33620
0
    return SetAsymKeyDer(key->k, ED25519_KEY_SIZE,
33621
0
        key->p, ED25519_PUB_KEY_SIZE, output, inLen, ED25519k);
33622
0
}
33623
33624
/* Write only private ED25519 key to DER format,
33625
 * length on success else < 0 */
33626
int wc_Ed25519PrivateKeyToDer(ed25519_key* key, byte* output, word32 inLen)
33627
0
{
33628
0
    if (key == NULL) {
33629
0
        return BAD_FUNC_ARG;
33630
0
    }
33631
0
    return SetAsymKeyDer(key->k, ED25519_KEY_SIZE,
33632
0
        NULL, 0, output, inLen, ED25519k);
33633
0
}
33634
#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_EXPORT */
33635
33636
#if defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_KEY_EXPORT)
33637
/* Write only private Curve25519 key to DER format,
33638
 * length on success else < 0 */
33639
int wc_Curve25519PrivateKeyToDer(curve25519_key* key, byte* output, word32 inLen)
33640
0
{
33641
0
    int    ret;
33642
0
    byte   privKey[CURVE25519_KEYSIZE];
33643
0
    word32 privKeyLen = CURVE25519_KEYSIZE;
33644
33645
0
    if (key == NULL) {
33646
0
        return BAD_FUNC_ARG;
33647
0
    }
33648
33649
0
    ret = wc_curve25519_export_private_raw(key, privKey, &privKeyLen);
33650
0
    if (ret == 0) {
33651
0
        ret = SetAsymKeyDer(privKey, privKeyLen, NULL, 0, output, inLen,
33652
0
            X25519k);
33653
0
    }
33654
0
    return ret;
33655
0
}
33656
33657
/* Write a public Curve25519 key to DER format,
33658
 * length on success else < 0 */
33659
int wc_Curve25519PublicKeyToDer(curve25519_key* key, byte* output, word32 inLen,
33660
                             int withAlg)
33661
0
{
33662
0
    int    ret;
33663
0
    byte   pubKey[CURVE25519_PUB_KEY_SIZE];
33664
0
    word32 pubKeyLen = (word32)sizeof(pubKey);
33665
33666
0
    if (key == NULL || output == NULL) {
33667
0
        return BAD_FUNC_ARG;
33668
0
    }
33669
33670
0
    ret = wc_curve25519_export_public(key, pubKey, &pubKeyLen);
33671
0
    if (ret == 0) {
33672
0
        ret = SetAsymKeyDerPublic(pubKey, pubKeyLen, output, inLen,
33673
0
            X25519k, withAlg);
33674
0
    }
33675
0
    return ret;
33676
0
}
33677
#endif /* HAVE_CURVE25519 && HAVE_CURVE25519_KEY_EXPORT */
33678
33679
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)
33680
int wc_Ed448PrivateKeyDecode(const byte* input, word32* inOutIdx,
33681
                               ed448_key* key, word32 inSz)
33682
0
{
33683
0
    int ret;
33684
0
    byte privKey[ED448_KEY_SIZE], pubKey[ED448_PUB_KEY_SIZE];
33685
0
    word32 privKeyLen = (word32)sizeof(privKey);
33686
0
    word32 pubKeyLen = (word32)sizeof(pubKey);
33687
33688
0
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
33689
0
        return BAD_FUNC_ARG;
33690
0
    }
33691
33692
0
    ret = DecodeAsymKey(input, inOutIdx, inSz, privKey, &privKeyLen,
33693
0
        pubKey, &pubKeyLen, ED448k);
33694
0
    if (ret == 0) {
33695
0
        if (pubKeyLen == 0) {
33696
0
            ret = wc_ed448_import_private_only(privKey, privKeyLen, key);
33697
0
        }
33698
0
        else {
33699
0
            ret = wc_ed448_import_private_key(privKey, privKeyLen,
33700
0
                pubKey, pubKeyLen, key);
33701
0
        }
33702
0
    }
33703
0
    return ret;
33704
0
}
33705
33706
int wc_Ed448PublicKeyDecode(const byte* input, word32* inOutIdx,
33707
                              ed448_key* key, word32 inSz)
33708
0
{
33709
0
    int ret;
33710
0
    byte pubKey[ED448_PUB_KEY_SIZE];
33711
0
    word32 pubKeyLen = (word32)sizeof(pubKey);
33712
33713
0
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
33714
0
        return BAD_FUNC_ARG;
33715
0
    }
33716
33717
0
    ret = DecodeAsymKeyPublic(input, inOutIdx, inSz,
33718
0
        pubKey, &pubKeyLen, ED448k);
33719
0
    if (ret == 0) {
33720
0
        ret = wc_ed448_import_public(pubKey, pubKeyLen, key);
33721
0
    }
33722
0
    return ret;
33723
0
}
33724
#endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT */
33725
33726
#if defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_IMPORT)
33727
int wc_Curve448PrivateKeyDecode(const byte* input, word32* inOutIdx,
33728
                               curve448_key* key, word32 inSz)
33729
0
{
33730
0
    int ret;
33731
0
    byte privKey[CURVE448_KEY_SIZE];
33732
0
    word32 privKeyLen = CURVE448_KEY_SIZE;
33733
33734
0
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
33735
0
        return BAD_FUNC_ARG;
33736
0
    }
33737
33738
0
    ret = DecodeAsymKey(input, inOutIdx, inSz, privKey, &privKeyLen,
33739
0
        NULL, NULL, X448k);
33740
0
    if (ret == 0) {
33741
0
        ret = wc_curve448_import_private(privKey, privKeyLen, key);
33742
0
    }
33743
0
    return ret;
33744
0
}
33745
33746
int wc_Curve448PublicKeyDecode(const byte* input, word32* inOutIdx,
33747
                              curve448_key* key, word32 inSz)
33748
0
{
33749
0
    int ret;
33750
0
    byte pubKey[CURVE448_PUB_KEY_SIZE];
33751
0
    word32 pubKeyLen = (word32)sizeof(pubKey);
33752
33753
0
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
33754
0
        return BAD_FUNC_ARG;
33755
0
    }
33756
33757
0
    ret = DecodeAsymKeyPublic(input, inOutIdx, inSz,
33758
0
        pubKey, &pubKeyLen, X448k);
33759
0
    if (ret == 0) {
33760
0
        ret = wc_curve448_import_public(pubKey, pubKeyLen, key);
33761
0
    }
33762
0
    return ret;
33763
0
}
33764
#endif /* HAVE_CURVE448 && HAVE_ED448_KEY_IMPORT */
33765
33766
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
33767
/* Write a Private ecc key, including public to DER format,
33768
 * length on success else < 0 */
33769
int wc_Ed448KeyToDer(ed448_key* key, byte* output, word32 inLen)
33770
0
{
33771
0
    if (key == NULL) {
33772
0
        return BAD_FUNC_ARG;
33773
0
    }
33774
0
    return SetAsymKeyDer(key->k, ED448_KEY_SIZE,
33775
0
        key->p, ED448_KEY_SIZE, output, inLen, ED448k);
33776
0
}
33777
33778
/* Write only private ecc key to DER format,
33779
 * length on success else < 0 */
33780
int wc_Ed448PrivateKeyToDer(ed448_key* key, byte* output, word32 inLen)
33781
0
{
33782
0
    if (key == NULL) {
33783
0
        return BAD_FUNC_ARG;
33784
0
    }
33785
0
    return SetAsymKeyDer(key->k, ED448_KEY_SIZE,
33786
0
        NULL, 0, output, inLen, ED448k);
33787
0
}
33788
33789
#endif /* HAVE_ED448 && HAVE_ED448_KEY_EXPORT */
33790
33791
#if defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_EXPORT)
33792
/* Write private Curve448 key to DER format,
33793
 * length on success else < 0 */
33794
int wc_Curve448PrivateKeyToDer(curve448_key* key, byte* output, word32 inLen)
33795
0
{
33796
0
    int    ret;
33797
0
    byte   privKey[CURVE448_KEY_SIZE];
33798
0
    word32 privKeyLen = CURVE448_KEY_SIZE;
33799
33800
0
    if (key == NULL) {
33801
0
        return BAD_FUNC_ARG;
33802
0
    }
33803
33804
0
    ret = wc_curve448_export_private_raw(key, privKey, &privKeyLen);
33805
0
    if (ret == 0) {
33806
0
        ret = SetAsymKeyDer(privKey, privKeyLen, NULL, 0, output, inLen,
33807
0
            X448k);
33808
0
    }
33809
0
    return ret;
33810
0
}
33811
/* Write a public Curve448 key to DER format,
33812
 * length on success else < 0 */
33813
int wc_Curve448PublicKeyToDer(curve448_key* key, byte* output, word32 inLen,
33814
                             int withAlg)
33815
0
{
33816
0
    int    ret;
33817
0
    byte   pubKey[CURVE448_PUB_KEY_SIZE];
33818
0
    word32 pubKeyLen = (word32)sizeof(pubKey);
33819
33820
0
    if (key == NULL || output == NULL) {
33821
0
        return BAD_FUNC_ARG;
33822
0
    }
33823
33824
0
    ret = wc_curve448_export_public(key, pubKey, &pubKeyLen);
33825
0
    if (ret == 0) {
33826
0
        ret = SetAsymKeyDerPublic(pubKey, pubKeyLen, output, inLen,
33827
0
            X448k, withAlg);
33828
0
    }
33829
0
    return ret;
33830
0
}
33831
#endif /* HAVE_CURVE448 && HAVE_CURVE448_KEY_EXPORT */
33832
33833
33834
#ifndef WOLFSSL_ASN_TEMPLATE
33835
#if (defined(HAVE_OCSP) || defined(HAVE_CRL)) && !defined(WOLFCRYPT_ONLY)
33836
33837
/* Get raw Date only, no processing, 0 on success */
33838
static int GetBasicDate(const byte* source, word32* idx, byte* date,
33839
                        byte* format, int maxIdx)
33840
{
33841
    int    ret, length;
33842
    const byte *datePtr = NULL;
33843
33844
    WOLFSSL_ENTER("GetBasicDate");
33845
33846
    ret = GetDateInfo(source, idx, &datePtr, format, &length, maxIdx);
33847
    if (ret < 0)
33848
        return ret;
33849
33850
    XMEMCPY(date, datePtr, length);
33851
33852
    return 0;
33853
}
33854
33855
#endif /* HAVE_OCSP || HAVE_CRL */
33856
#endif /* WOLFSSL_ASN_TEMPLATE */
33857
33858
33859
#if defined(HAVE_OCSP) && !defined(WOLFCRYPT_ONLY)
33860
33861
#ifndef WOLFSSL_ASN_TEMPLATE
33862
static int GetEnumerated(const byte* input, word32* inOutIdx, int *value,
33863
        int sz)
33864
{
33865
    word32 idx = *inOutIdx;
33866
    word32 len;
33867
    byte   tag;
33868
33869
    WOLFSSL_ENTER("GetEnumerated");
33870
33871
    *value = 0;
33872
33873
    if (GetASNTag(input, &idx, &tag, sz) < 0)
33874
        return ASN_PARSE_E;
33875
33876
    if (tag != ASN_ENUMERATED)
33877
        return ASN_PARSE_E;
33878
33879
    if ((int)idx >= sz)
33880
        return BUFFER_E;
33881
33882
    len = input[idx++];
33883
    if (len > 4 || (int)(len + idx) > sz)
33884
        return ASN_PARSE_E;
33885
33886
    while (len--) {
33887
        *value  = *value << 8 | input[idx++];
33888
    }
33889
33890
    *inOutIdx = idx;
33891
33892
    return *value;
33893
}
33894
#endif /* !WOLFSSL_ASN_TEMPLATE */
33895
33896
33897
#ifdef WOLFSSL_ASN_TEMPLATE
33898
/* ASN.1 template for OCSP single response.
33899
 * RFC 6960, 4.2.1 - ASN.1 Specification of the OCSP Response
33900
 */
33901
static const ASNItem singleResponseASN[] = {
33902
/* SEQ                   */ { 0, ASN_SEQUENCE, 1, 1, 0 },
33903
                                                      /* certId */
33904
/* CID_SEQ               */     { 1, ASN_SEQUENCE, 1, 1, 0 },
33905
                                                          /* hashAlgorithm */
33906
/* CID_HASHALGO_SEQ      */         { 2, ASN_SEQUENCE, 1, 1, 0 },
33907
/* CID_HASHALGO_OID      */             { 3, ASN_OBJECT_ID, 0, 0, 0 },
33908
/* CID_HASHALGO_NULL     */             { 3, ASN_TAG_NULL, 0, 0, 1 },
33909
                                                          /* issuerNameHash */
33910
/* CID_ISSUERHASH        */         { 2, ASN_OCTET_STRING, 0, 0, 0 },
33911
                                                          /* issuerKeyHash */
33912
/* CID_ISSUERKEYHASH     */         { 2, ASN_OCTET_STRING, 0, 0, 0 },
33913
                                                          /* serialNumber */
33914
/* CID_SERIAL            */         { 2, ASN_INTEGER, 0, 0, 0 },
33915
                                                      /* certStatus - CHOICE */
33916
                                                      /* good              [0] IMPLICIT NULL */
33917
/* CS_GOOD               */     { 1, ASN_CONTEXT_SPECIFIC | 0, 0, 0, 2 },
33918
                                                      /* revoked           [1] IMPLICIT RevokedInfo */
33919
/* CS_REVOKED            */     { 1, ASN_CONTEXT_SPECIFIC | 1, 1, 1, 2 },
33920
                                                          /* revocationTime */
33921
/* CS_REVOKED_TIME       */         { 2, ASN_GENERALIZED_TIME, 0, 0, 0 },
33922
                                                          /* revocationReason  [0] EXPLICIT CRLReason OPTIONAL */
33923
/* CS_REVOKED_REASON     */         { 2, ASN_CONTEXT_SPECIFIC | 0, 0, 1, 1 },
33924
                                                              /* crlReason */
33925
/* CS_REVOKED_REASON_VAL */             { 3, ASN_ENUMERATED, 0, 0, 0 },
33926
                                                      /* unknown           [2] IMPLICIT UnknownInfo ::= NULL */
33927
/* UNKNOWN               */     { 1, ASN_CONTEXT_SPECIFIC | 2, 0, 0, 2 },
33928
33929
                                                      /* thisUpdate */
33930
/* THISUPDATE_GT         */     { 1, ASN_GENERALIZED_TIME, 0, 0, 0 },
33931
                                                      /* nextUpdate */
33932
/* NEXTUPDATE            */     { 1, ASN_CONTEXT_SPECIFIC | 0, 1, 1, 1 },
33933
/* NEXTUPDATE_GT         */         { 2, ASN_GENERALIZED_TIME, 0, 0, 0 },
33934
                                                      /* singleExtensions */
33935
/* EXT                   */     { 1, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 1 },
33936
};
33937
enum {
33938
    SINGLERESPONSEASN_IDX_SEQ = 0,
33939
    SINGLERESPONSEASN_IDX_CID_SEQ,
33940
    SINGLERESPONSEASN_IDX_CID_HASHALGO_SEQ,
33941
    SINGLERESPONSEASN_IDX_CID_HASHALGO_OID,
33942
    SINGLERESPONSEASN_IDX_CID_HASHALGO_NULL,
33943
    SINGLERESPONSEASN_IDX_CID_ISSUERHASH,
33944
    SINGLERESPONSEASN_IDX_CID_ISSUERKEYHASH,
33945
    SINGLERESPONSEASN_IDX_CID_SERIAL,
33946
    SINGLERESPONSEASN_IDX_CS_GOOD,
33947
    SINGLERESPONSEASN_IDX_CS_REVOKED,
33948
    SINGLERESPONSEASN_IDX_CS_REVOKED_TIME,
33949
    SINGLERESPONSEASN_IDX_CS_REVOKED_REASON,
33950
    SINGLERESPONSEASN_IDX_CS_REVOKED_REASON_VAL,
33951
    SINGLERESPONSEASN_IDX_UNKNOWN,
33952
    SINGLERESPONSEASN_IDX_THISUPDATE_GT,
33953
    SINGLERESPONSEASN_IDX_NEXTUPDATE,
33954
    SINGLERESPONSEASN_IDX_NEXTUPDATE_GT,
33955
    SINGLERESPONSEASN_IDX_EXT,
33956
};
33957
33958
/* Number of items in ASN.1 template for OCSP single response. */
33959
#define singleResponseASN_Length (sizeof(singleResponseASN) / sizeof(ASNItem))
33960
#endif
33961
33962
static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size,
33963
                                int wrapperSz, OcspEntry* single)
33964
{
33965
#ifndef WOLFSSL_ASN_TEMPLATE
33966
    word32 idx = *ioIndex, prevIndex, oid, localIdx, certIdIdx;
33967
    int length;
33968
    int ret;
33969
    byte tag;
33970
33971
    WOLFSSL_ENTER("DecodeSingleResponse");
33972
33973
    prevIndex = idx;
33974
33975
    /* Wrapper around the Single Response */
33976
    if (GetSequence(source, &idx, &length, size) < 0)
33977
        return ASN_PARSE_E;
33978
33979
    /* Wrapper around the CertID */
33980
    certIdIdx = idx;
33981
    if (GetSequence(source, &idx, &length, size) < 0)
33982
        return ASN_PARSE_E;
33983
    single->rawCertId = source + certIdIdx;
33984
    /* Hash algorithm */
33985
    ret = GetAlgoId(source, &idx, &oid, oidIgnoreType, size);
33986
    if (ret < 0)
33987
        return ret;
33988
    single->hashAlgoOID = oid;
33989
    /* Save reference to the hash of CN */
33990
    ret = GetOctetString(source, &idx, &length, size);
33991
    if (ret < 0)
33992
        return ret;
33993
    if (length > (int)sizeof(single->issuerHash))
33994
        return BUFFER_E;
33995
    XMEMCPY(single->issuerHash, source + idx, length);
33996
    idx += length;
33997
    /* Save reference to the hash of the issuer public key */
33998
    ret = GetOctetString(source, &idx, &length, size);
33999
    if (ret < 0)
34000
        return ret;
34001
    if (length > (int)sizeof(single->issuerKeyHash))
34002
        return BUFFER_E;
34003
    XMEMCPY(single->issuerKeyHash, source + idx, length);
34004
    idx += length;
34005
34006
    /* Get serial number */
34007
    if (wc_GetSerialNumber(source, &idx, single->status->serial,
34008
                        &single->status->serialSz, size) < 0)
34009
        return ASN_PARSE_E;
34010
    single->rawCertIdSize = idx - certIdIdx;
34011
34012
    if (idx >= size)
34013
        return BUFFER_E;
34014
34015
    /* CertStatus */
34016
    switch (source[idx++])
34017
    {
34018
        case (ASN_CONTEXT_SPECIFIC | CERT_GOOD):
34019
            single->status->status = CERT_GOOD;
34020
            idx++;
34021
            break;
34022
        case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_REVOKED):
34023
            single->status->status = CERT_REVOKED;
34024
            if (GetLength(source, &idx, &length, size) < 0)
34025
                return ASN_PARSE_E;
34026
            idx += length;
34027
            break;
34028
        case (ASN_CONTEXT_SPECIFIC | CERT_UNKNOWN):
34029
            single->status->status = CERT_UNKNOWN;
34030
            idx++;
34031
            break;
34032
        default:
34033
            return ASN_PARSE_E;
34034
    }
34035
34036
    if (idx >= size)
34037
        return BUFFER_E;
34038
34039
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
34040
    single->status->thisDateAsn = source + idx;
34041
    localIdx = 0;
34042
    if (GetDateInfo(single->status->thisDateAsn, &localIdx, NULL,
34043
                    (byte*)&single->status->thisDateParsed.type,
34044
                    &single->status->thisDateParsed.length, size - idx) < 0)
34045
        return ASN_PARSE_E;
34046
34047
    if (idx + localIdx >= size)
34048
        return BUFFER_E;
34049
34050
    XMEMCPY(single->status->thisDateParsed.data,
34051
            single->status->thisDateAsn + localIdx - single->status->thisDateParsed.length,
34052
            single->status->thisDateParsed.length);
34053
#endif
34054
    if (GetBasicDate(source, &idx, single->status->thisDate,
34055
                                                &single->status->thisDateFormat, size) < 0)
34056
        return ASN_PARSE_E;
34057
34058
#ifndef NO_ASN_TIME_CHECK
34059
#ifndef WOLFSSL_NO_OCSP_DATE_CHECK
34060
    if (!XVALIDATE_DATE(single->status->thisDate, single->status->thisDateFormat, BEFORE))
34061
        return ASN_BEFORE_DATE_E;
34062
#endif
34063
#endif
34064
34065
    /* The following items are optional. Only check for them if there is more
34066
     * unprocessed data in the singleResponse wrapper. */
34067
    localIdx = idx;
34068
    if (((int)(idx - prevIndex) < wrapperSz) &&
34069
        GetASNTag(source, &localIdx, &tag, size) == 0 &&
34070
        tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
34071
    {
34072
        idx++;
34073
        if (GetLength(source, &idx, &length, size) < 0)
34074
            return ASN_PARSE_E;
34075
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
34076
        single->status->nextDateAsn = source + idx;
34077
        localIdx = 0;
34078
        if (GetDateInfo(single->status->nextDateAsn, &localIdx, NULL,
34079
                        (byte*)&single->status->nextDateParsed.type,
34080
                        &single->status->nextDateParsed.length, size - idx) < 0)
34081
            return ASN_PARSE_E;
34082
34083
        if (idx + localIdx >= size)
34084
            return BUFFER_E;
34085
34086
        XMEMCPY(single->status->nextDateParsed.data,
34087
                single->status->nextDateAsn + localIdx - single->status->nextDateParsed.length,
34088
                single->status->nextDateParsed.length);
34089
#endif
34090
        if (GetBasicDate(source, &idx, single->status->nextDate,
34091
                                                &single->status->nextDateFormat, size) < 0)
34092
            return ASN_PARSE_E;
34093
34094
#ifndef NO_ASN_TIME_CHECK
34095
#ifndef WOLFSSL_NO_OCSP_DATE_CHECK
34096
        if (!XVALIDATE_DATE(single->status->nextDate, single->status->nextDateFormat, AFTER))
34097
            return ASN_AFTER_DATE_E;
34098
#endif
34099
#endif
34100
    }
34101
34102
    /* Skip the optional extensions in singleResponse. */
34103
    localIdx = idx;
34104
    if (((int)(idx - prevIndex) < wrapperSz) &&
34105
        GetASNTag(source, &localIdx, &tag, size) == 0 &&
34106
        tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
34107
    {
34108
        idx++;
34109
        if (GetLength(source, &idx, &length, size) < 0)
34110
            return ASN_PARSE_E;
34111
        idx += length;
34112
    }
34113
34114
    *ioIndex = idx;
34115
34116
    return 0;
34117
#else
34118
    DECL_ASNGETDATA(dataASN, singleResponseASN_Length);
34119
    int ret = 0;
34120
    word32 ocspDigestSize = OCSP_DIGEST_SIZE;
34121
    CertStatus* cs = NULL;
34122
    word32 serialSz;
34123
    word32 issuerHashLen;
34124
    word32 issuerKeyHashLen;
34125
    word32 thisDateLen;
34126
    word32 nextDateLen;
34127
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
34128
    defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY)
34129
    WOLFSSL_ASN1_TIME *at;
34130
#endif
34131
34132
    (void)wrapperSz;
34133
34134
    WOLFSSL_ENTER("DecodeSingleResponse");
34135
34136
    CALLOC_ASNGETDATA(dataASN, singleResponseASN_Length, ret, NULL);
34137
34138
    if (ret == 0) {
34139
        /* Certificate Status field. */
34140
        cs = single->status;
34141
34142
        /* Set maximum lengths for data. */
34143
        issuerHashLen    = OCSP_DIGEST_SIZE;
34144
        issuerKeyHashLen = OCSP_DIGEST_SIZE;
34145
        serialSz         = EXTERNAL_SERIAL_SIZE;
34146
        thisDateLen      = MAX_DATE_SIZE;
34147
        nextDateLen      = MAX_DATE_SIZE;
34148
34149
        /* Set OID type, buffers to hold data and variables to hold size. */
34150
        GetASN_OID(&dataASN[SINGLERESPONSEASN_IDX_CID_HASHALGO_OID],
34151
                oidHashType);
34152
        GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_CID_ISSUERHASH],
34153
                single->issuerHash, &issuerHashLen);
34154
        GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_CID_ISSUERKEYHASH],
34155
                single->issuerKeyHash, &issuerKeyHashLen);
34156
        GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_CID_SERIAL], cs->serial,
34157
                &serialSz);
34158
        GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_THISUPDATE_GT],
34159
                cs->thisDate, &thisDateLen);
34160
        GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_NEXTUPDATE_GT],
34161
                cs->nextDate, &nextDateLen);
34162
        /* TODO: decode revoked time and reason. */
34163
        /* Decode OCSP single response. */
34164
        ret = GetASN_Items(singleResponseASN, dataASN, singleResponseASN_Length,
34165
                1, source, ioIndex, size);
34166
    }
34167
    if (ret == 0) {
34168
        single->hashAlgoOID =
34169
            dataASN[SINGLERESPONSEASN_IDX_CID_HASHALGO_OID].data.oid.sum;
34170
        ocspDigestSize = (word32)wc_HashGetDigestSize(
34171
            wc_OidGetHash((int)single->hashAlgoOID));
34172
    }
34173
    /* Validate the issuer hash length is the size required. */
34174
    if ((ret == 0) && (issuerHashLen != ocspDigestSize)) {
34175
        ret = ASN_PARSE_E;
34176
    }
34177
    /* Validate the issuer key hash length is the size required. */
34178
    if ((ret == 0) && (issuerKeyHashLen != ocspDigestSize)) {
34179
        ret = ASN_PARSE_E;
34180
    }
34181
    if (ret == 0) {
34182
        /* Store serial size. */
34183
        cs->serialSz = (int)serialSz;
34184
        /* Set the hash algorithm OID */
34185
        single->hashAlgoOID =
34186
                dataASN[SINGLERESPONSEASN_IDX_CID_HASHALGO_OID].data.oid.sum;
34187
34188
        /* Determine status by which item was found. */
34189
        if (dataASN[SINGLERESPONSEASN_IDX_CS_GOOD].tag != 0) {
34190
            cs->status = CERT_GOOD;
34191
        }
34192
        if (dataASN[SINGLERESPONSEASN_IDX_CS_REVOKED].tag != 0) {
34193
            cs->status = CERT_REVOKED;
34194
        }
34195
        if (dataASN[SINGLERESPONSEASN_IDX_UNKNOWN].tag != 0) {
34196
            cs->status = CERT_UNKNOWN;
34197
        }
34198
34199
        /* Store the thisDate format - only one possible. */
34200
        cs->thisDateFormat = ASN_GENERALIZED_TIME;
34201
    #if !defined(NO_ASN_TIME_CHECK) && !defined(WOLFSSL_NO_OCSP_DATE_CHECK)
34202
        /* Check date is a valid string and BEFORE now. */
34203
        if (!XVALIDATE_DATE(cs->thisDate, ASN_GENERALIZED_TIME, BEFORE)) {
34204
            ret = ASN_BEFORE_DATE_E;
34205
        }
34206
    }
34207
    if (ret == 0) {
34208
    #endif
34209
    #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
34210
        defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY)
34211
        /* Store ASN.1 version of thisDate. */
34212
        cs->thisDateAsn = GetASNItem_Addr(
34213
                dataASN[SINGLERESPONSEASN_IDX_THISUPDATE_GT], source);
34214
        at = &cs->thisDateParsed;
34215
        at->type = ASN_GENERALIZED_TIME;
34216
        XMEMCPY(at->data, cs->thisDate, thisDateLen);
34217
        at->length = (int)thisDateLen;
34218
    #endif
34219
    }
34220
    if ((ret == 0) &&
34221
            (dataASN[SINGLERESPONSEASN_IDX_NEXTUPDATE_GT].tag != 0)) {
34222
        /* Store the nextDate format - only one possible. */
34223
        cs->nextDateFormat = ASN_GENERALIZED_TIME;
34224
    #if !defined(NO_ASN_TIME_CHECK) && !defined(WOLFSSL_NO_OCSP_DATE_CHECK)
34225
        /* Check date is a valid string and AFTER now. */
34226
        if (!XVALIDATE_DATE(cs->nextDate, ASN_GENERALIZED_TIME, AFTER)) {
34227
            ret = ASN_AFTER_DATE_E;
34228
        }
34229
    }
34230
    if ((ret == 0) &&
34231
            (dataASN[SINGLERESPONSEASN_IDX_NEXTUPDATE_GT].tag != 0)) {
34232
    #endif
34233
    #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
34234
        defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY)
34235
        /* Store ASN.1 version of thisDate. */
34236
        cs->nextDateAsn = GetASNItem_Addr(
34237
                dataASN[SINGLERESPONSEASN_IDX_NEXTUPDATE_GT], source);
34238
        at = &cs->nextDateParsed;
34239
        at->type = ASN_GENERALIZED_TIME;
34240
        XMEMCPY(at->data, cs->nextDate, nextDateLen);
34241
        at->length = (int)nextDateLen;
34242
    #endif
34243
    }
34244
    if (ret == 0) {
34245
        /* OcspEntry now used. */
34246
        single->used = 1;
34247
    }
34248
34249
    FREE_ASNGETDATA(dataASN, NULL);
34250
    return ret;
34251
#endif
34252
}
34253
34254
#ifdef WOLFSSL_ASN_TEMPLATE
34255
/* ASN.1 template for OCSP response extension header.
34256
 * RFC 6960, 4.2.1 - ASN.1 Specification of the OCSP Response
34257
 */
34258
static const ASNItem respExtHdrASN[] = {
34259
                                   /* responseExtensions */
34260
/* EXT     */    { 0, ASN_CONTEXT_SPECIFIC | 1, 1, 1, 0 },
34261
                                       /* extensions */
34262
/* EXT_SEQ */        { 1, ASN_SEQUENCE, 1, 1, 0 },
34263
};
34264
enum {
34265
    RESPEXTHDRASN_IDX_EXT = 0,
34266
    RESPEXTHDRASN_IDX_EXT_SEQ,
34267
};
34268
34269
/* Number of items in ASN.1 template for OCSP response extension header. */
34270
#define respExtHdrASN_Length (sizeof(respExtHdrASN) / sizeof(ASNItem))
34271
#endif
34272
34273
static int DecodeOcspRespExtensions(byte* source, word32* ioIndex,
34274
                                    OcspResponse* resp, word32 sz)
34275
{
34276
#ifndef WOLFSSL_ASN_TEMPLATE
34277
    word32 idx = *ioIndex;
34278
    int length;
34279
    int ext_bound; /* boundary index for the sequence of extensions */
34280
    word32 oid;
34281
    int ret;
34282
    byte tag;
34283
34284
    WOLFSSL_ENTER("DecodeOcspRespExtensions");
34285
34286
    if ((idx + 1) > sz)
34287
        return BUFFER_E;
34288
34289
    if (GetASNTag(source, &idx, &tag, sz) < 0)
34290
        return ASN_PARSE_E;
34291
34292
    if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
34293
        return ASN_PARSE_E;
34294
34295
    if (GetLength(source, &idx, &length, sz) < 0)
34296
        return ASN_PARSE_E;
34297
34298
    if (GetSequence(source, &idx, &length, sz) < 0)
34299
        return ASN_PARSE_E;
34300
34301
    ext_bound = idx + length;
34302
34303
    while (idx < (word32)ext_bound) {
34304
        word32 localIdx;
34305
34306
        if (GetSequence(source, &idx, &length, sz) < 0) {
34307
            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
34308
            return ASN_PARSE_E;
34309
        }
34310
34311
        oid = 0;
34312
        if (GetObjectId(source, &idx, &oid, oidOcspType, sz) < 0) {
34313
            WOLFSSL_MSG("\tfail: OBJECT ID");
34314
            return ASN_PARSE_E;
34315
        }
34316
34317
        /* check for critical flag */
34318
        if ((idx + 1) > (word32)sz) {
34319
            WOLFSSL_MSG("\tfail: malformed buffer");
34320
            return BUFFER_E;
34321
        }
34322
34323
        localIdx = idx;
34324
        if (GetASNTag(source, &localIdx, &tag, sz) == 0 && tag == ASN_BOOLEAN) {
34325
            WOLFSSL_MSG("\tfound optional critical flag, moving past");
34326
            ret = GetBoolean(source, &idx, sz);
34327
            if (ret < 0)
34328
                return ret;
34329
        }
34330
34331
        ret = GetOctetString(source, &idx, &length, sz);
34332
        if (ret < 0)
34333
            return ret;
34334
34335
        if (oid == OCSP_NONCE_OID) {
34336
            /* get data inside extra OCTET_STRING */
34337
            ret = GetOctetString(source, &idx, &length, sz);
34338
            if (ret < 0)
34339
                return ret;
34340
34341
            resp->nonce = source + idx;
34342
            resp->nonceSz = length;
34343
        }
34344
34345
        idx += length;
34346
    }
34347
34348
    *ioIndex = idx;
34349
    return 0;
34350
#else
34351
    /* certExtASN_Length is greater than respExtHdrASN_Length */
34352
    DECL_ASNGETDATA(dataASN, certExtASN_Length);
34353
    int ret = 0;
34354
    word32 idx = *ioIndex;
34355
    word32 maxIdx = 0;
34356
34357
    WOLFSSL_ENTER("DecodeOcspRespExtensions");
34358
34359
    CALLOC_ASNGETDATA(dataASN, certExtASN_Length, ret, resp->heap);
34360
34361
    if (ret == 0) {
34362
        /* Check for header and move past. */
34363
        ret = GetASN_Items(respExtHdrASN, dataASN, respExtHdrASN_Length, 0,
34364
            source, &idx, sz);
34365
    }
34366
    if (ret == 0) {
34367
        /* Keep end extensions index for total length check. */
34368
        maxIdx = idx + dataASN[RESPEXTHDRASN_IDX_EXT_SEQ].length;
34369
    }
34370
34371
    /* Step through all extensions. */
34372
    while ((ret == 0) && (idx < maxIdx)) {
34373
        /* Clear dynamic data, set OID type to expect. */
34374
        XMEMSET(dataASN, 0, sizeof(*dataASN) * certExtASN_Length);
34375
        GetASN_OID(&dataASN[CERTEXTASN_IDX_OID], oidOcspType);
34376
        /* TODO: check criticality. */
34377
        /* Decode OCSP response extension. */
34378
        ret = GetASN_Items(certExtASN, dataASN, certExtASN_Length, 0,
34379
                           source, &idx, sz);
34380
        if (ret == 0) {
34381
            word32 oid = dataASN[CERTEXTASN_IDX_OID].data.oid.sum;
34382
            int length = (int)dataASN[CERTEXTASN_IDX_VAL].length;
34383
34384
            if (oid == OCSP_NONCE_OID) {
34385
                /* Extract nonce data. */
34386
                ret = GetOctetString(source, &idx, &length, sz);
34387
                if (ret >= 0) {
34388
                    ret = 0;
34389
                    /* get data inside extra OCTET_STRING */
34390
                    resp->nonce = source + idx;
34391
                    resp->nonceSz = length;
34392
                }
34393
            }
34394
            /* Ignore all other extension types. */
34395
34396
            /* Skip over rest of extension. */
34397
            idx += (word32)length;
34398
        }
34399
    }
34400
34401
    /* Return index after extensions. */
34402
    *ioIndex = idx;
34403
34404
    FREE_ASNGETDATA(dataASN, resp->heap);
34405
    return ret;
34406
#endif
34407
}
34408
34409
#ifdef WOLFSSL_ASN_TEMPLATE
34410
/* ASN.1 template for OCSP ResponseData.
34411
 * RFC 6960, 4.2.1 - ASN.1 Specification of the OCSP Response
34412
 */
34413
static const ASNItem ocspRespDataASN[] = {
34414
/* SEQ         */    { 0, ASN_SEQUENCE, 1, 1, 0 },
34415
                                             /* version DEFAULT v1 */
34416
/* VER_PRESENT */        { 1, ASN_CONTEXT_SPECIFIC | 0, 1, 1, 1 },
34417
/* VER         */            { 2, ASN_INTEGER, 1, 0, 0 },
34418
                                             /* byName */
34419
/* BYNAME      */        { 1, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 2 },
34420
                                             /* byKey */
34421
/* BYKEY       */        { 1, ASN_CONTEXT_SPECIFIC | 2, 1, 0, 2 },
34422
                                             /* producedAt */
34423
/* PA          */        { 1, ASN_GENERALIZED_TIME, 0, 0, 0, },
34424
                                             /* responses */
34425
/* RESP        */        { 1, ASN_SEQUENCE, 1, 0, 0 },
34426
                                             /* responseExtensions */
34427
/* RESPEXT     */        { 1, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 1 }
34428
};
34429
enum {
34430
    OCSPRESPDATAASN_IDX_SEQ = 0,
34431
    OCSPRESPDATAASN_IDX_VER_PRESENT,
34432
    OCSPRESPDATAASN_IDX_VER,
34433
    OCSPRESPDATAASN_IDX_BYNAME,
34434
    OCSPRESPDATAASN_IDX_BYKEY,
34435
    OCSPRESPDATAASN_IDX_PA,
34436
    OCSPRESPDATAASN_IDX_RESP,
34437
    OCSPRESPDATAASN_IDX_RESPEXT,
34438
};
34439
34440
/* Number of items in ASN.1 template for OCSP ResponseData. */
34441
#define ocspRespDataASN_Length (sizeof(ocspRespDataASN) / sizeof(ASNItem))
34442
#endif
34443
34444
static int DecodeResponseData(byte* source, word32* ioIndex,
34445
                              OcspResponse* resp, word32 size)
34446
{
34447
#ifndef WOLFSSL_ASN_TEMPLATE
34448
    word32 idx = *ioIndex, prev_idx, localIdx;
34449
    int length;
34450
    int version;
34451
    int ret;
34452
    byte tag;
34453
    int wrapperSz;
34454
    OcspEntry* single;
34455
34456
    WOLFSSL_ENTER("DecodeResponseData");
34457
34458
    resp->response = source + idx;
34459
    prev_idx = idx;
34460
    if (GetSequence(source, &idx, &length, size) < 0)
34461
        return ASN_PARSE_E;
34462
    resp->responseSz = length + idx - prev_idx;
34463
34464
    /* Get version. It is an EXPLICIT[0] DEFAULT(0) value. If this
34465
     * item isn't an EXPLICIT[0], then set version to zero and move
34466
     * onto the next item.
34467
     */
34468
    localIdx = idx;
34469
    if (GetASNTag(source, &localIdx, &tag, size) == 0 &&
34470
            tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
34471
    {
34472
        idx += 2; /* Eat the value and length */
34473
        if (GetMyVersion(source, &idx, &version, size) < 0)
34474
            return ASN_PARSE_E;
34475
    } else
34476
        version = 0;
34477
34478
    localIdx = idx;
34479
    if (GetASNTag(source, &localIdx, &tag, size) == 0 &&
34480
        ( tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1) ||
34481
          tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2) ))
34482
    {
34483
        idx++; /* advance past ASN tag */
34484
        if (GetLength(source, &idx, &length, size) < 0)
34485
            return ASN_PARSE_E;
34486
        idx += length;
34487
    }
34488
    else
34489
        return ASN_PARSE_E;
34490
34491
    /* save pointer to the producedAt time */
34492
    if (GetBasicDate(source, &idx, resp->producedDate,
34493
                                        &resp->producedDateFormat, size) < 0)
34494
        return ASN_PARSE_E;
34495
34496
    /* Outer wrapper of the SEQUENCE OF Single Responses. */
34497
    if (GetSequence(source, &idx, &wrapperSz, size) < 0)
34498
        return ASN_PARSE_E;
34499
34500
    localIdx = idx;
34501
    single = resp->single;
34502
    while (idx - localIdx < (word32)wrapperSz) {
34503
        ret = DecodeSingleResponse(source, &idx, size, wrapperSz, single);
34504
        if (ret < 0)
34505
            return ret; /* ASN_PARSE_E, ASN_BEFORE_DATE_E, ASN_AFTER_DATE_E */
34506
        if (idx - localIdx < (word32)wrapperSz) {
34507
            single->next = (OcspEntry*)XMALLOC(sizeof(OcspEntry), resp->heap,
34508
                DYNAMIC_TYPE_OCSP_ENTRY);
34509
            if (single->next == NULL) {
34510
                return MEMORY_E;
34511
            }
34512
            XMEMSET(single->next, 0, sizeof(OcspEntry));
34513
34514
            single->next->status = (CertStatus*)XMALLOC(sizeof(CertStatus),
34515
                resp->heap, DYNAMIC_TYPE_OCSP_STATUS);
34516
            if (single->next->status == NULL) {
34517
                XFREE(single->next, resp->heap, DYNAMIC_TYPE_OCSP_ENTRY);
34518
                single->next = NULL;
34519
                return MEMORY_E;
34520
            }
34521
            XMEMSET(single->next->status, 0, sizeof(CertStatus));
34522
34523
            single->next->isDynamic = 1;
34524
34525
            single = single->next;
34526
        }
34527
    }
34528
34529
    /*
34530
     * Check the length of the ResponseData against the current index to
34531
     * see if there are extensions, they are optional.
34532
     */
34533
    if (idx - prev_idx < resp->responseSz)
34534
        if (DecodeOcspRespExtensions(source, &idx, resp, size) < 0)
34535
            return ASN_PARSE_E;
34536
34537
    *ioIndex = idx;
34538
    return 0;
34539
#else
34540
    DECL_ASNGETDATA(dataASN, ocspRespDataASN_Length);
34541
    int ret = 0;
34542
    byte version;
34543
    word32 dateSz, idx = *ioIndex;
34544
    OcspEntry* single = NULL;
34545
34546
    WOLFSSL_ENTER("DecodeResponseData");
34547
34548
    CALLOC_ASNGETDATA(dataASN, ocspRespDataASN_Length, ret, resp->heap);
34549
34550
    if (ret == 0) {
34551
        resp->response = source + idx;
34552
        /* Default, not present, is v1 = 0. */
34553
        version = 0;
34554
        /* Max size of date supported. */
34555
        dateSz = MAX_DATE_SIZE;
34556
34557
        /* Set the where to put version an produced date. */
34558
        GetASN_Int8Bit(&dataASN[OCSPRESPDATAASN_IDX_VER], &version);
34559
        GetASN_Buffer(&dataASN[OCSPRESPDATAASN_IDX_PA], resp->producedDate,
34560
                &dateSz);
34561
        /* Decode the ResponseData. */
34562
        ret = GetASN_Items(ocspRespDataASN, dataASN, ocspRespDataASN_Length,
34563
                1, source, ioIndex, size);
34564
    }
34565
    /* Only support v1 == 0 */
34566
    if ((ret == 0) && (version != 0)) {
34567
        ret = ASN_PARSE_E;
34568
    }
34569
    /* Ensure date is a minimal size. */
34570
    if ((ret == 0) && (dateSz < MIN_DATE_SIZE)) {
34571
        ret = ASN_PARSE_E;
34572
    }
34573
    if (ret == 0) {
34574
        /* TODO: use byName/byKey fields. */
34575
        /* Store size of response. */
34576
        resp->responseSz = *ioIndex - idx;
34577
        /* Store date format/tag. */
34578
        resp->producedDateFormat = dataASN[OCSPRESPDATAASN_IDX_PA].tag;
34579
34580
        /* Get the index of the responses SEQUENCE. */
34581
        idx = GetASNItem_DataIdx(dataASN[OCSPRESPDATAASN_IDX_RESP], source);
34582
        /* Start with the pre-existing OcspEntry. */
34583
        single = resp->single;
34584
    }
34585
    while ((ret == 0) && (idx < dataASN[OCSPRESPDATAASN_IDX_RESPEXT].offset)) {
34586
        /* Allocate and use a new OCSP entry if this is used. */
34587
        if (single->used) {
34588
            single->next = (OcspEntry*)XMALLOC(sizeof(OcspEntry), resp->heap,
34589
                    DYNAMIC_TYPE_OCSP_ENTRY);
34590
            if (single->next == NULL) {
34591
                ret = MEMORY_E;
34592
            }
34593
            else {
34594
                XMEMSET(single->next, 0, sizeof(OcspEntry));
34595
34596
                single->next->status = (CertStatus*)XMALLOC(sizeof(CertStatus),
34597
                    resp->heap, DYNAMIC_TYPE_OCSP_STATUS);
34598
                if (single->next->status == NULL) {
34599
                    XFREE(single->next, resp->heap, DYNAMIC_TYPE_OCSP_ENTRY);
34600
                    single->next = NULL;
34601
                    ret = MEMORY_E;
34602
                }
34603
                else {
34604
                    XMEMSET(single->next->status, 0, sizeof(CertStatus));
34605
34606
                    /* Entry to be freed. */
34607
                    single->next->isDynamic = 1;
34608
                    /* used will be 0 (false) */
34609
34610
                    single = single->next;
34611
                }
34612
            }
34613
        }
34614
        if (ret == 0) {
34615
            /* Decode SingleResponse into OcspEntry. */
34616
            ret = DecodeSingleResponse(source, &idx,
34617
                dataASN[OCSPRESPDATAASN_IDX_RESPEXT].offset,
34618
                (int)dataASN[OCSPRESPDATAASN_IDX_RESP].length, single);
34619
            /* single->used set on successful decode. */
34620
        }
34621
    }
34622
34623
    /* Check if there were extensions. */
34624
    if ((ret == 0) &&
34625
            (dataASN[OCSPRESPDATAASN_IDX_RESPEXT].data.buffer.data != NULL)) {
34626
        /* Get index of [1] */
34627
        idx = dataASN[OCSPRESPDATAASN_IDX_RESPEXT].offset;
34628
        /* Decode the response extensions. */
34629
        if (DecodeOcspRespExtensions(source, &idx, resp, *ioIndex) < 0) {
34630
            ret = ASN_PARSE_E;
34631
        }
34632
    }
34633
34634
    FREE_ASNGETDATA(dataASN, resp->heap);
34635
    return ret;
34636
#endif
34637
}
34638
34639
34640
#ifndef WOLFSSL_ASN_TEMPLATE
34641
#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
34642
34643
static int DecodeCerts(byte* source,
34644
                            word32* ioIndex, OcspResponse* resp, word32 size)
34645
{
34646
    word32 idx = *ioIndex;
34647
    byte tag;
34648
34649
    WOLFSSL_ENTER("DecodeCerts");
34650
34651
    if (GetASNTag(source, &idx, &tag, size) < 0)
34652
        return ASN_PARSE_E;
34653
34654
    if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
34655
    {
34656
        int length;
34657
34658
        if (GetLength(source, &idx, &length, size) < 0)
34659
            return ASN_PARSE_E;
34660
34661
        if (GetSequence(source, &idx, &length, size) < 0)
34662
            return ASN_PARSE_E;
34663
34664
        resp->cert = source + idx;
34665
        resp->certSz = length;
34666
34667
        idx += length;
34668
    }
34669
    *ioIndex = idx;
34670
    return 0;
34671
}
34672
34673
#endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */
34674
#endif /* !WOLFSSL_ASN_TEMPLATE */
34675
34676
#ifdef WOLFSSL_ASN_TEMPLATE
34677
/* ASN.1 template for BasicOCSPResponse.
34678
 * RFC 6960, 4.2.1 - ASN.1 Specification of the OCSP Response
34679
 */
34680
static const ASNItem ocspBasicRespASN[] = {
34681
/* SEQ          */ { 0, ASN_SEQUENCE, 1, 1, 0 },
34682
                                            /* tbsResponseData */
34683
/* TBS_SEQ      */     { 1, ASN_SEQUENCE, 1, 0, 0, },
34684
                                            /* signatureAlgorithm */
34685
/* SIGALGO      */     { 1, ASN_SEQUENCE, 1, 1, 0, },
34686
/* SIGALGO_OID  */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
34687
/* SIGALGO_NULL */         { 2, ASN_TAG_NULL, 0, 0, 1 },
34688
                                            /* parameters */
34689
#ifdef WC_RSA_PSS
34690
/* SIGALGO_PARAMS      */  { 2, ASN_SEQUENCE, 1, 0, 1 },
34691
#endif
34692
                                            /* signature */
34693
/* SIGNATURE    */     { 1, ASN_BIT_STRING, 0, 0, 0 },
34694
                                            /* certs */
34695
/* CERTS        */     { 1, ASN_CONTEXT_SPECIFIC | 0, 1, 1, 1 },
34696
/* CERTS_SEQ    */         { 2, ASN_SEQUENCE, 1, 0, 0, },
34697
};
34698
enum {
34699
    OCSPBASICRESPASN_IDX_SEQ = 0,
34700
    OCSPBASICRESPASN_IDX_TBS_SEQ,
34701
    OCSPBASICRESPASN_IDX_SIGALGO,
34702
    OCSPBASICRESPASN_IDX_SIGALGO_OID,
34703
    OCSPBASICRESPASN_IDX_SIGALGO_NULL,
34704
#ifdef WC_RSA_PSS
34705
    OCSPBASICRESPASN_IDX_SIGNATURE_PARAMS,
34706
#endif
34707
    OCSPBASICRESPASN_IDX_SIGNATURE,
34708
    OCSPBASICRESPASN_IDX_CERTS,
34709
    OCSPBASICRESPASN_IDX_CERTS_SEQ,
34710
};
34711
34712
/* Number of items in ASN.1 template for BasicOCSPResponse. */
34713
#define ocspBasicRespASN_Length (sizeof(ocspBasicRespASN) / sizeof(ASNItem))
34714
#endif /* WOLFSSL_ASN_TEMPLATE */
34715
34716
static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
34717
            OcspResponse* resp, word32 size, void* cm, void* heap, int noVerify)
34718
{
34719
#ifndef WOLFSSL_ASN_TEMPLATE
34720
    int    length;
34721
    word32 idx = *ioIndex;
34722
    #ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
34723
    word32 end_index;
34724
    #endif
34725
    int    ret;
34726
    int    sigLength;
34727
    const byte*   sigParams = NULL;
34728
    word32        sigParamsSz = 0;
34729
    WOLFSSL_ENTER("DecodeBasicOcspResponse");
34730
    (void)heap;
34731
34732
    if (GetSequence(source, &idx, &length, size) < 0)
34733
        return ASN_PARSE_E;
34734
34735
    if (idx + length > size)
34736
        return ASN_INPUT_E;
34737
    #ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
34738
    end_index = idx + length;
34739
    #endif
34740
34741
    if ((ret = DecodeResponseData(source, &idx, resp, size)) < 0)
34742
        return ret; /* ASN_PARSE_E, ASN_BEFORE_DATE_E, ASN_AFTER_DATE_E */
34743
34744
    /* Get the signature algorithm */
34745
    if (GetAlgoId(source, &idx, &resp->sigOID, oidSigType, size) < 0) {
34746
        return ASN_PARSE_E;
34747
    }
34748
#ifdef WC_RSA_PSS
34749
    else if (resp->sigOID == CTC_RSASSAPSS) {
34750
        word32 sz;
34751
        int len;
34752
        const byte* params;
34753
34754
        sz = idx;
34755
        params = source + idx;
34756
        if (GetSequence(source, &idx, &len, size) < 0)
34757
            ret = ASN_PARSE_E;
34758
        if (ret == 0) {
34759
            idx += len;
34760
            sigParams = params;
34761
            sigParamsSz = idx - sz;
34762
        }
34763
    }
34764
#endif
34765
34766
    ret = CheckBitString(source, &idx, &sigLength, size, 1, NULL);
34767
    if (ret != 0)
34768
        return ret;
34769
34770
    resp->sigSz = sigLength;
34771
    resp->sig = source + idx;
34772
    idx += sigLength;
34773
34774
    /*
34775
     * Check the length of the BasicOcspResponse against the current index to
34776
     * see if there are certificates, they are optional.
34777
     */
34778
#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
34779
    if (idx < end_index)
34780
    {
34781
        int cert_inited = 0;
34782
#ifdef WOLFSSL_SMALL_STACK
34783
        DecodedCert *cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
34784
                                                  DYNAMIC_TYPE_TMP_BUFFER);
34785
        if (cert == NULL)
34786
            return MEMORY_E;
34787
#else
34788
        DecodedCert cert[1];
34789
#endif
34790
34791
        do {
34792
            if (DecodeCerts(source, &idx, resp, size) < 0) {
34793
                ret = ASN_PARSE_E;
34794
                break;
34795
            }
34796
34797
            InitDecodedCert(cert, resp->cert, resp->certSz, heap);
34798
            cert_inited = 1;
34799
34800
            /* Don't verify if we don't have access to Cert Manager. */
34801
            ret = ParseCertRelative(cert, CERT_TYPE,
34802
                                    noVerify ? NO_VERIFY : VERIFY_OCSP_CERT,
34803
                                    cm);
34804
            if (ret < 0) {
34805
                WOLFSSL_MSG("\tOCSP Responder certificate parsing failed");
34806
                break;
34807
            }
34808
34809
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK
34810
            if ((cert->extExtKeyUsage & EXTKEYUSE_OCSP_SIGN) == 0) {
34811
                if (XMEMCMP(cert->subjectHash,
34812
                            resp->single->issuerHash, OCSP_DIGEST_SIZE) == 0) {
34813
                    WOLFSSL_MSG("\tOCSP Response signed by issuer");
34814
                }
34815
                else {
34816
                    WOLFSSL_MSG("\tOCSP Responder key usage check failed");
34817
    #ifdef OPENSSL_EXTRA
34818
                    resp->verifyError = OCSP_BAD_ISSUER;
34819
    #else
34820
                    ret = BAD_OCSP_RESPONDER;
34821
                    break;
34822
    #endif
34823
                }
34824
            }
34825
#endif
34826
34827
            /* ConfirmSignature is blocking here */
34828
            ret = ConfirmSignature(
34829
                &cert->sigCtx,
34830
                resp->response, resp->responseSz,
34831
                cert->publicKey, cert->pubKeySize, cert->keyOID,
34832
                resp->sig, resp->sigSz, resp->sigOID, sigParams, sigParamsSz,
34833
                NULL);
34834
34835
            if (ret != 0) {
34836
                WOLFSSL_MSG("\tOCSP Confirm signature failed");
34837
                ret = ASN_OCSP_CONFIRM_E;
34838
                break;
34839
            }
34840
        } while(0);
34841
34842
        if (cert_inited)
34843
            FreeDecodedCert(cert);
34844
#ifdef WOLFSSL_SMALL_STACK
34845
        XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
34846
#endif
34847
34848
        if (ret != 0)
34849
            return ret;
34850
    }
34851
    else
34852
#endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */
34853
    {
34854
        Signer* ca;
34855
        int sigValid = -1;
34856
34857
        #ifndef NO_SKID
34858
            ca = GetCA(cm, resp->single->issuerKeyHash);
34859
        #else
34860
            ca = GetCA(cm, resp->single->issuerHash);
34861
        #endif
34862
34863
        if (ca) {
34864
            SignatureCtx sigCtx;
34865
            InitSignatureCtx(&sigCtx, heap, INVALID_DEVID);
34866
34867
            /* ConfirmSignature is blocking here */
34868
            sigValid = ConfirmSignature(&sigCtx, resp->response,
34869
                resp->responseSz, ca->publicKey, ca->pubKeySize, ca->keyOID,
34870
                resp->sig, resp->sigSz, resp->sigOID, sigParams, sigParamsSz,
34871
                NULL);
34872
        }
34873
        if (ca == NULL || sigValid != 0) {
34874
            WOLFSSL_MSG("\tOCSP Confirm signature failed");
34875
            return ASN_OCSP_CONFIRM_E;
34876
        }
34877
34878
        (void)noVerify;
34879
    }
34880
34881
    *ioIndex = idx;
34882
    return 0;
34883
#else
34884
    DECL_ASNGETDATA(dataASN, ocspBasicRespASN_Length);
34885
    int ret = 0;
34886
    word32 idx = *ioIndex;
34887
    const byte*   sigParams = NULL;
34888
    word32        sigParamsSz = 0;
34889
#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
34890
    #ifdef WOLFSSL_SMALL_STACK
34891
        DecodedCert* cert = NULL;
34892
    #else
34893
        DecodedCert cert[1];
34894
    #endif
34895
    int certInit = 0;
34896
#endif
34897
34898
    WOLFSSL_ENTER("DecodeBasicOcspResponse");
34899
    (void)heap;
34900
34901
    CALLOC_ASNGETDATA(dataASN, ocspBasicRespASN_Length, ret, heap);
34902
34903
    if (ret == 0) {
34904
        /* Set expecting signature OID. */
34905
        GetASN_OID(&dataASN[OCSPBASICRESPASN_IDX_SIGALGO_OID], oidSigType);
34906
        /* Decode BasicOCSPResponse. */
34907
        ret = GetASN_Items(ocspBasicRespASN, dataASN, ocspBasicRespASN_Length,
34908
                1, source, &idx, size);
34909
    }
34910
    if (ret == 0) {
34911
        word32 dataIdx = 0;
34912
        /* Decode the response data. */
34913
        if (DecodeResponseData(
34914
                GetASNItem_Addr(dataASN[OCSPBASICRESPASN_IDX_TBS_SEQ], source),
34915
                &dataIdx, resp,
34916
                GetASNItem_Length(dataASN[OCSPBASICRESPASN_IDX_TBS_SEQ], source)
34917
                ) < 0) {
34918
            ret = ASN_PARSE_E;
34919
        }
34920
    }
34921
#ifdef WC_RSA_PSS
34922
    if (ret == 0 && (dataASN[OCSPBASICRESPASN_IDX_SIGNATURE_PARAMS].tag != 0)) {
34923
        sigParams = GetASNItem_Addr(
34924
                dataASN[OCSPBASICRESPASN_IDX_SIGNATURE_PARAMS],
34925
                source);
34926
        sigParamsSz =
34927
               GetASNItem_Length(dataASN[OCSPBASICRESPASN_IDX_SIGNATURE_PARAMS],
34928
               source);
34929
    }
34930
#endif
34931
    if (ret == 0) {
34932
        /* Get the signature OID and signature. */
34933
        resp->sigOID = dataASN[OCSPBASICRESPASN_IDX_SIGALGO_OID].data.oid.sum;
34934
        GetASN_GetRef(&dataASN[OCSPBASICRESPASN_IDX_SIGNATURE], &resp->sig,
34935
                &resp->sigSz);
34936
    }
34937
#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
34938
    if ((ret == 0) &&
34939
            (dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data != NULL)) {
34940
        /* TODO: support more than one certificate. */
34941
        /* Store reference to certificate BER data. */
34942
        GetASN_GetRef(&dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ], &resp->cert,
34943
                &resp->certSz);
34944
34945
        /* Allocate a certificate object to decode cert into. */
34946
    #ifdef WOLFSSL_SMALL_STACK
34947
        cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), heap,
34948
                DYNAMIC_TYPE_TMP_BUFFER);
34949
        if (cert == NULL) {
34950
            ret = MEMORY_E;
34951
        }
34952
    }
34953
    if ((ret == 0) &&
34954
            (dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data != NULL)) {
34955
    #endif
34956
        /* Initialize the certificate object. */
34957
        InitDecodedCert(cert, resp->cert, resp->certSz, heap);
34958
        certInit = 1;
34959
        /* Parse the certificate and don't verify if we don't have access to
34960
         * Cert Manager. */
34961
        ret = ParseCertRelative(cert, CERT_TYPE, noVerify ? NO_VERIFY : VERIFY,
34962
                cm);
34963
        if (ret < 0) {
34964
            WOLFSSL_MSG("\tOCSP Responder certificate parsing failed");
34965
        }
34966
    }
34967
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK
34968
    if ((ret == 0) &&
34969
            (dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data != NULL) &&
34970
            !noVerify) {
34971
        ret = CheckOcspResponder(resp, cert, cm);
34972
    }
34973
#endif /* WOLFSSL_NO_OCSP_ISSUER_CHECK */
34974
    if ((ret == 0) &&
34975
            (dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data != NULL)) {
34976
        /* TODO: ConfirmSignature is blocking here */
34977
        /* Check the signature of the response. */
34978
        ret = ConfirmSignature(&cert->sigCtx, resp->response, resp->responseSz,
34979
            cert->publicKey, cert->pubKeySize, cert->keyOID, resp->sig,
34980
            resp->sigSz, resp->sigOID, NULL, 0, NULL);
34981
        if (ret != 0) {
34982
            WOLFSSL_MSG("\tOCSP Confirm signature failed");
34983
            ret = ASN_OCSP_CONFIRM_E;
34984
        }
34985
    }
34986
    if ((ret == 0) &&
34987
            (dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data == NULL))
34988
#else
34989
    if (ret == 0)
34990
#endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */
34991
    {
34992
        Signer* ca;
34993
        int sigValid = -1;
34994
34995
        /* Resonse didn't have a certificate - lookup CA. */
34996
    #ifndef NO_SKID
34997
        ca = GetCA(cm, resp->single->issuerKeyHash);
34998
    #else
34999
        ca = GetCA(cm, resp->single->issuerHash);
35000
    #endif
35001
        if (ca) {
35002
            SignatureCtx sigCtx;
35003
35004
            /* Initialize he signature context. */
35005
            InitSignatureCtx(&sigCtx, heap, INVALID_DEVID);
35006
35007
            /* TODO: ConfirmSignature is blocking here */
35008
            /* Check the signature of the response CA public key. */
35009
            sigValid = ConfirmSignature(&sigCtx, resp->response,
35010
                resp->responseSz, ca->publicKey, ca->pubKeySize, ca->keyOID,
35011
                resp->sig, resp->sigSz, resp->sigOID, sigParams, sigParamsSz,
35012
                NULL);
35013
        }
35014
        if ((ca == NULL) || (sigValid != 0)) {
35015
            /* Didn't find certificate or signature verificate failed. */
35016
            WOLFSSL_MSG("\tOCSP Confirm signature failed");
35017
            ret = ASN_OCSP_CONFIRM_E;
35018
        }
35019
    }
35020
35021
    if (ret == 0) {
35022
        /* Update the position to after response data. */
35023
        *ioIndex = idx;
35024
    }
35025
35026
#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
35027
    if (certInit) {
35028
        FreeDecodedCert(cert);
35029
    }
35030
    #ifdef WOLFSSL_SMALL_STACK
35031
    if (cert != NULL) {
35032
        /* Dispose of certificate object. */
35033
        XFREE(cert, heap, DYNAMIC_TYPE_TMP_BUFFER);
35034
    }
35035
    #endif
35036
#endif
35037
    FREE_ASNGETDATA(dataASN, heap);
35038
    return ret;
35039
#endif /* WOLFSSL_ASN_TEMPLATE */
35040
}
35041
35042
35043
void InitOcspResponse(OcspResponse* resp, OcspEntry* single, CertStatus* status,
35044
                      byte* source, word32 inSz, void* heap)
35045
{
35046
    WOLFSSL_ENTER("InitOcspResponse");
35047
35048
    XMEMSET(status, 0, sizeof(CertStatus));
35049
    XMEMSET(single,  0, sizeof(OcspEntry));
35050
    XMEMSET(resp,   0, sizeof(OcspResponse));
35051
35052
    single->status       = status;
35053
    resp->responseStatus = -1;
35054
    resp->single         = single;
35055
    resp->source         = source;
35056
    resp->maxIdx         = inSz;
35057
    resp->heap           = heap;
35058
}
35059
35060
void FreeOcspResponse(OcspResponse* resp)
35061
{
35062
    OcspEntry *single, *next;
35063
35064
    if (resp != NULL) {
35065
        for (single = resp->single; single; single = next) {
35066
            next = single->next;
35067
            if (single->isDynamic) {
35068
                XFREE(single->status, resp->heap, DYNAMIC_TYPE_OCSP_STATUS);
35069
                XFREE(single, resp->heap, DYNAMIC_TYPE_OCSP_ENTRY);
35070
            }
35071
        }
35072
    }
35073
}
35074
35075
#ifdef WOLFSSL_ASN_TEMPLATE
35076
/* ASN.1 template for OCSPResponse.
35077
 * RFC 6960, 4.2.1 - ASN.1 Specification of the OCSP Response
35078
 */
35079
static const ASNItem ocspResponseASN[] = {
35080
                                     /* OCSPResponse ::= SEQUENCE */
35081
/* SEQ        */ { 0, ASN_SEQUENCE, 1, 1, 0 },
35082
                                         /* responseStatus      OCSPResponseStatus */
35083
/* STATUS     */     { 1, ASN_ENUMERATED, 0, 0, 0, },
35084
                                         /* responseBytes   [0] EXPLICIT ResponseBytes OPTIONAL */
35085
/* BYTES      */     { 1, ASN_CONTEXT_SPECIFIC | 0, 1, 1, 1 },
35086
                                             /* ResponseBytes ::= SEQUENCE */
35087
/* BYTES_SEQ  */         { 2, ASN_SEQUENCE, 1, 1, 0 },
35088
                                                /* responseType   OBJECT IDENTIFIER */
35089
/* BYTES_TYPE */            { 3, ASN_OBJECT_ID, 0, 0, 0 },
35090
                                                /* response       OCTET STRING */
35091
/* BYTES_VAL  */            { 3, ASN_OCTET_STRING, 0, 0, 0 },
35092
};
35093
enum {
35094
    OCSPRESPONSEASN_IDX_SEQ = 0,
35095
35096
    OCSPRESPONSEASN_IDX_STATUS,
35097
35098
    OCSPRESPONSEASN_IDX_BYTES,
35099
35100
    OCSPRESPONSEASN_IDX_BYTES_SEQ,
35101
35102
    OCSPRESPONSEASN_IDX_BYTES_TYPE,
35103
35104
    OCSPRESPONSEASN_IDX_BYTES_VAL,
35105
};
35106
35107
/* Number of items in ASN.1 template for OCSPResponse. */
35108
#define ocspResponseASN_Length (sizeof(ocspResponseASN) / sizeof(ASNItem))
35109
#endif /* WOLFSSL_ASN_TEMPLATE */
35110
35111
int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap, int noVerify)
35112
{
35113
#ifndef WOLFSSL_ASN_TEMPLATE
35114
    int ret;
35115
    int length = 0;
35116
    word32 idx = 0;
35117
    byte* source = resp->source;
35118
    word32 size = resp->maxIdx;
35119
    word32 oid;
35120
    byte   tag;
35121
35122
    WOLFSSL_ENTER("OcspResponseDecode");
35123
35124
    /* peel the outer SEQUENCE wrapper */
35125
    if (GetSequence(source, &idx, &length, size) < 0) {
35126
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
35127
        return ASN_PARSE_E;
35128
    }
35129
35130
    /* First get the responseStatus, an ENUMERATED */
35131
    if (GetEnumerated(source, &idx, &resp->responseStatus, size) < 0) {
35132
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
35133
        return ASN_PARSE_E;
35134
    }
35135
35136
    if (resp->responseStatus != OCSP_SUCCESSFUL) {
35137
        WOLFSSL_LEAVE("OcspResponseDecode", 0);
35138
        return 0;
35139
    }
35140
35141
    /* Next is an EXPLICIT record called ResponseBytes, OPTIONAL */
35142
    if (idx >= size) {
35143
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
35144
        return ASN_PARSE_E;
35145
    }
35146
    if (GetASNTag(source, &idx, &tag, size) < 0) {
35147
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
35148
        return ASN_PARSE_E;
35149
    }
35150
    if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
35151
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
35152
        return ASN_PARSE_E;
35153
    }
35154
    if (GetLength(source, &idx, &length, size) < 0) {
35155
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
35156
        return ASN_PARSE_E;
35157
    }
35158
35159
    /* Get the responseBytes SEQUENCE */
35160
    if (GetSequence(source, &idx, &length, size) < 0) {
35161
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
35162
        return ASN_PARSE_E;
35163
    }
35164
35165
    /* Check ObjectID for the resposeBytes */
35166
    if (GetObjectId(source, &idx, &oid, oidOcspType, size) < 0) {
35167
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
35168
        return ASN_PARSE_E;
35169
    }
35170
    if (oid != OCSP_BASIC_OID) {
35171
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
35172
        return ASN_PARSE_E;
35173
    }
35174
    ret = GetOctetString(source, &idx, &length, size);
35175
    if (ret < 0) {
35176
        WOLFSSL_LEAVE("OcspResponseDecode", ret);
35177
        return ret;
35178
    }
35179
35180
    ret = DecodeBasicOcspResponse(source, &idx, resp, size, cm, heap, noVerify);
35181
    if (ret < 0) {
35182
        WOLFSSL_LEAVE("OcspResponseDecode", ret);
35183
        return ret;
35184
    }
35185
35186
    WOLFSSL_LEAVE("OcspResponseDecode", 0);
35187
    return 0;
35188
#else
35189
    DECL_ASNGETDATA(dataASN, ocspResponseASN_Length);
35190
    int ret = 0;
35191
    word32 idx = 0, size = resp->maxIdx;
35192
    byte* source = resp->source;
35193
    byte status;
35194
    byte* basic;
35195
    word32 basicSz;
35196
35197
    WOLFSSL_ENTER("OcspResponseDecode");
35198
35199
    CALLOC_ASNGETDATA(dataASN, ocspResponseASN_Length, ret, resp->heap);
35200
35201
    if (ret == 0) {
35202
        /* Set variable to put status in and expect OCSP OID. */
35203
        GetASN_Int8Bit(&dataASN[OCSPRESPONSEASN_IDX_STATUS], &status);
35204
        GetASN_OID(&dataASN[OCSPRESPONSEASN_IDX_BYTES_TYPE], oidOcspType);
35205
        /* Decode OCSPResponse (and ResponseBytes). */
35206
        ret = GetASN_Items(ocspResponseASN, dataASN, ocspResponseASN_Length, 1,
35207
            source, &idx, size);
35208
    }
35209
    if (ret == 0) {
35210
        /* Get response. */
35211
        resp->responseStatus = status;
35212
        if (dataASN[OCSPRESPONSEASN_IDX_BYTES_TYPE].data.oid.sum
35213
                == OCSP_BASIC_OID) {
35214
            /* Get reference to BasicOCSPResponse. */
35215
            GetASN_GetRef(&dataASN[OCSPRESPONSEASN_IDX_BYTES_VAL], &basic,
35216
                    &basicSz);
35217
            idx = 0;
35218
            /* Decode BasicOCSPResponse. */
35219
            ret = DecodeBasicOcspResponse(basic, &idx, resp, basicSz, cm, heap,
35220
                noVerify);
35221
        }
35222
        /* Only support BasicOCSPResponse. */
35223
        else {
35224
            ret = ASN_PARSE_E;
35225
        }
35226
    }
35227
35228
    FREE_ASNGETDATA(dataASN, resp->heap);
35229
    WOLFSSL_LEAVE("OcspResponseDecode", ret);
35230
    return ret;
35231
#endif /* WOLFSSL_ASN_TEMPLATE */
35232
}
35233
35234
#ifdef WOLFSSL_ASN_TEMPLATE
35235
/* ASN.1 template for OCSP nonce extension.
35236
 * RFC 6960, 4.4.1 - Nonce
35237
 * X.509: RFC 5280, 4.1 - Basic Certificate Fields. (Extension)
35238
 */
35239
static const ASNItem ocspNonceExtASN[] = {
35240
/* SEQ       */ { 0, ASN_SEQUENCE, 1, 1, 0 },
35241
                                     /* Extension */
35242
/* EXT       */     { 1, ASN_SEQUENCE, 1, 1, 0 },
35243
                                        /* extnId */
35244
/* EXT_OID   */        {2, ASN_OBJECT_ID, 0, 0, 0 },
35245
                                        /* critcal not encoded. */
35246
                                        /* extnValue */
35247
/* EXT_VAL   */        {2, ASN_OCTET_STRING, 0, 1, 0 },
35248
                                               /* nonce */
35249
/* EXT_NONCE */            {3, ASN_OCTET_STRING, 0, 0, 0 },
35250
};
35251
enum {
35252
    OCSPNONCEEXTASN_IDX_SEQ = 0,
35253
    OCSPNONCEEXTASN_IDX_EXT,
35254
    OCSPNONCEEXTASN_IDX_EXT_OID,
35255
    OCSPNONCEEXTASN_IDX_EXT_VAL,
35256
    OCSPNONCEEXTASN_IDX_EXT_NONCE,
35257
};
35258
35259
/* Number of items in ASN.1 template for OCSP nonce extension. */
35260
#define ocspNonceExtASN_Length (sizeof(ocspNonceExtASN) / sizeof(ASNItem))
35261
#endif /* WOLFSSL_ASN_TEMPLATE */
35262
35263
word32 EncodeOcspRequestExtensions(OcspRequest* req, byte* output, word32 size)
35264
{
35265
    const byte NonceObjId[] = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
35266
                                       0x30, 0x01, 0x02 };
35267
#ifndef WOLFSSL_ASN_TEMPLATE
35268
    byte seqArray[5][MAX_SEQ_SZ];
35269
    word32 seqSz[5], totalSz = (word32)sizeof(NonceObjId);
35270
35271
    WOLFSSL_ENTER("SetOcspReqExtensions");
35272
35273
    if (!req || !output || !req->nonceSz)
35274
        return 0;
35275
35276
    totalSz += req->nonceSz;
35277
    totalSz += seqSz[0] = SetOctetString(req->nonceSz, seqArray[0]);
35278
    totalSz += seqSz[1] = SetOctetString(req->nonceSz + seqSz[0], seqArray[1]);
35279
    totalSz += seqSz[2] = SetObjectId(sizeof(NonceObjId), seqArray[2]);
35280
    totalSz += seqSz[3] = SetSequence(totalSz, seqArray[3]);
35281
    totalSz += seqSz[4] = SetSequence(totalSz, seqArray[4]);
35282
35283
    if (totalSz > size)
35284
        return 0;
35285
35286
    totalSz = 0;
35287
35288
    XMEMCPY(output + totalSz, seqArray[4], seqSz[4]);
35289
    totalSz += seqSz[4];
35290
35291
    XMEMCPY(output + totalSz, seqArray[3], seqSz[3]);
35292
    totalSz += seqSz[3];
35293
35294
    XMEMCPY(output + totalSz, seqArray[2], seqSz[2]);
35295
    totalSz += seqSz[2];
35296
35297
    XMEMCPY(output + totalSz, NonceObjId, sizeof(NonceObjId));
35298
    totalSz += (word32)sizeof(NonceObjId);
35299
35300
    XMEMCPY(output + totalSz, seqArray[1], seqSz[1]);
35301
    totalSz += seqSz[1];
35302
35303
    XMEMCPY(output + totalSz, seqArray[0], seqSz[0]);
35304
    totalSz += seqSz[0];
35305
35306
    XMEMCPY(output + totalSz, req->nonce, req->nonceSz);
35307
    totalSz += req->nonceSz;
35308
35309
    return totalSz;
35310
#else
35311
    int ret = 0;
35312
35313
    WOLFSSL_ENTER("SetOcspReqExtensions");
35314
35315
    /* Check request has nonce to write in extension. */
35316
    if (req != NULL && req->nonceSz != 0) {
35317
        DECL_ASNSETDATA(dataASN, ocspNonceExtASN_Length);
35318
        int sz;
35319
35320
        CALLOC_ASNSETDATA(dataASN, ocspNonceExtASN_Length, ret, req->heap);
35321
35322
        /* Set nonce extension OID and nonce. */
35323
        SetASN_Buffer(&dataASN[OCSPNONCEEXTASN_IDX_EXT_OID], NonceObjId,
35324
                sizeof(NonceObjId));
35325
        SetASN_Buffer(&dataASN[OCSPNONCEEXTASN_IDX_EXT_NONCE], req->nonce,
35326
                (word32)req->nonceSz);
35327
        /* Calculate size of nonce extension. */
35328
        ret = SizeASN_Items(ocspNonceExtASN, dataASN, ocspNonceExtASN_Length,
35329
                            &sz);
35330
        /* Check buffer big enough for encoding if supplied. */
35331
        if ((ret == 0) && (output != NULL) && (sz > (int)size)) {
35332
            ret = BUFFER_E;
35333
        }
35334
        if ((ret == 0) && (output != NULL)) {
35335
            /* Encode nonce extension. */
35336
            SetASN_Items(ocspNonceExtASN, dataASN, ocspNonceExtASN_Length,
35337
                         output);
35338
        }
35339
        if (ret == 0) {
35340
            /* Return size of encoding. */
35341
            ret = sz;
35342
        }
35343
35344
        FREE_ASNSETDATA(dataASN, req->heap);
35345
    }
35346
35347
    return (word32)ret;
35348
#endif /* WOLFSSL_ASN_TEMPLATE */
35349
}
35350
35351
35352
#ifdef WOLFSSL_ASN_TEMPLATE
35353
/* ASN.1 template for OCSPRequest.
35354
 * RFC 6960, 4.1.1 - ASN.1 Specification of the OCSP Request
35355
 */
35356
static const ASNItem ocspRequestASN[] = {
35357
                                              /* OCSPRequest */
35358
/* SEQ               */    { 0, ASN_SEQUENCE, 1, 1, 0 },
35359
                                                  /* tbsRequest */
35360
/* TBS               */        { 1, ASN_SEQUENCE, 1, 1, 0 },
35361
                                                      /* version not written - v1 */
35362
                                                      /* requestorName not written */
35363
                                                      /* requestList */
35364
/* TBS_SEQ           */            { 2, ASN_SEQUENCE, 1, 1, 0 },
35365
                                                          /* Request */
35366
/* TBS_LIST          */                { 3, ASN_SEQUENCE, 1, 1, 0 },
35367
                                                              /* reqCert */
35368
/* TBS_REQ_CID       */                    { 4, ASN_SEQUENCE, 1, 1, 0 },
35369
                                                                  /* hashAlgorithm */
35370
/* TBS_REQ_HASH      */                        { 5, ASN_SEQUENCE, 1, 1, 0 },
35371
/* TBS_REQ_HASH_OID  */                            { 6, ASN_OBJECT_ID, 0, 0, 0 },
35372
                                                                  /* issuerNameHash */
35373
/* TBS_REQ_ISSUER    */                        { 5, ASN_OCTET_STRING, 0, 0, 0 },
35374
                                                                  /* issuerKeyHash */
35375
/* TBS_REQ_ISSUERKEY */                        { 5, ASN_OCTET_STRING, 0, 0, 0 },
35376
                                                                  /* serialNumber */
35377
/* TBS_REQ_SERIAL    */                        { 5, ASN_INTEGER, 0, 0, 0 },
35378
                                                      /* requestExtensions */
35379
/* TBS_REQEXT        */            { 2, ASN_CONTEXT_SPECIFIC | 2, 1, 0, 0 },
35380
                                                  /* optionalSignature not written. */
35381
};
35382
enum {
35383
    OCSPREQUESTASN_IDX_SEQ = 0,
35384
    OCSPREQUESTASN_IDX_TBS,
35385
    OCSPREQUESTASN_IDX_TBS_SEQ,
35386
    OCSPREQUESTASN_IDX_TBS_LIST,
35387
    OCSPREQUESTASN_IDX_TBS_REQ_CID,
35388
    OCSPREQUESTASN_IDX_TBS_REQ_HASH,
35389
    OCSPREQUESTASN_IDX_TBS_REQ_HASH_OID,
35390
    OCSPREQUESTASN_IDX_TBS_REQ_ISSUER,
35391
    OCSPREQUESTASN_IDX_TBS_REQ_ISSUERKEY,
35392
    OCSPREQUESTASN_IDX_TBS_REQ_SERIAL,
35393
    OCSPREQUESTASN_IDX_TBS_REQEXT,
35394
};
35395
35396
/* Number of items in ASN.1 template for OCSPRequest. */
35397
#define ocspRequestASN_Length (sizeof(ocspRequestASN) / sizeof(ASNItem))
35398
#endif
35399
35400
int EncodeOcspRequest(OcspRequest* req, byte* output, word32 size)
35401
{
35402
#ifndef WOLFSSL_ASN_TEMPLATE
35403
    byte seqArray[5][MAX_SEQ_SZ];
35404
    /* The ASN.1 of the OCSP Request is an onion of sequences */
35405
    byte algoArray[MAX_ALGO_SZ];
35406
    byte issuerArray[MAX_ENCODED_DIG_SZ];
35407
    byte issuerKeyArray[MAX_ENCODED_DIG_SZ];
35408
    byte snArray[MAX_SN_SZ];
35409
    byte extArray[MAX_OCSP_EXT_SZ];
35410
    word32 seqSz[5], algoSz, issuerSz, issuerKeySz, extSz, totalSz;
35411
    int i, snSz;
35412
    int keyIdSz;
35413
35414
    WOLFSSL_ENTER("EncodeOcspRequest");
35415
35416
#ifdef NO_SHA
35417
    algoSz = SetAlgoID(SHA256h, algoArray, oidHashType, 0);
35418
    keyIdSz = WC_SHA256_DIGEST_SIZE;
35419
#else
35420
    algoSz = SetAlgoID(SHAh, algoArray, oidHashType, 0);
35421
    keyIdSz = WC_SHA_DIGEST_SIZE;
35422
#endif
35423
35424
    issuerSz    = SetDigest(req->issuerHash,    keyIdSz,    issuerArray);
35425
    issuerKeySz = SetDigest(req->issuerKeyHash, keyIdSz,    issuerKeyArray);
35426
    snSz        = SetSerialNumber(req->serial,  req->serialSz, snArray,
35427
                                                          MAX_SN_SZ, MAX_SN_SZ);
35428
    extSz       = 0;
35429
35430
    if (snSz < 0)
35431
        return snSz;
35432
35433
    if (req->nonceSz) {
35434
        /* TLS Extensions use this function too - put extensions after
35435
         * ASN.1: Context Specific [2].
35436
         */
35437
        extSz = EncodeOcspRequestExtensions(req, extArray + 2,
35438
                                            OCSP_NONCE_EXT_SZ);
35439
        extSz += SetExplicit(2, extSz, extArray);
35440
    }
35441
35442
    totalSz = algoSz + issuerSz + issuerKeySz + snSz;
35443
    for (i = 4; i >= 0; i--) {
35444
        seqSz[i] = SetSequence(totalSz, seqArray[i]);
35445
        totalSz += seqSz[i];
35446
        if (i == 2) totalSz += extSz;
35447
    }
35448
35449
    if (output == NULL)
35450
        return totalSz;
35451
    if (totalSz > size)
35452
        return BUFFER_E;
35453
35454
    totalSz = 0;
35455
    for (i = 0; i < 5; i++) {
35456
        XMEMCPY(output + totalSz, seqArray[i], seqSz[i]);
35457
        totalSz += seqSz[i];
35458
    }
35459
35460
    XMEMCPY(output + totalSz, algoArray, algoSz);
35461
    totalSz += algoSz;
35462
35463
    XMEMCPY(output + totalSz, issuerArray, issuerSz);
35464
    totalSz += issuerSz;
35465
35466
    XMEMCPY(output + totalSz, issuerKeyArray, issuerKeySz);
35467
    totalSz += issuerKeySz;
35468
35469
    XMEMCPY(output + totalSz, snArray, snSz);
35470
    totalSz += snSz;
35471
35472
    if (extSz != 0) {
35473
        XMEMCPY(output + totalSz, extArray, extSz);
35474
        totalSz += extSz;
35475
    }
35476
35477
    return totalSz;
35478
#else
35479
    DECL_ASNSETDATA(dataASN, ocspRequestASN_Length);
35480
    word32 extSz = 0;
35481
    int sz = 0;
35482
    int ret = 0;
35483
    word32 keyIdSz;
35484
35485
    WOLFSSL_ENTER("EncodeOcspRequest");
35486
35487
    CALLOC_ASNSETDATA(dataASN, ocspRequestASN_Length, ret, req->heap);
35488
35489
    if (ret == 0) {
35490
        /* Set OID of hash algorithm use on issuer and key. */
35491
    #ifdef NO_SHA
35492
        SetASN_OID(&dataASN[OCSPREQUESTASN_IDX_TBS_REQ_HASH_OID], SHA256h,
35493
                oidHashType);
35494
        keyIdSz = WC_SHA256_DIGEST_SIZE;
35495
    #else
35496
        SetASN_OID(&dataASN[OCSPREQUESTASN_IDX_TBS_REQ_HASH_OID], SHAh,
35497
                oidHashType);
35498
        keyIdSz = WC_SHA_DIGEST_SIZE;
35499
    #endif
35500
        /* Set issuer, issuer key hash and serial number of certificate being
35501
         * checked. */
35502
        SetASN_Buffer(&dataASN[OCSPREQUESTASN_IDX_TBS_REQ_ISSUER],
35503
                req->issuerHash, keyIdSz);
35504
        SetASN_Buffer(&dataASN[OCSPREQUESTASN_IDX_TBS_REQ_ISSUERKEY],
35505
                req->issuerKeyHash, keyIdSz);
35506
        SetASN_Buffer(&dataASN[OCSPREQUESTASN_IDX_TBS_REQ_SERIAL],
35507
                req->serial, (word32)req->serialSz);
35508
        /* Only extension to write is nonce - check if one to encode. */
35509
        if (req->nonceSz) {
35510
            /* Get size of extensions and leave space for them in encoding. */
35511
            ret = (int)(extSz = EncodeOcspRequestExtensions(req, NULL, 0));
35512
            SetASN_Buffer(&dataASN[OCSPREQUESTASN_IDX_TBS_REQEXT], NULL, extSz);
35513
            if (ret > 0) {
35514
                ret = 0;
35515
            }
35516
        }
35517
        else {
35518
            /* Don't write out extensions. */
35519
            dataASN[OCSPREQUESTASN_IDX_TBS_REQEXT].noOut = 1;
35520
        }
35521
    }
35522
    if (ret == 0) {
35523
        /* Calculate size of encoding. */
35524
        ret = SizeASN_Items(ocspRequestASN, dataASN, ocspRequestASN_Length,
35525
                &sz);
35526
    }
35527
    /* Check buffer big enough for encoding if supplied. */
35528
    if ((ret == 0) && (output != NULL) && (sz > (int)size)) {
35529
        ret = BUFFER_E;
35530
    }
35531
    if ((ret == 0) && (output != NULL)) {
35532
        /* Encode OCSPRequest. */
35533
        SetASN_Items(ocspRequestASN, dataASN, ocspRequestASN_Length, output);
35534
        if (req->nonceSz) {
35535
            /* Encode extensions into space provided. */
35536
            ret = (int)EncodeOcspRequestExtensions(req,
35537
                (byte*)dataASN[OCSPREQUESTASN_IDX_TBS_REQEXT].data.buffer.data,
35538
                extSz);
35539
            if (ret > 0) {
35540
                ret = 0;
35541
            }
35542
        }
35543
    }
35544
35545
    if (ret == 0) {
35546
        /* Return size of encoding. */
35547
        ret = sz;
35548
    }
35549
35550
    FREE_ASNSETDATA(dataASN, req->heap);
35551
    return ret;
35552
#endif /* WOLFSSL_ASN_TEMPLATE */
35553
}
35554
35555
35556
int InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce,
35557
                                                                     void* heap)
35558
{
35559
    int ret;
35560
35561
    WOLFSSL_ENTER("InitOcspRequest");
35562
35563
    if (req == NULL)
35564
        return BAD_FUNC_ARG;
35565
35566
    XMEMSET(req, 0, sizeof(OcspRequest));
35567
    req->heap = heap;
35568
35569
    if (cert) {
35570
        XMEMCPY(req->issuerHash,    cert->issuerHash,    KEYID_SIZE);
35571
        XMEMCPY(req->issuerKeyHash, cert->issuerKeyHash, KEYID_SIZE);
35572
35573
        req->serial = (byte*)XMALLOC((size_t)cert->serialSz, req->heap,
35574
                                                     DYNAMIC_TYPE_OCSP_REQUEST);
35575
        if (req->serial == NULL)
35576
            return MEMORY_E;
35577
35578
        XMEMCPY(req->serial, cert->serial, (size_t)cert->serialSz);
35579
        req->serialSz = cert->serialSz;
35580
35581
        if (cert->extAuthInfoSz != 0 && cert->extAuthInfo != NULL) {
35582
            req->url = (byte*)XMALLOC((size_t)cert->extAuthInfoSz + 1,
35583
                                          req->heap, DYNAMIC_TYPE_OCSP_REQUEST);
35584
            if (req->url == NULL) {
35585
                XFREE(req->serial, req->heap, DYNAMIC_TYPE_OCSP);
35586
                req->serial = NULL;
35587
                return MEMORY_E;
35588
            }
35589
35590
            XMEMCPY(req->url, cert->extAuthInfo, (size_t)cert->extAuthInfoSz);
35591
            req->urlSz = cert->extAuthInfoSz;
35592
            req->url[req->urlSz] = 0;
35593
        }
35594
    }
35595
35596
    if (useNonce) {
35597
        WC_RNG rng;
35598
35599
    #ifndef HAVE_FIPS
35600
        ret = wc_InitRng_ex(&rng, req->heap, INVALID_DEVID);
35601
    #else
35602
        ret = wc_InitRng(&rng);
35603
    #endif
35604
        if (ret != 0) {
35605
            WOLFSSL_MSG("\tCannot initialize RNG. Skipping the OCSP Nonce.");
35606
        } else {
35607
            if (wc_RNG_GenerateBlock(&rng, req->nonce, MAX_OCSP_NONCE_SZ) != 0)
35608
                WOLFSSL_MSG("\tCannot run RNG. Skipping the OCSP Nonce.");
35609
            else
35610
                req->nonceSz = MAX_OCSP_NONCE_SZ;
35611
35612
            wc_FreeRng(&rng);
35613
        }
35614
    }
35615
35616
    return 0;
35617
}
35618
35619
void FreeOcspRequest(OcspRequest* req)
35620
{
35621
    WOLFSSL_ENTER("FreeOcspRequest");
35622
35623
    if (req) {
35624
        if (req->serial)
35625
            XFREE(req->serial, req->heap, DYNAMIC_TYPE_OCSP_REQUEST);
35626
        req->serial = NULL;
35627
35628
#ifdef OPENSSL_EXTRA
35629
        if (req->serialInt) {
35630
            if (req->serialInt->isDynamic) {
35631
                XFREE(req->serialInt->data, NULL, DYNAMIC_TYPE_OPENSSL);
35632
            }
35633
            XFREE(req->serialInt, NULL, DYNAMIC_TYPE_OPENSSL);
35634
        }
35635
        req->serialInt = NULL;
35636
#endif
35637
35638
        if (req->url)
35639
            XFREE(req->url, req->heap, DYNAMIC_TYPE_OCSP_REQUEST);
35640
        req->url = NULL;
35641
35642
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
35643
    defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_APACHE_HTTPD) || \
35644
    defined(HAVE_LIGHTY)
35645
        if (req->cid != NULL)
35646
            wolfSSL_OCSP_CERTID_free((WOLFSSL_OCSP_CERTID*)req->cid);
35647
        req->cid = NULL;
35648
#endif
35649
    }
35650
}
35651
35652
35653
int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp)
35654
{
35655
    int cmp = -1; /* default as not matching, cmp gets set on each check */
35656
    int ocspDigestSize;
35657
    OcspEntry *single, *next, *prev = NULL, *top;
35658
35659
    WOLFSSL_ENTER("CompareOcspReqResp");
35660
35661
    if (req == NULL) {
35662
        WOLFSSL_MSG("\tReq missing");
35663
        return -1;
35664
    }
35665
    if (resp == NULL || resp->single == NULL) {
35666
        WOLFSSL_MSG("\tResp missing");
35667
        return 1;
35668
    }
35669
35670
    /* Nonces are not critical. The responder may not necessarily add
35671
     * the nonce to the response. */
35672
    if (req->nonceSz && resp->nonce != NULL
35673
#ifndef WOLFSSL_FORCE_OCSP_NONCE_CHECK
35674
            && resp->nonceSz != 0
35675
#endif
35676
    ) {
35677
        cmp = req->nonceSz - resp->nonceSz;
35678
        if (cmp != 0) {
35679
            WOLFSSL_MSG("\tnonceSz mismatch");
35680
            return cmp;
35681
        }
35682
35683
        cmp = XMEMCMP(req->nonce, resp->nonce, (size_t)req->nonceSz);
35684
        if (cmp != 0) {
35685
            WOLFSSL_MSG("\tnonce mismatch");
35686
            return cmp;
35687
        }
35688
    }
35689
35690
    /* match based on found status and return */
35691
    for (single = resp->single; single; single = next) {
35692
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
35693
        ocspDigestSize = wc_HashGetDigestSize(
35694
            wc_OidGetHash(single->hashAlgoOID));
35695
    #else
35696
        ocspDigestSize = OCSP_DIGEST_SIZE;
35697
    #endif
35698
        cmp = req->serialSz - single->status->serialSz;
35699
        if (cmp == 0) {
35700
            cmp = XMEMCMP(req->serial, single->status->serial,
35701
                                                          (size_t)req->serialSz)
35702
               || XMEMCMP(req->issuerHash, single->issuerHash,
35703
                                                         (size_t)ocspDigestSize)
35704
               || XMEMCMP(req->issuerKeyHash, single->issuerKeyHash,
35705
                                                        (size_t)ocspDigestSize);
35706
            if (cmp == 0) {
35707
                /* match found */
35708
                if (resp->single != single && prev) {
35709
                    /* move to top of list */
35710
                    top = resp->single;
35711
                    resp->single = single;
35712
                    prev->next = single->next;
35713
                    single->next = top;
35714
                }
35715
                break;
35716
            }
35717
        }
35718
        next = single->next;
35719
        prev = single;
35720
    }
35721
35722
    if (cmp != 0) {
35723
        WOLFSSL_MSG("\trequest and response mismatch");
35724
        return cmp;
35725
    }
35726
35727
    return 0;
35728
}
35729
35730
#endif /* HAVE_OCSP */
35731
35732
35733
#ifdef WOLFSSL_ASN_TEMPLATE
35734
/* ASN.1 template for certificate name hash. */
35735
static const ASNItem nameHashASN[] = {
35736
/* OID  */ { 0, ASN_OBJECT_ID, 0, 0, 1 },
35737
/* NAME */ { 0, ASN_SEQUENCE, 1, 0, 0 },
35738
};
35739
enum {
35740
    NAMEHASHASN_IDX_OID = 0,
35741
    NAMEHASHASN_IDX_NAME
35742
};
35743
35744
/* Number of items in ASN.1 template for certificate name hash. */
35745
0
#define nameHashASN_Length (sizeof(nameHashASN) / sizeof(ASNItem))
35746
#endif /* WOLFSSL_ASN_TEMPLATE */
35747
35748
/* store WC_SHA hash of NAME */
35749
int GetNameHash(const byte* source, word32* idx, byte* hash, int maxIdx)
35750
0
{
35751
    /* Use summy signature OID. */
35752
0
    return GetNameHash_ex(source, idx, hash, maxIdx, 0);
35753
0
}
35754
35755
/* store WC_SHA hash of NAME */
35756
int GetNameHash_ex(const byte* source, word32* idx, byte* hash, int maxIdx,
35757
    word32 sigOID)
35758
0
{
35759
#ifndef WOLFSSL_ASN_TEMPLATE
35760
    int    length;  /* length of all distinguished names */
35761
    int    ret;
35762
    word32 dummy;
35763
    byte   tag;
35764
35765
    WOLFSSL_ENTER("GetNameHash");
35766
35767
    dummy = *idx;
35768
    if (GetASNTag(source, &dummy, &tag, (word32)maxIdx) == 0 &&
35769
            tag == ASN_OBJECT_ID) {
35770
        WOLFSSL_MSG("Trying optional prefix...");
35771
35772
        if (GetLength(source, idx, &length, (word32)maxIdx) < 0)
35773
            return ASN_PARSE_E;
35774
35775
        *idx += (word32)length;
35776
        WOLFSSL_MSG("Got optional prefix");
35777
    }
35778
35779
    /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
35780
     * calculated over the entire DER encoding of the Name field, including
35781
     * the tag and length. */
35782
    dummy = *idx;
35783
    if (GetSequence(source, idx, &length, (word32)maxIdx) < 0)
35784
        return ASN_PARSE_E;
35785
35786
    ret = CalcHashId_ex(source + dummy, (word32)length + *idx - dummy, hash,
35787
        HashIdAlg(sigOID));
35788
35789
    *idx += (word32)length;
35790
35791
    return ret;
35792
#else
35793
0
    ASNGetData dataASN[nameHashASN_Length];
35794
0
    int ret;
35795
35796
0
    XMEMSET(dataASN, 0, sizeof(dataASN));
35797
    /* Ignore the OID even when present. */
35798
0
    GetASN_OID(&dataASN[NAMEHASHASN_IDX_OID], oidIgnoreType);
35799
    /* Decode certificate name. */
35800
0
    ret = GetASN_Items(nameHashASN, dataASN, nameHashASN_Length, 0, source, idx,
35801
0
           (word32)maxIdx);
35802
0
    if (ret == 0) {
35803
        /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
35804
         * calculated over the entire DER encoding of the Name field, including
35805
         * the tag and length. */
35806
        /* Calculate hash of complete name including SEQUENCE. */
35807
0
        ret = CalcHashId_ex(
35808
0
                GetASNItem_Addr(dataASN[NAMEHASHASN_IDX_NAME], source),
35809
0
                GetASNItem_Length(dataASN[NAMEHASHASN_IDX_NAME], source),
35810
0
                hash, HashIdAlg(sigOID));
35811
0
    }
35812
35813
0
    return ret;
35814
0
#endif /* WOLFSSL_ASN_TEMPLATE */
35815
0
}
35816
35817
#if defined(HAVE_CRL) && !defined(WOLFCRYPT_ONLY)
35818
35819
#ifdef OPENSSL_EXTRA
35820
static char* GetNameFromDer(const byte* source, int sz)
35821
{
35822
    char* out;
35823
35824
    out = (char*)XMALLOC((size_t)sz, NULL, DYNAMIC_TYPE_OPENSSL);
35825
    if (out == NULL) {
35826
        WOLFSSL_MSG("Name malloc failed");
35827
        return NULL;
35828
    }
35829
35830
    XMEMCPY(out, source, (size_t)sz);
35831
35832
    return out;
35833
}
35834
#endif
35835
35836
/* initialize decoded CRL */
35837
void InitDecodedCRL(DecodedCRL* dcrl, void* heap)
35838
{
35839
    WOLFSSL_MSG("InitDecodedCRL");
35840
35841
    XMEMSET(dcrl, 0, sizeof(DecodedCRL));
35842
    dcrl->heap = heap;
35843
#ifdef WOLFSSL_HEAP_TEST
35844
    dcrl->heap = (void*)WOLFSSL_HEAP_TEST;
35845
#endif
35846
}
35847
35848
35849
/* free decoded CRL resources */
35850
void FreeDecodedCRL(DecodedCRL* dcrl)
35851
{
35852
    RevokedCert* tmp = dcrl->certs;
35853
35854
    WOLFSSL_MSG("FreeDecodedCRL");
35855
35856
    while(tmp) {
35857
        RevokedCert* next = tmp->next;
35858
        XFREE(tmp, dcrl->heap, DYNAMIC_TYPE_REVOKED);
35859
        tmp = next;
35860
    }
35861
#ifdef OPENSSL_EXTRA
35862
    if (dcrl->issuer != NULL)
35863
        XFREE(dcrl->issuer, NULL, DYNAMIC_TYPE_OPENSSL);
35864
#endif
35865
}
35866
35867
35868
#ifdef WOLFSSL_ASN_TEMPLATE
35869
/* ASN.1 template for revoked certificates.
35870
 * X.509: RFC 5280, 5.1 - CRL Fields
35871
 */
35872
static const ASNItem revokedASN[] = {
35873
/* SEQ      */    { 0, ASN_SEQUENCE, 1, 1, 0 },
35874
                                     /* userCertificate    CertificateSerialNumber */
35875
/* CERT     */        { 1, ASN_INTEGER, 0, 0, 0 },
35876
                                     /* revocationDate     Time */
35877
/* TIME_UTC */        { 1, ASN_UTC_TIME, 0, 0, 2 },
35878
/* TIME_GT  */        { 1, ASN_GENERALIZED_TIME, 0, 0, 2 },
35879
                                     /* crlEntryExensions  Extensions */
35880
/* TIME_EXT */        { 1, ASN_SEQUENCE, 1, 0, 1 },
35881
};
35882
enum {
35883
    REVOKEDASN_IDX_SEQ = 0,
35884
    REVOKEDASN_IDX_CERT,
35885
    REVOKEDASN_IDX_TIME_UTC,
35886
    REVOKEDASN_IDX_TIME_GT,
35887
    REVOKEDASN_IDX_TIME_EXT,
35888
};
35889
35890
/* Number of items in ASN.1 template for revoked certificates. */
35891
#define revokedASN_Length (sizeof(revokedASN) / sizeof(ASNItem))
35892
#endif
35893
35894
/* Get Revoked Cert list, 0 on success */
35895
static int GetRevoked(RevokedCert* rcert, const byte* buff, word32* idx,
35896
                      DecodedCRL* dcrl, word32 maxIdx)
35897
{
35898
#ifndef WOLFSSL_ASN_TEMPLATE
35899
    int ret;
35900
    int len;
35901
    word32 end;
35902
    RevokedCert* rc;
35903
#ifdef CRL_STATIC_REVOKED_LIST
35904
    int totalCerts = 0;
35905
#endif
35906
    WOLFSSL_ENTER("GetRevoked");
35907
35908
    if (GetSequence(buff, idx, &len, maxIdx) < 0)
35909
        return ASN_PARSE_E;
35910
35911
    end = *idx + len;
35912
35913
#ifdef CRL_STATIC_REVOKED_LIST
35914
    totalCerts = dcrl->totalCerts;
35915
35916
    if (totalCerts >= CRL_MAX_REVOKED_CERTS) {
35917
        return MEMORY_E;
35918
    }
35919
35920
    rc = &rcert[totalCerts];
35921
    ret = wc_GetSerialNumber(buff, idx, rc->serialNumber, &rc->serialSz,maxIdx);
35922
    if (ret < 0) {
35923
        WOLFSSL_MSG("wc_GetSerialNumber error");
35924
        return ret;
35925
    }
35926
#else
35927
35928
    rc = (RevokedCert*)XMALLOC(sizeof(RevokedCert), dcrl->heap,
35929
                                                          DYNAMIC_TYPE_REVOKED);
35930
    if (rc == NULL) {
35931
        WOLFSSL_MSG("Alloc Revoked Cert failed");
35932
        return MEMORY_E;
35933
    }
35934
    ret = wc_GetSerialNumber(buff, idx, rc->serialNumber, &rc->serialSz,maxIdx);
35935
    if (ret < 0) {
35936
        WOLFSSL_MSG("wc_GetSerialNumber error");
35937
        XFREE(rc, dcrl->heap, DYNAMIC_TYPE_REVOKED);
35938
        return ret;
35939
    }
35940
    /* add to list */
35941
    rc->next = dcrl->certs;
35942
    dcrl->certs = rc;
35943
35944
    (void)rcert;
35945
#endif /* CRL_STATIC_REVOKED_LIST */
35946
    dcrl->totalCerts++;
35947
    /* get date */
35948
#ifndef NO_ASN_TIME
35949
    ret = GetBasicDate(buff, idx, rc->revDate, &rc->revDateFormat, maxIdx);
35950
    if (ret < 0) {
35951
        WOLFSSL_MSG("Expecting Date");
35952
        return ret;
35953
    }
35954
#endif
35955
    /* skip extensions */
35956
    *idx = end;
35957
35958
    return 0;
35959
#else
35960
    DECL_ASNGETDATA(dataASN, revokedASN_Length);
35961
    int ret = 0;
35962
    word32 serialSz = EXTERNAL_SERIAL_SIZE;
35963
    word32 revDateSz = MAX_DATE_SIZE;
35964
    RevokedCert* rc;
35965
#ifdef CRL_STATIC_REVOKED_LIST
35966
    int totalCerts = dcrl->totalCerts;
35967
35968
    if (totalCerts >= CRL_MAX_REVOKED_CERTS) {
35969
        return MEMORY_E;
35970
    }
35971
35972
    rc = &rcert[totalCerts];
35973
35974
#else
35975
    /* Allocate a new revoked certificate object. */
35976
    rc = (RevokedCert*)XMALLOC(sizeof(RevokedCert), dcrl->heap,
35977
            DYNAMIC_TYPE_CRL);
35978
    if (rc == NULL) {
35979
        ret = MEMORY_E;
35980
    }
35981
#endif /* CRL_STATIC_REVOKED_LIST */
35982
35983
    CALLOC_ASNGETDATA(dataASN, revokedASN_Length, ret, dcrl->heap);
35984
35985
    if (ret == 0) {
35986
        /* Set buffer to place serial number into. */
35987
        GetASN_Buffer(&dataASN[REVOKEDASN_IDX_CERT], rc->serialNumber,
35988
                &serialSz);
35989
        /* Set buffer to store revocation date. */
35990
        GetASN_Buffer(&dataASN[REVOKEDASN_IDX_TIME_UTC], rc->revDate,
35991
                &revDateSz);
35992
        GetASN_Buffer(&dataASN[REVOKEDASN_IDX_TIME_GT], rc->revDate,
35993
                &revDateSz);
35994
        /* Decode the Revoked */
35995
        ret = GetASN_Items(revokedASN, dataASN, revokedASN_Length, 1, buff, idx,
35996
                maxIdx);
35997
    }
35998
    if (ret == 0) {
35999
        /* Store size of serial number. */
36000
        rc->serialSz = (int)serialSz;
36001
        rc->revDateFormat = (dataASN[REVOKEDASN_IDX_TIME_UTC].tag != 0)
36002
                ? dataASN[REVOKEDASN_IDX_TIME_UTC].tag
36003
                : dataASN[REVOKEDASN_IDX_TIME_GT].tag;
36004
36005
        /* TODO: use extensions, only v2 */
36006
        /* Add revoked certificate to chain. */
36007
#ifndef CRL_STATIC_REVOKED_LIST
36008
        rc->next = dcrl->certs;
36009
        dcrl->certs = rc;
36010
#endif
36011
        dcrl->totalCerts++;
36012
    }
36013
36014
    FREE_ASNGETDATA(dataASN, dcrl->heap);
36015
#ifndef CRL_STATIC_REVOKED_LIST
36016
    if ((ret != 0) && (rc != NULL)) {
36017
        XFREE(rc, dcrl->heap, DYNAMIC_TYPE_CRL);
36018
    }
36019
    (void)rcert;
36020
#endif
36021
    return ret;
36022
#endif /* WOLFSSL_ASN_TEMPLATE */
36023
}
36024
36025
#ifdef WOLFSSL_ASN_TEMPLATE
36026
/* Parse the revoked certificates of a CRL.
36027
 *
36028
 * @param [in] dcrl    Decoded CRL object.
36029
 * @param [in] buff    Buffer holding CRL.
36030
 * @param [in] idx     Index into buffer of revoked certificates.
36031
 * @param [in] maxIdx  Maximum index of revoked cartificates data.
36032
 * @return  0 on success.
36033
 * @return  ASN_PARSE_E on failure.
36034
 */
36035
static int ParseCRL_RevokedCerts(RevokedCert* rcert, DecodedCRL* dcrl,
36036
                                 const byte* buff, word32 idx, word32 maxIdx)
36037
{
36038
    int ret = 0;
36039
36040
    /* Parse each revoked cerificate. */
36041
    while ((ret == 0) && (idx < maxIdx)) {
36042
        /* Parse a revoked certificate. */
36043
        if (GetRevoked(rcert, buff, &idx, dcrl, maxIdx) < 0) {
36044
            ret = ASN_PARSE_E;
36045
        }
36046
    }
36047
36048
    return ret;
36049
}
36050
#endif /* WOLFSSL_ASN_TEMPLATE */
36051
36052
#ifndef WOLFSSL_ASN_TEMPLATE
36053
/* Get CRL Signature, 0 on success */
36054
static int GetCRL_Signature(const byte* source, word32* idx, DecodedCRL* dcrl,
36055
                            int maxIdx)
36056
{
36057
    int    length;
36058
    int    ret;
36059
36060
    WOLFSSL_ENTER("GetCRL_Signature");
36061
36062
    ret = CheckBitString(source, idx, &length, maxIdx, 1, NULL);
36063
    if (ret != 0)
36064
        return ret;
36065
    dcrl->sigLength = length;
36066
36067
    dcrl->signature = (byte*)&source[*idx];
36068
    *idx += dcrl->sigLength;
36069
36070
    return 0;
36071
}
36072
#endif /* !WOLFSSL_ASN_TEMPLATE */
36073
36074
int VerifyCRL_Signature(SignatureCtx* sigCtx, const byte* toBeSigned,
36075
                        word32 tbsSz, const byte* signature, word32 sigSz,
36076
                        word32 signatureOID, Signer *ca, void* heap)
36077
{
36078
    /* try to confirm/verify signature */
36079
#ifndef IGNORE_KEY_EXTENSIONS
36080
    if ((ca->keyUsage & KEYUSE_CRL_SIGN) == 0) {
36081
        WOLFSSL_MSG("CA cannot sign CRLs");
36082
        WOLFSSL_ERROR_VERBOSE(ASN_CRL_NO_SIGNER_E);
36083
        return ASN_CRL_NO_SIGNER_E;
36084
    }
36085
#endif /* IGNORE_KEY_EXTENSIONS */
36086
36087
    InitSignatureCtx(sigCtx, heap, INVALID_DEVID);
36088
    if (ConfirmSignature(sigCtx, toBeSigned, tbsSz, ca->publicKey,
36089
                         ca->pubKeySize, ca->keyOID, signature, sigSz,
36090
                         signatureOID, NULL, 0, NULL) != 0) {
36091
        WOLFSSL_MSG("CRL Confirm signature failed");
36092
        WOLFSSL_ERROR_VERBOSE(ASN_CRL_CONFIRM_E);
36093
        return ASN_CRL_CONFIRM_E;
36094
    }
36095
36096
    return 0;
36097
}
36098
36099
#ifdef WOLFSSL_ASN_TEMPLATE
36100
/* Find the signer for the CRL and verify the signature.
36101
 *
36102
 * @param [in] dcrl  Decoded CRL object.
36103
 * @param [in] buff  Buffer holding CRL.
36104
 * @param [in] cm    Certificate manager object.
36105
 * @return  0 on success.
36106
 * @return  ASN_CRL_NO_SIGNER_E when no signer found.
36107
 * @return  ASN_CRL_CONFIRM_E when signature did not verify.
36108
 */
36109
static int PaseCRL_CheckSignature(DecodedCRL* dcrl, const byte* buff, void* cm)
36110
{
36111
    int ret = 0;
36112
    Signer* ca = NULL;
36113
    SignatureCtx sigCtx;
36114
36115
    /* OpenSSL doesn't add skid by default for CRLs cause firefox chokes.
36116
     * If experiencing issues uncomment NO_SKID define in CRL section of
36117
     * wolfssl/wolfcrypt/settings.h */
36118
#ifndef NO_SKID
36119
    if (dcrl->extAuthKeyIdSet) {
36120
        /* more unique than issuerHash */
36121
        ca = GetCA(cm, dcrl->extAuthKeyId);
36122
    }
36123
    /* Check issuerHash matched CA's subjectNameHash. */
36124
    if ((ca != NULL) && (XMEMCMP(dcrl->issuerHash, ca->subjectNameHash,
36125
            KEYID_SIZE) != 0)) {
36126
        ca = NULL;
36127
    }
36128
    if (ca == NULL) {
36129
        ca = GetCAByName(cm, dcrl->issuerHash); /* last resort */
36130
        /* If AKID is available then this CA doesn't have the public
36131
         * key required */
36132
        if (ca && dcrl->extAuthKeyIdSet) {
36133
            WOLFSSL_MSG("CA SKID doesn't match AKID");
36134
            ca = NULL;
36135
        }
36136
    }
36137
#else
36138
    ca = GetCA(cm, dcrl->issuerHash);
36139
#endif /* !NO_SKID */
36140
    WOLFSSL_MSG("About to verify CRL signature");
36141
36142
    if (ca == NULL) {
36143
        WOLFSSL_MSG("Did NOT find CRL issuer CA");
36144
        ret = ASN_CRL_NO_SIGNER_E;
36145
        WOLFSSL_ERROR_VERBOSE(ret);
36146
    }
36147
36148
    if (ret == 0) {
36149
        WOLFSSL_MSG("Found CRL issuer CA");
36150
        /* Verify CRL signature with CA. */
36151
        ret = VerifyCRL_Signature(&sigCtx, buff + dcrl->certBegin,
36152
           dcrl->sigIndex - dcrl->certBegin, dcrl->signature, dcrl->sigLength,
36153
           dcrl->signatureOID, ca, dcrl->heap);
36154
    }
36155
36156
    return ret;
36157
}
36158
#endif
36159
36160
#ifndef WOLFSSL_ASN_TEMPLATE
36161
static int ParseCRL_CertList(RevokedCert* rcert, DecodedCRL* dcrl,
36162
                           const byte* buf,word32* inOutIdx, int sz, int verify)
36163
{
36164
    word32 oid, dateIdx, idx, checkIdx;
36165
    int length;
36166
#ifdef WOLFSSL_NO_CRL_NEXT_DATE
36167
    int doNextDate = 1;
36168
#endif
36169
    byte tag;
36170
36171
    if (dcrl == NULL || inOutIdx == NULL || buf == NULL) {
36172
        return BAD_FUNC_ARG;
36173
    }
36174
36175
    /* may have version */
36176
    idx = *inOutIdx;
36177
36178
    checkIdx = idx;
36179
    if (GetASNTag(buf, &checkIdx, &tag, sz) == 0 && tag == ASN_INTEGER) {
36180
        if (GetMyVersion(buf, &idx, &dcrl->version, sz) < 0)
36181
            return ASN_PARSE_E;
36182
        dcrl->version++;
36183
    }
36184
36185
    if (GetAlgoId(buf, &idx, &oid, oidIgnoreType, sz) < 0)
36186
        return ASN_PARSE_E;
36187
36188
    checkIdx = idx;
36189
    if (GetSequence(buf, &checkIdx, &length, sz) < 0) {
36190
        return ASN_PARSE_E;
36191
    }
36192
#ifdef OPENSSL_EXTRA
36193
    dcrl->issuerSz = length + (checkIdx - idx);
36194
    dcrl->issuer   = (byte*)GetNameFromDer(buf + idx, (int)dcrl->issuerSz);
36195
#endif
36196
36197
    if (GetNameHash_ex(buf, &idx, dcrl->issuerHash, sz, oid) < 0)
36198
        return ASN_PARSE_E;
36199
36200
    if (GetBasicDate(buf, &idx, dcrl->lastDate, &dcrl->lastDateFormat, sz) < 0)
36201
        return ASN_PARSE_E;
36202
36203
    dateIdx = idx;
36204
36205
    if (GetBasicDate(buf, &idx, dcrl->nextDate, &dcrl->nextDateFormat, sz) < 0)
36206
    {
36207
#ifndef WOLFSSL_NO_CRL_NEXT_DATE
36208
        (void)dateIdx;
36209
        return ASN_PARSE_E;
36210
#else
36211
        dcrl->nextDateFormat = ASN_OTHER_TYPE;  /* skip flag */
36212
        doNextDate = 0;
36213
        idx = dateIdx;
36214
#endif
36215
    }
36216
36217
#ifdef WOLFSSL_NO_CRL_NEXT_DATE
36218
    if (doNextDate)
36219
#endif
36220
    {
36221
#ifndef NO_ASN_TIME
36222
        if (verify != NO_VERIFY &&
36223
                !XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, AFTER)) {
36224
            WOLFSSL_MSG("CRL after date is no longer valid");
36225
            WOLFSSL_ERROR_VERBOSE(CRL_CERT_DATE_ERR);
36226
            return CRL_CERT_DATE_ERR;
36227
        }
36228
#else
36229
        (void)verify;
36230
#endif
36231
    }
36232
36233
    checkIdx = idx;
36234
    if (idx != dcrl->sigIndex &&
36235
           GetASNTag(buf, &checkIdx, &tag, sz) == 0 && tag != CRL_EXTENSIONS) {
36236
36237
        int len;
36238
36239
        if (GetSequence(buf, &idx, &len, sz) < 0)
36240
            return ASN_PARSE_E;
36241
        len += idx;
36242
36243
        while (idx < (word32)len) {
36244
            if (GetRevoked(rcert, buf, &idx, dcrl, len) < 0)
36245
                return ASN_PARSE_E;
36246
        }
36247
    }
36248
36249
    *inOutIdx = idx;
36250
36251
    return 0;
36252
}
36253
#endif /* !WOLFSSL_ASN_TEMPLATE */
36254
36255
36256
#ifndef NO_SKID
36257
static int ParseCRL_AuthKeyIdExt(const byte* input, int sz, DecodedCRL* dcrl)
36258
{
36259
#ifndef WOLFSSL_ASN_TEMPLATE
36260
    word32 idx = 0;
36261
    int length = 0, ret = 0;
36262
    byte tag;
36263
36264
    WOLFSSL_ENTER("ParseCRL_AuthKeyIdExt");
36265
36266
    if (GetSequence(input, &idx, &length, sz) < 0) {
36267
        WOLFSSL_MSG("\tfail: should be a SEQUENCE");
36268
        return ASN_PARSE_E;
36269
    }
36270
36271
    if (GetASNTag(input, &idx, &tag, sz) < 0) {
36272
        return ASN_PARSE_E;
36273
    }
36274
36275
    if (tag != (ASN_CONTEXT_SPECIFIC | 0)) {
36276
        WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available");
36277
        return 0;
36278
    }
36279
36280
    if (GetLength(input, &idx, &length, sz) <= 0) {
36281
        WOLFSSL_MSG("\tfail: extension data length");
36282
        return ASN_PARSE_E;
36283
    }
36284
36285
    dcrl->extAuthKeyIdSet = 1;
36286
    /* Get the hash or hash of the hash if wrong size. */
36287
    ret = GetHashId(input + idx, length, dcrl->extAuthKeyId,
36288
        HashIdAlg(dcrl->signatureOID));
36289
36290
    return ret;
36291
#else
36292
    DECL_ASNGETDATA(dataASN, authKeyIdASN_Length);
36293
    int ret = 0;
36294
    word32 idx = 0;
36295
36296
    WOLFSSL_ENTER("ParseCRL_AuthKeyIdExt");
36297
36298
    CALLOC_ASNGETDATA(dataASN, authKeyIdASN_Length, ret, dcrl->heap);
36299
36300
    if (ret == 0) {
36301
        /* Parse an authority key identifier. */
36302
        ret = GetASN_Items(authKeyIdASN, dataASN, authKeyIdASN_Length, 1, input,
36303
                           &idx, (word32)sz);
36304
    }
36305
    if (ret == 0) {
36306
        /* Key id is optional. */
36307
        if (dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data == NULL) {
36308
            WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available");
36309
        }
36310
        else {
36311
            /* Get the hash or hash of the hash if wrong size. */
36312
            ret = GetHashId(dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data,
36313
                (int)dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.length,
36314
                dcrl->extAuthKeyId, HashIdAlg(dcrl->signatureOID));
36315
        }
36316
    }
36317
36318
    FREE_ASNGETDATA(dataASN, dcrl->heap);
36319
    return ret;
36320
#endif /* WOLFSSL_ASN_TEMPLATE */
36321
}
36322
#endif
36323
36324
36325
#ifndef WOLFSSL_ASN_TEMPLATE
36326
static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf,
36327
        word32* inOutIdx, word32 sz)
36328
{
36329
    int length;
36330
    word32 idx;
36331
    word32 ext_bound; /* boundary index for the sequence of extensions */
36332
    word32 oid;
36333
    byte tag;
36334
36335
    WOLFSSL_ENTER("ParseCRL_Extensions");
36336
    (void)dcrl;
36337
36338
    if (inOutIdx == NULL)
36339
        return BAD_FUNC_ARG;
36340
36341
    idx = *inOutIdx;
36342
36343
    /* CRL Extensions are optional */
36344
    if ((idx + 1) > sz)
36345
        return 0;
36346
36347
    /* CRL Extensions are optional */
36348
    if (GetASNTag(buf, &idx, &tag, sz) < 0)
36349
        return 0;
36350
36351
    /* CRL Extensions are optional */
36352
    if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
36353
        return 0;
36354
36355
    if (GetLength(buf, &idx, &length, sz) < 0)
36356
        return ASN_PARSE_E;
36357
36358
    if (GetSequence(buf, &idx, &length, sz) < 0)
36359
        return ASN_PARSE_E;
36360
36361
    ext_bound = idx + length;
36362
36363
    while (idx < (word32)ext_bound) {
36364
        word32 localIdx;
36365
        int ret;
36366
36367
        if (GetSequence(buf, &idx, &length, sz) < 0) {
36368
            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
36369
            return ASN_PARSE_E;
36370
        }
36371
36372
        oid = 0;
36373
        if (GetObjectId(buf, &idx, &oid, oidCrlExtType, sz) < 0) {
36374
            WOLFSSL_MSG("\tfail: OBJECT ID");
36375
            return ASN_PARSE_E;
36376
        }
36377
36378
        /* check for critical flag */
36379
        if ((idx + 1) > (word32)sz) {
36380
            WOLFSSL_MSG("\tfail: malformed buffer");
36381
            return BUFFER_E;
36382
        }
36383
36384
        localIdx = idx;
36385
        if (GetASNTag(buf, &localIdx, &tag, sz) == 0 && tag == ASN_BOOLEAN) {
36386
            WOLFSSL_MSG("\tfound optional critical flag, moving past");
36387
            ret = GetBoolean(buf, &idx, sz);
36388
            if (ret < 0)
36389
                return ret;
36390
        }
36391
36392
        ret = GetOctetString(buf, &idx, &length, sz);
36393
        if (ret < 0)
36394
            return ret;
36395
36396
        if (oid == AUTH_KEY_OID) {
36397
        #ifndef NO_SKID
36398
            ret = ParseCRL_AuthKeyIdExt(buf + idx, length, dcrl);
36399
            if (ret < 0) {
36400
                WOLFSSL_MSG("\tcouldn't parse AuthKeyId extension");
36401
                return ret;
36402
            }
36403
        #endif
36404
        }
36405
        else if (oid == CRL_NUMBER_OID) {
36406
            localIdx = idx;
36407
            if (GetASNTag(buf, &localIdx, &tag, sz) == 0 &&
36408
                    tag == ASN_INTEGER) {
36409
                ret = GetASNInt(buf, &idx, &length, sz);
36410
                if (ret < 0) {
36411
                    WOLFSSL_MSG("\tcouldn't parse CRL number extension");
36412
                    return ret;
36413
                }
36414
                else {
36415
                    if (length > 1) {
36416
                        int    i;
36417
                    #ifdef WOLFSSL_SMALL_STACK
36418
                        mp_int* m = (mp_int*)XMALLOC(sizeof(*m), NULL,
36419
                                DYNAMIC_TYPE_BIGINT);
36420
                        if (m == NULL) {
36421
                            return MEMORY_E;
36422
                        }
36423
                    #else
36424
                        mp_int m[1];
36425
                    #endif
36426
36427
                        if (mp_init(m) != MP_OKAY) {
36428
                            ret = MP_INIT_E;
36429
                        }
36430
36431
                        if (ret == 0)
36432
                            ret = mp_read_unsigned_bin(m, buf + idx, length);
36433
                        if (ret != MP_OKAY)
36434
                            ret = BUFFER_E;
36435
36436
                        if (ret == 0) {
36437
                            dcrl->crlNumber = 0;
36438
                            for (i = 0; i < (int)(*m).used; ++i) {
36439
                                if (i > (CHAR_BIT *
36440
                                         (int)sizeof(word32) / DIGIT_BIT)) {
36441
                                    break;
36442
                                }
36443
                                dcrl->crlNumber |= ((word32)(*m).dp[i]) <<
36444
                                    (DIGIT_BIT * i);
36445
                            }
36446
                        }
36447
36448
                        mp_free(m);
36449
                    #ifdef WOLFSSL_SMALL_STACK
36450
                        XFREE(m, NULL, DYNAMIC_TYPE_BIGINT);
36451
                    #endif
36452
36453
                        if (ret != 0)
36454
                            return ret;
36455
                    }
36456
                    else if (length == 1) {
36457
                        dcrl->crlNumber = buf[idx];
36458
                    }
36459
                }
36460
            }
36461
        }
36462
36463
        idx += length;
36464
    }
36465
36466
    *inOutIdx = idx;
36467
36468
    return 0;
36469
}
36470
#else
36471
/* Parse the extensions of a CRL.
36472
 *
36473
 * @param [in] dcrl    Decoded CRL object.
36474
 * @param [in] buff    Buffer holding CRL.
36475
 * @param [in] idx     Index into buffer of extensions.
36476
 * @param [in] maxIdx  Maximum index of extension data.
36477
 * @return  0 on success.
36478
 * @return  ASN_PARSE_E on failure.
36479
 */
36480
static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf, word32 idx,
36481
        word32 maxIdx)
36482
{
36483
    DECL_ASNGETDATA(dataASN, certExtASN_Length);
36484
    int ret = 0;
36485
36486
    ALLOC_ASNGETDATA(dataASN, certExtASN_Length, ret, dcrl->heap);
36487
36488
    while ((ret == 0) && (idx < maxIdx)) {
36489
        byte critical = 0;
36490
36491
        /* Clear dynamic data. */
36492
        XMEMSET(dataASN, 0, sizeof(*dataASN) * certExtASN_Length);
36493
        /* Ensure OID is an extention type. */
36494
        GetASN_OID(&dataASN[CERTEXTASN_IDX_OID], oidCertExtType);
36495
        /* Set criticality variable. */
36496
        GetASN_Int8Bit(&dataASN[CERTEXTASN_IDX_CRIT], &critical);
36497
        /* Parse extension wrapper. */
36498
        ret = GetASN_Items(certExtASN, dataASN, certExtASN_Length, 0, buf, &idx,
36499
                maxIdx);
36500
        if (ret == 0) {
36501
            /* OID in extension. */
36502
            word32 oid = dataASN[CERTEXTASN_IDX_OID].data.oid.sum;
36503
            /* Length of extension data. */
36504
            int length = (int)dataASN[CERTEXTASN_IDX_VAL].length;
36505
36506
            if (oid == AUTH_KEY_OID) {
36507
            #ifndef NO_SKID
36508
                /* Parse Authority Key Id extesion.
36509
                 * idx is at start of OCTET_STRING data. */
36510
                ret = ParseCRL_AuthKeyIdExt(buf + idx, length, dcrl);
36511
                if (ret != 0) {
36512
                    WOLFSSL_MSG("\tcouldn't parse AuthKeyId extension");
36513
                }
36514
            #endif
36515
            }
36516
            /* TODO: Parse CRL Number extension */
36517
            /* TODO: check criticality */
36518
            /* Move index on to next extension. */
36519
            idx += (word32)length;
36520
        }
36521
    }
36522
36523
    if (ret < 0) {
36524
        ret = ASN_PARSE_E;
36525
    }
36526
36527
    FREE_ASNGETDATA(dataASN, dcrl->heap);
36528
36529
    return ret;
36530
}
36531
#endif /* !WOLFSSL_ASN_TEMPLATE */
36532
36533
36534
#ifdef WOLFSSL_ASN_TEMPLATE
36535
/* ASN.1 template for a CRL- CertificateList.
36536
 * X.509: RFC 5280, 5.1 - CRL Fields
36537
 */
36538
static const ASNItem crlASN[] = {
36539
                                       /* CertificateList */
36540
/* SEQ                */    { 0, ASN_SEQUENCE, 1, 1, 0 },
36541
                                           /* tbsCertList */
36542
/* TBS                */        { 1, ASN_SEQUENCE, 1, 1, 0 },
36543
                                               /* version     Version OPTIONAL if present must be v2 */
36544
/* TBS_VER            */            { 2, ASN_INTEGER, 0, 0, 1 },
36545
                                               /* signature */
36546
/* TBS_SIGALGO        */            { 2, ASN_SEQUENCE, 1, 1, 0 },
36547
/* TBS_SIGALGO_OID    */                { 3, ASN_OBJECT_ID, 0, 0, 0 },
36548
/* TBS_SIGALGO_NULL   */                { 3, ASN_TAG_NULL, 0, 0, 1 },
36549
                                               /* issuer */
36550
/* TBS_ISSUER         */            { 2, ASN_SEQUENCE, 1, 0, 0 },
36551
                                               /* thisUpdate */
36552
/* TBS_THISUPDATE_UTC */            { 2, ASN_UTC_TIME, 0, 0, 2 },
36553
/* TBS_THISUPDATE_GT  */            { 2, ASN_GENERALIZED_TIME, 0, 0, 2 },
36554
                                               /* nextUpdate */
36555
/* TBS_NEXTUPDATE_UTC */            { 2, ASN_UTC_TIME, 0, 0, 3 },
36556
/* TBS_NEXTUPDATE_GT  */            { 2, ASN_GENERALIZED_TIME, 0, 0, 3 },
36557
                                               /* revokedCertificates */
36558
/* TBS_REVOKEDCERTS   */            { 2, ASN_SEQUENCE, 1, 0, 1 },
36559
                                               /* crlExtensions */
36560
/* TBS_EXT            */            { 2, ASN_CONTEXT_SPECIFIC | 0, 1, 1, 1 },
36561
/* TBS_EXT_SEQ        */                { 3, ASN_SEQUENCE, 1, 0, 0 },
36562
                                           /* signatureAlgorithm */
36563
/* SIGALGO            */        { 1, ASN_SEQUENCE, 1, 1, 0 },
36564
/* SIGALGO_OID        */            { 2, ASN_OBJECT_ID, 0, 0, 0 },
36565
/* SIGALGO_NULL       */            { 2, ASN_TAG_NULL, 0, 0, 1 },
36566
                                           /* signatureValue */
36567
/* SIGNATURE          */        { 1, ASN_BIT_STRING, 0, 0, 0 },
36568
};
36569
enum {
36570
    CRLASN_IDX_SEQ = 0,
36571
    CRLASN_IDX_TBS,
36572
    CRLASN_IDX_TBS_VER,
36573
    CRLASN_IDX_TBS_SIGALGO,
36574
    CRLASN_IDX_TBS_SIGALGO_OID,
36575
    CRLASN_IDX_TBS_SIGALGO_NULL,
36576
    CRLASN_IDX_TBS_ISSUER,
36577
    CRLASN_IDX_TBS_THISUPDATE_UTC,
36578
    CRLASN_IDX_TBS_THISUPDATE_GT,
36579
    CRLASN_IDX_TBS_NEXTUPDATE_UTC,
36580
    CRLASN_IDX_TBS_NEXTUPDATE_GT,
36581
    CRLASN_IDX_TBS_REVOKEDCERTS,
36582
    CRLASN_IDX_TBS_EXT,
36583
    CRLASN_IDX_TBS_EXT_SEQ,
36584
    CRLASN_IDX_SIGALGO,
36585
    CRLASN_IDX_SIGALGO_OID,
36586
    CRLASN_IDX_SIGALGO_NULL,
36587
    CRLASN_IDX_SIGNATURE,
36588
};
36589
36590
/* Number of items in ASN.1 template for a CRL- CertificateList. */
36591
#define crlASN_Length (sizeof(crlASN) / sizeof(ASNItem))
36592
#endif
36593
36594
/* parse crl buffer into decoded state, 0 on success */
36595
int ParseCRL(RevokedCert* rcert, DecodedCRL* dcrl, const byte* buff, word32 sz,
36596
             int verify, void* cm)
36597
{
36598
#ifndef WOLFSSL_ASN_TEMPLATE
36599
    Signer*      ca = NULL;
36600
    SignatureCtx sigCtx;
36601
    int          ret = 0;
36602
    int          len;
36603
    word32       idx = 0;
36604
36605
    WOLFSSL_MSG("ParseCRL");
36606
36607
    /* raw crl hash */
36608
    /* hash here if needed for optimized comparisons
36609
     * wc_Sha sha;
36610
     * wc_InitSha(&sha);
36611
     * wc_ShaUpdate(&sha, buff, sz);
36612
     * wc_ShaFinal(&sha, dcrl->crlHash); */
36613
36614
    if (GetSequence(buff, &idx, &len, sz) < 0)
36615
        return ASN_PARSE_E;
36616
36617
    dcrl->certBegin = idx;
36618
    /* Normalize sz for the length inside the outer sequence. */
36619
    sz = len + idx;
36620
36621
    if (GetSequence(buff, &idx, &len, sz) < 0)
36622
        return ASN_PARSE_E;
36623
    dcrl->sigIndex = len + idx;
36624
36625
    if (ParseCRL_CertList(rcert, dcrl, buff, &idx, dcrl->sigIndex, verify) < 0)
36626
        return ASN_PARSE_E;
36627
36628
    if (ParseCRL_Extensions(dcrl, buff, &idx, dcrl->sigIndex) < 0)
36629
        return ASN_PARSE_E;
36630
36631
    idx = dcrl->sigIndex;
36632
36633
    if (GetAlgoId(buff, &idx, &dcrl->signatureOID, oidSigType, sz) < 0)
36634
        return ASN_PARSE_E;
36635
36636
    if (GetCRL_Signature(buff, &idx, dcrl, sz) < 0)
36637
        return ASN_PARSE_E;
36638
36639
    /* openssl doesn't add skid by default for CRLs cause firefox chokes
36640
       if experiencing issues uncomment NO_SKID define in CRL section of
36641
       wolfssl/wolfcrypt/settings.h */
36642
#ifndef NO_SKID
36643
    if (dcrl->extAuthKeyIdSet) {
36644
        ca = GetCA(cm, dcrl->extAuthKeyId); /* more unique than issuerHash */
36645
    }
36646
    if (ca != NULL && XMEMCMP(dcrl->issuerHash, ca->subjectNameHash,
36647
            KEYID_SIZE) != 0) {
36648
        ca = NULL;
36649
    }
36650
    if (ca == NULL) {
36651
        ca = GetCAByName(cm, dcrl->issuerHash); /* last resort */
36652
        /* If AKID is available then this CA doesn't have the public
36653
         * key required */
36654
        if (ca && dcrl->extAuthKeyIdSet) {
36655
            WOLFSSL_MSG("CA SKID doesn't match AKID");
36656
            ca = NULL;
36657
        }
36658
    }
36659
#else
36660
    ca = GetCA(cm, dcrl->issuerHash);
36661
#endif /* !NO_SKID */
36662
    WOLFSSL_MSG("About to verify CRL signature");
36663
36664
    if (ca == NULL) {
36665
        WOLFSSL_MSG("Did NOT find CRL issuer CA");
36666
        ret = ASN_CRL_NO_SIGNER_E;
36667
        WOLFSSL_ERROR_VERBOSE(ret);
36668
        goto end;
36669
    }
36670
36671
    WOLFSSL_MSG("Found CRL issuer CA");
36672
    ret = VerifyCRL_Signature(&sigCtx, buff + dcrl->certBegin,
36673
           dcrl->sigIndex - dcrl->certBegin, dcrl->signature, dcrl->sigLength,
36674
           dcrl->signatureOID, ca, dcrl->heap);
36675
36676
end:
36677
    return ret;
36678
#else
36679
    DECL_ASNGETDATA(dataASN, crlASN_Length);
36680
    int ret = 0;
36681
    /* Default version - v1 = 0 */
36682
    byte version = 0;
36683
    word32 idx = 0;
36684
    /* Size of buffer for date. */
36685
    word32 lastDateSz = MAX_DATE_SIZE;
36686
    word32 nextDateSz = MAX_DATE_SIZE;
36687
36688
    /* When NO_ASN_TIME is defined, verify not used. */
36689
    (void)verify;
36690
36691
    WOLFSSL_MSG("ParseCRL");
36692
36693
    CALLOC_ASNGETDATA(dataASN, crlASN_Length, ret, dcrl->heap);
36694
36695
    if (ret == 0) {
36696
        /* Set variable to store version. */
36697
        GetASN_Int8Bit(&dataASN[CRLASN_IDX_TBS_VER], &version);
36698
        /* Set expecting signature OID. */
36699
        GetASN_OID(&dataASN[CRLASN_IDX_TBS_SIGALGO_OID], oidSigType);
36700
        /* Set buffer to put last and next date into. */
36701
        GetASN_Buffer(&dataASN[CRLASN_IDX_TBS_THISUPDATE_UTC], dcrl->lastDate,
36702
                &lastDateSz);
36703
        GetASN_Buffer(&dataASN[CRLASN_IDX_TBS_THISUPDATE_GT], dcrl->lastDate,
36704
                &lastDateSz);
36705
        GetASN_Buffer(&dataASN[CRLASN_IDX_TBS_NEXTUPDATE_UTC], dcrl->nextDate,
36706
                &nextDateSz);
36707
        GetASN_Buffer(&dataASN[CRLASN_IDX_TBS_NEXTUPDATE_GT], dcrl->nextDate,
36708
                &nextDateSz);
36709
        /* Set expecting signature OID. */
36710
        GetASN_OID(&dataASN[CRLASN_IDX_SIGALGO_OID], oidSigType);
36711
        /* Decode the CRL. */
36712
        ret = GetASN_Items(crlASN, dataASN, crlASN_Length, 1, buff, &idx, sz);
36713
    }
36714
    /* Version must be v2 = 1 if present. */
36715
    if ((ret == 0) && (dataASN[CRLASN_IDX_TBS_VER].tag != 0) &&
36716
            (version != 1)) {
36717
        ret = ASN_PARSE_E;
36718
    }
36719
    /* Check minimum size of last date. */
36720
    if ((ret == 0) && (lastDateSz < MIN_DATE_SIZE)) {
36721
        ret = ASN_PARSE_E;
36722
    }
36723
    /* Check minimum size of next date. */
36724
    if ((ret == 0) && (nextDateSz < MIN_DATE_SIZE)) {
36725
        ret = ASN_PARSE_E;
36726
    }
36727
    /* 'signatureAlgorithm' OID must be the same as 'signature' OID. */
36728
    if ((ret == 0) && (dataASN[CRLASN_IDX_SIGALGO_OID].data.oid.sum !=
36729
            dataASN[CRLASN_IDX_TBS_SIGALGO_OID].data.oid.sum)) {
36730
        ret = ASN_PARSE_E;
36731
    }
36732
    if (ret == 0) {
36733
        /* Store version */
36734
        dcrl->version = ++version;
36735
        /* Store offset of to be signed part. */
36736
        dcrl->certBegin = dataASN[CRLASN_IDX_TBS].offset;
36737
        /* Store index of signature. */
36738
        dcrl->sigIndex = dataASN[CRLASN_IDX_SIGALGO].offset;
36739
        /* Store address and length of signature data. */
36740
        GetASN_GetRef(&dataASN[CRLASN_IDX_SIGNATURE], &dcrl->signature,
36741
                &dcrl->sigLength);
36742
        /* Get the signature OID. */
36743
        dcrl->signatureOID = dataASN[CRLASN_IDX_SIGALGO_OID].data.oid.sum;
36744
        /* Get the format/tag of the last and next date. */
36745
        dcrl->lastDateFormat = (dataASN[CRLASN_IDX_TBS_THISUPDATE_UTC].tag != 0)
36746
                ? dataASN[CRLASN_IDX_TBS_THISUPDATE_UTC].tag
36747
                : dataASN[CRLASN_IDX_TBS_THISUPDATE_GT].tag;
36748
        dcrl->nextDateFormat = (dataASN[CRLASN_IDX_TBS_NEXTUPDATE_UTC].tag != 0)
36749
                ? dataASN[CRLASN_IDX_TBS_NEXTUPDATE_UTC].tag
36750
                : dataASN[CRLASN_IDX_TBS_NEXTUPDATE_GT].tag;
36751
    #ifndef NO_ASN_TIME
36752
        if (dcrl->nextDateFormat != 0) {
36753
            /* Next date was set, so validate it. */
36754
            if (verify != NO_VERIFY &&
36755
                 !XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, AFTER)) {
36756
                WOLFSSL_MSG("CRL after date is no longer valid");
36757
                ret = CRL_CERT_DATE_ERR;
36758
                WOLFSSL_ERROR_VERBOSE(ret);
36759
            }
36760
        }
36761
    }
36762
    if (ret == 0) {
36763
    #endif
36764
    #ifdef OPENSSL_EXTRA
36765
        /* Parse and store the issuer name. */
36766
        dcrl->issuerSz = GetASNItem_Length(dataASN[CRLASN_IDX_TBS_ISSUER],
36767
                            buff);
36768
        dcrl->issuer   = (byte*)GetNameFromDer((byte*)GetASNItem_Addr(
36769
                            dataASN[CRLASN_IDX_TBS_ISSUER], buff),
36770
                            (int)dcrl->issuerSz);
36771
    #endif
36772
        /* Calculate the Hash id from the issuer name. */
36773
        ret = CalcHashId_ex(
36774
                GetASNItem_Addr(dataASN[CRLASN_IDX_TBS_ISSUER], buff),
36775
                GetASNItem_Length(dataASN[CRLASN_IDX_TBS_ISSUER], buff),
36776
                dcrl->issuerHash, HashIdAlg(dcrl->signatureOID));
36777
        if (ret < 0) {
36778
            ret = ASN_PARSE_E;
36779
        }
36780
    }
36781
36782
    if ((ret == 0) && (dataASN[CRLASN_IDX_TBS_REVOKEDCERTS].tag != 0)) {
36783
        /* Parse revoked cerificates - starting after SEQUENCE OF. */
36784
        ret = ParseCRL_RevokedCerts(rcert, dcrl, buff,
36785
            GetASNItem_DataIdx(dataASN[CRLASN_IDX_TBS_REVOKEDCERTS], buff),
36786
            GetASNItem_EndIdx(dataASN[CRLASN_IDX_TBS_REVOKEDCERTS], buff));
36787
    }
36788
    if (ret == 0) {
36789
        /* Parse the extensions - starting after SEQUENCE OF. */
36790
        ret = ParseCRL_Extensions(dcrl, buff,
36791
            GetASNItem_DataIdx(dataASN[CRLASN_IDX_TBS_EXT_SEQ], buff),
36792
            GetASNItem_EndIdx(dataASN[CRLASN_IDX_TBS_EXT_SEQ], buff));
36793
    }
36794
    if (ret == 0) {
36795
        /* Find signer and verify signature. */
36796
        ret = PaseCRL_CheckSignature(dcrl, buff, cm);
36797
    }
36798
36799
    FREE_ASNGETDATA(dataASN, dcrl->heap);
36800
    return ret;
36801
#endif /* WOLFSSL_ASN_TEMPLATE */
36802
}
36803
36804
#endif /* HAVE_CRL */
36805
36806
36807
36808
#ifdef WOLFSSL_CERT_PIV
36809
36810
#ifdef WOLFSSL_ASN_TEMPLATE
36811
/* Template for PIV. */
36812
static const ASNItem pivASN[] = {
36813
/* CERT        */ { 0, ASN_PIV_CERT, 0, 0, 0 },
36814
/* NONCE       */ { 0, ASN_PIV_NONCE, 0, 0, 1 },
36815
/* SIGNEDNONCE */ { 0, ASN_PIV_SIGNED_NONCE, 0, 0, 1 },
36816
};
36817
enum {
36818
    PIVASN_IDX_CERT = 0,
36819
    PIVASN_IDX_NONCE,
36820
    PIVASN_IDX_SIGNEDNONCE,
36821
};
36822
36823
#define pivASN_Length (sizeof(pivASN) / sizeof(ASNItem))
36824
36825
static const ASNItem pivCertASN[] = {
36826
                          /* 0x53 = 0x40 | 0x13 */
36827
/* CERT */ { 1, ASN_APPLICATION | 0x13, 0, 1, 0 },
36828
                               /* 0x70 = 0x40 | 0x10 + 0x20 (CONSTRUCTED) */
36829
/* X509 */      { 2, ASN_APPLICATION | 0x10, 1, 0, 0 },
36830
                               /* 0x71 = 0x40 | 0x11 + 0x20 (CONSTRUCTED) */
36831
/* INFO */      { 2, ASN_APPLICATION | 0x11, 1, 0, 1 },
36832
                               /* 0xFE = 0xC0 | 0x1E + 0x20 (CONSTRUCTED) */
36833
/* ERR */      { 2, ASN_PRIVATE | 0x1e, 1, 0, 1 },
36834
};
36835
enum {
36836
    PIVCERTASN_IDX_CERT,
36837
    PIVCERTASN_IDX_X509,
36838
    PIVCERTASN_IDX_INFO,
36839
    PIVCERTASN_IDX_ERR,
36840
};
36841
36842
#define pivCertASN_Length (sizeof(pivCertASN) / sizeof(ASNItem))
36843
#endif
36844
36845
int wc_ParseCertPIV(wc_CertPIV* piv, const byte* buf, word32 totalSz)
36846
{
36847
#ifndef WOLFSSL_ASN_TEMPLATE
36848
    int length = 0;
36849
    word32 idx = 0;
36850
36851
    WOLFSSL_ENTER("wc_ParseCertPIV");
36852
36853
    if (piv == NULL || buf == NULL || totalSz == 0)
36854
        return BAD_FUNC_ARG;
36855
36856
    XMEMSET(piv, 0, sizeof(wc_CertPIV));
36857
36858
    /* Detect Identiv PIV (with 0x0A, 0x0B and 0x0C sections) */
36859
    /* Certificate (0A 82 05FA) */
36860
    if (GetASNHeader(buf, ASN_PIV_CERT, &idx, &length, totalSz) >= 0) {
36861
        /* Identiv Type PIV card */
36862
        piv->isIdentiv = 1;
36863
36864
        piv->cert =   &buf[idx];
36865
        piv->certSz = length;
36866
        idx += length;
36867
36868
        /* Nonce (0B 14) */
36869
        if (GetASNHeader(buf, ASN_PIV_NONCE, &idx, &length, totalSz) >= 0) {
36870
            piv->nonce =   &buf[idx];
36871
            piv->nonceSz = length;
36872
            idx += length;
36873
        }
36874
36875
        /* Signed Nonce (0C 82 0100) */
36876
        if (GetASNHeader(buf, ASN_PIV_SIGNED_NONCE, &idx, &length, totalSz) >= 0) {
36877
            piv->signedNonce =   &buf[idx];
36878
            piv->signedNonceSz = length;
36879
        }
36880
36881
        idx = 0;
36882
        buf = piv->cert;
36883
        totalSz = piv->certSz;
36884
    }
36885
36886
    /* Certificate Buffer Total Size (53 82 05F6) */
36887
    if (GetASNHeader(buf, ASN_APPLICATION | ASN_PRINTABLE_STRING, &idx,
36888
                                                   &length, totalSz) < 0) {
36889
        return ASN_PARSE_E;
36890
    }
36891
    /* PIV Certificate (70 82 05ED) */
36892
    if (GetASNHeader(buf, ASN_PIV_TAG_CERT, &idx, &length,
36893
                                                         totalSz) < 0) {
36894
        return ASN_PARSE_E;
36895
    }
36896
36897
    /* Capture certificate buffer pointer and length */
36898
    piv->cert =   &buf[idx];
36899
    piv->certSz = length;
36900
    idx += length;
36901
36902
    /* PIV Certificate Info (71 01 00) */
36903
    if (GetASNHeader(buf, ASN_PIV_TAG_CERT_INFO, &idx, &length,
36904
                                                        totalSz) >= 0) {
36905
        if (length >= 1) {
36906
            piv->compression = (buf[idx] & ASN_PIV_CERT_INFO_COMPRESSED);
36907
            piv->isX509 =      ((buf[idx] & ASN_PIV_CERT_INFO_ISX509) != 0);
36908
        }
36909
        idx += length;
36910
    }
36911
36912
    /* PIV Error Detection (FE 00) */
36913
    if (GetASNHeader(buf, ASN_PIV_TAG_ERR_DET, &idx, &length,
36914
                                                        totalSz) >= 0) {
36915
        piv->certErrDet =   &buf[idx];
36916
        piv->certErrDetSz = length;
36917
        idx += length;
36918
    }
36919
36920
    return 0;
36921
#else
36922
    /* pivCertASN_Length is longer than pivASN_Length */
36923
    DECL_ASNGETDATA(dataASN, pivCertASN_Length);
36924
    int ret = 0;
36925
    word32 idx;
36926
    byte info;
36927
36928
    WOLFSSL_ENTER("wc_ParseCertPIV");
36929
36930
    ALLOC_ASNGETDATA(dataASN, pivCertASN_Length, ret, NULL);
36931
36932
    if (ret == 0) {
36933
        /* Clear dynamic data. */
36934
        XMEMSET(dataASN, 0, sizeof(*dataASN) * pivASN_Length);
36935
        /* Start parsing from start of buffer. */
36936
        idx = 0;
36937
        /* Parse Identiv wrapper. */
36938
        ret = GetASN_Items(pivASN, dataASN, pivASN_Length, 1, buf, &idx,
36939
                totalSz);
36940
        if (ret == 0) {
36941
            /* Identiv wrapper found. */
36942
            piv->isIdentiv = 1;
36943
            /* Get nonce reference. */
36944
            if (dataASN[PIVASN_IDX_NONCE].tag != 0) {
36945
                GetASN_GetConstRef(&dataASN[PIVASN_IDX_NONCE], &piv->nonce,
36946
                        &piv->nonceSz);
36947
            }
36948
            /* Get signedNonce reference. */
36949
            if (dataASN[PIVASN_IDX_SIGNEDNONCE].tag != 0) {
36950
                GetASN_GetConstRef(&dataASN[PIVASN_IDX_SIGNEDNONCE],
36951
                        &piv->signedNonce, &piv->signedNonceSz);
36952
            }
36953
            /* Get the certificate data for parsing. */
36954
            GetASN_GetConstRef(&dataASN[PIVASN_IDX_CERT], &buf, &totalSz);
36955
        }
36956
        ret = 0;
36957
    }
36958
    if (ret == 0) {
36959
        /* Clear dynamic data and set variable to put cert info into. */
36960
        XMEMSET(dataASN, 0, sizeof(*dataASN) * pivCertASN_Length);
36961
        GetASN_Int8Bit(&dataASN[PIVCERTASN_IDX_INFO], &info);
36962
        /* Start parsing from start of buffer. */
36963
        idx = 0;
36964
        /* Parse PIV cetificate data. */
36965
        ret = GetASN_Items(pivCertASN, dataASN, pivCertASN_Length, 1, buf, &idx,
36966
                totalSz);
36967
        if (ret == 0) {
36968
            /* Get X.509 certificate reference. */
36969
            GetASN_GetConstRef(&dataASN[PIVCERTASN_IDX_X509], &piv->cert,
36970
                    &piv->certSz);
36971
            /* Set the certificate info if available. */
36972
            if (dataASN[PIVCERTASN_IDX_INFO].tag != 0) {
36973
                /* Bits 1 and 2 are compression. */
36974
                piv->compression = info & ASN_PIV_CERT_INFO_COMPRESSED;
36975
                /* Bits 3 is X509 flag. */
36976
                piv->isX509 = ((info & ASN_PIV_CERT_INFO_ISX509) != 0);
36977
            }
36978
            /* Get X.509 certificate error detection reference. */
36979
            GetASN_GetConstRef(&dataASN[PIVCERTASN_IDX_ERR], &piv->certErrDet,
36980
                     &piv->certErrDetSz);
36981
        }
36982
        ret = 0;
36983
    }
36984
36985
    FREE_ASNGETDATA(dataASN, NULL);
36986
    return ret;
36987
#endif /* WOLFSSL_ASN_TEMPLATE */
36988
}
36989
36990
#endif /* WOLFSSL_CERT_PIV */
36991
36992
36993
36994
#ifdef HAVE_SMIME
36995
36996
/*****************************************************************************
36997
* wc_MIME_parse_headers - Reads the char array in and parses out MIME headers
36998
* and parameters into headers.  Will continue until in has no more content.
36999
*
37000
* RETURNS:
37001
* returns zero on success, non-zero on error.
37002
*/
37003
int wc_MIME_parse_headers(char* in, int inLen, MimeHdr** headers)
37004
{
37005
    MimeHdr* nextHdr = NULL;
37006
    MimeHdr* curHdr = NULL;
37007
    MimeParam* nextParam = NULL;
37008
    size_t start = 0;
37009
    size_t end = 0;
37010
    char* nameAttr = NULL;
37011
    char* bodyVal = NULL;
37012
    MimeTypes mimeType = MIME_HDR;
37013
    MimeStatus mimeStatus = MIME_NAMEATTR;
37014
    int ret = -1;
37015
    size_t pos = 0;
37016
    size_t lineLen = 0;
37017
    char* curLine = NULL;
37018
    char* ptr = NULL;
37019
37020
    if (in == NULL || inLen <= 0 || in[inLen] != '\0' || headers == NULL) {
37021
        ret = BAD_FUNC_ARG;
37022
        goto error;
37023
    }
37024
    nextHdr = (MimeHdr*)XMALLOC(sizeof(MimeHdr), NULL, DYNAMIC_TYPE_PKCS7);
37025
    if (nextHdr == NULL) {
37026
        ret = MEMORY_E;
37027
        goto error;
37028
    }
37029
    XMEMSET(nextHdr, 0, sizeof(MimeHdr));
37030
    nextParam = (MimeParam*)XMALLOC(sizeof(MimeParam), NULL,
37031
                                    DYNAMIC_TYPE_PKCS7);
37032
    if (nextParam == NULL) {
37033
        ret = MEMORY_E;
37034
        goto error;
37035
    }
37036
    XMEMSET(nextParam, 0, sizeof(MimeParam));
37037
37038
    curLine = XSTRTOK(in, "\r\n", &ptr);
37039
    if (curLine == NULL) {
37040
        ret = ASN_PARSE_E;
37041
        goto error;
37042
    }
37043
37044
    while (curLine != NULL) {
37045
        /* Leftover from previous line, add params to previous header. */
37046
        if (curLine[0] == ' ' && curHdr) {
37047
            mimeType = MIME_PARAM;
37048
        }
37049
        else {
37050
            mimeType = MIME_HDR;
37051
        }
37052
        start = 0;
37053
        lineLen = XSTRLEN(curLine);
37054
        if (lineLen == 0) {
37055
            ret = BAD_FUNC_ARG;
37056
            goto error;
37057
        }
37058
37059
        for (pos = 0; pos < lineLen; pos++) {
37060
            char cur = curLine[pos];
37061
37062
            if (mimeStatus == MIME_NAMEATTR && ((cur == ':' &&
37063
                mimeType == MIME_HDR) || (cur == '=' &&
37064
                mimeType == MIME_PARAM)) && pos >= 1) {
37065
                mimeStatus = MIME_BODYVAL;
37066
                end = pos-1;
37067
                if (nameAttr != NULL)
37068
                    XFREE(nameAttr, NULL, DYNAMIC_TYPE_PKCS7);
37069
                ret = wc_MIME_header_strip(curLine, &nameAttr, start, end);
37070
                if (ret) {
37071
                    goto error;
37072
                }
37073
                start = pos+1;
37074
            }
37075
            else if (mimeStatus == MIME_BODYVAL && cur == ';' && pos >= 1) {
37076
                end = pos-1;
37077
                if (bodyVal != NULL)
37078
                    XFREE(bodyVal, NULL, DYNAMIC_TYPE_PKCS7);
37079
                ret = wc_MIME_header_strip(curLine, &bodyVal, start, end);
37080
                if (ret) {
37081
                    goto error;
37082
                }
37083
                if (mimeType == MIME_HDR) {
37084
                    nextHdr->name = nameAttr;
37085
                    nameAttr = NULL;
37086
                    nextHdr->body = bodyVal;
37087
                    bodyVal = NULL;
37088
                    nextHdr->next = curHdr;
37089
                    curHdr = nextHdr;
37090
                    nextHdr = (MimeHdr*)XMALLOC(sizeof(MimeHdr), NULL,
37091
                                                DYNAMIC_TYPE_PKCS7);
37092
                    if (nextHdr == NULL) {
37093
                        ret = MEMORY_E;
37094
                        goto error;
37095
                    }
37096
                    XMEMSET(nextHdr, 0, sizeof(MimeHdr));
37097
                }
37098
                else {
37099
                    nextParam->attribute = nameAttr;
37100
                    nameAttr = NULL;
37101
                    nextParam->value = bodyVal;
37102
                    bodyVal = NULL;
37103
                    nextParam->next = curHdr->params;
37104
                    curHdr->params = nextParam;
37105
                    nextParam = (MimeParam*)XMALLOC(sizeof(MimeParam), NULL,
37106
                                                    DYNAMIC_TYPE_PKCS7);
37107
                    if (nextParam == NULL) {
37108
                        ret = MEMORY_E;
37109
                        goto error;
37110
                    }
37111
                    XMEMSET(nextParam, 0, sizeof(MimeParam));
37112
                }
37113
                mimeType = MIME_PARAM;
37114
                mimeStatus = MIME_NAMEATTR;
37115
                start = pos+1;
37116
            }
37117
        }
37118
37119
        end = lineLen-1;
37120
        /* Omit newline characters. */
37121
        while ((curLine[end] == '\r' || curLine[end] == '\n') && end > 0) {
37122
            end--;
37123
        }
37124
        if (end >= start && mimeStatus == MIME_BODYVAL) {
37125
            ret = wc_MIME_header_strip(curLine, &bodyVal, start, end);
37126
            if (ret) {
37127
                goto error;
37128
            }
37129
            if (mimeType == MIME_HDR) {
37130
                nextHdr->name = nameAttr;
37131
                nameAttr = NULL;
37132
                nextHdr->body = bodyVal;
37133
                bodyVal = NULL;
37134
                nextHdr->next = curHdr;
37135
                curHdr = nextHdr;
37136
                nextHdr = (MimeHdr*)XMALLOC(sizeof(MimeHdr), NULL,
37137
                                            DYNAMIC_TYPE_PKCS7);
37138
                if (nextHdr == NULL) {
37139
                    ret = MEMORY_E;
37140
                    goto error;
37141
                }
37142
                XMEMSET(nextHdr, 0, sizeof(MimeHdr));
37143
            } else {
37144
                nextParam->attribute = nameAttr;
37145
                nameAttr = NULL;
37146
                nextParam->value = bodyVal;
37147
                bodyVal = NULL;
37148
                nextParam->next = curHdr->params;
37149
                curHdr->params = nextParam;
37150
                nextParam = (MimeParam*)XMALLOC(sizeof(MimeParam), NULL,
37151
                                                DYNAMIC_TYPE_PKCS7);
37152
                if (nextParam == NULL) {
37153
                    ret = MEMORY_E;
37154
                    goto error;
37155
                }
37156
                XMEMSET(nextParam, 0, sizeof(MimeParam));
37157
            }
37158
        }
37159
37160
        curLine = XSTRTOK(NULL, "\r\n", &ptr);
37161
        mimeStatus = MIME_NAMEATTR;
37162
    }
37163
37164
    *headers = curHdr;
37165
    ret = 0; /* success if at this point */
37166
37167
error:
37168
    if (ret != 0)
37169
        wc_MIME_free_hdrs(curHdr);
37170
    wc_MIME_free_hdrs(nextHdr);
37171
    XFREE(nameAttr, NULL, DYNAMIC_TYPE_PKCS7);
37172
    XFREE(bodyVal, NULL, DYNAMIC_TYPE_PKCS7);
37173
    XFREE(nextParam, NULL, DYNAMIC_TYPE_PKCS7);
37174
37175
    return ret;
37176
}
37177
37178
/*****************************************************************************
37179
* wc_MIME_header_strip - Reads the string in from indices start to end, strips
37180
* out disallowed/separator characters and places the rest into *out.
37181
*
37182
* RETURNS:
37183
* returns zero on success, non-zero on error.
37184
*/
37185
int wc_MIME_header_strip(char* in, char** out, size_t start, size_t end)
37186
{
37187
    size_t inPos = start;
37188
    size_t outPos = 0;
37189
    size_t inLen = 0;
37190
37191
    if (end < start || in == NULL || out == NULL) {
37192
        return BAD_FUNC_ARG;
37193
    }
37194
37195
    inLen = XSTRLEN(in);
37196
    if (start > inLen || end > inLen) {
37197
        return BAD_FUNC_ARG;
37198
    }
37199
37200
    *out = (char*)XMALLOC(((end-start)+2)*sizeof(char), NULL,
37201
                          DYNAMIC_TYPE_PKCS7);
37202
    if (*out == NULL) {
37203
        return MEMORY_E;
37204
    }
37205
37206
    while (inPos <= end) {
37207
        if (in[inPos] >= MIME_HEADER_ASCII_MIN && in[inPos] <=
37208
            MIME_HEADER_ASCII_MAX && in[inPos] != ';' && in[inPos] != '\"') {
37209
            (*out)[outPos] = in[inPos];
37210
            outPos++;
37211
        }
37212
        inPos++;
37213
    }
37214
    (*out)[outPos] = '\0';
37215
37216
    return 0;
37217
}
37218
37219
/*****************************************************************************
37220
* wc_MIME_find_header_name - Searches through all given headers until a header with
37221
* a name matching the provided name is found.
37222
*
37223
* RETURNS:
37224
* returns a pointer to the found header, if no match was found, returns NULL.
37225
*/
37226
MimeHdr* wc_MIME_find_header_name(const char* name, MimeHdr* header)
37227
{
37228
    while (header) {
37229
        if (!XSTRCMP(name, header->name)) {
37230
            return header;
37231
        }
37232
        header = header->next;
37233
    }
37234
37235
    return header;
37236
}
37237
37238
/*****************************************************************************
37239
* wc_MIME_find_param_attr - Searches through all parameters until a parameter
37240
* with a attribute matching the provided attribute is found.
37241
*
37242
* RETURNS:
37243
* returns a pointer to the found parameter, if no match was found,
37244
* returns NULL.
37245
*/
37246
MimeParam* wc_MIME_find_param_attr(const char* attribute,
37247
                                    MimeParam* param)
37248
{
37249
    while (param) {
37250
        if (!XSTRCMP(attribute, param->attribute)) {
37251
            return param;
37252
        }
37253
        param = param->next;
37254
    }
37255
37256
    return param;
37257
}
37258
37259
/*****************************************************************************
37260
* wc_MIME_single_canonicalize - Canonicalize a line by converting the trailing
37261
* line ending to CRLF.
37262
*
37263
* line - input line to canonicalize
37264
* len  - length of line in chars on input, length of output array on return
37265
*
37266
* RETURNS:
37267
* returns a pointer to a canonicalized line on success, NULL on error.
37268
*/
37269
char* wc_MIME_single_canonicalize(const char* line, word32* len)
37270
{
37271
    size_t end = 0;
37272
    char* canonLine = NULL;
37273
37274
    if (line == NULL || len == NULL || *len == 0) {
37275
        return NULL;
37276
    }
37277
37278
    end = *len;
37279
    while (end >= 1 && ((line[end-1] == '\r') || (line[end-1] == '\n'))) {
37280
        end--;
37281
    }
37282
37283
    /* Need 2 chars for \r\n and 1 for EOL */
37284
    canonLine = (char*)XMALLOC((end+3)*sizeof(char), NULL, DYNAMIC_TYPE_PKCS7);
37285
    if (canonLine == NULL) {
37286
        return NULL;
37287
    }
37288
37289
    XMEMCPY(canonLine, line, end);
37290
    canonLine[end] = '\r';
37291
    canonLine[end+1] = '\n';
37292
    canonLine[end+2] = '\0';
37293
    *len = (word32)(end + 3);
37294
37295
    return canonLine;
37296
}
37297
37298
/*****************************************************************************
37299
* wc_MIME_free_hdrs - Frees all MIME headers, parameters and strings starting from
37300
* the provided header pointer.
37301
*
37302
* RETURNS:
37303
* returns zero on success, non-zero on error.
37304
*/
37305
int wc_MIME_free_hdrs(MimeHdr* head)
37306
{
37307
    MimeHdr* curHdr = NULL;
37308
    MimeParam* curParam = NULL;
37309
37310
    while (head) {
37311
        while (head->params) {
37312
            curParam = head->params;
37313
            head->params = head->params->next;
37314
            XFREE(curParam->attribute, NULL, DYNAMIC_TYPE_PKCS7);
37315
            XFREE(curParam->value, NULL, DYNAMIC_TYPE_PKCS7);
37316
            XFREE(curParam, NULL, DYNAMIC_TYPE_PKCS7);
37317
        }
37318
        curHdr = head;
37319
        head = head->next;
37320
        XFREE(curHdr->name, NULL, DYNAMIC_TYPE_PKCS7);
37321
        XFREE(curHdr->body, NULL, DYNAMIC_TYPE_PKCS7);
37322
        XFREE(curHdr, NULL, DYNAMIC_TYPE_PKCS7);
37323
    }
37324
37325
    return 0;
37326
}
37327
37328
#endif /* HAVE_SMIME */
37329
37330
37331
#undef ERROR_OUT
37332
37333
37334
#ifdef WOLFSSL_ASN_PRINT
37335
37336
/*******************************************************************************
37337
 * ASN.1 Parsing and Printing Implemenation
37338
 ******************************************************************************/
37339
37340
/* Initialize ASN.1 print options.
37341
 *
37342
 * @param [in, out] opts  ASN.1 options for printing.
37343
 * @return  0 on success.
37344
 * @return  BAD_FUNC_ARG when asn1 is NULL.
37345
 */
37346
int wc_Asn1PrintOptions_Init(Asn1PrintOptions* opts)
37347
0
{
37348
0
    int ret = 0;
37349
37350
0
    if (opts == NULL) {
37351
0
        ret = BAD_FUNC_ARG;
37352
0
    }
37353
0
    else {
37354
0
        XMEMSET(opts, 0, sizeof(*opts));
37355
0
    }
37356
37357
0
    return ret;
37358
0
}
37359
37360
/* Set a print option into Asn1PrintOptions object.
37361
 *
37362
 * @param [in, out] opts  ASN.1 options for printing.
37363
 * @param [in]      opt   Option to set value of.
37364
 * @param [in]      val   Value to set for option.
37365
 * @return  0 on success.
37366
 * @return  BAD_FUNC_ARG when asn1 is NULL.
37367
 * @return  BAD_FUNC_ARG when val is out of range for option.
37368
 */
37369
int wc_Asn1PrintOptions_Set(Asn1PrintOptions* opts, enum Asn1PrintOpt opt,
37370
    word32 val)
37371
0
{
37372
0
    int ret = 0;
37373
37374
    /* Validate parameters. */
37375
0
    if (opts == NULL) {
37376
0
        ret = BAD_FUNC_ARG;
37377
0
    }
37378
37379
0
    if (ret == 0) {
37380
0
        switch (opt) {
37381
        /* Offset into DER/BER data to start decoding from. */
37382
0
        case ASN1_PRINT_OPT_OFFSET:
37383
0
            opts->offset = val;
37384
0
            break;
37385
        /* Length of DER/BER encoding to parse. */
37386
0
        case ASN1_PRINT_OPT_LENGTH:
37387
0
            opts->length = val;
37388
0
            break;
37389
        /* Number of spaces to indent for each change in depth. */
37390
0
        case ASN1_PRINT_OPT_INDENT:
37391
            /* Only 4 bits allowed for value. */
37392
0
            if (val >= (1 << 4)) {
37393
0
                ret = BAD_FUNC_ARG;
37394
0
            }
37395
0
            else {
37396
0
                opts->indent = (word8)val;
37397
0
            }
37398
0
            break;
37399
        /* Draw branches instead of indenting. */
37400
0
        case ASN1_PRINT_OPT_DRAW_BRANCH:
37401
            /* Boolean value. */
37402
0
            opts->draw_branch = (val > 0);
37403
0
            break;
37404
        /* Show raw data of primitive types as octets. */
37405
0
        case ASN1_PRINT_OPT_SHOW_DATA:
37406
            /* Boolean value. */
37407
0
            opts->show_data = (val > 0);
37408
0
            break;
37409
        /* Show header data as octets. */
37410
0
        case ASN1_PRINT_OPT_SHOW_HEADER_DATA:
37411
            /* Boolean value. */
37412
0
            opts->show_header_data = (val > 0);
37413
0
            break;
37414
        /* Show the wolfSSL OID value for OBJECT_ID. */
37415
0
        case ASN1_PRINT_OPT_SHOW_OID:
37416
            /* Boolean value. */
37417
0
            opts->show_oid = (val > 0);
37418
0
            break;
37419
        /* Don't show text representations of primitive types. */
37420
0
        case ASN1_PRINT_OPT_SHOW_NO_TEXT:
37421
            /* Boolean value. */
37422
0
            opts->show_no_text = (val > 0);
37423
0
            break;
37424
        /* Don't show dump text representations of primitive types. */
37425
0
        case ASN1_PRINT_OPT_SHOW_NO_DUMP_TEXT:
37426
            /* Boolean value. */
37427
0
            opts->show_no_dump_text = (val > 0);
37428
0
            break;
37429
0
        }
37430
0
    }
37431
37432
0
    return ret;
37433
0
}
37434
37435
/* Initialize an ASN.1 parse object.
37436
 *
37437
 * @param [in, out] asn1  ASN.1 parse object.
37438
 * @return  0 on success.
37439
 * @return  BAD_FUNC_ARG when asn1 is NULL.
37440
 */
37441
int wc_Asn1_Init(Asn1* asn1)
37442
0
{
37443
0
    int ret = 0;
37444
37445
0
    if (asn1 == NULL) {
37446
0
        ret = BAD_FUNC_ARG;
37447
0
    }
37448
0
    else {
37449
0
        XMEMSET(asn1, 0, sizeof(*asn1));
37450
0
        asn1->file = XBADFILE;
37451
0
    }
37452
37453
0
    return ret;
37454
0
}
37455
37456
/* Set the file to use when printing.
37457
 *
37458
 * @param [in, out] asn1  ASN.1 parse object.
37459
 * @param [in]      file  File to print to.
37460
 * @return  0 on success.
37461
 * @return  BAD_FUNC_ARG when asn1 is NULL.
37462
 * @return  BAD_FUNC_ARG when file is XBADFILE.
37463
 */
37464
int wc_Asn1_SetFile(Asn1* asn1, XFILE file)
37465
0
{
37466
0
    int ret = 0;
37467
37468
0
    if ((asn1 == NULL) || (file == XBADFILE)) {
37469
0
        ret = BAD_FUNC_ARG;
37470
0
    }
37471
0
    else {
37472
0
        asn1->file = file;
37473
0
    }
37474
37475
0
    return ret;
37476
0
}
37477
37478
/* Maximum OID dotted form size. */
37479
0
#define ASN1_OID_DOTTED_MAX_SZ         16
37480
37481
/* Print OID in dotted form or as hex bytes.
37482
 *
37483
 * @param [in]  file        File pointer to write to.
37484
 * @param [in]  oid         OBJECT_ID data.
37485
 * @param [in]  oid_len     Length of OBJECT_ID data.
37486
 */
37487
static void PrintObjectIdNum(XFILE file, unsigned char* oid, word32 len)
37488
0
{
37489
0
    word16 dotted_nums[ASN1_OID_DOTTED_MAX_SZ];
37490
0
    word32 num = ASN1_OID_DOTTED_MAX_SZ;
37491
0
    word32 i;
37492
37493
    /* Decode OBJECT_ID into dotted form array. */
37494
0
    if (DecodeObjectId(oid, len, dotted_nums, &num) == 0) {
37495
        /* Print out each number of dotted form. */
37496
0
        for (i = 0; i < num; i++) {
37497
0
            XFPRINTF(file, "%d", dotted_nums[i]);
37498
            /* Add separetor. */
37499
0
            if (i < num - 1) {
37500
0
                XFPRINTF(file, ".");
37501
0
            }
37502
0
        }
37503
0
    }
37504
0
    else {
37505
        /* Print out bytes as we couldn't decode. */
37506
0
        for (i = 0; i < len; i++) {
37507
0
            XFPRINTF(file, "%02x", oid[i]);
37508
            /* Add separetor. */
37509
0
            if (i < len - 1) {
37510
0
                XFPRINTF(file, ":");
37511
0
            }
37512
0
        }
37513
0
    }
37514
0
}
37515
37516
/* OID value to name mapping. */
37517
typedef struct OidName {
37518
    /* wolfSSL OID value. */
37519
    word32 oid;
37520
    /* Long name to print when OID seen. */
37521
    const char* name;
37522
} OidName;
37523
37524
/* Extra OID to name mappings. */
37525
static const OidName extraOids[] = {
37526
    { 0x005c, "commonName" },
37527
    { 0x005d, "surname" },
37528
    { 0x005e, "serialNumber" },
37529
    { 0x005f, "countryName" },
37530
    { 0x0060, "localityName" },
37531
    { 0x0061, "stateOrProvinceName" },
37532
    { 0x0062, "streetAddress" },
37533
    { 0x0063, "organizationName" },
37534
    { 0x0064, "organizationUnitName" },
37535
    { 0x0065, "title" },
37536
    { 0x0086, "certificateExtension" },
37537
    { 0x028d, "emailAddress" },
37538
    { 0x0293, "challengePassword" },
37539
    { 0x029a, "extensionReq" },
37540
};
37541
/* Length of table of extra OID to name mappings. */
37542
0
#define EXTRA_OIDS_LEN   ((int)(sizeof(extraOids) / sizeof(*extraOids)))
37543
37544
/* Convert OID value to long name.
37545
 *
37546
 * @param [in]  oid   OID value.
37547
 * @param [out] name  Long name for OID when known.
37548
 * @return  1 when OID known.
37549
 * @return  0 when OID not known.
37550
 */
37551
static int Oid2LongName(word32 oid, const char** name)
37552
0
{
37553
0
    int ret = 0;
37554
0
    int i;
37555
37556
    /* Step through each entry in table. */
37557
0
    for (i = 0; i < EXTRA_OIDS_LEN; i++) {
37558
0
        if (extraOids[i].oid == oid) {
37559
            /* Return the name associated with the OID value. */
37560
0
            *name = extraOids[i].name;
37561
0
            ret = 1;
37562
0
            break;
37563
0
        }
37564
0
    }
37565
37566
0
    return ret;
37567
0
}
37568
37569
/* Print the text version of the OBJECT_ID.
37570
 *
37571
 * @param [in] asn1  ASN.1 parse object.
37572
 * @param [in] opts  ASN.1 options for printing.
37573
 */
37574
static void PrintObjectIdText(Asn1* asn1, Asn1PrintOptions* opts)
37575
0
{
37576
0
    word32 oid = (word32)-1;
37577
#if !defined(WOLFCRYPT_ONLY) && defined(OPENSSL_EXTRA)
37578
    int nid;
37579
#endif
37580
0
    const char* ln = NULL;
37581
0
    word32 i = 0;
37582
0
    int known = 1;
37583
37584
    /* Get the OID value for the OBJECT_ID. */
37585
0
    if (GetObjectId(asn1->data + asn1->offset, &i, &oid, oidIgnoreType,
37586
0
            asn1->item.len + 2) == ASN_PARSE_E) {
37587
0
        known = 0;
37588
0
    }
37589
0
    else
37590
#if !defined(WOLFCRYPT_ONLY) && defined(OPENSSL_EXTRA)
37591
    /* Lookup NID for OID value. */
37592
    if ((nid = oid2nid(oid, oidIgnoreType)) != -1) {
37593
        /* Lookup long name for NID. */
37594
        ln = wolfSSL_OBJ_nid2ln(nid);
37595
    }
37596
    else
37597
#endif
37598
    /* Lookup long name for extra known OID values. */
37599
0
    if (!Oid2LongName(oid, &ln)) {
37600
        /* Unknown OID value. */
37601
0
        ln = NULL;
37602
0
        known = 0;
37603
0
    }
37604
37605
0
    XFPRINTF(asn1->file, ":");
37606
    /* Show OID value if not known or asked to. */
37607
0
    if ((!known) || opts->show_oid) {
37608
0
        XFPRINTF(asn1->file, "(0x%x) ", oid);
37609
0
    }
37610
0
    if (ln != NULL) {
37611
        /* Print long name. */
37612
0
        XFPRINTF(asn1->file, "%s", ln);
37613
0
    }
37614
0
    else {
37615
        /* Print out as numbers - either dotted or hex values. */
37616
0
        PrintObjectIdNum(asn1->file, asn1->data + asn1->item.data_idx,
37617
0
            asn1->item.len);
37618
0
    }
37619
0
}
37620
37621
/* Print ASN.1 data as a character string.
37622
 *
37623
 * @param [in] asn1  ASN.1 parse object.
37624
 */
37625
static void PrintText(Asn1* asn1)
37626
0
{
37627
0
    word32 i;
37628
37629
0
    XFPRINTF(asn1->file, ":");
37630
    /* Print all data bytes as characters. */
37631
0
    for (i = 0; i < asn1->item.len; i++) {
37632
0
        XFPRINTF(asn1->file, "%c", asn1->data[asn1->item.data_idx + i]);
37633
0
    }
37634
0
}
37635
37636
/* Print data as a hex bytes.
37637
 *
37638
 * @param [in] file  File pointer to write to.
37639
 * @param [in] data  Data to print.
37640
 * @param [in] len   Number of bytes to print.
37641
 */
37642
static void PrintHex(XFILE file, unsigned char* data, word32 len)
37643
0
{
37644
0
    word32 i;
37645
37646
    /* Print data bytes as hex numbers. */
37647
0
    for (i = 0; i < len; i++) {
37648
0
        XFPRINTF(file, "%02x", data[i]);
37649
0
    }
37650
0
}
37651
37652
/* Print ASN.1 data as a hex bytes.
37653
 *
37654
 * @param [in] asn1  ASN.1 parse object.
37655
 */
37656
static void PrintHexText(Asn1* asn1)
37657
0
{
37658
0
    XFPRINTF(asn1->file, ":");
37659
0
    PrintHex(asn1->file, asn1->data + asn1->item.data_idx, asn1->item.len);
37660
0
}
37661
37662
/* Print ASN.1 BIT_STRING data as hex bytes noting special first byte.
37663
 *
37664
 * @param [in] asn1  ASN.1 parse object.
37665
 */
37666
static void PrintBitStringText(Asn1* asn1)
37667
0
{
37668
0
    if (asn1->item.len > 0) {
37669
0
        XFPRINTF(asn1->file, ":[%02x]", asn1->data[asn1->item.data_idx]);
37670
0
        PrintHex(asn1->file, asn1->data + asn1->item.data_idx + 1,
37671
0
            asn1->item.len - 1);
37672
0
    }
37673
0
}
37674
37675
/* Print ASN.1 BOOLEAN data as text with value.
37676
 *
37677
 * @param [in] asn1  ASN.1 parse object.
37678
 */
37679
static void PrintBooleanText(Asn1* asn1)
37680
0
{
37681
    /* Booleans should be 1 byte of data. */
37682
0
    if (asn1->item.len == 1) {
37683
0
        XFPRINTF(asn1->file, ":%s (%d)",
37684
0
            (asn1->data[asn1->item.data_idx] == 0) ? "FALSE" : "TRUE",
37685
0
            asn1->data[asn1->item.data_idx]);
37686
0
    }
37687
0
}
37688
37689
/* Print ASN.1 data as single byte +/- number.
37690
 *
37691
 * @param [in] asn1  ASN.1 parse object.
37692
 */
37693
static void PrintNumberText(Asn1* asn1)
37694
0
{
37695
    /* Only supporting 1 byte of data for now. */
37696
0
    if (asn1->item.len == 1) {
37697
0
       int num = asn1->data[asn1->item.data_idx];
37698
37699
0
       XFPRINTF(asn1->file, ":%d", num >= 0x80 ? num - 0x100 : num);
37700
0
    }
37701
0
}
37702
37703
/* Print ASN.1 data as a text based on the tag.
37704
 *
37705
 * TODO: handle more tags.
37706
 *
37707
 * @param [in] asn1  ASN.1 parse object.
37708
 * @param [in] opts  ASN.1 options for printing.
37709
 */
37710
static void PrintAsn1Text(Asn1* asn1, Asn1PrintOptions* opts)
37711
0
{
37712
    /* Get the long name for OBJECT_ID where possible. */
37713
0
    if (asn1->item.tag == ASN_OBJECT_ID) {
37714
0
        PrintObjectIdText(asn1, opts);
37715
0
    }
37716
    /* Data is an array of printable characters. */
37717
0
    else if ((asn1->item.tag == ASN_UTF8STRING) ||
37718
0
             (asn1->item.tag == ASN_IA5_STRING) ||
37719
0
             (asn1->item.tag == ASN_PRINTABLE_STRING) ||
37720
0
             (asn1->item.tag == ASN_T61STRING) ||
37721
0
             (asn1->item.tag == ASN_BMPSTRING) ||
37722
0
             (asn1->item.tag == ASN_UTC_TIME) ||
37723
0
             (asn1->item.tag == ASN_GENERALIZED_TIME) ||
37724
0
             (asn1->item.tag == ASN_UNIVERSALSTRING) ||
37725
0
             (asn1->item.tag == ASN_OBJECT_DESC) ||
37726
0
             (asn1->item.tag == ASN_CHARACTER_STRING)) {
37727
0
        PrintText(asn1);
37728
0
    }
37729
    /* Show TRUE and FALSE with number. */
37730
0
    else if (asn1->item.tag == ASN_BOOLEAN) {
37731
0
        PrintBooleanText(asn1);
37732
0
    }
37733
    /* Show number. */
37734
0
    else if (asn1->item.tag == ASN_ENUMERATED) {
37735
0
        PrintNumberText(asn1);
37736
0
    }
37737
    /* Dumping potentially long string of hex digites. */
37738
0
    else if (!opts->show_no_dump_text) {
37739
        /* Dump all bytes. */
37740
0
        if ((asn1->item.tag == ASN_INTEGER) ||
37741
0
            (asn1->item.tag == ASN_OCTET_STRING) ||
37742
0
            ((asn1->item.tag > ASN_APPLICATION) && (asn1->item.cons))) {
37743
0
            PrintHexText(asn1);
37744
0
        }
37745
        /* First byte is number of unused bits in last byte.
37746
         * Print first specially and dump rest of the bytes. */
37747
0
        else if (asn1->item.tag == ASN_BIT_STRING) {
37748
0
            PrintBitStringText(asn1);
37749
0
        }
37750
0
    }
37751
0
}
37752
37753
0
#define HexToChar(n) ((((n) >= 32) && ((n) < 127)) ? (n) : '.')
37754
37755
/* Dump data as hex bytes.
37756
 *
37757
 * @param [in] file  File pointer to write to.
37758
 * @param [in] data  Data to print.
37759
 * @param [in] len   Number of bytes to print.
37760
 */
37761
static void DumpData(XFILE file, unsigned char* data, word32 len)
37762
0
{
37763
0
    word32 i;
37764
0
    word32 j;
37765
37766
0
    for (i = 0; i < len; i += j) {
37767
        /* Print offset. */
37768
0
        XFPRINTF(file, "       %04x:", i);
37769
0
        for (j = 0; (j < 16) && (i + j < len); j++) {
37770
            /* Print byte as hex number. */
37771
0
            XFPRINTF(file, "%s%02x", (j == 8) ? "  " : " ", data[i + j]);
37772
0
        }
37773
        /* Print spaces between hex and characters. */
37774
0
        XFPRINTF(file, "   %*s", (16 - j) * 3 + ((j < 8) ? 1 : 0), "");
37775
0
        for (j = 0; (j < 16) && (i + j < len); j++) {
37776
            /* Print byte as hex number. */
37777
0
            XFPRINTF(file, "%c", HexToChar(data[i + j]));
37778
0
        }
37779
0
        XFPRINTF(file, "\n");
37780
0
    }
37781
0
}
37782
37783
/* Update current depth based on the current position.
37784
 *
37785
 * @param [in, out] asn1  ASN.1 parse object.
37786
 */
37787
static void UpdateDepth(Asn1* asn1)
37788
0
{
37789
    /* If current index is greater than or equal end index then it is done. */
37790
0
    while ((asn1->depth > 0) &&
37791
0
           (asn1->end_idx[asn1->depth-1] <= asn1->curr)) {
37792
        /* Move up a depth. */
37793
0
        asn1->depth--;
37794
0
    }
37795
0
}
37796
37797
/* Check validity of end index of constructed ASN.1 items.
37798
 *
37799
 * @param [in, out] asn1  ASN.1 parse object.
37800
 * @return  0 on success.
37801
 * @return  ASN_DEPTH_E when end offset invalid.
37802
 */
37803
static int CheckDepth(Asn1* asn1)
37804
0
{
37805
0
    int ret = 0;
37806
0
    int i;
37807
0
    word32 curr_end = asn1->curr + asn1->item.len;
37808
37809
0
    for (i = 0; (ret == 0) && (i < asn1->depth); i++) {
37810
        /* Each end index must be at least as large as the current one. */
37811
0
        if (asn1->end_idx[i] < asn1->end_idx[asn1->depth]) {
37812
0
            ret = ASN_DEPTH_E;
37813
0
        }
37814
        /* Each end index must be at least as large as current index. */
37815
0
        if (asn1->end_idx[i] < curr_end) {
37816
0
            ret = ASN_DEPTH_E;
37817
0
        }
37818
0
    }
37819
37820
0
    return ret;
37821
0
}
37822
37823
/* Draw branching based on depth for an ASN.1 item.
37824
 *
37825
 * @param [in] asn1  ASN.1 parse object.
37826
 */
37827
static void DrawBranch(Asn1* asn1)
37828
0
{
37829
0
    int i;
37830
0
    word32 end = asn1->curr + asn1->item.len;
37831
37832
    /* Write out the character for all depths but current. */
37833
0
    for (i = 0; i < asn1->depth; i++) {
37834
0
        if (asn1->item.cons || (end < asn1->end_idx[i])) {
37835
0
            if (i < asn1->depth - 1) {
37836
                /* Constructed or not end index and not current depth: | */
37837
0
                XFPRINTF(asn1->file, "\xe2\x94\x82");
37838
0
            }
37839
0
            else {
37840
                /* Constructed or not end index and current depth: |- */
37841
0
                XFPRINTF(asn1->file, "\xe2\x94\x9c");
37842
0
            }
37843
0
        }
37844
0
        else if ((i > 1) && (end >= asn1->end_idx[i-1])) {
37845
            /* End index for previous: _|_ (in top half) */
37846
0
            XFPRINTF(asn1->file, "\xe2\x94\xb4");
37847
0
        }
37848
0
        else {
37849
            /* End index but not for previous: L (in top half) */
37850
0
            XFPRINTF(asn1->file, "\xe2\x94\x94");
37851
0
        }
37852
0
    }
37853
    /* Prefix to tag name. */
37854
0
    if (asn1->item.cons) {
37855
0
        if (asn1->depth > 0) {
37856
            /* Have other line to connect to: T (in bottom half) */
37857
0
            XFPRINTF(asn1->file, "\xe2\x94\xac");
37858
0
        }
37859
0
        else {
37860
            /* Have no other line to connect to: r */
37861
0
            XFPRINTF(asn1->file, "\xe2\x94\x8c");
37862
0
        }
37863
0
    }
37864
0
    else {
37865
        /* In a sequence: - */
37866
0
        XFPRINTF(asn1->file, "\xe2\x94\x80");
37867
0
    }
37868
0
}
37869
37870
/* Print data as hex bytes separated by space.
37871
 *
37872
 * @param [in] file  File pointer to write to.
37873
 * @param [in] data  Data to print.
37874
 * @param [in] len   Number of bytes to print.
37875
 */
37876
static void PrintHexBytes(XFILE file, unsigned char* data, word32 len)
37877
0
{
37878
0
    word32 i;
37879
37880
0
    for (i = 0; i < len; i++) {
37881
0
        XFPRINTF(file, " %02x", data[i]);
37882
0
    }
37883
0
}
37884
37885
/* Dump header data.
37886
 *
37887
 * @param [in] asn1  ASN.1 parse object.
37888
 * @param [in] opts  ASN.1 options for printing.
37889
 */
37890
static void DumpHeader(Asn1* asn1, Asn1PrintOptions* opts)
37891
0
{
37892
    /* Put on same line when not showing data too and not showing text data. */
37893
0
    if ((!opts->show_data) && opts->show_no_text) {
37894
0
        XFPRINTF(asn1->file, "%10s", "");
37895
0
    }
37896
0
    else {
37897
        /* Align with start of data. */
37898
0
        XFPRINTF(asn1->file, "\n%12s", "");
37899
0
    }
37900
0
    XFPRINTF(asn1->file, " %02x", asn1->item.tag);
37901
0
    if (asn1->curr >= asn1->offset + 1) {
37902
        /* Print the header bytes as hex bytes separated by a space. */
37903
0
        PrintHexBytes(asn1->file, asn1->data + asn1->offset + 1,
37904
0
            asn1->curr - (asn1->offset + 1));
37905
0
    }
37906
0
}
37907
37908
/* Print ASN.1 item info based on header and indeces.
37909
 *
37910
 * @param [in] asn1  ASN.1 parse object.
37911
 * @param [in] opts  ASN.1 options for printing.
37912
 */
37913
static void PrintInfo(Asn1* asn1, Asn1PrintOptions* opts)
37914
0
{
37915
    /* Print offset of this ASN.1 item. */
37916
0
    XFPRINTF(asn1->file, "%4d: ", asn1->offset);
37917
    /* Print length of header. */
37918
0
    XFPRINTF(asn1->file, "%1d ", asn1->curr - asn1->offset);
37919
    /* Print data length. */
37920
0
    XFPRINTF(asn1->file, "%c%4d%c", asn1->item.cons ? '[' : '+', asn1->item.len,
37921
0
                      asn1->item.cons ? ']' : ' ');
37922
    /* Print depth. */
37923
0
    XFPRINTF(asn1->file, " %s(%d)", (asn1->depth < 10) ? " " : "", asn1->depth);
37924
0
    if (!opts->draw_branch) {
37925
        /* Indent to depth as required. */
37926
0
        XFPRINTF(asn1->file, "%*s ", asn1->depth * opts->indent, "");
37927
0
        if (!opts->indent) {
37928
            /* Indicate constructed if no indent. */
37929
0
            XFPRINTF(asn1->file, "%c", asn1->item.cons ? '+' : ' ');
37930
0
        }
37931
0
    }
37932
0
    else {
37933
        /* Draw branch structure for ASN.1 item. */
37934
0
        XFPRINTF(asn1->file, " ");
37935
0
        DrawBranch(asn1);
37936
0
    }
37937
    /* Print tag name. */
37938
0
    XFPRINTF(asn1->file, "%-16s", TagString(asn1->item.tag));
37939
0
}
37940
37941
/* Expecting tag part of ASN.1 item. */
37942
0
#define ASN_PART_TAG        0
37943
/* Expecting length part of ASN.1 item. */
37944
0
#define ASN_PART_LENGTH     1
37945
/* Expecting data part of ASN.1 item. */
37946
0
#define ASN_PART_DATA       2
37947
37948
/* Print next ASN.1 item.
37949
 *
37950
 * @param [in, out] asn1  ASN.1 parse object.
37951
 * @param [in]      opts  ASN.1 print options.
37952
 * @return  0 on success.
37953
 * @return  BAD_FUNC_ARG when asn1 or opts is NULL.
37954
 * @return  ASN_LEN_E when ASN.1 item's length too long.
37955
 * @return  ASN_DEPTH_E when end offset invalid.
37956
 */
37957
static int wc_Asn1_Print(Asn1* asn1, Asn1PrintOptions* opts)
37958
0
{
37959
0
    int ret = 0;
37960
37961
    /* Process tag. */
37962
0
    if (asn1->part == ASN_PART_TAG) {
37963
        /* Recalculate which depth we are at. */
37964
0
        UpdateDepth(asn1);
37965
        /* Get tag. */
37966
0
        asn1->item.tag = asn1->data[asn1->curr] & (byte)~ASN_CONSTRUCTED;
37967
        /* Store whether tag indicates constructed. */
37968
0
        asn1->item.cons = (asn1->data[asn1->curr] & ASN_CONSTRUCTED) ==
37969
0
                     ASN_CONSTRUCTED;
37970
        /* Start of ASN.1 item is current index. */
37971
0
        asn1->offset = asn1->curr;
37972
        /* Step over tag. */
37973
0
        asn1->curr++;
37974
        /* Next part is length. */
37975
0
        asn1->part = ASN_PART_LENGTH;
37976
0
    }
37977
    /* Process length. */
37978
0
    if (asn1->part == ASN_PART_LENGTH) {
37979
0
        int len;
37980
37981
        /* Decode length and step over it. */
37982
0
        if (GetLength(asn1->data, &asn1->curr, &len, asn1->max) < 0) {
37983
0
            ret = ASN_LEN_E;
37984
0
        }
37985
0
        else {
37986
            /* Store ASN.1 item data offset. */
37987
0
            asn1->item.data_idx = asn1->curr;
37988
            /* Store ASN.1 item data length. */
37989
0
            asn1->item.len = (word32)len;
37990
37991
            /* Print info about ASN.1 item. */
37992
0
            PrintInfo(asn1, opts);
37993
37994
0
            if (!asn1->item.cons) {
37995
                /* Move on to print data. */
37996
0
                asn1->part = ASN_PART_DATA;
37997
0
            }
37998
0
            else {
37999
                /* Print header now if not printing data. */
38000
0
                if (opts->show_header_data) {
38001
0
                    DumpHeader(asn1, opts);
38002
0
                }
38003
0
                XFPRINTF(asn1->file, "\n");
38004
                /* Record end offset for this depth. */
38005
0
                asn1->end_idx[asn1->depth++] = asn1->curr + asn1->item.len;
38006
                /* Done with this ASN.1 item. */
38007
0
                asn1->part = ASN_PART_TAG;
38008
0
            }
38009
            /* Check end indeces are valid. */
38010
0
            ret = CheckDepth(asn1);
38011
0
        }
38012
0
    }
38013
    /* Process data. */
38014
0
    if ((ret == 0) && (asn1->part == ASN_PART_DATA)) {
38015
0
        if (!opts->show_no_text) {
38016
            /* Print text representation of data. */
38017
0
            PrintAsn1Text(asn1, opts);
38018
0
        }
38019
0
        if (opts->show_header_data) {
38020
            /* Dump header bytes. */
38021
0
            DumpHeader(asn1, opts);
38022
0
        }
38023
0
        XFPRINTF(asn1->file, "\n");
38024
0
        if (opts->show_data) {
38025
            /* Dump data bytes. */
38026
0
            DumpData(asn1->file, asn1->data + asn1->item.data_idx,
38027
0
                asn1->item.len);
38028
0
        }
38029
        /* Step past data to next ASN.1 item. */
38030
0
        asn1->curr += asn1->item.len;
38031
        /* Update the depth based on end indeces. */
38032
0
        UpdateDepth(asn1);
38033
        /* Done with this ASN.1 item. */
38034
0
        asn1->part = ASN_PART_TAG;
38035
0
    }
38036
38037
    /* Make ASN.1 item printing go out. */
38038
0
    fflush(asn1->file);
38039
38040
0
    return ret;
38041
0
}
38042
38043
/* Print all ASN.1 items.
38044
 *
38045
 * @param [in, out] asn1  ASN.1 parse object.
38046
 * @param [in]      opts  ASN.1 print options.
38047
 * @param [in]      data  BER/DER data to print.
38048
 * @param [in]      len   Length of data to print in bytes.
38049
 * @return  0 on success.
38050
 * @return  BAD_FUNC_ARG when asn1, opts or data is NULL.
38051
 * @return  ASN_LEN_E when ASN.1 item's length too long.
38052
 * @return  ASN_DEPTH_E when end offset invalid.
38053
 * @return  ASN_PARSE_E when not all of an ASN.1 item parsed.
38054
 */
38055
int wc_Asn1_PrintAll(Asn1* asn1, Asn1PrintOptions* opts, unsigned char* data,
38056
    word32 len)
38057
0
{
38058
0
    int ret = 0;
38059
38060
0
    if ((asn1 == NULL) || (opts == NULL) || (data == NULL)) {
38061
0
        ret = BAD_FUNC_ARG;
38062
0
    }
38063
38064
0
    if (ret == 0) {
38065
        /* Initialize start position. */
38066
0
        asn1->curr = 0;
38067
        /* Start parsing at tag. */
38068
0
        asn1->part = ASN_PART_TAG;
38069
        /* Start depth at 0. */
38070
0
        asn1->depth = 0;
38071
38072
        /* Store the starting point of the data to parse. */
38073
0
        asn1->data = data + opts->offset;
38074
0
        if (opts->length > 0) {
38075
            /* Use user specified maximum length. */
38076
0
            asn1->max = opts->length;
38077
0
        }
38078
0
        else {
38079
            /* Maximum length is up to end from offset. */
38080
0
            asn1->max = len - opts->offset;
38081
0
        }
38082
38083
        /* Keep going while no error and have data to parse. */
38084
0
        while ((ret == 0) && (asn1->curr < asn1->max)) {
38085
            /* Print an ASN.1 item. */
38086
0
            ret = wc_Asn1_Print(asn1, opts);
38087
0
        }
38088
0
    }
38089
0
    if ((ret == 0) && (asn1->part != ASN_PART_TAG)) {
38090
        /* Stopped before finishing ASN.1 item. */
38091
0
        ret = ASN_PARSE_E;
38092
0
    }
38093
0
    if ((ret == 0) && (asn1->depth != 0)) {
38094
        /* Stopped without seeing all items in a constructed item. */
38095
0
        ret = ASN_DEPTH_E;
38096
0
    }
38097
38098
0
    return ret;
38099
0
}
38100
38101
#endif /* WOLFSSL_ASN_PRINT */
38102
#endif /* !NO_ASN */
38103
38104
/* Functions that parse, but are not using ASN.1 */
38105
#if !defined(NO_RSA) && !defined(HAVE_USER_RSA) && \
38106
    (!defined(NO_BIG_INT) || defined(WOLFSSL_SP_MATH))
38107
/* import RSA public key elements (n, e) into RsaKey structure (key) */
38108
/* this function does not use any ASN.1 parsing */
38109
int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e,
38110
                             word32 eSz, RsaKey* key)
38111
0
{
38112
0
    if (n == NULL || e == NULL || key == NULL)
38113
0
        return BAD_FUNC_ARG;
38114
38115
0
    key->type = RSA_PUBLIC;
38116
38117
0
    if (mp_init(&key->n) != MP_OKAY)
38118
0
        return MP_INIT_E;
38119
38120
0
    if (mp_read_unsigned_bin(&key->n, n, nSz) != 0) {
38121
0
        mp_clear(&key->n);
38122
0
        return ASN_GETINT_E;
38123
0
    }
38124
#ifdef HAVE_WOLF_BIGINT
38125
    if ((int)nSz > 0 && wc_bigint_from_unsigned_bin(&key->n.raw, n, nSz) != 0) {
38126
        mp_clear(&key->n);
38127
        return ASN_GETINT_E;
38128
    }
38129
#endif /* HAVE_WOLF_BIGINT */
38130
38131
0
    if (mp_init(&key->e) != MP_OKAY) {
38132
0
        mp_clear(&key->n);
38133
0
        return MP_INIT_E;
38134
0
    }
38135
38136
0
    if (mp_read_unsigned_bin(&key->e, e, eSz) != 0) {
38137
0
        mp_clear(&key->n);
38138
0
        mp_clear(&key->e);
38139
0
        return ASN_GETINT_E;
38140
0
    }
38141
#ifdef HAVE_WOLF_BIGINT
38142
    if ((int)eSz > 0 && wc_bigint_from_unsigned_bin(&key->e.raw, e, eSz) != 0) {
38143
        mp_clear(&key->n);
38144
        mp_clear(&key->e);
38145
        return ASN_GETINT_E;
38146
    }
38147
#endif /* HAVE_WOLF_BIGINT */
38148
38149
#ifdef WOLFSSL_XILINX_CRYPT
38150
    if (wc_InitRsaHw(key) != 0) {
38151
        return BAD_STATE_E;
38152
    }
38153
#endif
38154
38155
0
    return 0;
38156
0
}
38157
#endif /* !NO_RSA && !HAVE_USER_RSA && (!NO_BIG_INT || WOLFSSL_SP_MATH) */
38158
38159
38160
#ifdef WOLFSSL_SEP
38161
38162
38163
#endif /* WOLFSSL_SEP */