Coverage Report

Created: 2025-07-23 06:53

/src/wolfssl/wolfcrypt/src/asn.c
Line
Count
Source (jump to first uncovered line)
1
/* asn.c
2
 *
3
 * Copyright (C) 2006-2025 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
/*
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
38
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
39
40
/*
41
ASN Options:
42
 * NO_ASN_TIME_CHECK: Disables ASN time checks (avoiding the ASN_BEFORE_DATE_E
43
 * and ASN_AFTER_DATE_E errors). Safer ways to avoid date errors would be to
44
 * set the WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY flag when calling the _ex versions of
45
 * cert loading functions or to define the WOLFSSL_NO_OCSP_DATE_CHECK macro to
46
 * skip OCSP date errors. Defining NO_ASN_TIME_CHECK will skip ALL date checks
47
 * and could pose a security risk.
48
 * NO_ASN_TIME: Disables time parts of the ASN code for systems without an RTC
49
    or wishing to save space.
50
 * IGNORE_NAME_CONSTRAINTS: Skip ASN name checks.
51
 * ASN_DUMP_OID: Allows dump of OID information for debugging.
52
 * RSA_DECODE_EXTRA: Decodes extra information in RSA public key.
53
 * WOLFSSL_CERT_GEN: Cert generation. Saves extra certificate info in GetName.
54
 * WOLFSSL_NO_ASN_STRICT: Disable strict RFC compliance checks to
55
    restore 3.13.0 behavior.
56
 * WOLFSSL_ASN_ALLOW_0_SERIAL: Even if WOLFSSL_NO_ASN_STRICT is not defined,
57
    allow a length=1, but zero value serial number.
58
 * WOLFSSL_NO_OCSP_OPTIONAL_CERTS: Skip optional OCSP certs (responder issuer
59
    must still be trusted)
60
 * WOLFSSL_NO_TRUSTED_CERTS_VERIFY: Workaround for situation where entire cert
61
    chain is not loaded. This only matches on subject and public key and
62
    does not perform a PKI validation, so it is not a secure solution.
63
    Only enabled for OCSP.
64
 * WOLFSSL_NO_OCSP_ISSUER_CHECK: Can be defined for backwards compatibility to
65
    disable checking of https://www.rfc-editor.org/rfc/rfc6960#section-4.2.2.2.
66
 * WOLFSSL_SMALL_CERT_VERIFY: Verify the certificate signature without using
67
    DecodedCert. Doubles up on some code but allows smaller dynamic memory
68
    usage.
69
 * WOLFSSL_NO_OCSP_DATE_CHECK: Disable date checks for OCSP responses. This
70
    may be required when the system's real-time clock is not very accurate.
71
    It is recommended to enforce the nonce check instead if possible.
72
 * WOLFSSL_NO_CRL_DATE_CHECK: Disable date checks for CRL's.
73
 * WOLFSSL_NO_CRL_NEXT_DATE: Do not fail if CRL next date is missing
74
 * WOLFSSL_FORCE_OCSP_NONCE_CHECK: Require nonces to be available in OCSP
75
    responses. The nonces are optional and may not be supported by all
76
    responders. If it can be ensured that the used responder sends nonces this
77
    option may improve security.
78
 * WOLFSSL_ASN_TEMPLATE: Encoding and decoding using a template.
79
 * WOLFSSL_DEBUG_ASN_TEMPLATE: Enables debugging output when using ASN.1
80
    templates.
81
 * WOLFSSL_ASN_TEMPLATE_TYPE_CHECK: Use ASN functions to better test compiler
82
    type issues for testing
83
 * CRLDP_VALIDATE_DATA: For ASN template only, validates the reason data
84
 * WOLFSSL_AKID_NAME: Enable support for full AuthorityKeyIdentifier extension.
85
    Only supports copying full AKID from an existing certificate.
86
 * WOLFSSL_CUSTOM_OID: Enable custom OID support for subject and request
87
    extensions
88
 * WOLFSSL_HAVE_ISSUER_NAMES: Store pointers to issuer name components and their
89
    lengths and encodings.
90
 * WOLFSSL_SUBJ_DIR_ATTR: Enable support for SubjectDirectoryAttributes
91
    extension.
92
 * WOLFSSL_SUBJ_INFO_ACC: Enable support for SubjectInfoAccess extension.
93
 * WOLFSSL_FPKI: Enable support for FPKI (Federal PKI) extensions.
94
 * WOLFSSL_CERT_NAME_ALL: Adds more certificate name capability at the
95
    cost of taking up more memory. Adds initials, givenname, dnQualifer for
96
    example.
97
 * WC_ASN_HASH_SHA256: Force use of SHA2-256 for the internal hash ID calcs.
98
 * WOLFSSL_ALLOW_ENCODING_CA_FALSE: Allow encoding BasicConstraints CA:FALSE
99
 *  which is discouraged by X.690 specification - default values shall not
100
 *  be encoded.
101
 * NO_TIME_SIGNEDNESS_CHECK: Disabled the time_t signedness check.
102
 * WOLFSSL_ECC_SIGALG_PARAMS_NULL_ALLOWED: Allows the ECDSA/EdDSA signature
103
 *  algorithms in certificates to have NULL parameter instead of empty.
104
 *  DO NOT enable this unless required for interoperability.
105
 * WOLFSSL_ASN_EXTRA: Make more ASN.1 APIs available regardless of internal
106
 *  usage.
107
*/
108
109
#ifndef NO_RSA
110
    #include <wolfssl/wolfcrypt/rsa.h>
111
    #if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_CRYPTOCELL)
112
        extern int wc_InitRsaHw(RsaKey* key);
113
    #endif
114
#endif
115
116
#ifndef NO_ASN
117
118
#include <wolfssl/wolfcrypt/asn.h>
119
#include <wolfssl/wolfcrypt/coding.h>
120
#include <wolfssl/wolfcrypt/md2.h>
121
#include <wolfssl/wolfcrypt/hmac.h>
122
#include <wolfssl/wolfcrypt/pwdbased.h>
123
#include <wolfssl/wolfcrypt/des3.h>
124
#include <wolfssl/wolfcrypt/aes.h>
125
#include <wolfssl/wolfcrypt/rc2.h>
126
#include <wolfssl/wolfcrypt/wc_encrypt.h>
127
128
#include <wolfssl/wolfcrypt/random.h>
129
#include <wolfssl/wolfcrypt/hash.h>
130
#ifdef NO_INLINE
131
    #include <wolfssl/wolfcrypt/misc.h>
132
#else
133
    #define WOLFSSL_MISC_INCLUDED
134
    #include <wolfcrypt/src/misc.c>
135
#endif
136
137
#ifndef NO_RC4
138
    #include <wolfssl/wolfcrypt/arc4.h>
139
#endif
140
141
#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
142
    #include <wolfssl/wolfcrypt/sha512.h>
143
#endif
144
145
#ifndef NO_SHA256
146
    #include <wolfssl/wolfcrypt/sha256.h>
147
#endif
148
149
#ifdef HAVE_ECC
150
    #include <wolfssl/wolfcrypt/ecc.h>
151
#endif
152
153
#ifdef WOLFSSL_SM2
154
    #include <wolfssl/wolfcrypt/sm2.h>
155
#endif
156
157
#ifdef HAVE_ED25519
158
    #include <wolfssl/wolfcrypt/ed25519.h>
159
#endif
160
#ifdef HAVE_CURVE25519
161
    #include <wolfssl/wolfcrypt/curve25519.h>
162
#endif
163
164
#ifdef HAVE_ED448
165
    #include <wolfssl/wolfcrypt/ed448.h>
166
#endif
167
#ifdef HAVE_CURVE448
168
    #include <wolfssl/wolfcrypt/curve448.h>
169
#endif
170
171
#if defined(HAVE_FALCON)
172
    #include <wolfssl/wolfcrypt/falcon.h>
173
#endif
174
#if defined(HAVE_DILITHIUM)
175
    #include <wolfssl/wolfcrypt/dilithium.h>
176
#endif
177
#if defined(HAVE_SPHINCS)
178
    #include <wolfssl/wolfcrypt/sphincs.h>
179
#endif
180
181
#ifdef WOLFSSL_QNX_CAAM
182
    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
183
#endif
184
185
#if defined(WOLFSSL_RENESAS_FSPSM_TLS) || defined(WOLFSSL_RENESAS_TSIP_TLS)
186
    #include <wolfssl/wolfcrypt/port/Renesas/renesas_cmn.h>
187
#endif
188
189
#ifndef NO_DSA
190
    #include <wolfssl/wolfcrypt/dsa.h>
191
#else
192
    typedef void* DsaKey;
193
#endif
194
195
#ifdef WOLF_CRYPTO_CB
196
    #include <wolfssl/wolfcrypt/cryptocb.h>
197
#endif
198
199
#ifndef WOLFCRYPT_ONLY
200
    #include <wolfssl/internal.h>
201
#endif
202
203
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
204
    #include <wolfssl/openssl/objects.h>
205
#endif
206
207
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
208
        !defined(WOLFCRYPT_ONLY)
209
    #define WOLFSSL_X509_NAME_AVAILABLE
210
#endif
211
212
#ifdef _MSC_VER
213
    /* 4996 warning to use MS extensions e.g., strcpy_s instead of XSTRNCPY */
214
    #pragma warning(disable: 4996)
215
#endif
216
217
0
#define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; }
218
219
#if !defined(NO_SKID) && (!defined(HAVE_FIPS) || !defined(HAVE_FIPS_VERSION))
220
    #if !defined(HAVE_SELFTEST) || (defined(HAVE_SELFTEST) && \
221
                                   (!defined(HAVE_SELFTEST_VERSION) || \
222
                                    HAVE_SELFTEST_VERSION < 2))
223
    #ifndef WOLFSSL_AES_KEY_SIZE_ENUM
224
    #define WOLFSSL_AES_KEY_SIZE_ENUM
225
    enum Asn_Misc {
226
        AES_IV_SIZE         = 16,
227
        AES_128_KEY_SIZE    = 16,
228
        AES_192_KEY_SIZE    = 24,
229
        AES_256_KEY_SIZE    = 32
230
    };
231
    #endif
232
    #endif /* HAVE_SELFTEST */
233
#endif
234
235
#if defined(WOLFSSL_ASN_PRINT) || defined(WOLFSSL_DEBUG_ASN_TEMPLATE)
236
237
/* String representations of tags. */
238
static const char* tagString[4][32] = {
239
    /* Universal */
240
    {
241
        "EOC",
242
        "BOOLEAN",
243
        "INTEGER",
244
        "BIT STRING",
245
        "OCTET STRING",
246
        "NULL",
247
        "OBJECT ID",
248
        "ObjectDescriptor",
249
        "INSTANCE OF",
250
        "REAL",
251
        "ENUMERATED",
252
        "EMBEDDED PDV",
253
        "UT8String",
254
        "RELATIVE-OID",
255
        "(0x0e) 14",
256
        "(0x0f) 15",
257
        "SEQUENCE",
258
        "SET",
259
        "NumericString",
260
        "PrintableString",
261
        "T61String",
262
        "VideotexString",
263
        "IA5String",
264
        "UTCTime",
265
        "GeneralizedTime",
266
        "GraphicString",
267
        "ISO646String",
268
        "GeneralString",
269
        "UniversalString",
270
        "CHARACTER STRING",
271
        "BMPString",
272
        "(0x1f) 31",
273
    },
274
    /* Application */
275
    {
276
         "[A 0]",  "[A 1]",  "[A 2]",  "[A 3]",
277
         "[A 4]",  "[A 5]",  "[A 6]",  "[A 7]",
278
         "[A 8]",  "[A 9]", "[A 10]", "[A 11]",
279
        "[A 12]", "[A 13]", "[A 14]", "[A 15]",
280
        "[A 16]", "[A 17]", "[A 18]", "[A 19]",
281
        "[A 20]", "[A 21]", "[A 22]", "[A 23]",
282
        "[A 24]", "[A 25]", "[A 26]", "[A 27]",
283
        "[A 28]", "[A 20]", "[A 30]", "[A 31]"
284
    },
285
    /* Context-Specific */
286
    {
287
         "[0]",  "[1]",  "[2]",  "[3]",  "[4]",  "[5]",  "[6]",  "[7]",
288
         "[8]",  "[9]", "[10]", "[11]", "[12]", "[13]", "[14]", "[15]",
289
        "[16]", "[17]", "[18]", "[19]", "[20]", "[21]", "[22]", "[23]",
290
        "[24]", "[25]", "[26]", "[27]", "[28]", "[20]", "[30]", "[31]"
291
    },
292
    /* Private */
293
    {
294
         "[P 0]",  "[P 1]",  "[P 2]",  "[P 3]",
295
         "[P 4]",  "[P 5]",  "[P 6]",  "[P 7]",
296
         "[P 8]",  "[P 9]", "[P 10]", "[P 11]",
297
        "[P 12]", "[P 13]", "[P 14]", "[P 15]",
298
        "[P 16]", "[P 17]", "[P 18]", "[P 19]",
299
        "[P 20]", "[P 21]", "[P 22]", "[P 23]",
300
        "[P 24]", "[P 25]", "[P 26]", "[P 27]",
301
        "[P 28]", "[P 20]", "[P 30]", "[P 31]"
302
    }
303
};
304
305
/* Converts a tag byte to string.
306
 *
307
 * @param [in] tag  BER tag value to interpret.
308
 * @return  String corresponding to tag.
309
 */
310
static const char* TagString(byte tag)
311
0
{
312
0
    return tagString[tag >> 6][tag & ASN_TYPE_MASK];
313
0
}
314
315
#endif
316
317
318
/* Calculates the minimum number of bytes required to encode the value.
319
 *
320
 * @param [in] value  Value to be encoded.
321
 * @return  Number of bytes to encode value.
322
 */
323
static word32 BytePrecision(word32 value)
324
0
{
325
0
    word32 i;
326
0
    for (i = (word32)sizeof(value); i; --i)
327
0
        if (value >> ((i - 1) * WOLFSSL_BIT_SIZE))
328
0
            break;
329
330
0
    return i;
331
0
}
332
333
/* DER encodes the length value in output buffer.
334
 *
335
 *    0 ->  2^7-1: <len byte>.
336
 *  2^7 ->       : <0x80 + #bytes> <len big-endian bytes>
337
 *
338
 * @param [in]      length  Value to encode.
339
 * @param [in, out] output  Buffer to encode into.
340
 * @return  Number of bytes used in encoding.
341
 */
342
WOLFSSL_LOCAL word32 SetASNLength(word32 length, byte* output)
343
0
{
344
0
    word32 i = 0;
345
346
0
    if (length < ASN_LONG_LENGTH)
347
0
        output[i++] = (byte)length;
348
0
    else {
349
0
        word32 j;
350
351
0
        output[i++] = (byte)(BytePrecision(length) | ASN_LONG_LENGTH);
352
353
0
        for (j = BytePrecision(length); j; --j) {
354
0
            output[i] = (byte)(length >> ((j - 1) * WOLFSSL_BIT_SIZE));
355
0
            i++;
356
0
        }
357
0
    }
358
359
0
    return i;
360
0
}
361
362
#ifdef WC_ASN_RUNTIME_DATE_CHECK_CONTROL
363
static int AsnSkipDateCheck = 0;
364
int wc_AsnSetSkipDateCheck(int skip_p)
365
{
366
    AsnSkipDateCheck = (skip_p != 0);
367
    return 0;
368
}
369
int wc_AsnGetSkipDateCheck(void)
370
{
371
    return AsnSkipDateCheck;
372
}
373
#else
374
0
#define AsnSkipDateCheck 0
375
int wc_AsnSetSkipDateCheck(int skip_p)
376
0
{
377
0
    (void)skip_p;
378
0
    return NOT_COMPILED_IN;
379
0
}
380
int wc_AsnGetSkipDateCheck(void)
381
0
{
382
0
    return 0;
383
0
}
384
#endif
385
386
#ifdef WOLFSSL_ASN_TEMPLATE
387
/* Calculate the size of a DER encoded length value.
388
 *
389
 *    0 ->  2^7-1: <length byte>.
390
 *  2^7 ->       : <0x80 + #bytes> <big-endian length bytes>
391
 *
392
 * @param [in] length  Value to encode.
393
 * @return  Number of bytes required to encode.
394
 */
395
static word32 SizeASNLength(word32 length)
396
0
{
397
0
    return 1 + ((length >= ASN_LONG_LENGTH) ? BytePrecision(length) : 0);
398
0
}
399
400
/* Calculate the size of a DER encoded header.
401
 *
402
 * Header = Tag | Encoded length
403
 *
404
 * @param [in] length  Length value to encode.
405
 * @return  Number of bytes required to encode a DER header.
406
 */
407
#define SizeASNHeader(length) \
408
0
    (1 + SizeASNLength(length))
409
#endif
410
411
#ifdef WOLFSSL_ASN_TEMPLATE
412
#ifdef WOLFSSL_SMALL_STACK
413
    /* Declare the variable that is the dynamic data for decoding BER data.
414
     *
415
     * @param [in] name  Variable name to declare.
416
     * @param [in] cnt   Number of elements required.
417
     */
418
    #define DECL_ASNGETDATA(name, cnt)                                         \
419
        ASNGetData* name = NULL
420
421
    /* Allocates the dynamic BER decoding data.
422
     *
423
     * @param [in]      name  Variable name to declare.
424
     * @param [in]      cnt   Number of elements required.
425
     * @param [in, out] err   Error variable.
426
     * @param [in]      heap  Dynamic memory allocation hint.
427
     */
428
    #define ALLOC_ASNGETDATA(name, cnt, err, heap)                             \
429
    do {                                                                       \
430
        if ((err) == 0) {                                                      \
431
            (name) = (ASNGetData*)XMALLOC(sizeof(ASNGetData) * (cnt), (heap),  \
432
                                        DYNAMIC_TYPE_TMP_BUFFER);              \
433
            if ((name) == NULL) {                                              \
434
                (err) = MEMORY_E;                                              \
435
            }                                                                  \
436
        }                                                                      \
437
    }                                                                          \
438
    while (0)
439
440
    /* Allocates the dynamic BER decoding data and clears the memory.
441
     *
442
     * @param [in]      name  Variable name to declare.
443
     * @param [in]      cnt   Number of elements required.
444
     * @param [in, out] err   Error variable.
445
     * @param [in]      heap  Dynamic memory allocation hint.
446
     */
447
    #define CALLOC_ASNGETDATA(name, cnt, err, heap)                            \
448
    do {                                                                       \
449
        ALLOC_ASNGETDATA(name, cnt, err, heap);                                \
450
        if ((err) == 0) {                                                      \
451
            XMEMSET((name), 0, sizeof(ASNGetData) * (cnt));                    \
452
        }                                                                      \
453
    }                                                                          \
454
    while (0)
455
456
    /* Disposes of the dynamic BER decoding data.
457
     *
458
     * @param [in]      name  Variable name to declare.
459
     * @param [in]      heap  Dynamic memory allocation hint.
460
     */
461
    #define FREE_ASNGETDATA(name, heap)                                        \
462
    do {                                                                       \
463
        if ((name) != NULL) {                                                  \
464
            XFREE((name), (heap), DYNAMIC_TYPE_TMP_BUFFER);                    \
465
        }                                                                      \
466
    }                                                                          \
467
    while (0)
468
469
    /* Declare the variable that is the dynamic data for encoding DER data.
470
     *
471
     * @param [in] name  Variable name to declare.
472
     * @param [in] cnt   Number of elements required.
473
     */
474
    #define DECL_ASNSETDATA(name, cnt)                                         \
475
        ASNSetData* name = NULL
476
477
    /* Allocates the dynamic DER encoding data.
478
     *
479
     * @param [in]      name  Variable name to declare.
480
     * @param [in]      cnt   Number of elements required.
481
     * @param [in, out] err   Error variable.
482
     * @param [in]      heap  Dynamic memory allocation hint.
483
     */
484
    #define ALLOC_ASNSETDATA(name, cnt, err, heap)                             \
485
    do {                                                                       \
486
        if ((err) == 0) {                                                      \
487
            (name) = (ASNSetData*)XMALLOC(sizeof(ASNGetData) * (cnt), (heap),  \
488
                                    DYNAMIC_TYPE_TMP_BUFFER);                  \
489
            if ((name) == NULL) {                                              \
490
                (err) = MEMORY_E;                                              \
491
            }                                                                  \
492
        }                                                                      \
493
    }                                                                          \
494
    while (0)
495
496
    /* Allocates the dynamic DER encoding data and clears the memory.
497
     *
498
     * @param [in]      name  Variable name to declare.
499
     * @param [in]      cnt   Number of elements required.
500
     * @param [in, out] err   Error variable.
501
     * @param [in]      heap  Dynamic memory allocation hint.
502
     */
503
    #define CALLOC_ASNSETDATA(name, cnt, err, heap)                            \
504
    do {                                                                       \
505
        ALLOC_ASNSETDATA(name, cnt, err, heap);                                \
506
        if ((err) == 0) {                                                      \
507
            XMEMSET(name, 0, sizeof(ASNSetData) * (cnt));                      \
508
        }                                                                      \
509
    }                                                                          \
510
    while (0)
511
512
    /* Disposes of the dynamic DER encoding data.
513
     *
514
     * @param [in]      name  Variable name to declare.
515
     * @param [in]      heap  Dynamic memory allocation hint.
516
     */
517
    #define FREE_ASNSETDATA(name, heap)                                        \
518
    do {                                                                       \
519
        if ((name) != NULL) {                                                  \
520
            XFREE(name, heap, DYNAMIC_TYPE_TMP_BUFFER);                        \
521
        }                                                                      \
522
    }                                                                          \
523
    while (0)
524
#else
525
    /* Declare the variable that is the dynamic data for decoding BER data.
526
     *
527
     * @param [in] name  Variable name to declare.
528
     * @param [in] cnt   Number of elements required.
529
     */
530
    #define DECL_ASNGETDATA(name, cnt)                  \
531
0
        ASNGetData name[cnt]
532
533
    /* No implementation as declaration is static.
534
     *
535
     * @param [in]      name  Variable name to declare.
536
     * @param [in]      cnt   Number of elements required.
537
     * @param [in, out] err   Error variable.
538
     * @param [in]      heap  Dynamic memory allocation hint.
539
     */
540
0
    #define ALLOC_ASNGETDATA(name, cnt, err, heap) WC_DO_NOTHING
541
542
    /* Clears the memory of the dynamic BER encoding data.
543
     *
544
     * @param [in]      name  Variable name to declare.
545
     * @param [in]      cnt   Number of elements required.
546
     * @param [in, out] err   Error variable.
547
     * @param [in]      heap  Dynamic memory allocation hint.
548
     */
549
    #define CALLOC_ASNGETDATA(name, cnt, err, heap)     \
550
0
        XMEMSET(name, 0, sizeof(name))
551
552
    /* No implementation as declaration is static.
553
     *
554
     * @param [in]      name  Variable name to declare.
555
     * @param [in]      heap  Dynamic memory allocation hint.
556
     */
557
0
    #define FREE_ASNGETDATA(name, heap) WC_DO_NOTHING
558
559
    /* Declare the variable that is the dynamic data for encoding DER data.
560
     *
561
     * @param [in] name  Variable name to declare.
562
     * @param [in] cnt   Number of elements required.
563
     */
564
    #define DECL_ASNSETDATA(name, cnt)                  \
565
0
        ASNSetData name[cnt]
566
567
    /* No implementation as declaration is static.
568
     *
569
     * @param [in]      name  Variable name to declare.
570
     * @param [in]      cnt   Number of elements required.
571
     * @param [in, out] err   Error variable.
572
     * @param [in]      heap  Dynamic memory allocation hint.
573
     */
574
    #define ALLOC_ASNSETDATA(name, cnt, err, heap) WC_DO_NOTHING
575
576
    /* Clears the memory of the dynamic BER encoding data.
577
     *
578
     * @param [in]      name  Variable name to declare.
579
     * @param [in]      cnt   Number of elements required.
580
     * @param [in, out] err   Error variable.
581
     * @param [in]      heap  Dynamic memory allocation hint.
582
     */
583
    #define CALLOC_ASNSETDATA(name, cnt, err, heap)     \
584
0
        XMEMSET(name, 0, sizeof(name))
585
586
    /* No implementation as declaration is static.
587
     *
588
     * @param [in]      name  Variable name to declare.
589
     * @param [in]      heap  Dynamic memory allocation hint.
590
     */
591
0
    #define FREE_ASNSETDATA(name, heap) WC_DO_NOTHING
592
#endif
593
594
595
#ifdef DEBUG_WOLFSSL
596
    /* Enable this when debugging the parsing or creation of ASN.1 data. */
597
    #if 0
598
        #define WOLFSSL_DEBUG_ASN_TEMPLATE
599
    #endif
600
#endif
601
602
#ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
603
604
#include <stdarg.h>
605
606
/* Log a message that has the printf format string.
607
 *
608
 * @param [in] <va_args>  printf style arguments.
609
 */
610
#define WOLFSSL_MSG_VSNPRINTF(...)                    \
611
    do {                                              \
612
      char line[81];                                  \
613
      snprintf(line, sizeof(line) - 1, __VA_ARGS__);  \
614
      line[sizeof(line) - 1] = '\0';                  \
615
      WOLFSSL_MSG(line);                              \
616
    }                                                 \
617
    while (0)
618
#endif
619
620
/* Returns whether ASN.1 item is an integer and the Most-Significant Bit is set.
621
 *
622
 * @param [in] asn     ASN.1 items to encode.
623
 * @param [in] data_a  Data to place in each item. Lengths set were not known.
624
 * @param [in] i       Index of item to check.
625
 * @return  1 when ASN.1 item is an integer and MSB is 1.
626
 * @return  0 otherwise.
627
 */
628
#define ASNIntMSBSet(asn, data_a, i)                  \
629
0
    (((asn)[i].tag == ASN_INTEGER) &&                 \
630
0
      ((data_a)[i].data.buffer.data != NULL &&        \
631
0
      ((data_a)[i].data.buffer.data[0] & 0x80) == 0x80))
632
633
634
/* Calculate the size of a DER encoded number.
635
 *
636
 * @param [in] n     Number to be encoded.
637
 * @param [in] bits  Maximum number of bits to encode.
638
 * @param [in] tag   BER tag e.g. INTEGER, BIT_STRING, etc.
639
 * @return  Number of bytes to the ASN.1 item.
640
 */
641
static word32 SizeASN_Num(word32 n, int bits, byte tag)
642
0
{
643
0
    int    j;
644
0
    word32 len;
645
646
0
    len = 1 + 1 + (word32)bits / 8;
647
    /* Discover actual size by checking for high zeros. */
648
0
    for (j = bits - 8; j > 0; j -= 8) {
649
0
        if (n >> j)
650
0
            break;
651
0
        len--;
652
0
    }
653
0
    if (tag == ASN_BIT_STRING)
654
0
        len++;
655
0
    else if ((tag == ASN_INTEGER) && (((n >> j) & 0x80) == 0x80))
656
0
        len++;
657
658
0
    return len;
659
0
}
660
661
/* Calculate the size of the data in the constructed item based on the
662
 * length of the ASN.1 items below.
663
 *
664
 * @param [in]      asn    ASN.1 items to encode.
665
 * @param [in, out] data   Data to place in each item. Lengths set were not
666
 *                         known.
667
 * @param [in]      idx    Index of item working on.
668
 */
669
static void SizeASN_CalcDataLength(const ASNItem* asn, ASNSetData *data,
670
                                   int idx, int maxIdx)
671
0
{
672
0
    int j;
673
674
0
    data[idx].data.buffer.length = 0;
675
    /* Sum the item length of all items underneath. */
676
0
    for (j = idx + 1; j < maxIdx; j++) {
677
        /* Stop looking if the next ASN.1 is same level or higher. */
678
0
        if (asn[j].depth <= asn[idx].depth)
679
0
            break;
680
        /* Only add in length if it is one level below. */
681
0
        if (asn[j].depth - 1 == asn[idx].depth) {
682
0
            data[idx].data.buffer.length += data[j].length;
683
            /* The length of a header only item doesn't include the data unless
684
             * a replacement buffer is supplied.
685
             */
686
0
            if (asn[j].headerOnly && data[j].data.buffer.data == NULL &&
687
0
                    data[j].dataType != ASN_DATA_TYPE_REPLACE_BUFFER) {
688
0
                data[idx].data.buffer.length += data[j].data.buffer.length;
689
0
            }
690
0
        }
691
0
    }
692
0
}
693
694
/* Calculate the size of the DER encoding.
695
 *
696
 * Call SetASN_Items() to write encoding to a buffer.
697
 *
698
 * @param [in]      asn    ASN.1 items to encode.
699
 * @param [in, out] data   Data to place in each item. Lengths set where not
700
 *                         known.
701
 * @param [in]      count  Count of items to encode.
702
 * @param [out]     encSz  Length of the DER encoding.
703
 * @return  0 on success.
704
 * @return  BAD_STATE_E when the data type is not supported.
705
 */
706
int SizeASN_Items(const ASNItem* asn, ASNSetData *data, int count, int* encSz)
707
0
{
708
0
    int    i;
709
0
    word32 sz = 0;
710
0
    word32 len;
711
0
    word32 dataLen;
712
0
    int    length;
713
714
#ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
715
    WOLFSSL_ENTER("SizeASN_Items");
716
#endif
717
718
0
    for (i = count - 1; i >= 0; i--) {
719
        /* Skip this ASN.1 item when encoding. */
720
0
        if (data[i].noOut) {
721
            /* Set the offset to the current size - used in writing DER. */
722
0
            data[i].offset = sz;
723
0
            continue;
724
0
        }
725
726
0
        len = 0;
727
0
        switch (data[i].dataType) {
728
            /* Calculate the size of the number of different sizes. */
729
0
            case ASN_DATA_TYPE_WORD8:
730
0
                len = SizeASN_Num(data[i].data.u8, 8, asn[i].tag);
731
0
                break;
732
0
            case ASN_DATA_TYPE_WORD16:
733
0
                len = SizeASN_Num(data[i].data.u16, 16, asn[i].tag);
734
0
                break;
735
        #ifdef WOLFSSL_ASN_TEMPLATE_NEED_SET_INT32
736
            /* Not used yet! */
737
            case ASN_DATA_TYPE_WORD32:
738
                len = SizeASN_Num(data[i].data.u32, 32, asn[i].tag);
739
                break;
740
        #endif
741
742
0
            case ASN_DATA_TYPE_MP:
743
                /* Calculate the size of the MP integer data. */
744
0
                length = mp_unsigned_bin_size(data[i].data.mp);
745
0
                length += mp_leading_bit(data[i].data.mp) ? 1 : 0;
746
0
                len = (word32)SizeASNHeader((word32)length) + (word32)length;
747
0
                break;
748
749
0
            case ASN_DATA_TYPE_REPLACE_BUFFER:
750
                /* Buffer is put in directly - use the length. */
751
0
                len = data[i].data.buffer.length;
752
0
                break;
753
754
0
            case ASN_DATA_TYPE_NONE:
755
                /* Calculate the size based on the data to be included.
756
                 * Mostly used for constructed items.
757
                 */
758
0
                if (asn[i].headerOnly) {
759
0
                    if (data[i].data.buffer.data != NULL) {
760
                        /* Force all child nodes to be ignored. Buffer
761
                         * overwrites children. */
762
0
                        {
763
0
                            int ii;
764
0
                            for (ii = i + 1; ii < count; ii++) {
765
0
                                if (asn[ii].depth <= asn[i].depth)
766
0
                                    break;
767
0
                                sz -= data[ii].length;
768
0
                                data[ii].noOut = 1;
769
0
                            }
770
0
                        }
771
0
                    }
772
0
                    else {
773
                        /* Calculate data length from items below if no buffer
774
                         * supplied. */
775
0
                        SizeASN_CalcDataLength(asn, data, i, count);
776
0
                    }
777
0
                }
778
0
                if (asn[i].tag == ASN_BOOLEAN) {
779
0
                    dataLen = 1;
780
0
                }
781
0
                else {
782
0
                    dataLen = data[i].data.buffer.length;
783
0
                }
784
                /* BIT_STRING and INTEGER have one byte prepended. */
785
0
                if ((asn[i].tag == ASN_BIT_STRING) ||
786
0
                                                   ASNIntMSBSet(asn, data, i)) {
787
0
                    dataLen++;
788
                    /* ASN.1 items are below and cannot include extra byte. */
789
0
                    if (asn[i].headerOnly) {
790
0
                        len++;
791
0
                    }
792
0
                }
793
                /* Add in the size of tag and length. */
794
0
                len += SizeASNHeader(dataLen);
795
                /* Include data in length if not header only or if
796
                 * buffer supplied. */
797
0
                if (!asn[i].headerOnly || data[i].data.buffer.data != NULL) {
798
0
                    len += dataLen;
799
0
                }
800
0
                break;
801
802
        #ifdef DEBUG_WOLFSSL
803
            default:
804
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
805
                WOLFSSL_MSG_VSNPRINTF("%2d: %d", i, data[i].dataType);
806
                WOLFSSL_MSG("Bad data type");
807
            #endif
808
                return BAD_STATE_E;
809
        #endif
810
0
        }
811
812
        /* Set the total length of the item. */
813
0
        data[i].length = len;
814
        /* Add length to total size. */
815
0
        sz += len;
816
        /* Set the offset to the current size - used in writing DER. */
817
0
        data[i].offset = sz;
818
819
    #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
820
        WOLFSSL_MSG_VSNPRINTF("%2d: %4d %4d %c %*s %-16s", i,
821
                data[i].offset, data[i].length, asn[i].constructed ? '+' : ' ',
822
                asn[i].depth, "", TagString(asn[i].tag));
823
    #endif
824
0
    }
825
826
0
    *encSz = (int)sz;
827
0
    return 0;
828
0
}
829
830
/* Create the DER encoding of a number.
831
 *
832
 * Assumes that the out buffer is large enough for encoding.
833
 *
834
 * @param [in] n     Number to be encoded.
835
 * @param [in] bits  Maximum number of bits to encode.
836
 * @param [in] tag   DER tag e.g. INTEGER, BIT_STRING, etc.
837
 */
838
static void SetASN_Num(word32 n, int bits, byte* out, byte tag)
839
0
{
840
0
    int    j;
841
0
    word32 idx;
842
0
    byte   len;
843
844
    /* Encoding: Tag (1 byte) | Length (1 byte) | Data (number) */
845
846
    /* Data will start at index 2 unless BIT_STRING or INTEGER */
847
0
    idx = 2;
848
849
    /* Set the length of the number based on maximum bit length. */
850
0
    len = (byte)(bits / 8);
851
    /* Discover actual size by checking for leading zero bytes. */
852
0
    for (j = bits - 8; j > 0; j -= 8) {
853
0
        if ((n >> j) != 0) {
854
0
            break;
855
0
        }
856
0
        len--;
857
0
    }
858
    /* Keep j, index of first non-zero byte, for writing out. */
859
860
    /* A BIT_STRING has the number of unused bits in last byte prepended to
861
     * data.
862
     */
863
0
    if (tag == ASN_BIT_STRING) {
864
0
        byte unusedBits = 0;
865
0
        byte lastByte = (byte)(n >> j);
866
867
        /* Quick check last bit. */
868
0
        if ((lastByte & 0x01) == 0x00) {
869
0
            unusedBits++;
870
            /* Check each bit for first least significant bit set. */
871
0
            while (((lastByte >> unusedBits) & 0x01) == 0x00)
872
0
                unusedBits++;
873
0
        }
874
        /* Add unused bits byte. */
875
0
        len++;
876
0
        out[idx++] = unusedBits;
877
0
    }
878
879
    /* An INTEGER has a prepended byte if MSB of number is 1 - makes encoded
880
     * value positive. */
881
0
    if ((tag == ASN_INTEGER) && (((n >> j) & 0x80) == 0x80)) {
882
0
        len++;
883
0
        out[idx++] = 0;
884
0
    }
885
886
    /* Go back and put in length. */
887
0
    out[1] = len;
888
    /* Place in the required bytes of the number. */
889
0
    for (; j >= 0; j -= 8)
890
0
        out[idx++] = (byte)(n >> j);
891
0
}
892
893
/* Creates the DER encoding of the ASN.1 items.
894
 *
895
 * Assumes the output buffer is large enough to hold encoding.
896
 * Must call SizeASN_Items() to determine size of encoding and offsets.
897
 *
898
 * @param [in]      asn     ASN.1 items to encode.
899
 * @param [in]      data    Data to place in each item.
900
 * @param [in]      count   Count of items to encode.
901
 * @param [in, out] output  Buffer to write encoding into.
902
 * @return  Size of the DER encoding in bytes.
903
 */
904
int SetASN_Items(const ASNItem* asn, ASNSetData *data, int count, byte* output)
905
0
{
906
0
    int    i;
907
0
    int    length;
908
0
    int    err;
909
0
    word32 sz;
910
0
    word32 idx;
911
0
    byte*  out;
912
913
#ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
914
    WOLFSSL_ENTER("SetASN_Items");
915
#endif
916
917
    /* Offset of first item is the total length.
918
     * SizeASN_Items() calculated this. */
919
0
    sz = data[0].offset;
920
921
    /* Write out each item. */
922
0
    for (i = 0; i < count; i++) {
923
        /* Skip items not writing out. */
924
0
        if (data[i].noOut)
925
0
            continue;
926
927
        /* Start position to write item based on reverse offsets. */
928
0
        out = output + sz - data[i].offset;
929
        /* Index from start of item out. */
930
0
        idx = 0;
931
932
0
        if (data[i].dataType != ASN_DATA_TYPE_REPLACE_BUFFER) {
933
            /* Put in the tag - not dumping in DER from buffer. */
934
0
            out[idx++] = asn[i].tag |
935
0
                         (asn[i].constructed ? ASN_CONSTRUCTED : 0);
936
0
        }
937
938
    #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
939
        WOLFSSL_MSG_VSNPRINTF("%2d: %4d %4d %c %*s %-16s", i,
940
                sz - data[i].offset,
941
                data[i].length, asn[i].constructed ? '+' : ' ', asn[i].depth,
942
                "", TagString(asn[i].tag));
943
    #endif
944
945
0
        switch (data[i].dataType) {
946
            /* Write out the length and data of a number. */
947
0
            case ASN_DATA_TYPE_WORD8:
948
0
                SetASN_Num(data[i].data.u8, 8, out, asn[i].tag);
949
0
                break;
950
0
            case ASN_DATA_TYPE_WORD16:
951
0
                SetASN_Num(data[i].data.u16, 16, out, asn[i].tag);
952
0
                break;
953
        #ifdef WOLFSSL_ASN_TEMPLATE_NEED_SET_INT32
954
            /* Not used yet! */
955
            case ASN_DATA_TYPE_WORD32:
956
                SetASN_Num(data[i].data.u32, 32, out, asn[i].tag);
957
                break;
958
        #endif
959
960
            /* Write out the length and data of a multi-precision number. */
961
0
            case ASN_DATA_TYPE_MP:
962
                /* Get length in bytes. */
963
0
                length = mp_unsigned_bin_size(data[i].data.mp);
964
                /* Add one for leading zero to make encoding a positive num. */
965
0
                length += mp_leading_bit(data[i].data.mp) ? 1 : 0;
966
                /* Write out length. */
967
0
                idx += SetASNLength((word32)length, out + idx);
968
                /* Write out leading zero to make positive. */
969
0
                if (mp_leading_bit(data[i].data.mp)) {
970
0
                    out[idx++] = 0;
971
0
                }
972
                /* Encode number in big-endian byte array. */
973
0
                err = mp_to_unsigned_bin(data[i].data.mp, out + idx);
974
0
                if (err != MP_OKAY) {
975
0
                    WOLFSSL_MSG("SetASN_Items: Failed to write mp_int");
976
0
                    return MP_TO_E;
977
0
                }
978
0
                break;
979
980
0
            case ASN_DATA_TYPE_REPLACE_BUFFER:
981
0
                if (data[i].data.buffer.data == NULL) {
982
                    /* Return pointer for caller to use. */
983
0
                    data[i].data.buffer.data = out + idx;
984
0
                }
985
0
                else {
986
                    /* Dump in the DER encoded data. */
987
0
                    XMEMCPY(out + idx, data[i].data.buffer.data,
988
0
                            data[i].data.buffer.length);
989
0
                }
990
0
                break;
991
992
0
            case ASN_DATA_TYPE_NONE:
993
0
                if (asn[i].tag == ASN_BOOLEAN) {
994
                    /* Always one byte of data. */
995
0
                    out[idx++] = 1;
996
                    /* TRUE = 0xff, FALSE = 0x00 */
997
0
                    out[idx] = data[i].data.u8 ? 0xffU : 0x00U;
998
0
                }
999
0
                else if (asn[i].tag == ASN_TAG_NULL) {
1000
                    /* NULL tag is always a zero length item. */
1001
0
                    out[idx] = 0;
1002
0
                }
1003
0
                else {
1004
0
                    word32 dataLen = data[i].data.buffer.length;
1005
                    /* Add one to data length for BIT_STRING unused bits and
1006
                     * INTEGER leading zero to make positive.
1007
                     */
1008
0
                    if ((asn[i].tag == ASN_BIT_STRING) ||
1009
0
                                                   ASNIntMSBSet(asn, data, i)) {
1010
0
                        dataLen++;
1011
0
                    }
1012
                    /* Write out length. */
1013
0
                    idx += SetASNLength(dataLen, out + idx);
1014
0
                    if ((asn[i].tag == ASN_BIT_STRING) ||
1015
0
                                                   ASNIntMSBSet(asn, data, i)) {
1016
                       /* Write out leading byte. BIT_STRING has no unused bits
1017
                        * - use number data types if needed. */
1018
0
                        out[idx++] = 0x00;
1019
0
                    }
1020
                    /* Record pointer for caller if data not supplied. */
1021
0
                    if (data[i].data.buffer.data == NULL) {
1022
0
                        data[i].data.buffer.data = out + idx;
1023
0
                    }
1024
                    /* Copy supplied data if not putting out header only or
1025
                     * if buffer supplied. */
1026
0
                    else if (!asn[i].headerOnly ||
1027
0
                            data[i].data.buffer.data != NULL) {
1028
                        /* Allow data to come from output buffer. */
1029
0
                        XMEMMOVE(out + idx, data[i].data.buffer.data,
1030
0
                                 data[i].data.buffer.length);
1031
0
                    }
1032
0
                }
1033
0
                break;
1034
1035
        #ifdef DEBUG_WOLFSSL
1036
            default:
1037
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1038
                WOLFSSL_MSG_VSNPRINTF("Bad data type: %d", data[i].dataType);
1039
            #endif
1040
                return BAD_STATE_E;
1041
        #endif
1042
0
        }
1043
0
    }
1044
1045
0
    return (int)sz;
1046
0
}
1047
1048
1049
static int GetOID(const byte* input, word32* inOutIdx, word32* oid,
1050
                  word32 oidType, int length);
1051
1052
/* Maximum supported depth in ASN.1 description. */
1053
0
#define GET_ASN_MAX_DEPTH          7
1054
/* Maximum number of checked numbered choices. Only one of the items with the
1055
 * number is allowed.
1056
 */
1057
0
#define GET_ASN_MAX_CHOICES        2
1058
1059
/* Use existing function to decode BER length encoding. */
1060
0
#define GetASN_Length GetLength_ex
1061
1062
/* Check an INTEGER's first byte - must be a positive number.
1063
 *
1064
 * @param [in] input    BER encoded data.
1065
 * @param [in] idx      Index of BIT_STRING data.
1066
 * @param [in] length   Length of input data.
1067
 * @param [in] positive Indicates number must be positive.
1068
 * @return  0 on success.
1069
 * @return  ASN_PARSE_E when 0 is not required but seen.
1070
 * @return  ASN_EXPECT_0_E when 0 is required and not seen.
1071
 */
1072
static int GetASN_Integer(const byte* input, word32 idx, int length,
1073
                          int positive)
1074
0
{
1075
0
#if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) || \
1076
0
    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
1077
    /* Check contents consist of one or more octets. */
1078
0
    if (length == 0) {
1079
0
        WOLFSSL_MSG("Zero length INTEGER not allowed");
1080
0
        return ASN_PARSE_E;
1081
0
    }
1082
0
#endif
1083
0
    if (input[idx] == 0) {
1084
        /* Check leading zero byte required. */
1085
0
        if ((length > 1) && ((input[idx + 1] & 0x80) == 0)) {
1086
0
            WOLFSSL_MSG("Zero not required on INTEGER");
1087
0
        #ifndef WOLFSSL_ASN_INT_LEAD_0_ANY
1088
0
            return ASN_PARSE_E;
1089
0
        #endif
1090
0
        }
1091
0
    }
1092
    /* check for invalid padding on negative integer.
1093
     * c.f. X.690 (ISO/IEC 8825-2:2003 (E)) 10.4.6; RFC 5280 4.1
1094
     */
1095
0
    else if ((length > 1) && (input[idx] == 0xff) &&
1096
0
             ((input[idx + 1] & 0x80) != 0)) {
1097
0
        WOLFSSL_MSG("Bad INTEGER encoding of negative");
1098
0
    #ifndef WOLFSSL_ASN_INT_LEAD_0_ANY
1099
0
        return ASN_EXPECT_0_E;
1100
0
    #endif /* WOLFSSL_ASN_INT_LEAD_0_ANY */
1101
0
    }
1102
    /* Check whether a leading zero byte was required. */
1103
0
    else if (positive && (input[idx] & 0x80)) {
1104
0
        WOLFSSL_MSG("INTEGER is negative");
1105
0
    #ifndef WOLFSSL_ASN_INT_LEAD_0_ANY
1106
0
        return ASN_EXPECT_0_E;
1107
0
    #endif /* WOLFSSL_ASN_INT_LEAD_0_ANY */
1108
0
    }
1109
1110
0
    return 0;
1111
0
}
1112
1113
/* Check a BIT_STRING's first byte - unused bits.
1114
 *
1115
 * @param [in] input   BER encoded data.
1116
 * @param [in] idx     Index of BIT_STRING data.
1117
 * @param [in] length  Length of input data.
1118
 * @return  0 on success.
1119
 * @return  ASN_PARSE_E when unused bits is invalid.
1120
 */
1121
int GetASN_BitString(const byte* input, word32 idx, int length)
1122
0
{
1123
0
#if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) || \
1124
0
    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
1125
    /* Check contents consist of one or more octets. */
1126
0
    if (length == 0) {
1127
    #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1128
        WOLFSSL_MSG("Zero length BIT STRING not allowed");
1129
    #endif
1130
0
        return ASN_PARSE_E;
1131
0
    }
1132
0
#endif
1133
    /* Ensure unused bits value is valid range. */
1134
0
    if (input[idx] > 7) {
1135
    #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1136
        WOLFSSL_MSG_VSNPRINTF("BIT STRING unused bits too big: %d > 7",
1137
                input[idx]);
1138
    #endif
1139
0
        return ASN_PARSE_E;
1140
0
    }
1141
    /* Ensure unused bits are zero. */
1142
0
    if ((byte)(input[idx + (word32)length - 1] << (8 - input[idx])) != 0) {
1143
    #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1144
        WOLFSSL_MSG_VSNPRINTF("BIT STRING unused bits used: %d %02x",
1145
                input[idx], input[idx + length - 1]);
1146
    #endif
1147
0
        return ASN_PARSE_E;
1148
0
    }
1149
1150
0
    return 0;
1151
0
}
1152
1153
#ifndef WOLFSSL_NO_ASN_STRICT
1154
/* Check a UTF8STRING's data is valid.
1155
 *
1156
 * @param [in] input   BER encoded data.
1157
 * @param [in] idx     Index of UTF8STRING data.
1158
 * @param [in] length  Length of input data.
1159
 * @return  0 on success.
1160
 * @return  ASN_PARSE_E when data is invalid.
1161
 */
1162
static int GetASN_UTF8String(const byte* input, word32 idx, int length)
1163
0
{
1164
0
    int ret = 0;
1165
0
    word32 i = 0;
1166
1167
0
    while ((ret == 0) && ((int)i < length)) {
1168
0
        int cnt;
1169
1170
        /* Check code points and get count of following bytes. */
1171
0
        if ((input[idx + i] & 0x80) == 0x00) {
1172
0
            cnt = 0;
1173
0
        }
1174
0
        else if ((input[idx + i] & 0xe0) == 0xc0) {
1175
0
            cnt = 1;
1176
0
        }
1177
0
        else if ((input[idx + i] & 0xf0) == 0xe0) {
1178
0
            cnt = 2;
1179
0
        }
1180
0
        else if ((input[idx + i] & 0xf8) == 0xf0) {
1181
0
            cnt = 3;
1182
0
        }
1183
0
        else {
1184
0
            WOLFSSL_MSG("Invalid character in UTF8STRING\n");
1185
0
            ret = ASN_PARSE_E;
1186
0
            break;
1187
0
        }
1188
1189
        /* Have checked first byte. */
1190
0
        i++;
1191
        /* Check each following byte. */
1192
0
        for (; cnt > 0; cnt--) {
1193
            /* Check we have enough data. */
1194
0
            if ((int)i == length) {
1195
0
                WOLFSSL_MSG("Missing character in UTF8STRING\n");
1196
0
                ret = ASN_PARSE_E;
1197
0
                break;
1198
0
            }
1199
            /* Check following byte has top bit set. */
1200
0
            if ((input[idx + i] & 0x80) != 0x80) {
1201
0
                WOLFSSL_MSG("Invalid character in UTF8STRING\n");
1202
0
                ret = ASN_PARSE_E;
1203
0
                break;
1204
0
            }
1205
0
            i++;
1206
0
        }
1207
0
    }
1208
1209
0
    return ret;
1210
0
}
1211
#endif
1212
1213
/* Check an OBJECT IDENTIFIER's data is valid.
1214
 *
1215
 * X.690 8.19
1216
 *
1217
 * @param [in] input   BER encoded data.
1218
 * @param [in] idx     Index of OBJECT IDENTIFIER data.
1219
 * @param [in] length  Length of input data.
1220
 * @return  0 on success.
1221
 * @return  ASN_PARSE_E when data is invalid.
1222
 */
1223
static int GetASN_ObjectId(const byte* input, word32 idx, int length)
1224
0
{
1225
0
    int ret = 0;
1226
1227
    /* OID data must be at least 3 bytes. */
1228
0
    if (length < 3) {
1229
    #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1230
        WOLFSSL_MSG_VSNPRINTF("OID length must be 3 or more: %d", length);
1231
    #else
1232
0
        WOLFSSL_MSG("OID length less than 3");
1233
0
    #endif
1234
0
        ret = ASN_PARSE_E;
1235
0
    }
1236
    /* Last octet of a sub-identifier has bit 8 clear. Last octet must be last
1237
     * of a subidentifier. Ensure last octet hasn't got top bit set.
1238
     */
1239
0
    else if ((input[(int)idx + length - 1] & 0x80) == 0x80) {
1240
0
        WOLFSSL_MSG("OID last octet has top bit set");
1241
0
        ret = ASN_PARSE_E;
1242
0
    }
1243
1244
0
    return ret;
1245
0
}
1246
1247
/* Get the ASN.1 items from the BER encoding.
1248
 *
1249
 * @param [in] asn         ASN.1 item expected.
1250
 * @param [in] data        Data array to place found item into.
1251
 * @param [in] input       BER encoded data.
1252
 * @param [in] idx         Starting index of item data.
1253
 * @param [in] len         Length of input buffer upto end of this item's data.
1254
 * @param [in] zeroPadded  INTEGER was zero padded to make positive.
1255
 * @return  0 on success.
1256
 * @return  ASN_PARSE_E when BER encoded data is invalid.
1257
 * @return  ASN_EXPECT_0_E when NULL tagged item has a non-zero length.
1258
 * @return  MP_INIT_E when the unable to initialize an mp_int.
1259
 * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
1260
 * @return  BAD_STATE_E when the data type is not supported.
1261
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
1262
 */
1263
static int GetASN_StoreData(const ASNItem* asn, ASNGetData* data,
1264
                            const byte* input, word32 idx, int len,
1265
                            int zeroPadded)
1266
0
{
1267
0
    int i;
1268
0
    int err;
1269
1270
    /* Parse data based on data type to extract. */
1271
0
    switch (data->dataType) {
1272
        /* Parse a data into a number of specified bits. */
1273
0
        case ASN_DATA_TYPE_WORD8:
1274
            /* Check data is small enough to fit. */
1275
0
            if (len != 1) {
1276
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1277
                WOLFSSL_MSG_VSNPRINTF("Expecting one byte: %d", len);
1278
            #endif
1279
0
                return ASN_PARSE_E;
1280
0
            }
1281
            /* Fill number with all of data. */
1282
0
            *data->data.u8 = input[idx];
1283
0
            break;
1284
0
        case ASN_DATA_TYPE_WORD16:
1285
            /* Check data is small enough to fit. */
1286
0
            if (len == 0 || len > 2) {
1287
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1288
                WOLFSSL_MSG_VSNPRINTF("Expecting 1 or 2 bytes: %d", len);
1289
            #endif
1290
0
                return ASN_PARSE_E;
1291
0
            }
1292
            /* Fill number with all of data. */
1293
0
            *data->data.u16 = 0;
1294
0
            for (i = 0; i < len; i++) {
1295
0
                *data->data.u16 = (word16)(*data->data.u16 << 8U);
1296
0
                *data->data.u16 = (word16)(*data->data.u16 | input[idx + (word32)i]);
1297
0
            }
1298
0
            break;
1299
0
        case ASN_DATA_TYPE_WORD32:
1300
            /* Check data is small enough to fit. */
1301
0
            if (len == 0 || len > 4) {
1302
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1303
                WOLFSSL_MSG_VSNPRINTF("Expecting 1 to 4 bytes: %d", len);
1304
            #endif
1305
0
                return ASN_PARSE_E;
1306
0
            }
1307
            /* Fill number with all of data. */
1308
0
            *data->data.u32 = 0;
1309
0
            for (i = 0; i < len; i++) {
1310
0
                *data->data.u32 <<= 8;
1311
0
                *data->data.u32 |= input[idx + (word32)i] ;
1312
0
            }
1313
0
            break;
1314
1315
0
        case ASN_DATA_TYPE_BUFFER:
1316
            /* Check buffer is big enough to hold data. */
1317
0
            if (len > (int)*data->data.buffer.length) {
1318
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1319
                WOLFSSL_MSG_VSNPRINTF("Buffer too small for data: %d %d", len,
1320
                        *data->data.buffer.length);
1321
            #endif
1322
0
                return BUFFER_E;
1323
0
            }
1324
            /* Copy in data and record actual length seen. */
1325
0
            XMEMCPY(data->data.buffer.data, input + idx, (size_t)len);
1326
0
            *data->data.buffer.length = (word32)len;
1327
0
            break;
1328
1329
0
        case ASN_DATA_TYPE_EXP_BUFFER:
1330
            /* Check data is same size expected. */
1331
0
            if (len != (int)data->data.ref.length) {
1332
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1333
                WOLFSSL_MSG_VSNPRINTF("Data not expected length: %d %d", len,
1334
                        data->data.ref.length);
1335
            #endif
1336
0
                return ASN_PARSE_E;
1337
0
            }
1338
            /* Check data is same as expected. */
1339
0
            if (XMEMCMP(data->data.ref.data, input + idx, (size_t)len) != 0) {
1340
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1341
                WOLFSSL_MSG("Data not as expected");
1342
            #endif
1343
0
                return ASN_PARSE_E;
1344
0
            }
1345
0
            break;
1346
1347
0
        case ASN_DATA_TYPE_MP:
1348
0
        case ASN_DATA_TYPE_MP_POS_NEG:
1349
            /* Initialize mp_int and read in big-endian byte array. */
1350
0
            if (mp_init(data->data.mp) != MP_OKAY) {
1351
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1352
                WOLFSSL_MSG_VSNPRINTF("Failed to init mp: %p", data->data.mp);
1353
            #endif
1354
0
                return MP_INIT_E;
1355
0
            }
1356
0
            FALL_THROUGH;
1357
0
        case ASN_DATA_TYPE_MP_INITED:
1358
0
            err = mp_read_unsigned_bin(data->data.mp, (byte*)input + idx,
1359
0
                                       (word32)len);
1360
0
            if (err != 0) {
1361
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1362
                WOLFSSL_MSG_VSNPRINTF("Failed to read mp: %d", err);
1363
            #endif
1364
0
                mp_clear(data->data.mp);
1365
0
                return ASN_GETINT_E;
1366
0
            }
1367
        #ifdef HAVE_WOLF_BIGINT
1368
            err = wc_bigint_from_unsigned_bin(&data->data.mp->raw, input + idx,
1369
                    len);
1370
            if (err != 0) {
1371
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1372
                WOLFSSL_MSG_VSNPRINTF("Failed to create bigint: %d", err);
1373
            #endif
1374
                mp_clear(data->data.mp);
1375
                return ASN_GETINT_E;
1376
            }
1377
        #endif /* HAVE_WOLF_BIGINT */
1378
1379
        #ifdef WOLFSSL_SP_INT_NEGATIVE
1380
            /* Don't always read as positive. */
1381
            if ((data->dataType == ASN_DATA_TYPE_MP_POS_NEG) && (!zeroPadded) &&
1382
                (input[idx] & 0x80)) {
1383
                #ifdef MP_NEG
1384
                    data->data.mp->sign = MP_NEG;
1385
                #else
1386
                    #ifdef OPENSSL_EXTRA
1387
                        /* public API wolfSSL_ASN1_INTEGER_get() depends
1388
                         * indirectly on negative bignum handling here.
1389
                         */
1390
                        #error OPENSSL_EXTRA requires negative bignum support.
1391
                    #endif
1392
                    #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1393
                    WOLFSSL_MSG_VSNPRINTF("ASN negative integer without bignum support.");
1394
                    #endif
1395
                    mp_clear(data->data.mp);
1396
                    return ASN_GETINT_E;
1397
                #endif
1398
            }
1399
        #else
1400
0
            (void)zeroPadded;
1401
0
        #endif
1402
0
            break;
1403
1404
0
        case ASN_DATA_TYPE_CHOICE:
1405
            /* Check if tag matched any of the choices specified. */
1406
0
            for (i = 0; data->data.choice[i] != 0; i++)
1407
0
                if (data->data.choice[i] == data->tag)
1408
0
                    break;
1409
0
            if (data->data.choice[i] == 0) {
1410
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1411
                WOLFSSL_MSG("Tag didn't match a choice");
1412
            #endif
1413
0
                return ASN_PARSE_E;
1414
0
            }
1415
1416
            /* Store data pointer and length for caller. */
1417
0
            data->data.ref.data = input + idx;
1418
0
            data->data.ref.length = (word32)len;
1419
0
            break;
1420
1421
0
        case ASN_DATA_TYPE_NONE:
1422
            /* Default behaviour based on tag. */
1423
0
            if (asn->tag == ASN_BOOLEAN) {
1424
                /* BOOLEAN has only one byte of data in BER. */
1425
0
                if (len != 1) {
1426
                #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1427
                    WOLFSSL_MSG_VSNPRINTF("BOOLEAN length too long: %d", len);
1428
                #endif
1429
0
                    return ASN_PARSE_E;
1430
0
                }
1431
0
                if (data->data.u8 == NULL)
1432
0
                    return BAD_STATE_E;
1433
                /* Store C boolean value. */
1434
0
                *data->data.u8 = (input[idx] != 0);
1435
0
                break;
1436
0
            }
1437
0
            if (asn->tag == ASN_TAG_NULL) {
1438
                /* NULL has no data in BER. */
1439
0
                if (len != 0) {
1440
                #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1441
                    WOLFSSL_MSG_VSNPRINTF("NULL length too long: %d", len);
1442
                #endif
1443
0
                    return ASN_EXPECT_0_E;
1444
0
                }
1445
0
                data->data.ref.data = input + idx;
1446
0
                break;
1447
0
            }
1448
0
            if (asn->tag == ASN_OBJECT_ID) {
1449
0
                word32 oidIdx = 0;
1450
                /* Store OID data pointer and length */
1451
0
                data->data.oid.data = input + idx;
1452
0
                data->data.oid.length = (word32)len;
1453
                /* Get the OID sum. */
1454
0
                err = GetOID(input + idx, &oidIdx, &data->data.oid.sum,
1455
0
                        data->data.oid.type, len);
1456
0
                if (err < 0) {
1457
                #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1458
                    WOLFSSL_MSG_VSNPRINTF("OID check failed: %d", err);
1459
                #endif
1460
0
                    return err;
1461
0
                }
1462
0
                break;
1463
0
            }
1464
1465
            /* Otherwise store data pointer and length. */
1466
0
            data->data.ref.data = input + idx;
1467
0
            data->data.ref.length = (word32)len;
1468
0
            break;
1469
1470
    #ifdef DEBUG_WOLFSSL
1471
        default:
1472
            /* Bad ASN data type. */
1473
        #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1474
            WOLFSSL_MSG_VSNPRINTF("Bad data type: %d", data->dataType);
1475
        #endif
1476
            return BAD_STATE_E;
1477
    #endif
1478
0
    }
1479
1480
0
    return 0;
1481
0
}
1482
1483
/* Get the ASN.1 items from the BER encoding.
1484
 *
1485
 * @param [in]      asn       ASN.1 items expected.
1486
 * @param [in]      data      Data array to place found items into.
1487
 * @param [in]      count     Count of items to parse.
1488
 * @param [in]      complete  Whether the whole buffer is to be used up.
1489
 * @param [in]      input     BER encoded data.
1490
 * @param [in, out] inOutIdx  On in, starting index of data.
1491
 *                            On out, end of parsed data.
1492
 * @param [in]      length    Length of input buffer.
1493
 * @return  0 on success.
1494
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
1495
 *          is invalid.
1496
 * @return  BUFFER_E when data in buffer is too small.
1497
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
1498
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
1499
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
1500
 *          non-zero length.
1501
 * @return  MP_INIT_E when the unable to initialize an mp_int.
1502
 * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
1503
 * @return  BAD_STATE_E when the data type is not supported.
1504
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
1505
 */
1506
int GetASN_Items(const ASNItem* asn, ASNGetData *data, int count, int complete,
1507
                 const byte* input, word32* inOutIdx, word32 length)
1508
0
{
1509
0
    int    i;
1510
0
    int    j;
1511
0
    int    err;
1512
0
    int    len;
1513
    /* Current index into buffer. */
1514
0
    word32 idx = *inOutIdx;
1515
    /* Declare the end index array. */
1516
0
    word32 endIdx[GET_ASN_MAX_DEPTH];
1517
    /* Set choices to -1 to indicate they haven't been seen or found. */
1518
0
    signed char   choiceMet[GET_ASN_MAX_CHOICES] = { -1, -1 };
1519
    /* Not matching a choice right now. */
1520
0
    int    choice = 0;
1521
    /* Current depth of ASN.1 item. */
1522
0
    int    depth;
1523
    /* Minimum depth value seen. */
1524
0
    int    minDepth;
1525
    /* Integer had a zero prepended. */
1526
0
    int    zeroPadded;
1527
0
    word32 tmpW32Val;
1528
0
    signed char tmpScharVal;
1529
1530
#ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1531
    WOLFSSL_ENTER("GetASN_Items");
1532
#endif
1533
1534
    /* Set the end index at each depth to be the length. */
1535
0
    for (i=0; i<GET_ASN_MAX_DEPTH; i++) {
1536
0
        endIdx[i] = length;
1537
0
    }
1538
1539
    /* Start depth at first items depth. */
1540
0
    minDepth = depth = asn[0].depth;
1541
    /* Check every ASN.1 item. */
1542
0
    for (i = 0; i < count; i++) {
1543
        /* Store offset of ASN.1 item. */
1544
0
        data[i].offset = idx;
1545
        /* Length of data in ASN.1 item starts empty. */
1546
0
        data[i].length = 0;
1547
        /* Get current item depth. */
1548
0
        depth = asn[i].depth;
1549
    #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1550
        if (depth > GET_ASN_MAX_DEPTH) {
1551
            WOLFSSL_MSG("Depth in template too large");
1552
            return ASN_PARSE_E;
1553
        }
1554
    #endif
1555
        /* Keep track of minimum depth. */
1556
0
        if (depth < minDepth) {
1557
0
            minDepth = depth;
1558
0
        }
1559
1560
        /* Reset choice if different from previous. */
1561
0
        if (choice > 0 && asn[i].optional != choice) {
1562
0
            choice = 0;
1563
0
        }
1564
        /* Check if first of numbered choice. */
1565
0
        if (choice == 0 && asn[i].optional > 1) {
1566
0
            choice = asn[i].optional;
1567
0
            tmpScharVal = choiceMet[choice - 2];
1568
0
            XFENCE(); /* Prevent memory access */
1569
0
            if (tmpScharVal == -1) {
1570
                /* Choice seen but not found a match yet. */
1571
0
                choiceMet[choice - 2] = 0;
1572
0
            }
1573
0
        }
1574
1575
        /* Check for end of data or not a choice and tag not matching. */
1576
0
        tmpW32Val = endIdx[depth];
1577
0
        XFENCE(); /* Prevent memory access */
1578
0
        if (idx == tmpW32Val || (data[i].dataType != ASN_DATA_TYPE_CHOICE &&
1579
0
                              (input[idx] & ~ASN_CONSTRUCTED) != asn[i].tag)) {
1580
0
            if (asn[i].optional) {
1581
                /* Skip over ASN.1 items underneath this optional item. */
1582
0
                for (j = i + 1; j < count; j++) {
1583
0
                    if (asn[i].depth >= asn[j].depth)
1584
0
                        break;
1585
0
                    data[j].offset = idx;
1586
0
                    data[j].length = 0;
1587
0
                }
1588
0
                i = j - 1;
1589
0
                continue;
1590
0
            }
1591
1592
            /* Check for end of data. */
1593
0
            if (idx == length) {
1594
        #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1595
                WOLFSSL_MSG_VSNPRINTF(
1596
                    "%2d: %4d %4d %c %*s %-16s%*s  (index past end)",
1597
                    i, data[i].offset, data[i].length,
1598
                    asn[i].constructed ? '+' : ' ', asn[i].depth, "",
1599
                    TagString(asn[i].tag), 6 - asn[i].depth, "");
1600
                WOLFSSL_MSG_VSNPRINTF("Index past end of data: %d %d", idx,
1601
                        length);
1602
        #endif
1603
0
                return BUFFER_E;
1604
0
            }
1605
        #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1606
            /* Show expected versus found. */
1607
            WOLFSSL_MSG_VSNPRINTF(
1608
                "%2d: %4d %4d %c %*s %-16s%*s  Tag=0x%02x (%s)",
1609
                i, data[i].offset, data[i].length,
1610
                asn[i].constructed ? '+' : ' ', asn[i].depth, "",
1611
                TagString(asn[i].tag), 6 - asn[i].depth, "",
1612
                input[idx], TagString(input[idx]));
1613
        #endif
1614
            /* Check for end of data at this depth. */
1615
0
            if (idx == endIdx[depth]) {
1616
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1617
                WOLFSSL_MSG_VSNPRINTF("Index past outer item: %d %d", idx,
1618
                        endIdx[depth]);
1619
            #endif
1620
0
                return ASN_PARSE_E;
1621
0
            }
1622
1623
            /* Expecting an OBJECT_ID */
1624
0
            if (asn[i].tag == ASN_OBJECT_ID) {
1625
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1626
                WOLFSSL_MSG("Expecting OBJECT ID");
1627
            #endif
1628
0
                return ASN_OBJECT_ID_E;
1629
0
            }
1630
            /* Expecting a BIT_STRING */
1631
0
            if (asn[i].tag == ASN_BIT_STRING) {
1632
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1633
                WOLFSSL_MSG("Expecting BIT STRING");
1634
            #endif
1635
0
                return ASN_BITSTR_E;
1636
0
            }
1637
            /* Not the expected tag. */
1638
        #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1639
            WOLFSSL_MSG("Bad tag");
1640
        #endif
1641
0
            return ASN_PARSE_E;
1642
0
        }
1643
1644
        /* Store found tag in data. */
1645
0
        data[i].tag = input[idx];
1646
0
        XFENCE(); /* Prevent memory access */
1647
0
        if (data[i].dataType != ASN_DATA_TYPE_CHOICE) {
1648
0
            int constructed = (input[idx] & ASN_CONSTRUCTED) == ASN_CONSTRUCTED;
1649
            /* Check constructed match expected for non-choice ASN.1 item. */
1650
0
            if (asn[i].constructed != constructed) {
1651
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1652
                WOLFSSL_MSG_VSNPRINTF(
1653
                        "%2d: %4d %4d %c %*s %-16s%*s  Tag=0x%02x (%s)",
1654
                        i, data[i].offset, data[i].length,
1655
                        asn[i].constructed ? '+' : ' ', asn[i].depth, "",
1656
                        TagString(asn[i].tag), 6 - asn[i].depth, "",
1657
                        input[idx], TagString(input[idx]));
1658
                if (!constructed) {
1659
                    WOLFSSL_MSG("Not constructed");
1660
                }
1661
                else {
1662
                    WOLFSSL_MSG("Not expected to be constructed");
1663
                }
1664
            #endif
1665
0
                return ASN_PARSE_E;
1666
0
            }
1667
0
        }
1668
        /* Move index to start of length. */
1669
0
        idx++;
1670
        /* Get the encoded length. */
1671
0
        if (GetASN_Length(input, &idx, &len, endIdx[depth], 1) < 0) {
1672
        #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1673
            WOLFSSL_MSG_VSNPRINTF("%2d: idx=%d len=%d end=%d", i, idx, len,
1674
                    endIdx[depth]);
1675
        #endif
1676
0
            return ASN_PARSE_E;
1677
0
        }
1678
        /* Store length of data. */
1679
0
        data[i].length = (word32)len;
1680
        /* Note the max length of items under this one. */
1681
0
        endIdx[depth + 1] = idx + (word32)len;
1682
0
        if (choice > 1) {
1683
            /* Note we found a number choice. */
1684
0
            choiceMet[choice - 2] = 1;
1685
0
        }
1686
1687
    #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1688
        WOLFSSL_MSG_VSNPRINTF("%2d: %4d %4d %c %*s %-16s", i,
1689
                data[i].offset, data[i].length, asn[i].constructed ? '+' : ' ',
1690
                asn[i].depth, "", TagString(data[i].tag));
1691
    #endif
1692
1693
        /* Assume no zero padding on INTEGER. */
1694
0
        zeroPadded = 0;
1695
        /* Check data types that prepended a byte. */
1696
0
        if (asn[i].tag == ASN_INTEGER) {
1697
            /* Check validity of first byte. */
1698
0
            err = GetASN_Integer(input, idx, len,
1699
0
                    data[i].dataType == ASN_DATA_TYPE_MP ||
1700
0
                    data[i].dataType == ASN_DATA_TYPE_MP_INITED);
1701
0
            if (err != 0)
1702
0
                return err;
1703
0
            if (len > 1 && input[idx] == 0) {
1704
0
                zeroPadded = 1;
1705
                /* Move over prepended byte. */
1706
0
                idx++;
1707
0
                len--;
1708
0
            }
1709
0
        }
1710
0
        else if (asn[i].tag == ASN_BIT_STRING) {
1711
            /* Check prepended byte is correct. */
1712
0
            err = GetASN_BitString(input, idx, len);
1713
0
            if (err != 0)
1714
0
                return err;
1715
            /* Move over prepended byte. */
1716
0
            idx++;
1717
0
            len--;
1718
0
        }
1719
0
    #ifndef WOLFSSL_NO_ASN_STRICT
1720
0
        else if ((asn[i].tag == ASN_UTF8STRING) ||
1721
0
                 (data[i].tag == ASN_UTF8STRING)) {
1722
            /* Check validity of data. */
1723
0
            err = GetASN_UTF8String(input, idx, len);
1724
0
            if (err != 0)
1725
0
                return err;
1726
0
        }
1727
0
    #endif
1728
0
        else if (asn[i].tag == ASN_OBJECT_ID) {
1729
            /* Check validity of data. */
1730
0
            err = GetASN_ObjectId(input, idx, len);
1731
0
            if (err != 0)
1732
0
                return err;
1733
0
        }
1734
1735
        /* Don't parse data if only header required. */
1736
0
        if (asn[i].headerOnly) {
1737
            /* Store reference to data and length. */
1738
0
            data[i].data.ref.data = input + idx;
1739
0
            data[i].data.ref.length = (word32)len;
1740
0
            continue;
1741
0
        }
1742
1743
        /* Store the data at idx in the ASN data item. */
1744
0
        err = GetASN_StoreData(&asn[i], &data[i], input, idx, len, zeroPadded);
1745
0
        if (err != 0) {
1746
0
            return err;
1747
0
        }
1748
1749
        /* Move index to next item. */
1750
0
        idx += (word32)len;
1751
1752
        /* When matched numbered choice ... */
1753
0
        if (asn[i].optional > 1) {
1754
            /* Skip over other ASN.1 items of the same number. */
1755
0
            for (j = i + 1; j < count; j++) {
1756
0
                if (asn[j].depth <= asn[i].depth &&
1757
0
                                           asn[j].optional != asn[i].optional) {
1758
0
                   break;
1759
0
                }
1760
0
            }
1761
0
            i = j - 1;
1762
0
        }
1763
0
    }
1764
1765
0
    if (complete) {
1766
        /* When expecting ASN.1 items to completely use data, check we did. */
1767
0
        for (j = depth; j > minDepth; j--) {
1768
0
            if (idx < endIdx[j]) {
1769
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1770
                WOLFSSL_MSG_VSNPRINTF(
1771
                    "More data in constructed item at depth: %d", j - 1);
1772
            #endif
1773
0
                return ASN_PARSE_E;
1774
0
            }
1775
0
        }
1776
0
    }
1777
1778
    /* Check all choices where met - found an item for them. */
1779
0
    for (j = 0; j < GET_ASN_MAX_CHOICES; j++) {
1780
0
        if (choiceMet[j] == 0) {
1781
        #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1782
            WOLFSSL_MSG_VSNPRINTF("No choice seen: %d", j + 2);
1783
        #endif
1784
0
            return ASN_PARSE_E;
1785
0
        }
1786
0
    }
1787
1788
    /* Return index after ASN.1 data has been parsed. */
1789
0
    *inOutIdx = idx;
1790
1791
0
    return 0;
1792
0
}
1793
1794
#ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
1795
/* Calculate the size of the DER encoding.
1796
 *
1797
 * Call SetASN_Items() to write encoding to a buffer.
1798
 *
1799
 * @param [in]      asn    ASN.1 items to encode.
1800
 * @param [in, out] data   Data to place in each item. Lengths set were not
1801
 *                         known.
1802
 * @param [in]      count  Count of items to encode.
1803
 * @param [out]     len    Length of the DER encoding.
1804
 * @return  Size of the DER encoding in bytes.
1805
 */
1806
static int SizeASN_ItemsDebug(const char* name, const ASNItem* asn,
1807
    ASNSetData *data, int count, int* encSz)
1808
{
1809
    WOLFSSL_MSG_VSNPRINTF("TEMPLATE: %s", name);
1810
    return SizeASN_Items(asn, data, count, encSz);
1811
}
1812
1813
/* Creates the DER encoding of the ASN.1 items.
1814
 *
1815
 * Assumes the output buffer is large enough to hold encoding.
1816
 * Must call SizeASN_Items() to determine size of encoding and offsets.
1817
 *
1818
 * Displays the template name first.
1819
 *
1820
 * @param [in]      name    Name of ASN.1 template.
1821
 * @param [in]      asn     ASN.1 items to encode.
1822
 * @param [in]      data    Data to place in each item.
1823
 * @param [in]      count   Count of items to encode.
1824
 * @param [in, out] output  Buffer to write encoding into.
1825
 * @return  Size of the DER encoding in bytes.
1826
 */
1827
static int SetASN_ItemsDebug(const char* name, const ASNItem* asn,
1828
    ASNSetData *data, int count, byte* output)
1829
{
1830
    WOLFSSL_MSG_VSNPRINTF("TEMPLATE: %s", name);
1831
    return SetASN_Items(asn, data, count, output);
1832
}
1833
1834
/* Get the ASN.1 items from the BER encoding.
1835
 *
1836
 * Displays the template name first.
1837
 *
1838
 * @param [in]      name      Name of ASN.1 template.
1839
 * @param [in]      asn       ASN.1 items expected.
1840
 * @param [in]      data      Data array to place found items into.
1841
 * @param [in]      count     Count of items to parse.
1842
 * @param [in]      complete  Whether the whole buffer is to be used up.
1843
 * @param [in]      input     BER encoded data.
1844
 * @param [in, out] inOutIdx  On in, starting index of data.
1845
 *                            On out, end of parsed data.
1846
 * @param [in]      maxIdx    Maximum index of input data.
1847
 * @return  0 on success.
1848
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
1849
 * is invalid.
1850
 * @return  BUFFER_E when data in buffer is too small.
1851
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
1852
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
1853
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
1854
 *          non-zero length.
1855
 * @return  MP_INIT_E when the unable to initialize an mp_int.
1856
 * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
1857
 * @return  BAD_STATE_E when the data type is not supported.
1858
 */
1859
static int GetASN_ItemsDebug(const char* name, const ASNItem* asn,
1860
    ASNGetData *data, int count, int complete, const byte* input,
1861
    word32* inOutIdx, word32 maxIdx)
1862
{
1863
    WOLFSSL_MSG_VSNPRINTF("TEMPLATE: %s", name);
1864
    return GetASN_Items(asn, data, count, complete, input, inOutIdx, maxIdx);
1865
}
1866
1867
/* Calculate the size of the DER encoding.
1868
 *
1869
 * Call SetASN_Items() to write encoding to a buffer.
1870
 *
1871
 * @param [in]      asn    ASN.1 items to encode.
1872
 * @param [in, out] data   Data to place in each item. Lengths set were not
1873
 *                         known.
1874
 * @param [in]      count  Count of items to encode.
1875
 * @param [out]     len    Length of the DER encoding.
1876
 * @return  Size of the DER encoding in bytes.
1877
 */
1878
#define SizeASN_Items(asn, data, count, encSz)  \
1879
    SizeASN_ItemsDebug(#asn, asn, data, count, encSz)
1880
1881
/* Creates the DER encoding of the ASN.1 items.
1882
 *
1883
 * Assumes the output buffer is large enough to hold encoding.
1884
 * Must call SizeASN_Items() to determine size of encoding and offsets.
1885
 *
1886
 * Displays the template name first.
1887
 *
1888
 * @param [in]      name    Name of ASN.1 template.
1889
 * @param [in]      asn     ASN.1 items to encode.
1890
 * @param [in]      data    Data to place in each item.
1891
 * @param [in]      count   Count of items to encode.
1892
 * @param [in, out] output  Buffer to write encoding into.
1893
 * @return  Size of the DER encoding in bytes.
1894
 */
1895
#define SetASN_Items(asn, data, count, output)  \
1896
    SetASN_ItemsDebug(#asn, asn, data, count, output)
1897
1898
/* Get the ASN.1 items from the BER encoding.
1899
 *
1900
 * Displays the template name first.
1901
 *
1902
 * @param [in]      name      Name of ASN.1 template.
1903
 * @param [in]      asn       ASN.1 items expected.
1904
 * @param [in]      data      Data array to place found items into.
1905
 * @param [in]      count     Count of items to parse.
1906
 * @param [in]      complete  Whether the whole buffer is to be used up.
1907
 * @param [in]      input     BER encoded data.
1908
 * @param [in, out] inOutIdx  On in, starting index of data.
1909
 *                            On out, end of parsed data.
1910
 * @param [in]      maxIdx    Maximum index of input data.
1911
 * @return  0 on success.
1912
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
1913
 * is invalid.
1914
 * @return  BUFFER_E when data in buffer is too small.
1915
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
1916
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
1917
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
1918
 *          non-zero length.
1919
 * @return  MP_INIT_E when the unable to initialize an mp_int.
1920
 * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
1921
 * @return  BAD_STATE_E when the data type is not supported.
1922
 */
1923
#define GetASN_Items(asn, data, count, complete, input, inOutIdx, maxIdx)  \
1924
    GetASN_ItemsDebug(#asn, asn, data, count, complete, input, inOutIdx, maxIdx)
1925
#endif /* WOLFSSL_DEBUG_ASN_TEMPLATE */
1926
1927
/* Decode a BER encoded constructed sequence.
1928
 *
1929
 * @param [in]       input     Buffer of BER encoded data.
1930
 * @param [in, out]  inOutIdx  On in, index to start decoding from.
1931
 *                             On out, index of next encoded byte.
1932
 * @param [out]      len       Length of data under SEQUENCE.
1933
 * @param [in]       maxIdx    Maximum index of data. Index of byte after SEQ.
1934
 * @param [in]       complete  All data used with SEQUENCE and data under.
1935
 * @return  0 on success.
1936
 * @return  BUFFER_E when not enough data to complete decode.
1937
 * @return  ASN_PARSE when decoding failed.
1938
 */
1939
static int GetASN_Sequence(const byte* input, word32* inOutIdx, int* len,
1940
                           word32 maxIdx, int complete)
1941
0
{
1942
0
    int ret = 0;
1943
0
    word32 idx = *inOutIdx;
1944
1945
    /* Check buffer big enough for tag. */
1946
0
    if (idx + 1 > maxIdx) {
1947
0
        ret = BUFFER_E;
1948
0
    }
1949
    /* Check it is a constructed SEQUENCE. */
1950
0
    if ((ret == 0) && (input[idx++] != (ASN_SEQUENCE | ASN_CONSTRUCTED))) {
1951
0
        ret = ASN_PARSE_E;
1952
0
    }
1953
    /* Get the length. */
1954
0
    if ((ret == 0) && (GetASN_Length(input, &idx, len, maxIdx, 1) < 0)) {
1955
0
        ret = ASN_PARSE_E;
1956
0
    }
1957
    /* Check all data used if complete set. */
1958
0
    if ((ret == 0) && complete && (idx + (word32)*len != maxIdx)) {
1959
0
        ret = ASN_PARSE_E;
1960
0
    }
1961
0
    if (ret == 0) {
1962
        /* Return index of next byte of encoded data. */
1963
0
        *inOutIdx = idx;
1964
0
    }
1965
1966
0
    return ret;
1967
0
}
1968
1969
1970
#ifdef WOLFSSL_ASN_TEMPLATE_TYPE_CHECK
1971
/* Setup ASN data item to get an 8-bit number.
1972
 *
1973
 * @param [in] dataASN  Dynamic ASN data item.
1974
 * @param [in] num      Pointer to an 8-bit variable.
1975
 */
1976
void GetASN_Int8Bit(ASNGetData *dataASN, byte* num)
1977
{
1978
    dataASN->dataType = ASN_DATA_TYPE_WORD8;
1979
    dataASN->data.u8  = num;
1980
}
1981
1982
/* Setup ASN data item to get a 16-bit number.
1983
 *
1984
 * @param [in] dataASN  Dynamic ASN data item.
1985
 * @param [in] num      Pointer to a 16-bit variable.
1986
 */
1987
void GetASN_Int16Bit(ASNGetData *dataASN, word16* num)
1988
{
1989
    dataASN->dataType = ASN_DATA_TYPE_WORD16;
1990
    dataASN->data.u16 = num;
1991
}
1992
1993
/* Setup ASN data item to get a 32-bit number.
1994
 *
1995
 * @param [in] dataASN  Dynamic ASN data item.
1996
 * @param [in] num      Pointer to a 32-bit variable.
1997
 */
1998
void GetASN_Int32Bit(ASNGetData *dataASN, word32* num)
1999
{
2000
    dataASN->dataType = ASN_DATA_TYPE_WORD32;
2001
    dataASN->data.u32 = num;
2002
}
2003
2004
/* Setup ASN data item to get data into a buffer of a specific length.
2005
 *
2006
 * @param [in] dataASN  Dynamic ASN data item.
2007
 * @param [in] data     Buffer to hold data.
2008
 * @param [in] length   Length of buffer in bytes.
2009
 */
2010
void GetASN_Buffer(ASNGetData *dataASN, byte* data, word32* length)
2011
{
2012
    dataASN->dataType           = ASN_DATA_TYPE_BUFFER;
2013
    dataASN->data.buffer.data   = data;
2014
    dataASN->data.buffer.length = length;
2015
}
2016
2017
/* Setup ASN data item to check parsed data against expected buffer.
2018
 *
2019
 * @param [in] dataASN  Dynamic ASN data item.
2020
 * @param [in] data     Buffer containing expected data.
2021
 * @param [in] length   Length of buffer in bytes.
2022
 */
2023
void GetASN_ExpBuffer(ASNGetData *dataASN, const byte* data, word32 length)
2024
{
2025
    dataASN->dataType        = ASN_DATA_TYPE_EXP_BUFFER;
2026
    dataASN->data.ref.data   = data;
2027
    dataASN->data.ref.length = length;
2028
}
2029
2030
/* Setup ASN data item to get a number into an mp_int.
2031
 *
2032
 * @param [in] dataASN  Dynamic ASN data item.
2033
 * @param [in] num      Multi-precision number object.
2034
 */
2035
void GetASN_MP(ASNGetData *dataASN, mp_int* num)
2036
{
2037
    dataASN->dataType = ASN_DATA_TYPE_MP;
2038
    dataASN->data.mp  = num;
2039
}
2040
2041
/* Setup ASN data item to get a number into an mp_int that is initialized.
2042
 *
2043
 * @param [in] dataASN  Dynamic ASN data item.
2044
 * @param [in] num      Multi-precision number object.
2045
 */
2046
void GetASN_MP_Inited(ASNGetData *dataASN, mp_int* num)
2047
{
2048
    dataASN->dataType = ASN_DATA_TYPE_MP_INITED;
2049
    dataASN->data.mp  = num;
2050
}
2051
2052
/* Setup ASN data item to get a positive or negative number into an mp_int.
2053
 *
2054
 * @param [in] dataASN  Dynamic ASN data item.
2055
 * @param [in] num      Multi-precision number object.
2056
 */
2057
void GetASN_MP_PosNeg(ASNGetData *dataASN, mp_int* num)
2058
{
2059
    dataASN->dataType = ASN_DATA_TYPE_MP_POS_NEG;
2060
    dataASN->data.mp  = num;
2061
}
2062
2063
/* Setup ASN data item to be a choice of tags.
2064
 *
2065
 * @param [in] dataASN  Dynamic ASN data item.
2066
 * @param [in] options  0 terminated list of tags that are valid.
2067
 */
2068
void GetASN_Choice(ASNGetData *dataASN, const byte* options)
2069
{
2070
    dataASN->dataType    = ASN_DATA_TYPE_CHOICE;
2071
    dataASN->data.choice = options;
2072
}
2073
2074
/* Setup ASN data item to get a boolean value.
2075
 *
2076
 * @param [in] dataASN  Dynamic ASN data item.
2077
 * @param [in] num      Pointer to an 8-bit variable.
2078
 */
2079
void GetASN_Boolean(ASNGetData *dataASN, byte* num)
2080
{
2081
    dataASN->dataType    = ASN_DATA_TYPE_NONE;
2082
    dataASN->data.choice = num;
2083
}
2084
2085
/* Setup ASN data item to be a an OID of a specific type.
2086
 *
2087
 * @param [in] dataASN  Dynamic ASN data item.
2088
 * @param [in] oidType  Type of OID to expect.
2089
 */
2090
void GetASN_OID(ASNGetData *dataASN, int oidType)
2091
{
2092
    dataASN->data.oid.type = oidType;
2093
}
2094
2095
/* Get the data and length from an ASN data item.
2096
 *
2097
 * @param [in]  dataASN  Dynamic ASN data item.
2098
 * @param [out] data     Pointer to data of item.
2099
 * @param [out] length   Length of buffer in bytes.
2100
 */
2101
void GetASN_GetConstRef(ASNGetData * dataASN, const byte** data, word32* length)
2102
{
2103
    *data   = dataASN->data.ref.data;
2104
    *length = dataASN->data.ref.length;
2105
}
2106
2107
/* Get the data and length from an ASN data item.
2108
 *
2109
 * @param [in]  dataASN  Dynamic ASN data item.
2110
 * @param [out] data     Pointer to data of item.
2111
 * @param [out] length   Length of buffer in bytes.
2112
 */
2113
void GetASN_GetRef(ASNGetData * dataASN, byte** data, word32* length)
2114
{
2115
    *data   = (byte*)dataASN->data.ref.data;
2116
    *length =        dataASN->data.ref.length;
2117
}
2118
2119
/* Get the data and length from an ASN data item that is an OID.
2120
 *
2121
 * @param [in]  dataASN  Dynamic ASN data item.
2122
 * @param [out] data     Pointer to .
2123
 * @param [out] length   Length of buffer in bytes.
2124
 */
2125
void GetASN_OIDData(ASNGetData * dataASN, byte** data, word32* length)
2126
{
2127
    *data   = (byte*)dataASN->data.oid.data;
2128
    *length =        dataASN->data.oid.length;
2129
}
2130
2131
/* Setup an ASN data item to set a boolean.
2132
 *
2133
 * @param [in] dataASN  Dynamic ASN data item.
2134
 * @param [in] val      Boolean value.
2135
 */
2136
void SetASN_Boolean(ASNSetData *dataASN, byte val)
2137
{
2138
    dataASN->dataType = ASN_DATA_TYPE_NONE;
2139
    dataASN->data.u8  = val;
2140
}
2141
2142
/* Setup an ASN data item to set an 8-bit number.
2143
 *
2144
 * @param [in] dataASN  Dynamic ASN data item.
2145
 * @param [in] num      8-bit number to set.
2146
 */
2147
void SetASN_Int8Bit(ASNSetData *dataASN, byte num)
2148
{
2149
    dataASN->dataType = ASN_DATA_TYPE_WORD8;
2150
    dataASN->data.u8  = num;
2151
}
2152
2153
/* Setup an ASN data item to set a 16-bit number.
2154
 *
2155
 * @param [in] dataASN  Dynamic ASN data item.
2156
 * @param [in] num      16-bit number to set.
2157
 */
2158
void SetASN_Int16Bit(ASNSetData *dataASN, word16 num)
2159
{
2160
    dataASN->dataType = ASN_DATA_TYPE_WORD16;
2161
    dataASN->data.u16 = num;
2162
}
2163
2164
/* Setup an ASN data item to set the data in a buffer.
2165
 *
2166
 * @param [in] dataASN  Dynamic ASN data item.
2167
 * @param [in] data     Buffer containing data to set.
2168
 * @param [in] length   Length of data in buffer in bytes.
2169
 */
2170
void SetASN_Buffer(ASNSetData *dataASN, const byte* data, word32 length)
2171
{
2172
    dataASN->data.buffer.data   = data;
2173
    dataASN->data.buffer.length = length;
2174
}
2175
2176
/* Setup an ASN data item to set the DER encode data in a buffer.
2177
 *
2178
 * @param [in] dataASN  Dynamic ASN data item.
2179
 * @param [in] data     Buffer containing BER encoded data to set.
2180
 * @param [in] length   Length of data in buffer in bytes.
2181
 */
2182
void SetASN_ReplaceBuffer(ASNSetData *dataASN, const byte* data, word32 length)
2183
{
2184
    dataASN->dataType           = ASN_DATA_TYPE_REPLACE_BUFFER;
2185
    dataASN->data.buffer.data   = data;
2186
    dataASN->data.buffer.length = length;
2187
}
2188
2189
/* Setup an ASN data item to set an multi-precision number.
2190
 *
2191
 * @param [in] dataASN  Dynamic ASN data item.
2192
 * @param [in] num      Multi-precision number.
2193
 */
2194
void SetASN_MP(ASNSetData *dataASN, mp_int* num)
2195
{
2196
    dataASN->dataType = ASN_DATA_TYPE_MP;
2197
    dataASN->data.mp  = num;
2198
}
2199
2200
/* Setup an ASN data item to set an OID based on id and type.
2201
 *
2202
 * oid and oidType pair are unique.
2203
 *
2204
 * @param [in] dataASN  Dynamic ASN data item.
2205
 * @param [in] oid      OID identifier.
2206
 * @param [in] oidType  Type of OID.
2207
 */
2208
void SetASN_OID(ASNSetData *dataASN, int oid, int oidType)
2209
{
2210
    dataASN->data.buffer.data = OidFromId(oid, oidType,
2211
                                                  &dataASN->data.buffer.length);
2212
}
2213
#endif /* WOLFSSL_ASN_TEMPLATE_TYPE_CHECK */
2214
2215
#ifdef CRLDP_VALIDATE_DATA
2216
/* Get the data of the BIT_STRING as a 16-bit number.
2217
 *
2218
 * @param [in]  dataASN  Dynamic ASN data item.
2219
 * @param [out] val      ASN.1 item's data as a 16-bit number.
2220
 * @return  0 on success.
2221
 * @return  ASN_PARSE_E when BITSTRING value is more than 2 bytes.
2222
 * @return  ASN_PARSE_E when unused bits of BITSTRING is invalid.
2223
 */
2224
static int GetASN_BitString_Int16Bit(ASNGetData* dataASN, word16* val)
2225
{
2226
    int ret;
2227
    int i;
2228
    const byte* input = dataASN->data.ref.data;
2229
    int length = dataASN->data.ref.length;
2230
2231
    /* Validate the BIT_STRING data. */
2232
    ret = GetASN_BitString(input, 0, length);
2233
    if (ret == 0) {
2234
        /* Skip unused bits byte. */
2235
        input++;
2236
        length--;
2237
2238
        /* Check the data is usable. */
2239
        if (length == 0 || length > 2) {
2240
#ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
2241
            WOLFSSL_MSG_VSNPRINTF("Expecting 1 or 2 bytes: %d", length);
2242
#endif
2243
            ret = ASN_PARSE_E;
2244
        }
2245
    }
2246
    if (ret == 0) {
2247
        /* Fill 16-bit var with all the data. */
2248
        *val = 0;
2249
        for (i = 0; i < length; i++) {
2250
            *val <<= 8;
2251
            *val |= input[i];
2252
        }
2253
    }
2254
    return ret;
2255
}
2256
#endif /* CRLDP_VALIDATE_DATA */
2257
2258
#endif /* WOLFSSL_ASN_TEMPLATE */
2259
2260
2261
/* Decode the BER/DER length field.
2262
 *
2263
 * @param [in]      input     BER encoded data.
2264
 * @param [in, out] inOutIdx  On in, starting index of length.
2265
 *                            On out, end of parsed length.
2266
 * @param [out]     len       Length value decoded.
2267
 * @param [in]      maxIdx    Maximum index of input data.
2268
 * @return  Length on success.
2269
 * @return  ASN_PARSE_E if the encoding is invalid.
2270
 * @return  BUFFER_E when not enough data to complete decode.
2271
 */
2272
int GetLength(const byte* input, word32* inOutIdx, int* len, word32 maxIdx)
2273
0
{
2274
0
    return GetLength_ex(input, inOutIdx, len, maxIdx, 1);
2275
0
}
2276
2277
2278
/* Decode the BER/DER length field and check the length is valid on request.
2279
 *
2280
 * BER/DER has Type-Length-Value triplets.
2281
 * When requested will check that the Length decoded, indicating the number
2282
 * of bytes in the Value, is available in the buffer after the Length bytes.
2283
 *
2284
 * Only supporting a length upto INT_MAX.
2285
 *
2286
 * @param [in]      input     BER encoded data.
2287
 * @param [in, out] inOutIdx  On in, starting index of length.
2288
 *                            On out, end of parsed length.
2289
 * @param [out]     len       Length value decoded.
2290
 * @param [in]      maxIdx    Maximum index of input data.
2291
 * @param [in]      check     Whether to check the buffer has at least the
2292
 *                            decoded length of bytes remaining.
2293
 * @return  Length on success.
2294
 * @return  ASN_PARSE_E if the encoding is invalid.
2295
 * @return  BUFFER_E when not enough data to complete decode.
2296
 */
2297
int GetLength_ex(const byte* input, word32* inOutIdx, int* len, word32 maxIdx,
2298
                 int check)
2299
0
{
2300
0
    int     length = 0;
2301
0
    word32  idx = (word32)*inOutIdx;
2302
0
    byte    b;
2303
2304
    /* Ensure zero return length on error. */
2305
0
    *len = 0;
2306
2307
    /* Check there is at least one byte available containing length information.
2308
     */
2309
0
    if ((idx + 1) > maxIdx) {
2310
0
        WOLFSSL_MSG("GetLength - bad index on input");
2311
0
        return BUFFER_E;
2312
0
    }
2313
2314
    /* Get the first length byte. */
2315
0
    b = input[idx++];
2316
    /* Check if the first byte indicates the count of bytes. */
2317
0
    if (b >= ASN_LONG_LENGTH) {
2318
        /* Bottom 7 bits are the number of bytes to calculate length with.
2319
         * Note: 0 indicates indefinite length encoding *not* 0 bytes of length.
2320
         */
2321
0
        int bytes = (int)(b & 0x7F);
2322
0
        int minLen;
2323
2324
        /* Calculate minimum length to be encoded with bytes. */
2325
0
        if (b == ASN_INDEF_LENGTH) {
2326
            /* Indefinite length encoding - no length bytes. */
2327
0
            minLen = 0;
2328
0
        }
2329
0
        else if (bytes == 1) {
2330
0
            minLen = 0x80;
2331
0
        }
2332
        /* Only support up to the number of bytes that fit into return var. */
2333
0
        else if (bytes > (int)sizeof(length)) {
2334
0
            WOLFSSL_MSG("GetLength - overlong data length spec");
2335
0
            return ASN_PARSE_E;
2336
0
        }
2337
0
        else {
2338
0
            minLen = 1 << ((bytes - 1) * 8);
2339
0
        }
2340
2341
        /* Check the number of bytes required are available. */
2342
0
        if ((idx + (word32)bytes) > maxIdx) {
2343
0
            WOLFSSL_MSG("GetLength - bad long length");
2344
0
            return BUFFER_E;
2345
0
        }
2346
2347
        /* Big-endian encoding of number. */
2348
0
        while (bytes--) {
2349
0
            b = input[idx++];
2350
0
            length = (length << 8) | b;
2351
0
        }
2352
        /* Negative value indicates we overflowed the signed int. */
2353
0
        if (length < 0) {
2354
0
            return ASN_PARSE_E;
2355
0
        }
2356
        /* Don't allow lengths that are longer than strictly required. */
2357
0
        if (length < minLen) {
2358
0
            return ASN_PARSE_E;
2359
0
        }
2360
0
    }
2361
0
    else {
2362
        /* Length in first byte. */
2363
0
        length = b;
2364
0
    }
2365
2366
    /* When requested, check the buffer has at least length bytes left. */
2367
0
    if (check && ((idx + (word32)length) > maxIdx)) {
2368
0
        WOLFSSL_MSG("GetLength - value exceeds buffer length");
2369
0
        return BUFFER_E;
2370
0
    }
2371
2372
    /* Return index after length encoding. */
2373
0
    *inOutIdx = idx;
2374
    /* Return length if valid. */
2375
0
    if (length > 0) {
2376
0
        *len = length;
2377
0
    }
2378
2379
    /* Return length calculated or error code. */
2380
0
    return length;
2381
0
}
2382
2383
2384
/* Gets the tag of next BER/DER encoded item.
2385
 *
2386
 * Checks there is enough data in the buffer for the tag byte.
2387
 *
2388
 * @param [in]      input     BER encoded data.
2389
 * @param [in, out] inOutIdx  On in, starting index of tag.
2390
 *                            On out, end of parsed tag.
2391
 * @param [out]     tag       Tag value found.
2392
 * @param [in]      maxIdx    Maximum index of input data.
2393
 *
2394
 * return  0 on success
2395
 * return  BAD_FUNC_ARG when tag, inOutIdx or input is NULL.
2396
 * return  BUFFER_E when not enough space in buffer for tag.
2397
 */
2398
int GetASNTag(const byte* input, word32* inOutIdx, byte* tag, word32 maxIdx)
2399
0
{
2400
0
    int ret = 0;
2401
0
    word32 idx = 0;
2402
2403
    /* Check validity of parameters. */
2404
0
    if ((tag == NULL) || (inOutIdx == NULL) || (input == NULL)) {
2405
0
        ret = BAD_FUNC_ARG;
2406
0
    }
2407
0
    if (ret == 0) {
2408
        /* Get index and ensure space for tag. */
2409
0
        idx = *inOutIdx;
2410
0
        if (idx + ASN_TAG_SZ > maxIdx) {
2411
0
            WOLFSSL_MSG("Buffer too small for ASN tag");
2412
0
            ret = BUFFER_E;
2413
0
        }
2414
0
    }
2415
0
    if (ret == 0) {
2416
        /* Return the tag and the index after tag. */
2417
0
        *tag = input[idx];
2418
0
        *inOutIdx = idx + ASN_TAG_SZ;
2419
0
    }
2420
    /* Return error code. */
2421
0
    return ret;
2422
0
}
2423
2424
2425
/* Decode the DER/BER header (Type-Length) and check the length when requested.
2426
 *
2427
 * BER/DER has Type-Length-Value triplets.
2428
 * Check that the tag/type is the required value.
2429
 * When requested will check that the Length decoded, indicating the number
2430
 * of bytes in the Value, is available in the buffer after the Length bytes.
2431
 *
2432
 * Only supporting a length upto INT_MAX.
2433
 *
2434
 * @param [in]      input     Buffer holding DER/BER encoded data.
2435
 * @param [in]      tag       ASN.1 tag value expected in header.
2436
 * @param [in, out] inOutIdx  On in, starting index of header.
2437
 *                            On out, end of parsed header.
2438
 * @param [out]     len       Number of bytes in the ASN.1 data.
2439
 * @param [in]      maxIdx    Length of data in buffer.
2440
 * @param [in]      check     Whether to check the buffer has at least the
2441
 *                            decoded length of bytes remaining.
2442
 * @return  Number of bytes in the ASN.1 data on success.
2443
 * @return  BUFFER_E when there is not enough data to parse.
2444
 * @return  ASN_PARSE_E when the expected tag is not found or length is invalid.
2445
 */
2446
static int GetASNHeader_ex(const byte* input, byte tag, word32* inOutIdx,
2447
                           int* len, word32 maxIdx, int check)
2448
0
{
2449
0
    int    ret = 0;
2450
0
    word32 idx = *inOutIdx;
2451
0
    byte   tagFound;
2452
0
    int    length = 0;
2453
2454
    /* Get tag/type. */
2455
0
    if (GetASNTag(input, &idx, &tagFound, maxIdx) != 0) {
2456
0
        ret = ASN_PARSE_E;
2457
0
    }
2458
    /* Ensure tag is the expected value. */
2459
0
    if ((ret == 0) && (tagFound != tag)) {
2460
0
        ret = ASN_PARSE_E;
2461
0
    }
2462
    /* Get the encoded length. */
2463
0
    if ((ret == 0) && (GetLength_ex(input, &idx, &length, maxIdx, check) < 0)) {
2464
0
        ret = ASN_PARSE_E;
2465
0
    }
2466
0
    if (ret == 0 && tag == ASN_OBJECT_ID) {
2467
0
        if (length < 3) {
2468
            /* OID data must be at least 3 bytes. */
2469
0
            WOLFSSL_MSG("OID length less than 3");
2470
0
            ret = ASN_PARSE_E;
2471
0
        }
2472
0
        else if ((input[(int)idx + length - 1] & 0x80) == 0x80) {
2473
            /* Last octet of a sub-identifier has bit 8 clear. Last octet must
2474
             * be last of a subidentifier. Ensure last octet hasn't got top bit
2475
             * set. */
2476
0
            WOLFSSL_MSG("OID last octet has top bit set");
2477
0
            ret = ASN_PARSE_E;
2478
0
        }
2479
0
    }
2480
0
    if (ret == 0) {
2481
        /* Return the length of data and index after header. */
2482
0
        *len      = length;
2483
0
        *inOutIdx = idx;
2484
0
        ret = length;
2485
0
    }
2486
    /* Return number of data bytes or error code. */
2487
0
    return ret;
2488
0
}
2489
2490
2491
/* Decode the DER/BER header (Type-Length) and check the length.
2492
 *
2493
 * BER/DER has Type-Length-Value triplets.
2494
 * Check that the tag/type is the required value.
2495
 * Checks that the Length decoded, indicating the number of bytes in the Value,
2496
 * is available in the buffer after the Length bytes.
2497
 *
2498
 * @param [in]      input     Buffer holding DER/BER encoded data.
2499
 * @param [in]      tag       ASN.1 tag value expected in header.
2500
 * @param [in, out] inOutIdx  On in, starting index of header.
2501
 *                            On out, end of parsed header.
2502
 * @param [out]     len       Number of bytes in the ASN.1 data.
2503
 * @param [in]      maxIdx    Length of data in buffer.
2504
 * @return  Number of bytes in the ASN.1 data on success.
2505
 * @return  BUFFER_E when there is not enough data to parse.
2506
 * @return  ASN_PARSE_E when the expected tag is not found or length is invalid.
2507
 */
2508
int GetASNHeader(const byte* input, byte tag, word32* inOutIdx, int* len,
2509
                        word32 maxIdx)
2510
0
{
2511
0
    return GetASNHeader_ex(input, tag, inOutIdx, len, maxIdx, 1);
2512
0
}
2513
2514
#ifndef WOLFSSL_ASN_TEMPLATE
2515
static int GetHeader(const byte* input, byte* tag, word32* inOutIdx, int* len,
2516
                     word32 maxIdx, int check)
2517
{
2518
    word32 idx = *inOutIdx;
2519
    int    length;
2520
2521
    if ((idx + 1) > maxIdx)
2522
        return BUFFER_E;
2523
2524
    *tag = input[idx++];
2525
2526
    if (GetLength_ex(input, &idx, &length, maxIdx, check) < 0)
2527
        return ASN_PARSE_E;
2528
2529
    *len      = length;
2530
    *inOutIdx = idx;
2531
    return length;
2532
}
2533
#endif
2534
2535
/* Decode the header of a BER/DER encoded SEQUENCE.
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 SEQUENCE or length is invalid.
2545
 */
2546
int GetSequence(const byte* input, word32* inOutIdx, int* len,
2547
                           word32 maxIdx)
2548
0
{
2549
0
    return GetASNHeader(input, ASN_SEQUENCE | ASN_CONSTRUCTED, inOutIdx, len,
2550
0
                        maxIdx);
2551
0
}
2552
2553
/* Decode the header of a BER/DER encoded SEQUENCE.
2554
 *
2555
 * @param [in]      input     Buffer holding DER/BER encoded data.
2556
 * @param [in, out] inOutIdx  On in, starting index of header.
2557
 *                            On out, end of parsed header.
2558
 * @param [out]     len       Number of bytes in the ASN.1 data.
2559
 * @param [in]      maxIdx    Length of data in buffer.
2560
 * @param [in]      check     Whether to check the buffer has at least the
2561
 *                            decoded length of bytes remaining.
2562
 * @return  Number of bytes in the ASN.1 data on success.
2563
 * @return  BUFFER_E when there is not enough data to parse.
2564
 * @return  ASN_PARSE_E when the tag is not a SEQUENCE or length is invalid.
2565
 */
2566
int GetSequence_ex(const byte* input, word32* inOutIdx, int* len,
2567
                           word32 maxIdx, int check)
2568
0
{
2569
0
    return GetASNHeader_ex(input, ASN_SEQUENCE | ASN_CONSTRUCTED, inOutIdx, len,
2570
0
                        maxIdx, check);
2571
0
}
2572
2573
/* Decode the header of a BER/DER encoded SET.
2574
 *
2575
 * @param [in]      input     Buffer holding DER/BER encoded data.
2576
 * @param [in, out] inOutIdx  On in, starting index of header.
2577
 *                            On out, end of parsed header.
2578
 * @param [out]     len       Number of bytes in the ASN.1 data.
2579
 * @param [in]      maxIdx    Length of data in buffer.
2580
 * @return  Number of bytes in the ASN.1 data on success.
2581
 * @return  BUFFER_E when there is not enough data to parse.
2582
 * @return  ASN_PARSE_E when the tag is not a SET or length is invalid.
2583
 */
2584
int GetSet(const byte* input, word32* inOutIdx, int* len,
2585
                        word32 maxIdx)
2586
0
{
2587
0
    return GetASNHeader(input, ASN_SET | ASN_CONSTRUCTED, inOutIdx, len,
2588
0
                        maxIdx);
2589
0
}
2590
2591
/* Decode the header of a BER/DER encoded SET.
2592
 *
2593
 * @param [in]      input     Buffer holding DER/BER encoded data.
2594
 * @param [in, out] inOutIdx  On in, starting index of header.
2595
 *                            On out, end of parsed header.
2596
 * @param [out]     len       Number of bytes in the ASN.1 data.
2597
 * @param [in]      maxIdx    Length of data in buffer.
2598
 * @param [in]      check     Whether to check the buffer has at least the
2599
 *                            decoded length of bytes remaining.
2600
 * @return  Number of bytes in the ASN.1 data on success.
2601
 * @return  BUFFER_E when there is not enough data to parse.
2602
 * @return  ASN_PARSE_E when the tag is not a SET or length is invalid.
2603
 */
2604
int GetSet_ex(const byte* input, word32* inOutIdx, int* len,
2605
                        word32 maxIdx, int check)
2606
0
{
2607
0
    return GetASNHeader_ex(input, ASN_SET | ASN_CONSTRUCTED, inOutIdx, len,
2608
0
                        maxIdx, check);
2609
0
}
2610
2611
#if !defined(WOLFSSL_ASN_TEMPLATE) || defined(HAVE_OCSP)
2612
/* Decode the BER/DER encoded NULL.
2613
 *
2614
 * No data in a NULL ASN.1 item.
2615
 * Ensure that the all fields are as expected and move index past the element.
2616
 *
2617
 * @param [in]      input     Buffer holding DER/BER encoded data.
2618
 * @param [in, out] inOutIdx  On in, starting index of NULL item.
2619
 *                            On out, end of parsed NULL item.
2620
 * @param [in]      maxIdx    Length of data in buffer.
2621
 * @return  0 on success.
2622
 * @return  BUFFER_E when there is not enough data to parse.
2623
 * @return  ASN_TAG_NULL_E when the NULL tag is not found.
2624
 * @return  ASN_EXPECT_0_E when the length is not zero.
2625
 */
2626
static int GetASNNull(const byte* input, word32* inOutIdx, word32 maxIdx)
2627
{
2628
    int ret = 0;
2629
    word32 idx = *inOutIdx;
2630
2631
    /* Check buffer has enough data for a NULL item. */
2632
    if ((idx + 2) > maxIdx) {
2633
        ret = BUFFER_E;
2634
    }
2635
    /* Check the tag is NULL. */
2636
    if ((ret == 0) && (input[idx++] != ASN_TAG_NULL)) {
2637
        ret = ASN_TAG_NULL_E;
2638
    }
2639
    /* Check the length is zero. */
2640
    if ((ret == 0) && (input[idx++] != 0)) {
2641
        ret = ASN_EXPECT_0_E;
2642
    }
2643
    if (ret == 0) {
2644
        /* Return the index after NULL tag. */
2645
        *inOutIdx = idx;
2646
    }
2647
    /* Return error code. */
2648
    return ret;
2649
}
2650
#endif
2651
2652
#ifndef WOLFSSL_ASN_TEMPLATE
2653
/* Set the DER/BER encoding of the ASN.1 NULL element.
2654
 *
2655
 * output  Buffer to write into.
2656
 * returns the number of bytes added to the buffer.
2657
 */
2658
static int SetASNNull(byte* output)
2659
{
2660
    output[0] = ASN_TAG_NULL;
2661
    output[1] = 0;
2662
2663
    return 2;
2664
}
2665
#endif
2666
2667
#ifndef NO_CERTS
2668
#ifndef WOLFSSL_ASN_TEMPLATE
2669
/* Get the DER/BER encoding of an ASN.1 BOOLEAN.
2670
 *
2671
 * input     Buffer holding DER/BER encoded data.
2672
 * inOutIdx  Current index into buffer to parse.
2673
 * maxIdx    Length of data in buffer.
2674
 * returns BUFFER_E when there is not enough data to parse.
2675
 *         ASN_PARSE_E when the BOOLEAN tag is not found or length is not 1.
2676
 *         Otherwise, 0 to indicate the value was false and 1 to indicate true.
2677
 */
2678
static int GetBoolean(const byte* input, word32* inOutIdx, word32 maxIdx)
2679
{
2680
    word32 idx = *inOutIdx;
2681
    byte   b;
2682
2683
    if ((idx + 3) > maxIdx)
2684
        return BUFFER_E;
2685
2686
    b = input[idx++];
2687
    if (b != ASN_BOOLEAN)
2688
        return ASN_PARSE_E;
2689
2690
    if (input[idx++] != 1)
2691
        return ASN_PARSE_E;
2692
2693
    b = input[idx++] != 0;
2694
2695
    *inOutIdx = idx;
2696
    return b;
2697
}
2698
#endif
2699
#endif /* !NO_CERTS*/
2700
2701
2702
/* Decode the header of a BER/DER encoded OCTET STRING.
2703
 *
2704
 * @param [in]      input     Buffer holding DER/BER encoded data.
2705
 * @param [in, out] inOutIdx  On in, starting index of header.
2706
 *                            On out, end of parsed header.
2707
 * @param [out]     len       Number of bytes in the ASN.1 data.
2708
 * @param [in]      maxIdx    Length of data in buffer.
2709
 * @return  Number of bytes in the ASN.1 data on success.
2710
 * @return  BUFFER_E when there is not enough data to parse.
2711
 * @return  ASN_PARSE_E when the tag is not a OCTET STRING or length is invalid.
2712
 */
2713
int GetOctetString(const byte* input, word32* inOutIdx, int* len, word32 maxIdx)
2714
0
{
2715
0
    return GetASNHeader(input, ASN_OCTET_STRING, inOutIdx, len, maxIdx);
2716
0
}
2717
2718
/* Get the DER/BER encoding of an ASN.1 INTEGER header.
2719
 *
2720
 * Removes the leading zero byte when found.
2721
 *
2722
 * input     Buffer holding DER/BER encoded data.
2723
 * inOutIdx  Current index into buffer to parse.
2724
 * len       The number of bytes in the ASN.1 data (excluding any leading zero).
2725
 * maxIdx    Length of data in buffer.
2726
 * returns BUFFER_E when there is not enough data to parse.
2727
 *         ASN_PARSE_E when the INTEGER tag is not found, length is invalid,
2728
 *         or invalid use of or missing leading zero.
2729
 *         Otherwise, 0 to indicate success.
2730
 */
2731
int GetASNInt(const byte* input, word32* inOutIdx, int* len,
2732
                     word32 maxIdx)
2733
0
{
2734
0
    int    ret;
2735
2736
0
    ret = GetASNHeader(input, ASN_INTEGER, inOutIdx, len, maxIdx);
2737
0
    if (ret < 0)
2738
0
        return ret;
2739
2740
0
    if (*len > 0) {
2741
0
#ifndef WOLFSSL_ASN_INT_LEAD_0_ANY
2742
        /* check for invalid padding on negative integer.
2743
         * c.f. X.690 (ISO/IEC 8825-2:2003 (E)) 10.4.6; RFC 5280 4.1
2744
         */
2745
0
        if (*len > 1) {
2746
0
            if ((input[*inOutIdx] == 0xff) && (input[*inOutIdx + 1] & 0x80)) {
2747
0
                WOLFSSL_MSG("Bad INTEGER encoding of negative");
2748
0
                return ASN_EXPECT_0_E;
2749
0
            }
2750
0
        }
2751
0
#endif
2752
2753
        /* remove leading zero, unless there is only one 0x00 byte */
2754
0
        if ((input[*inOutIdx] == 0x00) && (*len > 1)) {
2755
0
            (*inOutIdx)++;
2756
0
            (*len)--;
2757
2758
0
#ifndef WOLFSSL_ASN_INT_LEAD_0_ANY
2759
0
            if (*len > 0 && (input[*inOutIdx] & 0x80) == 0) {
2760
0
                WOLFSSL_MSG("INTEGER is negative");
2761
0
                return ASN_EXPECT_0_E;
2762
0
            }
2763
0
#endif
2764
0
        }
2765
0
    }
2766
2767
0
    return 0;
2768
0
}
2769
2770
#ifndef WOLFSSL_ASN_TEMPLATE
2771
#if !defined(NO_CERTS) && defined(WOLFSSL_CUSTOM_CURVES)
2772
/* Get the DER/BER encoding of an ASN.1 INTEGER that has a value of no more than
2773
 * 7 bits.
2774
 *
2775
 * input     Buffer holding DER/BER encoded data.
2776
 * inOutIdx  Current index into buffer to parse.
2777
 * maxIdx    Length of data in buffer.
2778
 * returns BUFFER_E when there is not enough data to parse.
2779
 *         ASN_PARSE_E when the INTEGER tag is not found or length is invalid.
2780
 *         Otherwise, the 7-bit value.
2781
 */
2782
static int GetInteger7Bit(const byte* input, word32* inOutIdx, word32 maxIdx)
2783
{
2784
    word32 idx = *inOutIdx;
2785
    byte   b;
2786
2787
    if ((idx + 3) > maxIdx)
2788
        return BUFFER_E;
2789
2790
    if (GetASNTag(input, &idx, &b, maxIdx) != 0)
2791
        return ASN_PARSE_E;
2792
    if (b != ASN_INTEGER)
2793
        return ASN_PARSE_E;
2794
    if (input[idx++] != 1)
2795
        return ASN_PARSE_E;
2796
    b = input[idx++];
2797
2798
    *inOutIdx = idx;
2799
    return b;
2800
}
2801
#endif /* !NO_CERTS */
2802
2803
#if ((defined(WC_RSA_PSS) && !defined(NO_RSA)) || !defined(NO_CERTS))
2804
/* Get the DER/BER encoding of an ASN.1 INTEGER that has a value of no more than
2805
 * 16 bits.
2806
 *
2807
 * input     Buffer holding DER/BER encoded data.
2808
 * inOutIdx  Current index into buffer to parse.
2809
 * maxIdx    Length of data in buffer.
2810
 * returns BUFFER_E when there is not enough data to parse.
2811
 *         ASN_PARSE_E when the INTEGER tag is not found or length is invalid.
2812
 *         Otherwise, the 16-bit value.
2813
 */
2814
static int GetInteger16Bit(const byte* input, word32* inOutIdx, word32 maxIdx)
2815
{
2816
    word32 idx = *inOutIdx;
2817
    byte tag;
2818
    word16 n;
2819
2820
    if ((idx + 2) > maxIdx)
2821
        return BUFFER_E;
2822
2823
    if (GetASNTag(input, &idx, &tag, maxIdx) != 0)
2824
        return ASN_PARSE_E;
2825
    if (tag != ASN_INTEGER)
2826
        return ASN_PARSE_E;
2827
    if (input[idx] == 1) {
2828
        idx++;
2829
        if ((idx + 1) > maxIdx) {
2830
            return ASN_PARSE_E;
2831
        }
2832
        n = input[idx++];
2833
    }
2834
    else if (input[idx] == 2) {
2835
        idx++;
2836
        if ((idx + 2) > maxIdx) {
2837
            return ASN_PARSE_E;
2838
        }
2839
        n = input[idx++];
2840
        n = (n << 8) | input[idx++];
2841
    }
2842
    else
2843
        return ASN_PARSE_E;
2844
2845
    *inOutIdx = idx;
2846
    return n;
2847
}
2848
#endif /* WC_RSA_PSS && !NO_RSA */
2849
#endif /* !WOLFSSL_ASN_TEMPLATE */
2850
2851
#if !defined(NO_DSA) && !defined(NO_SHA)
2852
static const char sigSha1wDsaName[] = "SHAwDSA";
2853
static const char sigSha256wDsaName[] = "SHA256wDSA";
2854
#endif /* NO_DSA */
2855
#ifndef NO_RSA
2856
#ifdef WOLFSSL_MD2
2857
    static const char  sigMd2wRsaName[] = "md2WithRSAEncryption";
2858
#endif
2859
#ifndef NO_MD5
2860
    static const char  sigMd5wRsaName[] = "md5WithRSAEncryption";
2861
#endif
2862
#ifndef NO_SHA
2863
    static const char  sigSha1wRsaName[] = "sha1WithRSAEncryption";
2864
#endif
2865
#ifdef WOLFSSL_SHA224
2866
    static const char sigSha224wRsaName[] = "sha224WithRSAEncryption";
2867
#endif
2868
#ifndef NO_SHA256
2869
    static const char sigSha256wRsaName[] = "sha256WithRSAEncryption";
2870
#endif
2871
#ifdef WOLFSSL_SHA384
2872
    static const char sigSha384wRsaName[] = "sha384WithRSAEncryption";
2873
#endif
2874
#ifdef WOLFSSL_SHA512
2875
    static const char sigSha512wRsaName[] = "sha512WithRSAEncryption";
2876
#endif
2877
#ifdef WOLFSSL_SHA3
2878
#ifndef WOLFSSL_NOSHA3_224
2879
    static const char sigSha3_224wRsaName[] = "sha3_224WithRSAEncryption";
2880
#endif
2881
#ifndef WOLFSSL_NOSHA3_256
2882
    static const char sigSha3_256wRsaName[] = "sha3_256WithRSAEncryption";
2883
#endif
2884
#ifndef WOLFSSL_NOSHA3_384
2885
    static const char sigSha3_384wRsaName[] = "sha3_384WithRSAEncryption";
2886
#endif
2887
#ifndef WOLFSSL_NOSHA3_512
2888
    static const char sigSha3_512wRsaName[] = "sha3_512WithRSAEncryption";
2889
#endif
2890
#endif
2891
#ifdef WC_RSA_PSS
2892
    static const char sigRsaSsaPssName[] = "rsassaPss";
2893
#endif
2894
#endif /* NO_RSA */
2895
#ifdef HAVE_ECC
2896
#ifndef NO_SHA
2897
    static const char sigSha1wEcdsaName[] = "SHAwECDSA";
2898
#endif
2899
#ifdef WOLFSSL_SHA224
2900
    static const char sigSha224wEcdsaName[] = "SHA224wECDSA";
2901
#endif
2902
#ifndef NO_SHA256
2903
    static const char sigSha256wEcdsaName[] = "SHA256wECDSA";
2904
#endif
2905
#ifdef WOLFSSL_SHA384
2906
    static const char sigSha384wEcdsaName[] = "SHA384wECDSA";
2907
#endif
2908
#ifdef WOLFSSL_SHA512
2909
    static const char sigSha512wEcdsaName[] = "SHA512wECDSA";
2910
#endif
2911
#ifdef WOLFSSL_SHA3
2912
#ifndef WOLFSSL_NOSHA3_224
2913
    static const char sigSha3_224wEcdsaName[] = "SHA3_224wECDSA";
2914
#endif
2915
#ifndef WOLFSSL_NOSHA3_256
2916
    static const char sigSha3_256wEcdsaName[] = "SHA3_256wECDSA";
2917
#endif
2918
#ifndef WOLFSSL_NOSHA3_384
2919
    static const char sigSha3_384wEcdsaName[] = "SHA3_384wECDSA";
2920
#endif
2921
#ifndef WOLFSSL_NOSHA3_512
2922
    static const char sigSha3_512wEcdsaName[] = "SHA3_512wECDSA";
2923
#endif
2924
#endif
2925
#endif /* HAVE_ECC */
2926
static const char sigUnknownName[] = "Unknown";
2927
2928
2929
/* Get the human readable string for a signature type
2930
 *
2931
 * oid  Oid value for signature
2932
 */
2933
0
const char* GetSigName(int oid) {
2934
0
    switch (oid) {
2935
    #if !defined(NO_DSA) && !defined(NO_SHA)
2936
        case CTC_SHAwDSA:
2937
            return sigSha1wDsaName;
2938
        case CTC_SHA256wDSA:
2939
            return sigSha256wDsaName;
2940
    #endif /* NO_DSA && NO_SHA */
2941
0
    #ifndef NO_RSA
2942
        #ifdef WOLFSSL_MD2
2943
        case CTC_MD2wRSA:
2944
            return sigMd2wRsaName;
2945
        #endif
2946
        #ifndef NO_MD5
2947
        case CTC_MD5wRSA:
2948
            return sigMd5wRsaName;
2949
        #endif
2950
0
        #ifndef NO_SHA
2951
0
        case CTC_SHAwRSA:
2952
0
            return sigSha1wRsaName;
2953
0
        #endif
2954
0
        #ifdef WOLFSSL_SHA224
2955
0
        case CTC_SHA224wRSA:
2956
0
            return sigSha224wRsaName;
2957
0
        #endif
2958
0
        #ifndef NO_SHA256
2959
0
        case CTC_SHA256wRSA:
2960
0
            return sigSha256wRsaName;
2961
0
        #endif
2962
0
        #ifdef WOLFSSL_SHA384
2963
0
        case CTC_SHA384wRSA:
2964
0
            return sigSha384wRsaName;
2965
0
        #endif
2966
0
        #ifdef WOLFSSL_SHA512
2967
0
        case CTC_SHA512wRSA:
2968
0
            return sigSha512wRsaName;
2969
0
        #endif
2970
0
        #ifdef WOLFSSL_SHA3
2971
0
        #ifndef WOLFSSL_NOSHA3_224
2972
0
        case CTC_SHA3_224wRSA:
2973
0
            return sigSha3_224wRsaName;
2974
0
        #endif
2975
0
        #ifndef WOLFSSL_NOSHA3_256
2976
0
        case CTC_SHA3_256wRSA:
2977
0
            return sigSha3_256wRsaName;
2978
0
        #endif
2979
0
        #ifndef WOLFSSL_NOSHA3_384
2980
0
        case CTC_SHA3_384wRSA:
2981
0
            return sigSha3_384wRsaName;
2982
0
        #endif
2983
0
        #ifndef WOLFSSL_NOSHA3_512
2984
0
        case CTC_SHA3_512wRSA:
2985
0
            return sigSha3_512wRsaName;
2986
0
        #endif
2987
0
        #endif
2988
0
        #ifdef WC_RSA_PSS
2989
0
        case CTC_RSASSAPSS:
2990
0
            return sigRsaSsaPssName;
2991
0
        #endif
2992
0
    #endif /* NO_RSA */
2993
0
    #ifdef HAVE_ECC
2994
0
        #ifndef NO_SHA
2995
0
        case CTC_SHAwECDSA:
2996
0
            return sigSha1wEcdsaName;
2997
0
        #endif
2998
0
        #ifdef WOLFSSL_SHA224
2999
0
        case CTC_SHA224wECDSA:
3000
0
            return sigSha224wEcdsaName;
3001
0
        #endif
3002
0
        #ifndef NO_SHA256
3003
0
        case CTC_SHA256wECDSA:
3004
0
            return sigSha256wEcdsaName;
3005
0
        #endif
3006
0
        #ifdef WOLFSSL_SHA384
3007
0
        case CTC_SHA384wECDSA:
3008
0
            return sigSha384wEcdsaName;
3009
0
        #endif
3010
0
        #ifdef WOLFSSL_SHA512
3011
0
        case CTC_SHA512wECDSA:
3012
0
            return sigSha512wEcdsaName;
3013
0
        #endif
3014
0
        #ifdef WOLFSSL_SHA3
3015
0
        #ifndef WOLFSSL_NOSHA3_224
3016
0
        case CTC_SHA3_224wECDSA:
3017
0
            return sigSha3_224wEcdsaName;
3018
0
        #endif
3019
0
        #ifndef WOLFSSL_NOSHA3_256
3020
0
        case CTC_SHA3_256wECDSA:
3021
0
            return sigSha3_256wEcdsaName;
3022
0
        #endif
3023
0
        #ifndef WOLFSSL_NOSHA3_384
3024
0
        case CTC_SHA3_384wECDSA:
3025
0
            return sigSha3_384wEcdsaName;
3026
0
        #endif
3027
0
        #ifndef WOLFSSL_NOSHA3_512
3028
0
        case CTC_SHA3_512wECDSA:
3029
0
            return sigSha3_512wEcdsaName;
3030
0
        #endif
3031
0
        #endif
3032
0
    #endif /* HAVE_ECC */
3033
0
        default:
3034
0
            return sigUnknownName;
3035
0
    }
3036
0
}
3037
3038
3039
#if !defined(WOLFSSL_ASN_TEMPLATE) || defined(HAVE_PKCS7) || \
3040
    defined(OPENSSL_EXTRA)
3041
#if !defined(NO_DSA) || defined(HAVE_ECC) || !defined(NO_CERTS) || \
3042
   (!defined(NO_RSA) && \
3043
        (defined(WOLFSSL_CERT_GEN) || \
3044
        ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)))))
3045
/* Set the DER/BER encoding of the ASN.1 INTEGER header.
3046
 *
3047
 * When output is NULL, calculate the header length only.
3048
 *
3049
 * @param [in]  len        Length of INTEGER data in bytes.
3050
 * @param [in]  firstByte  First byte of data, most significant byte of integer,
3051
 *                         to encode.
3052
 * @param [out] output     Buffer to write into.
3053
 * @return  Number of bytes added to the buffer.
3054
 */
3055
int SetASNInt(int len, byte firstByte, byte* output)
3056
{
3057
    int idx = 0;
3058
3059
    if (output) {
3060
        /* Write out tag. */
3061
        output[idx] = ASN_INTEGER;
3062
    }
3063
    /* Step over tag. */
3064
    idx += ASN_TAG_SZ;
3065
    /* Check if first byte has top bit set in which case a 0 is needed to
3066
     * maintain positive value. */
3067
    if (firstByte & 0x80) {
3068
        /* Add pre-prepended byte to length of data in INTEGER. */
3069
        len++;
3070
    }
3071
    /* Encode length - passing NULL for output will not encode. */
3072
    idx += (int)SetLength((word32)len, output ? output + idx : NULL);
3073
    /* Put out prepended 0 as well. */
3074
    if (firstByte & 0x80) {
3075
        if (output) {
3076
            /* Write out 0 byte. */
3077
            output[idx] = 0x00;
3078
        }
3079
        /* Update index. */
3080
        idx++;
3081
    }
3082
3083
    /* Return index after header. */
3084
    return idx;
3085
}
3086
#endif
3087
#endif
3088
3089
#ifndef WOLFSSL_ASN_TEMPLATE
3090
#if !defined(NO_DSA) || defined(HAVE_ECC) || (defined(WOLFSSL_CERT_GEN) && \
3091
    !defined(NO_RSA)) || ((defined(WOLFSSL_KEY_GEN) || \
3092
    (!defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)) || \
3093
    defined(OPENSSL_EXTRA)) && !defined(NO_RSA))
3094
/* Set the DER/BER encoding of the ASN.1 INTEGER element with an mp_int.
3095
 * The number is assumed to be positive.
3096
 *
3097
 * n       Multi-precision integer to encode.
3098
 * maxSz   Maximum size of the encoded integer.
3099
 *         A negative value indicates no check of length requested.
3100
 * output  Buffer to write into.
3101
 * returns BUFFER_E when the data is too long for the buffer.
3102
 *         MP_TO_E when encoding the integer fails.
3103
 *         Otherwise, the number of bytes added to the buffer.
3104
 */
3105
static int SetASNIntMP(mp_int* n, int maxSz, byte* output)
3106
{
3107
    int idx = 0;
3108
    int leadingBit;
3109
    int length;
3110
3111
    leadingBit = mp_leading_bit(n);
3112
    length = mp_unsigned_bin_size(n);
3113
    if (maxSz >= 0 && (1 + length + (leadingBit ? 1 : 0)) > maxSz)
3114
        return BUFFER_E;
3115
    idx = SetASNInt(length, (byte)(leadingBit ? 0x80U : 0x00U), output);
3116
    if (maxSz >= 0 && (idx + length) > maxSz)
3117
        return BUFFER_E;
3118
3119
    if (output) {
3120
        int err = mp_to_unsigned_bin(n, output + idx);
3121
        if (err != MP_OKAY)
3122
            return MP_TO_E;
3123
    }
3124
    idx += length;
3125
3126
    return idx;
3127
}
3128
#endif
3129
#endif /* !WOLFSSL_ASN_TEMPLATE */
3130
3131
#ifdef WOLFSSL_ASN_TEMPLATE
3132
/* ASN.1 template for an INTEGER. */
3133
static const ASNItem intASN[] = {
3134
/* INT */ { 0, ASN_INTEGER, 0, 0, 0 }
3135
};
3136
enum {
3137
    INTASN_IDX_INT = 0
3138
};
3139
3140
/* Number of items in ASN.1 template for an INTEGER. */
3141
0
#define intASN_Length (sizeof(intASN) / sizeof(ASNItem))
3142
#endif /* WOLFSSL_ASN_TEMPLATE */
3143
3144
/* Windows header clash for WinCE using GetVersion */
3145
/* Decode Version - one byte INTEGER.
3146
 *
3147
 * @param [in]      input     Buffer of BER data.
3148
 * @param [in, out] inOutIdx  On in, start of encoded Version.
3149
 *                            On out, start of next encode ASN.1 item.
3150
 * @param [out]     version   Number encoded in INTEGER.
3151
 * @param [in]      maxIdx    Maximum index of data in buffer.
3152
 * @return  0 on success.
3153
 * @return  ASN_PARSE_E when encoding is invalid.
3154
 * @return  BUFFER_E when data in buffer is too small.
3155
 * @return  ASN_EXPECT_0_E when the most significant bit is set.
3156
 */
3157
int GetMyVersion(const byte* input, word32* inOutIdx,
3158
                               int* version, word32 maxIdx)
3159
0
{
3160
#ifndef WOLFSSL_ASN_TEMPLATE
3161
    word32 idx = *inOutIdx;
3162
    byte   tag;
3163
3164
    if ((idx + MIN_VERSION_SZ) > maxIdx)
3165
        return ASN_PARSE_E;
3166
3167
    if (GetASNTag(input, &idx, &tag, maxIdx) != 0)
3168
        return ASN_PARSE_E;
3169
3170
    if (tag != ASN_INTEGER)
3171
        return ASN_PARSE_E;
3172
3173
    if (input[idx++] != 0x01)
3174
        return ASN_VERSION_E;
3175
3176
    *version  = input[idx++];
3177
    *inOutIdx = idx;
3178
3179
    return *version;
3180
#else
3181
0
    ASNGetData dataASN[intASN_Length];
3182
0
    int ret;
3183
0
    byte num = 0;
3184
3185
    /* Clear dynamic data and set the version number variable. */
3186
0
    XMEMSET(dataASN, 0, sizeof(dataASN));
3187
0
    GetASN_Int8Bit(&dataASN[INTASN_IDX_INT], &num);
3188
    /* Decode the version (INTEGER). */
3189
0
    ret = GetASN_Items(intASN, dataASN, intASN_Length, 0, input, inOutIdx,
3190
0
                       maxIdx);
3191
0
    if (ret == 0) {
3192
        /* Return version through variable and return value. */
3193
0
        *version = num;
3194
0
        ret = num;
3195
0
    }
3196
0
    return ret;
3197
0
#endif /* WOLFSSL_ASN_TEMPLATE */
3198
0
}
3199
3200
3201
#if !defined(NO_PWDBASED) || defined(WOLFSSL_ASN_EXTRA)
3202
/* Decode small integer, 32 bits or less.
3203
 *
3204
 * @param [in]      input     Buffer of BER data.
3205
 * @param [in, out] inOutIdx  On in, start of encoded INTEGER.
3206
 *                            On out, start of next encode ASN.1 item.
3207
 * @param [out]     number    Number encoded in INTEGER.
3208
 * @param [in]      maxIdx    Maximum index of data in buffer.
3209
 * @return  0 on success.
3210
 * @return  ASN_PARSE_E when encoding is invalid.
3211
 * @return  BUFFER_E when data in buffer is too small.
3212
 * @return  ASN_EXPECT_0_E when the most significant bit is set.
3213
 */
3214
int GetShortInt(const byte* input, word32* inOutIdx, int* number, word32 maxIdx)
3215
0
{
3216
#ifndef WOLFSSL_ASN_TEMPLATE
3217
    word32 idx = *inOutIdx;
3218
    word32 len;
3219
    byte   tag;
3220
3221
    *number = 0;
3222
3223
    /* check for type and length bytes */
3224
    if ((idx + 2) > maxIdx)
3225
        return BUFFER_E;
3226
3227
    if (GetASNTag(input, &idx, &tag, maxIdx) != 0)
3228
        return ASN_PARSE_E;
3229
3230
    if (tag != ASN_INTEGER)
3231
        return ASN_PARSE_E;
3232
3233
    len = input[idx++];
3234
    if (len > 4)
3235
        return ASN_PARSE_E;
3236
3237
    if (len + idx > maxIdx)
3238
        return ASN_PARSE_E;
3239
3240
    while (len--) {
3241
        *number  = *number << 8 | input[idx++];
3242
    }
3243
3244
    *inOutIdx = idx;
3245
3246
    return *number;
3247
#else
3248
0
    ASNGetData dataASN[intASN_Length];
3249
0
    int ret;
3250
0
    word32 num = 0;
3251
3252
    /* Clear dynamic data and set the 32-bit number variable. */
3253
0
    XMEMSET(dataASN, 0, sizeof(dataASN));
3254
0
    GetASN_Int32Bit(&dataASN[INTASN_IDX_INT], &num);
3255
    /* Decode the short int (INTEGER). */
3256
0
    ret = GetASN_Items(intASN, dataASN, intASN_Length, 0, input, inOutIdx,
3257
0
                       maxIdx);
3258
0
    if (ret == 0) {
3259
        /* Return number through variable and return value. */
3260
0
        *number = (int)num;
3261
0
        ret = (int)num;
3262
0
    }
3263
0
    return ret;
3264
0
#endif
3265
0
}
3266
#endif /* !NO_PWDBASED || WOLFSSL_ASN_EXTRA */
3267
3268
3269
#ifndef NO_PWDBASED
3270
#if !defined(WOLFSSL_ASN_TEMPLATE) || defined(HAVE_PKCS8) || \
3271
     defined(HAVE_PKCS12)
3272
/* Set small integer, 32 bits or less. DER encoding with no leading 0s
3273
 * returns total amount written including ASN tag and length byte on success */
3274
int SetShortInt(byte* output, word32* inOutIdx, word32 number, word32 maxIdx)
3275
0
{
3276
0
    word32 idx = *inOutIdx;
3277
0
    word32 len;
3278
0
    int    i;
3279
0
    word32 extraByte = 0;
3280
3281
0
    if (number == 0)
3282
0
        len = 1;
3283
0
    else
3284
0
        len = BytePrecision(number);
3285
3286
    /* clarify the len range to prepare for the next right bit shifting */
3287
0
    if (len < 1 || len > sizeof(number)) {
3288
0
        return ASN_PARSE_E;
3289
0
    }
3290
0
    if (number >> (WOLFSSL_BIT_SIZE * len - 1)) {
3291
        /* Need one byte of zero value not to be negative number */
3292
0
        extraByte = 1;
3293
0
    }
3294
3295
    /* check for room for type and length bytes. */
3296
0
    if ((idx + 2 + extraByte + len) > maxIdx)
3297
0
        return BUFFER_E;
3298
3299
    /* check that MAX_SHORT_SZ allows this size of ShortInt. */
3300
0
    if (2 + extraByte + len > MAX_SHORT_SZ)
3301
0
        return ASN_PARSE_E;
3302
3303
0
    output[idx++] = ASN_INTEGER;
3304
0
    output[idx++] = (byte)(len + extraByte);
3305
0
    if (extraByte) {
3306
0
        output[idx++] = 0x00;
3307
0
    }
3308
3309
0
    for (i = (int)len - 1; i >= 0; --i)
3310
0
        output[idx++] = (byte)(number >> (i * WOLFSSL_BIT_SIZE));
3311
3312
0
    len = idx - *inOutIdx;
3313
0
    *inOutIdx = idx;
3314
3315
0
    return (int)len;
3316
0
}
3317
#endif /* !WOLFSSL_ASN_TEMPLATE || HAVE_PKCS8 || HAVE_PKCS12 */
3318
#endif /* !NO_PWDBASED */
3319
3320
#if !defined(WOLFSSL_ASN_TEMPLATE) && !defined(NO_CERTS)
3321
/* May not have one, not an error */
3322
static int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version,
3323
                              word32 maxIdx)
3324
{
3325
    word32 idx = *inOutIdx;
3326
    byte tag;
3327
3328
    WOLFSSL_ENTER("GetExplicitVersion");
3329
3330
    if (GetASNTag(input, &idx, &tag, maxIdx) != 0)
3331
        return ASN_PARSE_E;
3332
3333
    if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
3334
        int ret;
3335
3336
        *inOutIdx = ++idx;  /* skip header */
3337
        ret = GetMyVersion(input, inOutIdx, version, maxIdx);
3338
        if (ret >= 0) {
3339
            /* check if version is expected value rfc 5280 4.1 {0, 1, 2} */
3340
            if (*version > MAX_X509_VERSION || *version < MIN_X509_VERSION) {
3341
                WOLFSSL_MSG("Unexpected certificate version");
3342
                WOLFSSL_ERROR_VERBOSE(ASN_VERSION_E);
3343
                ret = ASN_VERSION_E;
3344
            }
3345
        }
3346
        return ret;
3347
    }
3348
3349
    /* go back as is */
3350
    *version = 0;
3351
3352
    return 0;
3353
}
3354
#endif
3355
3356
/* Decode small integer, 32 bits or less.
3357
 *
3358
 * mp_int is initialized.
3359
 *
3360
 * @param [out]     mpi       mp_int to hold number.
3361
 * @param [in]      input     Buffer of BER data.
3362
 * @param [in, out] inOutIdx  On in, start of encoded INTEGER.
3363
 *                            On out, start of next encode ASN.1 item.
3364
 * @param [in]      maxIdx    Maximum index of data in buffer.
3365
 * @return  0 on success.
3366
 * @return  ASN_PARSE_E when encoding is invalid.
3367
 * @return  BUFFER_E when data in buffer is too small.
3368
 * @return  ASN_EXPECT_0_E when the most significant bit is set.
3369
 * @return  MP_INIT_E when the unable to initialize an mp_int.
3370
 * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
3371
 */
3372
int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx, word32 maxIdx)
3373
0
{
3374
#ifndef WOLFSSL_ASN_TEMPLATE
3375
    word32 idx = *inOutIdx;
3376
    int    ret;
3377
    int    length;
3378
3379
    ret = GetASNInt(input, &idx, &length, maxIdx);
3380
    if (ret != 0)
3381
        return ret;
3382
3383
    if (mp_init(mpi) != MP_OKAY)
3384
        return MP_INIT_E;
3385
3386
    if (mp_read_unsigned_bin(mpi, input + idx, (word32)length) != 0) {
3387
        mp_clear(mpi);
3388
        return ASN_GETINT_E;
3389
    }
3390
3391
#ifdef HAVE_WOLF_BIGINT
3392
    if (wc_bigint_from_unsigned_bin(&mpi->raw, input + idx, length) != 0) {
3393
        mp_clear(mpi);
3394
        return ASN_GETINT_E;
3395
    }
3396
#endif /* HAVE_WOLF_BIGINT */
3397
3398
    *inOutIdx = idx + (word32)length;
3399
3400
    return 0;
3401
#else
3402
0
    ASNGetData dataASN[intASN_Length];
3403
3404
    /* Clear dynamic data and set the mp_int to fill with value. */
3405
0
    XMEMSET(dataASN, 0, sizeof(dataASN));
3406
0
    GetASN_MP_PosNeg(&dataASN[INTASN_IDX_INT], mpi);
3407
    /* Decode the big number (INTEGER). */
3408
0
    return GetASN_Items(intASN, dataASN, intASN_Length, 0, input, inOutIdx,
3409
0
                        maxIdx);
3410
0
#endif
3411
0
}
3412
3413
#if (defined(HAVE_ECC) || !defined(NO_DSA)) && !defined(WOLFSSL_ASN_TEMPLATE)
3414
static int GetIntPositive(mp_int* mpi, const byte* input, word32* inOutIdx,
3415
    word32 maxIdx, int initNum)
3416
{
3417
    word32 idx = *inOutIdx;
3418
    int    ret;
3419
    int    length;
3420
3421
    ret = GetASNInt(input, &idx, &length, maxIdx);
3422
    if (ret != 0)
3423
        return ret;
3424
3425
    /* should not be hit but adding in an additional sanity check */
3426
    if (idx + length > maxIdx) {
3427
        return MP_INIT_E;
3428
    }
3429
3430
    if ((input[idx] & 0x80) == 0x80) {
3431
        if (idx < 1) {
3432
            /* needs at least one byte for length value */
3433
            return MP_INIT_E;
3434
        }
3435
3436
        if (input[idx - 1] != 0x00) {
3437
            return MP_INIT_E;
3438
        }
3439
    }
3440
3441
    if (initNum) {
3442
        if (mp_init(mpi) != MP_OKAY)
3443
            return MP_INIT_E;
3444
    }
3445
3446
    if (mp_read_unsigned_bin(mpi, input + idx, (word32)length) != 0) {
3447
        mp_clear(mpi);
3448
        return ASN_GETINT_E;
3449
    }
3450
3451
#ifdef HAVE_WOLF_BIGINT
3452
    if (wc_bigint_from_unsigned_bin(&mpi->raw, input + idx, length) != 0) {
3453
        mp_clear(mpi);
3454
        return ASN_GETINT_E;
3455
    }
3456
#endif /* HAVE_WOLF_BIGINT */
3457
3458
    *inOutIdx = idx + (word32)length;
3459
3460
    return 0;
3461
}
3462
#endif /* (ECC || !NO_DSA) && !WOLFSSL_ASN_TEMPLATE */
3463
3464
#ifndef WOLFSSL_ASN_TEMPLATE
3465
#if !defined(NO_RSA) || !defined(NO_DSA)
3466
static int SkipInt(const byte* input, word32* inOutIdx, word32 maxIdx)
3467
{
3468
    word32 idx = *inOutIdx;
3469
    int    ret;
3470
    int    length;
3471
3472
    ret = GetASNInt(input, &idx, &length, maxIdx);
3473
    if (ret != 0)
3474
        return ret;
3475
3476
    *inOutIdx = idx + (word32)length;
3477
3478
    return 0;
3479
}
3480
#endif
3481
#endif /* !WOLFSSL_ASN_TEMPLATE */
3482
3483
#ifdef WOLFSSL_ASN_TEMPLATE
3484
/* ASN.1 template for a BIT_STRING. */
3485
static const ASNItem bitStringASN[] = {
3486
/* BIT_STR */ { 0, ASN_BIT_STRING, 0, 1, 0 }
3487
};
3488
enum {
3489
    BITSTRINGASN_IDX_BIT_STR = 0
3490
};
3491
3492
/* Number of items in ASN.1 template for a BIT_STRING. */
3493
0
#define bitStringASN_Length (sizeof(bitStringASN) / sizeof(ASNItem))
3494
#endif
3495
3496
/* Decode and check the BIT_STRING is valid. Return length and unused bits.
3497
 *
3498
 * @param [in]      input       Buffer holding BER encoding.
3499
 * @param [in, out] inOutIdx    On in, start of BIT_STRING.
3500
 *                              On out, start of ASN.1 item after BIT_STRING.
3501
 * @param [out]     len         Length of BIT_STRING data.
3502
 * @param [in]      maxIdx      Maximum index of data in buffer.
3503
 * @param [in]      zeroBits    Indicates whether zero unused bits is expected.
3504
 * @param [in]      unusedBits  Number of unused bits in last byte.
3505
 * @return  0 on success.
3506
 * @return  ASN_PARSE_E when encoding is invalid.
3507
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
3508
 * @return  BUFFER_E when data in buffer is too small.
3509
 * @return  ASN_EXPECT_0_E when unused bits is not zero when expected.
3510
 */
3511
int CheckBitString(const byte* input, word32* inOutIdx, int* len,
3512
                          word32 maxIdx, int zeroBits, byte* unusedBits)
3513
0
{
3514
#ifndef WOLFSSL_ASN_TEMPLATE
3515
    word32 idx = *inOutIdx;
3516
    int    length;
3517
    byte   b;
3518
3519
    if (GetASNTag(input, &idx, &b, maxIdx) != 0) {
3520
        return ASN_BITSTR_E;
3521
    }
3522
3523
    if (b != ASN_BIT_STRING) {
3524
        return ASN_BITSTR_E;
3525
    }
3526
3527
    if (GetLength(input, &idx, &length, maxIdx) < 0)
3528
        return ASN_PARSE_E;
3529
3530
    /* extra sanity check that length is greater than 0 */
3531
    if (length <= 0) {
3532
        WOLFSSL_MSG("Error length was 0 in CheckBitString");
3533
        return BUFFER_E;
3534
    }
3535
3536
    if (idx + 1 > maxIdx) {
3537
        WOLFSSL_MSG("Attempted buffer read larger than input buffer");
3538
        return BUFFER_E;
3539
    }
3540
3541
    b = input[idx];
3542
    if (zeroBits && (b != 0x00))
3543
        return ASN_EXPECT_0_E;
3544
    if (b >= 0x08)
3545
        return ASN_PARSE_E;
3546
    if (b != 0) {
3547
        if ((byte)(input[idx + (word32)length - 1] << (8 - b)) != 0)
3548
            return ASN_PARSE_E;
3549
    }
3550
    idx++;
3551
    length--; /* length has been checked for greater than 0 */
3552
3553
    *inOutIdx = idx;
3554
    if (len != NULL)
3555
        *len = length;
3556
    if (unusedBits != NULL)
3557
        *unusedBits = b;
3558
3559
    return 0;
3560
#else
3561
0
    ASNGetData dataASN[bitStringASN_Length];
3562
0
    int ret;
3563
0
    int bits = 0;
3564
3565
    /* Parse BIT_STRING and check validity of unused bits. */
3566
0
    XMEMSET(dataASN, 0, sizeof(dataASN));
3567
    /* Decode BIT_STRING. */
3568
0
    ret = GetASN_Items(bitStringASN, dataASN, bitStringASN_Length, 0, input,
3569
0
            inOutIdx, maxIdx);
3570
0
    if (ret == 0) {
3571
        /* Get unused bits from dynamic ASN.1 data. */
3572
0
        bits = GetASNItem_UnusedBits(dataASN[BITSTRINGASN_IDX_BIT_STR]);
3573
        /* Check unused bits is 0 when expected. */
3574
0
        if (zeroBits && (bits != 0)) {
3575
0
            ret = ASN_EXPECT_0_E;
3576
0
        }
3577
0
    }
3578
0
    if (ret == 0) {
3579
        /* Return length of data and unused bits if required. */
3580
0
        if (len != NULL) {
3581
0
            *len = (int)dataASN[BITSTRINGASN_IDX_BIT_STR].data.ref.length;
3582
0
        }
3583
0
        if (unusedBits != NULL) {
3584
0
            *unusedBits = (byte)bits;
3585
0
        }
3586
0
    }
3587
3588
0
    return ret;
3589
0
#endif
3590
0
}
3591
3592
/* RSA (with CertGen or KeyGen) OR ECC OR ED25519 OR ED448 (with CertGen or
3593
 * KeyGen) */
3594
#if (!defined(NO_RSA) && \
3595
     (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || \
3596
      defined(OPENSSL_EXTRA))) || \
3597
    (defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)) || \
3598
    ((defined(HAVE_ED25519) || defined(HAVE_ED448)) && \
3599
     (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || \
3600
      defined(OPENSSL_EXTRA))) || \
3601
    (defined(WC_ENABLE_ASYM_KEY_EXPORT) && !defined(NO_CERTS)) || \
3602
    (!defined(NO_DSA) && !defined(HAVE_SELFTEST) && defined(WOLFSSL_KEY_GEN)) || \
3603
    (!defined(NO_DH) && defined(WOLFSSL_DH_EXTRA))
3604
3605
/* Set the DER/BER encoding of the ASN.1 BIT STRING header.
3606
 *
3607
 * When output is NULL, calculate the header length only.
3608
 *
3609
 * @param [in]  len         Length of BIT STRING data.
3610
 *                          That is, the number of least significant zero bits
3611
 *                          before a one.
3612
 *                          The last byte is the most-significant non-zero byte
3613
 *                          of a number.
3614
 * @param [out] output      Buffer to write into.
3615
 * @return  Number of bytes added to the buffer.
3616
 */
3617
word32 SetBitString(word32 len, byte unusedBits, byte* output)
3618
0
{
3619
0
    word32 idx = 0;
3620
3621
0
    if (output) {
3622
        /* Write out tag. */
3623
0
        output[idx] = ASN_BIT_STRING;
3624
0
    }
3625
    /* Step over tag. */
3626
0
    idx += ASN_TAG_SZ;
3627
3628
    /* Encode length - passing NULL for output will not encode.
3629
     * Add one to length for unused bits. */
3630
0
    idx += SetLength(len + 1, output ? output + idx : NULL);
3631
0
    if (output) {
3632
        /* Write out unused bits. */
3633
0
        output[idx] = unusedBits;
3634
0
    }
3635
    /* Skip over unused bits. */
3636
0
    idx++;
3637
3638
    /* Return index after header. */
3639
0
    return idx;
3640
0
}
3641
#endif /* !NO_RSA || HAVE_ECC || HAVE_ED25519 || HAVE_ED448 */
3642
3643
#ifdef ASN_BER_TO_DER
3644
3645
#ifndef BER_OCTET_LENGTH
3646
    #define BER_OCTET_LENGTH 4096
3647
#endif
3648
3649
/* sets the terminating 0x00 0x00 at the end of an indefinite length
3650
 * returns the number of bytes written */
3651
word32 SetIndefEnd(byte* output)
3652
{
3653
    byte terminate[ASN_INDEF_END_SZ] = { 0x00, 0x00 };
3654
3655
    if (output != NULL) {
3656
        XMEMCPY(output, terminate, ASN_INDEF_END_SZ);
3657
    }
3658
3659
    return (word32)ASN_INDEF_END_SZ;
3660
}
3661
3662
3663
/* Breaks an octet string up into chunks for use with streaming
3664
 * returns 0 on success and updates idx */
3665
int StreamOctetString(const byte* inBuf, word32 inBufSz, byte* out,
3666
                      word32* outSz, word32* idx)
3667
{
3668
    word32 i  = 0;
3669
    word32 outIdx = *idx;
3670
    byte* tmp = out;
3671
3672
    if (tmp) tmp += outIdx;
3673
3674
    while (i < inBufSz) {
3675
        word32 ret, sz;
3676
3677
        sz = BER_OCTET_LENGTH;
3678
3679
        if ((sz + i) > inBufSz) {
3680
            sz = inBufSz - i;
3681
        }
3682
3683
        ret = SetOctetString(sz, tmp);
3684
        if (ret > 0) {
3685
            outIdx += ret;
3686
        }
3687
3688
        if (tmp) {
3689
            if ((word32)ret + sz + i + outIdx > *outSz) {
3690
                return BUFFER_E;
3691
            }
3692
            XMEMCPY(tmp + ret, inBuf + i, sz);
3693
            tmp += sz + ret;
3694
        }
3695
        outIdx += sz;
3696
        i      += sz;
3697
    }
3698
3699
    if (tmp) {
3700
        *idx = outIdx;
3701
        return 0;
3702
    }
3703
    else {
3704
        *outSz = outIdx;
3705
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
3706
    }
3707
}
3708
3709
3710
/* Convert BER to DER */
3711
3712
/* Pull information from the ASN.1 BER encoded item header */
3713
static int GetBerHeader(const byte* data, word32* idx, word32 maxIdx,
3714
                        byte* pTag, word32* pLen, int* indef)
3715
{
3716
    int len = 0;
3717
    byte tag;
3718
    word32 i = *idx;
3719
3720
    *indef = 0;
3721
3722
    /* Check there is enough data for a minimal header */
3723
    if (i + 2 > maxIdx) {
3724
        return ASN_PARSE_E;
3725
    }
3726
3727
    /* Retrieve tag */
3728
    tag = data[i++];
3729
3730
    /* Indefinite length handled specially */
3731
    if (data[i] == ASN_INDEF_LENGTH) {
3732
        /* Check valid tag for indefinite */
3733
        if (((tag & 0xc0) == 0) && ((tag & ASN_CONSTRUCTED) == 0x00)) {
3734
            return ASN_PARSE_E;
3735
        }
3736
        i++;
3737
        *indef = 1;
3738
    }
3739
    else if (GetLength(data, &i, &len, maxIdx) < 0) {
3740
        return ASN_PARSE_E;
3741
    }
3742
3743
    /* Return tag, length and index after BER item header */
3744
    *pTag = tag;
3745
    *pLen = (word32)len;
3746
    *idx = i;
3747
    return 0;
3748
}
3749
3750
#ifndef INDEF_ITEMS_MAX
3751
#define INDEF_ITEMS_MAX       20
3752
#endif
3753
3754
/* Indef length item data */
3755
typedef struct Indef {
3756
    word32 start;
3757
    int depth;
3758
    int headerLen;
3759
    word32 len;
3760
} Indef;
3761
3762
/* Indef length items */
3763
typedef struct IndefItems
3764
{
3765
    Indef len[INDEF_ITEMS_MAX];
3766
    int cnt;
3767
    int idx;
3768
    int depth;
3769
} IndefItems;
3770
3771
3772
/* Get header length of current item */
3773
static int IndefItems_HeaderLen(IndefItems* items)
3774
{
3775
    return items->len[items->idx].headerLen;
3776
}
3777
3778
/* Get data length of current item */
3779
static word32 IndefItems_Len(IndefItems* items)
3780
{
3781
    return items->len[items->idx].len;
3782
}
3783
3784
/* Add a indefinite length item */
3785
static int IndefItems_AddItem(IndefItems* items, word32 start)
3786
{
3787
    int ret = 0;
3788
    int i;
3789
3790
    if (items->cnt == INDEF_ITEMS_MAX) {
3791
        ret = MEMORY_E;
3792
    }
3793
    else {
3794
        i = items->cnt++;
3795
        items->len[i].start = start;
3796
        items->len[i].depth = items->depth++;
3797
        items->len[i].headerLen = 1;
3798
        items->len[i].len = 0;
3799
        items->idx = i;
3800
    }
3801
3802
    return ret;
3803
}
3804
3805
/* Increase data length of current item */
3806
static void IndefItems_AddData(IndefItems* items, word32 length)
3807
{
3808
    items->len[items->idx].len += length;
3809
}
3810
3811
/* Update header length of current item to reflect data length */
3812
static void IndefItems_UpdateHeaderLen(IndefItems* items)
3813
{
3814
    items->len[items->idx].headerLen +=
3815
                               (int)SetLength(items->len[items->idx].len, NULL);
3816
}
3817
3818
/* Go to indefinite parent of current item */
3819
static void IndefItems_Up(IndefItems* items)
3820
{
3821
    int i;
3822
    int depth = items->len[items->idx].depth - 1;
3823
3824
    for (i = items->cnt - 1; i >= 0; i--) {
3825
        if (items->len[i].depth == depth) {
3826
            break;
3827
        }
3828
    }
3829
    items->idx = i;
3830
    items->depth = depth + 1;
3831
}
3832
3833
/* Calculate final length by adding length of indefinite child items */
3834
static void IndefItems_CalcLength(IndefItems* items)
3835
{
3836
    int i;
3837
    int idx = items->idx;
3838
3839
    for (i = idx + 1; i < items->cnt; i++) {
3840
        if (items->len[i].depth == items->depth) {
3841
            items->len[idx].len += (word32)items->len[i].headerLen;
3842
            items->len[idx].len += items->len[i].len;
3843
        }
3844
    }
3845
    items->len[idx].headerLen += (int)SetLength(items->len[idx].len, NULL);
3846
}
3847
3848
/* Add more data to indefinite length item */
3849
static void IndefItems_MoreData(IndefItems* items, word32 length)
3850
{
3851
    if (items->cnt > 0 && items->idx >= 0) {
3852
        items->len[items->idx].len += length;
3853
    }
3854
}
3855
3856
/* Convert a BER encoding with indefinite length items to DER.
3857
 *
3858
 * ber    BER encoded data.
3859
 * berSz  Length of BER encoded data.
3860
 * der    Buffer to hold DER encoded version of data.
3861
 *        NULL indicates only the length is required.
3862
 * derSz  The size of the buffer to hold the DER encoded data.
3863
 *        Will be set if der is NULL, otherwise the value is checked as der is
3864
 *        filled.
3865
 * returns ASN_PARSE_E if the BER data is invalid and BAD_FUNC_ARG if ber or
3866
 * derSz are NULL.
3867
 */
3868
int wc_BerToDer(const byte* ber, word32 berSz, byte* der, word32* derSz)
3869
{
3870
    int ret = 0;
3871
    word32 i, j;
3872
#ifdef WOLFSSL_SMALL_STACK
3873
    IndefItems* indefItems = NULL;
3874
#else
3875
    IndefItems indefItems[1];
3876
#endif
3877
    byte tag, basic;
3878
    word32 length;
3879
    int indef;
3880
3881
    if (ber == NULL || derSz == NULL)
3882
        return BAD_FUNC_ARG;
3883
3884
#ifdef WOLFSSL_SMALL_STACK
3885
    indefItems = (IndefItems *)XMALLOC(sizeof(IndefItems), NULL,
3886
                                                       DYNAMIC_TYPE_TMP_BUFFER);
3887
    if (indefItems == NULL) {
3888
        ret = MEMORY_E;
3889
        goto end;
3890
    }
3891
#endif
3892
3893
    XMEMSET(indefItems, 0, sizeof(*indefItems));
3894
3895
    /* Calculate indefinite item lengths */
3896
    for (i = 0; i < berSz; ) {
3897
        word32 start = i;
3898
3899
        /* Get next BER item */
3900
        ret = GetBerHeader(ber, &i, berSz, &tag, &length, &indef);
3901
        if (ret != 0) {
3902
            goto end;
3903
        }
3904
3905
        if (indef) {
3906
            /* Indefinite item - add to list */
3907
            ret = IndefItems_AddItem(indefItems, i);
3908
            if (ret != 0) {
3909
                goto end;
3910
            }
3911
3912
            if ((tag & 0xC0) == 0 &&
3913
                tag != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&
3914
                tag != (ASN_SET      | ASN_CONSTRUCTED)) {
3915
                /* Constructed basic type - get repeating tag */
3916
                basic = (byte)(tag & (~ASN_CONSTRUCTED));
3917
3918
                /* Add up lengths of each item below */
3919
                for (; i < berSz; ) {
3920
                    /* Get next BER_item */
3921
                    ret = GetBerHeader(ber, &i, berSz, &tag, &length, &indef);
3922
                    if (ret != 0) {
3923
                        goto end;
3924
                    }
3925
3926
                    /* End of content closes item */
3927
                    if (tag == ASN_EOC) {
3928
                        /* Must be zero length */
3929
                        if (length != 0) {
3930
                            ret = ASN_PARSE_E;
3931
                            goto end;
3932
                        }
3933
                        break;
3934
                    }
3935
3936
                    /* Must not be indefinite and tag must match parent */
3937
                    if (indef || tag != basic) {
3938
                        ret = ASN_PARSE_E;
3939
                        goto end;
3940
                    }
3941
3942
                    /* Add to length */
3943
                    IndefItems_AddData(indefItems, length);
3944
                    /* Skip data */
3945
                    i += length;
3946
                }
3947
3948
                /* Ensure we got an EOC and not end of data */
3949
                if (tag != ASN_EOC) {
3950
                    ret = ASN_PARSE_E;
3951
                    goto end;
3952
                }
3953
3954
                /* Set the header length to include the length field */
3955
                IndefItems_UpdateHeaderLen(indefItems);
3956
                /* Go to indefinite parent item */
3957
                IndefItems_Up(indefItems);
3958
            }
3959
        }
3960
        else if (tag == ASN_EOC) {
3961
            /* End-of-content must be 0 length */
3962
            if (length != 0) {
3963
                ret = ASN_PARSE_E;
3964
                goto end;
3965
            }
3966
            /* Check there is an item to close - missing EOC */
3967
            if (indefItems->depth == 0) {
3968
                ret = ASN_PARSE_E;
3969
                goto end;
3970
            }
3971
3972
            /* Finish calculation of data length for indefinite item */
3973
            IndefItems_CalcLength(indefItems);
3974
            /* Go to indefinite parent item */
3975
            IndefItems_Up(indefItems);
3976
        }
3977
        else {
3978
            /* Known length item to add in - make sure enough data for it */
3979
            if (i + length > berSz) {
3980
                ret = ASN_PARSE_E;
3981
                goto end;
3982
            }
3983
3984
            /* Include all data - can't have indefinite inside definite */
3985
            i += length;
3986
            /* Add entire item to current indefinite item */
3987
            IndefItems_MoreData(indefItems, i - start);
3988
        }
3989
    }
3990
    /* Check we had a EOC for each indefinite item */
3991
    if (indefItems->depth != 0) {
3992
        ret = ASN_PARSE_E;
3993
        goto end;
3994
    }
3995
3996
    /* Write out DER */
3997
3998
    j = 0;
3999
    /* Reset index */
4000
    indefItems->idx = 0;
4001
    for (i = 0; i < berSz; ) {
4002
        word32 start = i;
4003
4004
        /* Get item - checked above */
4005
        (void)GetBerHeader(ber, &i, berSz, &tag, &length, &indef);
4006
        if (indef) {
4007
            if (der != NULL) {
4008
                /* Check enough space for header */
4009
                if (j + (word32)IndefItems_HeaderLen(indefItems) > *derSz) {
4010
                    ret = BUFFER_E;
4011
                    goto end;
4012
                }
4013
4014
                if ((tag & 0xC0) == 0 &&
4015
                    tag != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&
4016
                    tag != (ASN_SET      | ASN_CONSTRUCTED)) {
4017
                    /* Remove constructed tag for basic types */
4018
                    tag &= (byte)~ASN_CONSTRUCTED;
4019
                }
4020
                /* Add tag and length */
4021
                der[j] = tag;
4022
                (void)SetLength(IndefItems_Len(indefItems), der + j + 1);
4023
            }
4024
            /* Add header length of indefinite item */
4025
            j += (word32)IndefItems_HeaderLen(indefItems);
4026
4027
            if ((tag & 0xC0) == 0 &&
4028
                tag != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&
4029
                tag != (ASN_SET      | ASN_CONSTRUCTED)) {
4030
                /* For basic type - get each child item and add data */
4031
                for (; i < berSz; ) {
4032
                    (void)GetBerHeader(ber, &i, berSz, &tag, &length, &indef);
4033
                    if (tag == ASN_EOC) {
4034
                        break;
4035
                    }
4036
                    if (der != NULL) {
4037
                        if (j + length > *derSz) {
4038
                            ret = BUFFER_E;
4039
                            goto end;
4040
                        }
4041
                        XMEMCPY(der + j, ber + i, length);
4042
                    }
4043
                    j += length;
4044
                    i += length;
4045
                }
4046
            }
4047
4048
            /* Move to next indef item in list */
4049
            indefItems->idx++;
4050
        }
4051
        else if (tag == ASN_EOC) {
4052
            /* End-Of-Content is not written out in DER */
4053
        }
4054
        else {
4055
            /* Write out definite length item as is. */
4056
            i += length;
4057
            if (der != NULL) {
4058
                /* Ensure space for item */
4059
                if (j + i - start > *derSz) {
4060
                    ret = BUFFER_E;
4061
                    goto end;
4062
                }
4063
                /* Copy item as is */
4064
                XMEMCPY(der + j, ber + start, i - start);
4065
            }
4066
            j += i - start;
4067
        }
4068
    }
4069
4070
    /* Return the length of the DER encoded ASN.1 */
4071
    *derSz = j;
4072
    if (der == NULL) {
4073
        ret = WC_NO_ERR_TRACE(LENGTH_ONLY_E);
4074
    }
4075
end:
4076
#ifdef WOLFSSL_SMALL_STACK
4077
    XFREE(indefItems, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4078
#endif
4079
    return ret;
4080
}
4081
#endif
4082
4083
#ifndef WOLFSSL_ASN_TEMPLATE
4084
#if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)
4085
/* Set the DER/BER encoding of the ASN.1 BIT_STRING with a 16-bit value.
4086
 *
4087
 * val         16-bit value to encode.
4088
 * output      Buffer to write into.
4089
 * returns the number of bytes added to the buffer.
4090
 */
4091
static word32 SetBitString16Bit(word16 val, byte* output)
4092
{
4093
    word32 idx;
4094
    int    len;
4095
    byte   lastByte;
4096
    byte   unusedBits = 0;
4097
4098
    if ((val >> 8) != 0) {
4099
        len = 2;
4100
        lastByte = (byte)(val >> 8);
4101
    }
4102
    else {
4103
        len = 1;
4104
        lastByte = (byte)val;
4105
    }
4106
4107
    while (((lastByte >> unusedBits) & 0x01) == 0x00)
4108
        unusedBits++;
4109
4110
    idx = SetBitString((word32)len, unusedBits, output);
4111
    output[idx++] = (byte)val;
4112
    if (len > 1)
4113
        output[idx++] = (byte)(val >> 8);
4114
4115
    return idx;
4116
}
4117
#endif /* WOLFSSL_CERT_EXT || WOLFSSL_CERT_GEN */
4118
#endif /* !WOLFSSL_ASN_TEMPLATE */
4119
4120
/* hashType */
4121
#ifdef WOLFSSL_MD2
4122
    static const byte hashMd2hOid[] = {42, 134, 72, 134, 247, 13, 2, 2};
4123
#endif
4124
#ifndef NO_MD5
4125
    static const byte hashMd5hOid[] = {42, 134, 72, 134, 247, 13, 2, 5};
4126
#endif
4127
#ifndef NO_SHA
4128
    static const byte hashSha1hOid[] = {43, 14, 3, 2, 26};
4129
#endif
4130
#ifdef WOLFSSL_SHA224
4131
    static const byte hashSha224hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 4};
4132
#endif
4133
#ifndef NO_SHA256
4134
    static const byte hashSha256hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 1};
4135
#endif
4136
#ifdef WOLFSSL_SHA384
4137
    static const byte hashSha384hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 2};
4138
#endif
4139
#ifdef WOLFSSL_SHA512
4140
    static const byte hashSha512hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 3};
4141
    #ifndef WOLFSSL_NOSHA512_224
4142
    static const byte hashSha512_224hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 5};
4143
    #endif
4144
    #ifndef WOLFSSL_NOSHA512_256
4145
    static const byte hashSha512_256hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 6};
4146
    #endif
4147
#endif
4148
#ifdef WOLFSSL_SHA3
4149
#ifndef WOLFSSL_NOSHA3_224
4150
    static const byte hashSha3_224hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 7};
4151
#endif /* WOLFSSL_NOSHA3_224 */
4152
#ifndef WOLFSSL_NOSHA3_256
4153
    static const byte hashSha3_256hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 8};
4154
#endif /* WOLFSSL_NOSHA3_256 */
4155
#ifndef WOLFSSL_NOSHA3_384
4156
    static const byte hashSha3_384hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 9};
4157
#endif /* WOLFSSL_NOSHA3_384 */
4158
#ifndef WOLFSSL_NOSHA3_512
4159
    static const byte hashSha3_512hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 10};
4160
#endif /* WOLFSSL_NOSHA3_512 */
4161
#endif /* WOLFSSL_SHA3 */
4162
4163
/* hmacType */
4164
#ifndef NO_HMAC
4165
    #ifdef WOLFSSL_SHA224
4166
    static const byte hmacSha224Oid[] = {42, 134, 72, 134, 247, 13, 2, 8};
4167
    #endif
4168
    #ifndef NO_SHA256
4169
    static const byte hmacSha256Oid[] = {42, 134, 72, 134, 247, 13, 2, 9};
4170
    #endif
4171
    #ifdef WOLFSSL_SHA384
4172
    static const byte hmacSha384Oid[] = {42, 134, 72, 134, 247, 13, 2, 10};
4173
    #endif
4174
    #ifdef WOLFSSL_SHA512
4175
    static const byte hmacSha512Oid[] = {42, 134, 72, 134, 247, 13, 2, 11};
4176
    #endif
4177
#endif
4178
4179
/* sigType */
4180
#if !defined(NO_DSA) && !defined(NO_SHA)
4181
    static const byte sigSha1wDsaOid[] = {42, 134, 72, 206, 56, 4, 3};
4182
    static const byte sigSha256wDsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 2};
4183
#endif /* NO_DSA */
4184
#ifndef NO_RSA
4185
    #ifdef WOLFSSL_MD2
4186
    static const byte sigMd2wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 2};
4187
    #endif
4188
    #ifndef NO_MD5
4189
    static const byte sigMd5wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 4};
4190
    #endif
4191
    #ifndef NO_SHA
4192
    static const byte sigSha1wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 5};
4193
    #endif
4194
    #ifdef WOLFSSL_SHA224
4195
    static const byte sigSha224wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,14};
4196
    #endif
4197
    #ifndef NO_SHA256
4198
    static const byte sigSha256wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,11};
4199
    #endif
4200
    #ifdef WOLFSSL_SHA384
4201
    static const byte sigSha384wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,12};
4202
    #endif
4203
    #ifdef WOLFSSL_SHA512
4204
    static const byte sigSha512wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,13};
4205
    #endif
4206
    #ifdef WOLFSSL_SHA3
4207
    #ifndef WOLFSSL_NOSHA3_224
4208
    static const byte sigSha3_224wRsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 13};
4209
    #endif
4210
    #ifndef WOLFSSL_NOSHA3_256
4211
    static const byte sigSha3_256wRsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 14};
4212
    #endif
4213
    #ifndef WOLFSSL_NOSHA3_384
4214
    static const byte sigSha3_384wRsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 15};
4215
    #endif
4216
    #ifndef WOLFSSL_NOSHA3_512
4217
    static const byte sigSha3_512wRsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 16};
4218
    #endif
4219
    #endif
4220
    #ifdef WC_RSA_PSS
4221
    static const byte sigRsaSsaPssOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 10};
4222
    #endif
4223
#endif /* NO_RSA */
4224
#ifdef HAVE_ECC
4225
    #ifndef NO_SHA
4226
    static const byte sigSha1wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 1};
4227
    #endif
4228
    #ifdef WOLFSSL_SHA224
4229
    static const byte sigSha224wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 1};
4230
    #endif
4231
    #ifndef NO_SHA256
4232
    static const byte sigSha256wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 2};
4233
    #endif
4234
    #ifdef WOLFSSL_SHA384
4235
    static const byte sigSha384wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 3};
4236
    #endif
4237
    #ifdef WOLFSSL_SHA512
4238
    static const byte sigSha512wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 4};
4239
    #endif
4240
    #ifdef WOLFSSL_SHA3
4241
    #ifndef WOLFSSL_NOSHA3_224
4242
    static const byte sigSha3_224wEcdsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 9};
4243
    #endif
4244
    #ifndef WOLFSSL_NOSHA3_256
4245
    static const byte sigSha3_256wEcdsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 10};
4246
    #endif
4247
    #ifndef WOLFSSL_NOSHA3_384
4248
    static const byte sigSha3_384wEcdsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 11};
4249
    #endif
4250
    #ifndef WOLFSSL_NOSHA3_512
4251
    static const byte sigSha3_512wEcdsaOid[] = {96, 134, 72, 1, 101, 3, 4, 3, 12};
4252
    #endif
4253
    #endif
4254
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
4255
    /* 0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01, 0x83, 0x75 */
4256
    static const byte sigSm3wSm2Oid[] = {42, 129, 28, 207, 85, 1, 131, 117};
4257
    #endif
4258
#endif /* HAVE_ECC */
4259
#ifdef HAVE_ED25519
4260
    static const byte sigEd25519Oid[] = {43, 101, 112};
4261
#endif /* HAVE_ED25519 */
4262
#ifdef HAVE_ED448
4263
    static const byte sigEd448Oid[] = {43, 101, 113};
4264
#endif /* HAVE_ED448 */
4265
#ifdef HAVE_FALCON
4266
    /* Falcon Level 1: 1 3 9999 3 6 */
4267
    static const byte sigFalcon_Level1Oid[] = {43, 206, 15, 3, 6};
4268
4269
    /* Falcon Level 5: 1 3 9999 3 9 */
4270
    static const byte sigFalcon_Level5Oid[] = {43, 206, 15, 3, 9};
4271
#endif /* HAVE_FACON */
4272
#ifdef HAVE_DILITHIUM
4273
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
4274
    /* Dilithium Level 2: 1.3.6.1.4.1.2.267.12.4.4 */
4275
    static const byte sigDilithium_Level2Oid[] =
4276
        {43, 6, 1, 4, 1, 2, 130, 11, 12, 4, 4};
4277
4278
    /* Dilithium Level 3: 1.3.6.1.4.1.2.267.12.6.5 */
4279
    static const byte sigDilithium_Level3Oid[] =
4280
        {43, 6, 1, 4, 1, 2, 130, 11, 12, 6, 5};
4281
4282
    /* Dilithium Level 5: 1.3.6.1.4.1.2.267.12.8.7 */
4283
    static const byte sigDilithium_Level5Oid[] =
4284
        {43, 6, 1, 4, 1, 2, 130, 11, 12, 8, 7};
4285
#endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */
4286
4287
    /* ML-DSA Level 2: 2.16.840.1.101.3.4.3.17 */
4288
    static const byte sigMlDsa_Level2Oid[] =
4289
        {96, 134, 72, 1, 101, 3, 4, 3, 17};
4290
4291
    /* ML-DSA Level 3: 2.16.840.1.101.3.4.3.18 */
4292
    static const byte sigMlDsa_Level3Oid[] =
4293
        {96, 134, 72, 1, 101, 3, 4, 3, 18};
4294
4295
    /* ML-DSA Level 5: 2.16.840.1.101.3.4.3.19 */
4296
    static const byte sigMlDsa_Level5Oid[] =
4297
        {96, 134, 72, 1, 101, 3, 4, 3, 19};
4298
#endif /* HAVE_DILITHIUM */
4299
#ifdef HAVE_SPHINCS
4300
    /* Sphincs Fast Level 1: 1 3 9999 6 7 4 */
4301
    static const byte sigSphincsFast_Level1Oid[] =
4302
        {43, 206, 15, 6, 7, 4};
4303
4304
    /* Sphincs Fast Level 3: 1 3 9999 6 8 3 */
4305
    static const byte sigSphincsFast_Level3Oid[] =
4306
        {43, 206, 15, 6, 8, 3};
4307
4308
    /* Sphincs Fast Level 5: 1 3 9999 6 9 3 */
4309
    static const byte sigSphincsFast_Level5Oid[] =
4310
        {43, 206, 15, 6, 9, 3};
4311
4312
    /* Sphincs Small Level 1: 1 3 9999 6 7 10 */
4313
    static const byte sigSphincsSmall_Level1Oid[] =
4314
        {43, 206, 15, 6, 7, 10};
4315
4316
    /* Sphincs Small Level 3: 1 3 9999 6 8 7 */
4317
    static const byte sigSphincsSmall_Level3Oid[] =
4318
        {43, 206, 15, 6, 8, 7};
4319
4320
    /* Sphincs Small Level 5: 1 3 9999 6 9 7 */
4321
    static const byte sigSphincsSmall_Level5Oid[] =
4322
        {43, 206, 15, 6, 9, 7};
4323
#endif /* HAVE_SPHINCS */
4324
4325
/* keyType */
4326
#ifndef NO_DSA
4327
    static const byte keyDsaOid[] = {42, 134, 72, 206, 56, 4, 1};
4328
#endif /* NO_DSA */
4329
#ifndef NO_RSA
4330
    static const byte keyRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 1};
4331
#ifdef WC_RSA_PSS
4332
    static const byte keyRsaPssOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 10};
4333
#endif
4334
#endif /* NO_RSA */
4335
#ifdef HAVE_ECC
4336
    static const byte keyEcdsaOid[] = {42, 134, 72, 206, 61, 2, 1};
4337
#endif /* HAVE_ECC */
4338
#ifdef HAVE_ED25519
4339
    static const byte keyEd25519Oid[] = {43, 101, 112};
4340
#endif /* HAVE_ED25519 */
4341
#ifdef HAVE_CURVE25519
4342
    static const byte keyCurve25519Oid[] = {43, 101, 110};
4343
#endif
4344
#ifdef HAVE_ED448
4345
    static const byte keyEd448Oid[] = {43, 101, 113};
4346
#endif /* HAVE_ED448 */
4347
#ifdef HAVE_CURVE448
4348
    static const byte keyCurve448Oid[] = {43, 101, 111};
4349
#endif /* HAVE_CURVE448 */
4350
#ifndef NO_DH
4351
    static const byte keyDhOid[] = {42, 134, 72, 134, 247, 13, 1, 3, 1};
4352
#endif /* !NO_DH */
4353
#ifdef HAVE_FALCON
4354
    /* Falcon Level 1: 1 3 9999 3 6 */
4355
    static const byte keyFalcon_Level1Oid[] = {43, 206, 15, 3, 6};
4356
4357
    /* Falcon Level 5: 1 3 9999 3 9 */
4358
    static const byte keyFalcon_Level5Oid[] = {43, 206, 15, 3, 9};
4359
#endif /* HAVE_FALCON */
4360
#ifdef HAVE_DILITHIUM
4361
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
4362
    /* Dilithium Level 2: 1.3.6.1.4.1.2.267.12.4.4 */
4363
    static const byte keyDilithium_Level2Oid[] =
4364
        {43, 6, 1, 4, 1, 2, 130, 11, 12, 4, 4};
4365
4366
    /* Dilithium Level 3: 1.3.6.1.4.1.2.267.12.6.5 */
4367
    static const byte keyDilithium_Level3Oid[] =
4368
        {43, 6, 1, 4, 1, 2, 130, 11, 12, 6, 5};
4369
4370
    /* Dilithium Level 5: 1.3.6.1.4.1.2.267.12.8.7 */
4371
    static const byte keyDilithium_Level5Oid[] =
4372
        {43, 6, 1, 4, 1, 2, 130, 11, 12, 8, 7};
4373
#endif
4374
4375
    /* ML-DSA Level 2: 2.16.840.1.101.3.4.3.17 */
4376
    static const byte keyMlDsa_Level2Oid[] =
4377
        {96, 134, 72, 1, 101, 3, 4, 3, 17};
4378
4379
    /* ML-DSA Level 3: 2.16.840.1.101.3.4.3.18 */
4380
    static const byte keyMlDsa_Level3Oid[] =
4381
        {96, 134, 72, 1, 101, 3, 4, 3, 18};
4382
4383
    /* ML-DSA Level 5: 2.16.840.1.101.3.4.3.19 */
4384
    static const byte keyMlDsa_Level5Oid[] =
4385
        {96, 134, 72, 1, 101, 3, 4, 3, 19};
4386
#endif /* HAVE_DILITHIUM */
4387
#ifdef HAVE_SPHINCS
4388
    /* Sphincs Fast Level 1: 1 3 9999 6 7 4 */
4389
    static const byte keySphincsFast_Level1Oid[] =
4390
        {43, 206, 15, 6, 7, 4};
4391
4392
    /* Sphincs Fast Level 3: 1 3 9999 6 8 3 */
4393
    static const byte keySphincsFast_Level3Oid[] =
4394
        {43, 206, 15, 6, 8, 3};
4395
4396
    /* Sphincs Fast Level 5: 1 3 9999 6 9 3 */
4397
    static const byte keySphincsFast_Level5Oid[] =
4398
        {43, 206, 15, 6, 9, 3};
4399
4400
    /* Sphincs Small Level 1: 1 3 9999 6 7 10 */
4401
    static const byte keySphincsSmall_Level1Oid[] =
4402
        {43, 206, 15, 6, 7, 10};
4403
4404
    /* Sphincs Small Level 3: 1 3 9999 6 8 7 */
4405
    static const byte keySphincsSmall_Level3Oid[] =
4406
        {43, 206, 15, 6, 8, 7};
4407
4408
    /* Sphincs Small Level 5: 1 3 9999 6 9 7 */
4409
    static const byte keySphincsSmall_Level5Oid[] =
4410
        {43, 206, 15, 6, 9, 7};
4411
#endif /* HAVE_SPHINCS */
4412
4413
/* curveType */
4414
#ifdef HAVE_ECC
4415
    /* See "ecc_sets" table in ecc.c */
4416
#endif /* HAVE_ECC */
4417
4418
#ifdef HAVE_AES_CBC
4419
/* blkType */
4420
    #ifdef WOLFSSL_AES_128
4421
    static const byte blkAes128CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 2};
4422
    #endif
4423
    #ifdef WOLFSSL_AES_192
4424
    static const byte blkAes192CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 22};
4425
    #endif
4426
    #ifdef WOLFSSL_AES_256
4427
    static const byte blkAes256CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 42};
4428
    #endif
4429
#endif /* HAVE_AES_CBC */
4430
#ifdef HAVE_AESGCM
4431
    #ifdef WOLFSSL_AES_128
4432
    static const byte blkAes128GcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 6};
4433
    #endif
4434
    #ifdef WOLFSSL_AES_192
4435
    static const byte blkAes192GcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 26};
4436
    #endif
4437
    #ifdef WOLFSSL_AES_256
4438
    static const byte blkAes256GcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 46};
4439
    #endif
4440
#endif /* HAVE_AESGCM */
4441
#ifdef HAVE_AESCCM
4442
    #ifdef WOLFSSL_AES_128
4443
    static const byte blkAes128CcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 7};
4444
    #endif
4445
    #ifdef WOLFSSL_AES_192
4446
    static const byte blkAes192CcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 27};
4447
    #endif
4448
    #ifdef WOLFSSL_AES_256
4449
    static const byte blkAes256CcmOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 47};
4450
    #endif
4451
#endif /* HAVE_AESCCM */
4452
4453
#ifndef NO_DES3
4454
    static const byte blkDesCbcOid[]  = {43, 14, 3, 2, 7};
4455
    static const byte blkDes3CbcOid[] = {42, 134, 72, 134, 247, 13, 3, 7};
4456
#endif
4457
4458
/* keyWrapType */
4459
#ifdef WOLFSSL_AES_128
4460
    static const byte wrapAes128Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 5};
4461
#endif
4462
#ifdef WOLFSSL_AES_192
4463
    static const byte wrapAes192Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 25};
4464
#endif
4465
#ifdef WOLFSSL_AES_256
4466
    static const byte wrapAes256Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 45};
4467
#endif
4468
#ifdef HAVE_PKCS7
4469
/* From RFC 3211 */
4470
static const byte wrapPwriKekOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 16, 3,9};
4471
#endif
4472
4473
/* cmsKeyAgreeType */
4474
#ifndef NO_SHA
4475
    static const byte dhSinglePass_stdDH_sha1kdf_Oid[]   =
4476
                                          {43, 129, 5, 16, 134, 72, 63, 0, 2};
4477
#endif
4478
#ifdef WOLFSSL_SHA224
4479
    static const byte dhSinglePass_stdDH_sha224kdf_Oid[] = {43, 129, 4, 1, 11, 0};
4480
#endif
4481
#ifndef NO_SHA256
4482
    static const byte dhSinglePass_stdDH_sha256kdf_Oid[] = {43, 129, 4, 1, 11, 1};
4483
#endif
4484
#ifdef WOLFSSL_SHA384
4485
    static const byte dhSinglePass_stdDH_sha384kdf_Oid[] = {43, 129, 4, 1, 11, 2};
4486
#endif
4487
#ifdef WOLFSSL_SHA512
4488
    static const byte dhSinglePass_stdDH_sha512kdf_Oid[] = {43, 129, 4, 1, 11, 3};
4489
#endif
4490
4491
/* ocspType */
4492
#ifdef HAVE_OCSP
4493
    static const byte ocspBasicOid[]    = {43, 6, 1, 5, 5, 7, 48, 1, 1};
4494
    static const byte ocspNonceOid[]    = {43, 6, 1, 5, 5, 7, 48, 1, 2};
4495
    static const byte ocspNoCheckOid[]  = {43, 6, 1, 5, 5, 7, 48, 1, 5};
4496
#endif /* HAVE_OCSP */
4497
4498
/* certExtType */
4499
static const byte extBasicCaOid[] = {85, 29, 19};
4500
static const byte extAltNamesOid[] = {85, 29, 17};
4501
static const byte extCrlDistOid[] = {85, 29, 31};
4502
static const byte extAuthInfoOid[] = {43, 6, 1, 5, 5, 7, 1, 1};
4503
static const byte extAuthKeyOid[] = {85, 29, 35};
4504
static const byte extSubjKeyOid[] = {85, 29, 14};
4505
static const byte extCertPolicyOid[] = {85, 29, 32};
4506
static const byte extKeyUsageOid[] = {85, 29, 15};
4507
static const byte extInhibitAnyOid[] = {85, 29, 54};
4508
static const byte extExtKeyUsageOid[] = {85, 29, 37};
4509
#ifndef IGNORE_NAME_CONSTRAINTS
4510
    static const byte extNameConsOid[] = {85, 29, 30};
4511
#endif
4512
#ifdef HAVE_CRL
4513
static const byte extCrlNumberOid[] = {85, 29, 20};
4514
#endif
4515
#ifdef WOLFSSL_SUBJ_DIR_ATTR
4516
    static const byte extSubjDirAttrOid[] = {85, 29, 9};
4517
#endif
4518
#ifdef WOLFSSL_SUBJ_INFO_ACC
4519
    static const byte extSubjInfoAccessOid[] = {43, 6, 1, 5, 5, 7, 1, 11};
4520
#endif
4521
4522
/* certAuthInfoType */
4523
static const byte extAuthInfoOcspOid[] = {43, 6, 1, 5, 5, 7, 48, 1};
4524
static const byte extAuthInfoCaIssuerOid[] = {43, 6, 1, 5, 5, 7, 48, 2};
4525
#ifdef WOLFSSL_SUBJ_INFO_ACC
4526
    static const byte extAuthInfoCaRespOid[] = {43, 6, 1, 5, 5, 7, 48, 5};
4527
#endif /* WOLFSSL_SUBJ_INFO_ACC */
4528
4529
/* certPolicyType */
4530
static const byte extCertPolicyAnyOid[] = {85, 29, 32, 0};
4531
static const byte extCertPolicyIsrgDomainValid[] =
4532
    {43, 6, 1, 4, 1, 130, 223, 19, 1, 1, 1};
4533
#ifdef WOLFSSL_FPKI
4534
#define CERT_POLICY_TYPE_OID_BASE(num) {96, 134, 72, 1, 101, 3, 2, 1, 3, num}
4535
    static const byte extCertPolicyFpkiHighAssuranceOid[] =
4536
            CERT_POLICY_TYPE_OID_BASE(4);
4537
    static const byte extCertPolicyFpkiCommonHardwareOid[] =
4538
            CERT_POLICY_TYPE_OID_BASE(7);
4539
    static const byte extCertPolicyFpkiMediumHardwareOid[] =
4540
            CERT_POLICY_TYPE_OID_BASE(12);
4541
    static const byte extCertPolicyFpkiCommonAuthOid[] =
4542
            CERT_POLICY_TYPE_OID_BASE(13);
4543
    static const byte extCertPolicyFpkiCommonHighOid[] =
4544
            CERT_POLICY_TYPE_OID_BASE(16);
4545
    static const byte extCertPolicyFpkiCommonDevicesHardwareOid[] =
4546
            CERT_POLICY_TYPE_OID_BASE(36);
4547
    static const byte extCertPolicyFpkiCommonPivContentSigningOid[] =
4548
            CERT_POLICY_TYPE_OID_BASE(39);
4549
    static const byte extCertPolicyFpkiPivAuthOid[] =
4550
            CERT_POLICY_TYPE_OID_BASE(40);
4551
    static const byte extCertPolicyFpkiPivAuthHwOid[] =
4552
            CERT_POLICY_TYPE_OID_BASE(41);
4553
    static const byte extCertPolicyFpkiPiviAuthOid[] =
4554
            CERT_POLICY_TYPE_OID_BASE(45);
4555
4556
    /* Federal PKI Test OIDs - 2.16.840.1.101.3.2.1.48.x */
4557
    #define TEST_CERT_POLICY_TYPE_OID_BASE(num) {96, 134, 72, 1, 101, 3, 2, 1, 48, num}
4558
    static const byte extCertPolicyFpkiAuthTestOid[] =
4559
        TEST_CERT_POLICY_TYPE_OID_BASE(11);
4560
    static const byte extCertPolicyFpkiCardauthTestOid[] =
4561
        TEST_CERT_POLICY_TYPE_OID_BASE(13);
4562
    static const byte extCertPolicyFpkiPivContentTestOid[] =
4563
        TEST_CERT_POLICY_TYPE_OID_BASE(86);
4564
    static const byte extCertPolicyFpkiAuthDerivedTestOid[] =
4565
        TEST_CERT_POLICY_TYPE_OID_BASE(109);
4566
    static const byte extCertPolicyFpkiAuthDerivedHwTestOid[] =
4567
        TEST_CERT_POLICY_TYPE_OID_BASE(110);
4568
4569
    /* DoD PKI OIDs - 2.16.840.1.101.2.1.11.X */
4570
    #define DOD_POLICY_TYPE_OID_BASE(num) {96, 134, 72, 1, 101, 2, 1, 11, num}
4571
    static const byte extCertPolicyDodMediumOid[] =
4572
            DOD_POLICY_TYPE_OID_BASE(5);
4573
    static const byte extCertPolicyDodMediumHardwareOid[] =
4574
            DOD_POLICY_TYPE_OID_BASE(9);
4575
    static const byte extCertPolicyDodPivAuthOid[] =
4576
            DOD_POLICY_TYPE_OID_BASE(10);
4577
    static const byte extCertPolicyDodMediumNpeOid[] =
4578
            DOD_POLICY_TYPE_OID_BASE(17);
4579
    static const byte extCertPolicyDodMedium2048Oid[] =
4580
            DOD_POLICY_TYPE_OID_BASE(18);
4581
    static const byte extCertPolicyDodMediumHardware2048Oid[] =
4582
            DOD_POLICY_TYPE_OID_BASE(19);
4583
    static const byte extCertPolicyDodPivAuth2048Oid[] =
4584
            DOD_POLICY_TYPE_OID_BASE(20);
4585
    static const byte extCertPolicyDodPeerInteropOid[] =
4586
            DOD_POLICY_TYPE_OID_BASE(31);
4587
    static const byte extCertPolicyDodMediumNpe112Oid[] =
4588
            DOD_POLICY_TYPE_OID_BASE(36);
4589
    static const byte extCertPolicyDodMediumNpe128Oid[] =
4590
            DOD_POLICY_TYPE_OID_BASE(37);
4591
    static const byte extCertPolicyDodMediumNpe192Oid[] =
4592
            DOD_POLICY_TYPE_OID_BASE(38);
4593
    static const byte extCertPolicyDodMedium112Oid[] =
4594
            DOD_POLICY_TYPE_OID_BASE(39);
4595
    static const byte extCertPolicyDodMedium128Oid[] =
4596
            DOD_POLICY_TYPE_OID_BASE(40);
4597
    static const byte extCertPolicyDodMedium192Oid[] =
4598
            DOD_POLICY_TYPE_OID_BASE(41);
4599
    static const byte extCertPolicyDodMediumHardware112Oid[] =
4600
            DOD_POLICY_TYPE_OID_BASE(42);
4601
    static const byte extCertPolicyDodMediumHardware128Oid[] =
4602
            DOD_POLICY_TYPE_OID_BASE(43);
4603
    static const byte extCertPolicyDodMediumHardware192Oid[] =
4604
            DOD_POLICY_TYPE_OID_BASE(44);
4605
    static const byte extCertPolicyDodAdminOid[] =
4606
            DOD_POLICY_TYPE_OID_BASE(59);
4607
    static const byte extCertPolicyDodInternalNpe112Oid[] =
4608
            DOD_POLICY_TYPE_OID_BASE(60);
4609
    static const byte extCertPolicyDodInternalNpe128Oid[] =
4610
            DOD_POLICY_TYPE_OID_BASE(61);
4611
    static const byte extCertPolicyDodInternalNpe192Oid[] =
4612
            DOD_POLICY_TYPE_OID_BASE(62);
4613
4614
    /* ECA PKI OIDs - 2.16.840.1.101.3.2.1.12.X */
4615
    #define ECA_POLICY_TYPE_OID_BASE(num) {96, 134, 72, 1, 101, 3, 2, 1, 12, num}
4616
    static const byte extCertPolicyEcaMediumOid[] =
4617
            ECA_POLICY_TYPE_OID_BASE(1);
4618
    static const byte extCertPolicyEcaMediumHardwareOid[] =
4619
            ECA_POLICY_TYPE_OID_BASE(2);
4620
    static const byte extCertPolicyEcaMediumTokenOid[] =
4621
            ECA_POLICY_TYPE_OID_BASE(3);
4622
    static const byte extCertPolicyEcaMediumSha256Oid[] =
4623
            ECA_POLICY_TYPE_OID_BASE(4);
4624
    static const byte extCertPolicyEcaMediumTokenSha256Oid[] =
4625
            ECA_POLICY_TYPE_OID_BASE(5);
4626
    static const byte extCertPolicyEcaMediumHardwarePiviOid[] =
4627
            ECA_POLICY_TYPE_OID_BASE(6);
4628
    static const byte extCertPolicyEcaContentSigningPiviOid[] =
4629
            ECA_POLICY_TYPE_OID_BASE(8);
4630
    static const byte extCertPolicyEcaMediumDeviceSha256Oid[] =
4631
            ECA_POLICY_TYPE_OID_BASE(9);
4632
    static const byte extCertPolicyEcaMediumHardwareSha256Oid[] =
4633
            ECA_POLICY_TYPE_OID_BASE(10);
4634
4635
    /* Department of State PKI OIDs - 2.16.840.1.101.3.2.1.6.X */
4636
    #define STATE_POLICY_TYPE_OID_BASE(num) {96, 134, 72, 1, 101, 3, 2, 1, 6, num}
4637
    static const byte extCertPolicyStateBasicOid[] =
4638
            STATE_POLICY_TYPE_OID_BASE(1);
4639
    static const byte extCertPolicyStateLowOid[] =
4640
            STATE_POLICY_TYPE_OID_BASE(2);
4641
    static const byte extCertPolicyStateModerateOid[] =
4642
            STATE_POLICY_TYPE_OID_BASE(3);
4643
    static const byte extCertPolicyStateHighOid[] =
4644
            STATE_POLICY_TYPE_OID_BASE(4);
4645
    static const byte extCertPolicyStateMedHwOid[] =
4646
            STATE_POLICY_TYPE_OID_BASE(12);
4647
    static const byte extCertPolicyStateMediumDeviceHardwareOid[] =
4648
            STATE_POLICY_TYPE_OID_BASE(38);
4649
4650
    /* U.S. Treasury SSP PKI OIDs - 2.16.840.1.101.3.2.1.5.X */
4651
    #define TREASURY_POLICY_TYPE_OID_BASE(num) {96, 134, 72, 1, 101, 3, 2, 1, 5, num}
4652
    static const byte extCertPolicyTreasuryMediumHardwareOid[] =
4653
            TREASURY_POLICY_TYPE_OID_BASE(4);
4654
    static const byte extCertPolicyTreasuryHighOid[] =
4655
            TREASURY_POLICY_TYPE_OID_BASE(5);
4656
    static const byte extCertPolicyTreasuryPiviHardwareOid[] =
4657
            TREASURY_POLICY_TYPE_OID_BASE(10);
4658
    static const byte extCertPolicyTreasuryPiviContentSigningOid[] =
4659
            TREASURY_POLICY_TYPE_OID_BASE(12);
4660
4661
    /* Boeing PKI OIDs - 1.3.6.1.4.1.73.15.3.1.X */
4662
    #define BOEING_POLICY_TYPE_OID_BASE(num) {43, 6, 1, 4, 1, 73, 15, 3, 1, num}
4663
    static const byte extCertPolicyBoeingMediumHardwareSha256Oid[] =
4664
            BOEING_POLICY_TYPE_OID_BASE(12);
4665
    static const byte extCertPolicyBoeingMediumHardwareContentSigningSha256Oid[] =
4666
            BOEING_POLICY_TYPE_OID_BASE(17);
4667
4668
    /* Carillon Federal Services OIDs - 1.3.6.1.4.1.45606.3.1.X */
4669
    #define CARILLON_POLICY_TYPE_OID_BASE(num) {43, 6, 1, 4, 1, 130, 228, 38, 3, 1, num}
4670
    static const byte extCertPolicyCarillonMediumhw256Oid[] =
4671
            CARILLON_POLICY_TYPE_OID_BASE(12);
4672
    static const byte extCertPolicyCarillonAivhwOid[] =
4673
            CARILLON_POLICY_TYPE_OID_BASE(20);
4674
    static const byte extCertPolicyCarillonAivcontentOid[] =
4675
            CARILLON_POLICY_TYPE_OID_BASE(22);
4676
4677
    /* Carillon Information Security OIDs - 1.3.6.1.4.1.25054.3.1.X */
4678
    #define CIS_POLICY_TYPE_OID_BASE(num) {43, 6, 1, 4, 1, 129, 195, 94, 3, 1, num}
4679
    static const byte extCertPolicyCisMediumhw256Oid[] =
4680
            CIS_POLICY_TYPE_OID_BASE(12);
4681
    static const byte extCertPolicyCisMeddevhw256Oid[] =
4682
            CIS_POLICY_TYPE_OID_BASE(14);
4683
    static const byte extCertPolicyCisIcecapHwOid[] =
4684
            CIS_POLICY_TYPE_OID_BASE(20);
4685
    static const byte extCertPolicyCisIcecapContentOid[] =
4686
            CIS_POLICY_TYPE_OID_BASE(22);
4687
4688
    /* CertiPath Bridge OIDs - 1.3.6.1.4.1.24019.1.1.1.X */
4689
    #define CERTIPATH_POLICY_TYPE_OID_BASE(num) {43, 6, 1, 4, 1, 129, 187, 83, 1, 1, 1, num}
4690
    static const byte extCertPolicyCertipathMediumhwOid[] =
4691
            CERTIPATH_POLICY_TYPE_OID_BASE(2);
4692
    static const byte extCertPolicyCertipathHighhwOid[] =
4693
            CERTIPATH_POLICY_TYPE_OID_BASE(3);
4694
    static const byte extCertPolicyCertipathIcecapHwOid[] =
4695
            CERTIPATH_POLICY_TYPE_OID_BASE(7);
4696
    static const byte extCertPolicyCertipathIcecapContentOid[] =
4697
            CERTIPATH_POLICY_TYPE_OID_BASE(9);
4698
    static const byte extCertPolicyCertipathVarMediumhwOid[] =
4699
            CERTIPATH_POLICY_TYPE_OID_BASE(18);
4700
    static const byte extCertPolicyCertipathVarHighhwOid[] =
4701
            CERTIPATH_POLICY_TYPE_OID_BASE(19);
4702
4703
    /* TSCP Bridge OIDs - 1.3.6.1.4.1.38099.1.1.1.X */
4704
    #define TSCP_POLICY_TYPE_OID_BASE(num) {43, 6, 1, 4, 1, 130, 169, 83, 1, 1, 1, num}
4705
    static const byte extCertPolicyTscpMediumhwOid[] =
4706
            TSCP_POLICY_TYPE_OID_BASE(2);
4707
    static const byte extCertPolicyTscpPiviOid[] =
4708
            TSCP_POLICY_TYPE_OID_BASE(5);
4709
    static const byte extCertPolicyTscpPiviContentOid[] =
4710
            TSCP_POLICY_TYPE_OID_BASE(7);
4711
4712
    /* DigiCert NFI PKI OIDs - 2.16.840.1.113733.1.7.23.3.1.X */
4713
    #define DIGICERT_NFI_POLICY_TYPE_OID_BASE(num) {96, 134, 72, 1, 134, 248, 69, 1, 7, 23, 3, 1, num}
4714
    static const byte extCertPolicyDigicertNfiMediumHardwareOid[] =
4715
            DIGICERT_NFI_POLICY_TYPE_OID_BASE(7);
4716
    static const byte extCertPolicyDigicertNfiAuthOid[] =
4717
            DIGICERT_NFI_POLICY_TYPE_OID_BASE(13);
4718
    static const byte extCertPolicyDigicertNfiPiviHardwareOid[] =
4719
            DIGICERT_NFI_POLICY_TYPE_OID_BASE(18);
4720
    static const byte extCertPolicyDigicertNfiPiviContentSigningOid[] =
4721
            DIGICERT_NFI_POLICY_TYPE_OID_BASE(20);
4722
    static const byte extCertPolicyDigicertNfiMediumDevicesHardwareOid[] =
4723
            DIGICERT_NFI_POLICY_TYPE_OID_BASE(36);
4724
4725
    /* Entrust Managed Services NFI PKI OIDs - 2.16.840.1.114027.200.3.10.7.X */
4726
    #define ENTRUST_NFI_POLICY_TYPE_OID_BASE(num) {96, 134, 72, 1, 134, 250, 107, 129, 72, 3, 10, 7, num}
4727
    static const byte extCertPolicyEntrustNfiMediumHardwareOid[] =
4728
            ENTRUST_NFI_POLICY_TYPE_OID_BASE(2);
4729
    static const byte extCertPolicyEntrustNfiMediumAuthenticationOid[] =
4730
            ENTRUST_NFI_POLICY_TYPE_OID_BASE(4);
4731
    static const byte extCertPolicyEntrustNfiPiviHardwareOid[] =
4732
            ENTRUST_NFI_POLICY_TYPE_OID_BASE(6);
4733
    static const byte extCertPolicyEntrustNfiPiviContentSigningOid[] =
4734
            ENTRUST_NFI_POLICY_TYPE_OID_BASE(9);
4735
    static const byte extCertPolicyEntrustNfiMediumDevicesHwOid[] =
4736
            ENTRUST_NFI_POLICY_TYPE_OID_BASE(16);
4737
4738
    /* Exostar LLC PKI OIDs - 1.3.6.1.4.1.13948.1.1.1.X */
4739
    #define EXOSTAR_POLICY_TYPE_OID_BASE(num) {43, 6, 1, 4, 1, 236, 124, 1, 1, 1, num}
4740
    static const byte extCertPolicyExostarMediumHardwareSha2Oid[] =
4741
            EXOSTAR_POLICY_TYPE_OID_BASE(6);
4742
4743
    /* IdenTrust NFI OIDs - 2.16.840.1.113839.0.100.X.Y */
4744
    #define IDENTRUST_POLICY_TYPE_OID_BASE(num1, num2) {96, 134, 72, 1, 134, 249, 47, 0, 100, num1, num2}
4745
    static const byte extCertPolicyIdentrustMediumhwSignOid[] =
4746
            IDENTRUST_POLICY_TYPE_OID_BASE(12, 1);
4747
    static const byte extCertPolicyIdentrustMediumhwEncOid[] =
4748
            IDENTRUST_POLICY_TYPE_OID_BASE(12, 2);
4749
    static const byte extCertPolicyIdentrustPiviHwIdOid[] =
4750
            IDENTRUST_POLICY_TYPE_OID_BASE(18, 0);
4751
    static const byte extCertPolicyIdentrustPiviHwSignOid[] =
4752
            IDENTRUST_POLICY_TYPE_OID_BASE(18, 1);
4753
    static const byte extCertPolicyIdentrustPiviHwEncOid[] =
4754
            IDENTRUST_POLICY_TYPE_OID_BASE(18, 2);
4755
    static const byte extCertPolicyIdentrustPiviContentOid[] =
4756
            IDENTRUST_POLICY_TYPE_OID_BASE(20, 1);
4757
4758
    /* Lockheed Martin PKI OIDs - 1.3.6.1.4.1.103.100.1.1.3.X */
4759
    #define LOCKHEED_POLICY_TYPE_OID_BASE(num) {43, 6, 1, 4, 1, 103, 100, 1, 1, 3, num}
4760
    static const byte extCertPolicyLockheedMediumAssuranceHardwareOid[] =
4761
            LOCKHEED_POLICY_TYPE_OID_BASE(3);
4762
4763
    /* Northrop Grumman PKI OIDs - 1.3.6.1.4.1.16334.509.2.X */
4764
    #define NORTHROP_POLICY_TYPE_OID_BASE(num) {43, 6, 1, 4, 1, 255, 78, 131, 125, 2, num}
4765
    static const byte extCertPolicyNorthropMediumAssurance256HardwareTokenOid[] =
4766
            NORTHROP_POLICY_TYPE_OID_BASE(8);
4767
    static const byte extCertPolicyNorthropPiviAssurance256HardwareTokenOid[] =
4768
            NORTHROP_POLICY_TYPE_OID_BASE(9);
4769
    static const byte extCertPolicyNorthropPiviAssurance256ContentSigningOid[] =
4770
            NORTHROP_POLICY_TYPE_OID_BASE(11);
4771
    static const byte extCertPolicyNorthropMediumAssurance384HardwareTokenOid[] =
4772
            NORTHROP_POLICY_TYPE_OID_BASE(14);
4773
4774
    /* Raytheon PKI OIDs - 1.3.6.1.4.1.1569.10.1.X and 1.3.6.1.4.1.26769.10.1.X */
4775
    #define RAYTHEON_POLICY_TYPE_OID_BASE(num) {43, 6, 1, 4, 1, 140, 33, 10, 1, num}
4776
    static const byte extCertPolicyRaytheonMediumHardwareOid[] =
4777
            RAYTHEON_POLICY_TYPE_OID_BASE(12);
4778
    static const byte extCertPolicyRaytheonMediumDeviceHardwareOid[] =
4779
            RAYTHEON_POLICY_TYPE_OID_BASE(18);
4780
4781
    #define RAYTHEON_SHA2_POLICY_TYPE_OID_BASE(num) {43, 6, 1, 4, 1, 129, 209, 17, 10, 1, num}
4782
    static const byte extCertPolicyRaytheonSha2MediumHardwareOid[] =
4783
            RAYTHEON_SHA2_POLICY_TYPE_OID_BASE(12);
4784
    static const byte extCertPolicyRaytheonSha2MediumDeviceHardwareOid[] =
4785
            RAYTHEON_SHA2_POLICY_TYPE_OID_BASE(18);
4786
4787
    /* WidePoint NFI PKI OIDs - 1.3.6.1.4.1.3922.1.1.1.X */
4788
    #define WIDEPOINT_NFI_POLICY_TYPE_OID_BASE(num) {43, 6, 1, 4, 1, 158, 82, 1, 1, 1, num}
4789
    static const byte extCertPolicyWidepointNfiMediumHardwareOid[] =
4790
            WIDEPOINT_NFI_POLICY_TYPE_OID_BASE(12);
4791
    static const byte extCertPolicyWidepointNfiPiviHardwareOid[] =
4792
            WIDEPOINT_NFI_POLICY_TYPE_OID_BASE(18);
4793
    static const byte extCertPolicyWidepointNfiPiviContentSigningOid[] =
4794
            WIDEPOINT_NFI_POLICY_TYPE_OID_BASE(20);
4795
    static const byte extCertPolicyWidepointNfiMediumDevicesHardwareOid[] =
4796
            WIDEPOINT_NFI_POLICY_TYPE_OID_BASE(38);
4797
4798
    /* Australian Defence Organisation PKI OIDs - 1.2.36.1.334.1.2.X.X */
4799
    #define ADO_POLICY_TYPE_OID_BASE(type, num) {42, 36, 1, 130, 78, 1, 2, type, num}
4800
    static const byte extCertPolicyAdoIndividualMediumAssuranceOid[] =
4801
            ADO_POLICY_TYPE_OID_BASE(1, 2);
4802
    static const byte extCertPolicyAdoIndividualHighAssuranceOid[] =
4803
            ADO_POLICY_TYPE_OID_BASE(1, 3);
4804
    static const byte extCertPolicyAdoResourceMediumAssuranceOid[] =
4805
            ADO_POLICY_TYPE_OID_BASE(2, 2);
4806
4807
    /* Comodo Ltd PKI OID  1.3.6.1.4.1.6449.1.2.1.3.4 */
4808
    #define COMODO_POLICY_TYPE_OID_BASE(num) {43, 6, 1, 4, 1, 178, 49, 1, 2, 1, 3, num}
4809
    static const byte extCertPolicyComodoLtdOid[] =
4810
            COMODO_POLICY_TYPE_OID_BASE(4);
4811
4812
    /* Netherlands Ministry of Defence PKI OIDs - 2.16.528.1.1003.1.2.5.X */
4813
    #define NL_MOD_POLICY_TYPE_OID_BASE(num) {96, 132, 16, 1, 135, 107, 1, 2, 5, num}
4814
    static const byte extCertPolicyNlModAuthenticityOid[] =
4815
            NL_MOD_POLICY_TYPE_OID_BASE(1);
4816
    static const byte extCertPolicyNlModIrrefutabilityOid[] =
4817
            NL_MOD_POLICY_TYPE_OID_BASE(2);
4818
    static const byte extCertPolicyNlModConfidentialityOid[] =
4819
            NL_MOD_POLICY_TYPE_OID_BASE(3);
4820
#endif /* WOLFSSL_FPKI */
4821
4822
/* certAltNameType */
4823
static const byte extAltNamesHwNameOid[] = {43, 6, 1, 5, 5, 7, 8, 4};
4824
4825
/* certKeyUseType */
4826
static const byte extExtKeyUsageAnyOid[] = {85, 29, 37, 0};
4827
static const byte extExtKeyUsageServerAuthOid[]   = {43, 6, 1, 5, 5, 7, 3, 1};
4828
static const byte extExtKeyUsageClientAuthOid[]   = {43, 6, 1, 5, 5, 7, 3, 2};
4829
static const byte extExtKeyUsageCodeSigningOid[]  = {43, 6, 1, 5, 5, 7, 3, 3};
4830
static const byte extExtKeyUsageEmailProtectOid[] = {43, 6, 1, 5, 5, 7, 3, 4};
4831
static const byte extExtKeyUsageTimestampOid[]    = {43, 6, 1, 5, 5, 7, 3, 8};
4832
static const byte extExtKeyUsageOcspSignOid[]     = {43, 6, 1, 5, 5, 7, 3, 9};
4833
#ifdef WOLFSSL_WOLFSSH
4834
#define EXT_KEY_USAGE_OID_BASE(num) {43, 6, 1, 5, 5, 7, 3, num}
4835
    static const byte extExtKeyUsageSshClientAuthOid[] =
4836
            EXT_KEY_USAGE_OID_BASE(21);
4837
    static const byte extExtKeyUsageSshMSCLOid[] =
4838
            {43, 6, 1, 4, 1, 130, 55, 20, 2, 2};
4839
    static const byte extExtKeyUsageSshKpClientAuthOid[] =
4840
            {43, 6, 1, 5, 2, 3, 4};
4841
#endif /* WOLFSSL_WOLFSSH */
4842
4843
#ifdef WOLFSSL_SUBJ_DIR_ATTR
4844
#define SUBJ_DIR_ATTR_TYPE_OID_BASE(num) {43, 6, 1, 5, 5, 7, 9, num}
4845
    static const byte extSubjDirAttrDobOid[] = SUBJ_DIR_ATTR_TYPE_OID_BASE(1);
4846
    static const byte extSubjDirAttrPobOid[] = SUBJ_DIR_ATTR_TYPE_OID_BASE(2);
4847
    static const byte extSubjDirAttrGenderOid[] =
4848
            SUBJ_DIR_ATTR_TYPE_OID_BASE(3);
4849
    static const byte extSubjDirAttrCocOid[] = SUBJ_DIR_ATTR_TYPE_OID_BASE(4);
4850
    static const byte extSubjDirAttrCorOid[] = SUBJ_DIR_ATTR_TYPE_OID_BASE(5);
4851
#endif
4852
4853
#if defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_GEN) || \
4854
    defined(WOLFSSL_ASN_TEMPLATE) || defined(OPENSSL_EXTRA) || \
4855
    defined(OPENSSL_EXTRA_X509_SMALL)
4856
/* csrAttrType */
4857
#define CSR_ATTR_TYPE_OID_BASE(num) {42, 134, 72, 134, 247, 13, 1, 9, num}
4858
#if !defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_GEN) || \
4859
    defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
4860
    defined(WOLFSSL_ASN_TEMPLATE)
4861
static const byte attrEmailOid[] =             CSR_ATTR_TYPE_OID_BASE(1);
4862
#endif
4863
#ifdef WOLFSSL_CERT_REQ
4864
static const byte attrUnstructuredNameOid[] =  CSR_ATTR_TYPE_OID_BASE(2);
4865
static const byte attrPkcs9ContentTypeOid[] =  CSR_ATTR_TYPE_OID_BASE(3);
4866
static const byte attrChallengePasswordOid[] = CSR_ATTR_TYPE_OID_BASE(7);
4867
static const byte attrExtensionRequestOid[] =  CSR_ATTR_TYPE_OID_BASE(14);
4868
static const byte attrSerialNumberOid[] = {85, 4, 5};
4869
static const byte attrDnQualifier[] = {85, 4, 46};
4870
static const byte attrInitals[] = {85, 4, 43};
4871
static const byte attrSurname[] = {85, 4, 4};
4872
static const byte attrGivenName[] = {85, 4, 42};
4873
#endif
4874
#endif
4875
4876
/* kdfType */
4877
static const byte pbkdf2Oid[] = {42, 134, 72, 134, 247, 13, 1, 5, 12};
4878
4879
/* PKCS5 */
4880
#if !defined(NO_DES3) && !defined(NO_MD5)
4881
static const byte pbeMd5Des[] = {42, 134, 72, 134, 247, 13, 1, 5, 3};
4882
#endif
4883
#if !defined(NO_DES3) && !defined(NO_SHA)
4884
static const byte pbeSha1Des[] = {42, 134, 72, 134, 247, 13, 1, 5, 10};
4885
#endif
4886
static const byte pbes2[] = {42, 134, 72, 134, 247, 13, 1, 5, 13};
4887
4888
/* PKCS12 */
4889
#if !defined(NO_RC4) && !defined(NO_SHA)
4890
static const byte pbeSha1RC4128[] = {42, 134, 72, 134, 247, 13, 1, 12, 1, 1};
4891
#endif
4892
#if !defined(NO_DES3) && !defined(NO_SHA)
4893
static const byte pbeSha1Des3[] = {42, 134, 72, 134, 247, 13, 1, 12, 1, 3};
4894
#endif
4895
#if defined(WC_RC2) && !defined(NO_SHA)
4896
static const byte pbe40Rc2Cbc[] = {42, 134, 72, 134, 247, 13, 1, 12, 1, 6};
4897
#endif
4898
4899
#ifdef HAVE_LIBZ
4900
/* zlib compression */
4901
static const byte zlibCompress[] = {42, 134, 72, 134, 247, 13, 1, 9, 16, 3, 8};
4902
#endif
4903
#ifdef WOLFSSL_APACHE_HTTPD
4904
/* tlsExtType */
4905
static const byte tlsFeatureOid[] = {43, 6, 1, 5, 5, 7, 1, 24};
4906
/* certNameType */
4907
static const byte dnsSRVOid[] = {43, 6, 1, 5, 5, 7, 8, 7};
4908
#endif
4909
4910
#if defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_GEN) || \
4911
    defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
4912
    defined(WOLFSSL_ASN_TEMPLATE)
4913
/* Pilot attribute types (0.9.2342.19200300.100.1.*) */
4914
#define PLT_ATTR_TYPE_OID_BASE(num) {9, 146, 38, 137, 147, 242, 44, 100, 1, num}
4915
static const byte uidOid[] = PLT_ATTR_TYPE_OID_BASE(1); /* user id */
4916
static const byte rfc822Mlbx[] = PLT_ATTR_TYPE_OID_BASE(3); /* RFC822 mailbox */
4917
static const byte fvrtDrk[] = PLT_ATTR_TYPE_OID_BASE(5);/* favourite drink*/
4918
#endif
4919
4920
#if defined(WOLFSSL_CERT_GEN) || \
4921
    defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
4922
    defined(WOLFSSL_ASN_TEMPLATE)
4923
static const byte dcOid[] = {9, 146, 38, 137, 147, 242, 44, 100, 1, 25}; /* domain component */
4924
#endif
4925
4926
4927
/* Looks up the ID/type of an OID.
4928
 *
4929
 * When known returns the OID as a byte array and its length.
4930
 * ID-type are unique.
4931
 *
4932
 * Use oidIgnoreType to autofail.
4933
 *
4934
 * Note that while this function currently handles a large
4935
 * number of FPKI certificate policy OIDs, these OIDs are not
4936
 * currently being handled in the code, they are just recognized
4937
 * as valid OIDs.
4938
 *
4939
 * @param [in]  id     OID id.
4940
 * @param [in]  type   Type of OID (enum Oid_Types).
4941
 * @param [out] oidSz  Length of OID byte array returned.
4942
 * @return  Array of bytes for the OID.
4943
 * @return  NULL when ID/type not recognized.
4944
 */
4945
const byte* OidFromId(word32 id, word32 type, word32* oidSz)
4946
0
{
4947
0
    const byte* oid = NULL;
4948
4949
0
    *oidSz = 0;
4950
4951
0
    switch (type) {
4952
4953
0
        case oidHashType:
4954
0
            switch (id) {
4955
            #ifdef WOLFSSL_MD2
4956
                case MD2h:
4957
                    oid = hashMd2hOid;
4958
                    *oidSz = sizeof(hashMd2hOid);
4959
                    break;
4960
            #endif
4961
            #ifndef NO_MD5
4962
                case MD5h:
4963
                    oid = hashMd5hOid;
4964
                    *oidSz = sizeof(hashMd5hOid);
4965
                    break;
4966
            #endif
4967
0
            #ifndef NO_SHA
4968
0
                case SHAh:
4969
0
                    oid = hashSha1hOid;
4970
0
                    *oidSz = sizeof(hashSha1hOid);
4971
0
                    break;
4972
0
            #endif
4973
0
            #ifdef WOLFSSL_SHA224
4974
0
                case SHA224h:
4975
0
                    oid = hashSha224hOid;
4976
0
                    *oidSz = sizeof(hashSha224hOid);
4977
0
                    break;
4978
0
            #endif
4979
0
            #ifndef NO_SHA256
4980
0
                case SHA256h:
4981
0
                    oid = hashSha256hOid;
4982
0
                    *oidSz = sizeof(hashSha256hOid);
4983
0
                    break;
4984
0
            #endif
4985
0
            #ifdef WOLFSSL_SHA384
4986
0
                case SHA384h:
4987
0
                    oid = hashSha384hOid;
4988
0
                    *oidSz = sizeof(hashSha384hOid);
4989
0
                    break;
4990
0
            #endif
4991
0
            #ifdef WOLFSSL_SHA512
4992
0
                #ifndef WOLFSSL_NOSHA512_224
4993
0
                case SHA512_224h:
4994
0
                    oid = hashSha512_224hOid;
4995
0
                    *oidSz = sizeof(hashSha512_224hOid);
4996
0
                    break;
4997
0
                #endif
4998
0
                #ifndef WOLFSSL_NOSHA512_256
4999
0
                case SHA512_256h:
5000
0
                    oid = hashSha512_256hOid;
5001
0
                    *oidSz = sizeof(hashSha512_256hOid);
5002
0
                    break;
5003
0
                #endif
5004
0
                case SHA512h:
5005
0
                    oid = hashSha512hOid;
5006
0
                    *oidSz = sizeof(hashSha512hOid);
5007
0
                    break;
5008
0
            #endif
5009
0
            #ifdef WOLFSSL_SHA3
5010
0
            #ifndef WOLFSSL_NOSHA3_224
5011
0
                case SHA3_224h:
5012
0
                    oid = hashSha3_224hOid;
5013
0
                    *oidSz = sizeof(hashSha3_224hOid);
5014
0
                    break;
5015
0
            #endif /* WOLFSSL_NOSHA3_224 */
5016
0
            #ifndef WOLFSSL_NOSHA3_256
5017
0
                case SHA3_256h:
5018
0
                    oid = hashSha3_256hOid;
5019
0
                    *oidSz = sizeof(hashSha3_256hOid);
5020
0
                    break;
5021
0
            #endif /* WOLFSSL_NOSHA3_256 */
5022
0
            #ifndef WOLFSSL_NOSHA3_384
5023
0
                case SHA3_384h:
5024
0
                    oid = hashSha3_384hOid;
5025
0
                    *oidSz = sizeof(hashSha3_384hOid);
5026
0
                    break;
5027
0
            #endif /* WOLFSSL_NOSHA3_384 */
5028
0
            #ifndef WOLFSSL_NOSHA3_512
5029
0
                case SHA3_512h:
5030
0
                    oid = hashSha3_512hOid;
5031
0
                    *oidSz = sizeof(hashSha3_512hOid);
5032
0
                    break;
5033
0
            #endif /* WOLFSSL_NOSHA3_512 */
5034
0
            #endif /* WOLFSSL_SHA3 */
5035
0
                default:
5036
0
                    break;
5037
0
            }
5038
0
            break;
5039
5040
0
        case oidSigType:
5041
0
            switch (id) {
5042
                #if !defined(NO_DSA) && !defined(NO_SHA)
5043
                case CTC_SHAwDSA:
5044
                    oid = sigSha1wDsaOid;
5045
                    *oidSz = sizeof(sigSha1wDsaOid);
5046
                    break;
5047
                case CTC_SHA256wDSA:
5048
                    oid = sigSha256wDsaOid;
5049
                    *oidSz = sizeof(sigSha256wDsaOid);
5050
                    break;
5051
                #endif /* NO_DSA */
5052
0
                #ifndef NO_RSA
5053
                #ifdef WOLFSSL_MD2
5054
                case CTC_MD2wRSA:
5055
                    oid = sigMd2wRsaOid;
5056
                    *oidSz = sizeof(sigMd2wRsaOid);
5057
                    break;
5058
                #endif
5059
                #ifndef NO_MD5
5060
                case CTC_MD5wRSA:
5061
                    oid = sigMd5wRsaOid;
5062
                    *oidSz = sizeof(sigMd5wRsaOid);
5063
                    break;
5064
                #endif
5065
0
                #ifndef NO_SHA
5066
0
                case CTC_SHAwRSA:
5067
0
                    oid = sigSha1wRsaOid;
5068
0
                    *oidSz = sizeof(sigSha1wRsaOid);
5069
0
                    break;
5070
0
                #endif
5071
0
                #ifdef WOLFSSL_SHA224
5072
0
                case CTC_SHA224wRSA:
5073
0
                    oid = sigSha224wRsaOid;
5074
0
                    *oidSz = sizeof(sigSha224wRsaOid);
5075
0
                    break;
5076
0
                #endif
5077
0
                #ifndef NO_SHA256
5078
0
                case CTC_SHA256wRSA:
5079
0
                    oid = sigSha256wRsaOid;
5080
0
                    *oidSz = sizeof(sigSha256wRsaOid);
5081
0
                    break;
5082
0
                #endif
5083
0
                #ifdef WOLFSSL_SHA384
5084
0
                case CTC_SHA384wRSA:
5085
0
                    oid = sigSha384wRsaOid;
5086
0
                    *oidSz = sizeof(sigSha384wRsaOid);
5087
0
                    break;
5088
0
                #endif
5089
0
                #ifdef WOLFSSL_SHA512
5090
0
                case CTC_SHA512wRSA:
5091
0
                    oid = sigSha512wRsaOid;
5092
0
                    *oidSz = sizeof(sigSha512wRsaOid);
5093
0
                    break;
5094
0
                #endif /* WOLFSSL_SHA512 */
5095
0
                #ifdef WOLFSSL_SHA3
5096
0
                #ifndef WOLFSSL_NOSHA3_224
5097
0
                case CTC_SHA3_224wRSA:
5098
0
                    oid = sigSha3_224wRsaOid;
5099
0
                    *oidSz = sizeof(sigSha3_224wRsaOid);
5100
0
                    break;
5101
0
                #endif
5102
0
                #ifndef WOLFSSL_NOSHA3_256
5103
0
                case CTC_SHA3_256wRSA:
5104
0
                    oid = sigSha3_256wRsaOid;
5105
0
                    *oidSz = sizeof(sigSha3_256wRsaOid);
5106
0
                    break;
5107
0
                #endif
5108
0
                #ifndef WOLFSSL_NOSHA3_384
5109
0
                case CTC_SHA3_384wRSA:
5110
0
                    oid = sigSha3_384wRsaOid;
5111
0
                    *oidSz = sizeof(sigSha3_384wRsaOid);
5112
0
                    break;
5113
0
                #endif
5114
0
                #ifndef WOLFSSL_NOSHA3_512
5115
0
                case CTC_SHA3_512wRSA:
5116
0
                    oid = sigSha3_512wRsaOid;
5117
0
                    *oidSz = sizeof(sigSha3_512wRsaOid);
5118
0
                    break;
5119
0
                #endif
5120
0
                #endif
5121
0
                #ifdef WC_RSA_PSS
5122
0
                case CTC_RSASSAPSS:
5123
0
                    oid = sigRsaSsaPssOid;
5124
0
                    *oidSz = sizeof(sigRsaSsaPssOid);
5125
0
                    break;
5126
0
                #endif
5127
0
                #endif /* NO_RSA */
5128
0
                #ifdef HAVE_ECC
5129
0
                #ifndef NO_SHA
5130
0
                case CTC_SHAwECDSA:
5131
0
                    oid = sigSha1wEcdsaOid;
5132
0
                    *oidSz = sizeof(sigSha1wEcdsaOid);
5133
0
                    break;
5134
0
                #endif
5135
0
                #ifdef WOLFSSL_SHA224
5136
0
                case CTC_SHA224wECDSA:
5137
0
                    oid = sigSha224wEcdsaOid;
5138
0
                    *oidSz = sizeof(sigSha224wEcdsaOid);
5139
0
                    break;
5140
0
                #endif
5141
0
                #ifndef NO_SHA256
5142
0
                case CTC_SHA256wECDSA:
5143
0
                    oid = sigSha256wEcdsaOid;
5144
0
                    *oidSz = sizeof(sigSha256wEcdsaOid);
5145
0
                    break;
5146
0
                #endif
5147
0
                #ifdef WOLFSSL_SHA384
5148
0
                case CTC_SHA384wECDSA:
5149
0
                    oid = sigSha384wEcdsaOid;
5150
0
                    *oidSz = sizeof(sigSha384wEcdsaOid);
5151
0
                    break;
5152
0
                #endif
5153
0
                #ifdef WOLFSSL_SHA512
5154
0
                case CTC_SHA512wECDSA:
5155
0
                    oid = sigSha512wEcdsaOid;
5156
0
                    *oidSz = sizeof(sigSha512wEcdsaOid);
5157
0
                    break;
5158
0
                #endif
5159
0
                #ifdef WOLFSSL_SHA3
5160
0
                #ifndef WOLFSSL_NOSHA3_224
5161
0
                case CTC_SHA3_224wECDSA:
5162
0
                    oid = sigSha3_224wEcdsaOid;
5163
0
                    *oidSz = sizeof(sigSha3_224wEcdsaOid);
5164
0
                    break;
5165
0
                #endif
5166
0
                #ifndef WOLFSSL_NOSHA3_256
5167
0
                case CTC_SHA3_256wECDSA:
5168
0
                    oid = sigSha3_256wEcdsaOid;
5169
0
                    *oidSz = sizeof(sigSha3_256wEcdsaOid);
5170
0
                    break;
5171
0
                #endif
5172
0
                #ifndef WOLFSSL_NOSHA3_384
5173
0
                case CTC_SHA3_384wECDSA:
5174
0
                    oid = sigSha3_384wEcdsaOid;
5175
0
                    *oidSz = sizeof(sigSha3_384wEcdsaOid);
5176
0
                    break;
5177
0
                #endif
5178
0
                #ifndef WOLFSSL_NOSHA3_512
5179
0
                case CTC_SHA3_512wECDSA:
5180
0
                    oid = sigSha3_512wEcdsaOid;
5181
0
                    *oidSz = sizeof(sigSha3_512wEcdsaOid);
5182
0
                    break;
5183
0
                #endif
5184
0
                #endif
5185
                #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
5186
                case CTC_SM3wSM2:
5187
                    oid = sigSm3wSm2Oid;
5188
                    *oidSz = sizeof(sigSm3wSm2Oid);
5189
                    break;
5190
                #endif
5191
0
                #endif /* HAVE_ECC */
5192
                #ifdef HAVE_ED25519
5193
                case CTC_ED25519:
5194
                    oid = sigEd25519Oid;
5195
                    *oidSz = sizeof(sigEd25519Oid);
5196
                    break;
5197
                #endif
5198
                #ifdef HAVE_ED448
5199
                case CTC_ED448:
5200
                    oid = sigEd448Oid;
5201
                    *oidSz = sizeof(sigEd448Oid);
5202
                    break;
5203
                #endif
5204
                #ifdef HAVE_FALCON
5205
                case CTC_FALCON_LEVEL1:
5206
                    oid = sigFalcon_Level1Oid;
5207
                    *oidSz = sizeof(sigFalcon_Level1Oid);
5208
                    break;
5209
                case CTC_FALCON_LEVEL5:
5210
                    oid = sigFalcon_Level5Oid;
5211
                    *oidSz = sizeof(sigFalcon_Level5Oid);
5212
                    break;
5213
                #endif /* HAVE_FALCON */
5214
            #ifdef HAVE_DILITHIUM
5215
                #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
5216
                case CTC_DILITHIUM_LEVEL2:
5217
                    oid = sigDilithium_Level2Oid;
5218
                    *oidSz = sizeof(sigDilithium_Level2Oid);
5219
                    break;
5220
                case CTC_DILITHIUM_LEVEL3:
5221
                    oid = sigDilithium_Level3Oid;
5222
                    *oidSz = sizeof(sigDilithium_Level3Oid);
5223
                    break;
5224
                case CTC_DILITHIUM_LEVEL5:
5225
                    oid = sigDilithium_Level5Oid;
5226
                    *oidSz = sizeof(sigDilithium_Level5Oid);
5227
                    break;
5228
                #endif
5229
                case CTC_ML_DSA_LEVEL2:
5230
                    oid = sigMlDsa_Level2Oid;
5231
                    *oidSz = sizeof(sigMlDsa_Level2Oid);
5232
                    break;
5233
                case CTC_ML_DSA_LEVEL3:
5234
                    oid = sigMlDsa_Level3Oid;
5235
                    *oidSz = sizeof(sigMlDsa_Level3Oid);
5236
                    break;
5237
                case CTC_ML_DSA_LEVEL5:
5238
                    oid = sigMlDsa_Level5Oid;
5239
                    *oidSz = sizeof(sigMlDsa_Level5Oid);
5240
                    break;
5241
            #endif /* HAVE_DILITHIUM */
5242
                #ifdef HAVE_SPHINCS
5243
                case CTC_SPHINCS_FAST_LEVEL1:
5244
                    oid = sigSphincsFast_Level1Oid;
5245
                    *oidSz = sizeof(sigSphincsFast_Level1Oid);
5246
                    break;
5247
                case CTC_SPHINCS_FAST_LEVEL3:
5248
                    oid = sigSphincsFast_Level3Oid;
5249
                    *oidSz = sizeof(sigSphincsFast_Level3Oid);
5250
                    break;
5251
                case CTC_SPHINCS_FAST_LEVEL5:
5252
                    oid = sigSphincsFast_Level5Oid;
5253
                    *oidSz = sizeof(sigSphincsFast_Level5Oid);
5254
                    break;
5255
                case CTC_SPHINCS_SMALL_LEVEL1:
5256
                    oid = sigSphincsSmall_Level1Oid;
5257
                    *oidSz = sizeof(sigSphincsSmall_Level1Oid);
5258
                    break;
5259
                case CTC_SPHINCS_SMALL_LEVEL3:
5260
                    oid = sigSphincsSmall_Level3Oid;
5261
                    *oidSz = sizeof(sigSphincsSmall_Level3Oid);
5262
                    break;
5263
                case CTC_SPHINCS_SMALL_LEVEL5:
5264
                    oid = sigSphincsSmall_Level5Oid;
5265
                    *oidSz = sizeof(sigSphincsSmall_Level5Oid);
5266
                    break;
5267
                #endif /* HAVE_SPHINCS */
5268
0
                default:
5269
0
                    break;
5270
0
            }
5271
0
            break;
5272
5273
0
        case oidKeyType:
5274
0
            switch (id) {
5275
                #ifndef NO_DSA
5276
                case DSAk:
5277
                    oid = keyDsaOid;
5278
                    *oidSz = sizeof(keyDsaOid);
5279
                    break;
5280
                #endif /* NO_DSA */
5281
0
            #ifndef NO_RSA
5282
0
                case RSAk:
5283
0
                    oid = keyRsaOid;
5284
0
                    *oidSz = sizeof(keyRsaOid);
5285
0
                    break;
5286
0
                #ifdef WC_RSA_PSS
5287
0
                case RSAPSSk:
5288
0
                    oid = keyRsaPssOid;
5289
0
                    *oidSz = sizeof(keyRsaPssOid);
5290
0
                    break;
5291
0
                #endif
5292
0
            #endif /* NO_RSA */
5293
0
                #ifdef HAVE_ECC
5294
0
                case ECDSAk:
5295
0
                    oid = keyEcdsaOid;
5296
0
                    *oidSz = sizeof(keyEcdsaOid);
5297
0
                    break;
5298
0
                #endif /* HAVE_ECC */
5299
                #ifdef HAVE_ED25519
5300
                case ED25519k:
5301
                    oid = keyEd25519Oid;
5302
                    *oidSz = sizeof(keyEd25519Oid);
5303
                    break;
5304
                #endif /* HAVE_ED25519 */
5305
                #ifdef HAVE_CURVE25519
5306
                case X25519k:
5307
                    oid = keyCurve25519Oid;
5308
                    *oidSz = sizeof(keyCurve25519Oid);
5309
                    break;
5310
                #endif /* HAVE_CURVE25519 */
5311
                #ifdef HAVE_ED448
5312
                case ED448k:
5313
                    oid = keyEd448Oid;
5314
                    *oidSz = sizeof(keyEd448Oid);
5315
                    break;
5316
                #endif /* HAVE_ED448 */
5317
                #ifdef HAVE_CURVE448
5318
                case X448k:
5319
                    oid = keyCurve448Oid;
5320
                    *oidSz = sizeof(keyCurve448Oid);
5321
                    break;
5322
                #endif /* HAVE_CURVE448 */
5323
0
                #ifndef NO_DH
5324
0
                case DHk:
5325
0
                    oid = keyDhOid;
5326
0
                    *oidSz = sizeof(keyDhOid);
5327
0
                    break;
5328
0
                #endif /* !NO_DH */
5329
                #ifdef HAVE_FALCON
5330
                case FALCON_LEVEL1k:
5331
                    oid = keyFalcon_Level1Oid;
5332
                    *oidSz = sizeof(keyFalcon_Level1Oid);
5333
                    break;
5334
                case FALCON_LEVEL5k:
5335
                    oid = keyFalcon_Level5Oid;
5336
                    *oidSz = sizeof(keyFalcon_Level5Oid);
5337
                    break;
5338
                #endif /* HAVE_FALCON */
5339
            #ifdef HAVE_DILITHIUM
5340
                #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
5341
                case DILITHIUM_LEVEL2k:
5342
                    oid = keyDilithium_Level2Oid;
5343
                    *oidSz = sizeof(keyDilithium_Level2Oid);
5344
                    break;
5345
                case DILITHIUM_LEVEL3k:
5346
                    oid = keyDilithium_Level3Oid;
5347
                    *oidSz = sizeof(keyDilithium_Level3Oid);
5348
                    break;
5349
                case DILITHIUM_LEVEL5k:
5350
                    oid = keyDilithium_Level5Oid;
5351
                    *oidSz = sizeof(keyDilithium_Level5Oid);
5352
                    break;
5353
                #endif
5354
                case ML_DSA_LEVEL2k:
5355
                    oid = keyMlDsa_Level2Oid;
5356
                    *oidSz = sizeof(keyMlDsa_Level2Oid);
5357
                    break;
5358
                case ML_DSA_LEVEL3k:
5359
                    oid = keyMlDsa_Level3Oid;
5360
                    *oidSz = sizeof(keyMlDsa_Level3Oid);
5361
                    break;
5362
                case ML_DSA_LEVEL5k:
5363
                    oid = keyMlDsa_Level5Oid;
5364
                    *oidSz = sizeof(keyMlDsa_Level5Oid);
5365
                    break;
5366
            #endif /* HAVE_DILITHIUM */
5367
                #ifdef HAVE_SPHINCS
5368
                case SPHINCS_FAST_LEVEL1k:
5369
                    oid = keySphincsFast_Level1Oid;
5370
                    *oidSz = sizeof(keySphincsFast_Level1Oid);
5371
                    break;
5372
                case SPHINCS_FAST_LEVEL3k:
5373
                    oid = keySphincsFast_Level3Oid;
5374
                    *oidSz = sizeof(keySphincsFast_Level3Oid);
5375
                    break;
5376
                case SPHINCS_FAST_LEVEL5k:
5377
                    oid = keySphincsFast_Level5Oid;
5378
                    *oidSz = sizeof(keySphincsFast_Level5Oid);
5379
                    break;
5380
                case SPHINCS_SMALL_LEVEL1k:
5381
                    oid = keySphincsSmall_Level1Oid;
5382
                    *oidSz = sizeof(keySphincsSmall_Level1Oid);
5383
                    break;
5384
                case SPHINCS_SMALL_LEVEL3k:
5385
                    oid = keySphincsSmall_Level3Oid;
5386
                    *oidSz = sizeof(keySphincsSmall_Level3Oid);
5387
                    break;
5388
                case SPHINCS_SMALL_LEVEL5k:
5389
                    oid = keySphincsSmall_Level5Oid;
5390
                    *oidSz = sizeof(keySphincsSmall_Level5Oid);
5391
                    break;
5392
                #endif /* HAVE_SPHINCS */
5393
0
                default:
5394
0
                    break;
5395
0
            }
5396
0
            break;
5397
5398
0
        #ifdef HAVE_ECC
5399
0
        case oidCurveType:
5400
0
            if (wc_ecc_get_oid(id, &oid, oidSz) < 0) {
5401
0
                WOLFSSL_MSG("ECC OID not found");
5402
0
            }
5403
0
            break;
5404
0
        #endif /* HAVE_ECC */
5405
5406
0
        case oidBlkType:
5407
0
            switch (id) {
5408
0
    #ifdef HAVE_AES_CBC
5409
0
        #ifdef WOLFSSL_AES_128
5410
0
                case AES128CBCb:
5411
0
                    oid = blkAes128CbcOid;
5412
0
                    *oidSz = sizeof(blkAes128CbcOid);
5413
0
                    break;
5414
0
        #endif
5415
0
        #ifdef WOLFSSL_AES_192
5416
0
                case AES192CBCb:
5417
0
                    oid = blkAes192CbcOid;
5418
0
                    *oidSz = sizeof(blkAes192CbcOid);
5419
0
                    break;
5420
0
        #endif
5421
0
        #ifdef WOLFSSL_AES_256
5422
0
                case AES256CBCb:
5423
0
                    oid = blkAes256CbcOid;
5424
0
                    *oidSz = sizeof(blkAes256CbcOid);
5425
0
                    break;
5426
0
        #endif
5427
0
    #endif /* HAVE_AES_CBC */
5428
0
    #ifdef HAVE_AESGCM
5429
0
        #ifdef WOLFSSL_AES_128
5430
0
                case AES128GCMb:
5431
0
                    oid = blkAes128GcmOid;
5432
0
                    *oidSz = sizeof(blkAes128GcmOid);
5433
0
                    break;
5434
0
        #endif
5435
0
        #ifdef WOLFSSL_AES_192
5436
0
                case AES192GCMb:
5437
0
                    oid = blkAes192GcmOid;
5438
0
                    *oidSz = sizeof(blkAes192GcmOid);
5439
0
                    break;
5440
0
        #endif
5441
0
        #ifdef WOLFSSL_AES_256
5442
0
                case AES256GCMb:
5443
0
                    oid = blkAes256GcmOid;
5444
0
                    *oidSz = sizeof(blkAes256GcmOid);
5445
0
                    break;
5446
0
        #endif
5447
0
    #endif /* HAVE_AESGCM */
5448
    #ifdef HAVE_AESCCM
5449
        #ifdef WOLFSSL_AES_128
5450
                case AES128CCMb:
5451
                    oid = blkAes128CcmOid;
5452
                    *oidSz = sizeof(blkAes128CcmOid);
5453
                    break;
5454
        #endif
5455
        #ifdef WOLFSSL_AES_192
5456
                case AES192CCMb:
5457
                    oid = blkAes192CcmOid;
5458
                    *oidSz = sizeof(blkAes192CcmOid);
5459
                    break;
5460
        #endif
5461
        #ifdef WOLFSSL_AES_256
5462
                case AES256CCMb:
5463
                    oid = blkAes256CcmOid;
5464
                    *oidSz = sizeof(blkAes256CcmOid);
5465
                    break;
5466
        #endif
5467
    #endif /* HAVE_AESCCM */
5468
    #ifndef NO_DES3
5469
                case DESb:
5470
                    oid = blkDesCbcOid;
5471
                    *oidSz = sizeof(blkDesCbcOid);
5472
                    break;
5473
                case DES3b:
5474
                    oid = blkDes3CbcOid;
5475
                    *oidSz = sizeof(blkDes3CbcOid);
5476
                    break;
5477
    #endif /* !NO_DES3 */
5478
0
                default:
5479
0
                    break;
5480
0
            }
5481
0
            break;
5482
5483
        #ifdef HAVE_OCSP
5484
        case oidOcspType:
5485
            switch (id) {
5486
                case OCSP_BASIC_OID:
5487
                    oid = ocspBasicOid;
5488
                    *oidSz = sizeof(ocspBasicOid);
5489
                    break;
5490
                case OCSP_NONCE_OID:
5491
                    oid = ocspNonceOid;
5492
                    *oidSz = sizeof(ocspNonceOid);
5493
                    break;
5494
                default:
5495
                    break;
5496
            }
5497
            break;
5498
        #endif /* HAVE_OCSP */
5499
5500
0
        case oidCertExtType:
5501
0
            switch (id) {
5502
0
                case BASIC_CA_OID:
5503
0
                    oid = extBasicCaOid;
5504
0
                    *oidSz = sizeof(extBasicCaOid);
5505
0
                    break;
5506
0
                case ALT_NAMES_OID:
5507
0
                    oid = extAltNamesOid;
5508
0
                    *oidSz = sizeof(extAltNamesOid);
5509
0
                    break;
5510
0
                case CRL_DIST_OID:
5511
0
                    oid = extCrlDistOid;
5512
0
                    *oidSz = sizeof(extCrlDistOid);
5513
0
                    break;
5514
0
                case AUTH_INFO_OID:
5515
0
                    oid = extAuthInfoOid;
5516
0
                    *oidSz = sizeof(extAuthInfoOid);
5517
0
                    break;
5518
0
                case AUTH_KEY_OID:
5519
0
                    oid = extAuthKeyOid;
5520
0
                    *oidSz = sizeof(extAuthKeyOid);
5521
0
                    break;
5522
0
                case SUBJ_KEY_OID:
5523
0
                    oid = extSubjKeyOid;
5524
0
                    *oidSz = sizeof(extSubjKeyOid);
5525
0
                    break;
5526
0
                case CERT_POLICY_OID:
5527
0
                    oid = extCertPolicyOid;
5528
0
                    *oidSz = sizeof(extCertPolicyOid);
5529
0
                    break;
5530
0
                case KEY_USAGE_OID:
5531
0
                    oid = extKeyUsageOid;
5532
0
                    *oidSz = sizeof(extKeyUsageOid);
5533
0
                    break;
5534
0
                case INHIBIT_ANY_OID:
5535
0
                    oid = extInhibitAnyOid;
5536
0
                    *oidSz = sizeof(extInhibitAnyOid);
5537
0
                    break;
5538
0
                case EXT_KEY_USAGE_OID:
5539
0
                    oid = extExtKeyUsageOid;
5540
0
                    *oidSz = sizeof(extExtKeyUsageOid);
5541
0
                    break;
5542
0
            #ifndef IGNORE_NAME_CONSTRAINTS
5543
0
                case NAME_CONS_OID:
5544
0
                    oid = extNameConsOid;
5545
0
                    *oidSz = sizeof(extNameConsOid);
5546
0
                    break;
5547
0
            #endif
5548
            #ifdef HAVE_OCSP
5549
                case OCSP_NOCHECK_OID:
5550
                    oid = ocspNoCheckOid;
5551
                    *oidSz = sizeof(ocspNoCheckOid);
5552
                    break;
5553
            #endif
5554
            #ifdef WOLFSSL_SUBJ_DIR_ATTR
5555
                case SUBJ_DIR_ATTR_OID:
5556
                    oid = extSubjDirAttrOid;
5557
                    *oidSz = sizeof(extSubjDirAttrOid);
5558
                    break;
5559
            #endif
5560
            #ifdef WOLFSSL_SUBJ_INFO_ACC
5561
                case SUBJ_INFO_ACC_OID:
5562
                    oid = extSubjInfoAccessOid;
5563
                    *oidSz = sizeof(extSubjInfoAccessOid);
5564
                    break;
5565
            #endif
5566
0
                default:
5567
0
                    break;
5568
0
            }
5569
0
            break;
5570
5571
0
        case oidCrlExtType:
5572
            #ifdef HAVE_CRL
5573
            switch (id) {
5574
                case AUTH_KEY_OID:
5575
                    oid = extAuthKeyOid;
5576
                    *oidSz = sizeof(extAuthKeyOid);
5577
                    break;
5578
                case CRL_NUMBER_OID:
5579
                    oid = extCrlNumberOid;
5580
                    *oidSz = sizeof(extCrlNumberOid);
5581
                    break;
5582
                default:
5583
                    break;
5584
            }
5585
            #endif
5586
0
            break;
5587
5588
0
        case oidCertAuthInfoType:
5589
0
            switch (id) {
5590
0
                case AIA_OCSP_OID:
5591
0
                    oid = extAuthInfoOcspOid;
5592
0
                    *oidSz = sizeof(extAuthInfoOcspOid);
5593
0
                    break;
5594
0
                case AIA_CA_ISSUER_OID:
5595
0
                    oid = extAuthInfoCaIssuerOid;
5596
0
                    *oidSz = sizeof(extAuthInfoCaIssuerOid);
5597
0
                    break;
5598
                #ifdef WOLFSSL_SUBJ_INFO_ACC
5599
                case AIA_CA_REPO_OID:
5600
                    oid = extAuthInfoCaRespOid;
5601
                    *oidSz = sizeof(extAuthInfoCaRespOid);
5602
                    break;
5603
                #endif /* WOLFSSL_SUBJ_INFO_ACC */
5604
0
                default:
5605
0
                    break;
5606
0
            }
5607
0
            break;
5608
5609
0
        case oidCertPolicyType:
5610
0
            switch (id) {
5611
0
                case CP_ANY_OID:
5612
0
                    oid = extCertPolicyAnyOid;
5613
0
                    *oidSz = sizeof(extCertPolicyAnyOid);
5614
0
                    break;
5615
0
                case CP_ISRG_DOMAIN_VALID:
5616
0
                    oid = extCertPolicyIsrgDomainValid;
5617
0
                    *oidSz = sizeof(extCertPolicyIsrgDomainValid);
5618
0
                    break;
5619
                #if defined(WOLFSSL_FPKI)
5620
                case CP_FPKI_HIGH_ASSURANCE_OID:
5621
                    oid = extCertPolicyFpkiHighAssuranceOid;
5622
                    *oidSz = sizeof(extCertPolicyFpkiHighAssuranceOid);
5623
                    break;
5624
                case CP_FPKI_COMMON_HARDWARE_OID:
5625
                    oid = extCertPolicyFpkiCommonHardwareOid;
5626
                    *oidSz = sizeof(extCertPolicyFpkiCommonHardwareOid);
5627
                    break;
5628
                case CP_FPKI_MEDIUM_HARDWARE_OID:
5629
                    oid = extCertPolicyFpkiMediumHardwareOid;
5630
                    *oidSz = sizeof(extCertPolicyFpkiMediumHardwareOid);
5631
                    break;
5632
                case CP_FPKI_COMMON_HIGH_OID:
5633
                    oid = extCertPolicyFpkiCommonHighOid;
5634
                    *oidSz = sizeof(extCertPolicyFpkiCommonHighOid);
5635
                    break;
5636
                case CP_FPKI_COMMON_DEVICES_HARDWARE_OID:
5637
                    oid = extCertPolicyFpkiCommonDevicesHardwareOid;
5638
                    *oidSz = sizeof(extCertPolicyFpkiCommonDevicesHardwareOid);
5639
                    break;
5640
                case CP_FPKI_COMMON_PIV_CONTENT_SIGNING_OID:
5641
                    oid = extCertPolicyFpkiCommonPivContentSigningOid;
5642
                    *oidSz = sizeof(extCertPolicyFpkiCommonPivContentSigningOid);
5643
                    break;
5644
                case CP_FPKI_COMMON_AUTH_OID:
5645
                    oid = extCertPolicyFpkiCommonAuthOid;
5646
                    *oidSz = sizeof(extCertPolicyFpkiCommonAuthOid);
5647
                    break;
5648
                case CP_FPKI_PIV_AUTH_OID:
5649
                    oid = extCertPolicyFpkiPivAuthOid;
5650
                    *oidSz = sizeof(extCertPolicyFpkiPivAuthOid);
5651
                    break;
5652
                case CP_FPKI_PIV_AUTH_HW_OID: /* collision with AES256CBCb */
5653
                    oid = extCertPolicyFpkiPivAuthHwOid;
5654
                    *oidSz = sizeof(extCertPolicyFpkiPivAuthHwOid);
5655
                    break;
5656
                case CP_FPKI_PIVI_AUTH_OID:
5657
                    oid = extCertPolicyFpkiPiviAuthOid;
5658
                    *oidSz = sizeof(extCertPolicyFpkiPiviAuthOid);
5659
                    break;
5660
                case CP_FPKI_AUTH_TEST_OID:
5661
                    oid = extCertPolicyFpkiAuthTestOid;
5662
                    *oidSz = sizeof(extCertPolicyFpkiAuthTestOid);
5663
                    break;
5664
                case CP_FPKI_CARDAUTH_TEST_OID:
5665
                    oid = extCertPolicyFpkiCardauthTestOid;
5666
                    *oidSz = sizeof(extCertPolicyFpkiCardauthTestOid);
5667
                    break;
5668
                case CP_FPKI_PIV_CONTENT_TEST_OID:
5669
                    oid = extCertPolicyFpkiPivContentTestOid;
5670
                    *oidSz = sizeof(extCertPolicyFpkiPivContentTestOid);
5671
                    break;
5672
                case CP_FPKI_PIV_AUTH_DERIVED_TEST_OID:
5673
                    oid = extCertPolicyFpkiAuthDerivedTestOid;
5674
                    *oidSz = sizeof(extCertPolicyFpkiAuthDerivedTestOid);
5675
                    break;
5676
                case CP_FPKI_PIV_AUTH_DERIVED_HW_TEST_OID:
5677
                    oid = extCertPolicyFpkiAuthDerivedHwTestOid;
5678
                    *oidSz = sizeof(extCertPolicyFpkiAuthDerivedHwTestOid);
5679
                    break;
5680
                case CP_DOD_MEDIUM_OID:
5681
                    oid = extCertPolicyDodMediumOid;
5682
                    *oidSz = sizeof(extCertPolicyDodMediumOid);
5683
                    break;
5684
                case CP_DOD_MEDIUM_HARDWARE_OID:
5685
                    oid = extCertPolicyDodMediumHardwareOid;
5686
                    *oidSz = sizeof(extCertPolicyDodMediumHardwareOid);
5687
                    break;
5688
                case CP_DOD_PIV_AUTH_OID:
5689
                    oid = extCertPolicyDodPivAuthOid;
5690
                    *oidSz = sizeof(extCertPolicyDodPivAuthOid);
5691
                    break;
5692
                case CP_DOD_MEDIUM_NPE_OID:
5693
                    oid = extCertPolicyDodMediumNpeOid;
5694
                    *oidSz = sizeof(extCertPolicyDodMediumNpeOid);
5695
                    break;
5696
                case CP_DOD_MEDIUM_2048_OID:
5697
                    oid = extCertPolicyDodMedium2048Oid;
5698
                    *oidSz = sizeof(extCertPolicyDodMedium2048Oid);
5699
                    break;
5700
                case CP_DOD_MEDIUM_HARDWARE_2048_OID:
5701
                    oid = extCertPolicyDodMediumHardware2048Oid;
5702
                    *oidSz = sizeof(extCertPolicyDodMediumHardware2048Oid);
5703
                    break;
5704
                case CP_DOD_PIV_AUTH_2048_OID:
5705
                    oid = extCertPolicyDodPivAuth2048Oid;
5706
                    *oidSz = sizeof(extCertPolicyDodPivAuth2048Oid);
5707
                    break;
5708
                case CP_DOD_PEER_INTEROP_OID:
5709
                    oid = extCertPolicyDodPeerInteropOid;
5710
                    *oidSz = sizeof(extCertPolicyDodPeerInteropOid);
5711
                    break;
5712
                case CP_DOD_MEDIUM_NPE_112_OID:
5713
                    oid = extCertPolicyDodMediumNpe112Oid;
5714
                    *oidSz = sizeof(extCertPolicyDodMediumNpe112Oid);
5715
                    break;
5716
                case CP_DOD_MEDIUM_NPE_128_OID:
5717
                    oid = extCertPolicyDodMediumNpe128Oid;
5718
                    *oidSz = sizeof(extCertPolicyDodMediumNpe128Oid);
5719
                    break;
5720
                case CP_DOD_MEDIUM_NPE_192_OID:
5721
                    oid = extCertPolicyDodMediumNpe192Oid;
5722
                    *oidSz = sizeof(extCertPolicyDodMediumNpe192Oid);
5723
                    break;
5724
                case CP_DOD_MEDIUM_112_OID:
5725
                    oid = extCertPolicyDodMedium112Oid;
5726
                    *oidSz = sizeof(extCertPolicyDodMedium112Oid);
5727
                    break;
5728
                case CP_DOD_MEDIUM_128_OID:
5729
                    oid = extCertPolicyDodMedium128Oid;
5730
                    *oidSz = sizeof(extCertPolicyDodMedium128Oid);
5731
                    break;
5732
                case CP_DOD_MEDIUM_192_OID:
5733
                    oid = extCertPolicyDodMedium192Oid;
5734
                    *oidSz = sizeof(extCertPolicyDodMedium192Oid);
5735
                    break;
5736
                case CP_DOD_MEDIUM_HARDWARE_112_OID:
5737
                    oid = extCertPolicyDodMediumHardware112Oid;
5738
                    *oidSz = sizeof(extCertPolicyDodMediumHardware112Oid);
5739
                    break;
5740
                case CP_DOD_MEDIUM_HARDWARE_128_OID:
5741
                    oid = extCertPolicyDodMediumHardware128Oid;
5742
                    *oidSz = sizeof(extCertPolicyDodMediumHardware128Oid);
5743
                    break;
5744
                case CP_DOD_MEDIUM_HARDWARE_192_OID:
5745
                    oid = extCertPolicyDodMediumHardware192Oid;
5746
                    *oidSz = sizeof(extCertPolicyDodMediumHardware192Oid);
5747
                    break;
5748
                case CP_DOD_ADMIN_OID:
5749
                    oid = extCertPolicyDodAdminOid;
5750
                    *oidSz = sizeof(extCertPolicyDodAdminOid);
5751
                    break;
5752
                case CP_DOD_INTERNAL_NPE_112_OID:
5753
                    oid = extCertPolicyDodInternalNpe112Oid;
5754
                    *oidSz = sizeof(extCertPolicyDodInternalNpe112Oid);
5755
                    break;
5756
                case CP_DOD_INTERNAL_NPE_128_OID:
5757
                    oid = extCertPolicyDodInternalNpe128Oid;
5758
                    *oidSz = sizeof(extCertPolicyDodInternalNpe128Oid);
5759
                    break;
5760
                case CP_DOD_INTERNAL_NPE_192_OID:
5761
                    oid = extCertPolicyDodInternalNpe192Oid;
5762
                    *oidSz = sizeof(extCertPolicyDodInternalNpe192Oid);
5763
                    break;
5764
                case CP_ECA_MEDIUM_OID:
5765
                    oid = extCertPolicyEcaMediumOid;
5766
                    *oidSz = sizeof(extCertPolicyEcaMediumOid);
5767
                    break;
5768
                case CP_ECA_MEDIUM_HARDWARE_OID:
5769
                    oid = extCertPolicyEcaMediumHardwareOid;
5770
                    *oidSz = sizeof(extCertPolicyEcaMediumHardwareOid);
5771
                    break;
5772
                case CP_ECA_MEDIUM_TOKEN_OID:
5773
                    oid = extCertPolicyEcaMediumTokenOid;
5774
                    *oidSz = sizeof(extCertPolicyEcaMediumTokenOid);
5775
                    break;
5776
                case CP_ECA_MEDIUM_SHA256_OID:
5777
                    oid = extCertPolicyEcaMediumSha256Oid;
5778
                    *oidSz = sizeof(extCertPolicyEcaMediumSha256Oid);
5779
                    break;
5780
                case CP_ECA_MEDIUM_TOKEN_SHA256_OID:
5781
                    oid = extCertPolicyEcaMediumTokenSha256Oid;
5782
                    *oidSz = sizeof(extCertPolicyEcaMediumTokenSha256Oid);
5783
                    break;
5784
                case CP_ECA_MEDIUM_HARDWARE_PIVI_OID:
5785
                    oid = extCertPolicyEcaMediumHardwarePiviOid;
5786
                    *oidSz = sizeof(extCertPolicyEcaMediumHardwarePiviOid);
5787
                    break;
5788
                case CP_ECA_CONTENT_SIGNING_PIVI_OID:
5789
                    oid = extCertPolicyEcaContentSigningPiviOid;
5790
                    *oidSz = sizeof(extCertPolicyEcaContentSigningPiviOid);
5791
                    break;
5792
                case CP_ECA_MEDIUM_DEVICE_SHA256_OID:
5793
                    oid = extCertPolicyEcaMediumDeviceSha256Oid;
5794
                    *oidSz = sizeof(extCertPolicyEcaMediumDeviceSha256Oid);
5795
                    break;
5796
                case CP_ECA_MEDIUM_HARDWARE_SHA256_OID:
5797
                    oid = extCertPolicyEcaMediumHardwareSha256Oid;
5798
                    *oidSz = sizeof(extCertPolicyEcaMediumHardwareSha256Oid);
5799
                    break;
5800
5801
                /* Department of State PKI OIDs */
5802
                case CP_STATE_BASIC_OID:
5803
                    oid = extCertPolicyStateBasicOid;
5804
                    *oidSz = sizeof(extCertPolicyStateBasicOid);
5805
                    break;
5806
                case CP_STATE_LOW_OID:
5807
                    oid = extCertPolicyStateLowOid;
5808
                    *oidSz = sizeof(extCertPolicyStateLowOid);
5809
                    break;
5810
                case CP_STATE_MODERATE_OID:
5811
                    oid = extCertPolicyStateModerateOid;
5812
                    *oidSz = sizeof(extCertPolicyStateModerateOid);
5813
                    break;
5814
                case CP_STATE_HIGH_OID:
5815
                    oid = extCertPolicyStateHighOid;
5816
                    *oidSz = sizeof(extCertPolicyStateHighOid);
5817
                    break;
5818
                case CP_STATE_MEDHW_OID:
5819
                    oid = extCertPolicyStateMedHwOid;
5820
                    *oidSz = sizeof(extCertPolicyStateMedHwOid);
5821
                    break;
5822
                case CP_STATE_MEDDEVHW_OID:
5823
                    oid = extCertPolicyStateMediumDeviceHardwareOid;
5824
                    *oidSz = sizeof(extCertPolicyStateMediumDeviceHardwareOid);
5825
                    break;
5826
5827
                /* U.S. Treasury SSP PKI OIDs */
5828
                case CP_TREAS_MEDIUMHW_OID:
5829
                    oid = extCertPolicyTreasuryMediumHardwareOid;
5830
                    *oidSz = sizeof(extCertPolicyTreasuryMediumHardwareOid);
5831
                    break;
5832
                case CP_TREAS_HIGH_OID:
5833
                    oid = extCertPolicyTreasuryHighOid;
5834
                    *oidSz = sizeof(extCertPolicyTreasuryHighOid);
5835
                    break;
5836
                case CP_TREAS_PIVI_HW_OID:
5837
                    oid = extCertPolicyTreasuryPiviHardwareOid;
5838
                    *oidSz = sizeof(extCertPolicyTreasuryPiviHardwareOid);
5839
                    break;
5840
                case CP_TREAS_PIVI_CONTENT_OID:
5841
                    oid = extCertPolicyTreasuryPiviContentSigningOid;
5842
                    *oidSz = sizeof(extCertPolicyTreasuryPiviContentSigningOid);
5843
                    break;
5844
5845
                /* Boeing PKI OIDs */
5846
                case CP_BOEING_MEDIUMHW_SHA256_OID:
5847
                    oid = extCertPolicyBoeingMediumHardwareSha256Oid;
5848
                    *oidSz = sizeof(extCertPolicyBoeingMediumHardwareSha256Oid);
5849
                    break;
5850
                case CP_BOEING_MEDIUMHW_CONTENT_SHA256_OID:
5851
                    oid = extCertPolicyBoeingMediumHardwareContentSigningSha256Oid;
5852
                    *oidSz = sizeof(extCertPolicyBoeingMediumHardwareContentSigningSha256Oid);
5853
                    break;
5854
5855
                /* DigiCert NFI PKI OIDs */
5856
                case CP_DIGICERT_NFSSP_MEDIUMHW_OID:
5857
                    oid = extCertPolicyDigicertNfiMediumHardwareOid;
5858
                    *oidSz = sizeof(extCertPolicyDigicertNfiMediumHardwareOid);
5859
                    break;
5860
                case CP_DIGICERT_NFSSP_AUTH_OID:
5861
                    oid = extCertPolicyDigicertNfiAuthOid;
5862
                    *oidSz = sizeof(extCertPolicyDigicertNfiAuthOid);
5863
                    break;
5864
                case CP_DIGICERT_NFSSP_PIVI_HW_OID:
5865
                    oid = extCertPolicyDigicertNfiPiviHardwareOid;
5866
                    *oidSz = sizeof(extCertPolicyDigicertNfiPiviHardwareOid);
5867
                    break;
5868
                case CP_DIGICERT_NFSSP_PIVI_CONTENT_OID:
5869
                    oid = extCertPolicyDigicertNfiPiviContentSigningOid;
5870
                    *oidSz = sizeof(extCertPolicyDigicertNfiPiviContentSigningOid);
5871
                    break;
5872
                case CP_DIGICERT_NFSSP_MEDDEVHW_OID:
5873
                    oid = extCertPolicyDigicertNfiMediumDevicesHardwareOid;
5874
                    *oidSz = sizeof(extCertPolicyDigicertNfiMediumDevicesHardwareOid);
5875
                    break;
5876
5877
                /* Entrust Managed Services NFI PKI OIDs */
5878
                case CP_ENTRUST_NFSSP_MEDIUMHW_OID:
5879
                    oid = extCertPolicyEntrustNfiMediumHardwareOid;
5880
                    *oidSz = sizeof(extCertPolicyEntrustNfiMediumHardwareOid);
5881
                    break;
5882
                case CP_ENTRUST_NFSSP_MEDAUTH_OID:
5883
                    oid = extCertPolicyEntrustNfiMediumAuthenticationOid;
5884
                    *oidSz = sizeof(extCertPolicyEntrustNfiMediumAuthenticationOid);
5885
                    break;
5886
                case CP_ENTRUST_NFSSP_PIVI_HW_OID:
5887
                    oid = extCertPolicyEntrustNfiPiviHardwareOid;
5888
                    *oidSz = sizeof(extCertPolicyEntrustNfiPiviHardwareOid);
5889
                    break;
5890
                case CP_ENTRUST_NFSSP_PIVI_CONTENT_OID:
5891
                    oid = extCertPolicyEntrustNfiPiviContentSigningOid;
5892
                    *oidSz = sizeof(extCertPolicyEntrustNfiPiviContentSigningOid);
5893
                    break;
5894
                case CP_ENTRUST_NFSSP_MEDDEVHW_OID:
5895
                    oid = extCertPolicyEntrustNfiMediumDevicesHwOid;
5896
                    *oidSz = sizeof(extCertPolicyEntrustNfiMediumDevicesHwOid);
5897
                    break;
5898
5899
                /* Exostar LLC PKI OIDs */
5900
                case CP_EXOSTAR_MEDIUMHW_SHA2_OID:
5901
                    oid = extCertPolicyExostarMediumHardwareSha2Oid;
5902
                    *oidSz = sizeof(extCertPolicyExostarMediumHardwareSha2Oid);
5903
                    break;
5904
5905
                /* Lockheed Martin PKI OIDs */
5906
                case CP_LOCKHEED_MEDIUMHW_OID:
5907
                    oid = extCertPolicyLockheedMediumAssuranceHardwareOid;
5908
                    *oidSz = sizeof(extCertPolicyLockheedMediumAssuranceHardwareOid);
5909
                    break;
5910
5911
                /* Northrop Grumman PKI OIDs */
5912
                case CP_NORTHROP_MEDIUM_256_HW_OID:
5913
                    oid = extCertPolicyNorthropMediumAssurance256HardwareTokenOid;
5914
                    *oidSz = sizeof(extCertPolicyNorthropMediumAssurance256HardwareTokenOid);
5915
                    break;
5916
                case CP_NORTHROP_PIVI_256_HW_OID:
5917
                    oid = extCertPolicyNorthropPiviAssurance256HardwareTokenOid;
5918
                    *oidSz = sizeof(extCertPolicyNorthropPiviAssurance256HardwareTokenOid);
5919
                    break;
5920
                case CP_NORTHROP_PIVI_256_CONTENT_OID:
5921
                    oid = extCertPolicyNorthropPiviAssurance256ContentSigningOid;
5922
                    *oidSz = sizeof(extCertPolicyNorthropPiviAssurance256ContentSigningOid);
5923
                    break;
5924
                case CP_NORTHROP_MEDIUM_384_HW_OID:
5925
                    oid = extCertPolicyNorthropMediumAssurance384HardwareTokenOid;
5926
                    *oidSz = sizeof(extCertPolicyNorthropMediumAssurance384HardwareTokenOid);
5927
                    break;
5928
5929
                /* Raytheon PKI OIDs */
5930
                case CP_RAYTHEON_MEDIUMHW_OID:
5931
                    oid = extCertPolicyRaytheonMediumHardwareOid;
5932
                    *oidSz = sizeof(extCertPolicyRaytheonMediumHardwareOid);
5933
                    break;
5934
                case CP_RAYTHEON_MEDDEVHW_OID:
5935
                    oid = extCertPolicyRaytheonMediumDeviceHardwareOid;
5936
                    *oidSz = sizeof(extCertPolicyRaytheonMediumDeviceHardwareOid);
5937
                    break;
5938
                case CP_RAYTHEON_SHA2_MEDIUMHW_OID:
5939
                    oid = extCertPolicyRaytheonSha2MediumHardwareOid;
5940
                    *oidSz = sizeof(extCertPolicyRaytheonSha2MediumHardwareOid);
5941
                    break;
5942
                case CP_RAYTHEON_SHA2_MEDDEVHW_OID:
5943
                    oid = extCertPolicyRaytheonSha2MediumDeviceHardwareOid;
5944
                   *oidSz = sizeof(extCertPolicyRaytheonSha2MediumDeviceHardwareOid);
5945
                    break;
5946
5947
                /* WidePoint NFI PKI OIDs */
5948
                case CP_WIDEPOINT_MEDIUMHW_OID:
5949
                    oid = extCertPolicyWidepointNfiMediumHardwareOid;
5950
                    *oidSz = sizeof(extCertPolicyWidepointNfiMediumHardwareOid);
5951
                    break;
5952
                case CP_WIDEPOINT_PIVI_HW_OID:
5953
                    oid = extCertPolicyWidepointNfiPiviHardwareOid;
5954
                    *oidSz = sizeof(extCertPolicyWidepointNfiPiviHardwareOid);
5955
                    break;
5956
                case CP_WIDEPOINT_PIVI_CONTENT_OID:
5957
                    oid = extCertPolicyWidepointNfiPiviContentSigningOid;
5958
                    *oidSz = sizeof(extCertPolicyWidepointNfiPiviContentSigningOid);
5959
                    break;
5960
                case CP_WIDEPOINT_MEDDEVHW_OID:
5961
                    oid = extCertPolicyWidepointNfiMediumDevicesHardwareOid;
5962
                    *oidSz = sizeof(extCertPolicyWidepointNfiMediumDevicesHardwareOid);
5963
                    break;
5964
5965
                /* Australian Defence Organisation PKI OIDs */
5966
                case CP_ADO_MEDIUM_OID:
5967
                    oid = extCertPolicyAdoIndividualMediumAssuranceOid;
5968
                    *oidSz = sizeof(extCertPolicyAdoIndividualMediumAssuranceOid);
5969
                    break;
5970
                case CP_ADO_HIGH_OID:
5971
                    oid = extCertPolicyAdoIndividualHighAssuranceOid;
5972
                    *oidSz = sizeof(extCertPolicyAdoIndividualHighAssuranceOid);
5973
                    break;
5974
                case CP_ADO_RESOURCE_MEDIUM_OID:
5975
                    oid = extCertPolicyAdoResourceMediumAssuranceOid;
5976
                    *oidSz = sizeof(extCertPolicyAdoResourceMediumAssuranceOid);
5977
                    break;
5978
5979
                /* Netherlands Ministry of Defence PKI OIDs */
5980
                case CP_NL_MOD_AUTH_OID:
5981
                    oid = extCertPolicyNlModAuthenticityOid;
5982
                    *oidSz = sizeof(extCertPolicyNlModAuthenticityOid);
5983
                    break;
5984
                case CP_NL_MOD_IRREFUT_OID:
5985
                    oid = extCertPolicyNlModIrrefutabilityOid;
5986
                    *oidSz = sizeof(extCertPolicyNlModIrrefutabilityOid);
5987
                    break;
5988
                case CP_NL_MOD_CONFID_OID:
5989
                    oid = extCertPolicyNlModConfidentialityOid;
5990
                    *oidSz = sizeof(extCertPolicyNlModConfidentialityOid);
5991
                    break;
5992
5993
                /* IdenTrust NFI OIDs */
5994
                case CP_IDENTRUST_MEDIUMHW_SIGN_OID:
5995
                    oid = extCertPolicyIdentrustMediumhwSignOid;
5996
                    *oidSz = sizeof(extCertPolicyIdentrustMediumhwSignOid);
5997
                    break;
5998
                case CP_IDENTRUST_MEDIUMHW_ENC_OID:
5999
                    oid = extCertPolicyIdentrustMediumhwEncOid;
6000
                    *oidSz = sizeof(extCertPolicyIdentrustMediumhwEncOid);
6001
                    break;
6002
                case CP_IDENTRUST_PIVI_HW_ID_OID:
6003
                    oid = extCertPolicyIdentrustPiviHwIdOid;
6004
                    *oidSz = sizeof(extCertPolicyIdentrustPiviHwIdOid);
6005
                    break;
6006
                case CP_IDENTRUST_PIVI_HW_SIGN_OID:
6007
                    oid = extCertPolicyIdentrustPiviHwSignOid;
6008
                    *oidSz = sizeof(extCertPolicyIdentrustPiviHwSignOid);
6009
                    break;
6010
                case CP_IDENTRUST_PIVI_HW_ENC_OID:
6011
                    oid = extCertPolicyIdentrustPiviHwEncOid;
6012
                    *oidSz = sizeof(extCertPolicyIdentrustPiviHwEncOid);
6013
                    break;
6014
                case CP_IDENTRUST_PIVI_CONTENT_OID:
6015
                    oid = extCertPolicyIdentrustPiviContentOid;
6016
                    *oidSz = sizeof(extCertPolicyIdentrustPiviContentOid);
6017
                    break;
6018
6019
                /* TSCP Bridge OIDs */
6020
                case CP_TSCP_MEDIUMHW_OID:
6021
                    oid = extCertPolicyTscpMediumhwOid;
6022
                    *oidSz = sizeof(extCertPolicyTscpMediumhwOid);
6023
                    break;
6024
                case CP_TSCP_PIVI_OID:
6025
                    oid = extCertPolicyTscpPiviOid;
6026
                    *oidSz = sizeof(extCertPolicyTscpPiviOid);
6027
                    break;
6028
                case CP_TSCP_PIVI_CONTENT_OID:
6029
                    oid = extCertPolicyTscpPiviContentOid;
6030
                    *oidSz = sizeof(extCertPolicyTscpPiviContentOid);
6031
                    break;
6032
6033
                /* Carillon Federal Services OIDs */
6034
                case CP_CARILLON_MEDIUMHW_256_OID:
6035
                    oid = extCertPolicyCarillonMediumhw256Oid;
6036
                    *oidSz = sizeof(extCertPolicyCarillonMediumhw256Oid);
6037
                    break;
6038
                case CP_CARILLON_AIVHW_OID:
6039
                    oid = extCertPolicyCarillonAivhwOid;
6040
                    *oidSz = sizeof(extCertPolicyCarillonAivhwOid);
6041
                    break;
6042
                case CP_CARILLON_AIVCONTENT_OID:
6043
                    oid = extCertPolicyCarillonAivcontentOid;
6044
                    *oidSz = sizeof(extCertPolicyCarillonAivcontentOid);
6045
                    break;
6046
6047
                /* Carillon Information Security OIDs */
6048
                case CP_CIS_MEDIUMHW_256_OID:
6049
                    oid = extCertPolicyCisMediumhw256Oid;
6050
                    *oidSz = sizeof(extCertPolicyCisMediumhw256Oid);
6051
                    break;
6052
                case CP_CIS_MEDDEVHW_256_OID:
6053
                    oid = extCertPolicyCisMeddevhw256Oid;
6054
                    *oidSz = sizeof(extCertPolicyCisMeddevhw256Oid);
6055
                    break;
6056
                case CP_CIS_ICECAP_HW_OID:
6057
                    oid = extCertPolicyCisIcecapHwOid;
6058
                    *oidSz = sizeof(extCertPolicyCisIcecapHwOid);
6059
                    break;
6060
                case CP_CIS_ICECAP_CONTENT_OID:
6061
                    oid = extCertPolicyCisIcecapContentOid;
6062
                    *oidSz = sizeof(extCertPolicyCisIcecapContentOid);
6063
                    break;
6064
6065
                /* CertiPath Bridge OIDs */
6066
                case CP_CERTIPATH_MEDIUMHW_OID:
6067
                    oid = extCertPolicyCertipathMediumhwOid;
6068
                    *oidSz = sizeof(extCertPolicyCertipathMediumhwOid);
6069
                    break;
6070
                case CP_CERTIPATH_HIGHHW_OID:
6071
                    oid = extCertPolicyCertipathHighhwOid;
6072
                    *oidSz = sizeof(extCertPolicyCertipathHighhwOid);
6073
                    break;
6074
                case CP_CERTIPATH_ICECAP_HW_OID:
6075
                    oid = extCertPolicyCertipathIcecapHwOid;
6076
                    *oidSz = sizeof(extCertPolicyCertipathIcecapHwOid);
6077
                    break;
6078
                case CP_CERTIPATH_ICECAP_CONTENT_OID:
6079
                    oid = extCertPolicyCertipathIcecapContentOid;
6080
                    *oidSz = sizeof(extCertPolicyCertipathIcecapContentOid);
6081
                    break;
6082
                case CP_CERTIPATH_VAR_MEDIUMHW_OID:
6083
                    oid = extCertPolicyCertipathVarMediumhwOid;
6084
                    *oidSz = sizeof(extCertPolicyCertipathVarMediumhwOid);
6085
                    break;
6086
                case CP_CERTIPATH_VAR_HIGHHW_OID:
6087
                    oid = extCertPolicyCertipathVarHighhwOid;
6088
                    *oidSz = sizeof(extCertPolicyCertipathVarHighhwOid);
6089
                    break;
6090
                case CP_COMODO_OID:
6091
                    oid = extCertPolicyComodoLtdOid;
6092
                    *oidSz = sizeof(extCertPolicyComodoLtdOid);
6093
                    break;
6094
                /* FPKI OIDs */
6095
                #endif /* WOLFSSL_FPKI */
6096
0
                default:
6097
0
                    break;
6098
0
            }
6099
0
            break;
6100
6101
0
        case oidCertAltNameType:
6102
0
            switch (id) {
6103
0
                case HW_NAME_OID:
6104
0
                    oid = extAltNamesHwNameOid;
6105
0
                    *oidSz = sizeof(extAltNamesHwNameOid);
6106
0
                    break;
6107
0
                default:
6108
0
                    break;
6109
0
            }
6110
0
            break;
6111
6112
0
        case oidCertKeyUseType:
6113
0
            switch (id) {
6114
0
                case EKU_ANY_OID:
6115
0
                    oid = extExtKeyUsageAnyOid;
6116
0
                    *oidSz = sizeof(extExtKeyUsageAnyOid);
6117
0
                    break;
6118
0
                case EKU_SERVER_AUTH_OID:
6119
0
                    oid = extExtKeyUsageServerAuthOid;
6120
0
                    *oidSz = sizeof(extExtKeyUsageServerAuthOid);
6121
0
                    break;
6122
0
                case EKU_CLIENT_AUTH_OID:
6123
0
                    oid = extExtKeyUsageClientAuthOid;
6124
0
                    *oidSz = sizeof(extExtKeyUsageClientAuthOid);
6125
0
                    break;
6126
0
                case EKU_CODESIGNING_OID:
6127
0
                    oid = extExtKeyUsageCodeSigningOid;
6128
0
                    *oidSz = sizeof(extExtKeyUsageCodeSigningOid);
6129
0
                    break;
6130
0
                case EKU_EMAILPROTECT_OID:
6131
0
                    oid = extExtKeyUsageEmailProtectOid;
6132
0
                    *oidSz = sizeof(extExtKeyUsageEmailProtectOid);
6133
0
                    break;
6134
0
                case EKU_TIMESTAMP_OID:
6135
0
                    oid = extExtKeyUsageTimestampOid;
6136
0
                    *oidSz = sizeof(extExtKeyUsageTimestampOid);
6137
0
                    break;
6138
0
                case EKU_OCSP_SIGN_OID:
6139
0
                    oid = extExtKeyUsageOcspSignOid;
6140
0
                    *oidSz = sizeof(extExtKeyUsageOcspSignOid);
6141
0
                    break;
6142
                #ifdef WOLFSSL_WOLFSSH
6143
                case EKU_SSH_CLIENT_AUTH_OID:
6144
                    oid = extExtKeyUsageSshClientAuthOid;
6145
                    *oidSz = sizeof(extExtKeyUsageSshClientAuthOid);
6146
                    break;
6147
                case EKU_SSH_MSCL_OID:
6148
                    oid = extExtKeyUsageSshMSCLOid;
6149
                    *oidSz = sizeof(extExtKeyUsageSshMSCLOid);
6150
                    break;
6151
                case EKU_SSH_KP_CLIENT_AUTH_OID:
6152
                    oid = extExtKeyUsageSshKpClientAuthOid;
6153
                    *oidSz = sizeof(extExtKeyUsageSshKpClientAuthOid);
6154
                    break;
6155
                #endif /* WOLFSSL_WOLFSSH */
6156
0
                default:
6157
0
                    break;
6158
0
            }
6159
0
            break;
6160
6161
0
        case oidKdfType:
6162
0
            switch (id) {
6163
0
                case PBKDF2_OID:
6164
0
                    oid = pbkdf2Oid;
6165
0
                    *oidSz = sizeof(pbkdf2Oid);
6166
0
                    break;
6167
0
                default:
6168
0
                    break;
6169
0
            }
6170
0
            break;
6171
6172
0
        case oidPBEType:
6173
0
            switch (id) {
6174
        #if !defined(NO_SHA) && !defined(NO_RC4)
6175
                case PBE_SHA1_RC4_128_SUM:
6176
                case PBE_SHA1_RC4_128:
6177
                    oid = pbeSha1RC4128;
6178
                    *oidSz = sizeof(pbeSha1RC4128);
6179
                    break;
6180
        #endif
6181
        #if !defined(NO_MD5) && !defined(NO_DES3)
6182
                case PBE_MD5_DES_SUM:
6183
                case PBE_MD5_DES:
6184
                    oid = pbeMd5Des;
6185
                    *oidSz = sizeof(pbeMd5Des);
6186
                    break;
6187
6188
        #endif
6189
        #if !defined(NO_SHA) && !defined(NO_DES3)
6190
                case PBE_SHA1_DES_SUM:
6191
                case PBE_SHA1_DES:
6192
                    oid = pbeSha1Des;
6193
                    *oidSz = sizeof(pbeSha1Des);
6194
                    break;
6195
6196
        #endif
6197
        #if !defined(NO_SHA) && !defined(NO_DES3)
6198
                case PBE_SHA1_DES3_SUM:
6199
                case PBE_SHA1_DES3:
6200
                    oid = pbeSha1Des3;
6201
                    *oidSz = sizeof(pbeSha1Des3);
6202
                    break;
6203
        #endif
6204
        #if !defined(NO_SHA) && defined(WC_RC2)
6205
                case PBE_SHA1_40RC2_CBC_SUM:
6206
                case PBE_SHA1_40RC2_CBC:
6207
                    oid = pbe40Rc2Cbc;
6208
                    *oidSz = sizeof(pbe40Rc2Cbc);
6209
                    break;
6210
        #endif
6211
0
                case PBES2_SUM:
6212
0
                case PBES2:
6213
0
                    oid = pbes2;
6214
0
                    *oidSz = sizeof(pbes2);
6215
0
                    break;
6216
0
                default:
6217
0
                    break;
6218
0
            }
6219
0
            break;
6220
6221
0
        case oidKeyWrapType:
6222
0
            switch (id) {
6223
0
            #ifdef WOLFSSL_AES_128
6224
0
                case AES128_WRAP:
6225
0
                    oid = wrapAes128Oid;
6226
0
                    *oidSz = sizeof(wrapAes128Oid);
6227
0
                    break;
6228
0
            #endif
6229
0
            #ifdef WOLFSSL_AES_192
6230
0
                case AES192_WRAP:
6231
0
                    oid = wrapAes192Oid;
6232
0
                    *oidSz = sizeof(wrapAes192Oid);
6233
0
                    break;
6234
0
            #endif
6235
0
            #ifdef WOLFSSL_AES_256
6236
0
                case AES256_WRAP:
6237
0
                    oid = wrapAes256Oid;
6238
0
                    *oidSz = sizeof(wrapAes256Oid);
6239
0
                    break;
6240
0
            #endif
6241
            #ifdef HAVE_PKCS7
6242
                case PWRI_KEK_WRAP:
6243
                    oid = wrapPwriKekOid;
6244
                    *oidSz = sizeof(wrapPwriKekOid);
6245
                    break;
6246
            #endif
6247
0
                default:
6248
0
                    break;
6249
0
            }
6250
0
            break;
6251
6252
0
        case oidCmsKeyAgreeType:
6253
0
            switch (id) {
6254
0
            #ifndef NO_SHA
6255
0
                case dhSinglePass_stdDH_sha1kdf_scheme:
6256
0
                    oid = dhSinglePass_stdDH_sha1kdf_Oid;
6257
0
                    *oidSz = sizeof(dhSinglePass_stdDH_sha1kdf_Oid);
6258
0
                    break;
6259
0
            #endif
6260
0
            #ifdef WOLFSSL_SHA224
6261
0
                case dhSinglePass_stdDH_sha224kdf_scheme:
6262
0
                    oid = dhSinglePass_stdDH_sha224kdf_Oid;
6263
0
                    *oidSz = sizeof(dhSinglePass_stdDH_sha224kdf_Oid);
6264
0
                    break;
6265
0
            #endif
6266
0
            #ifndef NO_SHA256
6267
0
                case dhSinglePass_stdDH_sha256kdf_scheme:
6268
0
                    oid = dhSinglePass_stdDH_sha256kdf_Oid;
6269
0
                    *oidSz = sizeof(dhSinglePass_stdDH_sha256kdf_Oid);
6270
0
                    break;
6271
0
            #endif
6272
0
            #ifdef WOLFSSL_SHA384
6273
0
                case dhSinglePass_stdDH_sha384kdf_scheme:
6274
0
                    oid = dhSinglePass_stdDH_sha384kdf_Oid;
6275
0
                    *oidSz = sizeof(dhSinglePass_stdDH_sha384kdf_Oid);
6276
0
                    break;
6277
0
            #endif
6278
0
            #ifdef WOLFSSL_SHA512
6279
0
                case dhSinglePass_stdDH_sha512kdf_scheme:
6280
0
                    oid = dhSinglePass_stdDH_sha512kdf_Oid;
6281
0
                    *oidSz = sizeof(dhSinglePass_stdDH_sha512kdf_Oid);
6282
0
                    break;
6283
0
            #endif
6284
0
                default:
6285
0
                    break;
6286
0
            }
6287
0
            break;
6288
6289
0
#ifndef NO_HMAC
6290
0
        case oidHmacType:
6291
0
            switch (id) {
6292
0
        #ifdef WOLFSSL_SHA224
6293
0
                case HMAC_SHA224_OID:
6294
0
                    oid = hmacSha224Oid;
6295
0
                    *oidSz = sizeof(hmacSha224Oid);
6296
0
                    break;
6297
0
        #endif
6298
0
        #ifndef NO_SHA256
6299
0
                case HMAC_SHA256_OID:
6300
0
                    oid = hmacSha256Oid;
6301
0
                    *oidSz = sizeof(hmacSha256Oid);
6302
0
                    break;
6303
0
        #endif
6304
0
        #ifdef WOLFSSL_SHA384
6305
0
                case HMAC_SHA384_OID:
6306
0
                    oid = hmacSha384Oid;
6307
0
                    *oidSz = sizeof(hmacSha384Oid);
6308
0
                    break;
6309
0
        #endif
6310
0
        #ifdef WOLFSSL_SHA512
6311
0
                case HMAC_SHA512_OID:
6312
0
                    oid = hmacSha512Oid;
6313
0
                    *oidSz = sizeof(hmacSha512Oid);
6314
0
                    break;
6315
0
        #endif
6316
0
                default:
6317
0
                    break;
6318
0
            }
6319
0
            break;
6320
0
#endif /* !NO_HMAC */
6321
6322
#ifdef HAVE_LIBZ
6323
        case oidCompressType:
6324
            switch (id) {
6325
                case ZLIBc:
6326
                    oid = zlibCompress;
6327
                    *oidSz = sizeof(zlibCompress);
6328
                    break;
6329
                default:
6330
                    break;
6331
            }
6332
            break;
6333
#endif /* HAVE_LIBZ */
6334
#ifdef WOLFSSL_APACHE_HTTPD
6335
        case oidCertNameType:
6336
            switch (id) {
6337
                 case WC_NID_id_on_dnsSRV:
6338
                    oid = dnsSRVOid;
6339
                    *oidSz = sizeof(dnsSRVOid);
6340
                    break;
6341
                default:
6342
                    break;
6343
            }
6344
            break;
6345
        case oidTlsExtType:
6346
            switch (id) {
6347
                case TLS_FEATURE_OID:
6348
                    oid = tlsFeatureOid;
6349
                    *oidSz = sizeof(tlsFeatureOid);
6350
                    break;
6351
                default:
6352
                    break;
6353
            }
6354
            break;
6355
#endif /* WOLFSSL_APACHE_HTTPD */
6356
#ifdef WOLFSSL_CERT_REQ
6357
        case oidCsrAttrType:
6358
            switch (id) {
6359
                case GIVEN_NAME_OID:
6360
                    oid = attrGivenName;
6361
                    *oidSz = sizeof(attrGivenName);
6362
                    break;
6363
                case SURNAME_OID:
6364
                    oid = attrSurname;
6365
                    *oidSz = sizeof(attrSurname);
6366
                    break;
6367
                case INITIALS_OID:
6368
                    oid = attrInitals;
6369
                    *oidSz = sizeof(attrInitals);
6370
                    break;
6371
                case DNQUALIFIER_OID:
6372
                    oid = attrDnQualifier;
6373
                    *oidSz = sizeof(attrDnQualifier);
6374
                    break;
6375
                case UNSTRUCTURED_NAME_OID:
6376
                    oid = attrUnstructuredNameOid;
6377
                    *oidSz = sizeof(attrUnstructuredNameOid);
6378
                    break;
6379
                case PKCS9_CONTENT_TYPE_OID:
6380
                    oid = attrPkcs9ContentTypeOid;
6381
                    *oidSz = sizeof(attrPkcs9ContentTypeOid);
6382
                    break;
6383
                case CHALLENGE_PASSWORD_OID:
6384
                    oid = attrChallengePasswordOid;
6385
                    *oidSz = sizeof(attrChallengePasswordOid);
6386
                    break;
6387
                case SERIAL_NUMBER_OID:
6388
                    oid = attrSerialNumberOid;
6389
                    *oidSz = sizeof(attrSerialNumberOid);
6390
                    break;
6391
                case USER_ID_OID:
6392
                    oid = uidOid;
6393
                    *oidSz = sizeof(uidOid);
6394
                    break;
6395
                case EXTENSION_REQUEST_OID:
6396
                    oid = attrExtensionRequestOid;
6397
                    *oidSz = sizeof(attrExtensionRequestOid);
6398
                    break;
6399
                default:
6400
                    break;
6401
            }
6402
            break;
6403
#endif
6404
#ifdef WOLFSSL_SUBJ_DIR_ATTR
6405
        case oidSubjDirAttrType:
6406
            switch (id) {
6407
                case SDA_DOB_OID:
6408
                    oid = extSubjDirAttrDobOid;
6409
                    *oidSz = sizeof(extSubjDirAttrDobOid);
6410
                    break;
6411
                case SDA_POB_OID:
6412
                    oid = extSubjDirAttrPobOid;
6413
                    *oidSz = sizeof(extSubjDirAttrPobOid);
6414
                    break;
6415
                case SDA_GENDER_OID:
6416
                    oid = extSubjDirAttrGenderOid;
6417
                    *oidSz = sizeof(extSubjDirAttrGenderOid);
6418
                    break;
6419
                case SDA_COC_OID:
6420
                    oid = extSubjDirAttrCocOid;
6421
                    *oidSz = sizeof(extSubjDirAttrCocOid);
6422
                    break;
6423
                case SDA_COR_OID:
6424
                    oid = extSubjDirAttrCorOid;
6425
                    *oidSz = sizeof(extSubjDirAttrCorOid);
6426
                    break;
6427
                default:
6428
                    break;
6429
            }
6430
            break;
6431
#endif /* WOLFSSL_SUBJ_DIR_ATTR */
6432
0
        case oidIgnoreType:
6433
0
        default:
6434
0
            break;
6435
0
    }
6436
6437
0
    return oid;
6438
0
}
6439
6440
#ifdef HAVE_ECC
6441
6442
/* Check the OID id is for a known elliptic curve.
6443
 *
6444
 * @param [in]  oid  OID id.
6445
 * @return  ECC set id on success.
6446
 * @return  ECC_CURVE_OID_E when OID id is 0 or not supported.
6447
 */
6448
static int CheckCurve(word32 oid)
6449
0
{
6450
0
    int ret;
6451
0
    word32 oidSz;
6452
6453
    /* Lookup OID id. */
6454
0
    ret = wc_ecc_get_oid(oid, NULL, &oidSz);
6455
    /* Check for error or zero length OID size (can't get OID for encoding). */
6456
0
    if ((ret < 0) || (oidSz == 0)) {
6457
0
        WOLFSSL_MSG("CheckCurve not found");
6458
0
        WOLFSSL_ERROR_VERBOSE(ECC_CURVE_OID_E);
6459
0
        ret = ECC_CURVE_OID_E;
6460
0
    }
6461
6462
    /* Return ECC set id or error code. */
6463
0
    return ret;
6464
0
}
6465
6466
#endif
6467
6468
#ifdef HAVE_OID_ENCODING
6469
/* Encode dotted form of OID into byte array version.
6470
 *
6471
 * @param [in]      in     Dotted form of OID.
6472
 * @param [in]      inSz   Count of numbers in dotted form.
6473
 * @param [in]      out    Buffer to hold OID.
6474
 * @param [in, out] outSz  On in, size of buffer.
6475
 *                         On out, number of bytes in buffer.
6476
 * @return  0 on success
6477
 * @return  BAD_FUNC_ARG when in or outSz is NULL.
6478
 * @return  BUFFER_E when buffer too small.
6479
 */
6480
int wc_EncodeObjectId(const word16* in, word32 inSz, byte* out, word32* outSz)
6481
{
6482
    return EncodeObjectId(in, inSz, out, outSz);
6483
}
6484
6485
int EncodeObjectId(const word16* in, word32 inSz, byte* out, word32* outSz)
6486
{
6487
    int i, x, len;
6488
    word32 d, t;
6489
6490
    /* check args */
6491
    if (in == NULL || outSz == NULL || inSz <= 0) {
6492
        return BAD_FUNC_ARG;
6493
    }
6494
6495
    /* compute length of encoded OID */
6496
    d = ((word32)in[0] * 40) + in[1];
6497
    len = 0;
6498
    for (i = 1; i < (int)inSz; i++) {
6499
        x = 0;
6500
        t = d;
6501
        while (t) {
6502
            x++;
6503
            t >>= 1;
6504
        }
6505
        len += (x / 7) + ((x % 7) ? 1 : 0) + (d == 0 ? 1 : 0);
6506
6507
        if (i < (int)inSz - 1) {
6508
            d = in[i + 1];
6509
        }
6510
    }
6511
6512
    if (out) {
6513
        /* verify length */
6514
        if ((int)*outSz < len) {
6515
            return BUFFER_E; /* buffer provided is not large enough */
6516
        }
6517
6518
        /* calc first byte */
6519
        d = ((word32)in[0] * 40) + in[1];
6520
6521
        /* encode bytes */
6522
        x = 0;
6523
        for (i = 1; i < (int)inSz; i++) {
6524
            if (d) {
6525
                int y = x, z;
6526
                byte mask = 0;
6527
                while (d) {
6528
                    out[x++] = (byte)((d & 0x7F) | mask);
6529
                    d     >>= 7;
6530
                    mask  |= 0x80;  /* upper bit is set on all but the last byte */
6531
                }
6532
                /* now swap bytes y...x-1 */
6533
                z = x - 1;
6534
                while (y < z) {
6535
                    mask = out[y];
6536
                    out[y] = out[z];
6537
                    out[z] = mask;
6538
                    ++y;
6539
                    --z;
6540
                }
6541
            }
6542
            else {
6543
              out[x++] = 0x00; /* zero value */
6544
            }
6545
6546
            /* next word */
6547
            if (i < (int)inSz - 1) {
6548
                d = in[i + 1];
6549
            }
6550
        }
6551
    }
6552
6553
    /* return length */
6554
    *outSz = (word32)len;
6555
6556
    return 0;
6557
}
6558
#endif /* HAVE_OID_ENCODING */
6559
6560
#if defined(HAVE_OID_DECODING) || defined(WOLFSSL_ASN_PRINT)
6561
/* Encode dotted form of OID into byte array version.
6562
 *
6563
 * @param [in]      in     Byte array containing OID.
6564
 * @param [in]      inSz   Size of OID in bytes.
6565
 * @param [in]      out    Array to hold dotted form of OID.
6566
 * @param [in, out] outSz  On in, number of elements in array.
6567
 *                         On out, count of numbers in dotted form.
6568
 * @return  0 on success
6569
 * @return  BAD_FUNC_ARG when in or outSz is NULL.
6570
 * @return  BUFFER_E when dotted form buffer too small.
6571
 */
6572
int DecodeObjectId(const byte* in, word32 inSz, word16* out, word32* outSz)
6573
0
{
6574
0
    int x = 0, y = 0;
6575
0
    word32 t = 0;
6576
6577
    /* check args */
6578
0
    if (in == NULL || outSz == NULL) {
6579
0
        return BAD_FUNC_ARG;
6580
0
    }
6581
6582
    /* decode bytes */
6583
0
    while (inSz--) {
6584
0
        t = (t << 7) | (in[x] & 0x7F);
6585
0
        if (!(in[x] & 0x80)) {
6586
0
            if (y >= (int)*outSz) {
6587
0
                return BUFFER_E;
6588
0
            }
6589
0
            if (y == 0) {
6590
0
                out[0] = (word16)(t / 40);
6591
0
                out[1] = (word16)(t % 40);
6592
0
                y = 2;
6593
0
            }
6594
0
            else {
6595
0
                out[y++] = (word16)t;
6596
0
            }
6597
0
            t = 0; /* reset tmp */
6598
0
        }
6599
0
        x++;
6600
0
    }
6601
6602
    /* return length */
6603
0
    *outSz = (word32)y;
6604
6605
0
    return 0;
6606
0
}
6607
#endif /* HAVE_OID_DECODING || WOLFSSL_ASN_PRINT */
6608
6609
/* Decode the header of a BER/DER encoded OBJECT ID.
6610
 *
6611
 * @param [in]      input     Buffer holding DER/BER encoded data.
6612
 * @param [in, out] inOutIdx  On in, starting index of header.
6613
 *                            On out, end of parsed header.
6614
 * @param [out]     len       Number of bytes in the ASN.1 data.
6615
 * @param [in]      maxIdx    Length of data in buffer.
6616
 * @return  0 on success.
6617
 * @return  BUFFER_E when there is not enough data to parse.
6618
 * @return  ASN_PARSE_E when the tag is not a OBJECT ID or length is invalid.
6619
 */
6620
int GetASNObjectId(const byte* input, word32* inOutIdx, int* len, word32 maxIdx)
6621
0
{
6622
0
    int ret = GetASNHeader(input, ASN_OBJECT_ID, inOutIdx, len, maxIdx);
6623
0
    if (ret > 0) {
6624
        /* Only return 0 on success. */
6625
0
        ret = 0;
6626
0
    }
6627
0
    return ret;
6628
0
}
6629
6630
/* Set the DER/BER encoding of the ASN.1 OBJECT ID header.
6631
 *
6632
 * When output is NULL, calculate the header length only.
6633
 *
6634
 * @param [in]  len        Length of OBJECT ID data in bytes.
6635
 * @param [out] output     Buffer to write into.
6636
 * @return  Number of bytes added to the buffer.
6637
 */
6638
int SetObjectId(int len, byte* output)
6639
0
{
6640
0
    int idx = 0;
6641
6642
0
    if (output) {
6643
        /* Write out tag. */
6644
0
        output[idx] = ASN_OBJECT_ID;
6645
0
    }
6646
    /* Skip tag. */
6647
0
    idx += ASN_TAG_SZ;
6648
    /* Encode length - passing NULL for output will not encode. */
6649
0
    idx += (int)SetLength((word32)len, output ? output + idx : NULL);
6650
6651
    /* Return index after header. */
6652
0
    return idx;
6653
0
}
6654
6655
#ifdef ASN_DUMP_OID
6656
/* Dump the OID information.
6657
 *
6658
 * Decode the OID too if function available.
6659
 *
6660
 * @param [in] oidData  OID data from buffer.
6661
 * @param [in] oidSz    Size of OID data in buffer.
6662
 * @param [in] oid      OID id.
6663
 * @param [in] oidType  Type of OID.
6664
 * @return  0 on success.
6665
 * @return  BUFFER_E when not enough bytes for proper decode.
6666
 *          (HAVE_OID_DECODING)
6667
 */
6668
static int DumpOID(const byte* oidData, word32 oidSz, word32 oid,
6669
                   word32 oidType)
6670
{
6671
    int    ret = 0;
6672
    word32 i;
6673
6674
    /* support for dumping OID information */
6675
    printf("OID (Type %d, Sz %d, Sum %d): ", oidType, oidSz, oid);
6676
    /* Dump bytes in decimal. */
6677
    for (i = 0; i < oidSz; i++) {
6678
        printf("%d, ", oidData[i]);
6679
    }
6680
    printf("\n");
6681
    /* Dump bytes in hexadecimal. */
6682
    for (i = 0; i < oidSz; i++) {
6683
        printf("%02x, ", oidData[i]);
6684
    }
6685
    printf("\n");
6686
6687
    #ifdef HAVE_OID_DECODING
6688
    {
6689
        word16 decOid[MAX_OID_SZ];
6690
        word32 decOidSz = sizeof(decOid);
6691
        /* Decode the OID into dotted form. */
6692
        ret = DecodeObjectId(oidData, oidSz, decOid, &decOidSz);
6693
        if (ret == 0) {
6694
            printf("  Decoded (Sz %d): ", decOidSz);
6695
            for (i=0; i<decOidSz; i++) {
6696
                printf("%d.", decOid[i]);
6697
            }
6698
            printf("\n");
6699
        }
6700
        else {
6701
            printf("DecodeObjectId failed: %d\n", ret);
6702
        }
6703
    }
6704
    #endif /* HAVE_OID_DECODING */
6705
6706
    return ret;
6707
}
6708
#endif /* ASN_DUMP_OID */
6709
6710
#ifdef WOLFSSL_OLD_OID_SUM
6711
#ifdef WOLFSSL_FPKI
6712
/* Handles the large number of collisions from FPKI certificate policy
6713
 * OID sums.  Returns a special value (100000 + actual sum) if a
6714
 * collision is detected.
6715
 * @param [in]      oid      Buffer holding OID.
6716
 * @param [in]      oidSz    Length of OID data in buffer.
6717
 * @param [in]      oidSum   The sum of the OID being passed in.
6718
 */
6719
static word32 fpkiCertPolOid(const byte* oid, word32 oidSz, word32 oidSum) {
6720
6721
    switch (oidSum) {
6722
        case CP_ADO_MEDIUM_OID:
6723
            if ((word32)sizeof(extCertPolicyComodoLtdOid) == (word32)oidSz &&
6724
            XMEMCMP(oid, extCertPolicyComodoLtdOid,
6725
            sizeof(extCertPolicyComodoLtdOid)) == 0)
6726
                return CP_COMODO_OID;
6727
            break;
6728
        case CP_FPKI_HIGH_ASSURANCE_OID:
6729
            if ((word32)sizeof(extCertPolicyStateBasicOid) == (word32)oidSz &&
6730
            XMEMCMP(oid, extCertPolicyStateBasicOid,
6731
            sizeof(extCertPolicyStateBasicOid)) == 0)
6732
                return CP_STATE_BASIC_OID;
6733
            break;
6734
        case CP_FPKI_COMMON_DEVICES_HARDWARE_OID:
6735
            if ((word32)sizeof(extCertPolicyDodPeerInteropOid) == (word32)oidSz &&
6736
            XMEMCMP(oid, extCertPolicyDodPeerInteropOid,
6737
            sizeof(extCertPolicyDodPeerInteropOid)) == 0)
6738
                return CP_DOD_PEER_INTEROP_OID;
6739
            break;
6740
        case CP_FPKI_PIV_AUTH_HW_OID:
6741
            if ((word32)sizeof(extCertPolicyDodMediumNpe112Oid) == (word32)oidSz &&
6742
            XMEMCMP(oid, extCertPolicyDodMediumNpe112Oid,
6743
            sizeof(extCertPolicyDodMediumNpe112Oid)) == 0)
6744
                return CP_DOD_MEDIUM_NPE_112_OID;
6745
            else if ((word32)sizeof(extCertPolicyStateMediumDeviceHardwareOid) == (word32)oidSz &&
6746
            XMEMCMP(oid, extCertPolicyStateMediumDeviceHardwareOid,
6747
            sizeof(extCertPolicyStateMediumDeviceHardwareOid)) == 0)
6748
                return CP_STATE_MEDDEVHW_OID;
6749
            break;
6750
        case CP_FPKI_PIVI_AUTH_OID:
6751
            if ((word32)sizeof(extCertPolicyDodMedium128Oid) == (word32)oidSz &&
6752
            XMEMCMP(oid, extCertPolicyDodMedium128Oid,
6753
            sizeof(extCertPolicyDodMedium128Oid)) == 0)
6754
                return CP_DOD_MEDIUM_128_OID;
6755
            break;
6756
        case CP_FPKI_COMMON_PIVI_CONTENT_SIGNING_OID:
6757
            if ((word32)sizeof(extCertPolicyDodMediumHardware112Oid) == (word32)oidSz &&
6758
                XMEMCMP(oid, extCertPolicyDodMediumHardware112Oid,
6759
                sizeof(extCertPolicyDodMediumHardware112Oid)) == 0)
6760
                    return CP_DOD_MEDIUM_HARDWARE_112_OID;
6761
            else if ((word32)sizeof(extCertPolicyCertipathHighhwOid) == (word32)oidSz &&
6762
                XMEMCMP(oid, extCertPolicyCertipathHighhwOid,
6763
                sizeof(extCertPolicyCertipathHighhwOid)) == 0)
6764
                    return CP_CERTIPATH_HIGHHW_OID;
6765
            break;
6766
        case CP_DOD_MEDIUM_OID:
6767
            if ((word32)sizeof(extCertPolicyEcaMediumOid) == (word32)oidSz &&
6768
            XMEMCMP(oid, extCertPolicyEcaMediumOid,
6769
            sizeof(extCertPolicyEcaMediumOid)) == 0)
6770
                return CP_ECA_MEDIUM_OID;
6771
            break;
6772
        case CP_FPKI_COMMON_AUTH_OID:
6773
            if ((word32)sizeof(extCertPolicyEcaMediumSha256Oid) == (word32)oidSz &&
6774
            XMEMCMP(oid, extCertPolicyEcaMediumSha256Oid,
6775
            sizeof(extCertPolicyEcaMediumSha256Oid)) == 0)
6776
                return CP_ECA_MEDIUM_SHA256_OID;
6777
            break;
6778
        case CP_FPKI_MEDIUM_HARDWARE_OID:
6779
            if ((word32)sizeof(extCertPolicyEcaMediumTokenOid) == (word32)oidSz &&
6780
            XMEMCMP(oid, extCertPolicyEcaMediumTokenOid,
6781
            sizeof(extCertPolicyEcaMediumTokenOid)) == 0)
6782
                return CP_ECA_MEDIUM_TOKEN_OID;
6783
            else if ((word32)sizeof(extCertPolicyTreasuryPiviHardwareOid) == (word32)oidSz &&
6784
            XMEMCMP(oid, extCertPolicyTreasuryPiviHardwareOid,
6785
            sizeof(extCertPolicyTreasuryPiviHardwareOid)) == 0)
6786
                return CP_TREAS_PIVI_HW_OID;
6787
            break;
6788
        case CP_DOD_MEDIUM_HARDWARE_OID:
6789
            if ((word32)sizeof(extCertPolicyEcaMediumTokenSha256Oid) == (word32)oidSz &&
6790
            XMEMCMP(oid, extCertPolicyEcaMediumTokenSha256Oid,
6791
            sizeof(extCertPolicyEcaMediumTokenSha256Oid)) == 0)
6792
                return CP_ECA_MEDIUM_TOKEN_SHA256_OID;
6793
            else if ((word32)sizeof(extCertPolicyTreasuryPiviContentSigningOid) == (word32)oidSz &&
6794
            XMEMCMP(oid, extCertPolicyTreasuryPiviContentSigningOid,
6795
            sizeof(extCertPolicyTreasuryPiviContentSigningOid)) == 0)
6796
                return CP_TREAS_PIVI_CONTENT_OID;
6797
            break;
6798
        case CP_DOD_PIV_AUTH_OID:
6799
            if ((word32)sizeof(extCertPolicyEcaMediumHardwarePiviOid) == (word32)oidSz &&
6800
            XMEMCMP(oid, extCertPolicyEcaMediumHardwarePiviOid,
6801
            sizeof(extCertPolicyEcaMediumHardwarePiviOid)) == 0)
6802
                return CP_ECA_MEDIUM_HARDWARE_PIVI_OID;
6803
            else if ((word32)sizeof(extCertPolicyStateMedHwOid) == (word32)oidSz &&
6804
            XMEMCMP(oid, extCertPolicyStateMedHwOid,
6805
            sizeof(extCertPolicyStateMedHwOid)) == 0)
6806
                return CP_STATE_MEDHW_OID;
6807
            break;
6808
        case CP_FPKI_COMMON_HARDWARE_OID:
6809
            if ((word32)sizeof(extCertPolicyStateHighOid) == (word32)oidSz &&
6810
            XMEMCMP(oid, extCertPolicyStateHighOid,
6811
            sizeof(extCertPolicyStateHighOid)) == 0)
6812
                return CP_STATE_HIGH_OID;
6813
            else if ((word32)sizeof(extCertPolicyTreasuryHighOid) == (word32)oidSz &&
6814
            XMEMCMP(oid, extCertPolicyTreasuryHighOid,
6815
            sizeof(extCertPolicyTreasuryHighOid)) == 0)
6816
                return CP_TREAS_HIGH_OID;
6817
            break;
6818
        case CP_ECA_MEDIUM_HARDWARE_OID:
6819
            if ((word32)sizeof(extCertPolicyExostarMediumHardwareSha2Oid) == (word32)oidSz &&
6820
            XMEMCMP(oid, extCertPolicyExostarMediumHardwareSha2Oid,
6821
            sizeof(extCertPolicyExostarMediumHardwareSha2Oid)) == 0)
6822
                return CP_EXOSTAR_MEDIUMHW_SHA2_OID;
6823
            break;
6824
        case CP_ADO_HIGH_OID:
6825
            if ((word32)sizeof(extCertPolicyAdoResourceMediumAssuranceOid) == (word32)oidSz &&
6826
            XMEMCMP(oid, extCertPolicyAdoResourceMediumAssuranceOid,
6827
            sizeof(extCertPolicyAdoResourceMediumAssuranceOid)) == 0)
6828
                return CP_ADO_RESOURCE_MEDIUM_OID;
6829
            break;
6830
        case CP_DOD_ADMIN_OID:
6831
            if ((word32)sizeof(extCertPolicyCarillonAivcontentOid) == (word32)oidSz &&
6832
            XMEMCMP(oid, extCertPolicyCarillonAivcontentOid,
6833
            sizeof(extCertPolicyCarillonAivcontentOid)) == 0)
6834
                return CP_CARILLON_AIVCONTENT_OID;
6835
            break;
6836
        case CP_TREAS_MEDIUMHW_OID:
6837
            if ((word32)sizeof(extCertPolicyStateModerateOid) == (word32)oidSz &&
6838
            XMEMCMP(oid, extCertPolicyStateModerateOid,
6839
            sizeof(extCertPolicyStateModerateOid)) == 0)
6840
                return CP_STATE_MODERATE_OID;
6841
            break;
6842
        case CP_CIS_ICECAP_HW_OID:
6843
            if ((word32)sizeof(extCertPolicyNlModIrrefutabilityOid) == (word32)oidSz &&
6844
            XMEMCMP(oid, extCertPolicyNlModIrrefutabilityOid,
6845
            sizeof(extCertPolicyNlModIrrefutabilityOid)) == 0)
6846
                return CP_NL_MOD_IRREFUT_OID;
6847
            break;
6848
        case CP_DOD_MEDIUM_192_OID:
6849
            if ((word32)sizeof(extCertPolicyCertipathMediumhwOid) == (word32)oidSz &&
6850
            XMEMCMP(oid, extCertPolicyCertipathMediumhwOid,
6851
            sizeof(extCertPolicyCertipathMediumhwOid)) == 0)
6852
                return CP_CERTIPATH_MEDIUMHW_OID;
6853
            break;
6854
        case CP_CARILLON_AIVHW_OID:
6855
            if ((word32)sizeof(extCertPolicyCertipathVarMediumhwOid) == (word32)oidSz &&
6856
            XMEMCMP(oid, extCertPolicyCertipathVarMediumhwOid,
6857
            sizeof(extCertPolicyCertipathVarMediumhwOid)) == 0)
6858
                return CP_CERTIPATH_VAR_MEDIUMHW_OID;
6859
            break;
6860
        case CP_ISRG_DOMAIN_VALID:
6861
            if ((word32)sizeof(extCertPolicyEcaContentSigningPiviOid) == (word32)oidSz &&
6862
            XMEMCMP(oid, extCertPolicyEcaContentSigningPiviOid,
6863
            sizeof(extCertPolicyEcaContentSigningPiviOid)) == 0)
6864
                return CP_ECA_CONTENT_SIGNING_PIVI_OID;
6865
            break;
6866
        default:
6867
            break;
6868
    }
6869
6870
    return 0;
6871
}
6872
#endif
6873
#endif /* WOLFSSL_OLD_OID_SUM */
6874
6875
word32 wc_oid_sum(const byte* input, int length)
6876
0
{
6877
0
    int i;
6878
0
    word32 oid = 0;
6879
0
#ifndef WOLFSSL_OLD_OID_SUM
6880
0
    int shift = 0;
6881
0
#endif
6882
6883
    /* Check for valid input. */
6884
0
    if (input == NULL || length > MAX_OID_SZ) {
6885
0
        WOLFSSL_MSG("wc_oid_sum: invalid args");
6886
0
        return 0;
6887
0
    }
6888
6889
    /* Sum it up for now. */
6890
0
    for (i = 0; i < length; i++) {
6891
    #ifdef WOLFSSL_OLD_OID_SUM
6892
        oid += (word32)input[i];
6893
    #else
6894
0
        oid ^= ((word32)(~input[i])) << shift;
6895
0
        shift = (shift + 8) & 0x1f;
6896
0
    #endif
6897
0
    }
6898
0
#ifndef WOLFSSL_OLD_OID_SUM
6899
0
    oid &= 0x7fffffff;
6900
0
#endif
6901
6902
0
    return oid;
6903
0
}
6904
6905
/* Get the OID data and verify it is of the type specified when compiled in.
6906
 *
6907
 * @param [in]      input     Buffer holding OID.
6908
 * @param [in, out] inOutIdx  On in, starting index of OID.
6909
 *                            On out, end of parsed OID.
6910
 * @param [out]     oid       OID id.
6911
 * @param [in]      oidType   Expected type of OID. Define NO_VERIFY_OID to
6912
 *                            not compile in check.
6913
 * @param [in]      length    Length of OID data in buffer.
6914
 * @return  0 on success.
6915
 * @return  ASN_UNKNOWN_OID_E when OID is not recognized.
6916
 * @return  BUFFER_E when not enough bytes for proper decode. (ASN_DUMP_OID and
6917
 *          HAVE_OID_DECODING)
6918
 */
6919
static int GetOID(const byte* input, word32* inOutIdx, word32* oid,
6920
                  word32 oidType, int length)
6921
0
{
6922
0
    int    ret = 0;
6923
0
    word32 idx = *inOutIdx;
6924
0
#ifndef NO_VERIFY_OID
6925
0
    word32 actualOidSz;
6926
0
    const byte* actualOid;
6927
0
    const byte* checkOid = NULL;
6928
0
    word32 checkOidSz;
6929
0
#endif /* NO_VERIFY_OID */
6930
#ifdef WOLFSSL_OLD_OID_SUM
6931
#if defined(HAVE_SPHINCS) || defined(WOLFSSL_FPKI)
6932
    word32 found_collision = 0;
6933
#endif
6934
#endif
6935
0
    (void)oidType;
6936
0
    *oid = 0;
6937
6938
0
#if !defined(NO_VERIFY_OID) || defined(WOLFSSL_FPKI)
6939
    /* Keep references to OID data and length for check. */
6940
0
    actualOid = &input[idx];
6941
0
    actualOidSz = (word32)length;
6942
0
#endif /* NO_VERIFY_OID */
6943
6944
#ifdef WOLFSSL_OLD_OID_SUM
6945
#if defined(HAVE_SPHINCS)
6946
    /* Since we are summing it up, there could be collisions...and indeed there
6947
     * are: SPHINCS_FAST_LEVEL1 and SPHINCS_FAST_LEVEL3.
6948
     *
6949
     * We will look for the special case of SPHINCS_FAST_LEVEL3 and set *oid to
6950
     * 283 instead of 281; 282 is taken.
6951
     *
6952
     * These hacks will hopefully disappear when new standardized OIDs appear.
6953
     */
6954
    if (idx + (word32)sizeof(sigSphincsFast_Level3Oid) < (word32)length &&
6955
            XMEMCMP(&input[idx], sigSphincsFast_Level3Oid,
6956
               sizeof(sigSphincsFast_Level3Oid)) == 0) {
6957
        found_collision = SPHINCS_FAST_LEVEL3k;
6958
    }
6959
#endif /* HAVE_SPHINCS */
6960
#endif
6961
6962
0
    *oid = wc_oid_sum(actualOid, (int)actualOidSz);
6963
0
    idx += actualOidSz;
6964
6965
#ifdef WOLFSSL_OLD_OID_SUM
6966
#ifdef WOLFSSL_FPKI
6967
    /* Due to the large number of OIDs for FPKI certificate policy, there
6968
       are multiple collsisions.  Handle them in a dedicated function,
6969
       if a collision is detected, the OID is adjusted. */
6970
    if (oidType == oidCertPolicyType) {
6971
        found_collision = fpkiCertPolOid(actualOid, actualOidSz, *oid);
6972
    }
6973
#endif
6974
6975
#if defined(HAVE_SPHINCS) || defined(WOLFSSL_FPKI)
6976
    if (found_collision) {
6977
        *oid = found_collision;
6978
    }
6979
#endif /* HAVE_SPHINCS */
6980
#endif
6981
6982
    /* Return the index after the OID data. */
6983
0
    *inOutIdx = idx;
6984
6985
0
#ifndef NO_VERIFY_OID
6986
    /* 'Ignore' type means we don't care which OID it is. */
6987
0
    if (oidType != oidIgnoreType) {
6988
        /* Get the OID data for the id-type. */
6989
0
        checkOid = OidFromId(*oid, oidType, &checkOidSz);
6990
6991
#ifdef WOLFSSL_OLD_OID_SUM
6992
    #if defined(WOLFSSL_FPKI)
6993
        /* Handle OID sum collision of
6994
            AES256CBCb (454) 2.16.840.1.101.3.4.1.42
6995
            CP_FPKI_PIV_AUTH_HW_OID (454) 2.16.840.1.101.3.2.1.3.41
6996
        */
6997
        #if defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
6998
        if ((actualOidSz == (word32)sizeof(blkAes256CbcOid)) &&
6999
                (XMEMCMP(actualOid, blkAes256CbcOid,
7000
                 sizeof(blkAes256CbcOid)) == 0)) {
7001
7002
            checkOid   = blkAes256CbcOid;
7003
            checkOidSz = sizeof(blkAes256CbcOid);
7004
        }
7005
        #endif /* HAVE_AES_CBC */
7006
    #endif /* WOLFSSL_FPKI */
7007
#endif
7008
7009
    #ifdef ASN_DUMP_OID
7010
        /* Dump out the data for debug. */
7011
        ret = DumpOID(actualOid, actualOidSz, *oid, oidType);
7012
    #endif
7013
7014
        /* TODO: Want to fail when checkOid is NULL.
7015
         * Can't as too many situations where unknown OID is to be
7016
         * supported. Extra parameter for must not be NULL?
7017
         */
7018
        /* Check that the OID data matches what we found for the OID id. */
7019
0
        if ((ret == 0) && (checkOid != NULL) && ((checkOidSz != actualOidSz) ||
7020
0
                (XMEMCMP(actualOid, checkOid, checkOidSz) != 0))) {
7021
0
            WOLFSSL_MSG("OID Check Failed");
7022
0
            WOLFSSL_ERROR_VERBOSE(ASN_UNKNOWN_OID_E);
7023
0
            ret = ASN_UNKNOWN_OID_E;
7024
0
        }
7025
0
    }
7026
0
#endif /* NO_VERIFY_OID */
7027
7028
0
    return ret;
7029
0
}
7030
7031
#ifdef WOLFSSL_ASN_TEMPLATE
7032
/* ASN.1 template for an OBJECT_ID. */
7033
static const ASNItem objectIdASN[] = {
7034
/* OID */ { 0, ASN_OBJECT_ID, 0, 0, 0 }
7035
};
7036
enum {
7037
    OBJECTIDASN_IDX_OID = 0
7038
};
7039
7040
/* Number of items in ASN.1 template for an OBJECT_ID. */
7041
0
#define objectIdASN_Length (sizeof(objectIdASN) / sizeof(ASNItem))
7042
#endif
7043
7044
/* Get the OID id/sum from the BER encoded OBJECT_ID.
7045
 *
7046
 * @param [in]      input     Buffer holding BER encoded data.
7047
 * @param [in, out] inOutIdx  On in, start of OBJECT_ID.
7048
 *                            On out, start of ASN.1 item after OBJECT_ID.
7049
 * @param [out]     oid       Id of OID in OBJECT_ID data.
7050
 * @param [in]      oidType   Type of OID to expect.
7051
 * @param [in]      maxIdx    Maximum index of data in buffer.
7052
 * @return  0 on success.
7053
 * @return  ASN_PARSE_E when encoding is invalid.
7054
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
7055
 */
7056
int GetObjectId(const byte* input, word32* inOutIdx, word32* oid,
7057
                                  word32 oidType, word32 maxIdx)
7058
0
{
7059
#ifndef WOLFSSL_ASN_TEMPLATE
7060
    int ret, length;
7061
7062
    WOLFSSL_ENTER("GetObjectId");
7063
7064
    ret = GetASNObjectId(input, inOutIdx, &length, maxIdx);
7065
    if (ret != 0)
7066
        return ret;
7067
7068
    return GetOID(input, inOutIdx, oid, oidType, length);
7069
#else
7070
0
    ASNGetData dataASN[objectIdASN_Length];
7071
0
    int ret;
7072
7073
0
    WOLFSSL_ENTER("GetObjectId");
7074
7075
    /* Clear dynamic data and set OID type expected. */
7076
0
    XMEMSET(dataASN, 0, sizeof(dataASN));
7077
0
    GetASN_OID(&dataASN[OBJECTIDASN_IDX_OID], oidType);
7078
    /* Decode OBJECT_ID. */
7079
0
    ret = GetASN_Items(objectIdASN, dataASN, objectIdASN_Length, 0, input,
7080
0
                       inOutIdx, maxIdx);
7081
0
    if (ret == 0) {
7082
        /* Return the id/sum. */
7083
0
        *oid = dataASN[OBJECTIDASN_IDX_OID].data.oid.sum;
7084
0
    }
7085
7086
0
    return ret;
7087
0
#endif /* WOLFSSL_ASN_TEMPLATE */
7088
0
}
7089
7090
#ifndef WOLFSSL_ASN_TEMPLATE
7091
static int SkipObjectId(const byte* input, word32* inOutIdx, word32 maxIdx)
7092
{
7093
    word32 idx = *inOutIdx;
7094
    int    length;
7095
    int ret;
7096
7097
    ret = GetASNObjectId(input, &idx, &length, maxIdx);
7098
    if (ret != 0)
7099
        return ret;
7100
7101
    idx += (word32)length;
7102
    *inOutIdx = idx;
7103
7104
    return 0;
7105
}
7106
#endif
7107
7108
#ifdef WOLFSSL_ASN_TEMPLATE
7109
/* ASN.1 template for an algorithm identifier. */
7110
static const ASNItem algoIdASN[] = {
7111
/*  SEQ  */    { 0, ASN_SEQUENCE, 1, 1, 0 },
7112
/*  OID  */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
7113
/*  NULL */        { 1, ASN_TAG_NULL, 0, 0, 1 },
7114
};
7115
enum {
7116
    ALGOIDASN_IDX_SEQ = 0,
7117
    ALGOIDASN_IDX_OID,
7118
    ALGOIDASN_IDX_NULL
7119
};
7120
7121
/* Number of items in ASN.1 template for an algorithm identifier. */
7122
0
#define algoIdASN_Length (sizeof(algoIdASN) / sizeof(ASNItem))
7123
#endif
7124
7125
static int GetAlgoIdImpl(const byte* input, word32* inOutIdx, word32* oid,
7126
                     word32 oidType, word32 maxIdx, byte *absentParams)
7127
0
{
7128
#ifndef WOLFSSL_ASN_TEMPLATE
7129
    int    length;
7130
    word32 idx = *inOutIdx;
7131
    int    ret;
7132
    *oid = 0;
7133
7134
    WOLFSSL_ENTER("GetAlgoId");
7135
7136
    if (GetSequence(input, &idx, &length, maxIdx) < 0)
7137
        return ASN_PARSE_E;
7138
7139
    if (GetObjectId(input, &idx, oid, oidType, maxIdx) < 0)
7140
        return ASN_OBJECT_ID_E;
7141
7142
    /* could have NULL tag and 0 terminator, but may not */
7143
    if (idx < maxIdx) {
7144
        word32 localIdx = idx; /*use localIdx to not advance when checking tag*/
7145
        byte   tag;
7146
7147
        if (GetASNTag(input, &localIdx, &tag, maxIdx) == 0) {
7148
            if (tag == ASN_TAG_NULL) {
7149
                ret = GetASNNull(input, &idx, maxIdx);
7150
                if (ret != 0)
7151
                    return ret;
7152
7153
                if (absentParams != NULL) {
7154
                    *absentParams = FALSE;
7155
                }
7156
            }
7157
        }
7158
    }
7159
7160
    *inOutIdx = idx;
7161
7162
    return 0;
7163
#else
7164
0
    DECL_ASNGETDATA(dataASN, algoIdASN_Length);
7165
0
    int ret = 0;
7166
7167
0
    WOLFSSL_ENTER("GetAlgoId");
7168
7169
0
    CALLOC_ASNGETDATA(dataASN, algoIdASN_Length, ret, NULL);
7170
0
    if (ret == 0) {
7171
        /* Set OID type expected. */
7172
0
        GetASN_OID(&dataASN[ALGOIDASN_IDX_OID], oidType);
7173
        /* Decode the algorithm identifier. */
7174
0
        ret = GetASN_Items(algoIdASN, dataASN, algoIdASN_Length, 0, input,
7175
0
            inOutIdx, maxIdx);
7176
0
    }
7177
0
    if (ret == 0) {
7178
        /* Return the OID id/sum. */
7179
0
        *oid = dataASN[ALGOIDASN_IDX_OID].data.oid.sum;
7180
7181
0
        if ((absentParams != NULL) &&
7182
0
            (dataASN[ALGOIDASN_IDX_NULL].tag == ASN_TAG_NULL)) {
7183
0
            *absentParams = FALSE;
7184
0
        }
7185
0
    }
7186
7187
0
    FREE_ASNGETDATA(dataASN, NULL);
7188
0
    return ret;
7189
0
#endif /* WOLFSSL_ASN_TEMPLATE */
7190
0
}
7191
7192
/* Get the OID id/sum from the BER encoding of an algorithm identifier.
7193
 *
7194
 * NULL tag is skipped if present.
7195
 *
7196
 * @param [in]      input     Buffer holding BER encoded data.
7197
 * @param [in, out] inOutIdx  On in, start of algorithm identifier.
7198
 *                            On out, start of ASN.1 item after algorithm id.
7199
 * @param [out]     oid       Id of OID in algorithm identifier data.
7200
 * @param [in]      oidType   Type of OID to expect.
7201
 * @param [in]      maxIdx    Maximum index of data in buffer.
7202
 * @return  0 on success.
7203
 * @return  ASN_PARSE_E when encoding is invalid.
7204
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
7205
 */
7206
int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid,
7207
                     word32 oidType, word32 maxIdx)
7208
0
{
7209
0
    return GetAlgoIdImpl(input, inOutIdx, oid, oidType, maxIdx, NULL);
7210
0
}
7211
7212
int GetAlgoIdEx(const byte* input, word32* inOutIdx, word32* oid,
7213
                     word32 oidType, word32 maxIdx, byte *absentParams)
7214
0
{
7215
    /* Assume absent until proven otherwise */
7216
0
    if (absentParams != NULL) {
7217
0
        *absentParams = TRUE;
7218
0
    }
7219
7220
0
    return GetAlgoIdImpl(input, inOutIdx, oid, oidType, maxIdx, absentParams);
7221
0
}
7222
7223
#ifndef NO_RSA
7224
7225
#ifdef WC_RSA_PSS
7226
/* RFC 8017 - PKCS #1 has RSA PSS parameter ASN definition. */
7227
7228
/* Convert a hash OID to a hash type.
7229
 *
7230
 * @param  [in]   oid   Hash OID.
7231
 * @param  [out]  type  Hash type.
7232
 * @return  0 on success.
7233
 * @return  ASN_PARSE_E when hash OID not supported for RSA PSS.
7234
 */
7235
static int RsaPssHashOidToType(word32 oid, enum wc_HashType* type)
7236
0
{
7237
0
    int ret = 0;
7238
7239
0
    switch (oid) {
7240
    /* SHA-1 is missing as it is the default is not allowed to appear. */
7241
0
#ifdef WOLFSSL_SHA224
7242
0
    case SHA224h:
7243
0
        *type = WC_HASH_TYPE_SHA224;
7244
0
        break;
7245
0
#endif
7246
0
#ifndef NO_SHA256
7247
0
    case SHA256h:
7248
0
        *type = WC_HASH_TYPE_SHA256;
7249
0
        break;
7250
0
#endif
7251
0
#ifdef WOLFSSL_SHA384
7252
0
    case SHA384h:
7253
0
        *type = WC_HASH_TYPE_SHA384;
7254
0
        break;
7255
0
#endif
7256
0
#ifdef WOLFSSL_SHA512
7257
0
    case SHA512h:
7258
0
        *type = WC_HASH_TYPE_SHA512;
7259
0
        break;
7260
    /* TODO: SHA512_224h */
7261
    /* TODO: SHA512_256h */
7262
0
#endif
7263
0
    default:
7264
0
        ret = ASN_PARSE_E;
7265
0
        break;
7266
0
    }
7267
7268
0
    return ret;
7269
0
}
7270
7271
/* Convert a hash OID to a MGF1 type.
7272
 *
7273
 * @param  [in]   oid   Hash OID.
7274
 * @param  [out]  mgf   MGF type.
7275
 * @return  0 on success.
7276
 * @return  ASN_PARSE_E when hash OID not supported for RSA PSS.
7277
 */
7278
static int RsaPssHashOidToMgf1(word32 oid, int* mgf)
7279
0
{
7280
0
    int ret = 0;
7281
7282
0
    switch (oid) {
7283
    /* SHA-1 is missing as it is the default is not allowed to appear. */
7284
0
#ifdef WOLFSSL_SHA224
7285
0
    case SHA224h:
7286
0
        *mgf = WC_MGF1SHA224;
7287
0
        break;
7288
0
#endif
7289
0
#ifndef NO_SHA256
7290
0
    case SHA256h:
7291
0
        *mgf = WC_MGF1SHA256;
7292
0
        break;
7293
0
#endif
7294
0
#ifdef WOLFSSL_SHA384
7295
0
    case SHA384h:
7296
0
        *mgf = WC_MGF1SHA384;
7297
0
        break;
7298
0
#endif
7299
0
#ifdef WOLFSSL_SHA512
7300
0
    case SHA512h:
7301
0
        *mgf = WC_MGF1SHA512;
7302
0
        break;
7303
    /* TODO: SHA512_224h */
7304
    /* TODO: SHA512_256h */
7305
0
#endif
7306
0
    default:
7307
0
        ret = ASN_PARSE_E;
7308
0
        break;
7309
0
    }
7310
7311
0
    return ret;
7312
0
}
7313
7314
#if !defined(NO_CERTS) && !defined(NO_ASN_CRYPT)
7315
7316
/* Convert a hash OID to a fake signature OID.
7317
 *
7318
 * @param  [in]   oid     Hash OID.
7319
 * @param  [out]  sigOid  Signature OID to pass wto HashForSignature().
7320
 * @return  0 on success.
7321
 * @return  ASN_PARSE_E when hash OID not supported for RSA PSS.
7322
 */
7323
static int RsaPssHashOidToSigOid(word32 oid, word32* sigOid)
7324
0
{
7325
0
    int ret = 0;
7326
7327
0
    switch (oid) {
7328
0
#ifndef NO_SHA
7329
0
    case WC_HASH_TYPE_SHA:
7330
0
        *sigOid = CTC_SHAwRSA;
7331
0
        break;
7332
0
#endif
7333
0
#ifdef WOLFSSL_SHA224
7334
0
    case WC_HASH_TYPE_SHA224:
7335
0
        *sigOid = CTC_SHA224wRSA;
7336
0
        break;
7337
0
#endif
7338
0
#ifndef NO_SHA256
7339
0
    case WC_HASH_TYPE_SHA256:
7340
0
        *sigOid = CTC_SHA256wRSA;
7341
0
        break;
7342
0
#endif
7343
0
#ifdef WOLFSSL_SHA384
7344
0
    case WC_HASH_TYPE_SHA384:
7345
0
        *sigOid = CTC_SHA384wRSA;
7346
0
        break;
7347
0
#endif
7348
0
#ifdef WOLFSSL_SHA512
7349
0
    case WC_HASH_TYPE_SHA512:
7350
0
        *sigOid = CTC_SHA512wRSA;
7351
0
        break;
7352
0
#endif
7353
    /* TODO: SHA512_224h */
7354
    /* TODO: SHA512_256h */
7355
    /* Not supported by HashForSignature() */
7356
0
    default:
7357
0
        ret = ASN_PARSE_E;
7358
0
        break;
7359
0
    }
7360
7361
0
    return ret;
7362
0
}
7363
#endif
7364
7365
#ifdef WOLFSSL_ASN_TEMPLATE
7366
/* ASN tag for hashAlgorithm. */
7367
#define ASN_TAG_RSA_PSS_HASH        (ASN_CONTEXT_SPECIFIC | 0)
7368
/* ASN tag for maskGenAlgorithm. */
7369
#define ASN_TAG_RSA_PSS_MGF         (ASN_CONTEXT_SPECIFIC | 1)
7370
/* ASN tag for saltLength. */
7371
#define ASN_TAG_RSA_PSS_SALTLEN     (ASN_CONTEXT_SPECIFIC | 2)
7372
/* ASN tag for trailerField. */
7373
#define ASN_TAG_RSA_PSS_TRAILER     (ASN_CONTEXT_SPECIFIC | 3)
7374
7375
/* ASN.1 template for RSA PSS parameters. */
7376
static const ASNItem rsaPssParamsASN[] = {
7377
/*  SEQ         */  { 0, ASN_SEQUENCE, 1, 1, 0 },
7378
/*  HASH        */      { 1, ASN_TAG_RSA_PSS_HASH, 1, 1, 1 },
7379
/*  HASHSEQ     */          { 2, ASN_SEQUENCE, 1, 1, 0 },
7380
/*  HASHOID     */              { 3, ASN_OBJECT_ID, 0, 0, 0 },
7381
/*  HASHNULL    */              { 3, ASN_TAG_NULL, 0, 0, 1 },
7382
/*  MGF         */      { 1, ASN_TAG_RSA_PSS_MGF, 1, 1, 1 },
7383
/*  MGFSEQ      */          { 2, ASN_SEQUENCE, 1, 1, 0 },
7384
/*  MGFOID      */              { 3, ASN_OBJECT_ID, 0, 0, 0 },
7385
/*  MGFPARAM    */              { 3, ASN_SEQUENCE, 1, 1, 0 },
7386
/*  MGFHOID     */                  { 4, ASN_OBJECT_ID, 0, 0, 0 },
7387
/*  MGFHNULL    */                  { 4, ASN_TAG_NULL, 0, 0, 1 },
7388
/*  SALTLEN     */      { 1, ASN_TAG_RSA_PSS_SALTLEN, 1, 1, 1 },
7389
/*  SALTLENINT  */          { 2, ASN_INTEGER, 0, 0, 0 },
7390
/*  TRAILER     */      { 1, ASN_TAG_RSA_PSS_TRAILER, 1, 1, 1 },
7391
/*  TRAILERINT  */          { 2, ASN_INTEGER, 0, 0, 0 },
7392
};
7393
enum {
7394
    RSAPSSPARAMSASN_IDX_SEQ = 0,
7395
    RSAPSSPARAMSASN_IDX_HASH,
7396
    RSAPSSPARAMSASN_IDX_HASHSEQ,
7397
    RSAPSSPARAMSASN_IDX_HASHOID,
7398
    RSAPSSPARAMSASN_IDX_HASHNULL,
7399
    RSAPSSPARAMSASN_IDX_MGF,
7400
    RSAPSSPARAMSASN_IDX_MGFSEQ,
7401
    RSAPSSPARAMSASN_IDX_MGFOID,
7402
    RSAPSSPARAMSASN_IDX_MGFPARAM,
7403
    RSAPSSPARAMSASN_IDX_MGFHOID,
7404
    RSAPSSPARAMSASN_IDX_MGFHNULL,
7405
    RSAPSSPARAMSASN_IDX_SALTLEN,
7406
    RSAPSSPARAMSASN_IDX_SALTLENINT,
7407
    RSAPSSPARAMSASN_IDX_TRAILER,
7408
    RSAPSSPARAMSASN_IDX_TRAILERINT
7409
};
7410
7411
/* Number of items in ASN.1 template for an algorithm identifier. */
7412
0
#define rsaPssParamsASN_Length (sizeof(rsaPssParamsASN) / sizeof(ASNItem))
7413
#else
7414
/* ASN tag for hashAlgorithm. */
7415
#define ASN_TAG_RSA_PSS_HASH        (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)
7416
/* ASN tag for maskGenAlgorithm. */
7417
#define ASN_TAG_RSA_PSS_MGF         (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)
7418
/* ASN tag for saltLength. */
7419
#define ASN_TAG_RSA_PSS_SALTLEN     (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)
7420
/* ASN tag for trailerField. */
7421
#define ASN_TAG_RSA_PSS_TRAILER     (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 3)
7422
#endif
7423
7424
/* Decode the RSA PSS parameters.
7425
 *
7426
 * @param  [in]   params   Buffer holding BER encoded RSA PSS parameters.
7427
 * @param  [in]   sz       Size of data in buffer in bytes.
7428
 * @param  [out]  hash     Hash algorithm to use on message.
7429
 * @param  [out]  mgf      MGF algorithm to use with PSS padding.
7430
 * @param  [out]  saltLen  Length of salt in PSS padding.
7431
 * @return  BAD_FUNC_ARG when the params is NULL.
7432
 * @return  ASN_PARSE_E when the decoding fails.
7433
 * @return  0 on success.
7434
 */
7435
static int DecodeRsaPssParams(const byte* params, word32 sz,
7436
    enum wc_HashType* hash, int* mgf, int* saltLen)
7437
0
{
7438
#ifndef WOLFSSL_ASN_TEMPLATE
7439
    int ret = 0;
7440
    word32 idx = 0;
7441
    int len = 0;
7442
    word32 oid = 0;
7443
    byte tag;
7444
    int length;
7445
7446
    if (params == NULL) {
7447
        ret = BAD_FUNC_ARG;
7448
    }
7449
    if ((ret == 0) && (GetSequence_ex(params, &idx, &len, sz, 1) < 0)) {
7450
        ret = ASN_PARSE_E;
7451
    }
7452
    if (ret == 0) {
7453
        if ((idx < sz) && (params[idx] == ASN_TAG_RSA_PSS_HASH)) {
7454
            /* Hash algorithm to use on message. */
7455
            if (GetHeader(params, &tag, &idx, &length, sz, 0) < 0) {
7456
                ret = ASN_PARSE_E;
7457
            }
7458
            if (ret == 0) {
7459
                if (GetAlgoId(params, &idx, &oid, oidHashType, sz) < 0) {
7460
                    ret = ASN_PARSE_E;
7461
                }
7462
            }
7463
            if (ret == 0) {
7464
                ret = RsaPssHashOidToType(oid, hash);
7465
            }
7466
        }
7467
        else {
7468
            /* Default hash algorithm. */
7469
            *hash = WC_HASH_TYPE_SHA;
7470
        }
7471
    }
7472
    if (ret == 0) {
7473
        if ((idx < sz) && (params[idx] == ASN_TAG_RSA_PSS_MGF)) {
7474
            /* MGF and hash algorithm to use with padding. */
7475
            if (GetHeader(params, &tag, &idx, &length, sz, 0) < 0) {
7476
                ret = ASN_PARSE_E;
7477
            }
7478
            if (ret == 0) {
7479
                if (GetAlgoId(params, &idx, &oid, oidIgnoreType, sz) < 0) {
7480
                    ret = ASN_PARSE_E;
7481
                }
7482
            }
7483
            if ((ret == 0) && (oid != MGF1_OID)) {
7484
                ret = ASN_PARSE_E;
7485
            }
7486
            if (ret == 0) {
7487
                ret = GetAlgoId(params, &idx, &oid, oidHashType, sz);
7488
                if (ret == 0) {
7489
                    ret = RsaPssHashOidToMgf1(oid, mgf);
7490
                }
7491
            }
7492
        }
7493
        else {
7494
            /* Default MGF/Hash algorithm. */
7495
            *mgf = WC_MGF1SHA1;
7496
        }
7497
    }
7498
    if (ret == 0) {
7499
        if ((idx < sz) && (params[idx] == ASN_TAG_RSA_PSS_SALTLEN)) {
7500
            /* Salt length to use with padding. */
7501
            if (GetHeader(params, &tag, &idx, &length, sz, 0) < 0) {
7502
                ret = ASN_PARSE_E;
7503
            }
7504
            if (ret == 0) {
7505
                ret = GetInteger16Bit(params, &idx, sz);
7506
                if (ret >= 0) {
7507
                    *saltLen = ret;
7508
                    ret = 0;
7509
                }
7510
            }
7511
        }
7512
        else {
7513
            /* Default salt length. */
7514
            *saltLen = 20;
7515
        }
7516
    }
7517
    if (ret == 0) {
7518
        if ((idx < sz) && (params[idx] == ASN_TAG_RSA_PSS_TRAILER)) {
7519
            /* Unused - trialerField. */
7520
            if (GetHeader(params, &tag, &idx, &length, sz, 0) < 0) {
7521
                ret = ASN_PARSE_E;
7522
            }
7523
            if (ret == 0) {
7524
                ret = GetInteger16Bit(params, &idx, sz);
7525
                if (ret > 0) {
7526
                    ret = 0;
7527
                }
7528
            }
7529
        }
7530
    }
7531
    if ((ret == 0) && (idx != sz)) {
7532
        ret = ASN_PARSE_E;
7533
    }
7534
7535
    return ret;
7536
#else
7537
0
    DECL_ASNGETDATA(dataASN, rsaPssParamsASN_Length);
7538
0
    int ret = 0;
7539
0
    word16 sLen = 20;
7540
7541
0
    if (params == NULL) {
7542
0
        ret = BAD_FUNC_ARG;
7543
0
    }
7544
7545
0
    CALLOC_ASNGETDATA(dataASN, rsaPssParamsASN_Length, ret, NULL);
7546
0
    if (ret == 0) {
7547
0
        word32 inOutIdx = 0;
7548
        /* Default values. */
7549
0
        *hash = WC_HASH_TYPE_SHA;
7550
0
        *mgf = WC_MGF1SHA1;
7551
7552
        /* Set OID type expected. */
7553
0
        GetASN_OID(&dataASN[RSAPSSPARAMSASN_IDX_HASHOID], oidHashType);
7554
0
        GetASN_OID(&dataASN[RSAPSSPARAMSASN_IDX_MGFHOID], oidHashType);
7555
        /* Place the salt length into 16-bit var sLen. */
7556
0
        GetASN_Int16Bit(&dataASN[RSAPSSPARAMSASN_IDX_SALTLENINT], &sLen);
7557
        /* Decode the algorithm identifier. */
7558
0
        ret = GetASN_Items(rsaPssParamsASN, dataASN, rsaPssParamsASN_Length, 1,
7559
0
            params, &inOutIdx, sz);
7560
0
    }
7561
0
    if ((ret == 0) && (dataASN[RSAPSSPARAMSASN_IDX_HASHOID].tag != 0)) {
7562
0
        word32 oid = dataASN[RSAPSSPARAMSASN_IDX_HASHOID].data.oid.sum;
7563
0
        ret = RsaPssHashOidToType(oid, hash);
7564
0
    }
7565
0
    if ((ret == 0) && (dataASN[RSAPSSPARAMSASN_IDX_MGFHOID].tag != 0)) {
7566
0
        word32 oid = dataASN[RSAPSSPARAMSASN_IDX_MGFHOID].data.oid.sum;
7567
0
        ret = RsaPssHashOidToMgf1(oid, mgf);
7568
0
    }
7569
0
    if (ret == 0) {
7570
0
        *saltLen = sLen;
7571
0
    }
7572
7573
0
    FREE_ASNGETDATA(dataASN, NULL);
7574
0
    return ret;
7575
0
#endif /* WOLFSSL_ASN_TEMPLATE */
7576
0
}
7577
#endif /* WC_RSA_PSS */
7578
7579
#if defined(WOLFSSL_ASN_TEMPLATE) || (!defined(NO_CERTS) && \
7580
    (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || \
7581
     defined(WOLFSSL_KCAPI_RSA) || defined(WOLFSSL_SE050)))
7582
/* Byte offset of numbers in RSA key. */
7583
size_t rsaIntOffset[] = {
7584
    WC_OFFSETOF(RsaKey, n),
7585
    WC_OFFSETOF(RsaKey, e),
7586
#ifndef WOLFSSL_RSA_PUBLIC_ONLY
7587
    WC_OFFSETOF(RsaKey, d),
7588
    WC_OFFSETOF(RsaKey, p),
7589
    WC_OFFSETOF(RsaKey, q),
7590
#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)
7591
    WC_OFFSETOF(RsaKey, dP),
7592
    WC_OFFSETOF(RsaKey, dQ),
7593
    WC_OFFSETOF(RsaKey, u)
7594
#endif
7595
#endif
7596
};
7597
7598
/* Get a number from the RSA key based on an index.
7599
 *
7600
 * Order: { n, e, d, p, q, dP, dQ, u }
7601
 *
7602
 * Caller must ensure index is not invalid!
7603
 *
7604
 * @param [in] key  RSA key object.
7605
 * @param [in] idx  Index of number.
7606
 * @return  A pointer to an mp_int when valid index.
7607
 * @return  NULL when invalid index.
7608
 */
7609
static mp_int* GetRsaInt(RsaKey* key, int idx)
7610
0
{
7611
    /* Cast key to byte array to and use offset to get to mp_int field. */
7612
0
    return (mp_int*)(((byte*)key) + rsaIntOffset[idx]);
7613
0
}
7614
#endif
7615
7616
#ifdef WOLFSSL_ASN_TEMPLATE
7617
/* ASN.1 template for an RSA private key.
7618
 * PKCS #1: RFC 8017, A.1.2 - RSAPrivateKey
7619
 */
7620
static const ASNItem rsaKeyASN[] = {
7621
/*  SEQ */    { 0, ASN_SEQUENCE, 1, 1, 0 },
7622
/*  VER */        { 1, ASN_INTEGER, 0, 0, 0 },
7623
                /* Integers need to be in this specific order
7624
                 * as asn code depends on this. */
7625
/*  N   */        { 1, ASN_INTEGER, 0, 0, 0 },
7626
/*  E   */        { 1, ASN_INTEGER, 0, 0, 0 },
7627
#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) || defined(WOLFSSL_KEY_GEN)
7628
/*  D   */        { 1, ASN_INTEGER, 0, 0, 0 },
7629
/*  P   */        { 1, ASN_INTEGER, 0, 0, 0 },
7630
/*  Q   */        { 1, ASN_INTEGER, 0, 0, 0 },
7631
/*  DP  */        { 1, ASN_INTEGER, 0, 0, 0 },
7632
/*  DQ  */        { 1, ASN_INTEGER, 0, 0, 0 },
7633
/*  U   */        { 1, ASN_INTEGER, 0, 0, 0 },
7634
                /* otherPrimeInfos  OtherPrimeInfos OPTIONAL
7635
                 * v2 - multiprime */
7636
#endif
7637
};
7638
enum {
7639
    RSAKEYASN_IDX_SEQ = 0,
7640
    RSAKEYASN_IDX_VER,
7641
    /* Integers need to be in this specific order
7642
     * as asn code depends on this. */
7643
    RSAKEYASN_IDX_N,
7644
    RSAKEYASN_IDX_E,
7645
#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) || defined(WOLFSSL_KEY_GEN)
7646
    RSAKEYASN_IDX_D,
7647
    RSAKEYASN_IDX_P,
7648
    RSAKEYASN_IDX_Q,
7649
    RSAKEYASN_IDX_DP,
7650
    RSAKEYASN_IDX_DQ,
7651
    RSAKEYASN_IDX_U,
7652
#endif
7653
    WOLF_ENUM_DUMMY_LAST_ELEMENT(RSAKEYASN_IDX)
7654
};
7655
7656
/* Number of items in ASN.1 template for an RSA private key. */
7657
0
#define rsaKeyASN_Length (sizeof(rsaKeyASN) / sizeof(ASNItem))
7658
#endif
7659
7660
/* Decode RSA private key.
7661
 *
7662
 * PKCS #1: RFC 8017, A.1.2 - RSAPrivateKey
7663
 *
7664
 * Compiling with WOLFSSL_RSA_PUBLIC_ONLY will result in only the public fields
7665
 * being extracted.
7666
 *
7667
 * @param [in]      input     Buffer holding BER encoded data.
7668
 * @param [in, out] inOutIdx  On in, start of RSA private key.
7669
 *                            On out, start of ASN.1 item after RSA private key.
7670
 * @param [in, out] key       RSA key object. May be NULL.
7671
 * @param [out]     keySz     Size of key in bytes. May be NULL.
7672
 * @param [in]      inSz      Number of bytes in buffer.
7673
 * @return  0 on success.
7674
 * @return  BAD_FUNC_ARG when input or inOutIdx is NULL.
7675
 * @return  BAD_FUNC_ARG when key and keySz are NULL.
7676
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
7677
 *          is invalid.
7678
 * @return  BUFFER_E when data in buffer is too small.
7679
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
7680
 *          non-zero length.
7681
 * @return  MP_INIT_E when the unable to initialize an mp_int.
7682
 * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
7683
 */
7684
static int _RsaPrivateKeyDecode(const byte* input, word32* inOutIdx,
7685
    RsaKey* key, int* keySz, word32 inSz)
7686
0
{
7687
#ifndef WOLFSSL_ASN_TEMPLATE
7688
    int version, length;
7689
    word32 algId = 0;
7690
7691
    if (inOutIdx == NULL || input == NULL || (key == NULL && keySz == NULL)) {
7692
        return BAD_FUNC_ARG;
7693
    }
7694
7695
    /* if has pkcs8 header skip it */
7696
    if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) {
7697
        /* ignore error, did not have pkcs8 header */
7698
    }
7699
7700
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
7701
        return ASN_PARSE_E;
7702
7703
    if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
7704
        return ASN_PARSE_E;
7705
7706
    if (key == NULL) {
7707
        int i;
7708
7709
        /* Modulus */
7710
        if (GetASNInt(input, inOutIdx, keySz, inSz) < 0) {
7711
            return ASN_PARSE_E;
7712
        }
7713
        *inOutIdx += (word32)*keySz;
7714
        for (i = 1; i < RSA_INTS; i++) {
7715
            if (SkipInt(input, inOutIdx, inSz) < 0) {
7716
                return ASN_RSA_KEY_E;
7717
            }
7718
        }
7719
    }
7720
    else {
7721
        key->type = RSA_PRIVATE;
7722
7723
    #ifdef WOLFSSL_CHECK_MEM_ZERO
7724
        mp_memzero_add("Decode RSA key d", &key->d);
7725
        mp_memzero_add("Decode RSA key p", &key->p);
7726
        mp_memzero_add("Decode RSA key q", &key->q);
7727
    #if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || \
7728
        !defined(RSA_LOW_MEM)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
7729
        mp_memzero_add("Decode RSA key dP", &key->dP);
7730
        mp_memzero_add("Decode RSA key dQ", &key->dQ);
7731
        mp_memzero_add("Decode RSA key u", &key->u);
7732
    #endif
7733
    #endif
7734
7735
        if (GetInt(&key->n,  input, inOutIdx, inSz) < 0 ||
7736
            GetInt(&key->e,  input, inOutIdx, inSz) < 0 ||
7737
    #ifndef WOLFSSL_RSA_PUBLIC_ONLY
7738
            GetInt(&key->d,  input, inOutIdx, inSz) < 0 ||
7739
            GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
7740
            GetInt(&key->q,  input, inOutIdx, inSz) < 0
7741
    #else
7742
            SkipInt(input, inOutIdx, inSz) < 0 ||
7743
            SkipInt(input, inOutIdx, inSz) < 0 ||
7744
            SkipInt(input, inOutIdx, inSz) < 0
7745
    #endif
7746
           ) {
7747
                return ASN_RSA_KEY_E;
7748
           }
7749
    #if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)) \
7750
        && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
7751
        if (GetInt(&key->dP, input, inOutIdx, inSz) < 0 ||
7752
            GetInt(&key->dQ, input, inOutIdx, inSz) < 0 ||
7753
            GetInt(&key->u,  input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;
7754
    #else
7755
        if (SkipInt(input, inOutIdx, inSz) < 0 ||
7756
            SkipInt(input, inOutIdx, inSz) < 0 ||
7757
            SkipInt(input, inOutIdx, inSz) < 0 )  return ASN_RSA_KEY_E;
7758
    #endif
7759
7760
    #if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_CRYPTOCELL)
7761
        if (wc_InitRsaHw(key) != 0) {
7762
            return BAD_STATE_E;
7763
        }
7764
    #endif
7765
    }
7766
7767
    return 0;
7768
#else
7769
0
    DECL_ASNGETDATA(dataASN, rsaKeyASN_Length);
7770
0
    int        ret = 0;
7771
0
    byte       version = (byte)-1;
7772
0
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
7773
0
    word32 algId = 0;
7774
0
#endif
7775
0
    void*      heap = NULL;
7776
7777
    /* Check validity of parameters. */
7778
0
    if ((inOutIdx == NULL) || (input == NULL) || ((key == NULL) &&
7779
0
            (keySz == NULL))) {
7780
0
        ret = BAD_FUNC_ARG;
7781
0
    }
7782
7783
0
    if ((ret == 0) && (key != NULL)) {
7784
0
        heap = key->heap;
7785
0
    }
7786
7787
0
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
7788
0
    if (ret == 0) {
7789
        /* if has pkcs8 header skip it */
7790
0
        if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) {
7791
            /* ignore error, did not have pkcs8 header */
7792
0
        }
7793
0
    }
7794
0
#endif
7795
7796
0
    (void)heap;
7797
0
    CALLOC_ASNGETDATA(dataASN, rsaKeyASN_Length, ret, heap);
7798
7799
0
    if (ret == 0) {
7800
        /* Register variable to hold version field. */
7801
0
        GetASN_Int8Bit(&dataASN[RSAKEYASN_IDX_VER], &version);
7802
        /* Setup data to store INTEGER data in mp_int's in RSA object. */
7803
    #if defined(WOLFSSL_RSA_PUBLIC_ONLY)
7804
        #define RSA_ASN_INTS        RSA_PUB_INTS
7805
        /* Not extracting all data from BER encoding. */
7806
        #define RSA_ASN_COMPLETE    0
7807
    #else
7808
0
        #define RSA_ASN_INTS        RSA_INTS
7809
        /* Extracting all data from BER encoding. */
7810
0
        #define RSA_ASN_COMPLETE    1
7811
0
    #endif
7812
0
        if (key != NULL) {
7813
0
            int i;
7814
            /* Extract all public fields. */
7815
0
            for (i = 0; i < RSA_ASN_INTS; i++) {
7816
0
                GetASN_MP(&dataASN[(byte)RSAKEYASN_IDX_N + i],
7817
0
                    GetRsaInt(key, i));
7818
0
            }
7819
0
        }
7820
        /* Parse BER encoding for RSA private key. */
7821
0
        ret = GetASN_Items(rsaKeyASN, dataASN, rsaKeyASN_Length,
7822
0
            RSA_ASN_COMPLETE, input, inOutIdx, inSz);
7823
0
    }
7824
    /* Check version: 0 - two prime, 1 - multi-prime
7825
     * Multi-prime has optional sequence after coefficient for extra primes.
7826
     * If extra primes, parsing will fail as not all the buffer was used.
7827
     */
7828
0
    if ((ret == 0) && (version > PKCS1v1)) {
7829
0
        ret = ASN_PARSE_E;
7830
0
    }
7831
0
    if ((ret == 0) && (key != NULL)) {
7832
0
    #if !defined(WOLFSSL_RSA_PUBLIC_ONLY)
7833
        /* RSA key object has all private key values. */
7834
0
        key->type = RSA_PRIVATE;
7835
    #else
7836
        /* RSA key object has all public key values. */
7837
        key->type = RSA_PUBLIC;
7838
    #endif
7839
7840
    #ifdef WOLFSSL_XILINX_CRYPT
7841
        if (wc_InitRsaHw(key) != 0)
7842
            ret = BAD_STATE_E;
7843
    #endif
7844
0
    }
7845
0
    else if (ret == 0) {
7846
        /* Not filling in key but do want key size. */
7847
0
        *keySz = (int)dataASN[(byte)RSAKEYASN_IDX_N].length;
7848
        /* Check whether first byte of data is 0x00 and drop it. */
7849
0
        if (input[(int)dataASN[RSAKEYASN_IDX_E].offset - *keySz] == 0) {
7850
0
            (*keySz)--;
7851
0
        }
7852
0
    }
7853
7854
0
    FREE_ASNGETDATA(dataASN, heap);
7855
0
    return ret;
7856
0
#endif /* WOLFSSL_ASN_TEMPLATE */
7857
0
}
7858
7859
/* Decode RSA private key.
7860
 *
7861
 * PKCS #1: RFC 8017, A.1.2 - RSAPrivateKey
7862
 *
7863
 * Compiling with WOLFSSL_RSA_PUBLIC_ONLY will result in only the public fields
7864
 * being extracted.
7865
 *
7866
 * @param [in]      input     Buffer holding BER encoded data.
7867
 * @param [in, out] inOutIdx  On in, start of RSA private key.
7868
 *                            On out, start of ASN.1 item after RSA private key.
7869
 * @param [in, out] key       RSA key object.
7870
 * @param [in]      inSz      Number of bytes in buffer.
7871
 * @return  0 on success.
7872
 * @return  BAD_FUNC_ARG when input, inOutIdx or key is NULL.
7873
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
7874
 *          is invalid.
7875
 * @return  BUFFER_E when data in buffer is too small.
7876
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
7877
 *          non-zero length.
7878
 * @return  MP_INIT_E when the unable to initialize an mp_int.
7879
 * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
7880
 */
7881
int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
7882
    word32 inSz)
7883
0
{
7884
0
    if (key == NULL) {
7885
0
        return BAD_FUNC_ARG;
7886
0
    }
7887
0
    return _RsaPrivateKeyDecode(input, inOutIdx, key, NULL, inSz);
7888
0
}
7889
7890
/* Valdidate RSA private key ASN.1 encoding.
7891
 *
7892
 * PKCS #1: RFC 8017, A.1.2 - RSAPrivateKey
7893
 *
7894
 * Compiling with WOLFSSL_RSA_PUBLIC_ONLY will result in only the public fields
7895
 * being extracted.
7896
 *
7897
 * @param [in]      input     Buffer holding BER encoded data.
7898
 * @param [in, out] inOutIdx  On in, start of RSA private key.
7899
 *                            On out, start of ASN.1 item after RSA private key.
7900
 * @param [in]      inSz      Number of bytes in buffer.
7901
 * @return  0 on success.
7902
 * @return  BAD_FUNC_ARG when input, inOutIdx or keySz is NULL.
7903
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
7904
 *          is invalid.
7905
 * @return  BUFFER_E when data in buffer is too small.
7906
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
7907
 *          non-zero length.
7908
 * @return  MP_INIT_E when the unable to initialize an mp_int.
7909
 * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
7910
 */
7911
int wc_RsaPrivateKeyValidate(const byte* input, word32* inOutIdx, int* keySz,
7912
     word32 inSz)
7913
0
{
7914
0
    return _RsaPrivateKeyDecode(input, inOutIdx, NULL, keySz, inSz);
7915
0
}
7916
#endif /* NO_RSA */
7917
7918
#ifdef WOLFSSL_ASN_TEMPLATE
7919
/* ASN.1 template for a PKCS #8 key.
7920
 * Ignoring optional attributes and public key.
7921
 * PKCS #8: RFC 5958, 2 - PrivateKeyInfo
7922
 */
7923
static const ASNItem pkcs8KeyASN[] = {
7924
/*  SEQ                 */    { 0, ASN_SEQUENCE, 1, 1, 0 },
7925
/*  VER                 */        { 1, ASN_INTEGER, 0, 0, 0 },
7926
/*  PKEY_ALGO_SEQ       */        { 1, ASN_SEQUENCE, 1, 1, 0 },
7927
/*  PKEY_ALGO_OID_KEY   */            { 2, ASN_OBJECT_ID, 0, 0, 0 },
7928
/*  PKEY_ALGO_OID_CURVE */            { 2, ASN_OBJECT_ID, 0, 0, 1 },
7929
/*  PKEY_ALGO_NULL      */            { 2, ASN_TAG_NULL, 0, 0, 1 },
7930
#ifdef WC_RSA_PSS
7931
/*  PKEY_ALGO_PARAM_SEQ */            { 2, ASN_SEQUENCE, 1, 0, 1 },
7932
#endif
7933
/*  PKEY_DATA           */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
7934
/*  OPTIONAL Attributes IMPLICIT [0] */
7935
                                  { 1, ASN_CONTEXT_SPECIFIC | 0, 1, 0, 1 },
7936
/* [[2: publicKey        [1] PublicKey OPTIONAL ]] */
7937
};
7938
enum {
7939
    PKCS8KEYASN_IDX_SEQ = 0,
7940
    PKCS8KEYASN_IDX_VER,
7941
    PKCS8KEYASN_IDX_PKEY_ALGO_SEQ,
7942
    PKCS8KEYASN_IDX_PKEY_ALGO_OID_KEY,
7943
    PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE,
7944
    PKCS8KEYASN_IDX_PKEY_ALGO_NULL,
7945
#ifdef WC_RSA_PSS
7946
    PKCS8KEYASN_IDX_PKEY_ALGO_PARAM_SEQ,
7947
#endif
7948
    PKCS8KEYASN_IDX_PKEY_DATA,
7949
    PKCS8KEYASN_IDX_PKEY_ATTRIBUTES,
7950
    WOLF_ENUM_DUMMY_LAST_ELEMENT(PKCS8KEYASN_IDX)
7951
};
7952
7953
/* Number of items in ASN.1 template for a PKCS #8 key. */
7954
0
#define pkcs8KeyASN_Length (sizeof(pkcs8KeyASN) / sizeof(ASNItem))
7955
#endif
7956
7957
/* Remove PKCS #8 header around an RSA, ECDSA, Ed25519, or Ed448.
7958
 *
7959
 * @param [in]       input     Buffer holding BER data.
7960
 * @param [in, out]  inOutIdx  On in, start of PKCS #8 encoding.
7961
 *                             On out, start of encoded key.
7962
 * @param [in]       sz        Size of data in buffer.
7963
 * @param [out]      algId     Key's algorithm id from PKCS #8 header.
7964
 * @param [out]      eccOid    ECC curve OID.
7965
 * @return  Length of key data on success.
7966
 * @return  BAD_FUNC_ARG when input or inOutIdx is NULL.
7967
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
7968
 *          is invalid.
7969
 * @return  BUFFER_E when data in buffer is too small.
7970
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
7971
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
7972
 *          non-zero length.
7973
 */
7974
int ToTraditionalInline_ex2(const byte* input, word32* inOutIdx, word32 sz,
7975
                            word32* algId, word32* eccOid)
7976
0
{
7977
#ifndef WOLFSSL_ASN_TEMPLATE
7978
    word32 idx;
7979
    int    version, length;
7980
    int    ret;
7981
    byte   tag;
7982
7983
    if (input == NULL || inOutIdx == NULL)
7984
        return BAD_FUNC_ARG;
7985
7986
    idx = *inOutIdx;
7987
7988
    if (GetSequence(input, &idx, &length, sz) < 0)
7989
        return ASN_PARSE_E;
7990
7991
    if (GetMyVersion(input, &idx, &version, sz) < 0)
7992
        return ASN_PARSE_E;
7993
7994
    if (GetAlgoId(input, &idx, algId, oidKeyType, sz) < 0)
7995
        return ASN_PARSE_E;
7996
7997
    if (GetASNTag(input, &idx, &tag, sz) < 0)
7998
        return ASN_PARSE_E;
7999
    idx = idx - 1; /* reset idx after finding tag */
8000
8001
#if defined(WC_RSA_PSS) && !defined(NO_RSA)
8002
    if (*algId == RSAPSSk && tag == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
8003
        word32 seqIdx = idx;
8004
        int seqLen;
8005
        /* Not set when -1. */
8006
        enum wc_HashType hash = WC_HASH_TYPE_NONE;
8007
        int mgf = -1;
8008
        int saltLen = 0;
8009
8010
        if (GetSequence(input, &idx, &seqLen, sz) < 0) {
8011
            return ASN_PARSE_E;
8012
        }
8013
        /* Get the private key parameters. */
8014
        ret = DecodeRsaPssParams(input + seqIdx,
8015
            seqLen + idx - seqIdx, &hash, &mgf, &saltLen);
8016
        if (ret != 0) {
8017
            return ASN_PARSE_E;
8018
        }
8019
        /* TODO: store parameters so that usage can be checked. */
8020
        idx += seqLen;
8021
    }
8022
#endif /* WC_RSA_PSS && !NO_RSA */
8023
8024
    if (tag == ASN_OBJECT_ID) {
8025
        if ((*algId == ECDSAk) && (eccOid != NULL)) {
8026
            if (GetObjectId(input, &idx, eccOid, oidCurveType, sz) < 0)
8027
                return ASN_PARSE_E;
8028
        }
8029
        else {
8030
            if (SkipObjectId(input, &idx, sz) < 0)
8031
                return ASN_PARSE_E;
8032
        }
8033
    }
8034
8035
    ret = GetOctetString(input, &idx, &length, sz);
8036
    if (ret < 0) {
8037
        if (ret == WC_NO_ERR_TRACE(BUFFER_E))
8038
            return ASN_PARSE_E;
8039
        /* Some private keys don't expect an octet string */
8040
        WOLFSSL_MSG("Couldn't find Octet string");
8041
    }
8042
8043
    *inOutIdx = idx;
8044
8045
    return length;
8046
#else
8047
0
    DECL_ASNGETDATA(dataASN, pkcs8KeyASN_Length);
8048
0
    int ret = 0;
8049
0
    word32 oid = 9;
8050
0
    byte version = 0;
8051
0
    word32 idx;
8052
8053
0
    (void)eccOid;
8054
8055
    /* Check validity of parameters. */
8056
0
    if (input == NULL || inOutIdx == NULL) {
8057
0
        return BAD_FUNC_ARG;
8058
0
    }
8059
8060
0
    idx = *inOutIdx;
8061
8062
0
    CALLOC_ASNGETDATA(dataASN, pkcs8KeyASN_Length, ret, NULL);
8063
8064
0
    if (ret == 0) {
8065
        /* Get version, check key type and curve type. */
8066
0
        GetASN_Int8Bit(&dataASN[PKCS8KEYASN_IDX_VER], &version);
8067
0
        GetASN_OID(&dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_KEY], oidKeyType);
8068
0
        GetASN_OID(&dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE], oidCurveType);
8069
        /* Parse data. */
8070
0
        ret = GetASN_Items(pkcs8KeyASN, dataASN, pkcs8KeyASN_Length, 1, input,
8071
0
                           &idx, sz);
8072
0
    }
8073
8074
0
    if (ret == 0) {
8075
        /* Key type OID. */
8076
0
        oid = dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_KEY].data.oid.sum;
8077
8078
        /* Version 1 includes an optional public key.
8079
         * If public key is included then the parsing will fail as it did not
8080
         * use all the data.
8081
         */
8082
0
        if (version > PKCS8v1) {
8083
0
            ret = ASN_PARSE_E;
8084
0
        }
8085
0
    }
8086
0
    if (ret == 0) {
8087
0
        switch (oid) {
8088
0
    #ifndef NO_RSA
8089
0
            case RSAk:
8090
                /* Must have NULL item but not OBJECT_ID item. */
8091
0
                if ((dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag == 0) ||
8092
0
                    (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE].tag != 0)) {
8093
0
                    ret = ASN_PARSE_E;
8094
0
                }
8095
0
                break;
8096
0
        #ifdef WC_RSA_PSS
8097
0
            case RSAPSSk:
8098
                /* Must not have NULL item. */
8099
0
                if (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag != 0) {
8100
0
                    ret = ASN_PARSE_E;
8101
0
                }
8102
0
                if (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_PARAM_SEQ].tag != 0) {
8103
0
                    enum wc_HashType hash;
8104
0
                    int mgf;
8105
0
                    int saltLen;
8106
0
                    const byte* params = GetASNItem_Addr(
8107
0
                        dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_PARAM_SEQ], input);
8108
0
                    word32 paramsSz = GetASNItem_Length(
8109
0
                        dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_PARAM_SEQ], input);
8110
8111
                    /* Validate the private key parameters. */
8112
0
                    ret = DecodeRsaPssParams(params, paramsSz, &hash, &mgf,
8113
0
                        &saltLen);
8114
0
                    if (ret != 0) {
8115
0
                        return ASN_PARSE_E;
8116
0
                    }
8117
                    /* TODO: store parameters so that usage can be checked. */
8118
0
                }
8119
0
                break;
8120
0
        #endif
8121
0
    #endif
8122
0
        #ifdef HAVE_ECC
8123
0
            case ECDSAk:
8124
                /* Must not have NULL item. */
8125
0
                if (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag != 0) {
8126
0
                    ret = ASN_PARSE_E;
8127
0
                }
8128
0
                if (eccOid != NULL) {
8129
0
                    ASNGetData* oidCurve =
8130
0
                        &dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE];
8131
0
                    *eccOid = oidCurve->data.oid.sum;
8132
0
                }
8133
0
                break;
8134
0
        #endif
8135
        #ifdef HAVE_ED25519
8136
            case ED25519k:
8137
                /* Neither NULL item nor OBJECT_ID item allowed. */
8138
                if ((dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag != 0) ||
8139
                    (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE].tag != 0)) {
8140
                    ret = ASN_PARSE_E;
8141
                }
8142
                break;
8143
        #endif
8144
        #ifdef HAVE_CURVE25519
8145
            case X25519k:
8146
                /* Neither NULL item nor OBJECT_ID item allowed. */
8147
                if ((dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag != 0) ||
8148
                    (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE].tag != 0)) {
8149
                    ret = ASN_PARSE_E;
8150
                }
8151
                break;
8152
        #endif
8153
        #ifdef HAVE_ED448
8154
            case ED448k:
8155
                /* Neither NULL item nor OBJECT_ID item allowed. */
8156
                if ((dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag != 0) ||
8157
                    (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE].tag != 0)) {
8158
                    ret = ASN_PARSE_E;
8159
                }
8160
                break;
8161
        #endif
8162
        #ifdef HAVE_CURVE448
8163
            case X448k:
8164
                /* Neither NULL item nor OBJECT_ID item allowed. */
8165
                if ((dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag != 0) ||
8166
                    (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE].tag != 0)) {
8167
                    ret = ASN_PARSE_E;
8168
                }
8169
                break;
8170
        #endif
8171
0
        #ifndef NO_DH
8172
0
            case DHk:
8173
                /* Neither NULL item nor OBJECT_ID item allowed. */
8174
0
                if ((dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag != 0) ||
8175
0
                    (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE].tag != 0)) {
8176
0
                    ret = ASN_PARSE_E;
8177
0
                }
8178
0
                break;
8179
0
        #endif
8180
            /* DSAk not supported. */
8181
            /* Falcon, Dilithium and Sphincs not supported. */
8182
            /* Ignore OID lookup failures. */
8183
0
            default:
8184
0
                break;
8185
0
        }
8186
0
    }
8187
0
    if (ret == 0) {
8188
        /* Return algorithm id of internal key. */
8189
0
        *algId = oid;
8190
        /* Return index to start of internal key. */
8191
0
        *inOutIdx = GetASNItem_DataIdx(dataASN[PKCS8KEYASN_IDX_PKEY_DATA], input);
8192
        /* Return value is length of internal key. */
8193
0
        ret = (int)dataASN[PKCS8KEYASN_IDX_PKEY_DATA].data.ref.length;
8194
0
    }
8195
8196
0
    FREE_ASNGETDATA(dataASN, NULL);
8197
0
    return ret;
8198
0
#endif
8199
0
}
8200
8201
/* Remove PKCS #8 header around an RSA, ECDSA, Ed25519, or Ed448.
8202
 *
8203
 * @param [in]       input     Buffer holding BER data.
8204
 * @param [in, out]  inOutIdx  On in, start of PKCS #8 encoding.
8205
 *                             On out, start of encoded key.
8206
 * @param [in]       sz        Size of data in buffer.
8207
 * @param [out]      algId     Key's algorithm id from PKCS #8 header.
8208
 * @return  Length of key data on success.
8209
 * @return  BAD_FUNC_ARG when input or inOutIdx is NULL.
8210
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
8211
 *          is invalid.
8212
 * @return  BUFFER_E when data in buffer is too small.
8213
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
8214
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
8215
 *          non-zero length.
8216
 */
8217
int ToTraditionalInline_ex(const byte* input, word32* inOutIdx, word32 sz,
8218
                           word32* algId)
8219
0
{
8220
0
    return ToTraditionalInline_ex2(input, inOutIdx, sz, algId, NULL);
8221
0
}
8222
8223
8224
/* TODO: test case  */
8225
int ToTraditionalInline(const byte* input, word32* inOutIdx, word32 sz)
8226
0
{
8227
0
    word32 oid;
8228
8229
0
    return ToTraditionalInline_ex(input, inOutIdx, sz, &oid);
8230
0
}
8231
8232
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
8233
8234
/* Remove PKCS8 header, move beginning of traditional to beginning of input */
8235
int ToTraditional_ex(byte* input, word32 sz, word32* algId)
8236
0
{
8237
0
    word32 inOutIdx = 0;
8238
0
    int    length;
8239
8240
0
    if (input == NULL)
8241
0
        return BAD_FUNC_ARG;
8242
8243
0
    length = ToTraditionalInline_ex(input, &inOutIdx, sz, algId);
8244
0
    if (length < 0)
8245
0
        return length;
8246
8247
0
    if ((word32)length + inOutIdx > sz)
8248
0
        return BUFFER_E;
8249
8250
0
    XMEMMOVE(input, input + inOutIdx, (size_t)length);
8251
8252
0
    return length;
8253
0
}
8254
8255
int ToTraditional(byte* input, word32 sz)
8256
0
{
8257
0
    word32 oid;
8258
8259
0
    return ToTraditional_ex(input, sz, &oid);
8260
0
}
8261
8262
#endif /* HAVE_PKCS8 || HAVE_PKCS12 */
8263
8264
#if defined(HAVE_PKCS8)
8265
8266
int wc_GetPkcs8TraditionalOffset(byte* input, word32* inOutIdx, word32 sz)
8267
0
{
8268
0
    int length;
8269
0
    word32 algId;
8270
8271
0
    if (input == NULL || inOutIdx == NULL || (*inOutIdx > sz))
8272
0
        return BAD_FUNC_ARG;
8273
8274
0
    length = ToTraditionalInline_ex(input, inOutIdx, sz, &algId);
8275
8276
0
    return length;
8277
0
}
8278
8279
int wc_CreatePKCS8Key(byte* out, word32* outSz, byte* key, word32 keySz,
8280
        int algoID, const byte* curveOID, word32 oidSz)
8281
0
{
8282
#ifndef WOLFSSL_ASN_TEMPLATE
8283
    word32 keyIdx = 0;
8284
    word32 tmpSz  = 0;
8285
    word32 sz;
8286
    word32 tmpAlgId = 0;
8287
8288
    /* If out is NULL then return the max size needed
8289
     * + 2 for ASN_OBJECT_ID and ASN_OCTET_STRING tags */
8290
    if (out == NULL && outSz != NULL) {
8291
        *outSz = keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ
8292
                 + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 2;
8293
8294
        if (curveOID != NULL)
8295
            *outSz += oidSz + MAX_LENGTH_SZ + 1;
8296
8297
        WOLFSSL_MSG("Checking size of PKCS8");
8298
8299
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
8300
    }
8301
8302
    WOLFSSL_ENTER("wc_CreatePKCS8Key");
8303
8304
    if (key == NULL || out == NULL || outSz == NULL) {
8305
        return BAD_FUNC_ARG;
8306
    }
8307
8308
    /* check the buffer has enough room for largest possible size */
8309
    if (curveOID != NULL) {
8310
        if (*outSz < (keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ
8311
               + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 3 + oidSz + MAX_LENGTH_SZ))
8312
            return BUFFER_E;
8313
    }
8314
    else {
8315
        oidSz = 0; /* with no curveOID oid size must be 0 */
8316
        if (*outSz < (keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ
8317
                  + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 2))
8318
            return BUFFER_E;
8319
    }
8320
8321
    /* sanity check: make sure the key doesn't already have a PKCS 8 header */
8322
    if (ToTraditionalInline_ex(key, &keyIdx, keySz, &tmpAlgId) >= 0) {
8323
        (void)tmpAlgId;
8324
        return ASN_PARSE_E;
8325
    }
8326
8327
    /* PrivateKeyInfo ::= SEQUENCE */
8328
    keyIdx = MAX_SEQ_SZ; /* save room for sequence */
8329
8330
    /*  version Version
8331
     *  no header information just INTEGER */
8332
    sz = (word32)SetMyVersion(PKCS8v0, out + keyIdx, 0);
8333
    tmpSz += sz; keyIdx += sz;
8334
    /*  privateKeyAlgorithm PrivateKeyAlgorithmIdentifier */
8335
    sz = 0; /* set sz to 0 and get privateKey oid buffer size needed */
8336
    if (curveOID != NULL && oidSz > 0) {
8337
        byte buf[MAX_LENGTH_SZ];
8338
        sz = SetLength(oidSz, buf);
8339
        sz += 1; /* plus one for ASN object id */
8340
    }
8341
    sz = (word32)SetAlgoID(algoID, out + keyIdx, oidKeyType, (int)(oidSz + sz));
8342
    tmpSz += sz; keyIdx += sz;
8343
8344
    /*  privateKey          PrivateKey *
8345
     * pkcs8 ecc uses slightly different format. Places curve oid in
8346
     * buffer */
8347
    if (curveOID != NULL && oidSz > 0) {
8348
        sz = (word32)SetObjectId((int)oidSz, out + keyIdx);
8349
        keyIdx += sz; tmpSz += sz;
8350
        XMEMCPY(out + keyIdx, curveOID, oidSz);
8351
        keyIdx += oidSz; tmpSz += oidSz;
8352
    }
8353
8354
    sz = (word32)SetOctetString(keySz, out + keyIdx);
8355
    keyIdx += sz; tmpSz += sz;
8356
    XMEMCPY(out + keyIdx, key, keySz);
8357
    tmpSz += keySz;
8358
8359
    /*  attributes          optional
8360
     * No attributes currently added */
8361
8362
    /* rewind and add sequence */
8363
    sz = SetSequence(tmpSz, out);
8364
    XMEMMOVE(out + sz, out + MAX_SEQ_SZ, tmpSz);
8365
8366
    *outSz = tmpSz + sz;
8367
    return (int)(tmpSz + sz);
8368
#else
8369
    /* pkcs8KeyASN_Length-1, the -1 is because we are not adding the optional
8370
     * set of attributes */
8371
0
    DECL_ASNSETDATA(dataASN, pkcs8KeyASN_Length-1);
8372
0
    int sz = 0;
8373
0
    int ret = 0;
8374
0
    word32 keyIdx = 0;
8375
0
    word32 tmpAlgId = 0;
8376
8377
0
    WOLFSSL_ENTER("wc_CreatePKCS8Key");
8378
8379
    /* Check validity of parameters. */
8380
0
    if (out == NULL && outSz != NULL) {
8381
0
    }
8382
0
    else if (key == NULL || out == NULL || outSz == NULL) {
8383
0
        ret = BAD_FUNC_ARG;
8384
0
    }
8385
8386
0
#ifndef WOLFSSL_NO_ASN_STRICT
8387
    /* Sanity check: make sure key doesn't have PKCS #8 header. */
8388
0
    if (ToTraditionalInline_ex(key, &keyIdx, keySz, &tmpAlgId) >= 0) {
8389
0
        (void)tmpAlgId;
8390
0
        ret = ASN_PARSE_E;
8391
0
    }
8392
#else
8393
    (void)keyIdx;
8394
    (void)tmpAlgId;
8395
#endif
8396
8397
0
    CALLOC_ASNSETDATA(dataASN, pkcs8KeyASN_Length-1, ret, NULL);
8398
8399
0
    if (ret == 0) {
8400
        /* Only support default PKCS #8 format - v0. */
8401
0
        SetASN_Int8Bit(&dataASN[PKCS8KEYASN_IDX_VER], PKCS8v0);
8402
        /* Set key OID that corresponds to key data. */
8403
0
        SetASN_OID(&dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_KEY], (word32)algoID,
8404
0
            oidKeyType);
8405
0
        if (curveOID != NULL && oidSz > 0) {
8406
            /* ECC key and curveOID set to write. */
8407
0
            SetASN_Buffer(&dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE],
8408
0
                curveOID, oidSz);
8409
0
        }
8410
0
        else {
8411
            /* EC curve OID to encode. */
8412
0
            dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE].noOut = 1;
8413
0
        }
8414
        /* Only RSA keys have NULL tagged item after OID. */
8415
0
        dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].noOut = (algoID != RSAk);
8416
0
    #ifdef WC_RSA_PSS
8417
0
        dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_PARAM_SEQ].noOut = 1;
8418
0
    #endif
8419
        /* Set key data to encode. */
8420
0
        SetASN_Buffer(&dataASN[PKCS8KEYASN_IDX_PKEY_DATA], key, keySz);
8421
8422
        /* Get the size of the DER encoding. */
8423
0
        ret = SizeASN_Items(pkcs8KeyASN, dataASN, pkcs8KeyASN_Length-1, &sz);
8424
0
    }
8425
0
    if ((ret == 0) || (ret == WC_NO_ERR_TRACE(LENGTH_ONLY_E))) {
8426
        /* Always return the calculated size. */
8427
0
        *outSz = (word32)sz;
8428
0
    }
8429
    /* Check for buffer to encoded into. */
8430
0
    if ((ret == 0) && (out == NULL)) {
8431
0
        WOLFSSL_MSG("Checking size of PKCS8");
8432
0
        ret = WC_NO_ERR_TRACE(LENGTH_ONLY_E);
8433
0
    }
8434
0
    if (ret == 0) {
8435
        /*  Encode PKCS #8 key into buffer. */
8436
0
        SetASN_Items(pkcs8KeyASN, dataASN, pkcs8KeyASN_Length-1, out);
8437
0
        ret = sz;
8438
0
    }
8439
8440
0
    FREE_ASNSETDATA(dataASN, NULL);
8441
0
    return ret;
8442
0
#endif /* WOLFSSL_ASN_TEMPLATE */
8443
0
}
8444
8445
#endif /* HAVE_PKCS8 */
8446
8447
#if defined(HAVE_PKCS12) || !defined(NO_CHECK_PRIVATE_KEY)
8448
/* check that the private key is a pair for the public key
8449
 * return 1 (true) on match
8450
 * return 0 or negative value on failure/error
8451
 *
8452
 * privKey   : buffer holding DER format private key
8453
 * privKeySz : size of private key buffer
8454
 * pubKey    : buffer holding DER format public key
8455
 * pubKeySz  : size of public key buffer
8456
 * ks        : type of key
8457
 * heap      : heap hint to use */
8458
int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz,
8459
                       const byte* pubKey, word32 pubKeySz, enum Key_Sum ks,
8460
                       void* heap)
8461
0
{
8462
0
    int ret;
8463
0
    (void)privKeySz;
8464
0
    (void)pubKeySz;
8465
0
    (void)ks;
8466
8467
0
    if (privKey == NULL || pubKey == NULL) {
8468
0
        return BAD_FUNC_ARG;
8469
0
    }
8470
8471
0
    #if !defined(NO_RSA) && !defined(NO_ASN_CRYPT)
8472
    /* test if RSA key */
8473
0
    if (ks == RSAk
8474
0
    #ifdef WC_RSA_PSS
8475
0
        || ks == RSAPSSk
8476
0
    #endif
8477
0
        ) {
8478
    #ifdef WOLFSSL_SMALL_STACK
8479
        RsaKey* a;
8480
        RsaKey* b = NULL;
8481
    #else
8482
0
        RsaKey a[1], b[1];
8483
0
    #endif
8484
0
        word32 keyIdx = 0;
8485
8486
    #ifdef WOLFSSL_SMALL_STACK
8487
        a = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
8488
        if (a == NULL)
8489
            return MEMORY_E;
8490
        b = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
8491
        if (b == NULL) {
8492
            XFREE(a, NULL, DYNAMIC_TYPE_RSA);
8493
            return MEMORY_E;
8494
        }
8495
    #endif
8496
8497
0
        if ((ret = wc_InitRsaKey(a, heap)) < 0) {
8498
    #ifdef WOLFSSL_SMALL_STACK
8499
            XFREE(b, NULL, DYNAMIC_TYPE_RSA);
8500
            XFREE(a, NULL, DYNAMIC_TYPE_RSA);
8501
    #endif
8502
0
            return ret;
8503
0
        }
8504
0
        if ((ret = wc_InitRsaKey(b, heap)) < 0) {
8505
0
            wc_FreeRsaKey(a);
8506
    #ifdef WOLFSSL_SMALL_STACK
8507
            XFREE(b, NULL, DYNAMIC_TYPE_RSA);
8508
            XFREE(a, NULL, DYNAMIC_TYPE_RSA);
8509
    #endif
8510
0
            return ret;
8511
0
        }
8512
0
        if ((ret = wc_RsaPrivateKeyDecode(privKey, &keyIdx, a, privKeySz)) == 0) {
8513
0
            WOLFSSL_MSG("Checking RSA key pair");
8514
0
            keyIdx = 0; /* reset to 0 for parsing public key */
8515
8516
0
            if ((ret = wc_RsaPublicKeyDecode(pubKey, &keyIdx, b,
8517
0
                    pubKeySz)) == 0) {
8518
                /* both keys extracted successfully now check n and e
8519
                 * values are the same. This is dereferencing RsaKey */
8520
0
                if (mp_cmp(&(a->n), &(b->n)) != MP_EQ ||
8521
0
                    mp_cmp(&(a->e), &(b->e)) != MP_EQ) {
8522
0
                    ret = MP_CMP_E;
8523
0
                    WOLFSSL_ERROR_VERBOSE(ret);
8524
0
                }
8525
0
                else
8526
0
                    ret = 1;
8527
0
            }
8528
0
            else {
8529
0
                WOLFSSL_ERROR_VERBOSE(ret);
8530
0
            }
8531
0
        }
8532
0
        wc_FreeRsaKey(b);
8533
0
        wc_FreeRsaKey(a);
8534
    #ifdef WOLFSSL_SMALL_STACK
8535
        XFREE(b, NULL, DYNAMIC_TYPE_RSA);
8536
        XFREE(a, NULL, DYNAMIC_TYPE_RSA);
8537
    #endif
8538
0
    }
8539
0
    else
8540
0
    #endif /* !NO_RSA && !NO_ASN_CRYPT */
8541
8542
0
    #if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT)
8543
0
    if (ks == ECDSAk) {
8544
    #ifdef WOLFSSL_SMALL_STACK
8545
        ecc_key* key_pair;
8546
        byte*    privDer;
8547
    #else
8548
0
        ecc_key  key_pair[1];
8549
0
        byte     privDer[MAX_ECC_BYTES];
8550
0
    #endif
8551
0
        word32   privSz = MAX_ECC_BYTES;
8552
0
        word32   keyIdx = 0;
8553
8554
    #ifdef WOLFSSL_SMALL_STACK
8555
        key_pair = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
8556
        if (key_pair == NULL)
8557
            return MEMORY_E;
8558
        privDer = (byte*)XMALLOC(MAX_ECC_BYTES, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8559
        if (privDer == NULL) {
8560
            XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
8561
            return MEMORY_E;
8562
        }
8563
    #endif
8564
8565
0
        if ((ret = wc_ecc_init_ex(key_pair, heap, INVALID_DEVID)) < 0) {
8566
    #ifdef WOLFSSL_SMALL_STACK
8567
            XFREE(privDer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8568
            XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
8569
    #endif
8570
0
            return ret;
8571
0
        }
8572
8573
0
        if ((ret = wc_EccPrivateKeyDecode(privKey, &keyIdx, key_pair,
8574
0
                privKeySz)) == 0) {
8575
0
            WOLFSSL_MSG("Checking ECC key pair");
8576
8577
0
            if ((ret = wc_ecc_export_private_only(key_pair, privDer, &privSz))
8578
0
                                                                         == 0) {
8579
            #ifdef WOLFSSL_CHECK_MEM_ZERO
8580
                wc_MemZero_Add("wc_CheckPrivateKey privDer", privDer, privSz);
8581
            #endif
8582
0
                wc_ecc_free(key_pair);
8583
0
                ret = wc_ecc_init_ex(key_pair, heap, INVALID_DEVID);
8584
0
                if (ret == 0) {
8585
0
                    ret = wc_ecc_import_private_key(privDer,
8586
0
                                            privSz, pubKey,
8587
0
                                            pubKeySz, key_pair);
8588
0
                }
8589
8590
                /* public and private extracted successfully now check if is
8591
                 * a pair and also do sanity checks on key. wc_ecc_check_key
8592
                 * checks that private * base generator equals pubkey */
8593
0
                if (ret == 0) {
8594
0
                    if ((ret = wc_ecc_check_key(key_pair)) == 0) {
8595
0
                        ret = 1;
8596
0
                    }
8597
0
                    else {
8598
0
                        WOLFSSL_ERROR_VERBOSE(ret);
8599
0
                    }
8600
0
                }
8601
0
                ForceZero(privDer, privSz);
8602
0
            }
8603
0
        }
8604
0
        else {
8605
0
            WOLFSSL_ERROR_VERBOSE(ret);
8606
0
        }
8607
0
        wc_ecc_free(key_pair);
8608
    #ifdef WOLFSSL_SMALL_STACK
8609
        XFREE(privDer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8610
        XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
8611
    #elif defined(WOLFSSL_CHECK_MEM_ZERO)
8612
        wc_MemZero_Check(privDer, MAX_ECC_BYTES);
8613
    #endif
8614
0
    }
8615
0
    else
8616
0
    #endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT && !NO_ASN_CRYPT */
8617
8618
    #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) && !defined(NO_ASN_CRYPT)
8619
    if (ks == ED25519k) {
8620
    #ifdef WOLFSSL_SMALL_STACK
8621
        ed25519_key* key_pair;
8622
    #else
8623
        ed25519_key  key_pair[1];
8624
    #endif
8625
        word32       keyIdx = 0;
8626
8627
    #ifdef WOLFSSL_SMALL_STACK
8628
        key_pair = (ed25519_key*)XMALLOC(sizeof(ed25519_key), NULL,
8629
                                                          DYNAMIC_TYPE_ED25519);
8630
        if (key_pair == NULL)
8631
            return MEMORY_E;
8632
    #endif
8633
8634
        if ((ret = wc_ed25519_init_ex(key_pair, heap, INVALID_DEVID)) < 0) {
8635
    #ifdef WOLFSSL_SMALL_STACK
8636
            XFREE(key_pair, NULL, DYNAMIC_TYPE_ED25519);
8637
    #endif
8638
            return ret;
8639
        }
8640
        if ((ret = wc_Ed25519PrivateKeyDecode(privKey, &keyIdx, key_pair,
8641
                privKeySz)) == 0) {
8642
            WOLFSSL_MSG("Checking ED25519 key pair");
8643
            keyIdx = 0;
8644
            if ((ret = wc_ed25519_import_public(pubKey, pubKeySz,
8645
                    key_pair)) == 0) {
8646
                /* public and private extracted successfully no check if is
8647
                 * a pair and also do sanity checks on key. wc_ecc_check_key
8648
                 * checks that private * base generator equals pubkey */
8649
                if ((ret = wc_ed25519_check_key(key_pair)) == 0) {
8650
                    ret = 1;
8651
                }
8652
                else {
8653
                    WOLFSSL_ERROR_VERBOSE(ret);
8654
                }
8655
            }
8656
        }
8657
        else {
8658
            WOLFSSL_ERROR_VERBOSE(ret);
8659
        }
8660
        wc_ed25519_free(key_pair);
8661
    #ifdef WOLFSSL_SMALL_STACK
8662
        XFREE(key_pair, NULL, DYNAMIC_TYPE_ED25519);
8663
    #endif
8664
    }
8665
    else
8666
    #endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT && !NO_ASN_CRYPT */
8667
8668
    #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) && !defined(NO_ASN_CRYPT)
8669
    if (ks == ED448k) {
8670
    #ifdef WOLFSSL_SMALL_STACK
8671
        ed448_key* key_pair = NULL;
8672
    #else
8673
        ed448_key  key_pair[1];
8674
    #endif
8675
        word32     keyIdx = 0;
8676
8677
    #ifdef WOLFSSL_SMALL_STACK
8678
        key_pair = (ed448_key*)XMALLOC(sizeof(ed448_key), NULL,
8679
                                                            DYNAMIC_TYPE_ED448);
8680
        if (key_pair == NULL)
8681
            return MEMORY_E;
8682
    #endif
8683
8684
        if ((ret = wc_ed448_init_ex(key_pair, heap, INVALID_DEVID)) < 0) {
8685
    #ifdef WOLFSSL_SMALL_STACK
8686
            XFREE(key_pair, NULL, DYNAMIC_TYPE_ED448);
8687
    #endif
8688
            return ret;
8689
        }
8690
        if ((ret = wc_Ed448PrivateKeyDecode(privKey, &keyIdx, key_pair,
8691
                privKeySz)) == 0) {
8692
            WOLFSSL_MSG("Checking ED448 key pair");
8693
            keyIdx = 0;
8694
            if ((ret = wc_ed448_import_public(pubKey, pubKeySz,
8695
                    key_pair)) == 0) {
8696
                /* public and private extracted successfully no check if is
8697
                 * a pair and also do sanity checks on key. wc_ecc_check_key
8698
                 * checks that private * base generator equals pubkey */
8699
                if ((ret = wc_ed448_check_key(key_pair)) == 0) {
8700
                    ret = 1;
8701
                }
8702
                else {
8703
                    WOLFSSL_ERROR_VERBOSE(ret);
8704
                }
8705
            }
8706
        }
8707
        else {
8708
            WOLFSSL_ERROR_VERBOSE(ret);
8709
        }
8710
        wc_ed448_free(key_pair);
8711
    #ifdef WOLFSSL_SMALL_STACK
8712
        XFREE(key_pair, NULL, DYNAMIC_TYPE_ED448);
8713
    #endif
8714
    }
8715
    else
8716
    #endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT && !NO_ASN_CRYPT */
8717
    #if defined(HAVE_FALCON)
8718
    if ((ks == FALCON_LEVEL1k) || (ks == FALCON_LEVEL5k)) {
8719
    #ifdef WOLFSSL_SMALL_STACK
8720
        falcon_key* key_pair = NULL;
8721
    #else
8722
        falcon_key  key_pair[1];
8723
    #endif
8724
        word32     keyIdx = 0;
8725
8726
    #ifdef WOLFSSL_SMALL_STACK
8727
        key_pair = (falcon_key*)XMALLOC(sizeof(falcon_key), NULL,
8728
                                        DYNAMIC_TYPE_FALCON);
8729
        if (key_pair == NULL)
8730
            return MEMORY_E;
8731
    #endif
8732
        ret = wc_falcon_init(key_pair);
8733
        if (ret  < 0) {
8734
    #ifdef WOLFSSL_SMALL_STACK
8735
            XFREE(key_pair, NULL, DYNAMIC_TYPE_FALCON);
8736
    #endif
8737
            return ret;
8738
        }
8739
8740
        if (ks == FALCON_LEVEL1k) {
8741
            ret = wc_falcon_set_level(key_pair, 1);
8742
        }
8743
        else if (ks == FALCON_LEVEL5k) {
8744
            ret = wc_falcon_set_level(key_pair, 5);
8745
        }
8746
8747
        if (ret  < 0) {
8748
    #ifdef WOLFSSL_SMALL_STACK
8749
            XFREE(key_pair, NULL, DYNAMIC_TYPE_FALCON);
8750
    #endif
8751
            return ret;
8752
        }
8753
        if ((ret = wc_Falcon_PrivateKeyDecode(privKey, &keyIdx, key_pair,
8754
                                             privKeySz)) == 0) {
8755
            WOLFSSL_MSG("Checking Falcon key pair");
8756
            keyIdx = 0;
8757
            if ((ret = wc_falcon_import_public(pubKey, pubKeySz,
8758
                                               key_pair)) == 0) {
8759
                /* Public and private extracted successfully. Sanity check. */
8760
                if ((ret = wc_falcon_check_key(key_pair)) == 0) {
8761
                    ret = 1;
8762
                }
8763
                else {
8764
                    WOLFSSL_ERROR_VERBOSE(ret);
8765
                }
8766
            }
8767
        }
8768
        else {
8769
            WOLFSSL_ERROR_VERBOSE(ret);
8770
        }
8771
        wc_falcon_free(key_pair);
8772
    #ifdef WOLFSSL_SMALL_STACK
8773
        XFREE(key_pair, NULL, DYNAMIC_TYPE_FALCON);
8774
    #endif
8775
    }
8776
    else
8777
    #endif /* HAVE_FALCON */
8778
#if defined(HAVE_DILITHIUM) && !defined(WOLFSSL_DILITHIUM_NO_SIGN) && \
8779
    !defined(WOLFSSL_DILITHIUM_NO_VERIFY) && !defined(WOLFSSL_DILITHIUM_NO_ASN1)
8780
    if ((ks == ML_DSA_LEVEL2k) ||
8781
        (ks == ML_DSA_LEVEL3k) ||
8782
        (ks == ML_DSA_LEVEL5k)
8783
    #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
8784
     || (ks == DILITHIUM_LEVEL2k)
8785
     || (ks == DILITHIUM_LEVEL3k)
8786
     || (ks == DILITHIUM_LEVEL5k)
8787
    #endif
8788
        ) {
8789
    #ifdef WOLFSSL_SMALL_STACK
8790
        dilithium_key* key_pair = NULL;
8791
    #else
8792
        dilithium_key  key_pair[1];
8793
    #endif
8794
        word32     keyIdx = 0;
8795
8796
    #ifdef WOLFSSL_SMALL_STACK
8797
        key_pair = (dilithium_key*)XMALLOC(sizeof(dilithium_key), NULL,
8798
                                        DYNAMIC_TYPE_DILITHIUM);
8799
        if (key_pair == NULL)
8800
            return MEMORY_E;
8801
    #endif
8802
        ret = wc_dilithium_init(key_pair);
8803
        if (ret  < 0) {
8804
    #ifdef WOLFSSL_SMALL_STACK
8805
            XFREE(key_pair, NULL, DYNAMIC_TYPE_DILITHIUM);
8806
    #endif
8807
            return ret;
8808
        }
8809
8810
8811
        if (ks == ML_DSA_LEVEL2k) {
8812
            ret = wc_dilithium_set_level(key_pair, WC_ML_DSA_44);
8813
        }
8814
        else if (ks == ML_DSA_LEVEL3k) {
8815
            ret = wc_dilithium_set_level(key_pair, WC_ML_DSA_65);
8816
        }
8817
        else if (ks == ML_DSA_LEVEL5k) {
8818
            ret = wc_dilithium_set_level(key_pair, WC_ML_DSA_87);
8819
        }
8820
    #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
8821
        else if (ks == DILITHIUM_LEVEL2k) {
8822
            ret = wc_dilithium_set_level(key_pair, WC_ML_DSA_44_DRAFT);
8823
        }
8824
        else if (ks == DILITHIUM_LEVEL3k) {
8825
            ret = wc_dilithium_set_level(key_pair, WC_ML_DSA_65_DRAFT);
8826
        }
8827
        else if (ks == DILITHIUM_LEVEL5k) {
8828
            ret = wc_dilithium_set_level(key_pair, WC_ML_DSA_87_DRAFT);
8829
        }
8830
    #endif
8831
8832
        if (ret  < 0) {
8833
    #ifdef WOLFSSL_SMALL_STACK
8834
            XFREE(key_pair, NULL, DYNAMIC_TYPE_DILITHIUM);
8835
    #endif
8836
            return ret;
8837
        }
8838
        if ((ret = wc_Dilithium_PrivateKeyDecode(privKey, &keyIdx, key_pair,
8839
                                             privKeySz)) == 0) {
8840
            WOLFSSL_MSG("Checking Dilithium key pair");
8841
            keyIdx = 0;
8842
            if ((ret = wc_dilithium_import_public(pubKey, pubKeySz,
8843
                                               key_pair)) == 0) {
8844
                /* Public and private extracted successfully. Sanity check. */
8845
                if ((ret = wc_dilithium_check_key(key_pair)) == 0)
8846
                    ret = 1;
8847
            }
8848
        }
8849
        wc_dilithium_free(key_pair);
8850
    #ifdef WOLFSSL_SMALL_STACK
8851
        XFREE(key_pair, NULL, DYNAMIC_TYPE_DILITHIUM);
8852
    #endif
8853
    }
8854
    else
8855
#endif /* HAVE_DILITHIUM && !WOLFSSL_DILITHIUM_VERIFY_ONLY */
8856
    #if defined(HAVE_SPHINCS)
8857
    if ((ks == SPHINCS_FAST_LEVEL1k) ||
8858
        (ks == SPHINCS_FAST_LEVEL3k) ||
8859
        (ks == SPHINCS_FAST_LEVEL5k) ||
8860
        (ks == SPHINCS_SMALL_LEVEL1k) ||
8861
        (ks == SPHINCS_SMALL_LEVEL3k) ||
8862
        (ks == SPHINCS_SMALL_LEVEL5k)) {
8863
    #ifdef WOLFSSL_SMALL_STACK
8864
        sphincs_key* key_pair = NULL;
8865
    #else
8866
        sphincs_key  key_pair[1];
8867
    #endif
8868
        word32     keyIdx = 0;
8869
8870
    #ifdef WOLFSSL_SMALL_STACK
8871
        key_pair = (sphincs_key*)XMALLOC(sizeof(sphincs_key), NULL,
8872
                                        DYNAMIC_TYPE_SPHINCS);
8873
        if (key_pair == NULL)
8874
            return MEMORY_E;
8875
    #endif
8876
        ret = wc_sphincs_init(key_pair);
8877
        if (ret  < 0) {
8878
    #ifdef WOLFSSL_SMALL_STACK
8879
            XFREE(key_pair, NULL, DYNAMIC_TYPE_SPHINCS);
8880
    #endif
8881
            return ret;
8882
        }
8883
8884
        if (ks == SPHINCS_FAST_LEVEL1k) {
8885
            ret = wc_sphincs_set_level_and_optim(key_pair, 1, FAST_VARIANT);
8886
        }
8887
        else if (ks == SPHINCS_FAST_LEVEL3k) {
8888
            ret = wc_sphincs_set_level_and_optim(key_pair, 3, FAST_VARIANT);
8889
        }
8890
        else if (ks == SPHINCS_FAST_LEVEL5k) {
8891
            ret = wc_sphincs_set_level_and_optim(key_pair, 5, FAST_VARIANT);
8892
        }
8893
        else if (ks == SPHINCS_SMALL_LEVEL1k) {
8894
            ret = wc_sphincs_set_level_and_optim(key_pair, 1, SMALL_VARIANT);
8895
        }
8896
        else if (ks == SPHINCS_SMALL_LEVEL3k) {
8897
            ret = wc_sphincs_set_level_and_optim(key_pair, 3, SMALL_VARIANT);
8898
        }
8899
        else if (ks == SPHINCS_SMALL_LEVEL5k) {
8900
            ret = wc_sphincs_set_level_and_optim(key_pair, 5, SMALL_VARIANT);
8901
        }
8902
8903
        if (ret  < 0) {
8904
    #ifdef WOLFSSL_SMALL_STACK
8905
            XFREE(key_pair, NULL, DYNAMIC_TYPE_SPHINCS);
8906
    #endif
8907
            return ret;
8908
        }
8909
        if ((ret = wc_Sphincs_PrivateKeyDecode(privKey, &keyIdx, key_pair,
8910
                                             privKeySz)) == 0) {
8911
            WOLFSSL_MSG("Checking Sphincs key pair");
8912
            keyIdx = 0;
8913
            if ((ret = wc_sphincs_import_public(pubKey, pubKeySz,
8914
                                               key_pair)) == 0) {
8915
                /* Public and private extracted successfully. Sanity check. */
8916
                if ((ret = wc_sphincs_check_key(key_pair)) == 0)
8917
                    ret = 1;
8918
            }
8919
        }
8920
        wc_sphincs_free(key_pair);
8921
    #ifdef WOLFSSL_SMALL_STACK
8922
        XFREE(key_pair, NULL, DYNAMIC_TYPE_SPHINCS);
8923
    #endif
8924
    }
8925
    else
8926
    #endif /* HAVE_SPHINCS */
8927
0
    {
8928
0
        ret = 0;
8929
0
    }
8930
0
    (void)ks;
8931
0
    (void)heap;
8932
8933
0
    return ret;
8934
0
}
8935
8936
/* check that the private key is a pair for the public key in certificate
8937
 * return 1 (true) on match
8938
 * return 0 or negative value on failure/error
8939
 *
8940
 * key      : buffer holding DER format key
8941
 * keySz    : size of key buffer
8942
 * der      : a initialized and parsed DecodedCert holding a certificate
8943
 * checkAlt : indicate if we check primary or alternative key
8944
 */
8945
int wc_CheckPrivateKeyCert(const byte* key, word32 keySz, DecodedCert* der,
8946
                           int checkAlt, void* heap)
8947
0
{
8948
0
    int ret = 0;
8949
8950
0
    if (key == NULL || der == NULL) {
8951
0
        return BAD_FUNC_ARG;
8952
0
    }
8953
8954
#ifdef WOLFSSL_DUAL_ALG_CERTS
8955
    if (checkAlt && der->sapkiDer != NULL) {
8956
        /* We have to decode the public key first */
8957
        /* Default to max pub key size. */
8958
        word32 pubKeyLen = MAX_PUBLIC_KEY_SZ;
8959
        byte* decodedPubKey = (byte*)XMALLOC(pubKeyLen, heap,
8960
                                             DYNAMIC_TYPE_PUBLIC_KEY);
8961
        if (decodedPubKey == NULL) {
8962
            ret = MEMORY_E;
8963
        }
8964
        if (ret == 0) {
8965
            if (der->sapkiOID == RSAk || der->sapkiOID == ECDSAk) {
8966
                /* Simply copy the data */
8967
                XMEMCPY(decodedPubKey, der->sapkiDer, der->sapkiLen);
8968
                pubKeyLen = der->sapkiLen;
8969
            }
8970
            else {
8971
            #if defined(WC_ENABLE_ASYM_KEY_IMPORT)
8972
                word32 idx = 0;
8973
                ret = DecodeAsymKeyPublic(der->sapkiDer, &idx, der->sapkiLen,
8974
                                          decodedPubKey, &pubKeyLen,
8975
                                          der->sapkiOID);
8976
            #else
8977
                ret = NOT_COMPILED_IN;
8978
            #endif /* WC_ENABLE_ASYM_KEY_IMPORT */
8979
            }
8980
        }
8981
        if (ret == 0) {
8982
            ret = wc_CheckPrivateKey(key, keySz, decodedPubKey, pubKeyLen,
8983
                                     (enum Key_Sum) der->sapkiOID, heap);
8984
        }
8985
        XFREE(decodedPubKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
8986
    }
8987
    else
8988
#endif
8989
0
    {
8990
0
        ret = wc_CheckPrivateKey(key, keySz, der->publicKey,
8991
0
                der->pubKeySize, (enum Key_Sum) der->keyOID, heap);
8992
0
    }
8993
8994
0
    (void)checkAlt;
8995
8996
0
    return ret;
8997
0
}
8998
8999
#endif /* HAVE_PKCS12 || !NO_CHECK_PRIVATE_KEY */
9000
9001
#ifndef NO_PWDBASED
9002
9003
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
9004
/* Check the PBE algorithm is supported and return wolfSSL id, version and block
9005
 * size of encryption algorithm.
9006
 *
9007
 * When PBES2, version is PKCS5v2, CheckAlgoV2() must be called to get id and
9008
 * blockSz based on encryption algorithm.
9009
 *
9010
 * @param [in]  first    First byte of OID to use in check.
9011
 * @param [in]  second   Second byte of OID to use in check.
9012
 * @param [out] id       wolfSSL id for PBE algorithm.
9013
 * @param [out] version  Version of PBE OID:
9014
 *                       PKCS12v1 (PBE), PKCS5 (PBES1), PKCS5v2 (PBES2).
9015
 * @param [out] blockSz  Block size of encryption algorithm.
9016
 * @return  0 on success.
9017
 * @return  ALGO_ID_E when OID not supported.
9018
 * @return  ASN_INPUT_E when first byte is invalid.
9019
 */
9020
static int CheckAlgo(int first, int second, int* id, int* version, int* blockSz)
9021
0
{
9022
0
    int ret = 0;
9023
9024
0
    (void)id;
9025
0
    (void)blockSz;
9026
9027
0
    *version = -1;
9028
9029
    /* pkcs-12 1 = pkcs-12PbeIds */
9030
0
    if (first == 1) {
9031
        /* PKCS #12: Appendix C */
9032
0
        switch (second) {
9033
0
#if !defined(NO_SHA)
9034
    #ifndef NO_RC4
9035
        case PBE_SHA1_RC4_128:
9036
            *id = PBE_SHA1_RC4_128;
9037
            *version = PKCS12v1;
9038
            if (blockSz != NULL) {
9039
                *blockSz = 1;
9040
            }
9041
            break;
9042
    #endif
9043
    #ifndef NO_DES3
9044
        case PBE_SHA1_DES3:
9045
            *id = PBE_SHA1_DES3;
9046
            *version = PKCS12v1;
9047
            if (blockSz != NULL) {
9048
                *blockSz = DES_BLOCK_SIZE;
9049
            }
9050
            break;
9051
    #endif
9052
    #ifdef WC_RC2
9053
        case PBE_SHA1_40RC2_CBC:
9054
            *id = PBE_SHA1_40RC2_CBC;
9055
            *version = PKCS12v1;
9056
            if (blockSz != NULL) {
9057
                *blockSz = RC2_BLOCK_SIZE;
9058
            }
9059
            break;
9060
    #endif
9061
0
#endif /* !NO_SHA */
9062
0
        default:
9063
0
            ret = ALGO_ID_E;
9064
0
            break;
9065
0
        }
9066
0
    }
9067
0
    else if (first != PKCS5) {
9068
        /* Bad OID. */
9069
0
        ret = ASN_INPUT_E;
9070
0
    }
9071
    /* PKCS #5 PBES2: Appendix A.4
9072
     * pkcs-5 13 = id-PBES2 */
9073
0
    else if (second == PBES2) {
9074
0
        *version = PKCS5v2;
9075
        /* Id and block size come from CheckAlgoV2() */
9076
0
    }
9077
0
    else  {
9078
        /* PKCS #5 PBES1: Appendix A.3 */
9079
        /* see RFC 2898 for ids */
9080
0
        switch (second) {
9081
    #ifndef NO_DES3
9082
        #ifndef NO_MD5
9083
        case PBES1_MD5_DES:
9084
            *id = PBE_MD5_DES;
9085
            *version = PKCS5;
9086
            if (blockSz != NULL) {
9087
                *blockSz = DES_BLOCK_SIZE;
9088
            }
9089
            break;
9090
        #endif
9091
        #ifndef NO_SHA
9092
        case PBES1_SHA1_DES:
9093
            *id = PBE_SHA1_DES;
9094
            *version = PKCS5;
9095
            if (blockSz != NULL) {
9096
                *blockSz = DES_BLOCK_SIZE;
9097
            }
9098
            break;
9099
        #endif
9100
    #endif /* !NO_DES3 */
9101
0
        default:
9102
0
            ret = ALGO_ID_E;
9103
0
            break;
9104
0
        }
9105
0
    }
9106
9107
    /* Return error code. */
9108
0
    return ret;
9109
0
}
9110
9111
#endif /* HAVE_PKCS8 || HAVE_PKCS12 */
9112
9113
#ifdef HAVE_PKCS8
9114
9115
/* Check the encryption algorithm with PBES2 is supported and return block size
9116
 * and wolfSSL id for the PBE.
9117
 *
9118
 * @param [in]  oid      Encryption algorithm OID id.
9119
 * @param [out] id       wolfSSL id for PBE algorithm.
9120
 * @param [out] version  Version of PBE OID:
9121
 *                       PKCS12v1 (PBE), PKCS5 (PBES1), PKCS5v2 (PBES2).
9122
 * @return  0 on success.
9123
 * @return  ALGO_ID_E when encryption algorithm is not supported with PBES2.
9124
 */
9125
static int CheckAlgoV2(int oid, int* id, int* blockSz)
9126
0
{
9127
0
    int ret = 0;
9128
9129
0
    (void)id;
9130
0
    (void)blockSz;
9131
9132
0
    switch (oid) {
9133
#if !defined(NO_DES3) && !defined(NO_SHA)
9134
    case DESb:
9135
        *id = PBE_SHA1_DES;
9136
        if (blockSz != NULL) {
9137
            *blockSz = DES_BLOCK_SIZE;
9138
        }
9139
        break;
9140
    case DES3b:
9141
        *id = PBE_SHA1_DES3;
9142
        if (blockSz != NULL) {
9143
            *blockSz = DES_BLOCK_SIZE;
9144
        }
9145
        break;
9146
#endif
9147
0
#ifdef WOLFSSL_AES_256
9148
0
    case AES256CBCb:
9149
0
        *id = PBE_AES256_CBC;
9150
0
        if (blockSz != NULL) {
9151
0
            *blockSz = WC_AES_BLOCK_SIZE;
9152
0
        }
9153
0
        break;
9154
0
#endif
9155
0
#ifdef WOLFSSL_AES_128
9156
0
    case AES128CBCb:
9157
0
        *id = PBE_AES128_CBC;
9158
0
        if (blockSz != NULL) {
9159
0
            *blockSz = WC_AES_BLOCK_SIZE;
9160
0
        }
9161
0
        break;
9162
0
#endif
9163
0
    default:
9164
0
        WOLFSSL_MSG("No PKCS v2 algo found");
9165
0
        ret = ALGO_ID_E;
9166
0
        break;
9167
0
    }
9168
9169
    /* Return error code. */
9170
0
    return ret;
9171
0
}
9172
9173
#endif /* HAVE_PKCS8 */
9174
9175
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
9176
9177
int wc_GetKeyOID(byte* key, word32 keySz, const byte** curveOID, word32* oidSz,
9178
        int* algoID, void* heap)
9179
0
{
9180
0
    word32 tmpIdx = 0;
9181
9182
0
    if (key == NULL || algoID == NULL)
9183
0
        return BAD_FUNC_ARG;
9184
9185
0
    *algoID = 0;
9186
9187
0
    #if !defined(NO_RSA) && !defined(NO_ASN_CRYPT)
9188
0
    {
9189
0
        RsaKey *rsa = (RsaKey *)XMALLOC(sizeof *rsa, heap, DYNAMIC_TYPE_TMP_BUFFER);
9190
0
        if (rsa == NULL)
9191
0
            return MEMORY_E;
9192
9193
0
        wc_InitRsaKey(rsa, heap);
9194
0
        if (wc_RsaPrivateKeyDecode(key, &tmpIdx, rsa, keySz) == 0) {
9195
0
            *algoID = RSAk;
9196
0
        }
9197
0
        else {
9198
0
            WOLFSSL_MSG("Not RSA DER key");
9199
0
        }
9200
0
        wc_FreeRsaKey(rsa);
9201
0
        XFREE(rsa, heap, DYNAMIC_TYPE_TMP_BUFFER);
9202
0
    }
9203
0
    #endif /* !NO_RSA && !NO_ASN_CRYPT */
9204
0
    #if defined(HAVE_ECC) && !defined(NO_ASN_CRYPT)
9205
0
    if (*algoID == 0) {
9206
0
        ecc_key *ecc = (ecc_key *)XMALLOC(sizeof *ecc, heap, DYNAMIC_TYPE_TMP_BUFFER);
9207
0
        if (ecc == NULL)
9208
0
            return MEMORY_E;
9209
9210
0
        tmpIdx = 0;
9211
0
        wc_ecc_init_ex(ecc, heap, INVALID_DEVID);
9212
0
        if (wc_EccPrivateKeyDecode(key, &tmpIdx, ecc, keySz) == 0) {
9213
0
            *algoID = ECDSAk;
9214
9215
            /* now find oid */
9216
0
            if (wc_ecc_get_oid(ecc->dp->oidSum, curveOID, oidSz) < 0) {
9217
0
                WOLFSSL_MSG("Error getting ECC curve OID");
9218
0
                wc_ecc_free(ecc);
9219
0
                XFREE(ecc, heap, DYNAMIC_TYPE_TMP_BUFFER);
9220
0
                return BAD_FUNC_ARG;
9221
0
            }
9222
0
        }
9223
0
        else {
9224
0
            WOLFSSL_MSG("Not ECC DER key either");
9225
0
        }
9226
0
        wc_ecc_free(ecc);
9227
0
        XFREE(ecc, heap, DYNAMIC_TYPE_TMP_BUFFER);
9228
0
    }
9229
0
#endif /* HAVE_ECC && !NO_ASN_CRYPT */
9230
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) && !defined(NO_ASN_CRYPT)
9231
    if (*algoID == 0) {
9232
        ed25519_key *ed25519 = (ed25519_key *)XMALLOC(sizeof *ed25519, heap,
9233
            DYNAMIC_TYPE_TMP_BUFFER);
9234
        if (ed25519 == NULL)
9235
            return MEMORY_E;
9236
9237
        tmpIdx = 0;
9238
        if (wc_ed25519_init_ex(ed25519, heap, INVALID_DEVID) == 0) {
9239
            if (wc_Ed25519PrivateKeyDecode(key, &tmpIdx, ed25519, keySz) == 0) {
9240
                *algoID = ED25519k;
9241
            }
9242
            else {
9243
                WOLFSSL_MSG("Not ED25519 DER key");
9244
            }
9245
            wc_ed25519_free(ed25519);
9246
        }
9247
        else {
9248
            WOLFSSL_MSG("GetKeyOID wc_ed25519_init failed");
9249
        }
9250
        XFREE(ed25519, heap, DYNAMIC_TYPE_TMP_BUFFER);
9251
    }
9252
#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT && !NO_ASN_CRYPT */
9253
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) && !defined(NO_ASN_CRYPT)
9254
    if (*algoID == 0) {
9255
        ed448_key *ed448 = (ed448_key *)XMALLOC(sizeof *ed448, heap,
9256
            DYNAMIC_TYPE_TMP_BUFFER);
9257
        if (ed448 == NULL)
9258
            return MEMORY_E;
9259
9260
        tmpIdx = 0;
9261
        if (wc_ed448_init(ed448) == 0) {
9262
            if (wc_Ed448PrivateKeyDecode(key, &tmpIdx, ed448, keySz) == 0) {
9263
                *algoID = ED448k;
9264
            }
9265
            else {
9266
                WOLFSSL_MSG("Not ED448 DER key");
9267
            }
9268
            wc_ed448_free(ed448);
9269
        }
9270
        else {
9271
            WOLFSSL_MSG("GetKeyOID wc_ed448_init failed");
9272
        }
9273
        XFREE(ed448, heap, DYNAMIC_TYPE_TMP_BUFFER);
9274
    }
9275
#endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT && !NO_ASN_CRYPT */
9276
#if defined(HAVE_FALCON)
9277
    if (*algoID == 0) {
9278
        falcon_key *falcon = (falcon_key *)XMALLOC(sizeof(*falcon), heap,
9279
            DYNAMIC_TYPE_TMP_BUFFER);
9280
        if (falcon == NULL)
9281
            return MEMORY_E;
9282
9283
        if (wc_falcon_init(falcon) != 0) {
9284
            tmpIdx = 0;
9285
            if (wc_falcon_set_level(falcon, 1) == 0) {
9286
                if (wc_Falcon_PrivateKeyDecode(key, &tmpIdx, falcon, keySz)
9287
                    == 0) {
9288
                    *algoID = FALCON_LEVEL1k;
9289
                }
9290
                else {
9291
                    WOLFSSL_MSG("Not Falcon Level 1 DER key");
9292
                }
9293
            }
9294
            else if (wc_falcon_set_level(falcon, 5) == 0) {
9295
                if (wc_Falcon_PrivateKeyDecode(key, &tmpIdx, falcon, keySz)
9296
                    == 0) {
9297
                    *algoID = FALCON_LEVEL5k;
9298
                }
9299
                else {
9300
                    WOLFSSL_MSG("Not Falcon Level 5 DER key");
9301
                }
9302
            }
9303
            else {
9304
                WOLFSSL_MSG("GetKeyOID falcon initialization failed");
9305
            }
9306
            wc_falcon_free(falcon);
9307
        }
9308
        XFREE(falcon, heap, DYNAMIC_TYPE_TMP_BUFFER);
9309
    }
9310
#endif /* HAVE_FALCON */
9311
#if defined(HAVE_DILITHIUM) && !defined(WOLFSSL_DILITHIUM_NO_SIGN) && \
9312
    !defined(WOLFSSL_DILITHIUM_NO_VERIFY) && !defined(WOLFSSL_DILITHIUM_NO_ASN1)
9313
    if (*algoID == 0) {
9314
        dilithium_key *dilithium = (dilithium_key *)XMALLOC(sizeof(*dilithium),
9315
             heap, DYNAMIC_TYPE_TMP_BUFFER);
9316
        if (dilithium == NULL)
9317
            return MEMORY_E;
9318
9319
        /* wc_dilithium_init() returns 0 on success and a non-zero value on
9320
         * failure. */
9321
        if (wc_dilithium_init(dilithium) == 0) {
9322
            if ((*algoID == 0) &&
9323
                (wc_dilithium_set_level(dilithium, WC_ML_DSA_44) == 0)) {
9324
                tmpIdx = 0;
9325
                if (wc_Dilithium_PrivateKeyDecode(key, &tmpIdx, dilithium,
9326
                        keySz) == 0) {
9327
                    *algoID = ML_DSA_LEVEL2k;
9328
                }
9329
                else {
9330
                    WOLFSSL_MSG("Not Dilithium Level 2 DER key");
9331
                }
9332
            }
9333
            if ((*algoID == 0) &&
9334
                (wc_dilithium_set_level(dilithium, WC_ML_DSA_65) == 0)) {
9335
                tmpIdx = 0;
9336
                if (wc_Dilithium_PrivateKeyDecode(key, &tmpIdx, dilithium,
9337
                        keySz) == 0) {
9338
                    *algoID = ML_DSA_LEVEL3k;
9339
                }
9340
                else {
9341
                    WOLFSSL_MSG("Not Dilithium Level 3 DER key");
9342
                }
9343
            }
9344
            if ((*algoID == 0) &&
9345
                (wc_dilithium_set_level(dilithium, WC_ML_DSA_87) == 0)) {
9346
                tmpIdx = 0;
9347
                if (wc_Dilithium_PrivateKeyDecode(key, &tmpIdx, dilithium,
9348
                        keySz) == 0) {
9349
                    *algoID = ML_DSA_LEVEL5k;
9350
                }
9351
                else {
9352
                    WOLFSSL_MSG("Not Dilithium Level 5 DER key");
9353
                }
9354
            }
9355
            else {
9356
                WOLFSSL_MSG("GetKeyOID dilithium initialization failed");
9357
            }
9358
            wc_dilithium_free(dilithium);
9359
        }
9360
        XFREE(dilithium, heap, DYNAMIC_TYPE_TMP_BUFFER);
9361
    }
9362
#endif /* HAVE_DILITHIUM && !WOLFSSL_DILITHIUM_VERIFY_ONLY */
9363
#if defined(HAVE_SPHINCS)
9364
    if (*algoID == 0) {
9365
        sphincs_key *sphincs = (sphincs_key *)XMALLOC(sizeof(*sphincs),
9366
             heap, DYNAMIC_TYPE_TMP_BUFFER);
9367
        if (sphincs == NULL)
9368
            return MEMORY_E;
9369
9370
        if (wc_sphincs_init(sphincs) != 0) {
9371
            tmpIdx = 0;
9372
            if (wc_sphincs_set_level_and_optim(sphincs, 1, FAST_VARIANT)
9373
                == 0) {
9374
                if (wc_Sphincs_PrivateKeyDecode(key, &tmpIdx, sphincs,
9375
                    keySz) == 0) {
9376
                    *algoID = SPHINCS_FAST_LEVEL1k;
9377
                }
9378
                else {
9379
                    WOLFSSL_MSG("Not Sphincs-fast Level 1 DER key");
9380
                }
9381
            }
9382
            else if (wc_sphincs_set_level_and_optim(sphincs, 3, FAST_VARIANT)
9383
                == 0) {
9384
                if (wc_Sphincs_PrivateKeyDecode(key, &tmpIdx, sphincs,
9385
                    keySz) == 0) {
9386
                    *algoID = SPHINCS_FAST_LEVEL3k;
9387
                }
9388
                else {
9389
                    WOLFSSL_MSG("Not Sphincs-fast Level 3 DER key");
9390
                }
9391
            }
9392
            else if (wc_sphincs_set_level_and_optim(sphincs, 5, FAST_VARIANT)
9393
                == 0) {
9394
                if (wc_Sphincs_PrivateKeyDecode(key, &tmpIdx, sphincs,
9395
                    keySz) == 0) {
9396
                    *algoID = SPHINCS_FAST_LEVEL5k;
9397
                }
9398
                else {
9399
                    WOLFSSL_MSG("Not Sphincs-fast Level 5 DER key");
9400
                }
9401
            }
9402
            else if (wc_sphincs_set_level_and_optim(sphincs, 1, SMALL_VARIANT)
9403
                == 0) {
9404
                if (wc_Sphincs_PrivateKeyDecode(key, &tmpIdx, sphincs,
9405
                    keySz) == 0) {
9406
                    *algoID = SPHINCS_SMALL_LEVEL1k;
9407
                }
9408
                else {
9409
                    WOLFSSL_MSG("Not Sphincs-small Level 1 DER key");
9410
                }
9411
            }
9412
            else if (wc_sphincs_set_level_and_optim(sphincs, 3, SMALL_VARIANT)
9413
                == 0) {
9414
                if (wc_Sphincs_PrivateKeyDecode(key, &tmpIdx, sphincs,
9415
                    keySz) == 0) {
9416
                    *algoID = SPHINCS_SMALL_LEVEL3k;
9417
                }
9418
                else {
9419
                    WOLFSSL_MSG("Not Sphincs-small Level 3 DER key");
9420
                }
9421
            }
9422
            else if (wc_sphincs_set_level_and_optim(sphincs, 5, SMALL_VARIANT)
9423
                == 0) {
9424
                if (wc_Sphincs_PrivateKeyDecode(key, &tmpIdx, sphincs,
9425
                    keySz) == 0) {
9426
                    *algoID = SPHINCS_SMALL_LEVEL5k;
9427
                }
9428
                else {
9429
                    WOLFSSL_MSG("Not Sphincs-small Level 5 DER key");
9430
                }
9431
            }
9432
            else {
9433
                WOLFSSL_MSG("GetKeyOID sphincs initialization failed");
9434
            }
9435
            wc_sphincs_free(sphincs);
9436
        }
9437
        XFREE(sphincs, heap, DYNAMIC_TYPE_TMP_BUFFER);
9438
    }
9439
#endif /* HAVE_SPHINCS */
9440
9441
    /* if flag is not set then this is not a key that we understand. */
9442
0
    if (*algoID == 0) {
9443
0
        WOLFSSL_MSG("Bad key DER or compile options");
9444
0
        return BAD_FUNC_ARG;
9445
0
    }
9446
9447
0
    (void)tmpIdx;
9448
0
    (void)curveOID;
9449
0
    (void)oidSz;
9450
0
    (void)keySz;
9451
0
    (void)heap;
9452
9453
0
    return 1;
9454
0
}
9455
9456
#endif /* HAVE_PKCS8 || HAVE_PKCS12 */
9457
9458
#ifdef WOLFSSL_ASN_TEMPLATE
9459
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
9460
/* ASN.1 template for PBES2 parameters.
9461
 * PKCS #5: RFC 8018, A.4 - PBES2-params without outer SEQUENCE
9462
 *                    A.2 - PBKDF2-params
9463
 *                    B.2 - Encryption schemes
9464
 *                    C   - AlgorithmIdentifier
9465
 */
9466
static const ASNItem pbes2ParamsASN[] = {
9467
/* KDF_SEQ                */ { 0, ASN_SEQUENCE, 1, 1, 0 },
9468
               /* PBKDF2 */
9469
/* KDF_OID                */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
9470
/* PBKDF2_PARAMS_SEQ      */     { 1, ASN_SEQUENCE, 1, 1, 0 },
9471
                   /* Salt */
9472
/* PBKDF2_PARAMS_SALT     */         { 2, ASN_OCTET_STRING, 0, 0, 0 },
9473
                   /* Iteration count */
9474
/* PBKDF2_PARAMS_ITER     */         { 2, ASN_INTEGER, 0, 0, 0 },
9475
                   /* Key length */
9476
/* PBKDF2_PARAMS_KEYLEN   */         { 2, ASN_INTEGER, 0, 0, 1 },
9477
                   /* PRF - default is HMAC-SHA1 */
9478
/* PBKDF2_PARAMS_PRF      */         { 2, ASN_SEQUENCE, 1, 1, 1 },
9479
/* PBKDF2_PARAMS_PRF_OID  */             { 3, ASN_OBJECT_ID, 0, 0, 0 },
9480
/* PBKDF2_PARAMS_PRF_NULL */             { 3, ASN_TAG_NULL, 0, 0, 1 },
9481
/* ENCS_SEQ               */ { 0, ASN_SEQUENCE, 1, 1, 0 },
9482
                   /* Encryption algorithm */
9483
/* ENCS_OID               */   { 1, ASN_OBJECT_ID, 0, 0, 0 },
9484
                   /* IV for CBC */
9485
/* ENCS_PARAMS            */   { 1, ASN_OCTET_STRING, 0, 0, 0 },
9486
};
9487
enum {
9488
    PBES2PARAMSASN_IDX_KDF_SEQ = 0,
9489
    PBES2PARAMSASN_IDX_KDF_OID,
9490
    PBES2PARAMSASN_IDX_PBKDF2_PARAMS_SEQ,
9491
    PBES2PARAMSASN_IDX_PBKDF2_PARAMS_SALT,
9492
    PBES2PARAMSASN_IDX_PBKDF2_PARAMS_ITER,
9493
    PBES2PARAMSASN_IDX_PBKDF2_PARAMS_KEYLEN,
9494
    PBES2PARAMSASN_IDX_PBKDF2_PARAMS_PRF,
9495
    PBES2PARAMSASN_IDX_PBKDF2_PARAMS_PRF_OID,
9496
    PBES2PARAMSASN_IDX_PBKDF2_PARAMS_PRF_NULL,
9497
    PBES2PARAMSASN_IDX_ENCS_SEQ,
9498
    PBES2PARAMSASN_IDX_ENCS_OID,
9499
    PBES2PARAMSASN_IDX_ENCS_PARAMS
9500
};
9501
9502
/* Number of items in ASN.1 template for PBES2 parameters. */
9503
0
#define pbes2ParamsASN_Length (sizeof(pbes2ParamsASN) / sizeof(ASNItem))
9504
9505
/* ASN.1 template for PBES1 parameters.
9506
 * PKCS #5: RFC 8018, A.3. - PBEParameter without outer SEQUENCE
9507
 */
9508
static const ASNItem pbes1ParamsASN[] = {
9509
            /* Salt */
9510
/* SALT */    { 0, ASN_OCTET_STRING, 0, 0, 0 },
9511
            /* Iteration count */
9512
/* ITER */    { 0, ASN_INTEGER, 0, 0, 0 },
9513
};
9514
enum {
9515
    PBES1PARAMSASN_IDX_SALT = 0,
9516
    PBES1PARAMSASN_IDX_ITER
9517
};
9518
9519
/* Number of items in ASN.1 template for PBES1 parameters. */
9520
0
#define pbes1ParamsASN_Length (sizeof(pbes1ParamsASN) / sizeof(ASNItem))
9521
#endif /* HAVE_PKCS8 || HAVE_PKCS12 */
9522
#endif /* WOLFSSL_ASN_TEMPLATE */
9523
9524
#ifdef HAVE_PKCS8
9525
9526
/*
9527
 * Equivalent to calling TraditionalEnc with the same parameters but with
9528
 * encAlgId set to 0. This function must be kept alive because it's sometimes
9529
 * part of the API (WOLFSSL_ASN_API).
9530
 */
9531
int UnTraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz,
9532
        const char* password, int passwordSz, int vPKCS, int vAlgo,
9533
        byte* salt, word32 saltSz, int itt, WC_RNG* rng, void* heap)
9534
0
{
9535
0
    return TraditionalEnc(key, keySz, out, outSz, password, passwordSz,
9536
0
                vPKCS, vAlgo, 0, salt, saltSz, itt, rng, heap);
9537
0
}
9538
9539
static int GetAlgoV2(int encAlgId, const byte** oid, int *len, int* id,
9540
                     int *blkSz)
9541
0
{
9542
0
    int ret = 0;
9543
9544
0
    switch (encAlgId) {
9545
#if !defined(NO_DES3) && !defined(NO_SHA)
9546
    case DESb:
9547
        *len = sizeof(blkDesCbcOid);
9548
        *oid = blkDesCbcOid;
9549
        *id = PBE_SHA1_DES;
9550
        *blkSz = 8;
9551
        break;
9552
    case DES3b:
9553
        *len = sizeof(blkDes3CbcOid);
9554
        *oid = blkDes3CbcOid;
9555
        *id = PBE_SHA1_DES3;
9556
        *blkSz = 8;
9557
        break;
9558
#endif
9559
0
#if defined(WOLFSSL_AES_128) && defined(HAVE_AES_CBC)
9560
0
    case AES128CBCb:
9561
0
        *len = sizeof(blkAes128CbcOid);
9562
0
        *oid = blkAes128CbcOid;
9563
0
        *id = PBE_AES128_CBC;
9564
0
        *blkSz = 16;
9565
0
        break;
9566
0
#endif
9567
0
#if defined(WOLFSSL_AES_256) && defined(HAVE_AES_CBC)
9568
0
    case AES256CBCb:
9569
0
        *len = sizeof(blkAes256CbcOid);
9570
0
        *oid = blkAes256CbcOid;
9571
0
        *id = PBE_AES256_CBC;
9572
0
        *blkSz = 16;
9573
0
        break;
9574
0
#endif
9575
0
    default:
9576
0
        (void)len;
9577
0
        (void)oid;
9578
0
        (void)id;
9579
0
        (void)blkSz;
9580
0
        ret = ALGO_ID_E;
9581
0
    }
9582
9583
0
    return ret;
9584
0
}
9585
9586
int wc_EncryptPKCS8Key_ex(byte* key, word32 keySz, byte* out, word32* outSz,
9587
        const char* password, int passwordSz, int vPKCS, int pbeOid,
9588
        int encAlgId, byte* salt, word32 saltSz, int itt, int hmacOid,
9589
        WC_RNG* rng, void* heap)
9590
0
{
9591
#ifdef WOLFSSL_SMALL_STACK
9592
    byte* saltTmp = NULL;
9593
#else
9594
0
    byte saltTmp[MAX_SALT_SIZE];
9595
0
#endif
9596
0
    int genSalt = 0;
9597
0
    int ret = 0;
9598
0
    int version = 0;
9599
0
    int pbeId = 0;
9600
0
    int blockSz = 0;
9601
0
    const byte* encOid = NULL;
9602
0
    int encOidSz = 0;
9603
0
    word32 padSz = 0;
9604
0
    word32 innerLen = 0;
9605
0
    const byte* pbeOidBuf = NULL;
9606
0
    word32 pbeOidBufSz = 0;
9607
0
    word32 pbeLen = 0;
9608
0
    word32 kdfLen = 0;
9609
0
    word32 encLen = 0;
9610
0
    byte cbcIv[MAX_IV_SIZE];
9611
0
    word32 idx = 0;
9612
0
    word32 encIdx = 0;
9613
0
    const byte* hmacOidBuf = NULL;
9614
0
    word32 hmacOidBufSz = 0;
9615
0
    byte tmpShort[MAX_SHORT_SZ];
9616
0
    word32 tmpIdx = 0;
9617
9618
0
    (void)heap;
9619
9620
0
    WOLFSSL_ENTER("wc_EncryptPKCS8Key_ex");
9621
9622
0
    if (key == NULL || outSz == NULL || password == NULL) {
9623
0
        ret = BAD_FUNC_ARG;
9624
0
    }
9625
9626
0
    if (ret == 0) {
9627
0
        ret = CheckAlgo(vPKCS, pbeOid, &pbeId, &version, &blockSz);
9628
0
    }
9629
0
    if (ret == 0 && (salt == NULL || saltSz == 0)) {
9630
0
        genSalt = 1;
9631
0
        saltSz = 8;
9632
0
    }
9633
0
    if (ret == 0 && version == PKCS5v2) {
9634
0
        ret = GetAlgoV2(encAlgId, &encOid, &encOidSz, &pbeId, &blockSz);
9635
0
    }
9636
0
    if (ret == 0) {
9637
0
        padSz = (word32)((blockSz - ((int)keySz & (blockSz - 1))) &
9638
0
            (blockSz - 1));
9639
0
        ret = SetShortInt(tmpShort, &tmpIdx, (word32)itt, MAX_SHORT_SZ);
9640
0
        if (ret > 0) {
9641
            /* inner = OCT salt INT itt */
9642
0
            innerLen = 2 + saltSz + (word32)ret;
9643
0
            ret = 0;
9644
0
        }
9645
0
    }
9646
0
    if (ret == 0) {
9647
0
        if (version != PKCS5v2) {
9648
0
            pbeOidBuf = OidFromId((word32)pbeId, oidPBEType, &pbeOidBufSz);
9649
            /* pbe = OBJ pbse1 SEQ [ inner ] */
9650
0
            pbeLen = 2 + pbeOidBufSz + 2 + innerLen;
9651
0
        }
9652
0
        else {
9653
0
            if (hmacOid > 0) {
9654
0
                hmacOidBuf = OidFromId((word32)hmacOid, oidHmacType,
9655
0
                                &hmacOidBufSz);
9656
0
                innerLen += 2 + 2 + hmacOidBufSz;
9657
0
            }
9658
0
            pbeOidBuf = pbes2;
9659
0
            pbeOidBufSz = sizeof(pbes2);
9660
            /* kdf = OBJ pbkdf2 [ SEQ innerLen ] */
9661
0
            kdfLen = 2U + (word32)sizeof(pbkdf2Oid) + 2U + innerLen;
9662
            /* enc = OBJ enc_alg OCT iv */
9663
0
            encLen = 2U + (word32)encOidSz + 2U + (word32)blockSz;
9664
            /* pbe = OBJ pbse2 SEQ [ SEQ [ kdf ] SEQ [ enc ] ] */
9665
0
            pbeLen = 2U + (word32)sizeof(pbes2) + 2U + 2U + kdfLen + 2U +
9666
0
                encLen;
9667
9668
0
            ret = wc_RNG_GenerateBlock(rng, cbcIv, (word32)blockSz);
9669
0
        }
9670
0
    }
9671
0
    if (ret == 0) {
9672
        /* outerLen = length of PBE encoding + octet string data */
9673
        /* Plus 2 for tag and length for pbe */
9674
0
        word32 outerLen = 2 + pbeLen;
9675
        /* Octet string tag, length */
9676
0
        outerLen += 1 + SetLength(keySz + padSz, NULL);
9677
        /* Octet string bytes */
9678
0
        outerLen += keySz + padSz;
9679
0
        if (out == NULL) {
9680
            /* Sequence tag, length */
9681
0
            *outSz = 1 + SetLength(outerLen, NULL) + outerLen;
9682
0
            return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
9683
0
        }
9684
0
        SetOctetString(keySz + padSz, out);
9685
9686
0
        idx += SetSequence(outerLen, out + idx);
9687
9688
0
        encIdx = idx + outerLen - keySz - padSz;
9689
        /* Put Encrypted content in place. */
9690
0
        XMEMCPY(out + encIdx, key, keySz);
9691
0
        if (padSz > 0) {
9692
0
            XMEMSET(out + encIdx + keySz, (int)padSz, padSz);
9693
0
            keySz += padSz;
9694
0
        }
9695
9696
0
        if (genSalt == 1) {
9697
        #ifdef WOLFSSL_SMALL_STACK
9698
            saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
9699
            if (saltTmp == NULL) {
9700
                ret = MEMORY_E;
9701
            }
9702
            else
9703
        #endif
9704
0
            {
9705
0
                salt = saltTmp;
9706
0
                if ((ret = wc_RNG_GenerateBlock(rng, saltTmp, saltSz)) != 0) {
9707
0
                    WOLFSSL_MSG("Error generating random salt");
9708
0
                }
9709
0
            }
9710
0
        }
9711
0
    }
9712
0
    if (ret == 0) {
9713
0
        ret = wc_CryptKey(password, passwordSz, salt, (int)saltSz, itt, pbeId,
9714
0
                  out + encIdx, (int)keySz, version, cbcIv, 1, hmacOid);
9715
0
    }
9716
0
    if (ret == 0) {
9717
0
        if (version != PKCS5v2) {
9718
            /* PBE algorithm */
9719
0
            idx += SetSequence(pbeLen, out + idx);
9720
0
            idx += (word32)SetObjectId((int)pbeOidBufSz, out + idx);
9721
0
            XMEMCPY(out + idx, pbeOidBuf, pbeOidBufSz);
9722
0
            idx += pbeOidBufSz;
9723
0
        }
9724
0
        else {
9725
            /* PBES2 algorithm identifier */
9726
0
            idx += SetSequence(pbeLen, out + idx);
9727
0
            idx += (word32)SetObjectId((int)pbeOidBufSz, out + idx);
9728
0
            XMEMCPY(out + idx, pbeOidBuf, pbeOidBufSz);
9729
0
            idx += pbeOidBufSz;
9730
            /* PBES2 Parameters: SEQ [ kdf ] SEQ [ enc ] */
9731
0
            idx += SetSequence(2 + kdfLen + 2 + encLen, out + idx);
9732
            /* KDF Algorithm Identifier */
9733
0
            idx += SetSequence(kdfLen, out + idx);
9734
0
            idx += (word32)SetObjectId((int)sizeof(pbkdf2Oid), out + idx);
9735
0
            XMEMCPY(out + idx, pbkdf2Oid, sizeof(pbkdf2Oid));
9736
0
            idx += (word32)sizeof(pbkdf2Oid);
9737
0
        }
9738
0
        idx += SetSequence(innerLen, out + idx);
9739
0
        idx += SetOctetString(saltSz, out + idx);
9740
0
        XMEMCPY(out + idx, salt, saltSz); idx += saltSz;
9741
0
        ret = SetShortInt(out, &idx, (word32)itt, *outSz);
9742
0
        if (ret > 0)
9743
0
            ret = 0;
9744
0
        if (version == PKCS5v2) {
9745
0
            if (hmacOid > 0) {
9746
0
                idx += SetSequence(2+hmacOidBufSz, out + idx);
9747
0
                idx += (word32)SetObjectId((int)hmacOidBufSz, out + idx);
9748
0
                XMEMCPY(out + idx, hmacOidBuf, hmacOidBufSz);
9749
0
                idx += (word32)hmacOidBufSz;
9750
0
            }
9751
0
        }
9752
0
    }
9753
0
    if (ret == 0) {
9754
0
        if (version == PKCS5v2) {
9755
            /* Encryption Algorithm Identifier */
9756
0
            idx += SetSequence(encLen, out + idx);
9757
0
            idx += (word32)SetObjectId(encOidSz, out + idx);
9758
0
            XMEMCPY(out + idx, encOid, (size_t)encOidSz);
9759
0
            idx += (word32)encOidSz;
9760
            /* Encryption Algorithm Parameter: CBC IV */
9761
0
            idx += SetOctetString((word32)blockSz, out + idx);
9762
0
            XMEMCPY(out + idx, cbcIv, (size_t)blockSz);
9763
0
            idx += (word32)blockSz;
9764
0
        }
9765
0
        idx += SetOctetString(keySz, out + idx);
9766
        /* Default PRF - no need to write out OID */
9767
0
        idx += keySz;
9768
9769
0
        ret = (int)idx;
9770
0
    }
9771
9772
#ifdef WOLFSSL_SMALL_STACK
9773
    XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
9774
#endif
9775
9776
0
    WOLFSSL_LEAVE("wc_EncryptPKCS8Key_ex", ret);
9777
9778
0
    return ret;
9779
0
}
9780
9781
int wc_EncryptPKCS8Key(byte* key, word32 keySz, byte* out, word32* outSz,
9782
        const char* password, int passwordSz, int vPKCS, int pbeOid,
9783
        int encAlgId, byte* salt, word32 saltSz, int itt, WC_RNG* rng,
9784
        void* heap)
9785
0
{
9786
0
    return wc_EncryptPKCS8Key_ex(key, keySz, out, outSz, password, passwordSz,
9787
0
                vPKCS, pbeOid, encAlgId, salt, saltSz, itt, 0, rng, heap);
9788
0
}
9789
9790
int wc_DecryptPKCS8Key(byte* input, word32 sz, const char* password,
9791
        int passwordSz)
9792
0
{
9793
0
    int ret;
9794
0
    int length;
9795
0
    word32 inOutIdx = 0;
9796
9797
0
    if (input == NULL || password == NULL) {
9798
0
        return BAD_FUNC_ARG;
9799
0
    }
9800
9801
0
    if (GetSequence(input, &inOutIdx, &length, sz) < 0) {
9802
0
        ret = ASN_PARSE_E;
9803
0
    }
9804
0
    else {
9805
0
        ret = DecryptContent(input + inOutIdx, sz - inOutIdx, password,
9806
0
                passwordSz);
9807
0
        if (ret > 0) {
9808
0
            XMEMMOVE(input, input + inOutIdx, (size_t)ret);
9809
0
        }
9810
0
    }
9811
9812
0
    if (ret > 0) {
9813
        /* DecryptContent will decrypt the data, but it will leave any padding
9814
         * bytes intact. This code calculates the length without the padding
9815
         * and we return that to the user. */
9816
0
        inOutIdx = 0;
9817
0
        if (GetSequence(input, &inOutIdx, &length, (word32)ret) < 0) {
9818
0
            ret = ASN_PARSE_E;
9819
0
        }
9820
0
        else {
9821
0
            ret = (int)inOutIdx + length;
9822
0
        }
9823
0
    }
9824
9825
0
    return ret;
9826
0
}
9827
9828
/* Takes an unencrypted, traditional DER-encoded key and converts it to a PKCS#8
9829
 * encrypted key. If out is not NULL, it will hold the encrypted key. If it's
9830
 * NULL, LENGTH_ONLY_E will be returned and outSz will have the required out
9831
 * buffer size. */
9832
int TraditionalEnc_ex(byte* key, word32 keySz, byte* out, word32* outSz,
9833
        const char* password, int passwordSz, int vPKCS, int vAlgo,
9834
        int encAlgId, byte* salt, word32 saltSz, int itt, int hmacOid,
9835
        WC_RNG* rng, void* heap)
9836
0
{
9837
0
    int ret = 0;
9838
0
    byte *pkcs8Key = NULL;
9839
0
    word32 pkcs8KeySz = 0;
9840
0
    int algId = 0;
9841
0
    const byte* curveOid = NULL;
9842
0
    word32 curveOidSz = 0;
9843
9844
0
    if (ret == 0) {
9845
        /* check key type and get OID if ECC */
9846
0
        ret = wc_GetKeyOID(key, keySz, &curveOid, &curveOidSz, &algId, heap);
9847
0
        if (ret == 1)
9848
0
            ret = 0;
9849
0
    }
9850
0
    if (ret == 0) {
9851
0
        ret = wc_CreatePKCS8Key(NULL, &pkcs8KeySz, key, keySz, algId, curveOid,
9852
0
                                                                    curveOidSz);
9853
0
        if (ret == WC_NO_ERR_TRACE(LENGTH_ONLY_E))
9854
0
            ret = 0;
9855
0
    }
9856
0
    if (ret == 0) {
9857
0
        pkcs8Key = (byte*)XMALLOC(pkcs8KeySz, heap, DYNAMIC_TYPE_TMP_BUFFER);
9858
0
        if (pkcs8Key == NULL)
9859
0
            ret = MEMORY_E;
9860
0
    }
9861
0
    if (ret == 0) {
9862
0
        ret = wc_CreatePKCS8Key(pkcs8Key, &pkcs8KeySz, key, keySz, algId,
9863
0
            curveOid, curveOidSz);
9864
0
        if (ret >= 0) {
9865
0
            pkcs8KeySz = (word32)ret;
9866
0
            ret = 0;
9867
0
        }
9868
0
    }
9869
#ifdef WOLFSSL_CHECK_MEM_ZERO
9870
    if (ret == 0) {
9871
        wc_MemZero_Add("TraditionalEnc pkcs8Key", pkcs8Key, pkcs8KeySz);
9872
    }
9873
#endif
9874
0
    if (ret == 0) {
9875
0
        ret = wc_EncryptPKCS8Key_ex(pkcs8Key, pkcs8KeySz, out, outSz, password,
9876
0
            passwordSz, vPKCS, vAlgo, encAlgId, salt, saltSz, itt, hmacOid, rng,
9877
0
            heap);
9878
0
    }
9879
9880
0
    if (pkcs8Key != NULL) {
9881
0
        ForceZero(pkcs8Key, pkcs8KeySz);
9882
0
        XFREE(pkcs8Key, heap, DYNAMIC_TYPE_TMP_BUFFER);
9883
0
    }
9884
9885
0
    (void)rng;
9886
9887
0
    return ret;
9888
0
}
9889
9890
/* Takes an unencrypted, traditional DER-encoded key and converts it to a PKCS#8
9891
 * encrypted key. If out is not NULL, it will hold the encrypted key. If it's
9892
 * NULL, LENGTH_ONLY_E will be returned and outSz will have the required out
9893
 * buffer size. */
9894
int TraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz,
9895
        const char* password, int passwordSz, int vPKCS, int vAlgo,
9896
        int encAlgId, byte* salt, word32 saltSz, int itt, WC_RNG* rng,
9897
        void* heap)
9898
0
{
9899
0
    return TraditionalEnc_ex(key, keySz, out, outSz, password, passwordSz,
9900
0
                vPKCS, vAlgo, encAlgId, salt, saltSz, itt, 0, rng, heap);
9901
9902
0
}
9903
9904
/* Same as TraditionalEnc, but in the public API. */
9905
int wc_CreateEncryptedPKCS8Key(byte* key, word32 keySz, byte* out,
9906
        word32* outSz, const char* password, int passwordSz, int vPKCS,
9907
        int pbeOid, int encAlgId, byte* salt, word32 saltSz, int itt,
9908
        WC_RNG* rng, void* heap)
9909
0
{
9910
0
    return TraditionalEnc(key, keySz, out, outSz, password, passwordSz, vPKCS,
9911
0
        pbeOid, encAlgId, salt, saltSz, itt, rng, heap);
9912
0
}
9913
9914
9915
#ifdef WOLFSSL_ASN_TEMPLATE
9916
/* ASN.1 template for PKCS #8/#7 encrypted key for decrypting
9917
 * PKCS #8: RFC 5958, 3 - EncryptedPrivateKeyInfo without outer SEQUENCE
9918
 * PKCS #7: RFC 2315, 10.1 - EncryptedContentInfo without outer SEQUENCE
9919
 */
9920
static const ASNItem pkcs8DecASN[] = {
9921
/* ENCALGO_SEQ    */ { 1, ASN_SEQUENCE, 1, 1, 0 },
9922
/* ENCALGO_OID    */     { 2, ASN_OBJECT_ID, 0, 0, 0 },
9923
/* ENCALGO_PARAMS */     { 2, ASN_SEQUENCE, 1, 0, 0 },
9924
            /* PKCS #7 */
9925
/* ENCCONTENT     */ { 1, ASN_CONTEXT_SPECIFIC | ASN_ENC_CONTENT,
9926
                                       0, 0, 2 },
9927
            /* PKCS #8 */
9928
/* ENCDATA        */ { 1, ASN_OCTET_STRING, 0, 0, 2 },
9929
};
9930
enum {
9931
    PKCS8DECASN_IDX_ENCALGO_SEQ = 0,
9932
    PKCS8DECASN_IDX_ENCALGO_OID,
9933
    PKCS8DECASN_IDX_ENCALGO_PARAMS,
9934
    PKCS8DECASN_IDX_ENCCONTENT,
9935
    PKCS8DECASN_IDX_ENCDATA
9936
};
9937
9938
/* Number of items in ASN.1 template for PKCS #8/#7 encrypted key. */
9939
0
#define pkcs8DecASN_Length (sizeof(pkcs8DecASN) / sizeof(ASNItem))
9940
#endif
9941
9942
/* Decrypt data using PBE algorithm.
9943
 *
9944
 * PKCS #8: RFC 5958, 3 - EncryptedPrivateKeyInfo without outer SEQUENCE
9945
 * PKCS #7: RFC 2315, 10.1 - EncryptedContentInfo without outer SEQUENCE
9946
 *
9947
 * Note: input buffer is overwritten with decrypted data!
9948
 *
9949
 * Salt is in KDF parameters and IV is PBE parameters when needed.
9950
 *
9951
 * @param [in] input       Data to decrypt and unwrap.
9952
 * @param [in] sz          Size of encrypted data.
9953
 * @param [in] password    Password to derive encryption key with.
9954
 * @param [in] passwordSz  Size of password in bytes.
9955
 * @return  Length of decrypted data on success.
9956
 * @return  MEMORY_E when dynamic memory allocation fails.
9957
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
9958
 *          is invalid.
9959
 * @return  BUFFER_E when data in buffer is too small.
9960
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
9961
 * @return  Other when decryption fails.
9962
 */
9963
int DecryptContent(byte* input, word32 sz, const char* password, int passwordSz)
9964
0
{
9965
#ifndef WOLFSSL_ASN_TEMPLATE
9966
    word32 inOutIdx = 0, seqEnd, oid, shaOid = 0;
9967
    int    ret = 0, first, second, length = 0, version, saltSz, id = 0;
9968
    int    iterations = 0, keySz = 0;
9969
#ifdef WOLFSSL_SMALL_STACK
9970
    byte*  salt = NULL;
9971
    byte*  cbcIv = NULL;
9972
#else
9973
    byte   salt[MAX_SALT_SIZE];
9974
    byte   cbcIv[MAX_IV_SIZE];
9975
#endif
9976
    byte   tag;
9977
9978
    if (passwordSz < 0) {
9979
        WOLFSSL_MSG("Bad password size");
9980
        return BAD_FUNC_ARG;
9981
    }
9982
9983
    if (GetAlgoId(input, &inOutIdx, &oid, oidIgnoreType, sz) < 0) {
9984
        ERROR_OUT(ASN_PARSE_E, exit_dc);
9985
    }
9986
9987
    first  = input[inOutIdx - 2];   /* PKCS version always 2nd to last byte */
9988
    second = input[inOutIdx - 1];   /* version.algo, algo id last byte */
9989
9990
    if (CheckAlgo(first, second, &id, &version, NULL) < 0) {
9991
        ERROR_OUT(ASN_INPUT_E, exit_dc); /* Algo ID error */
9992
    }
9993
9994
    if (version == PKCS5v2) {
9995
        if (GetSequence(input, &inOutIdx, &length, sz) < 0) {
9996
            ERROR_OUT(ASN_PARSE_E, exit_dc);
9997
        }
9998
9999
        if (GetAlgoId(input, &inOutIdx, &oid, oidKdfType, sz) < 0) {
10000
            ERROR_OUT(ASN_PARSE_E, exit_dc);
10001
        }
10002
10003
        if (oid != PBKDF2_OID) {
10004
            ERROR_OUT(ASN_PARSE_E, exit_dc);
10005
        }
10006
    }
10007
10008
    if (GetSequence(input, &inOutIdx, &length, sz) <= 0) {
10009
        ERROR_OUT(ASN_PARSE_E, exit_dc);
10010
    }
10011
    /* Find the end of this SEQUENCE so we can check for the OPTIONAL and
10012
     * DEFAULT items. */
10013
    seqEnd = inOutIdx + (word32)length;
10014
10015
    ret = GetOctetString(input, &inOutIdx, &saltSz, sz);
10016
    if (ret < 0)
10017
        goto exit_dc;
10018
10019
    if (saltSz > MAX_SALT_SIZE) {
10020
        ERROR_OUT(ASN_PARSE_E, exit_dc);
10021
    }
10022
10023
#ifdef WOLFSSL_SMALL_STACK
10024
    salt = (byte*)XMALLOC(MAX_SALT_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10025
    if (salt == NULL) {
10026
        ERROR_OUT(MEMORY_E, exit_dc);
10027
    }
10028
#endif
10029
10030
    XMEMCPY(salt, &input[inOutIdx], (size_t)saltSz);
10031
    inOutIdx += (word32)saltSz;
10032
10033
    if (GetShortInt(input, &inOutIdx, &iterations, sz) < 0) {
10034
        ERROR_OUT(ASN_PARSE_E, exit_dc);
10035
    }
10036
10037
    /* OPTIONAL key length */
10038
    if (seqEnd > inOutIdx) {
10039
        word32 localIdx = inOutIdx;
10040
10041
        if (GetASNTag(input, &localIdx, &tag, sz) < 0) {
10042
            ERROR_OUT(ASN_PARSE_E, exit_dc);
10043
        }
10044
10045
        if (tag == ASN_INTEGER &&
10046
                GetShortInt(input, &inOutIdx, &keySz, sz) < 0) {
10047
            ERROR_OUT(ASN_PARSE_E, exit_dc);
10048
        }
10049
    }
10050
10051
    /* DEFAULT HMAC is SHA-1 */
10052
    if (seqEnd > inOutIdx) {
10053
        if (GetAlgoId(input, &inOutIdx, &oid, oidHmacType, sz) < 0) {
10054
            ERROR_OUT(ASN_PARSE_E, exit_dc);
10055
        }
10056
10057
        shaOid = oid;
10058
    }
10059
10060
#ifdef WOLFSSL_SMALL_STACK
10061
    cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10062
    if (cbcIv == NULL) {
10063
        ERROR_OUT(MEMORY_E, exit_dc);
10064
    }
10065
#endif
10066
10067
    if (version == PKCS5v2) {
10068
        /* get encryption algo */
10069
        if (GetAlgoId(input, &inOutIdx, &oid, oidBlkType, sz) < 0) {
10070
            ERROR_OUT(ASN_PARSE_E, exit_dc);
10071
        }
10072
10073
        if (CheckAlgoV2((int)oid, &id, NULL) < 0) {
10074
            ERROR_OUT(ASN_PARSE_E, exit_dc); /* PKCS v2 algo id error */
10075
        }
10076
10077
        if (shaOid == 0)
10078
            shaOid = oid;
10079
10080
        ret = GetOctetString(input, &inOutIdx, &length, sz);
10081
        if (ret < 0)
10082
            goto exit_dc;
10083
10084
        if (length > MAX_IV_SIZE) {
10085
            ERROR_OUT(ASN_PARSE_E, exit_dc);
10086
        }
10087
10088
        XMEMCPY(cbcIv, &input[inOutIdx], (size_t)length);
10089
        inOutIdx += (word32)length;
10090
    }
10091
10092
    if (GetASNTag(input, &inOutIdx, &tag, sz) < 0) {
10093
        ERROR_OUT(ASN_PARSE_E, exit_dc);
10094
    }
10095
10096
    if (tag != (ASN_CONTEXT_SPECIFIC | 0) && tag != ASN_OCTET_STRING) {
10097
        ERROR_OUT(ASN_PARSE_E, exit_dc);
10098
    }
10099
10100
    if (GetLength(input, &inOutIdx, &length, sz) < 0) {
10101
        ERROR_OUT(ASN_PARSE_E, exit_dc);
10102
    }
10103
10104
    ret = wc_CryptKey(password, passwordSz, salt, saltSz, iterations, id,
10105
                   input + inOutIdx, length, version, cbcIv, 0, (int)shaOid);
10106
10107
exit_dc:
10108
#ifdef WOLFSSL_SMALL_STACK
10109
    XFREE(salt,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
10110
    XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10111
#endif
10112
10113
    if (ret == 0) {
10114
        XMEMMOVE(input, input + inOutIdx, (size_t)length);
10115
        ret = length;
10116
    }
10117
10118
    return ret;
10119
#else
10120
    /* pbes2ParamsASN longer than pkcs8DecASN_Length/pbes1ParamsASN_Length. */
10121
0
    DECL_ASNGETDATA(dataASN, pbes2ParamsASN_Length);
10122
0
    int    ret = 0;
10123
0
    int    id = 0;
10124
0
    int    version = 0;
10125
0
    word32 idx = 0;
10126
0
    word32 pIdx = 0;
10127
0
    word32 iterations = 0;
10128
0
    word32 keySz = 0;
10129
0
    word32 saltSz = 0;
10130
0
    word32 shaOid = 0;
10131
0
    byte*  salt = NULL;
10132
0
    byte*  key = NULL;
10133
0
    byte   cbcIv[MAX_IV_SIZE];
10134
0
    byte*  params = NULL;
10135
10136
0
    WOLFSSL_ENTER("DecryptContent");
10137
10138
0
    CALLOC_ASNGETDATA(dataASN, pbes2ParamsASN_Length, ret, NULL);
10139
10140
0
    if (ret == 0) {
10141
        /* Check OID is a PBE Type */
10142
0
        GetASN_OID(&dataASN[PKCS8DECASN_IDX_ENCALGO_OID], oidPBEType);
10143
0
        ret = GetASN_Items(pkcs8DecASN, dataASN, pkcs8DecASN_Length, 0, input,
10144
0
                           &idx, sz);
10145
0
    }
10146
0
    if (ret == 0) {
10147
        /* Check the PBE algorithm and get the version and id. */
10148
0
        idx = dataASN[PKCS8DECASN_IDX_ENCALGO_OID].data.oid.length;
10149
        /* Second last byte: 1 (PKCS #12 PBE Id) or 5 (PKCS #5)
10150
         * Last byte: Alg or PBES2 */
10151
0
        ret = CheckAlgo(dataASN[PKCS8DECASN_IDX_ENCALGO_OID].data.oid.data[idx - 2],
10152
0
                  dataASN[PKCS8DECASN_IDX_ENCALGO_OID].data.oid.data[idx - 1],
10153
0
                  &id, &version, NULL);
10154
0
    }
10155
0
    if (ret == 0) {
10156
        /* Get the parameters data. */
10157
0
        GetASN_GetRef(&dataASN[PKCS8DECASN_IDX_ENCALGO_PARAMS], &params, &sz);
10158
        /* Having a numbered choice means none or both will have errored out. */
10159
0
        if (dataASN[PKCS8DECASN_IDX_ENCCONTENT].tag != 0)
10160
0
            GetASN_GetRef(&dataASN[PKCS8DECASN_IDX_ENCCONTENT], &key, &keySz);
10161
0
        else if (dataASN[PKCS8DECASN_IDX_ENCDATA].tag != 0)
10162
0
            GetASN_GetRef(&dataASN[PKCS8DECASN_IDX_ENCDATA], &key, &keySz);
10163
0
        else
10164
0
            ret = ASN_RSA_KEY_E;
10165
0
    }
10166
10167
0
    if (ret == 0) {
10168
0
        if (version != PKCS5v2) {
10169
            /* Initialize for PBES1 parameters and put iterations in var. */
10170
0
            XMEMSET(dataASN, 0, sizeof(*dataASN) * pbes1ParamsASN_Length);
10171
0
            GetASN_Int32Bit(&dataASN[PBES1PARAMSASN_IDX_ITER], &iterations);
10172
            /* Parse the PBES1 parameters. */
10173
0
            ret = GetASN_Items(pbes1ParamsASN, dataASN, pbes1ParamsASN_Length,
10174
0
                               0, params, &pIdx, sz);
10175
0
            if (ret == 0) {
10176
                /* Get the salt data. */
10177
0
                GetASN_GetRef(&dataASN[PBES1PARAMSASN_IDX_SALT], &salt, &saltSz);
10178
0
            }
10179
0
        }
10180
0
        else {
10181
0
            word32 ivSz = MAX_IV_SIZE;
10182
10183
            /* Initialize for PBES2 parameters. Put iterations in var; match
10184
             * KDF, HMAC and cipher, and copy CBC into buffer. */
10185
0
            XMEMSET(dataASN, 0, sizeof(*dataASN) * pbes2ParamsASN_Length);
10186
0
            GetASN_ExpBuffer(&dataASN[PBES2PARAMSASN_IDX_KDF_OID], pbkdf2Oid, sizeof(pbkdf2Oid));
10187
0
            GetASN_Int32Bit(&dataASN[PBES2PARAMSASN_IDX_PBKDF2_PARAMS_ITER], &iterations);
10188
0
            GetASN_OID(&dataASN[PBES2PARAMSASN_IDX_PBKDF2_PARAMS_PRF_OID], oidHmacType);
10189
0
            GetASN_OID(&dataASN[PBES2PARAMSASN_IDX_ENCS_OID], oidBlkType);
10190
0
            GetASN_Buffer(&dataASN[PBES2PARAMSASN_IDX_ENCS_PARAMS], cbcIv, &ivSz);
10191
            /* Parse the PBES2 parameters  */
10192
0
            ret = GetASN_Items(pbes2ParamsASN, dataASN, pbes2ParamsASN_Length,
10193
0
                               0, params, &pIdx, sz);
10194
0
            if (ret == 0) {
10195
                /* Get the salt data. */
10196
0
                GetASN_GetRef(&dataASN[PBES2PARAMSASN_IDX_PBKDF2_PARAMS_SALT], &salt, &saltSz);
10197
                /* Get the digest and encryption algorithm id. */
10198
0
                shaOid = dataASN[PBES2PARAMSASN_IDX_PBKDF2_PARAMS_PRF_OID].data.oid.sum; /* Default HMAC-SHA1 */
10199
0
                id     = (int)dataASN[PBES2PARAMSASN_IDX_ENCS_OID].data.oid.sum;
10200
                /* Convert encryption algorithm to a PBE algorithm if needed. */
10201
0
                CheckAlgoV2(id, &id, NULL);
10202
0
            }
10203
0
        }
10204
0
    }
10205
10206
0
    if (ret == 0) {
10207
        /* Decrypt the key. */
10208
0
        ret = wc_CryptKey(
10209
0
            password, passwordSz, salt, (int)saltSz, (int)iterations, id, key,
10210
0
            (int)keySz, version, cbcIv, 0, (int)shaOid);
10211
0
    }
10212
0
    if (ret == 0) {
10213
        /* Copy the decrypted key into the input (inline). */
10214
0
        XMEMMOVE(input, key, keySz);
10215
0
        ret = (int)keySz;
10216
0
    }
10217
10218
0
    FREE_ASNGETDATA(dataASN, NULL);
10219
0
    return ret;
10220
0
#endif
10221
0
}
10222
10223
/* Decrypt data using PBE algorithm and get key from PKCS#8 wrapping.
10224
 *
10225
 * PKCS #8: RFC 5958, 3 - EncryptedPrivateKeyInfo
10226
 * PKCS #7: RFC 2315, 10.1 - EncryptedContentInfo
10227
 *
10228
 * Note: input buffer is overwritten with decrypted key!
10229
 *
10230
 * Salt is in KDF parameters and IV is PBE parameters when needed.
10231
 *
10232
 * @param [in]  input       Data to decrypt and unwrap.
10233
 * @param [in]  sz          Size of encrypted data.
10234
 * @param [in]  password    Password to derive encryption key with.
10235
 * @param [in]  passwordSz  Size of password in bytes.
10236
 * @param [out] algId       Key algorithm from PKCS#8 wrapper.
10237
 * @return  Length of decrypted data on success.
10238
 * @return  MEMORY_E when dynamic memory allocation fails.
10239
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
10240
 *          is invalid.
10241
 * @return  BUFFER_E when data in buffer is too small.
10242
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
10243
 * @return  Other when decryption fails.
10244
 */
10245
int ToTraditionalEnc(byte* input, word32 sz, const char* password,
10246
                     int passwordSz, word32* algId)
10247
0
{
10248
0
    int ret;
10249
10250
0
    ret = wc_DecryptPKCS8Key(input, sz, password, passwordSz);
10251
0
    if (ret > 0) {
10252
0
        ret = ToTraditional_ex(input, (word32)ret, algId);
10253
0
    }
10254
10255
0
    return ret;
10256
0
}
10257
10258
#endif /* HAVE_PKCS8 */
10259
10260
#ifdef HAVE_PKCS12
10261
10262
#ifdef WOLFSSL_ASN_TEMPLATE
10263
/* ASN.1 template for PKCS #8 encrypted key with PBES2 parameters.
10264
 * PKCS #8: RFC 5958, 3 - EncryptedPrivateKeyInfo
10265
 * PKCS #5: RFC 8018, A.4 - PBES2
10266
 */
10267
static const ASNItem p8EncPbes2ASN[] = {
10268
/* SEQ */           { 0, ASN_SEQUENCE, 1, 1, 0 },
10269
/* ALGO_SEQ */          { 1, ASN_SEQUENCE, 1, 1, 0 },
10270
                    /* PBE algorithm */
10271
/* ALGO_OID */              { 2, ASN_OBJECT_ID, 0, 0, 0 },
10272
/* ALGO_PARAMS_SEQ */       { 2, ASN_SEQUENCE, 1, 1, 0 },
10273
/* ALGO_PARAMS_KDF_SEQ */       { 3, ASN_SEQUENCE, 1, 1, 0 },
10274
               /* PBKDF2 */
10275
/* ALGO_PARAMS_KDF_OID */           { 4, ASN_OBJECT_ID, 0, 0, 0 },
10276
/* ALGO_PARAMS_PBKDF2_SEQ */        { 4, ASN_SEQUENCE, 1, 1, 0 },
10277
                   /* Salt */
10278
/* ALGO_PARAMS_PBKDF2_SALT */           { 5, ASN_OCTET_STRING, 0, 0, 0 },
10279
                   /* Iteration count */
10280
/* ALGO_PARAMS_PBKDF2_ITER */           { 5, ASN_INTEGER, 0, 0, 0 },
10281
                   /* Key length */
10282
/* ALGO_PARAMS_PBKDF2_KEYLEN */         { 5, ASN_INTEGER, 0, 0, 1 },
10283
                   /* PRF - default is HMAC-SHA1 */
10284
/* ALGO_PARAMS_PBKDF2_PRF */            { 5, ASN_SEQUENCE, 1, 1, 1 },
10285
/* ALGO_PARAMS_PBKDF2_PRF_OID */            { 6, ASN_OBJECT_ID, 0, 0, 0 },
10286
/* ALGO_PARAMS_PBKDF2_PRF_NULL */           { 6, ASN_TAG_NULL, 0, 0, 1 },
10287
/* ALGO_ENCS_SEQ */             { 3, ASN_SEQUENCE, 1, 1, 0 },
10288
                   /* Encryption algorithm */
10289
/* ALGO_ENCS_OID */                 { 4, ASN_OBJECT_ID, 0, 0, 0 },
10290
                   /* IV for CBC */
10291
/* ALGO_ENCS_PARAMS */              { 4, ASN_OCTET_STRING, 0, 0, 0 },
10292
/* ENCDATA */           { 1, (ASN_CONTEXT_SPECIFIC | 0), 0, 0, 0 },
10293
};
10294
enum {
10295
    P8ENCPBES2ASN_IDX_SEQ = 0,
10296
    P8ENCPBES2ASN_IDX_ALGO_SEQ,
10297
    P8ENCPBES2ASN_IDX_ALGO_OID,
10298
    P8ENCPBES2ASN_IDX_ALGO_PARAMS_SEQ,
10299
    P8ENCPBES2ASN_IDX_ALGO_PARAMS_KDF_SEQ,
10300
    P8ENCPBES2ASN_IDX_ALGO_PARAMS_KDF_OID,
10301
    P8ENCPBES2ASN_IDX_ALGO_PARAMS_PBKDF2_SEQ,
10302
    P8ENCPBES2ASN_IDX_ALGO_PARAMS_PBKDF2_SALT,
10303
    P8ENCPBES2ASN_IDX_ALGO_PARAMS_PBKDF2_ITER,
10304
    P8ENCPBES2ASN_IDX_ALGO_PARAMS_PBKDF2_KEYLEN,
10305
    P8ENCPBES2ASN_IDX_ALGO_PARAMS_PBKDF2_PRF,
10306
    P8ENCPBES2ASN_IDX_ALGO_PARAMS_PBKDF2_PRF_OID,
10307
    P8ENCPBES2ASN_IDX_ALGO_PARAMS_PBKDF2_PRF_NULL,
10308
    P8ENCPBES2ASN_IDX_ALGO_ENCS_SEQ,
10309
    P8ENCPBES2ASN_IDX_ALGO_ENCS_OID,
10310
    P8ENCPBES2ASN_IDX_ALGO_ENCS_PARAMS,
10311
    P8ENCPBES2ASN_IDX_ENCDATA
10312
};
10313
10314
0
#define p8EncPbes2ASN_Length (sizeof(p8EncPbes2ASN) / sizeof(ASNItem))
10315
#endif /* WOLFSSL_ASN_TEMPLATE */
10316
10317
static int EncryptContentPBES2(byte* input, word32 inputSz, byte* out,
10318
        word32* outSz, const char* password, int passwordSz, int encAlgId,
10319
        byte* salt, word32 saltSz, int itt, int hmacOid, WC_RNG* rng,
10320
        void* heap)
10321
0
{
10322
0
    int ret = 0;
10323
#ifndef WOLFSSL_ASN_TEMPLATE
10324
    (void)input;
10325
    (void)inputSz;
10326
    (void)out;
10327
    (void)outSz;
10328
    (void)password;
10329
    (void)passwordSz;
10330
    (void)encAlgId;
10331
    (void)salt;
10332
    (void)saltSz;
10333
    (void)itt;
10334
    (void)hmacOid;
10335
    (void)rng;
10336
    (void)heap;
10337
    ret = ASN_VERSION_E;
10338
#else /* WOLFSSL_ASN_TEMPLATE */
10339
    /* PBES2 is only supported when enabling the ASN template */
10340
10341
0
    DECL_ASNSETDATA(dataASN, p8EncPbes2ASN_Length);
10342
0
    const byte* blkOidBuf = NULL;
10343
0
    int blkOidSz = 0;
10344
0
    int pbesId = -1;
10345
0
    int blockSz = 0;
10346
0
    int asnSz = 0;
10347
0
    word32 pkcs8Sz = 0;
10348
0
    byte* cbcIv = NULL;
10349
0
    byte* saltEnc = NULL;
10350
0
    int genSalt = (salt == NULL || saltSz == 0);
10351
10352
0
    WOLFSSL_ENTER("EncryptContentPBES2");
10353
10354
    /* Must have a output size to return or check. */
10355
0
    if (outSz == NULL) {
10356
0
        ret = BAD_FUNC_ARG;
10357
0
    }
10358
0
    if ((ret == 0) && genSalt) {
10359
0
        salt = NULL;
10360
0
        saltSz = PKCS5V2_SALT_SZ;
10361
        /* Salt generated into encoding below. */
10362
0
    }
10363
    /* Check salt size is valid. */
10364
0
    if ((ret == 0) && (saltSz > MAX_SALT_SIZE)) {
10365
0
        ret = ASN_PARSE_E;
10366
0
    }
10367
0
    if ((ret == 0) && GetAlgoV2(encAlgId, &blkOidBuf, &blkOidSz, &pbesId,
10368
0
        &blockSz) < 0) {
10369
0
        ret = ASN_INPUT_E;
10370
0
    }
10371
0
    CALLOC_ASNSETDATA(dataASN, p8EncPbes2ASN_Length, ret, heap);
10372
10373
0
    if (ret == 0) {
10374
        /* Setup data to go into encoding including PBE algorithm, salt,
10375
         * iteration count, and padded key length. */
10376
0
        SetASN_OID(&dataASN[P8ENCPBES2ASN_IDX_ALGO_OID], (word32)PBES2,
10377
0
                   oidPBEType);
10378
0
        SetASN_Buffer(&dataASN[P8ENCPBES2ASN_IDX_ALGO_PARAMS_KDF_OID],
10379
0
            pbkdf2Oid, sizeof(pbkdf2Oid));
10380
0
        SetASN_Buffer(&dataASN[P8ENCPBES2ASN_IDX_ALGO_PARAMS_PBKDF2_SALT], NULL,
10381
0
            saltSz);
10382
0
        SetASN_Int16Bit(&dataASN[P8ENCPBES2ASN_IDX_ALGO_PARAMS_PBKDF2_ITER],
10383
0
            (word16)itt);
10384
0
        dataASN[P8ENCPBES2ASN_IDX_ALGO_PARAMS_PBKDF2_KEYLEN].noOut = 1;
10385
0
        if (hmacOid > 0) {
10386
0
            const byte* hmacOidBuf = NULL;
10387
0
            word32 hmacOidSz = 0;
10388
0
            hmacOidBuf = OidFromId((word32)hmacOid, oidHmacType, &hmacOidSz);
10389
0
            if (hmacOidBuf == NULL) {
10390
0
                ret = ASN_PARSE_E;
10391
0
            }
10392
0
            if (ret == 0) {
10393
0
                SetASN_Buffer(
10394
0
                    &dataASN[P8ENCPBES2ASN_IDX_ALGO_PARAMS_PBKDF2_PRF_OID],
10395
0
                    hmacOidBuf, hmacOidSz);
10396
0
            }
10397
0
        }
10398
0
        else {
10399
            /* SHA1 will be used as default without PRF parameters */
10400
0
            dataASN[P8ENCPBES2ASN_IDX_ALGO_PARAMS_PBKDF2_PRF].noOut = 1;
10401
0
            dataASN[P8ENCPBES2ASN_IDX_ALGO_PARAMS_PBKDF2_PRF_OID].noOut = 1;
10402
0
            dataASN[P8ENCPBES2ASN_IDX_ALGO_PARAMS_PBKDF2_PRF_NULL].noOut = 1;
10403
0
        }
10404
0
        SetASN_Buffer(&dataASN[P8ENCPBES2ASN_IDX_ALGO_ENCS_OID], blkOidBuf,
10405
0
            blkOidSz);
10406
0
        SetASN_Buffer(&dataASN[P8ENCPBES2ASN_IDX_ALGO_ENCS_PARAMS], NULL,
10407
0
            blockSz);
10408
0
        pkcs8Sz = wc_PkcsPad(NULL, inputSz, (word32)blockSz);
10409
0
        SetASN_Buffer(&dataASN[P8ENCPBES2ASN_IDX_ENCDATA], NULL, pkcs8Sz);
10410
10411
        /* Calculate size of encoding. */
10412
0
        ret = SizeASN_Items(p8EncPbes2ASN + P8ENCPBES2ASN_IDX_ALGO_SEQ,
10413
0
                dataASN + P8ENCPBES2ASN_IDX_ALGO_SEQ,
10414
0
                (int)(p8EncPbes2ASN_Length - P8ENCPBES2ASN_IDX_ALGO_SEQ),
10415
0
                &asnSz);
10416
0
    }
10417
    /* Return size when no output buffer. */
10418
0
    if ((ret == 0) && (out == NULL)) {
10419
0
        *outSz = (word32)asnSz;
10420
0
        ret = WC_NO_ERR_TRACE(LENGTH_ONLY_E);
10421
0
    }
10422
    /* Check output buffer is big enough for encoded data. */
10423
0
    if ((ret == 0) && (asnSz > (int)*outSz)) {
10424
0
        ret = BAD_FUNC_ARG;
10425
0
    }
10426
0
    if (ret == 0) {
10427
        /* Encode PKCS#8 key. */
10428
0
        SetASN_Items(p8EncPbes2ASN + P8ENCPBES2ASN_IDX_ALGO_SEQ,
10429
0
                 dataASN + P8ENCPBES2ASN_IDX_ALGO_SEQ,
10430
0
                 (int)(p8EncPbes2ASN_Length - P8ENCPBES2ASN_IDX_ALGO_SEQ),
10431
0
                 out);
10432
10433
0
        saltEnc = (byte*)
10434
0
            dataASN[P8ENCPBES2ASN_IDX_ALGO_PARAMS_PBKDF2_SALT].data.buffer.data;
10435
0
        if (genSalt) {
10436
            /* Generate salt into encoding. */
10437
0
            ret = wc_RNG_GenerateBlock(rng, saltEnc, saltSz);
10438
0
        }
10439
0
        else {
10440
0
            XMEMCPY(saltEnc, salt, saltSz);
10441
0
        }
10442
0
    }
10443
0
    if (ret == 0) {
10444
0
        cbcIv = (byte*)
10445
0
            dataASN[P8ENCPBES2ASN_IDX_ALGO_ENCS_PARAMS].data.buffer.data;
10446
0
        ret = wc_RNG_GenerateBlock(rng, cbcIv, (word32)blockSz);
10447
0
    }
10448
0
    if (ret == 0) {
10449
        /* Store PKCS#8 key in output buffer. */
10450
0
        byte* pkcs8 = (byte*)
10451
0
            dataASN[P8ENCPBES2ASN_IDX_ENCDATA].data.buffer.data;
10452
0
        XMEMCPY(pkcs8, input, inputSz);
10453
0
        (void)wc_PkcsPad(pkcs8, inputSz, (word32)blockSz);
10454
10455
        /* Encrypt PKCS#8 key inline. */
10456
0
        ret = wc_CryptKey(password, passwordSz, saltEnc, (int)saltSz, itt,
10457
0
            pbesId, pkcs8, (int)pkcs8Sz, PKCS5v2, cbcIv, 1, hmacOid);
10458
0
    }
10459
0
    if (ret == 0) {
10460
        /* Returning size on success. */
10461
0
        ret = asnSz;
10462
0
    }
10463
10464
0
    FREE_ASNSETDATA(dataASN, heap);
10465
0
    (void)heap;
10466
0
#endif /* WOLFSSL_ASN_TEMPLATE */
10467
0
    return ret;
10468
0
}
10469
10470
#ifdef WOLFSSL_ASN_TEMPLATE
10471
/* ASN.1 template for PKCS #8 encrypted key with PBES1 parameters.
10472
 * PKCS #8: RFC 5958, 3 - EncryptedPrivateKeyInfo
10473
 * PKCS #5: RFC 8018, A.3 - PBEParameter
10474
 */
10475
static const ASNItem p8EncPbes1ASN[] = {
10476
/* SEQ                   */ { 0, ASN_SEQUENCE, 1, 1, 0 },
10477
/* ENCALGO_SEQ           */     { 1, ASN_SEQUENCE, 1, 1, 0 },
10478
                    /* PBE algorithm */
10479
/* ENCALGO_OID           */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
10480
/* ENCALGO_PBEPARAM_SEQ  */         { 2, ASN_SEQUENCE, 1, 1, 0 },
10481
                        /* Salt */
10482
/* ENCALGO_PBEPARAM_SALT */             { 3, ASN_OCTET_STRING, 0, 0, 0 },
10483
                        /* Iteration Count */
10484
/* ENCALGO_PBEPARAM_ITER */             { 3, ASN_INTEGER, 0, 0, 0 },
10485
/* ENCDATA               */     { 1, (ASN_CONTEXT_SPECIFIC | 0), 0, 0, 0 },
10486
};
10487
enum {
10488
    P8ENCPBES1ASN_IDX_SEQ = 0,
10489
    P8ENCPBES1ASN_IDX_ENCALGO_SEQ,
10490
    P8ENCPBES1ASN_IDX_ENCALGO_OID,
10491
    P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_SEQ,
10492
    P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_SALT,
10493
    P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_ITER,
10494
    P8ENCPBES1ASN_IDX_ENCDATA
10495
};
10496
10497
0
#define p8EncPbes1ASN_Length (sizeof(p8EncPbes1ASN) / sizeof(ASNItem))
10498
#endif /* WOLFSSL_ASN_TEMPLATE */
10499
10500
/* Wrap a private key in PKCS#8 and encrypt.
10501
 *
10502
 * Used for PKCS#12 and PKCS#7.
10503
 * vPKCS is the version of PKCS to use.
10504
 * vAlgo is the algorithm version to use.
10505
 *
10506
 * When salt is NULL, a random number is generated.
10507
 *
10508
 * data returned is :
10509
 * [ seq - obj [ seq -salt,itt]] , construct with encrypted data
10510
 *
10511
 * @param [in]  input       Data to encrypt.
10512
 * @param [in]  inputSz     Length of data in bytes.
10513
 * @param [out] out         Buffer to write wrapped encrypted data into.
10514
 * @param [out] outSz       Length of encrypted data in bytes.
10515
 * @param [in]  password    Password used to create encryption key.
10516
 * @param [in]  passwordSz  Length of password in bytes.
10517
 * @param [in]  vPKCS       First byte used to determine PBE algorithm.
10518
 * @param [in]  vAlgo       Second byte used to determine PBE algorithm.
10519
 * @param [in]  encAlgId    Encryption Algorithm for PBES2.
10520
 * @param [in]  salt        Salt to use with KDF.
10521
 * @param [in]  saltSz      Length of salt in bytes.
10522
 * @param [in]  itt         Number of iterations to use in KDF.
10523
 * @param [in]  hmacOid     HMAC Algorithm for PBES2.
10524
 * @param [in]  rng         Random number generator to use to generate salt.
10525
 * @param [in]  heap        Dynamic memory allocator hint.
10526
 * @return  The size of encrypted data on success
10527
 * @return  LENGTH_ONLY_E when out is NULL and able to encode.
10528
 * @return  ASN_PARSE_E when the salt size is too large.
10529
 * @return  ASN_VERSION_E when attempting to use a PBES2 algorithm (use
10530
 *          TraditionalEnc).
10531
 * @return  MEMORY_E when dynamic memory allocation fails.
10532
 * @return  Other when encryption or random number generation fails.
10533
 */
10534
int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz,
10535
        const char* password, int passwordSz, int vPKCS, int vAlgo,
10536
        int encAlgId, byte* salt, word32 saltSz, int itt, int hmacOid,
10537
        WC_RNG* rng, void* heap)
10538
0
{
10539
#ifndef WOLFSSL_ASN_TEMPLATE
10540
    word32 sz;
10541
    word32 inOutIdx = 0;
10542
    word32 tmpIdx   = 0;
10543
    word32 totalSz  = 0;
10544
    word32 seqSz;
10545
    word32 innerSz;
10546
    int    ret;
10547
    int    version, id = PBE_NONE, blockSz = 0;
10548
#ifdef WOLFSSL_SMALL_STACK
10549
    byte*  saltTmp = NULL;
10550
    byte*  cbcIv   = NULL;
10551
#else
10552
    byte   saltTmp[MAX_SALT_SIZE];
10553
    byte   cbcIv[MAX_IV_SIZE];
10554
#endif
10555
    byte   seq[MAX_SEQ_SZ];
10556
    byte   shr[MAX_SHORT_SZ];
10557
    word32 maxShr = MAX_SHORT_SZ;
10558
    word32 algoSz;
10559
    const  byte* algoName;
10560
10561
    (void)encAlgId;
10562
    (void)hmacOid;
10563
    (void)heap;
10564
10565
    (void)EncryptContentPBES2;
10566
10567
    WOLFSSL_ENTER("EncryptContent");
10568
10569
    if (CheckAlgo(vPKCS, vAlgo, &id, &version, &blockSz) < 0)
10570
        return ASN_INPUT_E;  /* Algo ID error */
10571
10572
    if (version == PKCS5v2) {
10573
        WOLFSSL_MSG("PKCS#5 version 2 not supported yet");
10574
        return BAD_FUNC_ARG;
10575
    }
10576
10577
    if (saltSz > MAX_SALT_SIZE)
10578
        return ASN_PARSE_E;
10579
10580
    if (outSz == NULL) {
10581
        return BAD_FUNC_ARG;
10582
    }
10583
10584
    /* calculate size */
10585
    /* size of constructed string at end */
10586
    sz = wc_PkcsPad(NULL, inputSz, (word32)blockSz);
10587
    totalSz  = ASN_TAG_SZ;
10588
    totalSz += SetLength(sz, seq);
10589
    totalSz += sz;
10590
10591
    /* size of sequence holding object id and sub sequence of salt and itt */
10592
    algoName = OidFromId((word32)id, oidPBEType, &algoSz);
10593
    if (algoName == NULL) {
10594
        WOLFSSL_MSG("Unknown Algorithm");
10595
        return 0;
10596
    }
10597
    innerSz = (word32)SetObjectId((int)algoSz, seq);
10598
    innerSz += algoSz;
10599
10600
    /* get subsequence of salt and itt */
10601
    if (salt == NULL || saltSz == 0) {
10602
        sz = 8;
10603
    }
10604
    else {
10605
        sz = saltSz;
10606
    }
10607
    seqSz  = SetOctetString(sz, seq);
10608
    seqSz += sz;
10609
10610
    tmpIdx = 0;
10611
    ret = SetShortInt(shr, &tmpIdx, (word32)itt, maxShr);
10612
    if (ret >= 0) {
10613
        seqSz += (word32)ret;
10614
    }
10615
    else {
10616
        return ret;
10617
    }
10618
    innerSz += seqSz + SetSequence(seqSz, seq);
10619
    totalSz += innerSz + SetSequence(innerSz, seq);
10620
10621
    if (out == NULL) {
10622
        *outSz = totalSz;
10623
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
10624
    }
10625
10626
    inOutIdx = 0;
10627
    if (totalSz > *outSz)
10628
        return BUFFER_E;
10629
10630
    inOutIdx += SetSequence(innerSz, out + inOutIdx);
10631
    inOutIdx += (word32)SetObjectId((int)algoSz, out + inOutIdx);
10632
    XMEMCPY(out + inOutIdx, algoName, algoSz);
10633
    inOutIdx += algoSz;
10634
    inOutIdx += SetSequence(seqSz, out + inOutIdx);
10635
10636
    /* create random salt if one not provided */
10637
    if (salt == NULL || saltSz == 0) {
10638
        saltSz = 8;
10639
    #ifdef WOLFSSL_SMALL_STACK
10640
        saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
10641
        if (saltTmp == NULL)
10642
            return MEMORY_E;
10643
    #endif
10644
        salt = saltTmp;
10645
10646
        if ((ret = wc_RNG_GenerateBlock(rng, saltTmp, saltSz)) != 0) {
10647
            WOLFSSL_MSG("Error generating random salt");
10648
        #ifdef WOLFSSL_SMALL_STACK
10649
            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
10650
        #endif
10651
            return ret;
10652
        }
10653
    }
10654
    inOutIdx += SetOctetString(saltSz, out + inOutIdx);
10655
    if (saltSz + inOutIdx > *outSz) {
10656
    #ifdef WOLFSSL_SMALL_STACK
10657
        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
10658
    #endif
10659
        return BUFFER_E;
10660
    }
10661
    XMEMCPY(out + inOutIdx, salt, saltSz);
10662
    inOutIdx += saltSz;
10663
10664
    /* place iteration setting in buffer */
10665
    ret = SetShortInt(out, &inOutIdx, (word32)itt, *outSz);
10666
    if (ret < 0) {
10667
    #ifdef WOLFSSL_SMALL_STACK
10668
        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
10669
    #endif
10670
        return ret;
10671
    }
10672
10673
    if (inOutIdx + 1 > *outSz) {
10674
    #ifdef WOLFSSL_SMALL_STACK
10675
        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
10676
    #endif
10677
        return BUFFER_E;
10678
    }
10679
    out[inOutIdx++] = ASN_CONTEXT_SPECIFIC | 0;
10680
10681
    /* get pad size and verify buffer room */
10682
    sz = wc_PkcsPad(NULL, inputSz, (word32)blockSz);
10683
    if (sz + inOutIdx > *outSz) {
10684
    #ifdef WOLFSSL_SMALL_STACK
10685
        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
10686
    #endif
10687
        return BUFFER_E;
10688
    }
10689
    inOutIdx += SetLength(sz, out + inOutIdx);
10690
10691
    /* copy input to output buffer and pad end */
10692
    XMEMCPY(out + inOutIdx, input, inputSz);
10693
    sz = wc_PkcsPad(out + inOutIdx, inputSz, (word32)blockSz);
10694
#ifdef WOLFSSL_SMALL_STACK
10695
    cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
10696
    if (cbcIv == NULL) {
10697
        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
10698
        return MEMORY_E;
10699
    }
10700
#endif
10701
10702
    /* encrypt */
10703
    if ((ret = wc_CryptKey(password, passwordSz, salt, (int)saltSz, itt, id,
10704
                   out + inOutIdx, (int)sz, version, cbcIv, 1, 0)) < 0) {
10705
10706
    #ifdef WOLFSSL_SMALL_STACK
10707
        XFREE(cbcIv,   heap, DYNAMIC_TYPE_TMP_BUFFER);
10708
        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
10709
    #endif
10710
        return ret;  /* encrypt failure */
10711
    }
10712
10713
#ifdef WOLFSSL_SMALL_STACK
10714
    XFREE(cbcIv,   heap, DYNAMIC_TYPE_TMP_BUFFER);
10715
    XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
10716
#endif
10717
10718
    (void)rng;
10719
10720
    return (int)(inOutIdx + sz);
10721
#else /* WOLFSSL_ASN_TEMPLATE */
10722
    /* PBES2 is only supported when enabling the ASN template */
10723
10724
0
    DECL_ASNSETDATA(dataASN, p8EncPbes1ASN_Length);
10725
0
    int ret = 0;
10726
0
    int sz = 0;
10727
0
    int version = 0;
10728
0
    int id = -1;
10729
0
    int blockSz = 0;
10730
0
    word32 pkcs8Sz = 0;
10731
10732
0
    (void)heap;
10733
10734
0
    WOLFSSL_ENTER("EncryptContent");
10735
10736
    /* Must have a output size to return or check. */
10737
0
    if (outSz == NULL) {
10738
0
        ret = BAD_FUNC_ARG;
10739
0
    }
10740
    /* Check salt size is valid. */
10741
0
    if ((ret == 0) && (saltSz > MAX_SALT_SIZE)) {
10742
0
        ret = ASN_PARSE_E;
10743
0
    }
10744
    /* Get algorithm parameters for algorithm identifier. */
10745
0
    if ((ret == 0) && CheckAlgo(vPKCS, vAlgo, &id, &version, &blockSz) < 0) {
10746
0
        ret = ASN_INPUT_E;
10747
0
    }
10748
    /* Check PKCS #5 version - only PBSE1 parameters supported. */
10749
0
    if ((ret == 0) && (version == PKCS5v2)) {
10750
0
        return EncryptContentPBES2(input, inputSz, out, outSz, password,
10751
0
            passwordSz, encAlgId, salt, saltSz, itt, hmacOid, rng, heap);
10752
0
    }
10753
10754
0
    CALLOC_ASNSETDATA(dataASN, p8EncPbes1ASN_Length, ret, heap);
10755
10756
0
    if (ret == 0) {
10757
        /* Setup data to go into encoding including PBE algorithm, salt,
10758
         * iteration count, and padded key length. */
10759
0
        SetASN_OID(&dataASN[P8ENCPBES1ASN_IDX_ENCALGO_OID], (word32)id,
10760
0
                   oidPBEType);
10761
0
        if (salt == NULL || saltSz == 0) {
10762
0
            salt = NULL;
10763
0
            saltSz = PKCS5_SALT_SZ;
10764
            /* Salt generated into encoding below. */
10765
0
        }
10766
0
        SetASN_Buffer(&dataASN[P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_SALT],
10767
0
                salt, saltSz);
10768
0
        SetASN_Int16Bit(&dataASN[P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_ITER],
10769
0
                        (word16)itt);
10770
0
        pkcs8Sz = wc_PkcsPad(NULL, inputSz, (word32)blockSz);
10771
0
        SetASN_Buffer(&dataASN[P8ENCPBES1ASN_IDX_ENCDATA], NULL, pkcs8Sz);
10772
10773
        /* Calculate size of encoding. */
10774
0
        ret = SizeASN_Items(p8EncPbes1ASN + P8ENCPBES1ASN_IDX_ENCALGO_SEQ,
10775
0
                dataASN + P8ENCPBES1ASN_IDX_ENCALGO_SEQ,
10776
0
                (int)(p8EncPbes1ASN_Length - P8ENCPBES1ASN_IDX_ENCALGO_SEQ),
10777
0
                &sz);
10778
0
    }
10779
    /* Return size when no output buffer. */
10780
0
    if ((ret == 0) && (out == NULL)) {
10781
0
        *outSz = (word32)sz;
10782
0
        ret = WC_NO_ERR_TRACE(LENGTH_ONLY_E);
10783
0
    }
10784
    /* Check output buffer is big enough for encoded data. */
10785
0
    if ((ret == 0) && (sz > (int)*outSz)) {
10786
0
        ret = BAD_FUNC_ARG;
10787
0
    }
10788
0
    if (ret == 0) {
10789
        /* Encode PKCS#8 key. */
10790
0
        SetASN_Items(p8EncPbes1ASN + P8ENCPBES1ASN_IDX_ENCALGO_SEQ,
10791
0
                 dataASN + P8ENCPBES1ASN_IDX_ENCALGO_SEQ,
10792
0
                 (int)(p8EncPbes1ASN_Length - P8ENCPBES1ASN_IDX_ENCALGO_SEQ),
10793
0
                 out);
10794
10795
0
        if (salt == NULL) {
10796
            /* Generate salt into encoding. */
10797
0
            salt = (byte*)dataASN[P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_SALT].
10798
0
                data.buffer.data;
10799
0
            ret = wc_RNG_GenerateBlock(rng, salt, saltSz);
10800
0
        }
10801
0
    }
10802
0
    if (ret == 0) {
10803
0
        byte cbcIv[MAX_IV_SIZE];
10804
        /* Store PKCS#8 key in output buffer. */
10805
0
        byte* pkcs8 =
10806
0
            (byte*)dataASN[P8ENCPBES1ASN_IDX_ENCDATA].data.buffer.data;
10807
0
        XMEMCPY(pkcs8, input, inputSz);
10808
0
        (void)wc_PkcsPad(pkcs8, inputSz, (word32)blockSz);
10809
10810
        /* Encrypt PKCS#8 key inline. */
10811
0
        ret = wc_CryptKey(password, passwordSz, salt, (int)saltSz, itt, id,
10812
0
                          pkcs8, (int)pkcs8Sz, version, cbcIv, 1, 0);
10813
0
    }
10814
0
    if (ret == 0) {
10815
        /* Returning size on success. */
10816
0
        ret = sz;
10817
0
    }
10818
10819
0
    FREE_ASNSETDATA(dataASN, heap);
10820
0
    return ret;
10821
0
#endif /* WOLFSSL_ASN_TEMPLATE */
10822
0
}
10823
10824
10825
#endif /* HAVE_PKCS12 */
10826
#endif /* NO_PWDBASED */
10827
10828
/* Block padding used for PKCS#5, PKCS#7, PKCS#8 and PKCS#12.
10829
 *
10830
 * The length of padding is the value of each padding byte.
10831
 *
10832
 * When buf is NULL, the padded size is returned.
10833
 *
10834
 * @param [in, out] buf      Buffer of data to be padded. May be NULL.
10835
 * @param [in]      sz       Size of data in bytes.
10836
 * @param [in]      blockSz  Size of block, in bytes, which buffer size must be
10837
 *                           a multiple of. Assumed to be less than 256 and
10838
 *                           a power of 2.
10839
 * @return  Size of padded buffer in bytes.
10840
 */
10841
word32 wc_PkcsPad(byte* buf, word32 sz, word32 blockSz)
10842
0
{
10843
    /* Calculate number of padding bytes. */
10844
0
    word32 padSz = blockSz - (sz & (blockSz - 1));
10845
10846
    /* Pad with padSz byte. */
10847
0
    if (buf != NULL) {
10848
0
        word32 i;
10849
0
        for (i = 0; i < padSz; i++) {
10850
0
            buf[sz+i] = (byte)(padSz & 0xFF);
10851
0
        }
10852
0
    }
10853
10854
    /* Return padded buffer size in bytes. */
10855
0
    return sz + padSz;
10856
0
}
10857
10858
#ifndef NO_RSA
10859
#ifdef WOLFSSL_ASN_TEMPLATE
10860
/* ASN.1 template for an RSA public key.
10861
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
10862
 * PKCS #1: RFC 8017, A.1.1 - RSAPublicKey
10863
 */
10864
static const ASNItem rsaPublicKeyASN[] = {
10865
/*  SEQ            */ { 0, ASN_SEQUENCE, 1, 1, 0 },
10866
/*  ALGOID_SEQ     */     { 1, ASN_SEQUENCE, 1, 1, 0 },
10867
/*  ALGOID_OID     */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
10868
/*  ALGOID_NULL    */         { 2, ASN_TAG_NULL, 0, 0, 1 },
10869
#ifdef WC_RSA_PSS
10870
/*  ALGOID_P_SEQ   */         { 2, ASN_SEQUENCE, 1, 0, 1 },
10871
#endif
10872
/*  PUBKEY         */     { 1, ASN_BIT_STRING, 0, 1, 0 },
10873
                                                  /* RSAPublicKey */
10874
/*  PUBKEY_RSA_SEQ */         { 2, ASN_SEQUENCE, 1, 1, 0 },
10875
/*  PUBKEY_RSA_N   */             { 3, ASN_INTEGER, 0, 0, 0 },
10876
/*  PUBKEY_RSA_E   */             { 3, ASN_INTEGER, 0, 0, 0 },
10877
};
10878
enum {
10879
    RSAPUBLICKEYASN_IDX_SEQ = 0,
10880
    RSAPUBLICKEYASN_IDX_ALGOID_SEQ,
10881
    RSAPUBLICKEYASN_IDX_ALGOID_OID,
10882
    RSAPUBLICKEYASN_IDX_ALGOID_NULL,
10883
#ifdef WC_RSA_PSS
10884
    RSAPUBLICKEYASN_IDX_ALGOID_P_SEQ,
10885
#endif
10886
    RSAPUBLICKEYASN_IDX_PUBKEY,
10887
    RSAPUBLICKEYASN_IDX_PUBKEY_RSA_SEQ,
10888
    RSAPUBLICKEYASN_IDX_PUBKEY_RSA_N,
10889
    RSAPUBLICKEYASN_IDX_PUBKEY_RSA_E
10890
};
10891
10892
/* Number of items in ASN.1 template for an RSA public key. */
10893
0
#define rsaPublicKeyASN_Length (sizeof(rsaPublicKeyASN) / sizeof(ASNItem))
10894
#endif
10895
10896
#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_FSPSM_TLS)
10897
/* This function is to retrieve key position information in a cert.*
10898
 * The information will be used to call TSIP TLS-linked API for    *
10899
 * certificate verification.                                       */
10900
static int RsaPublicKeyDecodeRawIndex(const byte* input, word32* inOutIdx,
10901
                                      word32 inSz, word32* key_n,
10902
                                      word32* key_n_len, word32* key_e,
10903
                                      word32* key_e_len)
10904
{
10905
#ifndef WOLFSSL_ASN_TEMPLATE
10906
    int ret = 0;
10907
    int length = 0;
10908
10909
#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
10910
    byte b;
10911
#endif
10912
10913
    if (input == NULL || inOutIdx == NULL)
10914
        return BAD_FUNC_ARG;
10915
10916
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
10917
        return ASN_PARSE_E;
10918
10919
#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
10920
    if ((*inOutIdx + 1) > inSz)
10921
        return BUFFER_E;
10922
10923
    b = input[*inOutIdx];
10924
    if (b != ASN_INTEGER) {
10925
        /* not from decoded cert, will have algo id, skip past */
10926
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
10927
            return ASN_PARSE_E;
10928
10929
        if (SkipObjectId(input, inOutIdx, inSz) < 0)
10930
            return ASN_PARSE_E;
10931
10932
        /* Option NULL ASN.1 tag */
10933
        if (*inOutIdx  >= inSz) {
10934
            return BUFFER_E;
10935
        }
10936
        if (input[*inOutIdx] == ASN_TAG_NULL) {
10937
            ret = GetASNNull(input, inOutIdx, inSz);
10938
            if (ret != 0)
10939
                return ret;
10940
        }
10941
        /* TODO: support RSA PSS */
10942
10943
        /* should have bit tag length and seq next */
10944
        ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);
10945
        if (ret != 0)
10946
            return ret;
10947
10948
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
10949
            return ASN_PARSE_E;
10950
    }
10951
#endif /* OPENSSL_EXTRA */
10952
10953
    /* Get modulus */
10954
    ret = GetASNInt(input, inOutIdx, &length, inSz);
10955
    *key_n += *inOutIdx;
10956
    if (ret < 0) {
10957
        return ASN_RSA_KEY_E;
10958
    }
10959
    if (key_n_len)
10960
        *key_n_len = length;
10961
    *inOutIdx += length;
10962
10963
    /* Get exponent */
10964
    ret = GetASNInt(input, inOutIdx, &length, inSz);
10965
    *key_e += *inOutIdx;
10966
    if (ret < 0) {
10967
        return ASN_RSA_KEY_E;
10968
    }
10969
    if (key_e_len)
10970
        *key_e_len = length;
10971
    return ret;
10972
#else
10973
    int ret = 0;
10974
    const byte*  n   = NULL;
10975
    const byte*  e   = NULL; /* pointer to modulus/exponent */
10976
    word32 rawIndex = 0;
10977
10978
    ret = wc_RsaPublicKeyDecode_ex(input, inOutIdx, (word32)inSz,
10979
                                                &n, key_n_len, &e, key_e_len);
10980
    if (ret == 0) {
10981
        /* convert pointer to offset */
10982
        if (key_n != NULL) {
10983
            rawIndex = n - input;
10984
            *key_n += rawIndex;
10985
        }
10986
        if (key_e != NULL) {
10987
            rawIndex = e - input;
10988
            *key_e += rawIndex;
10989
        }
10990
    }
10991
    return ret;
10992
#endif
10993
10994
}
10995
#endif /* WOLFSSL_RENESAS_TSIP */
10996
/* Decode RSA public key.
10997
 *
10998
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
10999
 * PKCS #1: RFC 8017, A.1.1 - RSAPublicKey
11000
 *
11001
 * @param [in]      input     Buffer holding BER encoded data.
11002
 * @param [in, out] inOutIdx  On in, start of RSA public key.
11003
 *                            On out, start of ASN.1 item after RSA public key.
11004
 * @param [in]      inSz      Number of bytes in buffer.
11005
 * @param [out]     n         Pointer to modulus in buffer.
11006
 * @param [out]     nSz       Size of modulus in bytes.
11007
 * @param [out]     e         Pointer to exponent in buffer.
11008
 * @param [out]     eSz       Size of exponent in bytes.
11009
 * @return  0 on success.
11010
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
11011
 *          is invalid.
11012
 * @return  BUFFER_E when data in buffer is too small.
11013
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
11014
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
11015
 *          non-zero length.
11016
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
11017
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
11018
 */
11019
int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx, word32 inSz,
11020
    const byte** n, word32* nSz, const byte** e, word32* eSz)
11021
0
{
11022
#ifndef WOLFSSL_ASN_TEMPLATE
11023
    int ret = 0;
11024
    int length = 0;
11025
#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
11026
    word32 localIdx;
11027
    byte   tag;
11028
#endif
11029
11030
    if (input == NULL || inOutIdx == NULL)
11031
        return BAD_FUNC_ARG;
11032
11033
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
11034
        return ASN_PARSE_E;
11035
11036
#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
11037
    localIdx = *inOutIdx;
11038
    if (GetASNTag(input, &localIdx, &tag, inSz) < 0)
11039
        return BUFFER_E;
11040
11041
    if (tag != ASN_INTEGER) {
11042
        /* not from decoded cert, will have algo id, skip past */
11043
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
11044
            return ASN_PARSE_E;
11045
11046
        if (SkipObjectId(input, inOutIdx, inSz) < 0)
11047
            return ASN_PARSE_E;
11048
11049
        /* Option NULL ASN.1 tag */
11050
        if (*inOutIdx  >= inSz) {
11051
            return BUFFER_E;
11052
        }
11053
11054
        localIdx = *inOutIdx;
11055
        if (GetASNTag(input, &localIdx, &tag, inSz) < 0)
11056
            return ASN_PARSE_E;
11057
11058
        if (tag == ASN_TAG_NULL) {
11059
            ret = GetASNNull(input, inOutIdx, inSz);
11060
            if (ret != 0)
11061
                return ret;
11062
        }
11063
    #ifdef WC_RSA_PSS
11064
        /* Skip RSA PSS parameters. */
11065
        else if (tag == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
11066
            if (GetSequence(input, inOutIdx, &length, inSz) < 0)
11067
                return ASN_PARSE_E;
11068
            *inOutIdx += length;
11069
        }
11070
    #endif
11071
11072
        /* should have bit tag length and seq next */
11073
        ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);
11074
        if (ret != 0)
11075
            return ret;
11076
11077
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
11078
            return ASN_PARSE_E;
11079
    }
11080
#endif /* OPENSSL_EXTRA */
11081
11082
    /* Get modulus */
11083
    ret = GetASNInt(input, inOutIdx, &length, inSz);
11084
    if (ret < 0) {
11085
        return ASN_RSA_KEY_E;
11086
    }
11087
    if (nSz)
11088
        *nSz = (word32)length;
11089
    if (n)
11090
        *n = &input[*inOutIdx];
11091
    *inOutIdx += (word32)length;
11092
11093
    /* Get exponent */
11094
    ret = GetASNInt(input, inOutIdx, &length, inSz);
11095
    if (ret < 0) {
11096
        return ASN_RSA_KEY_E;
11097
    }
11098
    if (eSz)
11099
        *eSz = (word32)length;
11100
    if (e)
11101
        *e = &input[*inOutIdx];
11102
    *inOutIdx += (word32)length;
11103
11104
    return ret;
11105
#else
11106
0
    DECL_ASNGETDATA(dataASN, rsaPublicKeyASN_Length);
11107
0
    int ret = 0;
11108
0
#ifdef WC_RSA_PSS
11109
0
    word32 oid = RSAk;
11110
0
#endif
11111
11112
    /* Check validity of parameters. */
11113
0
    if (input == NULL || inOutIdx == NULL) {
11114
0
        ret = BAD_FUNC_ARG;
11115
0
    }
11116
11117
0
    CALLOC_ASNGETDATA(dataASN, rsaPublicKeyASN_Length, ret, NULL);
11118
11119
0
    if (ret == 0) {
11120
        /* Try decoding PKCS #1 public key by ignoring rest of ASN.1. */
11121
0
        ret = GetASN_Items(&rsaPublicKeyASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_SEQ],
11122
0
           &dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_SEQ],
11123
0
           (int)(rsaPublicKeyASN_Length - RSAPUBLICKEYASN_IDX_PUBKEY_RSA_SEQ),
11124
0
           0, input, inOutIdx, inSz);
11125
0
        if (ret != 0) {
11126
            /* Didn't work - try whole SubjectKeyInfo instead. */
11127
0
        #ifdef WC_RSA_PSS
11128
            /* Could be RSA or RSA PSS key. */
11129
0
            GetASN_OID(&dataASN[RSAPUBLICKEYASN_IDX_ALGOID_OID], oidKeyType);
11130
        #else
11131
            /* Set the OID to expect. */
11132
            GetASN_ExpBuffer(&dataASN[RSAPUBLICKEYASN_IDX_ALGOID_OID],
11133
                    keyRsaOid, sizeof(keyRsaOid));
11134
        #endif
11135
            /* Decode SubjectKeyInfo. */
11136
0
            ret = GetASN_Items(rsaPublicKeyASN, dataASN,
11137
0
                               rsaPublicKeyASN_Length, 1, input, inOutIdx,
11138
0
                               inSz);
11139
0
        }
11140
0
    }
11141
0
#ifdef WC_RSA_PSS
11142
0
    if ((ret == 0) && (dataASN[RSAPUBLICKEYASN_IDX_ALGOID_OID].tag != 0)) {
11143
        /* Two possible OIDs supported - RSA and RSA PSS. */
11144
0
        oid = dataASN[RSAPUBLICKEYASN_IDX_ALGOID_OID].data.oid.sum;
11145
0
        if ((oid != RSAk) && (oid != RSAPSSk)) {
11146
0
            ret = ASN_PARSE_E;
11147
0
        }
11148
0
    }
11149
0
    if ((ret == 0) && (dataASN[RSAPUBLICKEYASN_IDX_ALGOID_P_SEQ].tag != 0)) {
11150
        /* Can't have NULL and SEQ. */
11151
0
        if (dataASN[RSAPUBLICKEYASN_IDX_ALGOID_NULL].tag != 0) {
11152
0
            ret = ASN_PARSE_E;
11153
0
        }
11154
        /* SEQ present only with RSA PSS. */
11155
0
        if ((ret == 0) && (oid != RSAPSSk)) {
11156
0
            ret = ASN_PARSE_E;
11157
0
        }
11158
0
        if (ret == 0) {
11159
0
            enum wc_HashType hash;
11160
0
            int mgf;
11161
0
            int saltLen;
11162
0
            const byte* params = GetASNItem_Addr(
11163
0
                dataASN[RSAPUBLICKEYASN_IDX_ALGOID_P_SEQ], input);
11164
0
            word32 paramsSz = GetASNItem_Length(
11165
0
                dataASN[RSAPUBLICKEYASN_IDX_ALGOID_P_SEQ], input);
11166
11167
            /* Validate the private key parameters. */
11168
0
            ret = DecodeRsaPssParams(params, paramsSz, &hash, &mgf, &saltLen);
11169
            /* TODO: store parameters so that usage can be checked. */
11170
0
        }
11171
0
    }
11172
0
#endif
11173
0
    if (ret == 0) {
11174
        /* Return the buffers and lengths asked for. */
11175
0
        if (n != NULL) {
11176
0
            *n   = dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_N].data.ref.data;
11177
0
        }
11178
0
        if (nSz != NULL) {
11179
0
            *nSz = dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_N].data.ref.length;
11180
0
        }
11181
0
        if (e != NULL) {
11182
0
            *e   = dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_E].data.ref.data;
11183
0
        }
11184
0
        if (eSz != NULL) {
11185
0
            *eSz = dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_E].data.ref.length;
11186
0
        }
11187
0
    }
11188
11189
0
    FREE_ASNGETDATA(dataASN, NULL);
11190
0
    return ret;
11191
0
#endif /* WOLFSSL_ASN_TEMPLATE */
11192
0
}
11193
11194
/* Decode RSA public key.
11195
 *
11196
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
11197
 * PKCS #1: RFC 8017, A.1.1 - RSAPublicKey
11198
 *
11199
 * @param [in]      input     Buffer holding BER encoded data.
11200
 * @param [in, out] inOutIdx  On in, start of RSA public key.
11201
 *                            On out, start of ASN.1 item after RSA public key.
11202
 * @param [in, out] key       RSA key object.
11203
 * @param [in]      inSz      Number of bytes in buffer.
11204
 * @return  0 on success.
11205
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
11206
 *          is invalid.
11207
 * @return  BUFFER_E when data in buffer is too small.
11208
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
11209
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
11210
 *          non-zero length.
11211
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
11212
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
11213
 */
11214
int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
11215
                       word32 inSz)
11216
0
{
11217
0
    int ret;
11218
0
    const byte *n = NULL, *e = NULL;
11219
0
    word32 nSz = 0, eSz = 0;
11220
11221
0
    if (key == NULL)
11222
0
        return BAD_FUNC_ARG;
11223
11224
0
    ret = wc_RsaPublicKeyDecode_ex(input, inOutIdx, inSz, &n, &nSz, &e, &eSz);
11225
0
    if (ret == 0) {
11226
0
        ret = wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz, key);
11227
0
    }
11228
11229
0
    return ret;
11230
0
}
11231
#endif /* !NO_RSA */
11232
11233
#ifndef NO_DH
11234
#if defined(WOLFSSL_DH_EXTRA)
11235
/*
11236
 * Decodes DH public key to fill specified DhKey.
11237
 *
11238
 * return 0 on success, negative on failure
11239
 */
11240
int wc_DhPublicKeyDecode(const byte* input, word32* inOutIdx,
11241
                DhKey* key, word32 inSz)
11242
{
11243
    int ret = 0;
11244
    int length;
11245
    word32 oid = 0;
11246
11247
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
11248
        return BAD_FUNC_ARG;
11249
11250
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
11251
        return ASN_PARSE_E;
11252
11253
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
11254
        return ASN_PARSE_E;
11255
11256
    ret = GetObjectId(input, inOutIdx, &oid, oidKeyType, inSz);
11257
    if (oid != DHk || ret < 0)
11258
        return ASN_DH_KEY_E;
11259
11260
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
11261
        return ASN_PARSE_E;
11262
11263
    if (GetInt(&key->p, input, inOutIdx, inSz) < 0)
11264
        return ASN_DH_KEY_E;
11265
11266
    if (GetInt(&key->g, input, inOutIdx, inSz) < 0) {
11267
        mp_clear(&key->p);
11268
        return ASN_DH_KEY_E;
11269
    }
11270
    ret = (CheckBitString(input, inOutIdx, &length, inSz, 0, NULL) == 0);
11271
    if (ret > 0) {
11272
        /* Found Bit String WOLFSSL_DH_EXTRA is required to access DhKey.pub */
11273
        if (GetInt(&key->pub, input, inOutIdx, inSz) < 0) {
11274
            mp_clear(&key->p);
11275
            mp_clear(&key->g);
11276
            return ASN_DH_KEY_E;
11277
        }
11278
    }
11279
    else {
11280
        mp_clear(&key->p);
11281
        mp_clear(&key->g);
11282
        return ASN_DH_KEY_E;
11283
    }
11284
    return 0;
11285
}
11286
#endif /* WOLFSSL_DH_EXTRA */
11287
11288
#ifdef WOLFSSL_ASN_TEMPLATE
11289
/* ASN.1 template for DH key.
11290
 * PKCS #3, 9 - DHParameter.
11291
 * (Also in: RFC 2786, 3)
11292
 */
11293
static const ASNItem dhParamASN[] = {
11294
/* SEQ     */    { 0, ASN_SEQUENCE, 1, 1, 0 },
11295
                /* prime */
11296
/* PRIME   */        { 1, ASN_INTEGER, 0, 0, 0 },
11297
                /* base */
11298
/* BASE    */        { 1, ASN_INTEGER, 0, 0, 0 },
11299
                /* privateValueLength */
11300
/* PRIVLEN */        { 1, ASN_INTEGER, 0, 0, 1 },
11301
};
11302
enum {
11303
    DHPARAMASN_IDX_SEQ = 0,
11304
    DHPARAMASN_IDX_PRIME,
11305
    DHPARAMASN_IDX_BASE,
11306
    DHPARAMASN_IDX_PRIVLEN
11307
};
11308
11309
/* Number of items in ASN.1 template for DH key. */
11310
0
#define dhParamASN_Length (sizeof(dhParamASN) / sizeof(ASNItem))
11311
11312
#ifdef WOLFSSL_DH_EXTRA
11313
/* ASN.1 template for DH key wrapped in PKCS #8 or SubjectPublicKeyInfo.
11314
 * PKCS #8: RFC 5208, 5 - PrivateKeyInfo
11315
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
11316
 * RFC 3279, 2.3.3 - DH in SubjectPublicKeyInfo
11317
 */
11318
static const ASNItem dhKeyPkcs8ASN[] = {
11319
/* SEQ                  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
11320
/* VER                  */     { 1, ASN_INTEGER, 0, 0, 1 },
11321
/* PKEYALGO_SEQ         */     { 1, ASN_SEQUENCE, 1, 1, 0 },
11322
/* PKEYALGO_OID         */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
11323
                                                     /* DHParameter */
11324
/* PKEYALGO_PARAM_SEQ   */         { 2, ASN_SEQUENCE, 1, 1, 0 },
11325
                                                         /* p */
11326
/* PKEYALGO_PARAM_P     */             { 3, ASN_INTEGER, 0, 0, 0 },
11327
                                                         /* g */
11328
/* PKEYALGO_PARAM_G     */             { 3, ASN_INTEGER, 0, 0, 0 },
11329
                                                         /* q - factor of p-1 */
11330
/* PKEYALGO_PARAM_Q     */             { 3, ASN_INTEGER, 0, 0, 1 },
11331
                                                         /* j - subgroup factor */
11332
/* PKEYALGO_PARAM_J     */             { 3, ASN_INTEGER, 0, 0, 1 },
11333
                                                         /* ValidationParms */
11334
/* PKEYALGO_PARAM_VALID */             { 3, ASN_SEQUENCE, 0, 0, 1 },
11335
                                                 /* PrivateKey - PKCS #8 */
11336
/* PKEY_STR             */     { 1, ASN_OCTET_STRING, 0, 1, 2 },
11337
/* PKEY_INT             */         { 2, ASN_INTEGER, 0, 0, 0 },
11338
                                                 /* PublicKey - SubjectPublicKeyInfo. */
11339
/* PUBKEY_STR           */     { 1, ASN_BIT_STRING, 0, 1, 2 },
11340
/* PUBKEY_INT           */         { 2, ASN_INTEGER, 0, 0, 0 },
11341
};
11342
enum {
11343
    DHKEYPKCS8ASN_IDX_SEQ = 0,
11344
    DHKEYPKCS8ASN_IDX_VER,
11345
    DHKEYPKCS8ASN_IDX_PKEYALGO_SEQ,
11346
    DHKEYPKCS8ASN_IDX_PKEYALGO_OID,
11347
    DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_SEQ,
11348
    DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_P,
11349
    DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_G,
11350
    DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_Q,
11351
    DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_J,
11352
    DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_VALID,
11353
    DHKEYPKCS8ASN_IDX_PKEY_STR,
11354
    DHKEYPKCS8ASN_IDX_PKEY_INT,
11355
    DHKEYPKCS8ASN_IDX_PUBKEY_STR,
11356
    DHKEYPKCS8ASN_IDX_PUBKEY_INT
11357
};
11358
11359
#define dhKeyPkcs8ASN_Length (sizeof(dhKeyPkcs8ASN) / sizeof(ASNItem))
11360
#endif
11361
#endif
11362
11363
/* Decodes either PKCS#3 DH parameters or PKCS#8 DH key file (WOLFSSL_DH_EXTRA).
11364
 *
11365
 * See also wc_DhParamsLoad(). Loads directly into buffers rather than key
11366
 * object.
11367
 *
11368
 * @param [in]      input     BER/DER encoded data.
11369
 * @param [in, out] inOutIdx  On in, start of DH key data.
11370
 *                            On out, end of DH key data.
11371
 * @param [in, out] key       DH key object.
11372
 * @param [in]      inSz      Size of data in bytes.
11373
 * @return  0 on success.
11374
 * @return  BAD_FUNC_ARG when input, inOutIDx or key is NULL.
11375
 * @return  MEMORY_E when dynamic memory allocation fails.
11376
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
11377
 *          is invalid.
11378
 * @return  BUFFER_E when data in buffer is too small.
11379
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
11380
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
11381
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
11382
 *          non-zero length.
11383
 * @return  MP_INIT_E when the unable to initialize an mp_int.
11384
 * @return  ASN_GETINT_E when the unable to convert data to an mp_int.
11385
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
11386
 */
11387
int wc_DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32 inSz)
11388
0
{
11389
#ifndef WOLFSSL_ASN_TEMPLATE
11390
    int ret = 0;
11391
    int length;
11392
#ifdef WOLFSSL_DH_EXTRA
11393
    #if !defined(HAVE_FIPS) || \
11394
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
11395
    word32 oid = 0, temp = 0;
11396
    #endif
11397
#endif
11398
11399
    WOLFSSL_ENTER("wc_DhKeyDecode");
11400
11401
    if (inOutIdx == NULL)
11402
        return BAD_FUNC_ARG;
11403
11404
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
11405
        return ASN_PARSE_E;
11406
11407
#ifdef WOLFSSL_DH_EXTRA
11408
    #if !defined(HAVE_FIPS) || \
11409
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
11410
    temp = *inOutIdx;
11411
    #endif
11412
#endif
11413
    /* Assume input started after 1.2.840.113549.1.3.1 dhKeyAgreement */
11414
    if (GetInt(&key->p, input, inOutIdx, inSz) < 0) {
11415
        ret = ASN_DH_KEY_E;
11416
    }
11417
    if (ret == 0 && GetInt(&key->g, input, inOutIdx, inSz) < 0) {
11418
        mp_clear(&key->p);
11419
        ret = ASN_DH_KEY_E;
11420
    }
11421
11422
#ifdef WOLFSSL_DH_EXTRA
11423
    #if !defined(HAVE_FIPS) || \
11424
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
11425
    /* If ASN_DH_KEY_E: Check if input started at beginning of key */
11426
    if (ret == WC_NO_ERR_TRACE(ASN_DH_KEY_E)) {
11427
        *inOutIdx = temp;
11428
11429
        /* the version (0) - private only (for public skip) */
11430
        if (GetASNInt(input, inOutIdx, &length, inSz) == 0) {
11431
            *inOutIdx += (word32)length;
11432
        }
11433
11434
        /* Size of dhKeyAgreement section */
11435
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
11436
            return ASN_PARSE_E;
11437
11438
        /* Check for dhKeyAgreement */
11439
        ret = GetObjectId(input, inOutIdx, &oid, oidKeyType, inSz);
11440
        if (oid != DHk || ret < 0)
11441
            return ASN_DH_KEY_E;
11442
11443
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
11444
            return ASN_PARSE_E;
11445
11446
        if (GetInt(&key->p, input, inOutIdx, inSz) < 0) {
11447
            return ASN_DH_KEY_E;
11448
        }
11449
        if (ret == 0 && GetInt(&key->g, input, inOutIdx, inSz) < 0) {
11450
            mp_clear(&key->p);
11451
            return ASN_DH_KEY_E;
11452
        }
11453
    }
11454
11455
    temp = *inOutIdx;
11456
    ret = (CheckBitString(input, inOutIdx, &length, inSz, 0, NULL) == 0);
11457
    if (ret > 0) {
11458
        /* Found Bit String */
11459
        if (GetInt(&key->pub, input, inOutIdx, inSz) == 0) {
11460
            WOLFSSL_MSG("Found Public Key");
11461
            ret = 0;
11462
        }
11463
    } else {
11464
        *inOutIdx = temp;
11465
        ret = (GetOctetString(input, inOutIdx, &length, inSz) >= 0);
11466
        if (ret > 0) {
11467
            /* Found Octet String */
11468
            if (GetInt(&key->priv, input, inOutIdx, inSz) == 0) {
11469
                WOLFSSL_MSG("Found Private Key");
11470
11471
                /* Compute public */
11472
                ret = mp_exptmod(&key->g, &key->priv, &key->p, &key->pub);
11473
            }
11474
        } else {
11475
            /* Don't use length from failed CheckBitString/GetOctetString */
11476
            *inOutIdx = temp;
11477
            ret = 0;
11478
        }
11479
    }
11480
    #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
11481
#endif /* WOLFSSL_DH_EXTRA */
11482
11483
    WOLFSSL_LEAVE("wc_DhKeyDecode", ret);
11484
11485
    return ret;
11486
#else
11487
#ifdef WOLFSSL_DH_EXTRA
11488
    DECL_ASNGETDATA(dataASN, dhKeyPkcs8ASN_Length);
11489
#else
11490
0
    DECL_ASNGETDATA(dataASN, dhParamASN_Length);
11491
0
#endif
11492
0
    int ret = 0;
11493
11494
    /* Check input parameters are valid. */
11495
0
    if ((input == NULL) || (inOutIdx == NULL) || (key == NULL)) {
11496
0
        ret = BAD_FUNC_ARG;
11497
0
    }
11498
11499
#ifdef WOLFSSL_DH_EXTRA
11500
    ALLOC_ASNGETDATA(dataASN, dhKeyPkcs8ASN_Length, ret, key->heap);
11501
#else
11502
0
    ALLOC_ASNGETDATA(dataASN, dhParamASN_Length, ret, key->heap);
11503
0
#endif
11504
11505
0
    if (ret == 0) {
11506
        /* Initialize data and set mp_ints to hold p and g. */
11507
0
        XMEMSET(dataASN, 0, sizeof(*dataASN) * dhParamASN_Length);
11508
0
        GetASN_MP(&dataASN[DHPARAMASN_IDX_PRIME], &key->p);
11509
0
        GetASN_MP(&dataASN[DHPARAMASN_IDX_BASE], &key->g);
11510
        /* Try simple PKCS #3 template. */
11511
0
        ret = GetASN_Items(dhParamASN, dataASN, dhParamASN_Length, 1, input,
11512
0
                           inOutIdx, inSz);
11513
#ifdef WOLFSSL_DH_EXTRA
11514
        if (ret != 0) {
11515
            mp_free(&key->p);
11516
            mp_free(&key->g);
11517
11518
            /* Initialize data and set mp_ints to hold p, g, q, priv and pub. */
11519
            XMEMSET(dataASN, 0, sizeof(*dataASN) * dhKeyPkcs8ASN_Length);
11520
            GetASN_ExpBuffer(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_OID],
11521
                    keyDhOid, sizeof(keyDhOid));
11522
            GetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_P], &key->p);
11523
            GetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_G], &key->g);
11524
            GetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_Q], &key->q);
11525
            GetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEY_INT], &key->priv);
11526
            GetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PUBKEY_INT], &key->pub);
11527
            /* Try PKCS #8 wrapped template. */
11528
            ret = GetASN_Items(dhKeyPkcs8ASN, dataASN, dhKeyPkcs8ASN_Length, 1,
11529
                               input, inOutIdx, inSz);
11530
            if (ret == 0) {
11531
                /* VERSION only present in PKCS #8 private key structure */
11532
                if ((dataASN[DHKEYPKCS8ASN_IDX_PKEY_INT].length != 0) &&
11533
                        (dataASN[DHKEYPKCS8ASN_IDX_VER].length == 0)) {
11534
                    ret = ASN_PARSE_E;
11535
                }
11536
                else if ((dataASN[DHKEYPKCS8ASN_IDX_PUBKEY_INT].length != 0) &&
11537
                        (dataASN[DHKEYPKCS8ASN_IDX_VER].length != 0)) {
11538
                    ret = ASN_PARSE_E;
11539
                }
11540
            }
11541
            if ((ret == 0) && mp_iszero(&key->pub)) {
11542
                ret = mp_exptmod(&key->g, &key->priv, &key->p, &key->pub);
11543
            }
11544
        }
11545
#endif
11546
0
    }
11547
11548
0
    FREE_ASNGETDATA(dataASN, key->heap);
11549
0
    return ret;
11550
0
#endif /* WOLFSSL_ASN_TEMPLATE */
11551
0
}
11552
11553
#ifdef WOLFSSL_DH_EXTRA
11554
11555
/* Export DH Key (private or public) */
11556
int wc_DhKeyToDer(DhKey* key, byte* output, word32* outSz, int exportPriv)
11557
{
11558
#ifndef WOLFSSL_ASN_TEMPLATE
11559
    int ret, privSz = 0, pubSz = 0;
11560
    word32 keySz, idx, len, total;
11561
11562
    if (key == NULL || outSz == NULL) {
11563
        return BAD_FUNC_ARG;
11564
    }
11565
11566
    /* determine size */
11567
    if (exportPriv) {
11568
        /* octet string: priv */
11569
        privSz = SetASNIntMP(&key->priv, -1, NULL);
11570
        if (privSz < 0)
11571
            return privSz;
11572
        idx = 1 + SetLength((word32)privSz, NULL) +
11573
            (word32)privSz; /* +1 for ASN_OCTET_STRING */
11574
    }
11575
    else {
11576
        /* bit string: public */
11577
        pubSz = SetASNIntMP(&key->pub, -1, NULL);
11578
        if (pubSz < 0)
11579
            return pubSz;
11580
        idx = SetBitString((word32)pubSz, 0, NULL) + (word32)pubSz;
11581
    }
11582
    keySz = idx;
11583
11584
    /* DH Parameters sequence with P and G */
11585
    total = 0;
11586
    ret = wc_DhParamsToDer(key, NULL, &total);
11587
    if (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E))
11588
        return ret;
11589
    idx += total;
11590
11591
    /* object dhKeyAgreement 1.2.840.113549.1.3.1 */
11592
    idx += (word32)SetObjectId(sizeof(keyDhOid), NULL);
11593
    idx += (word32)sizeof(keyDhOid);
11594
    len = idx - keySz;
11595
    /* sequence - all but pub/priv */
11596
    idx += SetSequence(len, NULL);
11597
    if (exportPriv) {
11598
        /* version: 0 (ASN_INTEGER, 0x01, 0x00) */
11599
        idx += 3;
11600
    }
11601
    /* sequence */
11602
    total = idx + SetSequence(idx, NULL);
11603
11604
    /* if no output, then just getting size */
11605
    if (output == NULL) {
11606
        *outSz = total;
11607
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
11608
    }
11609
11610
    /* make sure output fits in buffer */
11611
    if (total > *outSz) {
11612
        return BUFFER_E;
11613
    }
11614
    total = idx;
11615
11616
    /* sequence */
11617
    idx = SetSequence(total, output);
11618
    if (exportPriv) {
11619
        /* version: 0 */
11620
        idx += (word32)SetMyVersion(0, output + idx, 0);
11621
    }
11622
    /* sequence - all but pub/priv */
11623
    idx += SetSequence(len, output + idx);
11624
    /* object dhKeyAgreement 1.2.840.113549.1.3.1 */
11625
    idx += (word32)SetObjectId(sizeof(keyDhOid), output + idx);
11626
    XMEMCPY(output + idx, keyDhOid, sizeof(keyDhOid));
11627
    idx += sizeof(keyDhOid);
11628
11629
    /* DH Parameters sequence with P and G */
11630
    total = *outSz - idx;
11631
    ret = wc_DhParamsToDer(key, output + idx, &total);
11632
    if (ret < 0)
11633
        return ret;
11634
    idx += total;
11635
11636
    /* octet string: priv */
11637
    if (exportPriv) {
11638
        idx += (word32)SetOctetString((word32)privSz, output + idx);
11639
        idx += (word32)SetASNIntMP(&key->priv, -1, output + idx);
11640
    }
11641
    else {
11642
        /* bit string: public */
11643
        idx += (word32)SetBitString((word32)pubSz, 0, output + idx);
11644
        idx += (word32)SetASNIntMP(&key->pub, -1, output + idx);
11645
    }
11646
    *outSz = idx;
11647
11648
    return (int)idx;
11649
#else
11650
    ASNSetData dataASN[dhKeyPkcs8ASN_Length];
11651
    int ret = 0;
11652
    int sz;
11653
11654
    WOLFSSL_ENTER("wc_DhKeyToDer");
11655
11656
    XMEMSET(dataASN, 0, sizeof(dataASN));
11657
    SetASN_Int8Bit(&dataASN[DHKEYPKCS8ASN_IDX_VER], 0);
11658
    SetASN_OID(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_OID], DHk, oidKeyType);
11659
    /* Set mp_int containing p and g. */
11660
    SetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_P], &key->p);
11661
    SetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_G], &key->g);
11662
    dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_Q].noOut = 1;
11663
    dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_J].noOut = 1;
11664
    dataASN[DHKEYPKCS8ASN_IDX_PKEYALGO_PARAM_VALID].noOut = 1;
11665
11666
    if (exportPriv) {
11667
        SetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PKEY_INT], &key->priv);
11668
        dataASN[DHKEYPKCS8ASN_IDX_PUBKEY_STR].noOut = 1;
11669
        dataASN[DHKEYPKCS8ASN_IDX_PUBKEY_INT].noOut = 1;
11670
    }
11671
    else {
11672
        dataASN[DHKEYPKCS8ASN_IDX_VER].noOut = 1;
11673
        dataASN[DHKEYPKCS8ASN_IDX_PKEY_STR].noOut = 1;
11674
        dataASN[DHKEYPKCS8ASN_IDX_PKEY_INT].noOut = 1;
11675
        SetASN_MP(&dataASN[DHKEYPKCS8ASN_IDX_PUBKEY_INT], &key->pub);
11676
    }
11677
11678
    /* Calculate the size of the DH parameters. */
11679
    ret = SizeASN_Items(dhKeyPkcs8ASN, dataASN, dhKeyPkcs8ASN_Length, &sz);
11680
    if (output == NULL) {
11681
        *outSz = (word32)sz;
11682
        ret = WC_NO_ERR_TRACE(LENGTH_ONLY_E);
11683
    }
11684
    /* Check buffer is big enough for encoding. */
11685
    if ((ret == 0) && ((int)*outSz < sz)) {
11686
        ret = BUFFER_E;
11687
    }
11688
    if (ret == 0) {
11689
        /* Encode the DH parameters into buffer. */
11690
        SetASN_Items(dhKeyPkcs8ASN, dataASN, dhKeyPkcs8ASN_Length, output);
11691
        /* Set the actual encoding size. */
11692
        *outSz = (word32)sz;
11693
        /* Return the actual encoding size. */
11694
        ret = sz;
11695
    }
11696
11697
    return ret;
11698
#endif
11699
}
11700
11701
int wc_DhPubKeyToDer(DhKey* key, byte* out, word32* outSz)
11702
{
11703
    return wc_DhKeyToDer(key, out, outSz, 0);
11704
}
11705
int wc_DhPrivKeyToDer(DhKey* key, byte* out, word32* outSz)
11706
{
11707
    return wc_DhKeyToDer(key, out, outSz, 1);
11708
}
11709
11710
11711
/* Convert DH key parameters to DER format, write to output (outSz)
11712
 * If output is NULL then max expected size is set to outSz and LENGTH_ONLY_E is
11713
 * returned.
11714
 *
11715
 * Note : static function due to redefinition complications with DhKey and FIPS
11716
 * version 2 build.
11717
 *
11718
 * return bytes written on success */
11719
int wc_DhParamsToDer(DhKey* key, byte* output, word32* outSz)
11720
{
11721
#ifndef WOLFSSL_ASN_TEMPLATE
11722
    int ret;
11723
    word32 idx, total;
11724
11725
    if (key == NULL || outSz == NULL) {
11726
        return BAD_FUNC_ARG;
11727
    }
11728
11729
    /* determine size */
11730
    /* integer - g */
11731
    ret = SetASNIntMP(&key->g, -1, NULL);
11732
    if (ret < 0)
11733
        return ret;
11734
    idx = (word32)ret;
11735
    /* integer - p */
11736
    ret = SetASNIntMP(&key->p, -1, NULL);
11737
    if (ret < 0)
11738
        return ret;
11739
    idx += (word32)ret;
11740
    total = idx;
11741
     /* sequence */
11742
    idx += SetSequence(idx, NULL);
11743
11744
    if (output == NULL) {
11745
        *outSz = idx;
11746
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
11747
    }
11748
    /* make sure output fits in buffer */
11749
    if (idx > *outSz) {
11750
        return BUFFER_E;
11751
    }
11752
11753
11754
    /* write DH parameters */
11755
    /* sequence - for P and G only */
11756
    idx = SetSequence(total, output);
11757
    /* integer - p */
11758
    ret = SetASNIntMP(&key->p, -1, output + idx);
11759
    if (ret < 0)
11760
        return ret;
11761
    idx += (word32)ret;
11762
    /* integer - g */
11763
    ret = SetASNIntMP(&key->g, -1, output + idx);
11764
    if (ret < 0)
11765
        return ret;
11766
    idx += (word32)ret;
11767
    *outSz = idx;
11768
11769
    return (int)idx;
11770
#else
11771
    ASNSetData dataASN[dhParamASN_Length];
11772
    int ret = 0;
11773
    int sz = 0;
11774
11775
    WOLFSSL_ENTER("wc_DhParamsToDer");
11776
11777
    if (key == NULL || outSz == NULL) {
11778
        ret = BAD_FUNC_ARG;
11779
    }
11780
11781
    if (ret == 0) {
11782
        XMEMSET(dataASN, 0, sizeof(dataASN));
11783
        /* Set mp_int containing p and g. */
11784
        SetASN_MP(&dataASN[DHPARAMASN_IDX_PRIME], &key->p);
11785
        SetASN_MP(&dataASN[DHPARAMASN_IDX_BASE], &key->g);
11786
        /* privateValueLength not encoded. */
11787
        dataASN[DHPARAMASN_IDX_PRIVLEN].noOut = 1;
11788
11789
        /* Calculate the size of the DH parameters. */
11790
        ret = SizeASN_Items(dhParamASN, dataASN, dhParamASN_Length, &sz);
11791
    }
11792
    if ((ret == 0) && (output == NULL)) {
11793
        *outSz = (word32)sz;
11794
        ret = WC_NO_ERR_TRACE(LENGTH_ONLY_E);
11795
    }
11796
    /* Check buffer is big enough for encoding. */
11797
    if ((ret == 0) && (*outSz < (word32)sz)) {
11798
        ret = BUFFER_E;
11799
    }
11800
    if (ret == 0) {
11801
        /* Encode the DH parameters into buffer. */
11802
        SetASN_Items(dhParamASN, dataASN, dhParamASN_Length, output);
11803
        /* Set the actual encoding size. */
11804
        *outSz = (word32)sz;
11805
        /* Return count of bytes written. */
11806
        ret = sz;
11807
    }
11808
11809
    return ret;
11810
#endif
11811
}
11812
11813
#endif /* WOLFSSL_DH_EXTRA */
11814
11815
/* Decode DH parameters.
11816
 *
11817
 * PKCS #3, 9 - DHParameter.
11818
 * (Also in: RFC 2786, 3)
11819
 *
11820
 * @param [in]      input     Buffer holding BER encoded data.
11821
 * @param [in, out] inOutIdx  On in, start of RSA public key.
11822
 *                            On out, start of ASN.1 item after RSA public key.
11823
 * @param [in]      inSz      Number of bytes in buffer.
11824
 * @param [in, out] p         Buffer to hold prime.
11825
 * @param [out]     pInOutSz  On in, size of buffer to hold prime in bytes.
11826
 *                            On out, size of prime in bytes.
11827
 * @param [in, out] g         Buffer to hold base.
11828
 * @param [out]     gInOutSz  On in, size of buffer to hold base in bytes.
11829
 *                            On out, size of base in bytes.
11830
 * @return  0 on success.
11831
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
11832
 *          is invalid.
11833
 * @return  BUFFER_E when data in buffer is too small.
11834
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set.
11835
 */
11836
int wc_DhParamsLoad(const byte* input, word32 inSz, byte* p, word32* pInOutSz,
11837
                 byte* g, word32* gInOutSz)
11838
0
{
11839
#ifndef WOLFSSL_ASN_TEMPLATE
11840
    word32 idx = 0;
11841
    int    ret;
11842
    int    length;
11843
11844
    if (GetSequence(input, &idx, &length, inSz) <= 0)
11845
        return ASN_PARSE_E;
11846
11847
    ret = GetASNInt(input, &idx, &length, inSz);
11848
    if (ret != 0)
11849
        return ret;
11850
11851
    if (length <= (int)*pInOutSz) {
11852
        XMEMCPY(p, &input[idx], (size_t)length);
11853
        *pInOutSz = (word32)length;
11854
    }
11855
    else {
11856
        return BUFFER_E;
11857
    }
11858
    idx += (word32)length;
11859
11860
    ret = GetASNInt(input, &idx, &length, inSz);
11861
    if (ret != 0)
11862
        return ret;
11863
11864
    if (length <= (int)*gInOutSz) {
11865
        XMEMCPY(g, &input[idx], (size_t)length);
11866
        *gInOutSz = (word32)length;
11867
    }
11868
    else {
11869
        return BUFFER_E;
11870
    }
11871
11872
    return 0;
11873
#else
11874
0
    DECL_ASNGETDATA(dataASN, dhParamASN_Length);
11875
0
    word32 idx = 0;
11876
0
    int ret = 0;
11877
11878
    /* Make sure pointers are valid before use. */
11879
0
    if ((input == NULL) || (p == NULL) || (pInOutSz == NULL) || (g == NULL) ||
11880
0
            (gInOutSz == NULL)) {
11881
0
        ret = BAD_FUNC_ARG;
11882
0
    }
11883
11884
0
    CALLOC_ASNGETDATA(dataASN, dhParamASN_Length, ret, NULL);
11885
11886
0
    if (ret == 0) {
11887
        /* Set the buffers to copy p and g into. */
11888
0
        GetASN_Buffer(&dataASN[DHPARAMASN_IDX_PRIME], p, pInOutSz);
11889
0
        GetASN_Buffer(&dataASN[DHPARAMASN_IDX_BASE], g, gInOutSz);
11890
        /* Decode the DH Parameters. */
11891
0
        ret = GetASN_Items(dhParamASN, dataASN, dhParamASN_Length, 1, input,
11892
0
                           &idx, inSz);
11893
0
    }
11894
11895
0
    FREE_ASNGETDATA(dataASN, NULL);
11896
0
    return ret;
11897
0
#endif /* WOLFSSL_ASN_TEMPLATE */
11898
0
}
11899
#endif /* !NO_DH */
11900
11901
11902
#ifndef NO_DSA
11903
11904
static mp_int* GetDsaInt(DsaKey* key, int idx)
11905
{
11906
    if (idx == 0)
11907
        return &key->p;
11908
    if (idx == 1)
11909
        return &key->q;
11910
    if (idx == 2)
11911
        return &key->g;
11912
    if (idx == 3)
11913
        return &key->y;
11914
    if (idx == 4)
11915
        return &key->x;
11916
11917
    return NULL;
11918
}
11919
11920
#ifdef WOLFSSL_ASN_TEMPLATE
11921
/* ASN.1 template for DSA public and private keys.
11922
 * Public key: seq, p, q, g, y
11923
 * Private key: seq, version, p, q, g, y, x
11924
 * RFC 3279, 2.3.2 - DSA in SubjectPublicKeyInfo
11925
 */
11926
static const ASNItem dsaKeyASN[] = {
11927
/* SEQ */    { 0, ASN_SEQUENCE, 1, 1, 0 },
11928
/* VER */        { 1, ASN_INTEGER, 0, 0, 0 },
11929
/* P   */        { 1, ASN_INTEGER, 0, 0, 0 },
11930
/* Q   */        { 1, ASN_INTEGER, 0, 0, 0 },
11931
/* G   */        { 1, ASN_INTEGER, 0, 0, 0 },
11932
/* Y   */        { 1, ASN_INTEGER, 0, 0, 0 },
11933
/* X   */        { 1, ASN_INTEGER, 0, 0, 0 },
11934
};
11935
enum {
11936
    DSAKEYASN_IDX_SEQ = 0,
11937
    DSAKEYASN_IDX_VER,
11938
    DSAKEYASN_IDX_P,
11939
    DSAKEYASN_IDX_Q,
11940
    DSAKEYASN_IDX_G,
11941
    DSAKEYASN_IDX_Y,
11942
    DSAKEYASN_IDX_X
11943
};
11944
11945
/* Number of items in ASN.1 template for DSA private key. */
11946
#define dsaKeyASN_Length (sizeof(dsaKeyASN) / sizeof(ASNItem))
11947
/* Number of items in ASN.1 template for DSA public key. */
11948
#define dsaPublicKeyASN_Length ((sizeof(dsaKeyASN) / sizeof(ASNItem)) - 2)
11949
11950
/* ASN.1 template for PublicKeyInfo with DSA.
11951
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
11952
 * RFC 3279, 2.3.2 - DSA in SubjectPublicKeyInfo
11953
 */
11954
static const ASNItem dsaPubKeyASN[] = {
11955
/* SEQ             */ { 0, ASN_SEQUENCE, 1, 1, 0 },
11956
/* ALGOID_SEQ      */     { 1, ASN_SEQUENCE, 1, 1, 0 },
11957
/* ALGOID_OID      */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
11958
/* ALGOID_PARAMS   */         { 2, ASN_SEQUENCE, 1, 1, 0 },
11959
                                                   /* p */
11960
/* ALGOID_PARAMS_P */             { 3, ASN_INTEGER, 0, 0, 0 },
11961
                                                   /* q */
11962
/* ALGOID_PARAMS_Q */             { 3, ASN_INTEGER, 0, 0, 0 },
11963
                                                   /* g */
11964
/* ALGOID_PARAMS_G */             { 3, ASN_INTEGER, 0, 0, 0 },
11965
/* PUBKEY_STR      */     { 1, ASN_BIT_STRING, 0, 1, 1 },
11966
                                               /* y */
11967
/* PUBKEY_Y        */         { 2, ASN_INTEGER, 0, 0, 0 },
11968
};
11969
enum {
11970
    DSAPUBKEYASN_IDX_SEQ = 0,
11971
    DSAPUBKEYASN_IDX_ALGOID_SEQ,
11972
    DSAPUBKEYASN_IDX_ALGOID_OID,
11973
    DSAPUBKEYASN_IDX_ALGOID_PARAMS,
11974
    DSAPUBKEYASN_IDX_ALGOID_PARAMS_P,
11975
    DSAPUBKEYASN_IDX_ALGOID_PARAMS_Q,
11976
    DSAPUBKEYASN_IDX_ALGOID_PARAMS_G,
11977
    DSAPUBKEYASN_IDX_PUBKEY_STR,
11978
    DSAPUBKEYASN_IDX_PUBKEY_Y
11979
};
11980
11981
/* Number of items in ASN.1 template for PublicKeyInfo with DSA. */
11982
#define dsaPubKeyASN_Length (sizeof(dsaPubKeyASN) / sizeof(ASNItem))
11983
#endif /* WOLFSSL_ASN_TEMPLATE */
11984
11985
/* Decode DSA public key.
11986
 *
11987
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
11988
 * RFC 3279, 2.3.2 - DSA in SubjectPublicKeyInfo
11989
 *
11990
 * @param [in]      input     Buffer holding BER encoded data.
11991
 * @param [in, out] inOutIdx  On in, start of DSA public key.
11992
 *                            On out, start of ASN.1 item after DSA public key.
11993
 * @param [in, out] key       DSA key object.
11994
 * @param [in]      inSz      Number of bytes in buffer.
11995
 * @return  0 on success.
11996
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
11997
 *          is invalid.
11998
 * @return  BUFFER_E when data in buffer is too small.
11999
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
12000
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
12001
 *          non-zero length.
12002
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
12003
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
12004
 */
12005
int wc_DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
12006
                          word32 inSz)
12007
{
12008
#ifndef WOLFSSL_ASN_TEMPLATE
12009
    int    length;
12010
    int    ret = 0;
12011
    word32 oid;
12012
    word32 maxIdx;
12013
12014
    if (input == NULL || inOutIdx == NULL || key == NULL)
12015
        return BAD_FUNC_ARG;
12016
12017
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
12018
        return ASN_PARSE_E;
12019
12020
    maxIdx = (word32)(*inOutIdx + (word32)length);
12021
    if (GetInt(&key->p,  input, inOutIdx, maxIdx) < 0 ||
12022
        GetInt(&key->q,  input, inOutIdx, maxIdx) < 0 ||
12023
        GetInt(&key->g,  input, inOutIdx, maxIdx) < 0 ||
12024
        GetInt(&key->y,  input, inOutIdx, maxIdx) < 0 )
12025
        ret = ASN_DH_KEY_E;
12026
12027
    if (ret != 0) {
12028
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
12029
            return ASN_PARSE_E;
12030
12031
        ret = GetObjectId(input, inOutIdx, &oid, oidIgnoreType, inSz);
12032
        if (ret != 0)
12033
            return ret;
12034
12035
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
12036
            return ASN_PARSE_E;
12037
12038
        if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
12039
            GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
12040
            GetInt(&key->g,  input, inOutIdx, inSz) < 0)
12041
            return ASN_DH_KEY_E;
12042
12043
        if (CheckBitString(input, inOutIdx, &length, inSz, 0, NULL) < 0)
12044
            return ASN_PARSE_E;
12045
12046
        if (GetInt(&key->y,  input, inOutIdx, inSz) < 0 )
12047
            return ASN_DH_KEY_E;
12048
12049
        ret = 0;
12050
    }
12051
12052
    key->type = DSA_PUBLIC;
12053
    return ret;
12054
#else
12055
    /* dsaPubKeyASN is longer than dsaPublicKeyASN. */
12056
    DECL_ASNGETDATA(dataASN, dsaPubKeyASN_Length);
12057
    int ret = 0;
12058
12059
    /* Validated parameters. */
12060
    if ((input == NULL) || (inOutIdx == NULL) || (key == NULL)) {
12061
        ret = BAD_FUNC_ARG;
12062
    }
12063
12064
    ALLOC_ASNGETDATA(dataASN, dsaPubKeyASN_Length, ret, key->heap);
12065
12066
    if (ret == 0) {
12067
        int i;
12068
12069
        /* Clear dynamic data items. */
12070
        XMEMSET(dataASN, 0, sizeof(ASNGetData) * dsaPublicKeyASN_Length);
12071
        /* seq
12072
         *   p, q, g, y
12073
         * Start DSA ints from DSAKEYASN_IDX_VER instead of DSAKEYASN_IDX_P */
12074
        for (i = 0; i < DSA_INTS - 1; i++)
12075
            GetASN_MP(&dataASN[(int)DSAKEYASN_IDX_VER + i], GetDsaInt(key, i));
12076
        /* Parse as simple form. */
12077
        ret = GetASN_Items(dsaKeyASN, dataASN, dsaPublicKeyASN_Length, 0, input,
12078
                           inOutIdx, inSz);
12079
        if (ret != 0) {
12080
            /* Clear dynamic data items. */
12081
            XMEMSET(dataASN, 0, sizeof(ASNGetData) * dsaPubKeyASN_Length);
12082
            /* Set DSA OID to expect. */
12083
            GetASN_ExpBuffer(&dataASN[DSAPUBKEYASN_IDX_ALGOID_OID],
12084
                    keyDsaOid, sizeof(keyDsaOid));
12085
            /* p, q, g */
12086
            for (i = 0; i < DSA_INTS - 2; i++)
12087
                GetASN_MP(&dataASN[(int)DSAPUBKEYASN_IDX_ALGOID_PARAMS_P + i],
12088
                        GetDsaInt(key, i));
12089
            /* y */
12090
            GetASN_MP(&dataASN[DSAPUBKEYASN_IDX_PUBKEY_Y], GetDsaInt(key, i));
12091
            /* Parse as SubjectPublicKeyInfo. */
12092
            ret = GetASN_Items(dsaPubKeyASN, dataASN, dsaPubKeyASN_Length, 1,
12093
                input, inOutIdx, inSz);
12094
        }
12095
    }
12096
12097
    if (ret == 0) {
12098
        /* Data parsed - set type of key parsed. */
12099
        key->type = DSA_PUBLIC;
12100
    }
12101
12102
    FREE_ASNGETDATA(dataASN, key->heap);
12103
    return ret;
12104
#endif
12105
}
12106
12107
int wc_DsaParamsDecode(const byte* input, word32* inOutIdx, DsaKey* key,
12108
                        word32 inSz)
12109
{
12110
    int    length;
12111
    word32 maxIdx;
12112
12113
    if (input == NULL || inOutIdx == NULL || key == NULL)
12114
        return BAD_FUNC_ARG;
12115
12116
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
12117
        return ASN_PARSE_E;
12118
12119
    maxIdx = (word32)(*inOutIdx + (word32)length);
12120
    if (GetInt(&key->p, input, inOutIdx, maxIdx) < 0 ||
12121
        GetInt(&key->q, input, inOutIdx, maxIdx) < 0 ||
12122
        GetInt(&key->g, input, inOutIdx, maxIdx) < 0)
12123
        return ASN_DH_KEY_E;
12124
12125
    return 0;
12126
}
12127
12128
12129
#ifdef WOLFSSL_ASN_TEMPLATE
12130
/* ASN.1 template for a DSA key holding private key in an OCTET_STRING. */
12131
static const ASNItem dsaKeyOctASN[] = {
12132
/*  SEQ      */ { 0, ASN_SEQUENCE, 1, 1, 0 },
12133
                /* p */
12134
/*  P        */     { 1, ASN_INTEGER, 0, 0, 0 },
12135
                /* q */
12136
/*  Q        */     { 1, ASN_INTEGER, 0, 0, 0 },
12137
                /* g */
12138
/*  G        */     { 1, ASN_INTEGER, 0, 0, 0 },
12139
                /* Private key */
12140
/*  PKEY_STR */     { 1, ASN_OCTET_STRING, 0, 1, 0 },
12141
                    /* x */
12142
/*  X        */         { 2, ASN_INTEGER, 0, 0, 0 },
12143
};
12144
enum {
12145
    DSAKEYOCTASN_IDX_SEQ = 0,
12146
    DSAKEYOCTASN_IDX_P,
12147
    DSAKEYOCTASN_IDX_Q,
12148
    DSAKEYOCTASN_IDX_G,
12149
    DSAKEYOCTASN_IDX_PKEY_STR,
12150
    DSAKEYOCTASN_IDX_X
12151
};
12152
12153
/* Number of items in ASN.1 template for a DSA key (OCTET_STRING version). */
12154
#define dsaKeyOctASN_Length (sizeof(dsaKeyOctASN) / sizeof(ASNItem))
12155
#endif
12156
12157
/* Decode DSA private key.
12158
 *
12159
 * @param [in]      input     Buffer holding BER encoded data.
12160
 * @param [in, out] inOutIdx  On in, start of DSA public key.
12161
 *                            On out, start of ASN.1 item after DSA public key.
12162
 * @param [in, out] key       DSA key object.
12163
 * @param [in]      inSz      Number of bytes in buffer.
12164
 * @return  0 on success.
12165
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
12166
 *          is invalid.
12167
 * @return  BUFFER_E when data in buffer is too small.
12168
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
12169
 *          non-zero length.
12170
 */
12171
int wc_DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
12172
                           word32 inSz)
12173
{
12174
#ifndef WOLFSSL_ASN_TEMPLATE
12175
    int length, version, ret = 0, temp = 0;
12176
    word32 algId = 0;
12177
12178
    /* Sanity checks on input */
12179
    if (input == NULL || inOutIdx == NULL || key == NULL) {
12180
        return BAD_FUNC_ARG;
12181
    }
12182
12183
    /* if has pkcs8 header skip it */
12184
    if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) {
12185
        /* ignore error, did not have pkcs8 header */
12186
    }
12187
12188
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
12189
        return ASN_PARSE_E;
12190
12191
    temp = (int)*inOutIdx;
12192
12193
    /* Default case expects a certificate with OctetString but no version ID */
12194
    ret = GetInt(&key->p, input, inOutIdx, inSz);
12195
    if (ret < 0) {
12196
        mp_clear(&key->p);
12197
        ret = ASN_PARSE_E;
12198
    }
12199
    else {
12200
        ret = GetInt(&key->q, input, inOutIdx, inSz);
12201
        if (ret < 0) {
12202
            mp_clear(&key->p);
12203
            mp_clear(&key->q);
12204
            ret = ASN_PARSE_E;
12205
        }
12206
        else {
12207
            ret = GetInt(&key->g, input, inOutIdx, inSz);
12208
            if (ret < 0) {
12209
                mp_clear(&key->p);
12210
                mp_clear(&key->q);
12211
                mp_clear(&key->g);
12212
                ret = ASN_PARSE_E;
12213
            }
12214
            else {
12215
                ret = GetOctetString(input, inOutIdx, &length, inSz);
12216
                if (ret < 0) {
12217
                    mp_clear(&key->p);
12218
                    mp_clear(&key->q);
12219
                    mp_clear(&key->g);
12220
                    ret = ASN_PARSE_E;
12221
                }
12222
                else {
12223
                    ret = GetInt(&key->y, input, inOutIdx, inSz);
12224
                    if (ret < 0) {
12225
                        mp_clear(&key->p);
12226
                        mp_clear(&key->q);
12227
                        mp_clear(&key->g);
12228
                        mp_clear(&key->y);
12229
                        ret = ASN_PARSE_E;
12230
                    }
12231
                }
12232
            }
12233
        }
12234
    }
12235
    /* An alternate pass if default certificate fails parsing */
12236
    if (ret == WC_NO_ERR_TRACE(ASN_PARSE_E)) {
12237
        *inOutIdx = (word32)temp;
12238
        if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
12239
            return ASN_PARSE_E;
12240
12241
        if (GetInt(&key->p,  input, inOutIdx, inSz) < 0 ||
12242
            GetInt(&key->q,  input, inOutIdx, inSz) < 0 ||
12243
            GetInt(&key->g,  input, inOutIdx, inSz) < 0 ||
12244
            GetInt(&key->y,  input, inOutIdx, inSz) < 0 ||
12245
            GetInt(&key->x,  input, inOutIdx, inSz) < 0 )
12246
            return ASN_DH_KEY_E;
12247
    }
12248
12249
    key->type = DSA_PRIVATE;
12250
    return 0;
12251
#else
12252
    /* dsaKeyASN is longer than dsaKeyOctASN. */
12253
    DECL_ASNGETDATA(dataASN, dsaKeyASN_Length);
12254
    int ret = 0;
12255
    byte version = 0;
12256
12257
    /* Sanity checks on input */
12258
    if ((input == NULL) || (inOutIdx == NULL) || (key == NULL)) {
12259
        ret = BAD_FUNC_ARG;
12260
    }
12261
12262
    CALLOC_ASNGETDATA(dataASN, dsaKeyASN_Length, ret, key->heap);
12263
12264
    if (ret == 0) {
12265
        int i;
12266
12267
        /* Try dsaKeyOctASN */
12268
        /* Initialize key data and set mp_ints for params */
12269
        for (i = 0; i < DSA_INTS - 2; i++) {
12270
            GetASN_MP(&dataASN[(int)DSAKEYOCTASN_IDX_P + i], GetDsaInt(key, i));
12271
        }
12272
        /* and priv */
12273
        GetASN_MP(&dataASN[DSAKEYOCTASN_IDX_X], GetDsaInt(key, i));
12274
        /* Try simple form. */
12275
        ret = GetASN_Items(dsaKeyOctASN, dataASN, dsaKeyOctASN_Length, 1, input,
12276
                           inOutIdx, inSz);
12277
12278
        if (ret != 0) {
12279
            /* Try dsaKeyASN */
12280
            XMEMSET(dataASN, 0, sizeof(*dataASN) * dsaKeyASN_Length);
12281
            GetASN_Int8Bit(&dataASN[DSAKEYASN_IDX_VER], &version);
12282
            for (i = 0; i < DSA_INTS; i++) {
12283
                mp_int* n = GetDsaInt(key, i);
12284
                mp_clear(n);
12285
                GetASN_MP(&dataASN[(int)DSAKEYASN_IDX_P + i], n);
12286
            }
12287
12288
            /* Try simple OCTET_STRING form. */
12289
            ret = GetASN_Items(dsaKeyASN, dataASN, dsaKeyASN_Length, 1, input,
12290
                               inOutIdx, inSz);
12291
        }
12292
    }
12293
12294
    if (ret == 0) {
12295
        /* Set the contents to be a private key. */
12296
        key->type = DSA_PRIVATE;
12297
    }
12298
12299
    FREE_ASNGETDATA(dataASN, key->heap);
12300
    return ret;
12301
#endif
12302
}
12303
12304
#ifndef WOLFSSL_ASN_TEMPLATE
12305
/* Release Tmp DSA resources */
12306
static WC_INLINE void FreeTmpDsas(byte** tmps, void* heap, int ints)
12307
{
12308
    int i;
12309
12310
    for (i = 0; i < ints; i++)
12311
        XFREE(tmps[i], heap, DYNAMIC_TYPE_DSA);
12312
12313
    (void)heap;
12314
}
12315
#endif /* !WOLFSSL_ASN_TEMPLATE */
12316
12317
#if !defined(HAVE_SELFTEST) && (defined(WOLFSSL_KEY_GEN) || \
12318
        defined(WOLFSSL_CERT_GEN))
12319
/* Encode a DSA public key into buffer.
12320
 *
12321
 * @param [out] output       Buffer to hold encoded data.
12322
 * @param [in]  key          DSA key object.
12323
 * @param [out] outLen       Length of buffer.
12324
 * @param [out] with_header  Whether to encode in SubjectPublicKeyInfo block.
12325
 * @return  Size of encoded data in bytes on success.
12326
 * @return  BAD_FUNC_ARG when output or key is NULL, or buffer size is less
12327
 *          than a minimal size (5 bytes), or buffer size is smaller than
12328
 *          encoding size.
12329
 * @return  MEMORY_E when dynamic memory allocation fails.
12330
 */
12331
int wc_SetDsaPublicKey(byte* output, DsaKey* key, int outLen, int with_header)
12332
{
12333
#ifndef WOLFSSL_ASN_TEMPLATE
12334
    /* p, g, q = DSA params, y = public exponent */
12335
#ifdef WOLFSSL_SMALL_STACK
12336
    byte* p = NULL;
12337
    byte* g = NULL;
12338
    byte* q = NULL;
12339
    byte* y = NULL;
12340
#else
12341
    byte p[MAX_DSA_INT_SZ];
12342
    byte g[MAX_DSA_INT_SZ];
12343
    byte q[MAX_DSA_INT_SZ];
12344
    byte y[MAX_DSA_INT_SZ];
12345
#endif
12346
    byte innerSeq[MAX_SEQ_SZ];
12347
    byte outerSeq[MAX_SEQ_SZ];
12348
    byte bitString[1 + MAX_LENGTH_SZ + 1];
12349
    int pSz, gSz, qSz, ySz;
12350
    word32 idx, innerSeqSz, outerSeqSz, bitStringSz = 0;
12351
    WOLFSSL_ENTER("wc_SetDsaPublicKey");
12352
12353
    if (output == NULL || key == NULL || outLen < MAX_SEQ_SZ) {
12354
        return BAD_FUNC_ARG;
12355
    }
12356
12357
    /* p */
12358
#ifdef WOLFSSL_SMALL_STACK
12359
    p = (byte*)XMALLOC(MAX_DSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12360
    if (p == NULL)
12361
        return MEMORY_E;
12362
#endif
12363
    if ((pSz = SetASNIntMP(&key->p, MAX_DSA_INT_SZ, p)) < 0) {
12364
        WOLFSSL_MSG("SetASNIntMP Error with p");
12365
#ifdef WOLFSSL_SMALL_STACK
12366
        XFREE(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12367
#endif
12368
        return pSz;
12369
    }
12370
12371
    /* q */
12372
#ifdef WOLFSSL_SMALL_STACK
12373
    q = (byte*)XMALLOC(MAX_DSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12374
    if (q == NULL)
12375
        return MEMORY_E;
12376
#endif
12377
    if ((qSz = SetASNIntMP(&key->q, MAX_DSA_INT_SZ, q)) < 0) {
12378
        WOLFSSL_MSG("SetASNIntMP Error with q");
12379
#ifdef WOLFSSL_SMALL_STACK
12380
        XFREE(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12381
        XFREE(q, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12382
#endif
12383
        return qSz;
12384
    }
12385
12386
    /* g */
12387
#ifdef WOLFSSL_SMALL_STACK
12388
    g = (byte*)XMALLOC(MAX_DSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12389
    if (g == NULL)
12390
        return MEMORY_E;
12391
#endif
12392
    if ((gSz = SetASNIntMP(&key->g, MAX_DSA_INT_SZ, g)) < 0) {
12393
        WOLFSSL_MSG("SetASNIntMP Error with g");
12394
#ifdef WOLFSSL_SMALL_STACK
12395
        XFREE(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12396
        XFREE(q, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12397
        XFREE(g, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12398
#endif
12399
        return gSz;
12400
    }
12401
12402
    /* y */
12403
#ifdef WOLFSSL_SMALL_STACK
12404
    y = (byte*)XMALLOC(MAX_DSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12405
    if (y == NULL)
12406
        return MEMORY_E;
12407
#endif
12408
    if ((ySz = SetASNIntMP(&key->y, MAX_DSA_INT_SZ, y)) < 0) {
12409
        WOLFSSL_MSG("SetASNIntMP Error with y");
12410
#ifdef WOLFSSL_SMALL_STACK
12411
        XFREE(p, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12412
        XFREE(q, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12413
        XFREE(g, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12414
        XFREE(y, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12415
#endif
12416
        return ySz;
12417
    }
12418
12419
    if (with_header) {
12420
        word32 algoSz;
12421
#ifdef WOLFSSL_SMALL_STACK
12422
        byte* algo = NULL;
12423
12424
        algo = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12425
        if (algo == NULL) {
12426
            XFREE(p,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12427
            XFREE(q,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12428
            XFREE(g,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12429
            XFREE(y,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12430
            return MEMORY_E;
12431
        }
12432
#else
12433
        byte algo[MAX_ALGO_SZ];
12434
#endif
12435
        innerSeqSz  = SetSequence((word32)(pSz + qSz + gSz), innerSeq);
12436
        algoSz = SetAlgoID(DSAk, algo, oidKeyType, 0);
12437
        bitStringSz  = SetBitString((word32)ySz, 0, bitString);
12438
        outerSeqSz = SetSequence(algoSz + innerSeqSz +
12439
                                 (word32)(pSz + qSz + gSz), outerSeq);
12440
12441
        idx = SetSequence(algoSz + innerSeqSz + (word32)(pSz + qSz + gSz) +
12442
                          bitStringSz + (word32)ySz + outerSeqSz, output);
12443
12444
        /* check output size */
12445
        if ((idx + algoSz + bitStringSz + innerSeqSz +
12446
             (word32)(pSz + qSz + gSz + ySz)) > (word32)outLen)
12447
        {
12448
            #ifdef WOLFSSL_SMALL_STACK
12449
                XFREE(p,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12450
                XFREE(q,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12451
                XFREE(g,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12452
                XFREE(y,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12453
                XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12454
            #endif
12455
            WOLFSSL_MSG("Error, output size smaller than outlen");
12456
            return BUFFER_E;
12457
        }
12458
12459
        /* outerSeq */
12460
        XMEMCPY(output + idx, outerSeq, outerSeqSz);
12461
        idx += outerSeqSz;
12462
        /* algo */
12463
        XMEMCPY(output + idx, algo, algoSz);
12464
        idx += algoSz;
12465
#ifdef WOLFSSL_SMALL_STACK
12466
        XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12467
#endif
12468
    } else {
12469
        innerSeqSz  = SetSequence((word32)(pSz + qSz + gSz + ySz), innerSeq);
12470
12471
        /* check output size */
12472
        if ((innerSeqSz + (word32)(pSz + qSz + gSz + ySz)) > (word32)outLen) {
12473
    #ifdef WOLFSSL_SMALL_STACK
12474
            XFREE(p,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12475
            XFREE(q,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12476
            XFREE(g,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12477
            XFREE(y,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12478
    #endif
12479
            WOLFSSL_MSG("Error, output size smaller than outlen");
12480
            return BUFFER_E;
12481
        }
12482
12483
        idx = 0;
12484
    }
12485
12486
    /* innerSeq */
12487
    XMEMCPY(output + idx, innerSeq, innerSeqSz);
12488
    idx += innerSeqSz;
12489
    /* p */
12490
    XMEMCPY(output + idx, p, (size_t)pSz);
12491
    idx += (word32)pSz;
12492
    /* q */
12493
    XMEMCPY(output + idx, q, (size_t)qSz);
12494
    idx += (word32)qSz;
12495
    /* g */
12496
    XMEMCPY(output + idx, g, (size_t)gSz);
12497
    idx += (word32)gSz;
12498
    /* bit string */
12499
    if (bitStringSz > 0) {
12500
        XMEMCPY(output + idx, bitString, bitStringSz);
12501
        idx += bitStringSz;
12502
    }
12503
    /* y */
12504
    XMEMCPY(output + idx, y, (size_t)ySz);
12505
    idx += (word32)ySz;
12506
12507
#ifdef WOLFSSL_SMALL_STACK
12508
    XFREE(p,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12509
    XFREE(q,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12510
    XFREE(g,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12511
    XFREE(y,    key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12512
#endif
12513
    return (int)idx;
12514
#else
12515
    DECL_ASNSETDATA(dataASN, dsaPubKeyASN_Length);
12516
    int ret = 0;
12517
    int i;
12518
    int sz = 0;
12519
    const ASNItem *data = NULL;
12520
    int count = 0;
12521
12522
    WOLFSSL_ENTER("wc_SetDsaPublicKey");
12523
12524
    if ((output == NULL) || (key == NULL) || (outLen < MAX_SEQ_SZ)) {
12525
        ret = BAD_FUNC_ARG;
12526
    }
12527
12528
    CALLOC_ASNSETDATA(dataASN, dsaPubKeyASN_Length, ret, key->heap);
12529
12530
    if (ret == 0) {
12531
        if (with_header) {
12532
            /* Using dsaPubKeyASN */
12533
            data = dsaPubKeyASN;
12534
            count = dsaPubKeyASN_Length;
12535
            /* Set the algorithm OID to write out. */
12536
            SetASN_OID(&dataASN[DSAPUBKEYASN_IDX_ALGOID_OID], DSAk, oidKeyType);
12537
            /* Set the mp_ints to encode - parameters and public value. */
12538
            for (i = 0; i < DSA_INTS - 2; i++) {
12539
                SetASN_MP(&dataASN[(int)DSAPUBKEYASN_IDX_ALGOID_PARAMS_P + i],
12540
                        GetDsaInt(key, i));
12541
            }
12542
            SetASN_MP(&dataASN[DSAPUBKEYASN_IDX_PUBKEY_Y], GetDsaInt(key, i));
12543
        }
12544
        else {
12545
            /* Using dsaKeyASN */
12546
            data = dsaKeyASN;
12547
            count = dsaPublicKeyASN_Length;
12548
            /* Set the mp_ints to encode - parameters and public value. */
12549
            for (i = 0; i < DSA_INTS - 1; i++) {
12550
                /* Move all DSA ints up one slot (ignore VERSION so now
12551
                 * it means P) */
12552
                SetASN_MP(&dataASN[(int)DSAKEYASN_IDX_VER + i],
12553
                        GetDsaInt(key, i));
12554
            }
12555
        }
12556
        ret = SizeASN_Items(data, dataASN, count, &sz);
12557
    }
12558
    /* Check buffer is big enough for encoding. */
12559
    if ((ret == 0) && (sz > (int)outLen)) {
12560
        ret = BAD_FUNC_ARG;
12561
    }
12562
    /* Encode the DSA public key into output buffer. */
12563
    if (ret == 0) {
12564
        ret = SetASN_Items(data, dataASN, count, output);
12565
    }
12566
12567
    FREE_ASNSETDATA(dataASN, key->heap);
12568
    return ret;
12569
#endif /* WOLFSSL_ASN_TEMPLATE */
12570
}
12571
12572
/* Encode a DSA public key into buffer.
12573
 *
12574
 * @param [out] output       Buffer to hold encoded data.
12575
 * @param [in]  key          DSA key object.
12576
 * @param [out] outLen       Length of buffer.
12577
 * @param [out] with_header  Whether to encode in SubjectPublicKeyInfo block.
12578
 * @return  Size of encoded data in bytes on success.
12579
 * @return  BAD_FUNC_ARG when output or key is NULL, or buffer size is less
12580
 *          than a minimal size (5 bytes), or buffer size is smaller than
12581
 *          encoding size.
12582
 * @return  MEMORY_E when dynamic memory allocation fails.
12583
 */
12584
int wc_DsaKeyToPublicDer(DsaKey* key, byte* output, word32 inLen)
12585
{
12586
    return wc_SetDsaPublicKey(output, key, (int)inLen, 1);
12587
}
12588
#endif /* !HAVE_SELFTEST && (WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN) */
12589
12590
static int DsaKeyIntsToDer(DsaKey* key, byte* output, word32* inLen,
12591
                           int ints, int includeVersion)
12592
{
12593
#ifndef WOLFSSL_ASN_TEMPLATE
12594
    word32 seqSz = 0, verSz = 0, intTotalLen = 0, outLen, j;
12595
    word32 sizes[DSA_INTS];
12596
    int    i, ret = 0;
12597
12598
    byte  seq[MAX_SEQ_SZ];
12599
    byte  ver[MAX_VERSION_SZ];
12600
    byte* tmps[DSA_INTS];
12601
12602
    if (ints > DSA_INTS || inLen == NULL)
12603
        return BAD_FUNC_ARG;
12604
12605
    XMEMSET(sizes, 0, sizeof(sizes));
12606
    for (i = 0; i < ints; i++)
12607
        tmps[i] = NULL;
12608
12609
    /* write all big ints from key to DER tmps */
12610
    for (i = 0; i < ints; i++) {
12611
        int mpSz;
12612
        mp_int* keyInt = GetDsaInt(key, i);
12613
        word32 rawLen = (word32)mp_unsigned_bin_size(keyInt) + 1;
12614
12615
        tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
12616
                                                              DYNAMIC_TYPE_DSA);
12617
        if (tmps[i] == NULL) {
12618
            ret = MEMORY_E;
12619
            break;
12620
        }
12621
12622
        mpSz = SetASNIntMP(keyInt, -1, tmps[i]);
12623
        if (mpSz < 0) {
12624
            ret = mpSz;
12625
            break;
12626
        }
12627
        sizes[i] = (word32)mpSz;
12628
        intTotalLen += (word32)mpSz;
12629
    }
12630
12631
    if (ret != 0) {
12632
        FreeTmpDsas(tmps, key->heap, ints);
12633
        return ret;
12634
    }
12635
12636
    /* make headers */
12637
    if (includeVersion)
12638
        verSz = (word32)SetMyVersion(0, ver, FALSE);
12639
    seqSz = SetSequence(verSz + intTotalLen, seq);
12640
12641
    outLen = seqSz + verSz + intTotalLen;
12642
    *inLen = outLen;
12643
    if (output == NULL) {
12644
        FreeTmpDsas(tmps, key->heap, ints);
12645
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
12646
    }
12647
    if (outLen > *inLen) {
12648
        FreeTmpDsas(tmps, key->heap, ints);
12649
        return BAD_FUNC_ARG;
12650
    }
12651
12652
    /* write to output */
12653
    XMEMCPY(output, seq, seqSz);
12654
    j = seqSz;
12655
    if (includeVersion) {
12656
        XMEMCPY(output + j, ver, verSz);
12657
        j += verSz;
12658
    }
12659
12660
    for (i = 0; i < ints; i++) {
12661
        XMEMCPY(output + j, tmps[i], sizes[i]);
12662
        j += sizes[i];
12663
    }
12664
    FreeTmpDsas(tmps, key->heap, ints);
12665
12666
    return (int)outLen;
12667
#else
12668
    DECL_ASNSETDATA(dataASN, dsaKeyASN_Length);
12669
    int ret = 0;
12670
    int sz = 0;
12671
12672
    (void)ints;
12673
12674
    if ((key == NULL) || (inLen == NULL)) {
12675
        ret = BAD_FUNC_ARG;
12676
    }
12677
    if ((ret == 0) && (ints > DSA_INTS)) {
12678
        ret = BAD_FUNC_ARG;
12679
    }
12680
12681
    CALLOC_ASNSETDATA(dataASN, dsaKeyASN_Length, ret, key->heap);
12682
12683
    if (ret == 0) {
12684
        int i;
12685
12686
        if (includeVersion) {
12687
            /* Set the version. */
12688
            SetASN_Int8Bit(&dataASN[DSAKEYASN_IDX_VER], 0);
12689
        }
12690
        else {
12691
            dataASN[DSAKEYASN_IDX_VER].noOut = 1;
12692
        }
12693
        dataASN[DSAKEYASN_IDX_Y].noOut = mp_iszero(&key->y);
12694
        dataASN[DSAKEYASN_IDX_X].noOut = mp_iszero(&key->x);
12695
        /* Set the mp_ints to encode - params, public and private value. */
12696
        for (i = 0; i < DSA_INTS; i++) {
12697
            if (i < ints)
12698
                SetASN_MP(&dataASN[(int)DSAKEYASN_IDX_P + i], GetDsaInt(key, i));
12699
            else
12700
                dataASN[(int)DSAKEYASN_IDX_P + i].noOut = 1;
12701
        }
12702
        /* Calculate size of the encoding. */
12703
        ret = SizeASN_Items(dsaKeyASN, dataASN, dsaKeyASN_Length, &sz);
12704
    }
12705
    if ((ret == 0) && (output == NULL)) {
12706
        *inLen = (word32)sz;
12707
        ret = WC_NO_ERR_TRACE(LENGTH_ONLY_E);
12708
    }
12709
    /* Check buffer is big enough for encoding. */
12710
    if ((ret == 0) && (sz > (int)*inLen)) {
12711
        ret = BAD_FUNC_ARG;
12712
    }
12713
    if (ret == 0) {
12714
        /* Encode the DSA private key into output buffer. */
12715
        SetASN_Items(dsaKeyASN, dataASN, dsaKeyASN_Length, output);
12716
        /* Return the size of the encoding. */
12717
        ret = sz;
12718
    }
12719
12720
    FREE_ASNSETDATA(dataASN, key->heap);
12721
    return ret;
12722
#endif /* WOLFSSL_ASN_TEMPLATE */
12723
}
12724
12725
/* Encode a DSA private key into buffer.
12726
 *
12727
 * @param [in]  key          DSA key object.
12728
 * @param [out] output       Buffer to hold encoded data.
12729
 * @param [out] inLen        Length of buffer.
12730
 * @return  Size of encoded data in bytes on success.
12731
 * @return  BAD_FUNC_ARG when key or output is NULL, or key is not a private key
12732
 *          or, buffer size is smaller than encoding size.
12733
 * @return  MEMORY_E when dynamic memory allocation fails.
12734
 */
12735
int wc_DsaKeyToDer(DsaKey* key, byte* output, word32 inLen)
12736
{
12737
    if (!key || !output)
12738
        return BAD_FUNC_ARG;
12739
12740
    if (key->type != DSA_PRIVATE)
12741
        return BAD_FUNC_ARG;
12742
12743
    return DsaKeyIntsToDer(key, output, &inLen, DSA_INTS, 1);
12744
}
12745
12746
/* Convert DsaKey parameters to DER format, write to output (inLen),
12747
   return bytes written. Version is excluded to be compatible with
12748
   OpenSSL d2i_DSAparams */
12749
int wc_DsaKeyToParamsDer(DsaKey* key, byte* output, word32 inLen)
12750
{
12751
    if (!key || !output)
12752
        return BAD_FUNC_ARG;
12753
12754
    return DsaKeyIntsToDer(key, output, &inLen, DSA_PARAM_INTS, 0);
12755
}
12756
12757
/* This version of the function allows output to be NULL. In that case, the
12758
   DsaKeyIntsToDer will return WC_NO_ERR_TRACE(LENGTH_ONLY_E) and the required
12759
   output buffer size will be pointed to by inLen. */
12760
int wc_DsaKeyToParamsDer_ex(DsaKey* key, byte* output, word32* inLen)
12761
{
12762
    if (!key || !inLen)
12763
        return BAD_FUNC_ARG;
12764
12765
    return DsaKeyIntsToDer(key, output, inLen, DSA_PARAM_INTS, 0);
12766
}
12767
12768
#endif /* NO_DSA */
12769
12770
#ifndef NO_CERTS
12771
/* Initialize decoded certificate object with buffer of DER encoding.
12772
 *
12773
 * @param [in, out] cert    Decoded certificate object.
12774
 * @param [in]      source  Buffer containing DER encoded certificate.
12775
 * @param [in]      inSz    Size of DER data in buffer in bytes.
12776
 * @param [in]      heap    Dynamic memory hint.
12777
 */
12778
void InitDecodedCert(DecodedCert* cert,
12779
                     const byte* source, word32 inSz, void* heap)
12780
0
{
12781
0
    InitDecodedCert_ex(cert, source, inSz, heap, INVALID_DEVID);
12782
0
}
12783
12784
12785
/* Initialize decoded certificate object with buffer of DER encoding.
12786
 *
12787
 * @param [in, out] cert    Decoded certificate object.
12788
 * @param [in]      source  Buffer containing DER encoded certificate.
12789
 * @param [in]      inSz    Size of DER data in buffer in bytes.
12790
 * @param [in]      heap    Dynamic memory hint.
12791
 * @param [in]      devId   Crypto callback ID to use.
12792
 */
12793
void InitDecodedCert_ex(DecodedCert* cert,
12794
                     const byte* source, word32 inSz, void* heap, int devId)
12795
0
{
12796
0
    if (cert != NULL) {
12797
0
        XMEMSET(cert, 0, sizeof(DecodedCert));
12798
12799
0
        cert->subjectCNEnc    = CTC_UTF8;
12800
0
        cert->issuer[0]       = '\0';
12801
0
        cert->subject[0]      = '\0';
12802
0
        cert->source          = source;  /* don't own */
12803
0
        cert->maxIdx          = inSz;    /* can't go over this index */
12804
0
        cert->heap            = heap;
12805
0
        cert->maxPathLen      = WOLFSSL_MAX_PATH_LEN;
12806
    #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
12807
        #ifdef WOLFSSL_CERT_NAME_ALL
12808
        cert->subjectNEnc     = CTC_UTF8;
12809
        cert->subjectIEnc     = CTC_UTF8;
12810
        cert->subjectDNQEnc   = CTC_UTF8;
12811
        cert->subjectGNEnc    = CTC_UTF8;
12812
        #endif
12813
        cert->subjectSNEnc    = CTC_UTF8;
12814
        cert->subjectCEnc     = CTC_PRINTABLE;
12815
        cert->subjectLEnc     = CTC_UTF8;
12816
        cert->subjectSTEnc    = CTC_UTF8;
12817
        cert->subjectOEnc     = CTC_UTF8;
12818
        cert->subjectOUEnc    = CTC_UTF8;
12819
    #ifdef WOLFSSL_HAVE_ISSUER_NAMES
12820
        cert->issuerSNEnc    = CTC_UTF8;
12821
        cert->issuerCEnc     = CTC_PRINTABLE;
12822
        cert->issuerLEnc     = CTC_UTF8;
12823
        cert->issuerSTEnc    = CTC_UTF8;
12824
        cert->issuerOEnc     = CTC_UTF8;
12825
        cert->issuerOUEnc    = CTC_UTF8;
12826
    #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
12827
    #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
12828
12829
0
        InitSignatureCtx(&cert->sigCtx, heap, devId);
12830
0
    }
12831
0
}
12832
12833
void wc_InitDecodedCert(DecodedCert* cert, const byte* source, word32 inSz,
12834
                        void* heap)
12835
0
{
12836
0
    InitDecodedCert(cert, source, inSz, heap);
12837
0
}
12838
12839
/* Free the alternative names object.
12840
 *
12841
 * Frees each linked list items and its name.
12842
 *
12843
 * @param [in, out] altNames  Alternative names.
12844
 * @param [in]      heap      Dynamic memory hint.
12845
 */
12846
void FreeAltNames(DNS_entry* altNames, void* heap)
12847
0
{
12848
0
    (void)heap;
12849
12850
0
    while (altNames) {
12851
0
        DNS_entry* tmp = altNames->next;
12852
12853
0
        XFREE(altNames->name, heap, DYNAMIC_TYPE_ALTNAME);
12854
    #ifdef WOLFSSL_IP_ALT_NAME
12855
        XFREE(altNames->ipString, heap, DYNAMIC_TYPE_ALTNAME);
12856
    #endif
12857
    #ifdef WOLFSSL_RID_ALT_NAME
12858
        XFREE(altNames->ridString, heap, DYNAMIC_TYPE_ALTNAME);
12859
    #endif
12860
0
        XFREE(altNames,       heap, DYNAMIC_TYPE_ALTNAME);
12861
0
        altNames = tmp;
12862
0
    }
12863
0
}
12864
12865
/* malloc and initialize a new alt name structure */
12866
DNS_entry* AltNameNew(void* heap)
12867
0
{
12868
0
    DNS_entry* ret;
12869
0
    ret = (DNS_entry*)XMALLOC(sizeof(DNS_entry), heap, DYNAMIC_TYPE_ALTNAME);
12870
0
    if (ret != NULL) {
12871
0
        XMEMSET(ret, 0, sizeof(DNS_entry));
12872
0
    }
12873
0
    (void)heap;
12874
0
    return ret;
12875
0
}
12876
12877
DNS_entry* AltNameDup(DNS_entry* from, void* heap)
12878
0
{
12879
0
    DNS_entry* ret;
12880
12881
0
    ret = AltNameNew(heap);
12882
0
    if (ret == NULL) {
12883
0
        WOLFSSL_MSG("\tOut of Memory");
12884
0
        return NULL;
12885
0
    }
12886
12887
0
    ret->type = from->type;
12888
0
    ret->len = from->len;
12889
12890
12891
0
    ret->name = CopyString(from->name, from->len, heap, DYNAMIC_TYPE_ALTNAME);
12892
#ifdef WOLFSSL_IP_ALT_NAME
12893
    ret->ipString = CopyString(from->ipString, 0, heap, DYNAMIC_TYPE_ALTNAME);
12894
#endif
12895
#ifdef WOLFSSL_RID_ALT_NAME
12896
    ret->ridString = CopyString(from->ridString, 0, heap, DYNAMIC_TYPE_ALTNAME);
12897
#endif
12898
0
    if (ret->name == NULL
12899
#ifdef WOLFSSL_IP_ALT_NAME
12900
            || (from->ipString != NULL && ret->ipString == NULL)
12901
#endif
12902
#ifdef WOLFSSL_RID_ALT_NAME
12903
            || (from->ridString != NULL && ret->ridString == NULL)
12904
#endif
12905
0
            ) {
12906
0
        WOLFSSL_MSG("\tOut of Memory");
12907
0
        FreeAltNames(ret, heap);
12908
0
        return NULL;
12909
0
    }
12910
12911
#ifdef WOLFSSL_FPKI
12912
    ret->oidSum = from->oidSum;
12913
#endif
12914
12915
0
    return ret;
12916
0
}
12917
12918
12919
#ifndef IGNORE_NAME_CONSTRAINTS
12920
12921
/* Free the subtree names object.
12922
 *
12923
 * Frees each linked list items and its name.
12924
 *
12925
 * @param [in, out] names  Subtree names.
12926
 * @param [in]      heap   Dynamic memory hint.
12927
 */
12928
void FreeNameSubtrees(Base_entry* names, void* heap)
12929
0
{
12930
0
    (void)heap;
12931
12932
0
    while (names) {
12933
0
        Base_entry* tmp = names->next;
12934
12935
0
        XFREE(names->name, heap, DYNAMIC_TYPE_ALTNAME);
12936
0
        XFREE(names,       heap, DYNAMIC_TYPE_ALTNAME);
12937
0
        names = tmp;
12938
0
    }
12939
0
}
12940
12941
#endif /* IGNORE_NAME_CONSTRAINTS */
12942
12943
/* Free the decoded cert object's dynamic data.
12944
 *
12945
 * @param [in, out] cert  Decoded certificate object.
12946
 */
12947
void FreeDecodedCert(DecodedCert* cert)
12948
0
{
12949
0
    if (cert == NULL)
12950
0
        return;
12951
0
    if (cert->subjectCNStored == 1) {
12952
0
        XFREE(cert->subjectCN, cert->heap, DYNAMIC_TYPE_SUBJECT_CN);
12953
0
    }
12954
0
    if (cert->pubKeyStored == 1) {
12955
0
        XFREE((void*)cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
12956
0
    }
12957
0
    if (cert->weOwnAltNames && cert->altNames)
12958
0
        FreeAltNames(cert->altNames, cert->heap);
12959
0
#ifndef IGNORE_NAME_CONSTRAINTS
12960
0
    if (cert->altEmailNames)
12961
0
        FreeAltNames(cert->altEmailNames, cert->heap);
12962
0
    if (cert->altDirNames)
12963
0
        FreeAltNames(cert->altDirNames, cert->heap);
12964
0
    if (cert->permittedNames)
12965
0
        FreeNameSubtrees(cert->permittedNames, cert->heap);
12966
0
    if (cert->excludedNames)
12967
0
        FreeNameSubtrees(cert->excludedNames, cert->heap);
12968
0
#endif /* IGNORE_NAME_CONSTRAINTS */
12969
#ifdef WOLFSSL_SEP
12970
    XFREE(cert->deviceType, cert->heap, DYNAMIC_TYPE_X509_EXT);
12971
    XFREE(cert->hwType, cert->heap, DYNAMIC_TYPE_X509_EXT);
12972
    XFREE(cert->hwSerialNum, cert->heap, DYNAMIC_TYPE_X509_EXT);
12973
#endif /* WOLFSSL_SEP */
12974
#ifdef WOLFSSL_X509_NAME_AVAILABLE
12975
    if (cert->issuerName != NULL)
12976
        wolfSSL_X509_NAME_free((WOLFSSL_X509_NAME*)cert->issuerName);
12977
    if (cert->subjectName != NULL)
12978
        wolfSSL_X509_NAME_free((WOLFSSL_X509_NAME*)cert->subjectName);
12979
#endif /* WOLFSSL_X509_NAME_AVAILABLE */
12980
#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_FSPSM_TLS)
12981
    XFREE(cert->sce_tsip_encRsaKeyIdx, cert->heap, DYNAMIC_TYPE_RSA);
12982
#endif
12983
0
    FreeSignatureCtx(&cert->sigCtx);
12984
0
}
12985
12986
void wc_FreeDecodedCert(DecodedCert* cert)
12987
0
{
12988
0
    FreeDecodedCert(cert);
12989
0
}
12990
12991
#ifndef WOLFSSL_ASN_TEMPLATE
12992
static int GetCertHeader(DecodedCert* cert)
12993
{
12994
    int ret = 0, len;
12995
12996
    if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
12997
        return ASN_PARSE_E;
12998
12999
    /* Reset the max index for the size indicated in the outer wrapper. */
13000
    cert->maxIdx = (word32)len + cert->srcIdx;
13001
    cert->certBegin = cert->srcIdx;
13002
13003
    if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
13004
        return ASN_PARSE_E;
13005
13006
    cert->sigIndex = (word32)len + cert->srcIdx;
13007
    if (cert->sigIndex > cert->maxIdx)
13008
        return ASN_PARSE_E;
13009
13010
    if (GetExplicitVersion(cert->source, &cert->srcIdx, &cert->version,
13011
                                                            cert->sigIndex) < 0)
13012
        return ASN_PARSE_E;
13013
13014
    ret = wc_GetSerialNumber(cert->source, &cert->srcIdx, cert->serial,
13015
        &cert->serialSz, cert->sigIndex);
13016
    if (ret < 0) {
13017
        return ret;
13018
    }
13019
13020
    return ret;
13021
}
13022
#endif
13023
13024
#if defined(HAVE_ED25519) || defined(HAVE_ED448) || defined(HAVE_FALCON) || \
13025
    defined(HAVE_DILITHIUM) || defined(HAVE_SPHINCS)
13026
/* Store the key data under the BIT_STRING in dynamically allocated data.
13027
 *
13028
 * @param [in, out] cert    Certificate object.
13029
 * @param [in]      source  Buffer containing encoded key.
13030
 * @param [in, out] srcIdx  On in, start of key data.
13031
 *                          On out, start of element after key data.
13032
 * @param [in]      maxIdx  Maximum index of certificate data.
13033
 */
13034
static int StoreKey(DecodedCert* cert, const byte* source, word32* srcIdx,
13035
                    word32 maxIdx)
13036
{
13037
    int ret;
13038
    int length;
13039
    byte* publicKey;
13040
13041
    ret = CheckBitString(source, srcIdx, &length, maxIdx, 1, NULL);
13042
    if (ret == 0) {
13043
    #ifdef HAVE_OCSP
13044
        ret = CalcHashId_ex(source + *srcIdx, (word32)length,
13045
            cert->subjectKeyHash, HashIdAlg(cert->signatureOID));
13046
    }
13047
    if (ret == 0) {
13048
    #endif
13049
        publicKey = (byte*)XMALLOC((size_t)length, cert->heap,
13050
                                   DYNAMIC_TYPE_PUBLIC_KEY);
13051
        if (publicKey == NULL) {
13052
            ret = MEMORY_E;
13053
        }
13054
        else {
13055
            XMEMCPY(publicKey, &source[*srcIdx], (size_t)length);
13056
            cert->publicKey = publicKey;
13057
            cert->pubKeyStored = 1;
13058
            cert->pubKeySize   = (word32)length;
13059
13060
            *srcIdx += (word32)length;
13061
        }
13062
    }
13063
13064
    return ret;
13065
}
13066
#endif /* HAVE_ED25519 || HAVE_ED448 */
13067
#endif
13068
13069
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
13070
13071
static int SetCurve(ecc_key* key, byte* output, size_t outSz)
13072
0
{
13073
#ifdef HAVE_OID_ENCODING
13074
    int ret;
13075
#endif
13076
0
    int idx;
13077
0
    word32 oidSz = 0;
13078
13079
    /* validate key */
13080
0
    if (key == NULL || key->dp == NULL) {
13081
0
        return BAD_FUNC_ARG;
13082
0
    }
13083
13084
#ifdef HAVE_OID_ENCODING
13085
    ret = EncodeObjectId(key->dp->oid, key->dp->oidSz, NULL, &oidSz);
13086
    if (ret != 0) {
13087
        return ret;
13088
    }
13089
#else
13090
0
    oidSz = key->dp->oidSz;
13091
0
#endif
13092
13093
0
    idx = SetObjectId((int)oidSz, output);
13094
13095
    /* length only */
13096
0
    if (output == NULL) {
13097
0
        return idx + (int)oidSz;
13098
0
    }
13099
13100
    /* verify output buffer has room */
13101
0
    if (oidSz > outSz)
13102
0
        return BUFFER_E;
13103
13104
#ifdef HAVE_OID_ENCODING
13105
    ret = EncodeObjectId(key->dp->oid, key->dp->oidSz, output+idx, &oidSz);
13106
    if (ret != 0) {
13107
        return ret;
13108
    }
13109
#else
13110
0
    XMEMCPY(output+idx, key->dp->oid, oidSz);
13111
0
#endif
13112
0
    idx += (int)oidSz;
13113
13114
0
    return idx;
13115
0
}
13116
13117
#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */
13118
13119
#ifdef HAVE_ECC
13120
#ifdef WOLFSSL_ASN_TEMPLATE
13121
/* ASN.1 template for ECC public key (SubjectPublicKeyInfo).
13122
 * RFC 5480, 2 - Subject Public Key Information Fields
13123
 *           2.1.1 - Unrestricted Algorithm Identifier and Parameters
13124
 * X9.62 ECC point format.
13125
 * See ASN.1 template 'eccSpecifiedASN' for specifiedCurve.
13126
 */
13127
static const ASNItem eccPublicKeyASN[] = {
13128
/* SEQ            */ { 0, ASN_SEQUENCE, 1, 1, 0 },
13129
                                             /* AlgorithmIdentifier */
13130
/* ALGOID_SEQ     */     { 1, ASN_SEQUENCE, 1, 1, 0 },
13131
                                                 /* algorithm */
13132
/* ALGOID_OID     */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
13133
                                                 /* namedCurve */
13134
/* ALGOID_CURVEID */         { 2, ASN_OBJECT_ID, 0, 0, 2 },
13135
                                                 /* specifiedCurve - explicit parameters */
13136
/* ALGOID_PARAMS  */         { 2, ASN_SEQUENCE, 1, 0, 2 },
13137
                                             /* Public Key */
13138
/* PUBKEY         */     { 1, ASN_BIT_STRING, 0, 0, 0 },
13139
};
13140
enum {
13141
    ECCPUBLICKEYASN_IDX_SEQ = 0,
13142
    ECCPUBLICKEYASN_IDX_ALGOID_SEQ,
13143
    ECCPUBLICKEYASN_IDX_ALGOID_OID,
13144
    ECCPUBLICKEYASN_IDX_ALGOID_CURVEID,
13145
    ECCPUBLICKEYASN_IDX_ALGOID_PARAMS,
13146
    ECCPUBLICKEYASN_IDX_PUBKEY
13147
};
13148
13149
/* Number of items in ASN.1 template for ECC public key. */
13150
0
#define eccPublicKeyASN_Length (sizeof(eccPublicKeyASN) / sizeof(ASNItem))
13151
#endif /* WOLFSSL_ASN_TEMPLATE */
13152
#endif /* HAVE_ECC */
13153
13154
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
13155
13156
/* Encode public ECC key in DER format.
13157
 *
13158
 * RFC 5480, 2 - Subject Public Key Information Fields
13159
 *           2.1.1 - Unrestricted Algorithm Identifier and Parameters
13160
 * X9.62 ECC point format.
13161
 * SEC 1 Ver. 2.0, C.2 - Syntax for Elliptic Curve Domain Parameters
13162
 *
13163
 * @param [out] output       Buffer to put encoded data in.
13164
 * @param [in]  key          ECC key object.
13165
 * @param [in]  outLen       Size of buffer in bytes.
13166
 * @param [in]  with_header  Whether to use SubjectPublicKeyInfo format.
13167
 * @return  Size of encoded data in bytes on success.
13168
 * @return  BAD_FUNC_ARG when key or key's parameters is NULL.
13169
 * @return  MEMORY_E when dynamic memory allocation failed.
13170
 */
13171
static int SetEccPublicKey(byte* output, ecc_key* key, int outLen,
13172
                           int with_header, int comp)
13173
0
{
13174
#ifndef WOLFSSL_ASN_TEMPLATE
13175
    int ret;
13176
    word32 idx = 0, curveSz, algoSz, pubSz, bitStringSz;
13177
    byte bitString[1 + MAX_LENGTH_SZ + 1]; /* 6 */
13178
    byte algo[MAX_ALGO_SZ];  /* 20 */
13179
13180
    /* public size */
13181
    pubSz = key->dp ? (word32)key->dp->size : MAX_ECC_BYTES;
13182
    if (comp)
13183
        pubSz = 1 + pubSz;
13184
    else
13185
        pubSz = 1 + 2 * pubSz;
13186
13187
    /* check for buffer overflow */
13188
    if (output != NULL && pubSz > (word32)outLen) {
13189
        return BUFFER_E;
13190
    }
13191
13192
    /* headers */
13193
    if (with_header) {
13194
        ret = SetCurve(key, NULL, 0);
13195
        if (ret <= 0) {
13196
            return ret;
13197
        }
13198
        curveSz = (word32)ret;
13199
        ret = 0;
13200
13201
        /* calculate size */
13202
        algoSz  = SetAlgoID(ECDSAk, algo, oidKeyType, (int)curveSz);
13203
        bitStringSz = SetBitString(pubSz, 0, bitString);
13204
        idx = SetSequence(pubSz + curveSz + bitStringSz + algoSz, NULL);
13205
13206
        /* check for buffer overflow */
13207
        if (output != NULL &&
13208
                curveSz + algoSz + bitStringSz + idx + pubSz > (word32)outLen) {
13209
            return BUFFER_E;
13210
        }
13211
13212
        idx = SetSequence(pubSz + curveSz + bitStringSz + algoSz,
13213
            output);
13214
        /* algo */
13215
        if (output)
13216
            XMEMCPY(output + idx, algo, algoSz);
13217
        idx += algoSz;
13218
        /* curve */
13219
        if (output)
13220
            (void)SetCurve(key, output + idx, curveSz);
13221
        idx += curveSz;
13222
        /* bit string */
13223
        if (output)
13224
            XMEMCPY(output + idx, bitString, bitStringSz);
13225
        idx += bitStringSz;
13226
    }
13227
13228
    /* pub */
13229
    if (output) {
13230
        PRIVATE_KEY_UNLOCK();
13231
        ret = wc_ecc_export_x963_ex(key, output + idx, &pubSz, comp);
13232
        PRIVATE_KEY_LOCK();
13233
        if (ret != 0) {
13234
            return ret;
13235
        }
13236
    }
13237
    idx += pubSz;
13238
13239
    return (int)idx;
13240
#else
13241
0
    word32 pubSz = 0;
13242
0
    int sz = 0;
13243
0
    int ret = 0;
13244
0
    int curveIdSz = 0;
13245
0
    byte* curveOid = NULL;
13246
13247
    /* Check key validity. */
13248
0
    if ((key == NULL) || (key->dp == NULL)) {
13249
0
        ret = BAD_FUNC_ARG;
13250
0
    }
13251
13252
0
    if (ret == 0) {
13253
        /* Calculate the size of the encoded public point. */
13254
0
        PRIVATE_KEY_UNLOCK();
13255
    #if defined(HAVE_COMP_KEY) && defined(HAVE_FIPS) && FIPS_VERSION3_LT(6,0,0)
13256
        /* in earlier versions of FIPS the get length functionality is not
13257
         * available with compressed keys */
13258
        pubSz = key->dp ? key->dp->size : MAX_ECC_BYTES;
13259
        if (comp)
13260
            pubSz = 1 + pubSz;
13261
        else
13262
            pubSz = 1 + 2 * pubSz;
13263
        ret = WC_NO_ERR_TRACE(LENGTH_ONLY_E);
13264
    #else
13265
0
        ret = wc_ecc_export_x963_ex(key, NULL, &pubSz, comp);
13266
0
    #endif
13267
0
        PRIVATE_KEY_LOCK();
13268
        /* LENGTH_ONLY_E on success. */
13269
0
        if (ret == WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
13270
0
            ret = 0;
13271
0
        }
13272
0
    }
13273
0
    if ((ret == 0) && with_header) {
13274
        /* Including SubjectPublicKeyInfo header. */
13275
0
        DECL_ASNSETDATA(dataASN, eccPublicKeyASN_Length);
13276
13277
0
        CALLOC_ASNSETDATA(dataASN, eccPublicKeyASN_Length, ret, key->heap);
13278
13279
        /* Get the length of the named curve OID to put into the encoding. */
13280
0
        curveIdSz = SetCurve(key, NULL, 0);
13281
0
        if (curveIdSz < 0) {
13282
0
            ret = curveIdSz;
13283
0
        }
13284
13285
0
        if (ret == 0) {
13286
            /* Set the key type OID. */
13287
0
            SetASN_OID(&dataASN[ECCPUBLICKEYASN_IDX_ALGOID_OID], ECDSAk,
13288
0
                    oidKeyType);
13289
            /* Set the curve OID. */
13290
0
            SetASN_ReplaceBuffer(&dataASN[ECCPUBLICKEYASN_IDX_ALGOID_CURVEID],
13291
0
                NULL, (word32)curveIdSz);
13292
            /* Don't try to write out explicit parameters. */
13293
0
            dataASN[ECCPUBLICKEYASN_IDX_ALGOID_PARAMS].noOut = 1;
13294
            /* Set size of public point to ensure space is made for it. */
13295
0
            SetASN_Buffer(&dataASN[ECCPUBLICKEYASN_IDX_PUBKEY], NULL, pubSz);
13296
            /* Calculate size of ECC public key. */
13297
0
            ret = SizeASN_Items(eccPublicKeyASN, dataASN,
13298
0
                                eccPublicKeyASN_Length, &sz);
13299
0
        }
13300
13301
        /* Check buffer, if passed in, is big enough for encoded data. */
13302
0
        if ((ret == 0) && (output != NULL) && (sz > outLen)) {
13303
0
            ret = BUFFER_E;
13304
0
        }
13305
0
        if ((ret == 0) && (output != NULL)) {
13306
            /* Encode ECC public key. */
13307
0
            SetASN_Items(eccPublicKeyASN, dataASN, eccPublicKeyASN_Length,
13308
0
                         output);
13309
            /* Skip to where public point is to be encoded. */
13310
0
            output += sz - (int)pubSz;
13311
            /* Cache the location to place the name curve OID. */
13312
0
            curveOid = (byte*)
13313
0
                dataASN[ECCPUBLICKEYASN_IDX_ALGOID_CURVEID].data.buffer.data;
13314
0
        }
13315
13316
0
        FREE_ASNSETDATA(dataASN, key->heap);
13317
0
    }
13318
0
    else if ((ret == 0) && (output != NULL) && (pubSz > (word32)outLen)) {
13319
0
        ret = BUFFER_E;
13320
0
    }
13321
0
    else {
13322
        /* Total size is the public point size. */
13323
0
        sz = (int)pubSz;
13324
0
    }
13325
13326
0
    if ((ret == 0) && (output != NULL)) {
13327
        /* Put named curve OID data into encoding. */
13328
0
        curveIdSz = SetCurve(key, curveOid, (size_t)curveIdSz);
13329
0
        if (curveIdSz < 0) {
13330
0
            ret = curveIdSz;
13331
0
        }
13332
0
    }
13333
0
    if ((ret == 0) && (output != NULL)) {
13334
        /* Encode public point. */
13335
0
        PRIVATE_KEY_UNLOCK();
13336
0
        ret = wc_ecc_export_x963_ex(key, output, &pubSz, comp);
13337
0
        PRIVATE_KEY_LOCK();
13338
0
    }
13339
0
    if (ret == 0) {
13340
        /* Return the size of the encoding. */
13341
0
        ret = sz;
13342
0
    }
13343
13344
0
    return ret;
13345
0
#endif
13346
0
}
13347
13348
13349
/* Encode the public part of an ECC key in a DER.
13350
 *
13351
 * Pass NULL for output to get the size of the encoding.
13352
 *
13353
 * @param [in]  key            ECC key object.
13354
 * @param [out] output         Buffer to hold DER encoding.
13355
 * @param [in]  inLen          Size of buffer in bytes.
13356
 * @param [in]  with_AlgCurve  Whether to use SubjectPublicKeyInfo format.
13357
 * @return  Size of encoded data in bytes on success.
13358
 * @return  BAD_FUNC_ARG when key or key's parameters is NULL.
13359
 * @return  MEMORY_E when dynamic memory allocation failed.
13360
 */
13361
WOLFSSL_ABI
13362
int wc_EccPublicKeyToDer(ecc_key* key, byte* output, word32 inLen,
13363
                                                              int with_AlgCurve)
13364
0
{
13365
0
    return SetEccPublicKey(output, key, (int)inLen, with_AlgCurve, 0);
13366
0
}
13367
13368
int wc_EccPublicKeyToDer_ex(ecc_key* key, byte* output, word32 inLen,
13369
                                                    int with_AlgCurve, int comp)
13370
0
{
13371
0
    return SetEccPublicKey(output, key, (int)inLen, with_AlgCurve, comp);
13372
0
}
13373
13374
int wc_EccPublicKeyDerSize(ecc_key* key, int with_AlgCurve)
13375
0
{
13376
0
    return SetEccPublicKey(NULL, key, 0, with_AlgCurve, 0);
13377
0
}
13378
13379
#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */
13380
13381
#ifdef WOLFSSL_ASN_TEMPLATE
13382
#if defined(WC_ENABLE_ASYM_KEY_EXPORT) || defined(WC_ENABLE_ASYM_KEY_IMPORT)
13383
/* ASN.1 template for the SubjectPublicKeyInfo of a general asymmetric key.
13384
 * Used with Ed448/Ed25519, Curve448/Curve25519, SPHINCS+, falcon, dilithium,
13385
 * etc.
13386
 *
13387
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
13388
 * RFC 8410, 4 - Subject Public Key Fields
13389
 */
13390
static const ASNItem publicKeyASN[] = {
13391
            /* SubjectPublicKeyInfo */
13392
/* SEQ        */ { 0, ASN_SEQUENCE, 1, 1, 0 },
13393
                                     /* AlgorithmIdentifier */
13394
/* ALGOID_SEQ */     { 1, ASN_SEQUENCE, 1, 1, 0 },
13395
                                         /* Ed25519/Ed448 OID, etc. */
13396
/* ALGOID_OID */         { 2, ASN_OBJECT_ID, 0, 0, 1 },
13397
                                     /* Public key stream */
13398
/* PUBKEY     */     { 1, ASN_BIT_STRING, 0, 0, 0 },
13399
};
13400
enum {
13401
    PUBKEYASN_IDX_SEQ = 0,
13402
    PUBKEYASN_IDX_ALGOID_SEQ,
13403
    PUBKEYASN_IDX_ALGOID_OID,
13404
    PUBKEYASN_IDX_PUBKEY
13405
};
13406
13407
/* Number of items in ASN.1 template for public key SubjectPublicKeyInfo. */
13408
#define publicKeyASN_Length (sizeof(publicKeyASN) / sizeof(ASNItem))
13409
#endif /* WC_ENABLE_ASYM_KEY_EXPORT || WC_ENABLE_ASYM_KEY_IMPORT */
13410
#endif /* WOLFSSL_ASN_TEMPLATE */
13411
13412
#ifdef WC_ENABLE_ASYM_KEY_EXPORT
13413
13414
/* Build ASN.1 formatted public key based on RFC 5280 and RFC 8410
13415
 *
13416
 * Pass NULL for output to get the size of the encoding.
13417
 *
13418
 * @param [in]  pubKey       public key buffer
13419
 * @param [in]  pubKeyLen    public key buffer length
13420
 * @param [out] output       Buffer to put encoded data in (optional)
13421
 * @param [in]  outLen       Size of buffer in bytes
13422
 * @param [in]  keyType      is "enum Key_Sum" like ED25519k
13423
 * @param [in]  withHeader   Whether to include SubjectPublicKeyInfo around key.
13424
 * @return  Size of encoded data in bytes on success
13425
 * @return  BAD_FUNC_ARG when key is NULL.
13426
 * @return  MEMORY_E when dynamic memory allocation failed.
13427
 */
13428
int SetAsymKeyDerPublic(const byte* pubKey, word32 pubKeyLen,
13429
    byte* output, word32 outLen, int keyType, int withHeader)
13430
{
13431
    int ret = 0;
13432
#ifndef WOLFSSL_ASN_TEMPLATE
13433
    word32 idx = 0;
13434
    word32 seqDataSz = 0;
13435
    word32 sz;
13436
#else
13437
    int sz = 0;
13438
    DECL_ASNSETDATA(dataASN, publicKeyASN_Length);
13439
#endif
13440
13441
    /* validate parameters */
13442
    if (pubKey == NULL){
13443
        return BAD_FUNC_ARG;
13444
    }
13445
    if (output != NULL && outLen == 0) {
13446
        return BUFFER_E;
13447
    }
13448
13449
#ifndef WOLFSSL_ASN_TEMPLATE
13450
    /* calculate size */
13451
    if (withHeader) {
13452
        word32 algoSz      = SetAlgoID(keyType, NULL, oidKeyType, 0);
13453
        word32 bitStringSz = SetBitString(pubKeyLen, 0, NULL);
13454
13455
        seqDataSz = algoSz + bitStringSz + pubKeyLen;
13456
        sz = SetSequence(seqDataSz, NULL) + seqDataSz;
13457
    }
13458
    else {
13459
        sz = pubKeyLen;
13460
    }
13461
13462
    /* checkout output size */
13463
    if (output != NULL && sz > outLen) {
13464
        ret = BUFFER_E;
13465
    }
13466
13467
    /* headers */
13468
    if (ret == 0 && output != NULL && withHeader) {
13469
        /* sequence */
13470
        idx = SetSequence(seqDataSz, output);
13471
        /* algo */
13472
        idx += SetAlgoID(keyType, output + idx, oidKeyType, 0);
13473
        /* bit string */
13474
        idx += SetBitString(pubKeyLen, 0, output + idx);
13475
    }
13476
13477
    if (ret == 0 && output != NULL) {
13478
        /* pub */
13479
        XMEMCPY(output + idx, pubKey, pubKeyLen);
13480
        idx += pubKeyLen;
13481
13482
        sz = idx;
13483
    }
13484
13485
    if (ret == 0) {
13486
        ret = (int)sz;
13487
    }
13488
#else
13489
    if (withHeader) {
13490
        CALLOC_ASNSETDATA(dataASN, publicKeyASN_Length, ret, NULL);
13491
13492
        if (ret == 0) {
13493
            /* Set the OID. */
13494
            SetASN_OID(&dataASN[PUBKEYASN_IDX_ALGOID_OID], (word32)keyType,
13495
                    oidKeyType);
13496
            /* Leave space for public point. */
13497
            SetASN_Buffer(&dataASN[PUBKEYASN_IDX_PUBKEY], NULL, pubKeyLen);
13498
            /* Calculate size of public key encoding. */
13499
            ret = SizeASN_Items(publicKeyASN, dataASN, publicKeyASN_Length,
13500
                                &sz);
13501
        }
13502
        if ((ret == 0) && (output != NULL) && (sz > (int)outLen)) {
13503
            ret = BUFFER_E;
13504
        }
13505
        if ((ret == 0) && (output != NULL)) {
13506
            /* Encode public key. */
13507
            SetASN_Items(publicKeyASN, dataASN, publicKeyASN_Length, output);
13508
            /* Set location to encode public point. */
13509
            output = (byte*)dataASN[PUBKEYASN_IDX_PUBKEY].data.buffer.data;
13510
        }
13511
13512
        FREE_ASNSETDATA(dataASN, NULL);
13513
    }
13514
    else if ((output != NULL) && (pubKeyLen > outLen)) {
13515
        ret = BUFFER_E;
13516
    }
13517
    else if (ret == 0) {
13518
        sz = (int)pubKeyLen;
13519
    }
13520
13521
    if ((ret == 0) && (output != NULL)) {
13522
        /* Put public key into space provided. */
13523
        XMEMCPY(output, pubKey, pubKeyLen);
13524
    }
13525
    if (ret == 0) {
13526
        ret = sz;
13527
    }
13528
#endif /* WOLFSSL_ASN_TEMPLATE */
13529
    return ret;
13530
}
13531
#endif /* WC_ENABLE_ASYM_KEY_EXPORT */
13532
13533
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
13534
/* Encode the public part of an Ed25519 key in DER.
13535
 *
13536
 * Pass NULL for output to get the size of the encoding.
13537
 *
13538
 * @param [in]  key       Ed25519 key object.
13539
 * @param [out] output    Buffer to put encoded data in.
13540
 * @param [in]  outLen    Size of buffer in bytes.
13541
 * @param [in]  withAlg   Whether to use SubjectPublicKeyInfo format.
13542
 * @return  Size of encoded data in bytes on success.
13543
 * @return  BAD_FUNC_ARG when key is NULL.
13544
 * @return  MEMORY_E when dynamic memory allocation failed.
13545
 */
13546
int wc_Ed25519PublicKeyToDer(ed25519_key* key, byte* output, word32 inLen,
13547
                             int withAlg)
13548
{
13549
    int    ret;
13550
    byte   pubKey[ED25519_PUB_KEY_SIZE];
13551
    word32 pubKeyLen = (word32)sizeof(pubKey);
13552
13553
    if (key == NULL) {
13554
        return BAD_FUNC_ARG;
13555
    }
13556
13557
    ret = wc_ed25519_export_public(key, pubKey, &pubKeyLen);
13558
    if (ret == 0) {
13559
        ret = SetAsymKeyDerPublic(pubKey, pubKeyLen, output, inLen,
13560
            ED25519k, withAlg);
13561
    }
13562
    return ret;
13563
}
13564
#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_EXPORT */
13565
13566
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
13567
/* Encode the public part of an Ed448 key in DER.
13568
 *
13569
 * Pass NULL for output to get the size of the encoding.
13570
 *
13571
 * @param [in]  key       Ed448 key object.
13572
 * @param [out] output    Buffer to put encoded data in.
13573
 * @param [in]  outLen    Size of buffer in bytes.
13574
 * @param [in]  withAlg   Whether to use SubjectPublicKeyInfo format.
13575
 * @return  Size of encoded data in bytes on success.
13576
 * @return  BAD_FUNC_ARG when key is NULL.
13577
 * @return  MEMORY_E when dynamic memory allocation failed.
13578
 */
13579
int wc_Ed448PublicKeyToDer(ed448_key* key, byte* output, word32 inLen,
13580
                           int withAlg)
13581
{
13582
    int    ret;
13583
    byte   pubKey[ED448_PUB_KEY_SIZE];
13584
    word32 pubKeyLen = (word32)sizeof(pubKey);
13585
13586
    if (key == NULL) {
13587
        return BAD_FUNC_ARG;
13588
    }
13589
13590
    ret = wc_ed448_export_public(key, pubKey, &pubKeyLen);
13591
    if (ret == 0) {
13592
        ret = SetAsymKeyDerPublic(pubKey, pubKeyLen, output, inLen,
13593
            ED448k, withAlg);
13594
    }
13595
    return ret;
13596
}
13597
#endif /* HAVE_ED448 && HAVE_ED448_KEY_EXPORT */
13598
#if !defined(NO_RSA) && !defined(NO_CERTS)
13599
#ifdef WOLFSSL_ASN_TEMPLATE
13600
/* ASN.1 template for header before RSA key in certificate. */
13601
static const ASNItem rsaCertKeyASN[] = {
13602
/* STR */ { 0, ASN_BIT_STRING, 0, 1, 0 },
13603
/* SEQ */     { 1, ASN_SEQUENCE, 1, 0, 0 },
13604
};
13605
enum {
13606
    RSACERTKEYASN_IDX_STR = 0,
13607
    RSACERTKEYASN_IDX_SEQ
13608
};
13609
13610
/* Number of items in ASN.1 template for header before RSA key in cert. */
13611
0
#define rsaCertKeyASN_Length (sizeof(rsaCertKeyASN) / sizeof(ASNItem))
13612
#endif
13613
13614
/* Store RSA key pointer and length in certificate object.
13615
 *
13616
 * @param [in, out] cert    Certificate object.
13617
 * @param [in]      source  Buffer containing encoded key.
13618
 * @param [in, out] srcIdx  On in, start of RSA key data.
13619
 *                          On out, start of element after RSA key data.
13620
 * @param [in]      maxIdx  Maximum index of key data.
13621
 * @return  0 on success.
13622
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
13623
 *          is invalid.
13624
 * @return  BUFFER_E when data in buffer is too small.
13625
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
13626
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
13627
 *          non-zero length.
13628
 */
13629
static int StoreRsaKey(DecodedCert* cert, const byte* source, word32* srcIdx,
13630
                       word32 maxIdx)
13631
0
{
13632
#ifndef WOLFSSL_ASN_TEMPLATE
13633
    int    length;
13634
    int    pubLen;
13635
    word32 pubIdx;
13636
13637
    if (CheckBitString(source, srcIdx, &pubLen, maxIdx, 1, NULL) != 0)
13638
        return ASN_PARSE_E;
13639
    pubIdx = *srcIdx;
13640
13641
    if (GetSequence(source, srcIdx, &length, pubIdx + (word32)pubLen) < 0)
13642
        return ASN_PARSE_E;
13643
13644
#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_FSPSM_TLS)
13645
    cert->sigCtx.CertAtt.pubkey_n_start =
13646
            cert->sigCtx.CertAtt.pubkey_e_start = pubIdx;
13647
#endif
13648
    cert->pubKeySize = (word32)pubLen;
13649
    cert->publicKey = source + pubIdx;
13650
#ifdef WOLFSSL_MAXQ10XX_TLS
13651
    cert->publicKeyIndex = pubIdx;
13652
#endif
13653
    *srcIdx += (word32)length;
13654
13655
#ifdef HAVE_OCSP
13656
    return CalcHashId_ex(cert->publicKey, cert->pubKeySize,
13657
        cert->subjectKeyHash, HashIdAlg(cert->signatureOID));
13658
#else
13659
    return 0;
13660
#endif
13661
#else
13662
0
    ASNGetData dataASN[rsaCertKeyASN_Length];
13663
0
    int ret;
13664
13665
    /* No dynamic data. */
13666
0
    XMEMSET(dataASN, 0, sizeof(dataASN));
13667
    /* Decode the header before the key data. */
13668
0
    ret = GetASN_Items(rsaCertKeyASN, dataASN, rsaCertKeyASN_Length, 1, source,
13669
0
                       srcIdx, maxIdx);
13670
0
    if (ret == 0) {
13671
        /* Store the pointer and length in certificate object starting at
13672
         * SEQUENCE. */
13673
0
        GetASN_GetConstRef(&dataASN[RSACERTKEYASN_IDX_STR],
13674
0
                &cert->publicKey, &cert->pubKeySize);
13675
13676
#ifdef WOLFSSL_MAXQ10XX_TLS
13677
    cert->publicKeyIndex = dataASN[RSACERTKEYASN_IDX_SEQ].offset;
13678
#endif
13679
13680
    #if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_FSPSM_TLS)
13681
        /* Start of SEQUENCE. */
13682
        cert->sigCtx.CertAtt.pubkey_n_start =
13683
            cert->sigCtx.CertAtt.pubkey_e_start = dataASN[RSACERTKEYASN_IDX_SEQ].offset;
13684
    #endif
13685
    #ifdef HAVE_OCSP
13686
        /* Calculate the hash of the public key for OCSP. */
13687
        ret = CalcHashId_ex(cert->publicKey, cert->pubKeySize,
13688
                         cert->subjectKeyHash, HashIdAlg(cert->signatureOID));
13689
    #endif
13690
0
    }
13691
13692
0
    return ret;
13693
0
#endif /* WOLFSSL_ASN_TEMPLATE */
13694
0
}
13695
#endif /* !NO_RSA && !NO_CERTS */
13696
13697
#if defined(HAVE_ECC) && !defined(NO_CERTS)
13698
13699
#ifdef WOLFSSL_ASN_TEMPLATE
13700
/* ASN.1 template for header before ECC key in certificate. */
13701
static const ASNItem eccCertKeyASN[] = {
13702
/* OID        */     { 1, ASN_OBJECT_ID, 0, 0, 2 },
13703
                            /* Algo parameters */
13704
/* PARAMS     */     { 1, ASN_SEQUENCE, 1, 0, 2 },
13705
                            /* Subject public key */
13706
/* SUBJPUBKEY */ { 0, ASN_BIT_STRING, 0, 0, 0 },
13707
};
13708
enum {
13709
    ECCCERTKEYASN_IDX_OID = 0,
13710
    ECCCERTKEYASN_IDX_PARAMS,
13711
    ECCCERTKEYASN_IDX_SUBJPUBKEY
13712
};
13713
13714
/* Number of items in ASN.1 template for header before ECC key in cert. */
13715
0
#define eccCertKeyASN_Length (sizeof(eccCertKeyASN) / sizeof(ASNItem))
13716
13717
#ifdef WOLFSSL_CUSTOM_CURVES
13718
static int EccSpecifiedECDomainDecode(const byte* input, word32 inSz,
13719
                                      ecc_key* key, void* heap, int* curveSz);
13720
#endif /* WOLFSSL_CUSTOM_CURVES */
13721
#endif /* WOLFSSL_ASN_TEMPLATE */
13722
13723
/* Store public ECC key in certificate object.
13724
 *
13725
 * Parse parameters and store public key data.
13726
 *
13727
 * @param [in, out] cert       Certificate object.
13728
 * @param [in]      source     Buffer containing encoded key.
13729
 * @param [in, out] srcIdx     On in, start of ECC key data.
13730
 *                             On out, start of element after ECC key data.
13731
 * @param [in]      maxIdx     Maximum index of key data.
13732
 * @param [in]      pubKey     Buffer holding encoded public key.
13733
 * @param [in]      pubKeyLen  Length of encoded public key in bytes.
13734
 * @return  0 on success.
13735
 * @return  BAD_FUNC_ARG when pubKey is NULL.
13736
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
13737
 *          is invalid.
13738
 * @return  BUFFER_E when data in buffer is too small.
13739
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
13740
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
13741
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
13742
 *          non-zero length.
13743
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
13744
 */
13745
static int StoreEccKey(DecodedCert* cert, const byte* source, word32* srcIdx,
13746
                       word32 maxIdx, const byte* pubKey, word32 pubKeyLen)
13747
0
{
13748
#ifndef WOLFSSL_ASN_TEMPLATE
13749
    int ret;
13750
    word32 localIdx;
13751
    byte* publicKey;
13752
    byte  tag;
13753
    int length;
13754
13755
    if (pubKey == NULL) {
13756
        return BAD_FUNC_ARG;
13757
    }
13758
13759
    localIdx = *srcIdx;
13760
    if (GetASNTag(source, &localIdx, &tag, maxIdx) < 0)
13761
        return ASN_PARSE_E;
13762
13763
    if (tag != (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
13764
        if (GetObjectId(source, srcIdx, &cert->pkCurveOID, oidCurveType,
13765
                                                                    maxIdx) < 0)
13766
            return ASN_PARSE_E;
13767
13768
        if ((ret = CheckCurve(cert->pkCurveOID)) < 0)
13769
            return ECC_CURVE_OID_E;
13770
13771
    #if defined(WOLFSSL_RENESAS_FSPSM_TLS) || defined(WOLFSSL_RENESAS_TSIP_TLS)
13772
        cert->sigCtx.CertAtt.curve_id = ret;
13773
    #else
13774
        (void)ret;
13775
    #endif
13776
        /* key header */
13777
        ret = CheckBitString(source, srcIdx, &length, maxIdx, 1, NULL);
13778
        if (ret != 0)
13779
            return ret;
13780
    #if defined(WOLFSSL_RENESAS_FSPSM_TLS) || defined(WOLFSSL_RENESAS_TSIP_TLS)
13781
        cert->sigCtx.CertAtt.pubkey_n_start =
13782
                cert->sigCtx.CertAtt.pubkey_e_start = (*srcIdx + 1);
13783
        cert->sigCtx.CertAtt.pubkey_n_len = ((length - 1) >> 1);
13784
        cert->sigCtx.CertAtt.pubkey_e_start +=
13785
                cert->sigCtx.CertAtt.pubkey_n_len;
13786
        cert->sigCtx.CertAtt.pubkey_e_len   =
13787
                cert->sigCtx.CertAtt.pubkey_n_len;
13788
    #endif
13789
    #ifdef WOLFSSL_MAXQ10XX_TLS
13790
        cert->publicKeyIndex = *srcIdx + 1;
13791
    #endif
13792
13793
    #ifdef HAVE_OCSP
13794
        ret = CalcHashId_ex(source + *srcIdx, (word32)length,
13795
            cert->subjectKeyHash, HashIdAlg(cert->signatureOID));
13796
        if (ret != 0)
13797
            return ret;
13798
    #endif
13799
        *srcIdx += (word32)length;
13800
    }
13801
13802
    publicKey = (byte*)XMALLOC(pubKeyLen, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
13803
    if (publicKey == NULL)
13804
        return MEMORY_E;
13805
    XMEMCPY(publicKey, pubKey, pubKeyLen);
13806
    cert->publicKey = publicKey;
13807
    cert->pubKeyStored = 1;
13808
    cert->pubKeySize   = pubKeyLen;
13809
13810
    return 0;
13811
#else
13812
0
    int ret = 0;
13813
0
    DECL_ASNGETDATA(dataASN, eccCertKeyASN_Length);
13814
0
    byte* publicKey;
13815
13816
    /* Validate parameters. */
13817
0
    if (pubKey == NULL) {
13818
0
        ret = BAD_FUNC_ARG;
13819
0
    }
13820
13821
    /* Clear dynamic data and check OID is a curve. */
13822
0
    CALLOC_ASNGETDATA(dataASN, eccCertKeyASN_Length, ret, cert->heap);
13823
0
    if (ret == 0) {
13824
0
        GetASN_OID(&dataASN[ECCCERTKEYASN_IDX_OID], oidCurveType);
13825
        /* Parse ECC public key header. */
13826
0
        ret = GetASN_Items(eccCertKeyASN, dataASN, eccCertKeyASN_Length, 1,
13827
0
                source, srcIdx, maxIdx);
13828
0
    }
13829
0
    if (ret == 0) {
13830
0
        if (dataASN[ECCCERTKEYASN_IDX_OID].tag != 0) {
13831
            /* Store curve OID. */
13832
0
            cert->pkCurveOID = dataASN[ECCCERTKEYASN_IDX_OID].data.oid.sum;
13833
0
        }
13834
0
        else {
13835
    #ifdef WOLFSSL_CUSTOM_CURVES
13836
            /* Parse explicit parameters. */
13837
            ret = EccSpecifiedECDomainDecode(
13838
                    dataASN[ECCCERTKEYASN_IDX_PARAMS].data.ref.data,
13839
                    dataASN[ECCCERTKEYASN_IDX_PARAMS].data.ref.length, NULL,
13840
                    NULL, &cert->pkCurveSize);
13841
    #else
13842
            /* Explicit parameters not supported in build configuration. */
13843
0
            ret = ASN_PARSE_E;
13844
0
    #endif
13845
0
        }
13846
13847
    #ifdef WOLFSSL_MAXQ10XX_TLS
13848
        cert->publicKeyIndex =
13849
            GetASNItem_DataIdx(dataASN[ECCCERTKEYASN_IDX_SUBJPUBKEY], source)
13850
            + 1;
13851
    #endif
13852
13853
    #ifdef HAVE_OCSP
13854
        if (ret == 0) {
13855
            /* Calculate the hash of the subject public key for OCSP. */
13856
            ret = CalcHashId_ex(
13857
                    dataASN[ECCCERTKEYASN_IDX_SUBJPUBKEY].data.ref.data,
13858
                    dataASN[ECCCERTKEYASN_IDX_SUBJPUBKEY].data.ref.length,
13859
                    cert->subjectKeyHash, HashIdAlg(cert->signatureOID));
13860
        }
13861
    }
13862
    if (ret == 0) {
13863
    #endif
13864
        /* Store public key data length. */
13865
0
        cert->pubKeySize = pubKeyLen;
13866
        /* Must allocated space for key.
13867
         * Don't memcpy into constant pointer so use temp. */
13868
0
        publicKey = (byte*)XMALLOC(cert->pubKeySize, cert->heap,
13869
0
                                   DYNAMIC_TYPE_PUBLIC_KEY);
13870
0
        if (publicKey == NULL) {
13871
0
            ret = MEMORY_E;
13872
0
        }
13873
0
        else {
13874
            /* Copy in whole public key and store pointer. */
13875
0
            XMEMCPY(publicKey, pubKey, cert->pubKeySize);
13876
0
            cert->publicKey = publicKey;
13877
            /* Indicate publicKey needs to be freed. */
13878
0
            cert->pubKeyStored = 1;
13879
0
        }
13880
0
    }
13881
0
    FREE_ASNGETDATA(dataASN, cert->heap);
13882
13883
0
    return ret;
13884
0
#endif /* WOLFSSL_ASN_TEMPLATE */
13885
0
}
13886
#endif /* HAVE_ECC && !NO_CERTS */
13887
13888
#ifndef NO_CERTS
13889
#if !defined(NO_DSA)
13890
#ifdef WOLFSSL_ASN_TEMPLATE
13891
/* ASN.1 template for DSA key in certificate.
13892
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
13893
 * RFC 3279, 2.3.2 - DSA in SubjectPublicKeyInfo
13894
 */
13895
static const ASNItem dsaCertKeyASN[] = {
13896
/*  0 */        { 1, ASN_SEQUENCE, 1, 1, 0 },
13897
/*  1 */            { 2, ASN_INTEGER, 0, 0, 0 },
13898
/*  2 */            { 2, ASN_INTEGER, 0, 0, 0 },
13899
/*  3 */            { 2, ASN_INTEGER, 0, 0, 0 },
13900
/*  4 */    { 0, ASN_BIT_STRING, 0, 1, 0 },
13901
/*  5 */        { 1, ASN_INTEGER, 0, 0, 0 },
13902
};
13903
13904
/* Number of items in ASN.1 template for DSA key in certificate. */
13905
#define dsaCertKeyASN_Length (sizeof(dsaCertKeyASN) / sizeof(ASNItem))
13906
#endif /* WOLFSSL_ASN_TEMPLATE */
13907
13908
/* Parse DSA parameters to ensure valid.
13909
 *
13910
 * @param [in]      source  Buffer containing encoded key.
13911
 * @param [in, out] srcIdx  On in, start of DSA key data.
13912
 *                          On out, start of element after DSA key data.
13913
 * @param [in]      maxIdx  Maximum index of key data.
13914
 * @param [in]      heap    Dynamic memory hint.
13915
 * @return  0 on success.
13916
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
13917
 *          is invalid.
13918
 * @return  BUFFER_E when data in buffer is too small.
13919
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
13920
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
13921
 *          non-zero length.
13922
 */
13923
static int ParseDsaKey(const byte* source, word32* srcIdx, word32 maxIdx,
13924
                       void* heap)
13925
{
13926
#ifndef WOLFSSL_ASN_TEMPLATE
13927
    int ret;
13928
    int length;
13929
13930
    (void)heap;
13931
13932
    ret = GetSequence(source, srcIdx, &length, maxIdx);
13933
    if (ret < 0)
13934
        return ret;
13935
13936
    ret = SkipInt(source, srcIdx, maxIdx);
13937
    if (ret != 0)
13938
        return ret;
13939
    ret = SkipInt(source, srcIdx, maxIdx);
13940
    if (ret != 0)
13941
        return ret;
13942
    ret = SkipInt(source, srcIdx, maxIdx);
13943
    if (ret != 0)
13944
        return ret;
13945
13946
    ret = CheckBitString(source, srcIdx, &length, maxIdx, 1, NULL);
13947
    if (ret != 0)
13948
        return ret;
13949
13950
    ret = GetASNInt(source, srcIdx, &length, maxIdx);
13951
    if (ret != 0)
13952
        return ASN_PARSE_E;
13953
13954
    *srcIdx += (word32)length;
13955
13956
    return 0;
13957
#else
13958
    DECL_ASNGETDATA(dataASN, dsaCertKeyASN_Length);
13959
    int ret = 0;
13960
13961
    (void)heap;
13962
13963
    CALLOC_ASNGETDATA(dataASN, dsaCertKeyASN_Length, ret, heap);
13964
    if (ret == 0) {
13965
        /* Parse the DSA key data to ensure valid. */
13966
        ret = GetASN_Items(dsaCertKeyASN, dataASN, dsaCertKeyASN_Length, 1,
13967
                           source, srcIdx, maxIdx);
13968
    }
13969
13970
    FREE_ASNGETDATA(dataASN, heap);
13971
    return ret;
13972
#endif /* WOLFSSL_ASN_TEMPLATE */
13973
}
13974
#endif /* !NO_DSA */
13975
13976
/* Decode the SubjectPublicKeyInfo block in a certificate.
13977
 *
13978
 * Stores the public key in fields of the certificate object.
13979
 * Validates the BER/DER items and does not store in a key object.
13980
 *
13981
 * @param [in, out] cert      Decoded certificate object.
13982
 * @param [in]      source    BER/DER encoded SubjectPublicKeyInfo block.
13983
 * @param [in, out] inOutIdx  On in, start of public key.
13984
 *                            On out, start of ASN.1 item after public key.
13985
 * @param [in]      maxIdx    Maximum index of key data.
13986
 * @return  0 on success.
13987
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
13988
 *          is invalid.
13989
 * @return  BUFFER_E when data in buffer is too small.
13990
 */
13991
static int GetCertKey(DecodedCert* cert, const byte* source, word32* inOutIdx,
13992
                      word32 maxIdx)
13993
0
{
13994
0
    word32 srcIdx = *inOutIdx;
13995
0
#if defined(HAVE_ECC) || !defined(NO_DSA)
13996
0
    int pubLen;
13997
0
#endif
13998
0
#if defined(HAVE_ECC) || !defined(NO_DSA)
13999
0
    int pubIdx = (int)srcIdx;
14000
0
#endif
14001
0
    int ret = 0;
14002
0
    int length;
14003
14004
    /* Validate parameters. */
14005
0
    if (source == NULL) {
14006
0
        return ASN_PARSE_E;
14007
0
    }
14008
14009
#ifndef WOLFSSL_ASN_TEMPLATE
14010
    if (GetSequence(source, &srcIdx, &length, maxIdx) < 0)
14011
#else
14012
    /* Get SEQUENCE and expect all data to be accounted for. */
14013
0
    if (GetASN_Sequence(source, &srcIdx, &length, maxIdx, 1) != 0)
14014
0
#endif
14015
0
    {
14016
0
        return ASN_PARSE_E;
14017
0
    }
14018
14019
0
#if defined(HAVE_ECC) || !defined(NO_DSA)
14020
0
    pubLen = (int)srcIdx - pubIdx + length;
14021
0
#endif
14022
0
    maxIdx = srcIdx + (word32)length;
14023
14024
    /* Decode the algorithm identifier for the key. */
14025
0
    if (GetAlgoId(source, &srcIdx, &cert->keyOID, oidKeyType, maxIdx) < 0) {
14026
0
        return ASN_PARSE_E;
14027
0
    }
14028
14029
0
    (void)length;
14030
14031
    /* Parse each type of public key. */
14032
0
    switch (cert->keyOID) {
14033
0
#ifndef NO_RSA
14034
0
    #ifdef WC_RSA_PSS
14035
0
        case RSAPSSk:
14036
0
            if (srcIdx != maxIdx &&
14037
0
                          source[srcIdx] == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
14038
0
                word32 seqIdx = srcIdx;
14039
0
                int seqLen;
14040
                /* Not set when -1. */
14041
0
                enum wc_HashType hash = WC_HASH_TYPE_NONE;
14042
0
                int mgf = -1;
14043
0
                int saltLen = 0;
14044
                /* Defaults for sig algorithm parameters. */
14045
0
                enum wc_HashType sigHash = WC_HASH_TYPE_SHA;
14046
0
                int sigMgf = WC_MGF1SHA1;
14047
0
                int sigSaltLen = 20;
14048
14049
0
                if (GetSequence(source, &srcIdx, &seqLen, maxIdx) < 0) {
14050
0
                    return ASN_PARSE_E;
14051
0
                }
14052
                /* Get the pubic key parameters. */
14053
0
                ret = DecodeRsaPssParams(source + seqIdx,
14054
0
                    (word32)seqLen + srcIdx - seqIdx, &hash, &mgf, &saltLen);
14055
0
                if (ret != 0) {
14056
0
                    return ASN_PARSE_E;
14057
0
                }
14058
                /* Get the signature parameters. */
14059
0
                ret = DecodeRsaPssParams(source + cert->sigParamsIndex,
14060
0
                    cert->sigParamsLength, &sigHash, &sigMgf, &sigSaltLen);
14061
0
                if (ret != 0) {
14062
0
                    return ASN_PARSE_E;
14063
0
                }
14064
                /* Validated signature params match public key params. */
14065
0
                if (hash != WC_HASH_TYPE_NONE && hash != sigHash) {
14066
0
                    WOLFSSL_MSG("RSA PSS: hash not matching signature hash");
14067
0
                    return ASN_PARSE_E;
14068
0
                }
14069
0
                if (mgf != -1 && mgf != sigMgf) {
14070
0
                    WOLFSSL_MSG("RSA PSS: MGF not matching signature MGF");
14071
0
                    return ASN_PARSE_E;
14072
0
                }
14073
0
                if (saltLen > sigSaltLen) {
14074
0
                    WOLFSSL_MSG("RSA PSS: sig salt length too small");
14075
0
                    return ASN_PARSE_E;
14076
0
                }
14077
0
                srcIdx += (word32)seqLen;
14078
0
            }
14079
0
            FALL_THROUGH;
14080
0
    #endif /* WC_RSA_PSS */
14081
0
        case RSAk:
14082
0
            ret = StoreRsaKey(cert, source, &srcIdx, maxIdx);
14083
0
            break;
14084
0
#endif /* NO_RSA */
14085
0
    #ifdef HAVE_ECC
14086
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
14087
        case SM2k:
14088
    #endif
14089
0
        case ECDSAk:
14090
0
            ret = StoreEccKey(cert, source, &srcIdx, maxIdx, source + pubIdx,
14091
0
                              (word32)pubLen);
14092
0
            break;
14093
0
    #endif /* HAVE_ECC */
14094
    #ifdef HAVE_ED25519
14095
        case ED25519k:
14096
            cert->pkCurveOID = ED25519k;
14097
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
14098
            break;
14099
    #endif /* HAVE_ED25519 */
14100
    #ifdef HAVE_ED448
14101
        case ED448k:
14102
            cert->pkCurveOID = ED448k;
14103
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
14104
            break;
14105
    #endif /* HAVE_ED448 */
14106
    #ifdef HAVE_FALCON
14107
        case FALCON_LEVEL1k:
14108
            cert->pkCurveOID = FALCON_LEVEL1k;
14109
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
14110
            break;
14111
        case FALCON_LEVEL5k:
14112
            cert->pkCurveOID = FALCON_LEVEL5k;
14113
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
14114
            break;
14115
    #endif /* HAVE_FALCON */
14116
    #ifdef HAVE_DILITHIUM
14117
        #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
14118
        case DILITHIUM_LEVEL2k:
14119
        case DILITHIUM_LEVEL3k:
14120
        case DILITHIUM_LEVEL5k:
14121
        #endif
14122
        case ML_DSA_LEVEL2k:
14123
        case ML_DSA_LEVEL3k:
14124
        case ML_DSA_LEVEL5k:
14125
            cert->pkCurveOID = cert->keyOID;
14126
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
14127
            break;
14128
    #endif /* HAVE_DILITHIUM */
14129
    #ifdef HAVE_SPHINCS
14130
        case SPHINCS_FAST_LEVEL1k:
14131
            cert->pkCurveOID = SPHINCS_FAST_LEVEL1k;
14132
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
14133
            break;
14134
        case SPHINCS_FAST_LEVEL3k:
14135
            cert->pkCurveOID = SPHINCS_FAST_LEVEL3k;
14136
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
14137
            break;
14138
        case SPHINCS_FAST_LEVEL5k:
14139
            cert->pkCurveOID = SPHINCS_FAST_LEVEL5k;
14140
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
14141
            break;
14142
        case SPHINCS_SMALL_LEVEL1k:
14143
            cert->pkCurveOID = SPHINCS_SMALL_LEVEL1k;
14144
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
14145
            break;
14146
        case SPHINCS_SMALL_LEVEL3k:
14147
            cert->pkCurveOID = SPHINCS_SMALL_LEVEL3k;
14148
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
14149
            break;
14150
        case SPHINCS_SMALL_LEVEL5k:
14151
            cert->pkCurveOID = SPHINCS_SMALL_LEVEL5k;
14152
            ret = StoreKey(cert, source, &srcIdx, maxIdx);
14153
            break;
14154
    #endif /* HAVE_SPHINCS */
14155
    #ifndef NO_DSA
14156
        case DSAk:
14157
            cert->publicKey = source + pubIdx;
14158
            cert->pubKeySize = (word32)pubLen;
14159
            ret = ParseDsaKey(source, &srcIdx, maxIdx, cert->heap);
14160
            break;
14161
    #endif /* NO_DSA */
14162
0
        default:
14163
0
            WOLFSSL_MSG("Unknown or not compiled in key OID");
14164
0
            WOLFSSL_ERROR_VERBOSE(ASN_UNKNOWN_OID_E);
14165
0
            ret = ASN_UNKNOWN_OID_E;
14166
0
    }
14167
14168
    /* Return index after public key. */
14169
0
    *inOutIdx = srcIdx;
14170
14171
    /* Return error code. */
14172
0
    return ret;
14173
0
}
14174
#endif
14175
14176
/* Return the hash algorithm to use with the signature algorithm.
14177
 *
14178
 * @param [in] oidSum  Signature id.
14179
 * @return  Hash algorithm id.
14180
 */
14181
int HashIdAlg(word32 oidSum)
14182
0
{
14183
0
    (void)oidSum;
14184
14185
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
14186
    if (oidSum == CTC_SM3wSM2) {
14187
        return WC_SM3;
14188
    }
14189
    if (oidSum == SM2k) {
14190
        return WC_SM3;
14191
    }
14192
#endif
14193
#if defined(NO_SHA) || (!defined(NO_SHA256) && defined(WC_ASN_HASH_SHA256))
14194
    return WC_SHA256;
14195
#else
14196
0
    return WC_SHA;
14197
0
#endif
14198
0
}
14199
14200
/* Calculate hash of the id using the SHA-1 or SHA-256.
14201
 *
14202
 * @param [in]  data  Data to hash.
14203
 * @param [in]  len   Length of data to hash.
14204
 * @param [out] hash  Buffer to hold hash.
14205
 * @return  0 on success.
14206
 * @return  MEMORY_E when dynamic memory allocation fails.
14207
 */
14208
int CalcHashId(const byte* data, word32 len, byte* hash)
14209
0
{
14210
    /* Use default hash algorithm. */
14211
0
    return CalcHashId_ex(data, len, hash,
14212
#if defined(NO_SHA) || (!defined(NO_SHA256) && defined(WC_ASN_HASH_SHA256))
14213
        WC_SHA256
14214
#else
14215
0
        WC_SHA
14216
0
#endif
14217
0
        );
14218
0
}
14219
14220
/* Calculate hash of the id using the SHA-1 or SHA-256.
14221
 *
14222
 * @param [in]  data  Data to hash.
14223
 * @param [in]  len   Length of data to hash.
14224
 * @param [out] hash  Buffer to hold hash.
14225
 * @return  0 on success.
14226
 * @return  MEMORY_E when dynamic memory allocation fails.
14227
 */
14228
int CalcHashId_ex(const byte* data, word32 len, byte* hash, int hashAlg)
14229
0
{
14230
0
    int ret;
14231
14232
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
14233
    if (hashAlg == WC_SM3) {
14234
        ret = wc_Sm3Hash(data, len, hash);
14235
    }
14236
    else
14237
#endif
14238
#if defined(NO_SHA) || (!defined(NO_SHA256) && defined(WC_ASN_HASH_SHA256))
14239
    if (hashAlg == WC_SHA256) {
14240
        ret = wc_Sha256Hash(data, len, hash);
14241
    }
14242
    else
14243
#elif !defined(NO_SHA)
14244
0
    if (hashAlg == WC_SHA) {
14245
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
14246
        XMEMSET(hash + WC_SHA_DIGEST_SIZE, 0, KEYID_SIZE - WC_SHA_DIGEST_SIZE);
14247
    #endif
14248
0
        ret = wc_ShaHash(data, len, hash);
14249
0
    }
14250
0
    else
14251
#else
14252
    (void)data;
14253
    (void)len;
14254
    (void)hash;
14255
#endif
14256
0
    {
14257
0
        ret = NOT_COMPILED_IN;
14258
0
    }
14259
14260
0
    return ret;
14261
0
}
14262
14263
#ifndef NO_CERTS
14264
/* Get the hash of the id using the SHA-1 or SHA-256.
14265
 *
14266
 * If the id is not the length of the hash, then hash it.
14267
 *
14268
 * @param [in]  id    Id to get hash for.
14269
 * @param [in]  len   Length of id in bytes.
14270
 * @param [out] hash  Buffer to hold hash.
14271
 * @return  0 on success.
14272
 * @return  MEMORY_E when dynamic memory allocation fails.
14273
 */
14274
static int GetHashId(const byte* id, int length, byte* hash, int hashAlg)
14275
0
{
14276
0
    int ret;
14277
14278
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
14279
    if (length == wc_HashGetDigestSize(wc_HashTypeConvert(hashAlg)))
14280
#else
14281
0
    if (length == KEYID_SIZE)
14282
0
#endif
14283
0
    {
14284
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
14285
        XMEMSET(hash + length, 0, KEYID_SIZE - length);
14286
    #endif
14287
0
        XMEMCPY(hash, id, (size_t)length);
14288
0
        ret = 0;
14289
0
    }
14290
0
    else {
14291
0
        ret = CalcHashId_ex(id, (word32)length, hash, hashAlg);
14292
0
    }
14293
14294
0
    return ret;
14295
0
}
14296
#endif /* !NO_CERTS */
14297
14298
#ifdef WOLFSSL_ASN_TEMPLATE
14299
/* Id for email address. */
14300
0
#define ASN_EMAIL     0x100
14301
/* Id for domain component. */
14302
0
#define ASN_DC        0x102
14303
/* Id for jurisdiction country. */
14304
#define ASN_JURIS_C   0x203
14305
/* Id for jurisdiction state. */
14306
#define ASN_JURIS_ST  0x202
14307
14308
/* Set the string for a name component into the subject name. */
14309
#define SetCertNameSubject(cert, id, val) \
14310
    *((char**)(((byte *)(cert)) + certNameSubject[(id) - 3].data)) = (val)
14311
/* Set the string length for a name component into the subject name. */
14312
#define SetCertNameSubjectLen(cert, id, val) \
14313
    *((int*)(((byte *)(cert)) + certNameSubject[(id) - 3].len)) = (int)(val)
14314
/* Set the encoding for a name component into the subject name. */
14315
#define SetCertNameSubjectEnc(cert, id, val) \
14316
    *((byte*)(((byte *)(cert)) + certNameSubject[(id) - 3].enc)) = (val)
14317
14318
/* Get the string of a name component from the subject name. */
14319
#ifdef WOLFSSL_NAMES_STATIC
14320
    #define GetCertNameSubjectStr(id) \
14321
        ((certNameSubject[(id) - 3].strLen) ? \
14322
         (certNameSubject[(id) - 3].str) : \
14323
         NULL)
14324
#else
14325
    #define GetCertNameSubjectStr(id) \
14326
0
        (certNameSubject[(id) - 3].str)
14327
#endif
14328
/* Get the string length of a name component from the subject name. */
14329
#define GetCertNameSubjectStrLen(id) \
14330
0
    (certNameSubject[(id) - 3].strLen)
14331
/* Get the NID of a name component from the subject name. */
14332
#define GetCertNameSubjectNID(id) \
14333
    (certNameSubject[(id) - 3].nid)
14334
14335
#define ValidCertNameSubject(id) \
14336
0
    (((id) - 3) >= 0 && ((id) - 3) < certNameSubjectSz && \
14337
0
            (certNameSubject[(id) - 3].strLen > 0))
14338
14339
/* Set the string for a name component into the issuer name. */
14340
#define SetCertNameIssuer(cert, id, val) \
14341
    *((char**)(((byte *)(cert)) + certNameSubject[(id) - 3].dataI)) = (val)
14342
/* Set the string length for a name component into the issuer name. */
14343
#define SetCertNameIssuerLen(cert, id, val) \
14344
    *((int*)(((byte *)(cert)) + certNameSubject[(id) - 3].lenI)) = (int)(val)
14345
/* Set the encoding for a name component into the issuer name. */
14346
#define SetCertNameIssuerEnc(cert, id, val) \
14347
    *((byte*)(((byte *)(cert)) + certNameSubject[(id) - 3].encI)) = (val)
14348
14349
14350
/* Mapping of certificate name component to useful information. */
14351
typedef struct CertNameData {
14352
    /* Type string of name component. */
14353
#ifdef WOLFSSL_NAMES_STATIC
14354
    const char str[20]; /* large enough for largest string in certNameSubject[]
14355
                         * below
14356
                         */
14357
    #define EMPTY_STR { 0 }
14358
#else
14359
    const char* str;
14360
    #define EMPTY_STR NULL
14361
#endif
14362
    /* Length of type string of name component. */
14363
    byte        strLen;
14364
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
14365
    /* Offset of data in subject name component. */
14366
    size_t      data;
14367
    /* Offset of length in subject name component. */
14368
    size_t      len;
14369
    /* Offset of encoding in subject name component. */
14370
    size_t      enc;
14371
#ifdef WOLFSSL_HAVE_ISSUER_NAMES
14372
    /* Offset of data in subject name component. */
14373
    size_t      dataI;
14374
    /* Offset of length in subject name component. */
14375
    size_t      lenI;
14376
    /* Offset of encoding in subject name component. */
14377
    size_t      encI;
14378
#endif
14379
#endif
14380
#ifdef WOLFSSL_X509_NAME_AVAILABLE
14381
    /* NID of type for subject name component. */
14382
    int         nid;
14383
#endif
14384
} CertNameData;
14385
14386
/* List of data for common name components. */
14387
static const CertNameData certNameSubject[] = {
14388
    /* Common Name */
14389
    {
14390
        "/CN=", 4,
14391
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
14392
        WC_OFFSETOF(DecodedCert, subjectCN),
14393
        WC_OFFSETOF(DecodedCert, subjectCNLen),
14394
        WC_OFFSETOF(DecodedCert, subjectCNEnc),
14395
#ifdef WOLFSSL_HAVE_ISSUER_NAMES
14396
        WC_OFFSETOF(DecodedCert, issuerCN),
14397
        WC_OFFSETOF(DecodedCert, issuerCNLen),
14398
        WC_OFFSETOF(DecodedCert, issuerCNEnc),
14399
#endif
14400
#endif
14401
#ifdef WOLFSSL_X509_NAME_AVAILABLE
14402
        WC_NID_commonName
14403
#endif
14404
    },
14405
    /* Surname */
14406
    {
14407
        "/SN=", 4,
14408
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
14409
        WC_OFFSETOF(DecodedCert, subjectSN),
14410
        WC_OFFSETOF(DecodedCert, subjectSNLen),
14411
        WC_OFFSETOF(DecodedCert, subjectSNEnc),
14412
#ifdef WOLFSSL_HAVE_ISSUER_NAMES
14413
        WC_OFFSETOF(DecodedCert, issuerSN),
14414
        WC_OFFSETOF(DecodedCert, issuerSNLen),
14415
        WC_OFFSETOF(DecodedCert, issuerSNEnc),
14416
#endif
14417
#endif
14418
#ifdef WOLFSSL_X509_NAME_AVAILABLE
14419
        WC_NID_surname
14420
#endif
14421
    },
14422
    /* Serial Number */
14423
    {
14424
        "/serialNumber=", 14,
14425
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
14426
        WC_OFFSETOF(DecodedCert, subjectSND),
14427
        WC_OFFSETOF(DecodedCert, subjectSNDLen),
14428
        WC_OFFSETOF(DecodedCert, subjectSNDEnc),
14429
#ifdef WOLFSSL_HAVE_ISSUER_NAMES
14430
        WC_OFFSETOF(DecodedCert, issuerSND),
14431
        WC_OFFSETOF(DecodedCert, issuerSNDLen),
14432
        WC_OFFSETOF(DecodedCert, issuerSNDEnc),
14433
#endif
14434
#endif
14435
#ifdef WOLFSSL_X509_NAME_AVAILABLE
14436
        WC_NID_serialNumber
14437
#endif
14438
    },
14439
    /* Country Name */
14440
    {
14441
        "/C=", 3,
14442
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
14443
        WC_OFFSETOF(DecodedCert, subjectC),
14444
        WC_OFFSETOF(DecodedCert, subjectCLen),
14445
        WC_OFFSETOF(DecodedCert, subjectCEnc),
14446
#ifdef WOLFSSL_HAVE_ISSUER_NAMES
14447
        WC_OFFSETOF(DecodedCert, issuerC),
14448
        WC_OFFSETOF(DecodedCert, issuerCLen),
14449
        WC_OFFSETOF(DecodedCert, issuerCEnc),
14450
#endif
14451
#endif
14452
#ifdef WOLFSSL_X509_NAME_AVAILABLE
14453
        WC_NID_countryName
14454
#endif
14455
    },
14456
    /* Locality Name */
14457
    {
14458
        "/L=", 3,
14459
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
14460
        WC_OFFSETOF(DecodedCert, subjectL),
14461
        WC_OFFSETOF(DecodedCert, subjectLLen),
14462
        WC_OFFSETOF(DecodedCert, subjectLEnc),
14463
#ifdef WOLFSSL_HAVE_ISSUER_NAMES
14464
        WC_OFFSETOF(DecodedCert, issuerL),
14465
        WC_OFFSETOF(DecodedCert, issuerLLen),
14466
        WC_OFFSETOF(DecodedCert, issuerLEnc),
14467
#endif
14468
#endif
14469
#ifdef WOLFSSL_X509_NAME_AVAILABLE
14470
        WC_NID_localityName
14471
#endif
14472
    },
14473
    /* State Name */
14474
    {
14475
        "/ST=", 4,
14476
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
14477
        WC_OFFSETOF(DecodedCert, subjectST),
14478
        WC_OFFSETOF(DecodedCert, subjectSTLen),
14479
        WC_OFFSETOF(DecodedCert, subjectSTEnc),
14480
#ifdef WOLFSSL_HAVE_ISSUER_NAMES
14481
        WC_OFFSETOF(DecodedCert, issuerST),
14482
        WC_OFFSETOF(DecodedCert, issuerSTLen),
14483
        WC_OFFSETOF(DecodedCert, issuerSTEnc),
14484
#endif
14485
#endif
14486
#ifdef WOLFSSL_X509_NAME_AVAILABLE
14487
        WC_NID_stateOrProvinceName
14488
#endif
14489
    },
14490
    /* Street Address */
14491
    {
14492
        "/street=", 8,
14493
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
14494
        WC_OFFSETOF(DecodedCert, subjectStreet),
14495
        WC_OFFSETOF(DecodedCert, subjectStreetLen),
14496
        WC_OFFSETOF(DecodedCert, subjectStreetEnc),
14497
#ifdef WOLFSSL_HAVE_ISSUER_NAMES
14498
        0,
14499
        0,
14500
        0,
14501
#endif
14502
#endif
14503
#ifdef WOLFSSL_X509_NAME_AVAILABLE
14504
        WC_NID_streetAddress
14505
#endif
14506
    },
14507
    /* Organization Name */
14508
    {
14509
        "/O=", 3,
14510
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
14511
        WC_OFFSETOF(DecodedCert, subjectO),
14512
        WC_OFFSETOF(DecodedCert, subjectOLen),
14513
        WC_OFFSETOF(DecodedCert, subjectOEnc),
14514
#ifdef WOLFSSL_HAVE_ISSUER_NAMES
14515
        WC_OFFSETOF(DecodedCert, issuerO),
14516
        WC_OFFSETOF(DecodedCert, issuerOLen),
14517
        WC_OFFSETOF(DecodedCert, issuerOEnc),
14518
#endif
14519
#endif
14520
#ifdef WOLFSSL_X509_NAME_AVAILABLE
14521
        WC_NID_organizationName
14522
#endif
14523
    },
14524
    /* Organization Unit Name */
14525
    {
14526
        "/OU=", 4,
14527
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
14528
        WC_OFFSETOF(DecodedCert, subjectOU),
14529
        WC_OFFSETOF(DecodedCert, subjectOULen),
14530
        WC_OFFSETOF(DecodedCert, subjectOUEnc),
14531
#ifdef WOLFSSL_HAVE_ISSUER_NAMES
14532
        WC_OFFSETOF(DecodedCert, issuerOU),
14533
        WC_OFFSETOF(DecodedCert, issuerOULen),
14534
        WC_OFFSETOF(DecodedCert, issuerOUEnc),
14535
#endif
14536
#endif
14537
#ifdef WOLFSSL_X509_NAME_AVAILABLE
14538
        WC_NID_organizationalUnitName
14539
#endif
14540
    },
14541
    /* Title */
14542
    {
14543
        EMPTY_STR, 0,
14544
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
14545
        0,
14546
        0,
14547
        0,
14548
#ifdef WOLFSSL_HAVE_ISSUER_NAMES
14549
        0,
14550
        0,
14551
        0,
14552
#endif
14553
#endif
14554
#ifdef WOLFSSL_X509_NAME_AVAILABLE
14555
        0,
14556
#endif
14557
    },
14558
    /* Undefined */
14559
    {
14560
        EMPTY_STR, 0,
14561
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
14562
        0,
14563
        0,
14564
        0,
14565
#ifdef WOLFSSL_HAVE_ISSUER_NAMES
14566
        0,
14567
        0,
14568
        0,
14569
#endif
14570
#endif
14571
#ifdef WOLFSSL_X509_NAME_AVAILABLE
14572
        0,
14573
#endif
14574
    },
14575
    /* Undefined */
14576
    {
14577
        EMPTY_STR, 0,
14578
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
14579
        0,
14580
        0,
14581
        0,
14582
#ifdef WOLFSSL_HAVE_ISSUER_NAMES
14583
        0,
14584
        0,
14585
        0,
14586
#endif
14587
#endif
14588
#ifdef WOLFSSL_X509_NAME_AVAILABLE
14589
        0,
14590
#endif
14591
    },
14592
    /* Business Category */
14593
    {
14594
        "/businessCategory=", 18,
14595
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
14596
        WC_OFFSETOF(DecodedCert, subjectBC),
14597
        WC_OFFSETOF(DecodedCert, subjectBCLen),
14598
        WC_OFFSETOF(DecodedCert, subjectBCEnc),
14599
#ifdef WOLFSSL_HAVE_ISSUER_NAMES
14600
        0,
14601
        0,
14602
        0,
14603
#endif
14604
#endif
14605
#ifdef WOLFSSL_X509_NAME_AVAILABLE
14606
        WC_NID_businessCategory
14607
#endif
14608
    },
14609
    /* Undefined */
14610
    {
14611
        EMPTY_STR, 0,
14612
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
14613
        0,
14614
        0,
14615
        0,
14616
#ifdef WOLFSSL_HAVE_ISSUER_NAMES
14617
        0,
14618
        0,
14619
        0,
14620
#endif
14621
#endif
14622
#ifdef WOLFSSL_X509_NAME_AVAILABLE
14623
        0,
14624
#endif
14625
    },
14626
    /* Postal Code */
14627
    {
14628
        "/postalCode=", 12,
14629
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
14630
        WC_OFFSETOF(DecodedCert, subjectPC),
14631
        WC_OFFSETOF(DecodedCert, subjectPCLen),
14632
        WC_OFFSETOF(DecodedCert, subjectPCEnc),
14633
#ifdef WOLFSSL_HAVE_ISSUER_NAMES
14634
        0,
14635
        0,
14636
        0,
14637
#endif
14638
#endif
14639
#ifdef WOLFSSL_X509_NAME_AVAILABLE
14640
        WC_NID_postalCode
14641
#endif
14642
    },
14643
    /* User Id */
14644
    {
14645
        "/userid=", 8,
14646
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
14647
        WC_OFFSETOF(DecodedCert, subjectUID),
14648
        WC_OFFSETOF(DecodedCert, subjectUIDLen),
14649
        WC_OFFSETOF(DecodedCert, subjectUIDEnc),
14650
#ifdef WOLFSSL_HAVE_ISSUER_NAMES
14651
        0,
14652
        0,
14653
        0,
14654
#endif
14655
#endif
14656
#ifdef WOLFSSL_X509_NAME_AVAILABLE
14657
        WC_NID_userId
14658
#endif
14659
    },
14660
#ifdef WOLFSSL_CERT_NAME_ALL
14661
    /* Name, id 41 */
14662
    {
14663
        "/N=", 3,
14664
    #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
14665
        WC_OFFSETOF(DecodedCert, subjectN),
14666
        WC_OFFSETOF(DecodedCert, subjectNLen),
14667
        WC_OFFSETOF(DecodedCert, subjectNEnc),
14668
#ifdef WOLFSSL_HAVE_ISSUER_NAMES
14669
        0,
14670
        0,
14671
        0,
14672
#endif
14673
    #endif
14674
    #ifdef WOLFSSL_X509_NAME_AVAILABLE
14675
        WC_NID_name
14676
    #endif
14677
    },
14678
    /* Given Name, id 42 */
14679
    {
14680
        "/GN=", 4,
14681
    #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
14682
        WC_OFFSETOF(DecodedCert, subjectGN),
14683
        WC_OFFSETOF(DecodedCert, subjectGNLen),
14684
        WC_OFFSETOF(DecodedCert, subjectGNEnc),
14685
#ifdef WOLFSSL_HAVE_ISSUER_NAMES
14686
        0,
14687
        0,
14688
        0,
14689
#endif
14690
    #endif
14691
    #ifdef WOLFSSL_X509_NAME_AVAILABLE
14692
        WC_NID_givenName
14693
    #endif
14694
    },
14695
    /* initials, id 43 */
14696
    {
14697
        "/initials=", 10,
14698
    #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
14699
        WC_OFFSETOF(DecodedCert, subjectI),
14700
        WC_OFFSETOF(DecodedCert, subjectILen),
14701
        WC_OFFSETOF(DecodedCert, subjectIEnc),
14702
#ifdef WOLFSSL_HAVE_ISSUER_NAMES
14703
        0,
14704
        0,
14705
        0,
14706
#endif
14707
    #endif
14708
    #ifdef WOLFSSL_X509_NAME_AVAILABLE
14709
        WC_NID_initials
14710
    #endif
14711
    },
14712
    /* DN Qualifier Name, id 46 */
14713
    {
14714
        "/dnQualifier=", 13,
14715
    #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
14716
        WC_OFFSETOF(DecodedCert, subjectDNQ),
14717
        WC_OFFSETOF(DecodedCert, subjectDNQLen),
14718
        WC_OFFSETOF(DecodedCert, subjectDNQEnc),
14719
#ifdef WOLFSSL_HAVE_ISSUER_NAMES
14720
        0,
14721
        0,
14722
        0,
14723
#endif
14724
    #endif
14725
    #ifdef WOLFSSL_X509_NAME_AVAILABLE
14726
        WC_NID_dnQualifier
14727
    #endif
14728
    },
14729
#endif /* WOLFSSL_CERT_NAME_ALL */
14730
};
14731
14732
static const int certNameSubjectSz =
14733
        (int) (sizeof(certNameSubject) / sizeof(CertNameData));
14734
14735
14736
/* ASN.1 template for an RDN.
14737
 * X.509: RFC 5280, 4.1.2.4 - RelativeDistinguishedName
14738
 */
14739
static const ASNItem rdnASN[] = {
14740
/* SET       */ { 1, ASN_SET, 1, 1, 0 },
14741
                           /* AttributeTypeAndValue */
14742
/* ATTR_SEQ  */     { 2, ASN_SEQUENCE, 1, 1, 0 },
14743
                                   /* AttributeType */
14744
/* ATTR_TYPE */         { 3, ASN_OBJECT_ID, 0, 0, 0 },
14745
                           /* AttributeValue: Choice of tags - rdnChoice. */
14746
/* ATTR_VAL  */         { 3, 0, 0, 0, 0 },
14747
};
14748
enum {
14749
    RDNASN_IDX_SET = 0,
14750
    RDNASN_IDX_ATTR_SEQ,
14751
    RDNASN_IDX_ATTR_TYPE,
14752
    RDNASN_IDX_ATTR_VAL
14753
};
14754
14755
/* Number of items in ASN.1 template for an RDN. */
14756
0
#define rdnASN_Length (sizeof(rdnASN) / sizeof(ASNItem))
14757
14758
/* Supported types of encodings (tags) for RDN strings.
14759
 * X.509: RFC 5280, 4.1.2.4 - DirectoryString
14760
 * (IA5 String not listed in RFC but required for alternative types)
14761
 */
14762
static const byte rdnChoice[] = {
14763
    ASN_PRINTABLE_STRING, ASN_IA5_STRING, ASN_UTF8STRING, ASN_T61STRING,
14764
    ASN_UNIVERSALSTRING, ASN_BMPSTRING, 0
14765
};
14766
#endif
14767
14768
#ifdef WOLFSSL_IP_ALT_NAME
14769
/* used to set the human readable string for the IP address with a ASN_IP_TYPE
14770
 * DNS entry
14771
 * return 0 on success
14772
 */
14773
static int GenerateDNSEntryIPString(DNS_entry* entry, void* heap)
14774
{
14775
    int ret = 0;
14776
    size_t nameSz = 0;
14777
    char tmpName[WOLFSSL_MAX_IPSTR];
14778
    unsigned char* ip;
14779
14780
    if (entry == NULL || entry->type != ASN_IP_TYPE) {
14781
        return BAD_FUNC_ARG;
14782
    }
14783
14784
    if (entry->len != WOLFSSL_IP4_ADDR_LEN &&
14785
            entry->len != WOLFSSL_IP6_ADDR_LEN) {
14786
        WOLFSSL_MSG("Unexpected IP size");
14787
        return BAD_FUNC_ARG;
14788
    }
14789
    ip = (unsigned char*)entry->name;
14790
14791
    XMEMSET(tmpName, 0, sizeof(tmpName));
14792
14793
    /* store IP addresses as a string */
14794
    if (entry->len == WOLFSSL_IP4_ADDR_LEN) {
14795
        if (XSNPRINTF(tmpName, sizeof(tmpName), "%u.%u.%u.%u", 0xFFU & ip[0],
14796
                      0xFFU & ip[1], 0xFFU & ip[2], 0xFFU & ip[3])
14797
            >= (int)sizeof(tmpName))
14798
        {
14799
            WOLFSSL_MSG("IP buffer overrun");
14800
            return BUFFER_E;
14801
        }
14802
    }
14803
14804
    if (entry->len == WOLFSSL_IP6_ADDR_LEN) {
14805
        size_t i;
14806
        for (i = 0; i < 8; i++) {
14807
            if (XSNPRINTF(tmpName + i * 5, sizeof(tmpName) - i * 5,
14808
                    "%02X%02X%s", 0xFF & ip[2 * i], 0xFF & ip[2 * i + 1],
14809
                    (i < 7) ? ":" : "")
14810
                >= (int)sizeof(tmpName))
14811
            {
14812
                WOLFSSL_MSG("IPv6 buffer overrun");
14813
                return BUFFER_E;
14814
            }
14815
        }
14816
    }
14817
14818
    nameSz = XSTRLEN(tmpName);
14819
    entry->ipString = (char*)XMALLOC(nameSz + 1, heap,
14820
        DYNAMIC_TYPE_ALTNAME);
14821
    if (entry->ipString == NULL) {
14822
        ret = MEMORY_E;
14823
    }
14824
14825
    if (ret == 0) {
14826
        XMEMCPY(entry->ipString, tmpName, nameSz);
14827
        entry->ipString[nameSz] = '\0';
14828
    }
14829
14830
    (void)heap;
14831
14832
    return ret;
14833
}
14834
#endif /* WOLFSSL_IP_ALT_NAME */
14835
14836
#ifdef WOLFSSL_RID_ALT_NAME
14837
/* used to set the human readable string for the registeredID with an
14838
 * ASN_RID_TYPE DNS entry
14839
 * return 0 on success
14840
 */
14841
static int GenerateDNSEntryRIDString(DNS_entry* entry, void* heap)
14842
{
14843
    int i, j, ret   = 0;
14844
    word16 nameSz   = 0;
14845
#if !defined(WOLFCRYPT_ONLY) && defined(OPENSSL_EXTRA)
14846
    int nid         = 0;
14847
#endif
14848
    int tmpSize     = MAX_OID_SZ;
14849
    word32 oid      = 0;
14850
    word32 idx      = 0;
14851
    word16 tmpName[MAX_OID_SZ];
14852
    char   oidName[MAX_OID_SZ];
14853
    char*  finalName = NULL;
14854
14855
    if (entry == NULL || entry->type != ASN_RID_TYPE) {
14856
        return BAD_FUNC_ARG;
14857
    }
14858
14859
    if (entry->len <= 0) {
14860
        return BAD_FUNC_ARG;
14861
    }
14862
14863
    XMEMSET(&oidName, 0, MAX_OID_SZ);
14864
14865
    ret = GetOID((const byte*)entry->name, &idx, &oid, oidIgnoreType,
14866
                 entry->len);
14867
    if (ret == 0) {
14868
    #if !defined(WOLFCRYPT_ONLY) && defined(OPENSSL_EXTRA)
14869
        if ((nid = oid2nid(oid, oidCsrAttrType)) > 0) {
14870
            /* OID has known string value */
14871
            finalName = (char*)wolfSSL_OBJ_nid2ln(nid);
14872
        }
14873
        else
14874
    #endif
14875
        {
14876
            /* Decode OBJECT_ID into dotted form array. */
14877
            ret = DecodeObjectId((const byte*)(entry->name),(word32)entry->len,
14878
                    tmpName, (word32*)&tmpSize);
14879
14880
            if (ret == 0) {
14881
                j = 0;
14882
                /* Append each number of dotted form. */
14883
                for (i = 0; i < tmpSize; i++) {
14884
                    if (j >= MAX_OID_SZ) {
14885
                        return BUFFER_E;
14886
                    }
14887
14888
                    if (i < tmpSize - 1) {
14889
                        ret = XSNPRINTF(oidName + j, (word32)(MAX_OID_SZ - j),
14890
                            "%d.", tmpName[i]);
14891
                    }
14892
                    else {
14893
                        ret = XSNPRINTF(oidName + j, (word32)(MAX_OID_SZ - j),
14894
                            "%d", tmpName[i]);
14895
                    }
14896
14897
                    if (ret >= 0) {
14898
                        j += ret;
14899
                    }
14900
                    else {
14901
                        return BUFFER_E;
14902
                    }
14903
                }
14904
                ret = 0;
14905
                finalName = oidName;
14906
            }
14907
        }
14908
    }
14909
14910
    if (ret == 0) {
14911
        nameSz = (word16)XSTRLEN((const char*)finalName);
14912
        if (nameSz > MAX_OID_SZ) {
14913
            return BUFFER_E;
14914
        }
14915
14916
        entry->ridString = (char*)XMALLOC((word32)(nameSz + 1), heap,
14917
                DYNAMIC_TYPE_ALTNAME);
14918
14919
        if (entry->ridString == NULL) {
14920
            ret = MEMORY_E;
14921
        }
14922
14923
        if (ret == 0) {
14924
            XMEMCPY(entry->ridString, finalName, (word32)(nameSz + 1));
14925
        }
14926
    }
14927
14928
    return ret;
14929
}
14930
#endif /* WOLFSSL_RID_ALT_NAME */
14931
14932
#ifdef WOLFSSL_ASN_TEMPLATE
14933
14934
#if defined(WOLFSSL_CERT_GEN) || !defined(NO_CERTS)
14935
14936
/* Adds a DNS entry to a list of DNS entries
14937
 *
14938
 * @param [in, out] lst      Linked list of DNS name entries.
14939
 * @param [in]      entry    Entry to add to the list
14940
 * @return  0 on success.
14941
 */
14942
static int AddDNSEntryToList(DNS_entry** lst, DNS_entry* entry)
14943
0
{
14944
#if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_ALT_NAMES_NO_REV)
14945
    entry->next = NULL;
14946
    if (*lst == NULL) {
14947
        /* First on list */
14948
        *lst = entry;
14949
    }
14950
    else {
14951
        DNS_entry* temp = *lst;
14952
14953
        /* Find end */
14954
        for (; (temp->next != NULL); temp = temp->next);
14955
14956
        /* Add to end */
14957
        temp->next = entry;
14958
    }
14959
#else
14960
    /* Prepend entry to linked list. */
14961
0
    entry->next = *lst;
14962
0
    *lst = entry;
14963
0
#endif
14964
14965
0
    return 0;
14966
0
}
14967
14968
14969
/* Allocate a DNS entry and set the fields.
14970
 *
14971
 * @param [in]      heap     Heap hint.
14972
 * @param [in]      str      DNS name string.
14973
 * @param [in]      strLen   Length of DNS name string.
14974
 * @param [in]      type     Type of DNS name string.
14975
 * @param [in, out] entries  Linked list of DNS name entries.
14976
 * @return  0 on success.
14977
 * @return  MEMORY_E when dynamic memory allocation fails.
14978
 */
14979
static int SetDNSEntry(void* heap, const char* str, int strLen,
14980
                       int type, DNS_entry** entries)
14981
0
{
14982
0
    DNS_entry* dnsEntry;
14983
0
    int ret = 0;
14984
14985
    /* TODO: consider one malloc. */
14986
    /* Allocate DNS Entry object. */
14987
0
    dnsEntry = AltNameNew(heap);
14988
0
    if (dnsEntry == NULL) {
14989
0
        ret = MEMORY_E;
14990
0
    }
14991
0
    if (ret == 0) {
14992
        /* Allocate DNS Entry name - length of string plus 1 for NUL. */
14993
0
        dnsEntry->name = (char*)XMALLOC((size_t)strLen + 1, heap,
14994
0
                                                          DYNAMIC_TYPE_ALTNAME);
14995
0
        if (dnsEntry->name == NULL) {
14996
0
            ret = MEMORY_E;
14997
0
        }
14998
0
    }
14999
0
    if (ret == 0) {
15000
        /* Set tag type, name length, name and NUL terminate name. */
15001
0
        dnsEntry->type = type;
15002
0
        dnsEntry->len = strLen;
15003
0
        XMEMCPY(dnsEntry->name, str, (size_t)strLen);
15004
0
        dnsEntry->name[strLen] = '\0';
15005
15006
#ifdef WOLFSSL_RID_ALT_NAME
15007
        /* store registeredID as a string */
15008
        if (type == ASN_RID_TYPE)
15009
            ret = GenerateDNSEntryRIDString(dnsEntry, heap);
15010
#endif
15011
0
    }
15012
#ifdef WOLFSSL_IP_ALT_NAME
15013
    /* store IP addresses as a string */
15014
    if (ret == 0 && type == ASN_IP_TYPE)
15015
        ret = GenerateDNSEntryIPString(dnsEntry, heap);
15016
#endif
15017
0
    if (ret == 0) {
15018
0
        ret = AddDNSEntryToList(entries, dnsEntry);
15019
0
    }
15020
15021
    /* failure cleanup */
15022
0
    if (ret != 0 && dnsEntry != NULL) {
15023
0
        XFREE(dnsEntry->name, heap, DYNAMIC_TYPE_ALTNAME);
15024
0
        XFREE(dnsEntry, heap, DYNAMIC_TYPE_ALTNAME);
15025
0
    }
15026
15027
0
    return ret;
15028
0
}
15029
#endif
15030
15031
/* Set the details of a subject name component into a certificate.
15032
 *
15033
 * @param [in, out] cert    Certificate object.
15034
 * @param [in]      id      Id of component.
15035
 * @param [in]      str     String for component.
15036
 * @param [in]      strLen  Length of string.
15037
 * @param [in]      tag     BER tag representing encoding of string.
15038
 * @return  0 on success, negative values on failure.
15039
 */
15040
static int SetSubject(DecodedCert* cert, int id, byte* str, int strLen,
15041
                      byte tag)
15042
0
{
15043
0
    int ret = 0;
15044
15045
    /* Put string and encoding into certificate. */
15046
0
    if (id == ASN_COMMON_NAME) {
15047
0
        cert->subjectCN = (char *)str;
15048
0
        cert->subjectCNLen = (int)strLen;
15049
0
        cert->subjectCNEnc = (char)tag;
15050
0
    }
15051
#if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
15052
    else if (id > ASN_COMMON_NAME && id <= ASN_USER_ID) {
15053
        /* Use table and offsets to put data into appropriate fields. */
15054
        SetCertNameSubject(cert, id, (char*)str);
15055
        SetCertNameSubjectLen(cert, id, strLen);
15056
        SetCertNameSubjectEnc(cert, id, tag);
15057
    }
15058
#endif
15059
0
#if !defined(IGNORE_NAME_CONSTRAINTS) || \
15060
0
     defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
15061
0
    else if (id == ASN_EMAIL) {
15062
0
        cert->subjectEmail = (char*)str;
15063
0
        cert->subjectEmailLen = strLen;
15064
0
    }
15065
0
#endif
15066
#ifdef WOLFSSL_CERT_EXT
15067
    /* TODO: consider mapping id to an index and using SetCertNameSubect*(). */
15068
    else if (id == ASN_JURIS_C) {
15069
        cert->subjectJC = (char*)str;
15070
        cert->subjectJCLen = strLen;
15071
        cert->subjectJCEnc = (char)tag;
15072
    }
15073
    else if (id == ASN_JURIS_ST) {
15074
        cert->subjectJS = (char*)str;
15075
        cert->subjectJSLen = strLen;
15076
        cert->subjectJSEnc = (char)tag;
15077
    }
15078
#endif
15079
15080
0
    return ret;
15081
0
}
15082
15083
#if (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)) && \
15084
    defined(WOLFSSL_HAVE_ISSUER_NAMES)
15085
/* Set the details of an issuer name component into a certificate.
15086
 *
15087
 * @param [in, out] cert    Certificate object.
15088
 * @param [in]      id      Id of component.
15089
 * @param [in]      str     String for component.
15090
 * @param [in]      strLen  Length of string.
15091
 * @param [in]      tag     BER tag representing encoding of string.
15092
 * @return  0 on success, negative values on failure.
15093
 */
15094
static int SetIssuer(DecodedCert* cert, int id, byte* str, int strLen,
15095
                      byte tag)
15096
{
15097
    int ret = 0;
15098
15099
    /* Put string and encoding into certificate. */
15100
    if (id == ASN_COMMON_NAME) {
15101
        cert->issuerCN = (char *)str;
15102
        cert->issuerCNLen = (int)strLen;
15103
        cert->issuerCNEnc = (char)tag;
15104
    }
15105
    else if (id > ASN_COMMON_NAME && id <= ASN_USER_ID) {
15106
        /* Use table and offsets to put data into appropriate fields. */
15107
        SetCertNameIssuer(cert, id, (char*)str);
15108
        SetCertNameIssuerLen(cert, id, strLen);
15109
        SetCertNameIssuerEnc(cert, id, tag);
15110
    }
15111
    else if (id == ASN_EMAIL) {
15112
        cert->issuerEmail = (char*)str;
15113
        cert->issuerEmailLen = strLen;
15114
    }
15115
15116
    return ret;
15117
}
15118
#endif
15119
15120
/* Get a RelativeDistinguishedName from the encoding and put in certificate.
15121
 *
15122
 * @param [in, out] cert       Certificate object.
15123
 * @param [in, out] full       Full name string. ([/<type>=<value>]*)
15124
 * @param [in, out] idx        Index int full name to place next component.
15125
 * @param [in, out] nid        NID of component type.
15126
 * @param [in]      isSubject  Whether this data is for a subject name.
15127
 * @param [in]      dataASN    Decoded data of RDN. Expected rdnASN type.
15128
 * @return  0 on success.
15129
 * @return  MEMORY_E when dynamic memory allocation fails.
15130
 * @return  ASN_PARSE_E when type not supported.
15131
 */
15132
static int GetRDN(DecodedCert* cert, char* full, word32* idx, int* nid,
15133
                  int isSubject, ASNGetData* dataASN)
15134
0
{
15135
0
    int         ret = 0;
15136
0
    const char* typeStr = NULL;
15137
0
    byte        typeStrLen = 0;
15138
0
    byte*       oid;
15139
0
    word32      oidSz;
15140
0
    int         id = 0;
15141
15142
0
    (void)nid;
15143
15144
    /* Get name type OID from data items. */
15145
0
    GetASN_OIDData(&dataASN[RDNASN_IDX_ATTR_TYPE], &oid, &oidSz);
15146
15147
    /* v1 name types */
15148
0
    if ((oidSz == 3) && (oid[0] == 0x55) && (oid[1] == 0x04)) {
15149
0
        id = oid[2];
15150
        /* Check range of supported ids in table. */
15151
0
        if (ValidCertNameSubject(id)) {
15152
            /* Get the type string, length and NID from table. */
15153
0
            typeStr = GetCertNameSubjectStr(id);
15154
0
            typeStrLen = GetCertNameSubjectStrLen(id);
15155
        #ifdef WOLFSSL_X509_NAME_AVAILABLE
15156
            *nid = GetCertNameSubjectNID(id);
15157
        #endif
15158
0
        }
15159
0
    }
15160
0
    else if (oidSz == sizeof(attrEmailOid) && XMEMCMP(oid, attrEmailOid, oidSz) == 0) {
15161
        /* Set the email id, type string, length and NID. */
15162
0
        id = ASN_EMAIL;
15163
0
        typeStr =  WOLFSSL_EMAIL_ADDR;
15164
0
        typeStrLen = sizeof(WOLFSSL_EMAIL_ADDR) - 1;
15165
    #ifdef WOLFSSL_X509_NAME_AVAILABLE
15166
        *nid = WC_NID_emailAddress;
15167
    #endif
15168
0
    }
15169
0
    else if (oidSz == sizeof(uidOid) && XMEMCMP(oid, uidOid, oidSz) == 0) {
15170
        /* Set the user id, type string, length and NID. */
15171
0
        id = ASN_USER_ID;
15172
0
        typeStr = WOLFSSL_USER_ID;
15173
0
        typeStrLen = sizeof(WOLFSSL_USER_ID) - 1;
15174
    #ifdef WOLFSSL_X509_NAME_AVAILABLE
15175
        *nid = WC_NID_userId;
15176
    #endif
15177
0
    }
15178
0
    else if (oidSz == sizeof(dcOid) && XMEMCMP(oid, dcOid, oidSz) == 0) {
15179
        /* Set the domain component, type string, length and NID. */
15180
0
        id = ASN_DC;
15181
0
        typeStr = WOLFSSL_DOMAIN_COMPONENT;
15182
0
        typeStrLen = sizeof(WOLFSSL_DOMAIN_COMPONENT) - 1;
15183
    #ifdef WOLFSSL_X509_NAME_AVAILABLE
15184
        *nid = WC_NID_domainComponent;
15185
    #endif
15186
0
    }
15187
0
    else if (oidSz == sizeof(rfc822Mlbx) && XMEMCMP(oid, rfc822Mlbx, oidSz) == 0) {
15188
        /* Set the RFC822 mailbox, type string, length and NID. */
15189
0
        id = ASN_RFC822_MAILBOX;
15190
0
        typeStr = WOLFSSL_RFC822_MAILBOX;
15191
0
        typeStrLen = sizeof(WOLFSSL_RFC822_MAILBOX) - 1;
15192
    #ifdef WOLFSSL_X509_NAME_AVAILABLE
15193
        *nid = WC_NID_rfc822Mailbox;
15194
    #endif
15195
0
    }
15196
0
    else if (oidSz == sizeof(fvrtDrk) && XMEMCMP(oid, fvrtDrk, oidSz) == 0) {
15197
        /* Set the favourite drink, type string, length and NID. */
15198
0
        id = ASN_FAVOURITE_DRINK;
15199
0
        typeStr = WOLFSSL_FAVOURITE_DRINK;
15200
0
        typeStrLen = sizeof(WOLFSSL_FAVOURITE_DRINK) - 1;
15201
    #ifdef WOLFSSL_X509_NAME_AVAILABLE
15202
        *nid = WC_NID_favouriteDrink;
15203
    #endif
15204
0
    }
15205
#ifdef WOLFSSL_CERT_REQ
15206
    else if (oidSz == sizeof(attrPkcs9ContentTypeOid) &&
15207
             XMEMCMP(oid, attrPkcs9ContentTypeOid, oidSz) == 0) {
15208
        /* Set the pkcs9_contentType, type string, length and NID. */
15209
        id = ASN_CONTENT_TYPE;
15210
        typeStr = WOLFSSL_CONTENT_TYPE;
15211
        typeStrLen = sizeof(WOLFSSL_CONTENT_TYPE) - 1;
15212
    #ifdef WOLFSSL_X509_NAME_AVAILABLE
15213
        *nid = WC_NID_pkcs9_contentType;
15214
    #endif
15215
    }
15216
#endif
15217
    /* Other OIDs that start with the same values. */
15218
0
    else if (oidSz == sizeof(dcOid) && XMEMCMP(oid, dcOid, oidSz-1) == 0) {
15219
0
        WOLFSSL_MSG("Unknown pilot attribute type");
15220
0
        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
15221
0
        ret = ASN_PARSE_E;
15222
0
    }
15223
0
    else if (oidSz == ASN_JOI_PREFIX_SZ + 1 &&
15224
0
                         XMEMCMP(oid, ASN_JOI_PREFIX, ASN_JOI_PREFIX_SZ) == 0) {
15225
        /* Set the jurisdiction id. */
15226
0
        id = 0x200 + oid[ASN_JOI_PREFIX_SZ];
15227
15228
        /* Set the jurisdiction type string, length and NID if known. */
15229
0
        if (oid[ASN_JOI_PREFIX_SZ] == ASN_JOI_C) {
15230
0
            typeStr = WOLFSSL_JOI_C;
15231
0
            typeStrLen = sizeof(WOLFSSL_JOI_C) - 1;
15232
        #ifdef WOLFSSL_X509_NAME_AVAILABLE
15233
            *nid = WC_NID_jurisdictionCountryName;
15234
        #endif /* WOLFSSL_X509_NAME_AVAILABLE */
15235
0
        }
15236
0
        else if (oid[ASN_JOI_PREFIX_SZ] == ASN_JOI_ST) {
15237
0
            typeStr = WOLFSSL_JOI_ST;
15238
0
            typeStrLen = sizeof(WOLFSSL_JOI_ST) - 1;
15239
        #ifdef WOLFSSL_X509_NAME_AVAILABLE
15240
            *nid = WC_NID_jurisdictionStateOrProvinceName;
15241
        #endif /* WOLFSSL_X509_NAME_AVAILABLE */
15242
0
        }
15243
0
        else {
15244
0
            WOLFSSL_MSG("Unknown Jurisdiction, skipping");
15245
0
        }
15246
0
    }
15247
15248
0
    if ((ret == 0) && (typeStr != NULL)) {
15249
        /* OID type to store for subject name and add to full string. */
15250
0
        byte*  str;
15251
0
        word32 strLen;
15252
0
        byte   tag = dataASN[RDNASN_IDX_ATTR_VAL].tag;
15253
15254
        /* Get the string reference and length. */
15255
0
        GetASN_GetRef(&dataASN[RDNASN_IDX_ATTR_VAL], &str, &strLen);
15256
15257
0
        if (isSubject) {
15258
            /* Store subject field components. */
15259
0
            ret = SetSubject(cert, id, str, (int)strLen, tag);
15260
0
        }
15261
    #if (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)) && \
15262
        defined(WOLFSSL_HAVE_ISSUER_NAMES)
15263
        /* Put issuer common name string and encoding into certificate. */
15264
        else {
15265
            ret = SetIssuer(cert, id, str, (int)strLen, tag);
15266
        }
15267
    #endif
15268
0
        if (ret == 0) {
15269
            /* Check there is space for this in the full name string and
15270
             * terminating NUL character. */
15271
0
            if ((typeStrLen + strLen) < (word32)(WC_ASN_NAME_MAX - *idx))
15272
0
            {
15273
                /* Add RDN to full string. */
15274
0
                XMEMCPY(&full[*idx], typeStr, typeStrLen);
15275
0
                *idx += typeStrLen;
15276
0
                XMEMCPY(&full[*idx], str, strLen);
15277
0
                *idx += strLen;
15278
0
            }
15279
0
            else {
15280
0
                WOLFSSL_MSG("ASN Name too big, skipping");
15281
0
            }
15282
0
        }
15283
0
    }
15284
15285
0
    return ret;
15286
0
}
15287
#endif /* WOLFSSL_ASN_TEMPLATE */
15288
15289
/* Get a certificate name into the certificate object.
15290
 *
15291
 * @param [in, out] cert      Decoded certificate object.
15292
 * @param [out]     full      Buffer to hold full name as a string.
15293
 * @param [out]     hash      Buffer to hold hash of name.
15294
 * @param [in]      nameType  ASN_ISSUER or ASN_SUBJECT.
15295
 * @param [in]      input     Buffer holding certificate name.
15296
 * @param [in, out] inOutIdx  On in, start of certificate name.
15297
 *                            On out, start of ASN.1 item after cert name.
15298
 * @param [in]      maxIdx    Index of next item after certificate name.
15299
 * @return  0 on success.
15300
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
15301
 *          is invalid.
15302
 * @return  BUFFER_E when data in buffer is too small.
15303
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
15304
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
15305
 * @return  MEMORY_E when dynamic memory allocation fails.
15306
 */
15307
static int GetCertName(DecodedCert* cert, char* full, byte* hash, int nameType,
15308
                       const byte* input, word32* inOutIdx, word32 maxIdx)
15309
0
{
15310
#ifndef WOLFSSL_ASN_TEMPLATE
15311
    int    length;  /* length of all distinguished names */
15312
    int    dummy;
15313
    int    ret;
15314
    word32 idx;
15315
    word32 srcIdx = *inOutIdx;
15316
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
15317
    !defined(WOLFCRYPT_ONLY)
15318
    WOLFSSL_X509_NAME* dName = NULL;
15319
#endif
15320
15321
    WOLFSSL_MSG("Getting Cert Name");
15322
15323
    /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
15324
     * calculated over the entire DER encoding of the Name field, including
15325
     * the tag and length. */
15326
    if (CalcHashId_ex(input + *inOutIdx, maxIdx - *inOutIdx, hash,
15327
            HashIdAlg(cert->signatureOID)) != 0) {
15328
        return ASN_PARSE_E;
15329
    }
15330
15331
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
15332
    !defined(WOLFCRYPT_ONLY)
15333
    dName = wolfSSL_X509_NAME_new_ex(cert->heap);
15334
    if (dName == NULL) {
15335
        return MEMORY_E;
15336
    }
15337
#endif /* OPENSSL_EXTRA */
15338
15339
    if (GetSequence(input, &srcIdx, &length, maxIdx) < 0) {
15340
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
15341
            !defined(WOLFCRYPT_ONLY)
15342
        wolfSSL_X509_NAME_free(dName);
15343
#endif /* OPENSSL_EXTRA */
15344
        return ASN_PARSE_E;
15345
    }
15346
15347
#if defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT)
15348
    /* store pointer to raw issuer */
15349
    if (nameType == ASN_ISSUER) {
15350
        cert->issuerRaw = &input[srcIdx];
15351
        cert->issuerRawLen = length;
15352
    }
15353
#endif
15354
#if !defined(IGNORE_NAME_CONSTRAINTS) || defined(WOLFSSL_CERT_EXT)
15355
    if (nameType == ASN_SUBJECT) {
15356
        cert->subjectRaw = &input[srcIdx];
15357
        cert->subjectRawLen = length;
15358
    }
15359
#endif
15360
15361
    length += (int)srcIdx;
15362
    idx = 0;
15363
15364
    while (srcIdx < (word32)length) {
15365
        byte        b       = 0;
15366
        byte        joint[3];
15367
        byte        tooBig  = FALSE;
15368
        int         oidSz;
15369
        const char* copy    = NULL;
15370
        int         copyLen = 0;
15371
        int         strLen  = 0;
15372
        byte        id      = 0;
15373
    #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \
15374
                && !defined(WOLFCRYPT_ONLY)
15375
         int        nid = WC_NID_undef;
15376
         int        enc;
15377
    #endif /* OPENSSL_EXTRA */
15378
15379
        if (GetSet(input, &srcIdx, &dummy, maxIdx) < 0) {
15380
            WOLFSSL_MSG("Cert name lacks set header, trying sequence");
15381
        }
15382
15383
        if (GetSequence(input, &srcIdx, &dummy, maxIdx) <= 0) {
15384
        #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
15385
            !defined(WOLFCRYPT_ONLY)
15386
            wolfSSL_X509_NAME_free(dName);
15387
        #endif /* OPENSSL_EXTRA */
15388
            return ASN_PARSE_E;
15389
        }
15390
15391
        ret = GetASNObjectId(input, &srcIdx, &oidSz, maxIdx);
15392
        if (ret != 0) {
15393
        #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
15394
            !defined(WOLFCRYPT_ONLY)
15395
            wolfSSL_X509_NAME_free(dName);
15396
        #endif /* OPENSSL_EXTRA */
15397
            return ret;
15398
        }
15399
15400
        /* make sure there is room for joint */
15401
        if ((srcIdx + sizeof(joint)) > (word32)maxIdx) {
15402
        #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
15403
            !defined(WOLFCRYPT_ONLY)
15404
            wolfSSL_X509_NAME_free(dName);
15405
        #endif /* OPENSSL_EXTRA */
15406
            return ASN_PARSE_E;
15407
        }
15408
15409
        XMEMCPY(joint, &input[srcIdx], sizeof(joint));
15410
15411
        /* v1 name types */
15412
        if (joint[0] == 0x55 && joint[1] == 0x04) {
15413
            srcIdx += 3;
15414
            id = joint[2];
15415
            if (GetHeader(input, &b, &srcIdx, &strLen, maxIdx, 1) < 0) {
15416
            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
15417
            !defined(WOLFCRYPT_ONLY)
15418
                wolfSSL_X509_NAME_free(dName);
15419
            #endif /* OPENSSL_EXTRA */
15420
                return ASN_PARSE_E;
15421
            }
15422
15423
        #ifndef WOLFSSL_NO_ASN_STRICT
15424
            /* RFC 5280 section 4.1.2.4 lists a DirectoryString as being
15425
             * 1..MAX in length */
15426
            if (strLen < 1) {
15427
                WOLFSSL_MSG("Non conforming DirectoryString of length 0 was"
15428
                            " found");
15429
                WOLFSSL_MSG("Use WOLFSSL_NO_ASN_STRICT if wanting to allow"
15430
                            " empty DirectoryString's");
15431
            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
15432
            !defined(WOLFCRYPT_ONLY)
15433
                wolfSSL_X509_NAME_free(dName);
15434
            #endif /* OPENSSL_EXTRA */
15435
                return ASN_PARSE_E;
15436
            }
15437
        #endif
15438
15439
            if (id == ASN_COMMON_NAME) {
15440
                if (nameType == ASN_SUBJECT) {
15441
                    cert->subjectCN = (char *)&input[srcIdx];
15442
                    cert->subjectCNLen = strLen;
15443
                    cert->subjectCNEnc = (char)b;
15444
                }
15445
            #if (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)) && \
15446
                defined(WOLFSSL_HAVE_ISSUER_NAMES)
15447
                else if (nameType == ASN_ISSUER) {
15448
                    cert->issuerCN = (char*)&input[srcIdx];
15449
                    cert->issuerCNLen = strLen;
15450
                    cert->issuerCNEnc = (char)b;
15451
                }
15452
            #endif
15453
15454
                copy = WOLFSSL_COMMON_NAME;
15455
                copyLen = sizeof(WOLFSSL_COMMON_NAME) - 1;
15456
            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \
15457
                && !defined(WOLFCRYPT_ONLY)
15458
                nid = WC_NID_commonName;
15459
            #endif /* OPENSSL_EXTRA */
15460
            }
15461
        #ifdef WOLFSSL_CERT_NAME_ALL
15462
            else if (id == ASN_NAME) {
15463
                copy = WOLFSSL_NAME;
15464
                copyLen = sizeof(WOLFSSL_NAME) - 1;
15465
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
15466
                    if (nameType == ASN_SUBJECT) {
15467
                        cert->subjectN = (char*)&input[srcIdx];
15468
                        cert->subjectNLen = strLen;
15469
                        cert->subjectNEnc = b;
15470
                    }
15471
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
15472
                #if (defined(OPENSSL_EXTRA) || \
15473
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
15474
                        && !defined(WOLFCRYPT_ONLY)
15475
                    nid = WC_NID_name;
15476
                #endif /* OPENSSL_EXTRA */
15477
            }
15478
            else if (id == ASN_INITIALS) {
15479
                copy = WOLFSSL_INITIALS;
15480
                copyLen = sizeof(WOLFSSL_INITIALS) - 1;
15481
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
15482
                    if (nameType == ASN_SUBJECT) {
15483
                        cert->subjectI = (char*)&input[srcIdx];
15484
                        cert->subjectILen = strLen;
15485
                        cert->subjectIEnc = b;
15486
                    }
15487
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
15488
                #if (defined(OPENSSL_EXTRA) || \
15489
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
15490
                        && !defined(WOLFCRYPT_ONLY)
15491
                    nid = WC_NID_initials;
15492
                #endif /* OPENSSL_EXTRA */
15493
            }
15494
            else if (id == ASN_GIVEN_NAME) {
15495
                copy = WOLFSSL_GIVEN_NAME;
15496
                copyLen = sizeof(WOLFSSL_GIVEN_NAME) - 1;
15497
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
15498
                    if (nameType == ASN_SUBJECT) {
15499
                        cert->subjectGN = (char*)&input[srcIdx];
15500
                        cert->subjectGNLen = strLen;
15501
                        cert->subjectGNEnc = b;
15502
                    }
15503
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
15504
                #if (defined(OPENSSL_EXTRA) || \
15505
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
15506
                        && !defined(WOLFCRYPT_ONLY)
15507
                    nid = WC_NID_givenName;
15508
                #endif /* OPENSSL_EXTRA */
15509
            }
15510
            else if (id == ASN_DNQUALIFIER) {
15511
                copy = WOLFSSL_DNQUALIFIER;
15512
                copyLen = sizeof(WOLFSSL_DNQUALIFIER) - 1;
15513
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
15514
                    if (nameType == ASN_SUBJECT) {
15515
                        cert->subjectDNQ = (char*)&input[srcIdx];
15516
                        cert->subjectDNQLen = strLen;
15517
                        cert->subjectDNQEnc = b;
15518
                    }
15519
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
15520
                #if (defined(OPENSSL_EXTRA) || \
15521
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
15522
                        && !defined(WOLFCRYPT_ONLY)
15523
                    nid = WC_NID_dnQualifier;
15524
                #endif /* OPENSSL_EXTRA */
15525
            }
15526
        #endif /* WOLFSSL_CERT_NAME_ALL */
15527
            else if (id == ASN_SUR_NAME) {
15528
                copy = WOLFSSL_SUR_NAME;
15529
                copyLen = sizeof(WOLFSSL_SUR_NAME) - 1;
15530
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
15531
                    if (nameType == ASN_SUBJECT) {
15532
                        cert->subjectSN = (char*)&input[srcIdx];
15533
                        cert->subjectSNLen = strLen;
15534
                        cert->subjectSNEnc = (char)b;
15535
                    }
15536
                #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
15537
                    else if (nameType == ASN_ISSUER) {
15538
                        cert->issuerSN = (char*)&input[srcIdx];
15539
                        cert->issuerSNLen = strLen;
15540
                        cert->issuerSNEnc = (char)b;
15541
                    }
15542
                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
15543
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
15544
                #if (defined(OPENSSL_EXTRA) || \
15545
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
15546
                        && !defined(WOLFCRYPT_ONLY)
15547
                    nid = WC_NID_surname;
15548
                #endif /* OPENSSL_EXTRA */
15549
            }
15550
            else if (id == ASN_COUNTRY_NAME) {
15551
                copy = WOLFSSL_COUNTRY_NAME;
15552
                copyLen = sizeof(WOLFSSL_COUNTRY_NAME) - 1;
15553
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
15554
                    if (nameType == ASN_SUBJECT) {
15555
                        cert->subjectC = (char*)&input[srcIdx];
15556
                        cert->subjectCLen = strLen;
15557
                        cert->subjectCEnc = (char)b;
15558
                    }
15559
                #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
15560
                    else if (nameType == ASN_ISSUER) {
15561
                        cert->issuerC = (char*)&input[srcIdx];
15562
                        cert->issuerCLen = strLen;
15563
                        cert->issuerCEnc = (char)b;
15564
                    }
15565
                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
15566
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
15567
                #if (defined(OPENSSL_EXTRA) || \
15568
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
15569
                        && !defined(WOLFCRYPT_ONLY)
15570
                    nid = WC_NID_countryName;
15571
                #endif /* OPENSSL_EXTRA */
15572
            }
15573
            else if (id == ASN_LOCALITY_NAME) {
15574
                copy = WOLFSSL_LOCALITY_NAME;
15575
                copyLen = sizeof(WOLFSSL_LOCALITY_NAME) - 1;
15576
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
15577
                    if (nameType == ASN_SUBJECT) {
15578
                        cert->subjectL = (char*)&input[srcIdx];
15579
                        cert->subjectLLen = strLen;
15580
                        cert->subjectLEnc = (char)b;
15581
                    }
15582
                    #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
15583
                    else if (nameType == ASN_ISSUER) {
15584
                        cert->issuerL = (char*)&input[srcIdx];
15585
                        cert->issuerLLen = strLen;
15586
                        cert->issuerLEnc = (char)b;
15587
                    }
15588
                    #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
15589
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
15590
                #if (defined(OPENSSL_EXTRA) || \
15591
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
15592
                        && !defined(WOLFCRYPT_ONLY)
15593
                    nid = WC_NID_localityName;
15594
                #endif /* OPENSSL_EXTRA */
15595
            }
15596
            else if (id == ASN_STATE_NAME) {
15597
                copy = WOLFSSL_STATE_NAME;
15598
                copyLen = sizeof(WOLFSSL_STATE_NAME) - 1;
15599
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
15600
                    if (nameType == ASN_SUBJECT) {
15601
                        cert->subjectST = (char*)&input[srcIdx];
15602
                        cert->subjectSTLen = strLen;
15603
                        cert->subjectSTEnc = (char)b;
15604
                    }
15605
                #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
15606
                    else if (nameType == ASN_ISSUER) {
15607
                        cert->issuerST = (char*)&input[srcIdx];
15608
                        cert->issuerSTLen = strLen;
15609
                        cert->issuerSTEnc = (char)b;
15610
                    }
15611
                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
15612
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT*/
15613
                #if (defined(OPENSSL_EXTRA) || \
15614
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
15615
                        && !defined(WOLFCRYPT_ONLY)
15616
                    nid = WC_NID_stateOrProvinceName;
15617
                #endif /* OPENSSL_EXTRA */
15618
            }
15619
            else if (id == ASN_ORG_NAME) {
15620
                copy = WOLFSSL_ORG_NAME;
15621
                copyLen = sizeof(WOLFSSL_ORG_NAME) - 1;
15622
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
15623
                    if (nameType == ASN_SUBJECT) {
15624
                        cert->subjectO = (char*)&input[srcIdx];
15625
                        cert->subjectOLen = strLen;
15626
                        cert->subjectOEnc = (char)b;
15627
                    }
15628
                #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
15629
                    else if (nameType == ASN_ISSUER) {
15630
                        cert->issuerO = (char*)&input[srcIdx];
15631
                        cert->issuerOLen = strLen;
15632
                        cert->issuerOEnc = (char)b;
15633
                    }
15634
                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
15635
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
15636
                #if (defined(OPENSSL_EXTRA) || \
15637
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
15638
                        && !defined(WOLFCRYPT_ONLY)
15639
                    nid = WC_NID_organizationName;
15640
                #endif /* OPENSSL_EXTRA */
15641
            }
15642
            else if (id == ASN_ORGUNIT_NAME) {
15643
                copy = WOLFSSL_ORGUNIT_NAME;
15644
                copyLen = sizeof(WOLFSSL_ORGUNIT_NAME) - 1;
15645
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
15646
                    if (nameType == ASN_SUBJECT) {
15647
                        cert->subjectOU = (char*)&input[srcIdx];
15648
                        cert->subjectOULen = strLen;
15649
                        cert->subjectOUEnc = (char)b;
15650
                    }
15651
                #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
15652
                    else if (nameType == ASN_ISSUER) {
15653
                        cert->issuerOU = (char*)&input[srcIdx];
15654
                        cert->issuerOULen = strLen;
15655
                        cert->issuerOUEnc = (char)b;
15656
                    }
15657
                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
15658
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
15659
                #if (defined(OPENSSL_EXTRA) || \
15660
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
15661
                        && !defined(WOLFCRYPT_ONLY)
15662
                    nid = WC_NID_organizationalUnitName;
15663
                #endif /* OPENSSL_EXTRA */
15664
            }
15665
            else if (id == ASN_SERIAL_NUMBER) {
15666
                copy = WOLFSSL_SERIAL_NUMBER;
15667
                copyLen = sizeof(WOLFSSL_SERIAL_NUMBER) - 1;
15668
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
15669
                    if (nameType == ASN_SUBJECT) {
15670
                        cert->subjectSND = (char*)&input[srcIdx];
15671
                        cert->subjectSNDLen = strLen;
15672
                        cert->subjectSNDEnc = (char)b;
15673
                    }
15674
                #if defined(WOLFSSL_HAVE_ISSUER_NAMES)
15675
                    else if (nameType == ASN_ISSUER) {
15676
                        cert->issuerSND = (char*)&input[srcIdx];
15677
                        cert->issuerSNDLen = strLen;
15678
                        cert->issuerSNDEnc = (char)b;
15679
                    }
15680
                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
15681
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
15682
                #if (defined(OPENSSL_EXTRA) || \
15683
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
15684
                        && !defined(WOLFCRYPT_ONLY)
15685
                    nid = WC_NID_serialNumber;
15686
                #endif /* OPENSSL_EXTRA */
15687
            }
15688
            else if (id == ASN_USER_ID) {
15689
                copy = WOLFSSL_USER_ID;
15690
                copyLen = sizeof(WOLFSSL_USER_ID) - 1;
15691
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
15692
                    if (nameType == ASN_SUBJECT) {
15693
                        cert->subjectUID = (char*)&input[srcIdx];
15694
                        cert->subjectUIDLen = strLen;
15695
                        cert->subjectUIDEnc = (char)b;
15696
                    }
15697
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
15698
                #if (defined(OPENSSL_EXTRA) || \
15699
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
15700
                        && !defined(WOLFCRYPT_ONLY)
15701
                    nid = WC_NID_userId;
15702
                #endif /* OPENSSL_EXTRA */
15703
            }
15704
        #ifdef WOLFSSL_CERT_EXT
15705
            else if (id == ASN_STREET_ADDR) {
15706
                copy = WOLFSSL_STREET_ADDR_NAME;
15707
                copyLen = sizeof(WOLFSSL_STREET_ADDR_NAME) - 1;
15708
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
15709
                    if (nameType == ASN_SUBJECT) {
15710
                        cert->subjectStreet = (char*)&input[srcIdx];
15711
                        cert->subjectStreetLen = strLen;
15712
                        cert->subjectStreetEnc = (char)b;
15713
                    }
15714
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
15715
                #if (defined(OPENSSL_EXTRA) || \
15716
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
15717
                        && !defined(WOLFCRYPT_ONLY)
15718
                    nid = WC_NID_streetAddress;
15719
                #endif /* OPENSSL_EXTRA */
15720
            }
15721
            else if (id == ASN_BUS_CAT) {
15722
                copy = WOLFSSL_BUS_CAT;
15723
                copyLen = sizeof(WOLFSSL_BUS_CAT) - 1;
15724
            #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
15725
                if (nameType == ASN_SUBJECT) {
15726
                    cert->subjectBC = (char*)&input[srcIdx];
15727
                    cert->subjectBCLen = strLen;
15728
                    cert->subjectBCEnc = (char)b;
15729
                }
15730
            #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
15731
            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \
15732
                        && !defined(WOLFCRYPT_ONLY)
15733
                nid = WC_NID_businessCategory;
15734
            #endif /* OPENSSL_EXTRA */
15735
            }
15736
            else if (id == ASN_POSTAL_CODE) {
15737
                copy = WOLFSSL_POSTAL_NAME;
15738
                copyLen = sizeof(WOLFSSL_POSTAL_NAME) - 1;
15739
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
15740
                    if (nameType == ASN_SUBJECT) {
15741
                        cert->subjectPC = (char*)&input[srcIdx];
15742
                        cert->subjectPCLen = strLen;
15743
                        cert->subjectPCEnc = (char)b;
15744
                    }
15745
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT*/
15746
                #if (defined(OPENSSL_EXTRA) || \
15747
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
15748
                        && !defined(WOLFCRYPT_ONLY)
15749
                    nid = WC_NID_postalCode;
15750
                #endif /* OPENSSL_EXTRA */
15751
            }
15752
        #endif /* WOLFSSL_CERT_EXT */
15753
        }
15754
    #ifdef WOLFSSL_CERT_EXT
15755
        else if ((srcIdx + ASN_JOI_PREFIX_SZ + 2 <= (word32)maxIdx) &&
15756
                 (0 == XMEMCMP(&input[srcIdx], ASN_JOI_PREFIX,
15757
                               ASN_JOI_PREFIX_SZ)) &&
15758
                 ((input[srcIdx+ASN_JOI_PREFIX_SZ] == ASN_JOI_C) ||
15759
                  (input[srcIdx+ASN_JOI_PREFIX_SZ] == ASN_JOI_ST)))
15760
        {
15761
            srcIdx += ASN_JOI_PREFIX_SZ;
15762
            id = input[srcIdx++];
15763
            b = input[srcIdx++]; /* encoding */
15764
15765
            if (GetLength(input, &srcIdx, &strLen,
15766
                          maxIdx) < 0) {
15767
            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
15768
            !defined(WOLFCRYPT_ONLY)
15769
                wolfSSL_X509_NAME_free(dName);
15770
            #endif /* OPENSSL_EXTRA */
15771
                return ASN_PARSE_E;
15772
            }
15773
15774
            /* Check for jurisdiction of incorporation country name */
15775
            if (id == ASN_JOI_C) {
15776
                copy = WOLFSSL_JOI_C;
15777
                copyLen = sizeof(WOLFSSL_JOI_C) - 1;
15778
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
15779
                    if (nameType == ASN_SUBJECT) {
15780
                        cert->subjectJC = (char*)&input[srcIdx];
15781
                        cert->subjectJCLen = strLen;
15782
                        cert->subjectJCEnc = (char)b;
15783
                    }
15784
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
15785
                #if (defined(OPENSSL_EXTRA) || \
15786
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
15787
                        && !defined(WOLFCRYPT_ONLY)
15788
                    nid = WC_NID_jurisdictionCountryName;
15789
                #endif /* OPENSSL_EXTRA */
15790
            }
15791
15792
            /* Check for jurisdiction of incorporation state name */
15793
            else if (id == ASN_JOI_ST) {
15794
                copy = WOLFSSL_JOI_ST;
15795
                copyLen = sizeof(WOLFSSL_JOI_ST) - 1;
15796
                #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
15797
                    if (nameType == ASN_SUBJECT) {
15798
                        cert->subjectJS = (char*)&input[srcIdx];
15799
                        cert->subjectJSLen = strLen;
15800
                        cert->subjectJSEnc = (char)b;
15801
                    }
15802
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
15803
                #if (defined(OPENSSL_EXTRA) || \
15804
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
15805
                        && !defined(WOLFCRYPT_ONLY)
15806
                    nid = WC_NID_jurisdictionStateOrProvinceName;
15807
                #endif /* OPENSSL_EXTRA */
15808
            }
15809
15810
            if ((strLen + copyLen) > (int)(WC_ASN_NAME_MAX - idx)) {
15811
                WOLFSSL_MSG("ASN Name too big, skipping");
15812
                tooBig = TRUE;
15813
            }
15814
        }
15815
    #endif /* WOLFSSL_CERT_EXT */
15816
        else {
15817
            /* skip */
15818
            byte email = FALSE;
15819
            byte pilot = FALSE;
15820
15821
            if (joint[0] == 0x2a && joint[1] == 0x86) {  /* email id hdr 42.134.* */
15822
                id = ASN_EMAIL_NAME;
15823
                email = TRUE;
15824
            }
15825
15826
            if (joint[0] == 0x9  && joint[1] == 0x92) { /* uid id hdr 9.146.* */
15827
                /* last value of OID is the type of pilot attribute */
15828
                id    = input[srcIdx + (word32)oidSz - 1];
15829
                if (id == 0x01)
15830
                    id = ASN_USER_ID;
15831
                pilot = TRUE;
15832
            }
15833
15834
            srcIdx += (word32)oidSz + 1;
15835
15836
            if (GetLength(input, &srcIdx, &strLen, maxIdx) < 0) {
15837
            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
15838
            !defined(WOLFCRYPT_ONLY)
15839
                wolfSSL_X509_NAME_free(dName);
15840
            #endif /* OPENSSL_EXTRA */
15841
                return ASN_PARSE_E;
15842
            }
15843
15844
            if (strLen > (int)(WC_ASN_NAME_MAX - idx)) {
15845
                WOLFSSL_MSG("ASN name too big, skipping");
15846
                tooBig = TRUE;
15847
            }
15848
15849
            if (email) {
15850
                copyLen = sizeof(WOLFSSL_EMAIL_ADDR) - 1;
15851
                if ((copyLen + strLen) > (int)(WC_ASN_NAME_MAX - idx)) {
15852
                    WOLFSSL_MSG("ASN name too big, skipping");
15853
                    tooBig = TRUE;
15854
                }
15855
                else {
15856
                    copy = WOLFSSL_EMAIL_ADDR;
15857
                }
15858
15859
                #if !defined(IGNORE_NAME_CONSTRAINTS) || \
15860
                     defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT)
15861
                    if (nameType == ASN_SUBJECT) {
15862
                        cert->subjectEmail = (char*)&input[srcIdx];
15863
                        cert->subjectEmailLen = strLen;
15864
                    }
15865
                #if defined(WOLFSSL_HAVE_ISSUER_NAMES) && \
15866
                    (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT))
15867
                    else if (nameType == ASN_ISSUER) {
15868
                        cert->issuerEmail = (char*)&input[srcIdx];
15869
                        cert->issuerEmailLen = strLen;
15870
                    }
15871
                #endif /* WOLFSSL_HAVE_ISSUER_NAMES */
15872
                #endif /* WOLFSSL_CERT_GEN || WOLFSSL_CERT_EXT */
15873
                #if (defined(OPENSSL_EXTRA) || \
15874
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
15875
                        && !defined(WOLFCRYPT_ONLY)
15876
                    nid = WC_NID_emailAddress;
15877
                #endif /* OPENSSL_EXTRA */
15878
            }
15879
15880
            if (pilot) {
15881
                switch (id) {
15882
                    case ASN_USER_ID:
15883
                        copy = WOLFSSL_USER_ID;
15884
                        copyLen = sizeof(WOLFSSL_USER_ID) - 1;
15885
                    #if (defined(OPENSSL_EXTRA) || \
15886
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
15887
                        && !defined(WOLFCRYPT_ONLY)
15888
                        nid = WC_NID_userId;
15889
                    #endif /* OPENSSL_EXTRA */
15890
                        break;
15891
                    case ASN_DOMAIN_COMPONENT:
15892
                        copy = WOLFSSL_DOMAIN_COMPONENT;
15893
                        copyLen = sizeof(WOLFSSL_DOMAIN_COMPONENT) - 1;
15894
                    #if (defined(OPENSSL_EXTRA) || \
15895
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
15896
                        && !defined(WOLFCRYPT_ONLY)
15897
                        nid = WC_NID_domainComponent;
15898
                    #endif /* OPENSSL_EXTRA */
15899
                        break;
15900
                    case ASN_RFC822_MAILBOX:
15901
                        copy = WOLFSSL_RFC822_MAILBOX;
15902
                        copyLen = sizeof(WOLFSSL_RFC822_MAILBOX) - 1;
15903
                    #if (defined(OPENSSL_EXTRA) || \
15904
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
15905
                        && !defined(WOLFCRYPT_ONLY)
15906
                        nid = WC_NID_rfc822Mailbox;
15907
                    #endif /* OPENSSL_EXTRA */
15908
                        break;
15909
                    case ASN_FAVOURITE_DRINK:
15910
                        copy = WOLFSSL_FAVOURITE_DRINK;
15911
                        copyLen = sizeof(WOLFSSL_FAVOURITE_DRINK) - 1;
15912
                    #if (defined(OPENSSL_EXTRA) || \
15913
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
15914
                        && !defined(WOLFCRYPT_ONLY)
15915
                        nid = WC_NID_favouriteDrink;
15916
                    #endif /* OPENSSL_EXTRA */
15917
                        break;
15918
                    case ASN_CONTENT_TYPE:
15919
                        copy = WOLFSSL_CONTENT_TYPE;
15920
                        copyLen = sizeof(WOLFSSL_CONTENT_TYPE) - 1;
15921
                    #if (defined(OPENSSL_EXTRA) || \
15922
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
15923
                        && !defined(WOLFCRYPT_ONLY)
15924
                        nid = WC_NID_pkcs9_contentType;
15925
                    #endif /* OPENSSL_EXTRA */
15926
                        break;
15927
                    default:
15928
                        WOLFSSL_MSG("Unknown pilot attribute type");
15929
                    #if (defined(OPENSSL_EXTRA) || \
15930
                                defined(OPENSSL_EXTRA_X509_SMALL)) && \
15931
                                !defined(WOLFCRYPT_ONLY)
15932
                        wolfSSL_X509_NAME_free(dName);
15933
                    #endif /* OPENSSL_EXTRA */
15934
                        return ASN_PARSE_E;
15935
                }
15936
            }
15937
        }
15938
        if ((copyLen + strLen) > (int)(WC_ASN_NAME_MAX - idx))
15939
        {
15940
            WOLFSSL_MSG("ASN Name too big, skipping");
15941
            tooBig = TRUE;
15942
        }
15943
        if ((copy != NULL) && !tooBig) {
15944
            XMEMCPY(&full[idx], copy, (size_t)copyLen);
15945
            idx += (word32)copyLen;
15946
            XMEMCPY(&full[idx], &input[srcIdx], (size_t)strLen);
15947
            idx += (word32)strLen;
15948
        }
15949
        #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
15950
            !defined(WOLFCRYPT_ONLY)
15951
        switch (b) {
15952
            case CTC_UTF8:
15953
                enc = WOLFSSL_MBSTRING_UTF8;
15954
                break;
15955
            case CTC_PRINTABLE:
15956
                enc = WOLFSSL_V_ASN1_PRINTABLESTRING;
15957
                break;
15958
            default:
15959
                WOLFSSL_MSG("Unknown encoding type, using UTF8 by default");
15960
                enc = WOLFSSL_MBSTRING_UTF8;
15961
        }
15962
15963
        if (nid != WC_NID_undef) {
15964
            if (wolfSSL_X509_NAME_add_entry_by_NID(dName, nid, enc,
15965
                            &input[srcIdx], strLen, -1, -1) !=
15966
                            WOLFSSL_SUCCESS) {
15967
                wolfSSL_X509_NAME_free(dName);
15968
                return ASN_PARSE_E;
15969
            }
15970
        }
15971
        #endif /* OPENSSL_EXTRA */
15972
        srcIdx += (word32)strLen;
15973
    }
15974
    full[idx++] = 0;
15975
15976
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
15977
            !defined(WOLFCRYPT_ONLY)
15978
    if (nameType == ASN_ISSUER) {
15979
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY)) &&\
15980
    (defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT))
15981
        dName->rawLen = min(cert->issuerRawLen, WC_ASN_NAME_MAX);
15982
        XMEMCPY(dName->raw, cert->issuerRaw, dName->rawLen);
15983
#endif
15984
        cert->issuerName = dName;
15985
    }
15986
    else {
15987
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
15988
        dName->rawLen = min(cert->subjectRawLen, WC_ASN_NAME_MAX);
15989
        XMEMCPY(dName->raw, cert->subjectRaw, dName->rawLen);
15990
#endif
15991
        cert->subjectName = dName;
15992
    }
15993
#endif
15994
15995
    *inOutIdx = srcIdx;
15996
15997
    return 0;
15998
#else
15999
0
    DECL_ASNGETDATA(dataASN, rdnASN_Length);
16000
0
    int    ret = 0;
16001
0
    word32 idx = 0;
16002
0
    int    len = 0;
16003
0
    word32 srcIdx = *inOutIdx;
16004
#ifdef WOLFSSL_X509_NAME_AVAILABLE
16005
    WOLFSSL_X509_NAME* dName = NULL;
16006
#endif /* WOLFSSL_X509_NAME_AVAILABLE */
16007
16008
0
    WOLFSSL_MSG("Getting Cert Name");
16009
16010
    /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
16011
     * calculated over the entire DER encoding of the Name field, including
16012
     * the tag and length. */
16013
0
    if (CalcHashId_ex(input + srcIdx, maxIdx - srcIdx, hash,
16014
0
            HashIdAlg(cert->signatureOID)) != 0) {
16015
0
        ret = ASN_PARSE_E;
16016
0
    }
16017
16018
0
    CALLOC_ASNGETDATA(dataASN, rdnASN_Length, ret, cert->heap);
16019
16020
#ifdef WOLFSSL_X509_NAME_AVAILABLE
16021
    if (ret == 0) {
16022
        /* Create an X509_NAME to hold data for OpenSSL compatibility APIs. */
16023
        dName = wolfSSL_X509_NAME_new_ex(cert->heap);
16024
        if (dName == NULL) {
16025
            ret = MEMORY_E;
16026
        }
16027
    }
16028
#endif /* WOLFSSL_X509_NAME_AVAILABLE */
16029
16030
0
    if (ret == 0) {
16031
        /* Expecting a SEQUENCE using up all data. */
16032
0
        ret = GetASN_Sequence(input, &srcIdx, &len, maxIdx, 1);
16033
0
    }
16034
0
    if (ret == 0) {
16035
    #if defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT)
16036
        /* Store pointer and length to raw issuer. */
16037
        if (nameType == ASN_ISSUER) {
16038
            cert->issuerRaw = &input[srcIdx];
16039
            cert->issuerRawLen = len;
16040
        }
16041
    #endif
16042
0
    #if !defined(IGNORE_NAME_CONSTRAINTS) || defined(WOLFSSL_CERT_EXT)
16043
        /* Store pointer and length to raw subject. */
16044
0
        if (nameType == ASN_SUBJECT) {
16045
0
            cert->subjectRaw = &input[srcIdx];
16046
0
            cert->subjectRawLen = len;
16047
0
        }
16048
0
    #endif
16049
16050
        /* Process all RDNs in name. */
16051
0
        while ((ret == 0) && (srcIdx < maxIdx)) {
16052
0
            int nid = 0;
16053
16054
            /* Initialize for data and setup RDN choice. */
16055
0
            GetASN_Choice(&dataASN[RDNASN_IDX_ATTR_VAL], rdnChoice);
16056
            /* Ignore type OID as too many to store in table. */
16057
0
            GetASN_OID(&dataASN[RDNASN_IDX_ATTR_TYPE], oidIgnoreType);
16058
            /* Parse RDN. */
16059
0
            ret = GetASN_Items(rdnASN, dataASN, rdnASN_Length, 1, input,
16060
0
                               &srcIdx, maxIdx);
16061
0
            if (ret == 0) {
16062
                /* Put RDN data into certificate. */
16063
0
                ret = GetRDN(cert, full, &idx, &nid, nameType == ASN_SUBJECT,
16064
0
                             dataASN);
16065
0
            }
16066
        #ifdef WOLFSSL_X509_NAME_AVAILABLE
16067
            /* TODO: push this back up to ssl.c
16068
             * (do parsing for WOLFSSL_X509_NAME on demand) */
16069
            if (ret == 0) {
16070
                int enc;
16071
                byte*  str;
16072
                word32 strLen;
16073
                byte   tag = dataASN[RDNASN_IDX_ATTR_VAL].tag;
16074
16075
                /* Get string reference. */
16076
                GetASN_GetRef(&dataASN[RDNASN_IDX_ATTR_VAL], &str, &strLen);
16077
16078
            #ifndef WOLFSSL_NO_ASN_STRICT
16079
                /* RFC 5280 section 4.1.2.4 lists a DirectoryString as being
16080
                 * 1..MAX in length */
16081
                if (ret == 0 && strLen < 1) {
16082
                    WOLFSSL_MSG("Non conforming DirectoryString of length 0 was"
16083
                                " found");
16084
                    WOLFSSL_MSG("Use WOLFSSL_NO_ASN_STRICT if wanting to allow"
16085
                                " empty DirectoryString's");
16086
                    ret = ASN_PARSE_E;
16087
                }
16088
            #endif
16089
16090
                /* Convert BER tag to a OpenSSL type. */
16091
                switch (tag) {
16092
                    case CTC_UTF8:
16093
                        enc = WOLFSSL_MBSTRING_UTF8;
16094
                        break;
16095
                    case CTC_PRINTABLE:
16096
                        enc = WOLFSSL_V_ASN1_PRINTABLESTRING;
16097
                        break;
16098
                    default:
16099
                        WOLFSSL_MSG("Unknown encoding type, default UTF8");
16100
                        enc = WOLFSSL_MBSTRING_UTF8;
16101
                }
16102
                if (nid != 0) {
16103
                    /* Add an entry to the X509_NAME. */
16104
                    if (wolfSSL_X509_NAME_add_entry_by_NID(dName, nid, enc, str,
16105
                            (int)strLen, -1, -1) != WOLFSSL_SUCCESS) {
16106
                        ret = ASN_PARSE_E;
16107
                    }
16108
                }
16109
            }
16110
        #endif
16111
0
        }
16112
0
    }
16113
0
    if (ret == 0) {
16114
        /* Terminate string. */
16115
0
        full[idx] = 0;
16116
        /* Return index into encoding after name. */
16117
0
        *inOutIdx = srcIdx;
16118
16119
#ifdef WOLFSSL_X509_NAME_AVAILABLE
16120
        /* Store X509_NAME in certificate. */
16121
        if (nameType == ASN_ISSUER) {
16122
        #if (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
16123
             defined(HAVE_LIGHTY)) && \
16124
            (defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT))
16125
            dName->rawLen = (int)min((word32)cert->issuerRawLen,
16126
                WC_ASN_NAME_MAX);
16127
            XMEMCPY(dName->raw, cert->issuerRaw, (size_t)dName->rawLen);
16128
        #endif
16129
            cert->issuerName = dName;
16130
        }
16131
        else {
16132
        #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
16133
            dName->rawLen = (int)min((word32)cert->subjectRawLen,
16134
                WC_ASN_NAME_MAX);
16135
            XMEMCPY(dName->raw, cert->subjectRaw, (size_t)dName->rawLen);
16136
        #endif
16137
            cert->subjectName = dName;
16138
        }
16139
    }
16140
    else {
16141
        /* Dispose of unused X509_NAME. */
16142
        wolfSSL_X509_NAME_free(dName);
16143
#endif
16144
0
    }
16145
16146
0
    FREE_ASNGETDATA(dataASN, cert->heap);
16147
0
    return ret;
16148
0
#endif /* WOLFSSL_ASN_TEMPLATE */
16149
0
}
16150
16151
#ifdef WOLFSSL_ASN_TEMPLATE
16152
/* ASN.1 template for certificate name. */
16153
static const ASNItem certNameASN[] = {
16154
/* OID  */ { 0, ASN_OBJECT_ID, 0, 0, 1 },
16155
/* NAME */ { 0, ASN_SEQUENCE, 1, 0, 0 },
16156
};
16157
enum {
16158
    CERTNAMEASN_IDX_OID = 0,
16159
    CERTNAMEASN_IDX_NAME
16160
};
16161
16162
/* Number of items in ASN.1 template for certificate name. */
16163
0
#define certNameASN_Length (sizeof(certNameASN) / sizeof(ASNItem))
16164
#endif
16165
16166
/* Get a certificate name into the certificate object.
16167
 *
16168
 * Either the issuer or subject name.
16169
 *
16170
 * @param [in, out] cert      Decoded certificate object.
16171
 * @param [in]      nameType  Type being decoded: ASN_ISSUER or ASN_SUBJECT.
16172
 * @param [in]      maxIdx    Index of next item after certificate name.
16173
 * @return  0 on success.
16174
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
16175
 *          is invalid.
16176
 * @return  BUFFER_E when data in buffer is too small.
16177
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
16178
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
16179
 * @return  MEMORY_E when dynamic memory allocation fails.
16180
 */
16181
int GetName(DecodedCert* cert, int nameType, int maxIdx)
16182
0
{
16183
#ifndef WOLFSSL_ASN_TEMPLATE
16184
    char*  full;
16185
    byte*  hash;
16186
    int    length;
16187
    word32 localIdx;
16188
    byte   tag;
16189
16190
    WOLFSSL_MSG("Getting Name");
16191
16192
    if (nameType == ASN_ISSUER) {
16193
        full = cert->issuer;
16194
        hash = cert->issuerHash;
16195
    }
16196
    else {
16197
        full = cert->subject;
16198
        hash = cert->subjectHash;
16199
    }
16200
16201
    if (cert->srcIdx >= (word32)maxIdx) {
16202
        return BUFFER_E;
16203
    }
16204
16205
    localIdx = cert->srcIdx;
16206
    if (GetASNTag(cert->source, &localIdx, &tag, (word32)maxIdx) < 0) {
16207
        return ASN_PARSE_E;
16208
    }
16209
16210
    if (tag == ASN_OBJECT_ID) {
16211
        WOLFSSL_MSG("Trying optional prefix...");
16212
16213
        if (SkipObjectId(cert->source, &cert->srcIdx, (word32)maxIdx) < 0)
16214
            return ASN_PARSE_E;
16215
        WOLFSSL_MSG("Got optional prefix");
16216
    }
16217
16218
    localIdx = cert->srcIdx;
16219
    if (GetASNTag(cert->source, &localIdx, &tag, (word32)maxIdx) < 0) {
16220
        return ASN_PARSE_E;
16221
    }
16222
    localIdx = cert->srcIdx + 1;
16223
    if (GetLength(cert->source, &localIdx, &length, (word32)maxIdx) < 0) {
16224
        return ASN_PARSE_E;
16225
    }
16226
    length += (int)(localIdx - cert->srcIdx);
16227
16228
    return GetCertName(cert, full, hash, nameType, cert->source, &cert->srcIdx,
16229
                       cert->srcIdx + (word32)length);
16230
#else
16231
0
    ASNGetData dataASN[certNameASN_Length];
16232
0
    word32 idx = cert->srcIdx;
16233
0
    int    ret = 0;
16234
16235
0
    WOLFSSL_MSG("Getting Name");
16236
16237
0
    XMEMSET(dataASN, 0, sizeof(dataASN));
16238
    /* Initialize for data and don't check optional prefix OID. */
16239
0
    GetASN_OID(&dataASN[CERTNAMEASN_IDX_OID], oidIgnoreType);
16240
0
    ret = GetASN_Items(certNameASN, dataASN, certNameASN_Length, 0,
16241
0
                       cert->source, &idx, (word32)maxIdx);
16242
0
    if (ret == 0) {
16243
0
        char* full;
16244
0
        byte* hash;
16245
16246
        /* Store offset of SEQUENCE that is start of name. */
16247
0
        cert->srcIdx = dataASN[CERTNAMEASN_IDX_NAME].offset;
16248
16249
        /* Get fields to fill in based on name type. */
16250
0
        if (nameType == ASN_ISSUER) {
16251
0
            full = cert->issuer;
16252
0
            hash = cert->issuerHash;
16253
0
        }
16254
0
        else {
16255
0
            full = cert->subject;
16256
0
            hash = cert->subjectHash;
16257
0
        }
16258
16259
        /* Parse certificate name. */
16260
0
        ret = GetCertName(cert, full, hash, nameType, cert->source,
16261
0
                          &cert->srcIdx, idx);
16262
0
    }
16263
16264
0
    return ret;
16265
0
#endif
16266
0
}
16267
16268
#ifndef NO_ASN_TIME
16269
16270
/* two byte date/time, add to value */
16271
static WC_INLINE int GetTime(int* value, const byte* date, int* idx)
16272
0
{
16273
0
    int i = *idx;
16274
16275
0
    if (date[i] < 0x30 || date[i] > 0x39 || date[i+1] < 0x30 ||
16276
0
                                                             date[i+1] > 0x39) {
16277
0
        return ASN_PARSE_E;
16278
0
    }
16279
16280
0
    *value += (int)btoi(date[i++]) * 10;
16281
0
    *value += (int)btoi(date[i++]);
16282
16283
0
    *idx = i;
16284
16285
0
    return 0;
16286
0
}
16287
16288
#ifdef WOLFSSL_LINUXKM
16289
static WC_INLINE int GetTime_Long(long* value, const byte* date, int* idx)
16290
{
16291
    int i = *idx;
16292
16293
    if (date[i] < 0x30 || date[i] > 0x39 || date[i+1] < 0x30 ||
16294
                                                             date[i+1] > 0x39) {
16295
        return ASN_PARSE_E;
16296
    }
16297
16298
    *value += (long)btoi(date[i++]) * 10;
16299
    *value += (long)btoi(date[i++]);
16300
16301
    *idx = i;
16302
16303
    return 0;
16304
}
16305
#endif
16306
16307
/* Extract certTime from date string parameter.
16308
 * Reminder: idx is incremented in each call to GetTime()
16309
 * Return 0 on failure, 1 for success.  */
16310
int ExtractDate(const unsigned char* date, unsigned char format,
16311
                struct tm* certTime, int* idx)
16312
0
{
16313
0
    XMEMSET(certTime, 0, sizeof(struct tm));
16314
16315
    /* Get the first two bytes of the year (century) */
16316
0
    if (format == ASN_UTC_TIME) {
16317
0
        if (btoi(date[*idx]) >= 5)
16318
0
            certTime->tm_year = 1900;
16319
0
        else
16320
0
            certTime->tm_year = 2000;
16321
0
    }
16322
0
    else {
16323
        /* format == GENERALIZED_TIME */
16324
#ifdef WOLFSSL_LINUXKM
16325
        if (GetTime_Long(&certTime->tm_year, date, idx) != 0) return 0;
16326
#else
16327
0
        if (GetTime(&certTime->tm_year, date, idx) != 0) return 0;
16328
0
#endif
16329
0
        certTime->tm_year *= 100;
16330
0
    }
16331
16332
#ifdef AVR
16333
    /* Extract the time from the struct tm and adjust tm_year, tm_mon */
16334
    /* AVR libc stores these as uint8_t instead of int */
16335
    /* AVR time_t also offsets from midnight 1 Jan 2000 */
16336
    int tm_year = certTime->tm_year - 2000;
16337
    int tm_mon  = certTime->tm_mon - 1;
16338
    int tm_mday = certTime->tm_mday;
16339
    int tm_hour = certTime->tm_hour;
16340
    int tm_min  = certTime->tm_min;
16341
    int tm_sec  = certTime->tm_sec;
16342
16343
    if (GetTime(&tm_year, date, idx) != 0) return 0;
16344
    if (GetTime(&tm_mon , date, idx) != 0) return 0;
16345
    if (GetTime(&tm_mday, date, idx) != 0) return 0;
16346
    if (GetTime(&tm_hour, date, idx) != 0) return 0;
16347
    if (GetTime(&tm_min , date, idx) != 0) return 0;
16348
    if (GetTime(&tm_sec , date, idx) != 0) return 0;
16349
16350
    /* Re-populate certTime with computed values */
16351
    certTime->tm_year = tm_year;
16352
    certTime->tm_mon  = tm_mon;
16353
    certTime->tm_mday = tm_mday;
16354
    certTime->tm_hour = tm_hour;
16355
    certTime->tm_min  = tm_min;
16356
    certTime->tm_sec  = tm_sec;
16357
#else /* !AVR */
16358
    /* Get the next two bytes of the year. */
16359
    #ifdef WOLFSSL_LINUXKM
16360
        if (GetTime_Long(&certTime->tm_year, date, idx) != 0) return 0;
16361
    #else
16362
0
        if (GetTime(&certTime->tm_year, date, idx) != 0) return 0;
16363
0
    #endif
16364
0
    certTime->tm_year -= 1900;
16365
16366
    /* The next fields are expected in specific order in [date] string: */
16367
0
    if (GetTime(&certTime->tm_mon , date, idx) != 0) return 0;
16368
0
    certTime->tm_mon  -= 1;
16369
0
    if (GetTime(&certTime->tm_mday, date, idx) != 0) return 0;
16370
0
    if (GetTime(&certTime->tm_hour, date, idx) != 0) return 0;
16371
0
    if (GetTime(&certTime->tm_min , date, idx) != 0) return 0;
16372
0
    if (GetTime(&certTime->tm_sec , date, idx) != 0) return 0;
16373
16374
0
#endif /* !AVR */
16375
16376
0
    return 1;
16377
0
}
16378
16379
16380
#ifdef WOLFSSL_ASN_TIME_STRING
16381
int GetTimeString(byte* date, int format, char* buf, int len)
16382
{
16383
    struct tm t;
16384
    int idx = 0;
16385
16386
    if (!ExtractDate(date, (unsigned char)format, &t, &idx)) {
16387
        return 0;
16388
    }
16389
16390
    if (date[idx] != 'Z') {
16391
        WOLFSSL_MSG("UTCtime, not Zulu") ;
16392
        return 0;
16393
    }
16394
16395
    /* place month in buffer */
16396
    buf[0] = '\0';
16397
    switch(t.tm_mon) {
16398
        case 0:  XSTRNCAT(buf, "Jan ", 5); break;
16399
        case 1:  XSTRNCAT(buf, "Feb ", 5); break;
16400
        case 2:  XSTRNCAT(buf, "Mar ", 5); break;
16401
        case 3:  XSTRNCAT(buf, "Apr ", 5); break;
16402
        case 4:  XSTRNCAT(buf, "May ", 5); break;
16403
        case 5:  XSTRNCAT(buf, "Jun ", 5); break;
16404
        case 6:  XSTRNCAT(buf, "Jul ", 5); break;
16405
        case 7:  XSTRNCAT(buf, "Aug ", 5); break;
16406
        case 8:  XSTRNCAT(buf, "Sep ", 5); break;
16407
        case 9:  XSTRNCAT(buf, "Oct ", 5); break;
16408
        case 10: XSTRNCAT(buf, "Nov ", 5); break;
16409
        case 11: XSTRNCAT(buf, "Dec ", 5); break;
16410
        default:
16411
            return 0;
16412
16413
    }
16414
    idx = 4; /* use idx now for char buffer */
16415
16416
    if (XSNPRINTF(buf + idx, (size_t)(len - idx), "%2d %02d:%02d:%02d %d GMT",
16417
              t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, (int)t.tm_year + 1900)
16418
        >= len - idx)
16419
    {
16420
        WOLFSSL_MSG("buffer overrun in GetTimeString");
16421
        return 0;
16422
    }
16423
16424
    return 1;
16425
}
16426
#endif /* WOLFSSL_ASN_TIME_STRING */
16427
16428
/* Check time struct for valid values. Returns 0 for success */
16429
static int ValidateGmtime(struct tm* inTime)
16430
0
{
16431
0
    int ret = 1;
16432
0
    if ((inTime != NULL) &&
16433
0
        (inTime->tm_sec >= 0) && (inTime->tm_sec <= 61) &&
16434
0
        (inTime->tm_min >= 0) && (inTime->tm_min <= 59) &&
16435
0
        (inTime->tm_hour >= 0) && (inTime->tm_hour <= 23) &&
16436
0
        (inTime->tm_mday >= 1) && (inTime->tm_mday <= 31) &&
16437
0
        (inTime->tm_mon >= 0) && (inTime->tm_mon <= 11) &&
16438
0
        (inTime->tm_wday >= 0) && (inTime->tm_wday <= 6) &&
16439
0
        (inTime->tm_yday >= 0) && (inTime->tm_yday <= 365)) {
16440
0
        ret = 0;
16441
0
    }
16442
16443
0
    return ret;
16444
0
}
16445
16446
#if !defined(NO_ASN_TIME) && !defined(USER_TIME) && \
16447
    !defined(TIME_OVERRIDES) && (defined(OPENSSL_EXTRA) || defined(HAVE_PKCS7))
16448
/* Set current time string, either UTC or GeneralizedTime.
16449
 * (void*) tm should be a pointer to time_t, output is placed in buf.
16450
 *
16451
 * Return time string length placed in buf on success, negative on error */
16452
int GetAsnTimeString(void* currTime, byte* buf, word32 len)
16453
{
16454
    byte* data_ptr  = buf;
16455
    byte  uf_time[ASN_GENERALIZED_TIME_SIZE];
16456
    int data_len = 0;
16457
16458
    WOLFSSL_ENTER("GetAsnTimeString");
16459
16460
    if (buf == NULL || len == 0)
16461
        return BAD_FUNC_ARG;
16462
16463
    XMEMSET(uf_time, 0, sizeof(uf_time));
16464
    /* GetFormattedTime returns length with null terminator */
16465
    data_len = GetFormattedTime(currTime, uf_time, (word32)sizeof(uf_time));
16466
    if (data_len <= 0) {
16467
        return ASN_TIME_E;
16468
    }
16469
    /* ensure room to add 2 bytes (ASN type and length) before proceeding */
16470
    else if (len < (word32)data_len + 2) {
16471
        return BUFFER_E;
16472
    }
16473
16474
    if (data_len == ASN_UTC_TIME_SIZE-1) {
16475
        /* increment data_len for ASN length byte after adding the data_ptr */
16476
        *data_ptr = (byte)ASN_UTC_TIME; data_ptr++; data_len++;
16477
        /* -1 below excludes null terminator */
16478
        *data_ptr = (byte)ASN_UTC_TIME_SIZE - 1; data_ptr++; data_len++;
16479
        XMEMCPY(data_ptr, (byte *)uf_time, ASN_UTC_TIME_SIZE - 1);
16480
        data_ptr += ASN_UTC_TIME_SIZE - 1;
16481
    }
16482
    else if (data_len == ASN_GENERALIZED_TIME_SIZE-1) {
16483
        /* increment data_len for ASN length byte after adding the data_ptr */
16484
        *data_ptr = (byte)ASN_GENERALIZED_TIME; data_ptr++; data_len++;
16485
        /* -1 below excludes null terminator */
16486
        *data_ptr = (byte)ASN_GENERALIZED_TIME_SIZE - 1; data_ptr++; data_len++;
16487
        XMEMCPY(data_ptr, (byte*)uf_time, ASN_GENERALIZED_TIME_SIZE - 1);
16488
        data_ptr += ASN_GENERALIZED_TIME_SIZE - 1;
16489
    }
16490
    else {
16491
        WOLFSSL_MSG("Invalid time size returned");
16492
        return ASN_TIME_E;
16493
    }
16494
    /* append null terminator */
16495
    *data_ptr = 0;
16496
16497
    /* return length without null terminator */
16498
    return data_len;
16499
}
16500
16501
/* return just the time string as either UTC or Generalized Time*/
16502
int GetFormattedTime(void* currTime, byte* buf, word32 len)
16503
{
16504
    struct tm* ts      = NULL;
16505
    struct tm* tmpTime = NULL;
16506
    int year, mon, day, hour, mini, sec;
16507
    int ret;
16508
#if defined(NEED_TMP_TIME)
16509
    struct tm tmpTimeStorage;
16510
    tmpTime = &tmpTimeStorage;
16511
#endif
16512
    /* Needed in case XGMTIME does not use the tmpTime argument. */
16513
    (void)tmpTime;
16514
16515
    WOLFSSL_ENTER("GetFormattedTime");
16516
16517
    if (buf == NULL || len == 0)
16518
        return BAD_FUNC_ARG;
16519
16520
    ts = (struct tm *)XGMTIME((time_t*)currTime, tmpTime);
16521
    if (ValidateGmtime(ts)) {
16522
        WOLFSSL_MSG("failed to get time data.");
16523
        return ASN_TIME_E;
16524
    }
16525
16526
    /* Note ASN_UTC_TIME_SIZE and ASN_GENERALIZED_TIME_SIZE include space for
16527
     * the null terminator. ASN encoded values leave off the terminator. */
16528
16529
    if (ts->tm_year >= 50 && ts->tm_year < 150) {
16530
        /* UTC Time */
16531
        if (ts->tm_year >= 50 && ts->tm_year < 100) {
16532
            year = ts->tm_year;
16533
        }
16534
        else {
16535
            year = ts->tm_year - 100;
16536
        }
16537
        mon  = ts->tm_mon + 1;
16538
        day  = ts->tm_mday;
16539
        hour = ts->tm_hour;
16540
        mini = ts->tm_min;
16541
        sec  = ts->tm_sec;
16542
        if (len < ASN_UTC_TIME_SIZE) {
16543
            WOLFSSL_MSG("buffer for GetFormattedTime is too short.");
16544
            return BUFFER_E;
16545
        }
16546
        ret = XSNPRINTF((char*)buf, len,
16547
                        "%02d%02d%02d%02d%02d%02dZ", year, mon, day,
16548
                        hour, mini, sec);
16549
    }
16550
    else {
16551
        /* GeneralizedTime */
16552
        year = ts->tm_year + 1900;
16553
        mon  = ts->tm_mon + 1;
16554
        day  = ts->tm_mday;
16555
        hour = ts->tm_hour;
16556
        mini = ts->tm_min;
16557
        sec  = ts->tm_sec;
16558
        if (len < ASN_GENERALIZED_TIME_SIZE) {
16559
            WOLFSSL_MSG("buffer for GetFormattedTime is too short.");
16560
            return BUFFER_E;
16561
        }
16562
        ret = XSNPRINTF((char*)buf, len,
16563
                        "%4d%02d%02d%02d%02d%02dZ", year, mon, day,
16564
                        hour, mini, sec);
16565
    }
16566
16567
    return ret;
16568
}
16569
16570
#endif /* !NO_ASN_TIME && !USER_TIME && !TIME_OVERRIDES &&
16571
        * (OPENSSL_EXTRA || HAVE_PKCS7) */
16572
16573
#if defined(USE_WOLF_VALIDDATE)
16574
16575
/* to the second */
16576
int DateGreaterThan(const struct tm* a, const struct tm* b)
16577
0
{
16578
0
    if (a->tm_year > b->tm_year)
16579
0
        return 1;
16580
16581
0
    if (a->tm_year == b->tm_year && a->tm_mon > b->tm_mon)
16582
0
        return 1;
16583
16584
0
    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
16585
0
           a->tm_mday > b->tm_mday)
16586
0
        return 1;
16587
16588
0
    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
16589
0
        a->tm_mday == b->tm_mday && a->tm_hour > b->tm_hour)
16590
0
        return 1;
16591
16592
0
    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
16593
0
        a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
16594
0
        a->tm_min > b->tm_min)
16595
0
        return 1;
16596
16597
0
    if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
16598
0
        a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
16599
0
        a->tm_min  == b->tm_min  && a->tm_sec > b->tm_sec)
16600
0
        return 1;
16601
16602
0
    return 0; /* false */
16603
0
}
16604
16605
16606
static WC_INLINE int DateLessThan(const struct tm* a, const struct tm* b)
16607
0
{
16608
0
    return DateGreaterThan(b,a);
16609
0
}
16610
16611
/* like atoi but only use first byte */
16612
/* Make sure before and after dates are valid */
16613
/* date = ASN.1 raw */
16614
/* format = ASN_UTC_TIME or ASN_GENERALIZED_TIME */
16615
/* dateType = ASN_AFTER or ASN_BEFORE */
16616
int wc_ValidateDate(const byte* date, byte format, int dateType)
16617
0
{
16618
0
    time_t ltime;
16619
0
    struct tm  certTime;
16620
0
    struct tm* localTime;
16621
0
    struct tm* tmpTime;
16622
0
    int    i = 0;
16623
0
    int    timeDiff = 0;
16624
0
    int    diffHH = 0, diffMM = 0;
16625
16626
0
#if defined(NEED_TMP_TIME)
16627
0
    struct tm tmpTimeStorage;
16628
0
    tmpTime = &tmpTimeStorage;
16629
#else
16630
    tmpTime = NULL;
16631
#endif
16632
0
    (void)tmpTime;
16633
16634
0
    ltime = wc_Time(0);
16635
0
#ifndef NO_TIME_SIGNEDNESS_CHECK
16636
0
    if (sizeof(ltime) == sizeof(word32) && (sword32)ltime < 0){
16637
        /* A negative response here could be due to a 32-bit time_t
16638
         * where the year is 2038 or later. */
16639
0
        WOLFSSL_MSG("wc_Time failed to return a valid value");
16640
0
        return 0;
16641
0
    }
16642
0
#endif
16643
16644
#ifdef WOLFSSL_BEFORE_DATE_CLOCK_SKEW
16645
    if (dateType == ASN_BEFORE) {
16646
        WOLFSSL_MSG("Skewing local time for before date check");
16647
        ltime += WOLFSSL_BEFORE_DATE_CLOCK_SKEW;
16648
    }
16649
#endif
16650
16651
#ifdef WOLFSSL_AFTER_DATE_CLOCK_SKEW
16652
    if (dateType == ASN_AFTER) {
16653
        WOLFSSL_MSG("Skewing local time for after date check");
16654
        ltime -= WOLFSSL_AFTER_DATE_CLOCK_SKEW;
16655
    }
16656
#endif
16657
16658
0
    if (!ExtractDate(date, format, &certTime, &i)) {
16659
0
        WOLFSSL_MSG("Error extracting the date");
16660
0
        return 0;
16661
0
    }
16662
16663
0
    if ((date[i] == '+') || (date[i] == '-')) {
16664
0
        int diffSign;
16665
16666
0
        WOLFSSL_MSG("Using time differential, not Zulu") ;
16667
0
        diffSign = date[i++] == '+' ? 1 : -1 ;
16668
0
        if (GetTime(&diffHH, date, &i) != 0)
16669
0
            return 0;
16670
0
        if (GetTime(&diffMM, date, &i) != 0)
16671
0
            return 0;
16672
0
        timeDiff = diffSign * (diffHH*60 + diffMM) * 60 ;
16673
0
    } else if (date[i] != 'Z') {
16674
0
        WOLFSSL_MSG("UTCtime, neither Zulu or time differential") ;
16675
0
        return 0;
16676
0
    }
16677
16678
0
    ltime -= (time_t)timeDiff;
16679
0
    localTime = XGMTIME(&ltime, tmpTime);
16680
16681
0
    if (ValidateGmtime(localTime)) {
16682
0
        WOLFSSL_MSG("XGMTIME failed");
16683
0
        return 0;
16684
0
    }
16685
16686
0
    if (dateType == ASN_BEFORE) {
16687
0
        if (DateLessThan(localTime, &certTime)) {
16688
0
            WOLFSSL_MSG("Date BEFORE check failed");
16689
0
            return 0;
16690
0
        }
16691
0
    }
16692
0
    else {  /* dateType == ASN_AFTER */
16693
0
        if (DateGreaterThan(localTime, &certTime)) {
16694
0
            WOLFSSL_MSG("Date AFTER check failed");
16695
0
            return 0;
16696
0
        }
16697
0
    }
16698
16699
0
    return 1;
16700
0
}
16701
#endif /* USE_WOLF_VALIDDATE */
16702
16703
int wc_GetTime(void* timePtr, word32 timeSize)
16704
0
{
16705
0
    time_t* ltime = (time_t*)timePtr;
16706
16707
0
    if (timePtr == NULL) {
16708
0
        return BAD_FUNC_ARG;
16709
0
    }
16710
16711
0
    if ((word32)sizeof(time_t) > timeSize) {
16712
0
        return BUFFER_E;
16713
0
    }
16714
16715
0
    *ltime = wc_Time(0);
16716
16717
0
    return 0;
16718
0
}
16719
16720
#ifdef TIME_OVERRIDES
16721
    #ifndef HAVE_TIME_T_TYPE
16722
        typedef long time_t;
16723
    #endif
16724
    extern time_t XTIME(time_t* t);
16725
#endif
16726
16727
static wc_time_cb timeFunc = NULL;
16728
16729
int wc_SetTimeCb(wc_time_cb f)
16730
0
{
16731
0
    timeFunc = f;
16732
0
    return 0;
16733
0
}
16734
16735
time_t wc_Time(time_t* t)
16736
0
{
16737
0
    if (timeFunc != NULL) {
16738
0
        return timeFunc(t);
16739
0
    }
16740
0
    return XTIME(t);
16741
0
}
16742
16743
#endif /* !NO_ASN_TIME */
16744
16745
16746
#ifdef WOLFSSL_ASN_TEMPLATE
16747
/* TODO: use a CHOICE instead of two items? */
16748
/* ASN.1 template for a date - either UTC or Generalized Time. */
16749
static const ASNItem dateASN[] = {
16750
/* UTC */ { 0, ASN_UTC_TIME, 0, 0, 2 },
16751
/* GT  */ { 0, ASN_GENERALIZED_TIME, 0, 0, 2 },
16752
};
16753
enum {
16754
    DATEASN_IDX_UTC = 0,
16755
    DATEASN_IDX_GT
16756
};
16757
16758
/* Number of items in ASN.1 template for a date. */
16759
0
#define dateASN_Length (sizeof(dateASN) / sizeof(ASNItem))
16760
#endif /* WOLFSSL_ASN_TEMPLATE */
16761
16762
/* Get date buffer, format and length. Returns 0=success or error */
16763
/* Decode a DateInfo - choice of UTC TIME or GENERALIZED TIME.
16764
 *
16765
 * @param [in]      source   Buffer containing encoded date.
16766
 * @param [in, out] idx      On in, the index of the date.
16767
 *                           On out, index after date.
16768
 * @param [out]     pDate    Pointer into buffer of data bytes.
16769
 * @param [out]     pFormat  Format of date - BER/DER tag.
16770
 * @param [out]     pLength  Length of date bytes.
16771
 * @param [in]      maxIdx   Index of next item after date.
16772
 * @return  0 on success.
16773
 * @return  BAD_FUNC_ARG when source or idx is NULL.
16774
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
16775
 *          is invalid.
16776
 * @return  BUFFER_E when data in buffer is too small.
16777
 */
16778
static int GetDateInfo(const byte* source, word32* idx, const byte** pDate,
16779
                        byte* pFormat, int* pLength, word32 maxIdx)
16780
0
{
16781
#ifndef WOLFSSL_ASN_TEMPLATE
16782
    int length;
16783
    byte format;
16784
16785
    if (source == NULL || idx == NULL)
16786
        return BAD_FUNC_ARG;
16787
16788
    /* get ASN format header */
16789
    if (*idx+1 > maxIdx)
16790
        return BUFFER_E;
16791
    format = source[*idx];
16792
    *idx += 1;
16793
    if (format != ASN_UTC_TIME && format != ASN_GENERALIZED_TIME) {
16794
        WOLFSSL_ERROR_VERBOSE(ASN_TIME_E);
16795
        return ASN_TIME_E;
16796
    }
16797
16798
    /* get length */
16799
    if (GetLength(source, idx, &length, maxIdx) < 0)
16800
        return ASN_PARSE_E;
16801
    if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
16802
        return ASN_DATE_SZ_E;
16803
16804
    /* return format, date and length */
16805
    if (pFormat)
16806
        *pFormat = format;
16807
    if (pDate)
16808
        *pDate = &source[*idx];
16809
    if (pLength)
16810
        *pLength = length;
16811
16812
    *idx += (word32)length;
16813
16814
    return 0;
16815
#else
16816
0
    ASNGetData dataASN[dateASN_Length];
16817
0
    int ret = 0;
16818
16819
0
    if ((source == NULL) || (idx == NULL)) {
16820
0
        ret = BAD_FUNC_ARG;
16821
0
    }
16822
0
    if (ret == 0) {
16823
        /* Initialize data. */
16824
0
        XMEMSET(dataASN, 0, sizeof(dataASN));
16825
        /* Parse date. */
16826
0
        ret = GetASN_Items(dateASN, dataASN, dateASN_Length, 0, source, idx,
16827
0
                           maxIdx);
16828
0
    }
16829
0
    if (ret == 0) {
16830
        /* Determine which tag was seen. */
16831
0
        int i = (dataASN[DATEASN_IDX_UTC].tag != 0) ? DATEASN_IDX_UTC
16832
0
                                                    : DATEASN_IDX_GT;
16833
        /* Return data from seen item. */
16834
0
        if (pFormat != NULL) {
16835
0
            *pFormat = dataASN[i].tag;
16836
0
        }
16837
0
        if (pDate != NULL) {
16838
0
            *pDate = dataASN[i].data.ref.data;
16839
0
        }
16840
0
        if (pLength != NULL) {
16841
0
            *pLength = (int)dataASN[i].data.ref.length;
16842
0
        }
16843
0
    }
16844
16845
0
    return ret;
16846
0
#endif
16847
0
}
16848
16849
#if !defined(NO_CERTS) && !defined(WOLFSSL_ASN_TEMPLATE)
16850
static int GetDate(DecodedCert* cert, int dateType, int verify, int maxIdx)
16851
{
16852
    int    ret, length;
16853
    const byte *datePtr = NULL;
16854
    byte   date[MAX_DATE_SIZE];
16855
    byte   format;
16856
    word32 startIdx = 0;
16857
16858
    if (dateType == ASN_BEFORE)
16859
        cert->beforeDate = &cert->source[cert->srcIdx];
16860
    else
16861
        cert->afterDate = &cert->source[cert->srcIdx];
16862
    startIdx = cert->srcIdx;
16863
16864
    ret = GetDateInfo(cert->source, &cert->srcIdx, &datePtr, &format,
16865
                      &length, (word32)maxIdx);
16866
    if (ret < 0)
16867
        return ret;
16868
16869
    XMEMSET(date, 0, MAX_DATE_SIZE);
16870
    XMEMCPY(date, datePtr, (size_t)length);
16871
16872
    if (dateType == ASN_BEFORE)
16873
        cert->beforeDateLen = (int)(cert->srcIdx - startIdx);
16874
    else
16875
        cert->afterDateLen  = (int)(cert->srcIdx - startIdx);
16876
16877
#ifndef NO_ASN_TIME_CHECK
16878
    if (verify != NO_VERIFY && verify != VERIFY_SKIP_DATE &&
16879
            (! AsnSkipDateCheck) &&
16880
            !XVALIDATE_DATE(date, format, dateType)) {
16881
        if (dateType == ASN_BEFORE) {
16882
            WOLFSSL_ERROR_VERBOSE(ASN_BEFORE_DATE_E);
16883
            return ASN_BEFORE_DATE_E;
16884
        }
16885
        else {
16886
            WOLFSSL_ERROR_VERBOSE(ASN_AFTER_DATE_E);
16887
            return ASN_AFTER_DATE_E;
16888
        }
16889
    }
16890
#else
16891
    (void)verify;
16892
#endif
16893
16894
    return 0;
16895
}
16896
16897
static int GetValidity(DecodedCert* cert, int verify, int maxIdx)
16898
{
16899
    int length;
16900
    int badDate = 0;
16901
16902
    if (GetSequence(cert->source, &cert->srcIdx, &length, (word32)maxIdx) < 0)
16903
        return ASN_PARSE_E;
16904
16905
    maxIdx = (int)cert->srcIdx + length;
16906
16907
    if (GetDate(cert, ASN_BEFORE, verify, maxIdx) < 0)
16908
        badDate = ASN_BEFORE_DATE_E; /* continue parsing */
16909
16910
    if (GetDate(cert, ASN_AFTER, verify, maxIdx) < 0)
16911
        return ASN_AFTER_DATE_E;
16912
16913
    if (badDate != 0)
16914
        return badDate;
16915
16916
    return 0;
16917
}
16918
#endif /* !NO_CERTS && !WOLFSSL_ASN_TEMPLATE */
16919
16920
16921
int wc_GetDateInfo(const byte* certDate, int certDateSz, const byte** date,
16922
    byte* format, int* length)
16923
0
{
16924
0
    int ret;
16925
0
    word32 idx = 0;
16926
16927
0
    ret = GetDateInfo(certDate, &idx, date, format, length, (word32)certDateSz);
16928
16929
0
    return ret;
16930
0
}
16931
16932
#ifndef NO_ASN_TIME
16933
int wc_GetDateAsCalendarTime(const byte* date, int length, byte format,
16934
    struct tm* timearg)
16935
0
{
16936
0
    int idx = 0;
16937
0
    (void)length;
16938
0
    if (!ExtractDate(date, format, timearg, &idx))
16939
0
        return ASN_TIME_E;
16940
0
    return 0;
16941
0
}
16942
16943
#if defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_ALT_NAMES)
16944
int wc_GetCertDates(Cert* cert, struct tm* before, struct tm* after)
16945
{
16946
    int ret = 0;
16947
    const byte* date;
16948
    byte format;
16949
    int length;
16950
16951
    if (cert == NULL)
16952
        return BAD_FUNC_ARG;
16953
16954
    if (before && cert->beforeDateSz > 0) {
16955
        ret = wc_GetDateInfo(cert->beforeDate, cert->beforeDateSz, &date,
16956
                             &format, &length);
16957
        if (ret == 0)
16958
            ret = wc_GetDateAsCalendarTime(date, length, format, before);
16959
    }
16960
    if (after && cert->afterDateSz > 0) {
16961
        ret = wc_GetDateInfo(cert->afterDate, cert->afterDateSz, &date,
16962
                             &format, &length);
16963
        if (ret == 0)
16964
            ret = wc_GetDateAsCalendarTime(date, length, format, after);
16965
    }
16966
16967
    return ret;
16968
}
16969
#endif /* WOLFSSL_CERT_GEN && WOLFSSL_ALT_NAMES */
16970
#endif /* !NO_ASN_TIME */
16971
16972
#if !defined(WOLFSSL_ASN_TEMPLATE) && !defined(NO_CERTS)
16973
static int GetSigAlg(DecodedCert* cert, word32* sigOid, word32 maxIdx)
16974
{
16975
    int length;
16976
    word32 endSeqIdx;
16977
16978
    if (GetSequence(cert->source, &cert->srcIdx, &length, maxIdx) < 0)
16979
        return ASN_PARSE_E;
16980
    endSeqIdx = cert->srcIdx + (word32)length;
16981
16982
    if (GetObjectId(cert->source, &cert->srcIdx, sigOid, oidSigType,
16983
                    maxIdx) < 0) {
16984
        return ASN_OBJECT_ID_E;
16985
    }
16986
16987
    if (cert->srcIdx != endSeqIdx) {
16988
#ifdef WC_RSA_PSS
16989
        if (*sigOid == CTC_RSASSAPSS) {
16990
            cert->sigParamsIndex = cert->srcIdx;
16991
            cert->sigParamsLength = endSeqIdx - cert->srcIdx;
16992
        }
16993
        else
16994
#endif
16995
        /* Only allowed a ASN NULL header with zero length. */
16996
        if  (endSeqIdx - cert->srcIdx != 2)
16997
            return ASN_PARSE_E;
16998
        else {
16999
            byte tag;
17000
            if (GetASNTag(cert->source, &cert->srcIdx, &tag, endSeqIdx) != 0)
17001
                return ASN_PARSE_E;
17002
            if (tag != ASN_TAG_NULL)
17003
                return ASN_PARSE_E;
17004
        }
17005
    }
17006
17007
    cert->srcIdx = endSeqIdx;
17008
17009
    return 0;
17010
}
17011
#endif
17012
17013
#ifndef NO_CERTS
17014
#ifdef WOLFSSL_ASN_TEMPLATE
17015
/* TODO: move code around to not require this. */
17016
static int DecodeCertInternal(DecodedCert* cert, int verify, int* criticalExt,
17017
                              int* badDateRet, int stopAtPubKey,
17018
                              int stopAfterPubKey);
17019
#endif
17020
17021
/* Assumes the target is a Raw-Public-Key certificate and parsed up to the
17022
 * public key. Returns CRYPTOCB_UNAVAILABLE if it determines that the cert is
17023
 * different from the Paw-Public-Key cert. In that case, cert->srcIdx is not
17024
 * consumed so as succeeding parse function can take over.
17025
 * In case that the target is Raw-Public-Key cert and contains a public key,
17026
 * returns 0  and consumes cert->srcIdx so as a public key retrieval function
17027
 * can follow.
17028
 */
17029
#if defined(HAVE_RPK)
17030
int TryDecodeRPKToKey(DecodedCert* cert)
17031
{
17032
    int ret = 0, len;
17033
    word32 tmpIdx;
17034
    word32 oid;
17035
17036
    WOLFSSL_ENTER("TryDecodeRPKToKey");
17037
17038
    if (cert == NULL)
17039
        return BAD_FUNC_ARG;
17040
17041
    tmpIdx = cert->srcIdx;
17042
17043
    /* both X509 cert and RPK cert should start with a Sequence tag */
17044
    if (ret == 0) {
17045
        if (GetSequence(cert->source, &tmpIdx, &len, cert->maxIdx) < 0)
17046
            ret = ASN_PARSE_E;
17047
    }
17048
    /* TBSCertificate of X509 or AlgorithmIdentifier of RPK cert */
17049
    if (ret == 0) {
17050
        if (GetSequence(cert->source, &tmpIdx, &len, cert->maxIdx) < 0)
17051
            ret = ASN_PARSE_E;
17052
    }
17053
    /* OBJ ID should be next in RPK cert */
17054
    if (ret == 0) {
17055
        if (GetObjectId(cert->source, &tmpIdx, &oid, oidKeyType, cert->maxIdx)
17056
                                                                            < 0)
17057
            ret = CRYPTOCB_UNAVAILABLE;
17058
    }
17059
    /* consume cert->srcIdx */
17060
    if (ret == 0) {
17061
        WOLFSSL_MSG("Looks like RPK certificate");
17062
        cert->srcIdx = tmpIdx;
17063
    }
17064
    WOLFSSL_LEAVE("TryDecodeRPKToKey", ret);
17065
    return ret;
17066
}
17067
#endif /* HAVE_RPK */
17068
17069
/* Parse the certificate up to the X.509 public key.
17070
 *
17071
 * If cert data is invalid then badDate get set to error value.
17072
 *
17073
 * @param [in, out] cert     Decoded certificate object.
17074
 * @param [in]      verify   Whether to verify dates.
17075
 * @param [out]     badDate  Error code when verify dates.
17076
 * @return  0 on success.
17077
 * @return  BAD_FUNC_ARG when cert or badDate is NULL.
17078
 * @return  ASN_TIME_E when date BER tag is nor UTC or GENERALIZED time.
17079
 * @return  ASN_DATE_SZ_E when time data is not supported.
17080
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
17081
 *          is invalid.
17082
 * @return  BUFFER_E when data in buffer is too small.
17083
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
17084
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set.
17085
 */
17086
int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate)
17087
0
{
17088
#ifndef WOLFSSL_ASN_TEMPLATE
17089
    int ret;
17090
17091
    if (cert == NULL || badDate == NULL)
17092
        return BAD_FUNC_ARG;
17093
17094
    *badDate = 0;
17095
    if ( (ret = GetCertHeader(cert)) < 0)
17096
        return ret;
17097
17098
    WOLFSSL_MSG("Got Cert Header");
17099
17100
#ifdef WOLFSSL_CERT_REQ
17101
    if (!cert->isCSR) {
17102
#endif
17103
        /* Using the sigIndex as the upper bound because that's where the
17104
         * actual certificate data ends. */
17105
        if ((ret = GetSigAlg(cert, &cert->signatureOID, cert->sigIndex)) < 0)
17106
            return ret;
17107
17108
        WOLFSSL_MSG("Got Algo ID");
17109
17110
        if ( (ret = GetName(cert, ASN_ISSUER, (int)cert->sigIndex)) < 0)
17111
            return ret;
17112
17113
        if ( (ret = GetValidity(cert, verify, (int)cert->sigIndex)) < 0)
17114
            *badDate = ret;
17115
#ifdef WOLFSSL_CERT_REQ
17116
    }
17117
#endif
17118
17119
    if ( (ret = GetName(cert, ASN_SUBJECT, (int)cert->sigIndex)) < 0)
17120
        return ret;
17121
17122
    WOLFSSL_MSG("Got Subject Name");
17123
    return ret;
17124
#else
17125
    /* Use common decode routine and stop at public key. */
17126
0
    int ret;
17127
17128
0
    *badDate = 0;
17129
17130
0
    ret = DecodeCertInternal(cert, verify, NULL, badDate, 1, 0);
17131
0
    if (ret >= 0) {
17132
        /* Store current index: public key. */
17133
0
        cert->srcIdx = (word32)ret;
17134
0
    }
17135
0
    return ret;
17136
0
#endif /* WOLFSSL_ASN_TEMPLATE */
17137
0
}
17138
17139
/* Parse the certificate up to and including X.509 public key.
17140
 *
17141
 * @param [in, out] cert     Decoded certificate object.
17142
 * @param [in]      verify   Whether to verify dates.
17143
 * @return  0 on success.
17144
 * @return  ASN_TIME_E when date BER tag is nor UTC or GENERALIZED time.
17145
 * @return  ASN_DATE_SZ_E when time data is not supported.
17146
 * @return  ASN_BEFORE_DATE_E when ASN_BEFORE date is invalid.
17147
 * @return  ASN_AFTER_DATE_E when ASN_AFTER date is invalid.
17148
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
17149
 *          is invalid.
17150
 * @return  BUFFER_E when data in buffer is too small.
17151
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
17152
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
17153
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set.
17154
 */
17155
int DecodeToKey(DecodedCert* cert, int verify)
17156
0
{
17157
#ifndef WOLFSSL_ASN_TEMPLATE
17158
    int badDate = 0;
17159
    int ret;
17160
17161
#if defined(HAVE_RPK)
17162
17163
    /* Raw Public Key certificate has only a SubjectPublicKeyInfo structure
17164
     * as its contents. So try to call GetCertKey to get public key from it.
17165
     * If it fails, the cert should be a X509 cert and proceed to process as
17166
     * x509 cert. */
17167
    ret = GetCertKey(cert, cert->source, &cert->srcIdx, cert->maxIdx);
17168
    if (ret == 0) {
17169
        WOLFSSL_MSG("Raw Public Key certificate found and parsed");
17170
        cert->isRPK = 1;
17171
        return ret;
17172
    }
17173
#endif /* HAVE_RPK */
17174
17175
    if ( (ret = wc_GetPubX509(cert, verify, &badDate)) < 0)
17176
        return ret;
17177
17178
    /* Determine if self signed */
17179
#ifdef WOLFSSL_CERT_REQ
17180
    if (cert->isCSR)
17181
        cert->selfSigned = 1;
17182
    else
17183
#endif
17184
    {
17185
        cert->selfSigned = XMEMCMP(cert->issuerHash, cert->subjectHash,
17186
            KEYID_SIZE) == 0 ? 1 : 0;
17187
    }
17188
17189
    ret = GetCertKey(cert, cert->source, &cert->srcIdx, cert->maxIdx);
17190
    if (ret != 0)
17191
        return ret;
17192
17193
    WOLFSSL_MSG("Got Key");
17194
17195
    if (badDate != 0)
17196
        return badDate;
17197
17198
    return ret;
17199
#else
17200
0
    int ret;
17201
0
    int badDate = 0;
17202
17203
#ifdef WOLFSSL_DUAL_ALG_CERTS
17204
    /* Call internal version and decode completely to also handle extensions.
17205
     * This is required to parse a potential alternative public key in the
17206
     * SubjectAlternativeKey extension. */
17207
    ret = DecodeCertInternal(cert, verify, NULL, &badDate, 0, 0);
17208
#else
17209
    /* Call internal version and stop after public key. */
17210
0
    ret = DecodeCertInternal(cert, verify, NULL, &badDate, 0, 1);
17211
0
#endif
17212
    /* Always return date errors. */
17213
0
    if (ret == 0) {
17214
0
        ret = badDate;
17215
0
    }
17216
0
    return ret;
17217
0
#endif /* WOLFSSL_ASN_TEMPLATE */
17218
0
}
17219
17220
#if !defined(WOLFSSL_ASN_TEMPLATE)
17221
static int GetSignature(DecodedCert* cert)
17222
{
17223
    int length;
17224
    int ret;
17225
17226
    ret = CheckBitString(cert->source, &cert->srcIdx, &length, cert->maxIdx, 1,
17227
                         NULL);
17228
    if (ret != 0)
17229
        return ret;
17230
17231
    cert->sigLength = (word32)length;
17232
    cert->signature = &cert->source[cert->srcIdx];
17233
    cert->srcIdx += cert->sigLength;
17234
17235
    if (cert->srcIdx != cert->maxIdx)
17236
        return ASN_PARSE_E;
17237
17238
    return 0;
17239
}
17240
#endif /* !WOLFSSL_ASN_TEMPLATE */
17241
#endif /* !NO_CERTS */
17242
17243
#ifndef WOLFSSL_ASN_TEMPLATE
17244
static word32 SetOctetString8Bit(word32 len, byte* output)
17245
{
17246
    output[0] = ASN_OCTET_STRING;
17247
    output[1] = (byte)len;
17248
    return 2;
17249
}
17250
static word32 SetDigest(const byte* digest, word32 digSz, byte* output)
17251
{
17252
    word32 idx = SetOctetString8Bit(digSz, output);
17253
    XMEMCPY(&output[idx], digest, digSz);
17254
17255
    return idx + digSz;
17256
}
17257
#endif
17258
17259
17260
/* Encode a length for DER.
17261
 *
17262
 * @param [in]  length  Value to encode.
17263
 * @param [out] output  Buffer to encode into.
17264
 * @return  Number of bytes encoded.
17265
 */
17266
word32 SetLength(word32 length, byte* output)
17267
0
{
17268
    /* Start encoding at start of buffer. */
17269
0
    word32 i = 0;
17270
17271
0
    if (length < ASN_LONG_LENGTH) {
17272
        /* Only one byte needed to encode. */
17273
0
        if (output) {
17274
            /* Write out length value. */
17275
0
            output[i] = (byte)length;
17276
0
        }
17277
        /* Skip over length. */
17278
0
        i++;
17279
0
    }
17280
0
    else {
17281
        /* Calculate the number of bytes required to encode value. */
17282
0
        byte j = (byte)BytePrecision(length);
17283
17284
0
        if (output) {
17285
            /* Encode count byte. */
17286
0
            output[i] = (byte)(j | ASN_LONG_LENGTH);
17287
0
        }
17288
        /* Skip over count byte. */
17289
0
        i++;
17290
17291
        /* Encode value as a big-endian byte array. */
17292
0
        for (; j > 0; --j) {
17293
0
            if (output) {
17294
                /* Encode next most-significant byte. */
17295
0
                output[i] = (byte)(length >> ((j - 1) * WOLFSSL_BIT_SIZE));
17296
0
            }
17297
            /* Skip over byte. */
17298
0
            i++;
17299
0
        }
17300
0
    }
17301
17302
    /* Return number of bytes in encoded length. */
17303
0
    return i;
17304
0
}
17305
17306
word32 SetLengthEx(word32 length, byte* output, byte isIndef)
17307
0
{
17308
0
    if (isIndef) {
17309
0
        if (output != NULL) {
17310
0
            output[0] = ASN_INDEF_LENGTH;
17311
0
        }
17312
0
        return 1;
17313
0
    }
17314
0
    else {
17315
0
        return SetLength(length, output);
17316
0
    }
17317
0
}
17318
/* Encode a DER header - type/tag and length.
17319
 *
17320
 * @param [in]  tag     DER tag of ASN.1 item.
17321
 * @param [in]  len     Length of data in ASN.1 item.
17322
 * @param [out] output  Buffer to encode into.
17323
 * @return  Number of bytes encoded.
17324
 */
17325
word32 SetHeader(byte tag, word32 len, byte* output, byte isIndef)
17326
0
{
17327
0
    if (output) {
17328
        /* Encode tag first. */
17329
0
        output[0] = tag;
17330
0
    }
17331
    /* Encode the length. */
17332
0
    return SetLengthEx(len, output ? output + ASN_TAG_SZ : NULL, isIndef) +
17333
0
        ASN_TAG_SZ;
17334
0
}
17335
17336
/* Encode a SEQUENCE header in DER.
17337
 *
17338
 * @param [in]  len     Length of data in SEQUENCE.
17339
 * @param [out] output  Buffer to encode into.
17340
 * @return  Number of bytes encoded.
17341
 */
17342
word32 SetSequence(word32 len, byte* output)
17343
0
{
17344
0
    return SetHeader(ASN_SEQUENCE | ASN_CONSTRUCTED, len, output, 0);
17345
0
}
17346
17347
word32 SetSequenceEx(word32 len, byte* output, byte isIndef)
17348
0
{
17349
0
    return SetHeader(ASN_SEQUENCE | ASN_CONSTRUCTED, len, output, isIndef);
17350
0
}
17351
17352
/* Encode an OCTET STRING header in DER.
17353
 *
17354
 * @param [in]  len     Length of data in OCTET STRING.
17355
 * @param [out] output  Buffer to encode into.
17356
 * @return  Number of bytes encoded.
17357
 */
17358
word32 SetOctetString(word32 len, byte* output)
17359
0
{
17360
0
    return SetHeader(ASN_OCTET_STRING, len, output, 0);
17361
0
}
17362
17363
word32 SetOctetStringEx(word32 len, byte* output, byte indef)
17364
0
{
17365
0
    if (indef)
17366
0
        return SetHeader(ASN_OCTET_STRING | ASN_CONSTRUCTED, len, output, indef);
17367
0
    return SetOctetString(len, output);
17368
0
}
17369
17370
/* Encode a SET header in DER.
17371
 *
17372
 * @param [in]  len     Length of data in SET.
17373
 * @param [out] output  Buffer to encode into.
17374
 * @return  Number of bytes encoded.
17375
 */
17376
word32 SetSet(word32 len, byte* output)
17377
0
{
17378
0
    return SetHeader(ASN_SET | ASN_CONSTRUCTED, len, output, 0);
17379
0
}
17380
17381
/* Encode an implicit context specific header in DER.
17382
 *
17383
 * Implicit means that it is constructed only if the included ASN.1 item is.
17384
 *
17385
 * @param [in]  tag     Tag for the implicit ASN.1 item.
17386
 * @param [in]  number  Context specific number.
17387
 * @param [in]  len     Length of data in SET.
17388
 * @param [out] output  Buffer to encode into.
17389
 * @return  Number of bytes encoded.
17390
 */
17391
word32 SetImplicit(byte tag, byte number, word32 len, byte* output, byte isIndef)
17392
0
{
17393
0
    byte useIndef = 0;
17394
17395
0
    if ((tag == ASN_OCTET_STRING) && isIndef) {
17396
0
        tag = ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | number;
17397
0
    }
17398
0
    else {
17399
0
        tag = (byte)(((tag == ASN_SEQUENCE || tag == ASN_SET) ?
17400
0
            ASN_CONSTRUCTED : 0) | ASN_CONTEXT_SPECIFIC | number);
17401
0
    }
17402
17403
0
    if (isIndef && (tag & ASN_CONSTRUCTED)) {
17404
0
        useIndef = 1;
17405
0
    }
17406
17407
0
    return SetHeader(tag, len, output, useIndef);
17408
0
}
17409
17410
/* Encode an explicit context specific header in DER.
17411
 *
17412
 * Explicit means that there will be an ASN.1 item underneath.
17413
 *
17414
 * @param [in]  number  Context specific number.
17415
 * @param [in]  len     Length of data in SET.
17416
 * @param [out] output  Buffer to encode into.
17417
 * @return  Number of bytes encoded.
17418
 */
17419
word32 SetExplicit(byte number, word32 len, byte* output, byte isIndef)
17420
0
{
17421
0
    return SetHeader((byte)(ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | number),
17422
0
                     len, output, isIndef);
17423
0
}
17424
17425
#if defined(OPENSSL_EXTRA)
17426
/* Encode an Othername into DER.
17427
 *
17428
 * @param [in]  name    Pointer to the WOLFSSL_ASN1_OTHERNAME to be encoded.
17429
 * @param [out] output  Buffer to encode into. If NULL, don't encode.
17430
 * @return  Number of bytes encoded or WOLFSSL_FAILURE if name parameter is bad.
17431
 */
17432
word32 SetOthername(void *name, byte *output)
17433
{
17434
    WOLFSSL_ASN1_OTHERNAME *nm = (WOLFSSL_ASN1_OTHERNAME *)name;
17435
    char *nameStr = NULL;
17436
    word32 nameSz = 0;
17437
17438
    if ((nm == NULL) || (nm->value == NULL)) {
17439
        WOLFSSL_MSG("otherName value is NULL");
17440
        return WOLFSSL_FAILURE;
17441
    }
17442
17443
    nameStr = nm->value->value.utf8string->data;
17444
    nameSz = (word32)nm->value->value.utf8string->length;
17445
17446
    if (output == NULL) {
17447
        return nm->type_id->objSz +
17448
            SetHeader(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC, nameSz + 2, NULL, 0) +
17449
            SetHeader(CTC_UTF8, nameSz, NULL, 0) + nameSz;
17450
    }
17451
    else {
17452
        const byte *output_start = output;
17453
        /* otherName OID */
17454
        XMEMCPY(output, nm->type_id->obj, nm->type_id->objSz);
17455
        output += nm->type_id->objSz;
17456
17457
        output += SetHeader(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC, nameSz + 2,
17458
                            output, 0);
17459
17460
        /* work around false positive from -fstack-protector */
17461
        PRAGMA_GCC_DIAG_PUSH
17462
        PRAGMA_GCC("GCC diagnostic ignored \"-Wstringop-overflow\"")
17463
17464
        output += SetHeader(CTC_UTF8, nameSz, output, 0);
17465
17466
        PRAGMA_GCC_DIAG_POP
17467
17468
        XMEMCPY(output, nameStr, nameSz);
17469
17470
        output += nameSz;
17471
        return (word32)(output - output_start);
17472
    }
17473
}
17474
#endif /* OPENSSL_EXTRA */
17475
17476
17477
#ifdef HAVE_ECC
17478
/* Determines whether the signature algorithm is using ECDSA.
17479
 *
17480
 * @param [in] algoOID  Signature algorithm identifier.
17481
 * @return  1 when algorithm is using ECDSA.
17482
 * @return  0 otherwise.
17483
 */
17484
static WC_INLINE int IsSigAlgoECDSA(word32 algoOID)
17485
0
{
17486
    /* ECDSA sigAlgo must not have ASN1 NULL parameters */
17487
0
    if (algoOID == CTC_SHAwECDSA || algoOID == CTC_SHA256wECDSA ||
17488
0
        algoOID == CTC_SHA384wECDSA || algoOID == CTC_SHA512wECDSA) {
17489
0
        return 1;
17490
0
    }
17491
17492
0
    return 0;
17493
0
}
17494
#endif
17495
17496
/* Determines if OID is for an EC signing algorithm including ECDSA and EdDSA
17497
 * and post-quantum algorithms.
17498
 *
17499
 * @param [in] algoOID  Algorithm OID.
17500
 * @return  1 when is EC signing algorithm.
17501
 * @return  0 otherwise.
17502
 */
17503
static WC_INLINE int IsSigAlgoECC(word32 algoOID)
17504
0
{
17505
0
    (void)algoOID;
17506
17507
0
    return (0
17508
0
        #ifdef HAVE_ECC
17509
0
              || IsSigAlgoECDSA(algoOID)
17510
0
        #endif
17511
        #ifdef WOLFSSL_SM2
17512
              || (algoOID == SM2k)
17513
        #endif
17514
        #ifdef HAVE_ED25519
17515
              || (algoOID == ED25519k)
17516
        #endif
17517
        #ifdef HAVE_CURVE25519
17518
              || (algoOID == X25519k)
17519
        #endif
17520
        #ifdef HAVE_ED448
17521
              || (algoOID == ED448k)
17522
        #endif
17523
        #ifdef HAVE_CURVE448
17524
              || (algoOID == X448k)
17525
        #endif
17526
        #ifdef HAVE_FACON
17527
              || (algoOID == FALCON_LEVEL1k)
17528
              || (algoOID == FALCON_LEVEL5k)
17529
        #endif
17530
        #ifdef HAVE_DILITHIUM
17531
            #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
17532
              || (algoOID == DILITHIUM_LEVEL2k)
17533
              || (algoOID == DILITHIUM_LEVEL3k)
17534
              || (algoOID == DILITHIUM_LEVEL5k)
17535
            #endif
17536
              || (algoOID == ML_DSA_LEVEL2k)
17537
              || (algoOID == ML_DSA_LEVEL3k)
17538
              || (algoOID == ML_DSA_LEVEL5k)
17539
        #endif
17540
        #ifdef HAVE_SPHINCS
17541
              || (algoOID == SPHINCS_FAST_LEVEL1k)
17542
              || (algoOID == SPHINCS_FAST_LEVEL3k)
17543
              || (algoOID == SPHINCS_FAST_LEVEL5k)
17544
              || (algoOID == SPHINCS_SMALL_LEVEL1k)
17545
              || (algoOID == SPHINCS_SMALL_LEVEL3k)
17546
              || (algoOID == SPHINCS_SMALL_LEVEL5k)
17547
        #endif
17548
0
    );
17549
0
}
17550
17551
/* Encode an algorithm identifier.
17552
 *
17553
 * [algoOID, type] is unique.
17554
 *
17555
 * @param [in]  algoOID   Algorithm identifier.
17556
 * @param [out] output    Buffer to hold encoding.
17557
 * @param [in]  type      Type of OID being encoded.
17558
 * @param [in]  curveSz   Add extra space for curve data.
17559
 * @return  Encoded data size on success.
17560
 * @return  0 when dynamic memory allocation fails.
17561
 */
17562
static word32 SetAlgoIDImpl(int algoOID, byte* output, int type, int curveSz,
17563
                            byte absentParams)
17564
0
{
17565
#ifndef WOLFSSL_ASN_TEMPLATE
17566
    word32 tagSz, idSz, seqSz, algoSz = 0;
17567
    const  byte* algoName = 0;
17568
    byte   ID_Length[1 + MAX_LENGTH_SZ];
17569
    byte   seqArray[MAX_SEQ_SZ + 1];  /* add object_id to end */
17570
    word32    length = 0;
17571
17572
    tagSz = ((type == oidHashType ||
17573
             (type == oidSigType && !IsSigAlgoECC((word32)algoOID)) ||
17574
             (type == oidKeyType && algoOID == RSAk)) &&
17575
                (absentParams == FALSE)) ? 2U : 0U;
17576
    algoName = OidFromId((word32)algoOID, (word32)type, &algoSz);
17577
    if (algoName == NULL) {
17578
        WOLFSSL_MSG("Unknown Algorithm");
17579
        return 0;
17580
    }
17581
17582
    idSz  = (word32)SetObjectId((int)algoSz, ID_Length);
17583
    seqSz = SetSequence(idSz + algoSz + tagSz + (word32)curveSz, seqArray);
17584
17585
    /* Copy only algo to output for DSA keys */
17586
    if (algoOID == DSAk && output) {
17587
        XMEMCPY(output, ID_Length, idSz);
17588
        XMEMCPY(output + idSz, algoName, algoSz);
17589
        if (tagSz == 2)
17590
            SetASNNull(&output[seqSz + idSz + algoSz]);
17591
    }
17592
    else if (output) {
17593
        XMEMCPY(output, seqArray, seqSz);
17594
        XMEMCPY(output + seqSz, ID_Length, idSz);
17595
        XMEMCPY(output + seqSz + idSz, algoName, algoSz);
17596
        if (tagSz == 2)
17597
            SetASNNull(&output[seqSz + idSz + algoSz]);
17598
    }
17599
17600
    if (algoOID == DSAk)
17601
        length = idSz + algoSz + tagSz;
17602
    else
17603
        length = seqSz + idSz + algoSz + tagSz;
17604
17605
    return length;
17606
#else
17607
0
    DECL_ASNSETDATA(dataASN, algoIdASN_Length);
17608
0
    int ret = 0;
17609
0
    const byte* algoName = 0;
17610
0
    word32 algoSz = 0;
17611
17612
0
    CALLOC_ASNSETDATA(dataASN, algoIdASN_Length, ret, NULL);
17613
17614
0
    algoName = OidFromId((word32)algoOID, (word32)type, &algoSz);
17615
0
    if (algoName == NULL) {
17616
0
        WOLFSSL_MSG("Unknown Algorithm");
17617
0
    }
17618
0
    else {
17619
0
        int sz;
17620
0
        int o = 0;
17621
17622
        /* Set the OID and OID type to encode. */
17623
0
        SetASN_OID(&dataASN[ALGOIDASN_IDX_OID], (word32)algoOID, (word32)type);
17624
        /* Hashes, signatures not ECC and keys not RSA output NULL tag. */
17625
0
        if (!(type == oidHashType ||
17626
0
                 (type == oidSigType && !IsSigAlgoECC((word32)algoOID)) ||
17627
0
                 (type == oidKeyType && algoOID == RSAk))) {
17628
            /* Don't put out NULL DER item. */
17629
0
            dataASN[ALGOIDASN_IDX_NULL].noOut = 1;
17630
0
        }
17631
        /* Override for absent (not NULL) params */
17632
0
        if (TRUE == absentParams) {
17633
0
            dataASN[ALGOIDASN_IDX_NULL].noOut = 1;
17634
0
        }
17635
0
        if (algoOID == DSAk) {
17636
            /* Don't include SEQUENCE for DSA keys. */
17637
0
            o = 1;
17638
0
        }
17639
0
        else if (curveSz > 0) {
17640
            /* Don't put out NULL DER item. */
17641
0
            dataASN[ALGOIDASN_IDX_NULL].noOut = 0;
17642
            /* Include space for extra data of length curveSz.
17643
             * Subtract 1 for sequence and 1 for length encoding. */
17644
0
            SetASN_Buffer(&dataASN[ALGOIDASN_IDX_NULL], NULL,
17645
0
                          (word32)curveSz - 2);
17646
0
        }
17647
17648
        /* Calculate size of encoding. */
17649
0
        ret = SizeASN_Items(algoIdASN + o, dataASN + o,
17650
0
                            (int)algoIdASN_Length - (int)o, &sz);
17651
0
        if (ret == 0 && output != NULL) {
17652
            /* Encode into buffer. */
17653
0
            SetASN_Items(algoIdASN + o, dataASN + o,
17654
0
                         (int)algoIdASN_Length - (int)o, output);
17655
0
            if (curveSz > 0) {
17656
                /* Return size excluding curve data. */
17657
0
                sz = (int)(dataASN[o].offset -
17658
0
                           dataASN[ALGOIDASN_IDX_NULL].offset);
17659
0
            }
17660
0
        }
17661
17662
0
        if (ret == 0) {
17663
            /* Return encoded size. */
17664
0
            ret = sz;
17665
0
        }
17666
0
        else {
17667
            /* Unsigned return type so 0 indicates error. */
17668
0
            ret = 0;
17669
0
        }
17670
0
    }
17671
17672
0
    FREE_ASNSETDATA(dataASN, NULL);
17673
0
    return (word32)ret;
17674
0
#endif /* WOLFSSL_ASN_TEMPLATE */
17675
0
}
17676
17677
/* Encode an algorithm identifier.
17678
 *
17679
 * [algoOID, type] is unique.
17680
 *
17681
 * @param [in]  algoOID   Algorithm identifier.
17682
 * @param [out] output    Buffer to hold encoding.
17683
 * @param [in]  type      Type of OID being encoded.
17684
 * @param [in]  curveSz   Add extra space for curve data.
17685
 * @return  Encoded data size on success.
17686
 * @return  0 when dynamic memory allocation fails.
17687
 */
17688
word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz)
17689
0
{
17690
0
    return SetAlgoIDImpl(algoOID, output, type, curveSz, FALSE);
17691
0
}
17692
17693
word32 SetAlgoIDEx(int algoOID, byte* output, int type, int curveSz,
17694
                   byte absentParams)
17695
0
{
17696
0
    return SetAlgoIDImpl(algoOID, output, type, curveSz, absentParams);
17697
0
}
17698
17699
#ifdef WOLFSSL_ASN_TEMPLATE
17700
/* Always encode PKCS#1 v1.5 RSA signature and compare to encoded data. */
17701
/* ASN.1 template for DigestInfo for a PKCS#1 v1.5 RSA signature.
17702
 * PKCS#1 v2.2: RFC 8017, A.2.4 - DigestInfo
17703
 */
17704
static const ASNItem digestInfoASN[] = {
17705
/* SEQ          */ { 0, ASN_SEQUENCE, 1, 1, 0 },
17706
                                         /* digestAlgorithm */
17707
/* DIGALGO_SEQ  */     { 1, ASN_SEQUENCE, 1, 1, 0 },
17708
/* DIGALGO_OID  */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
17709
/* DIGALGO_NULL */         { 2, ASN_TAG_NULL, 0, 0, 0 },
17710
                                         /* digest */
17711
/* DIGEST       */     { 1, ASN_OCTET_STRING, 0, 0, 0 }
17712
};
17713
enum {
17714
    DIGESTINFOASN_IDX_SEQ = 0,
17715
    DIGESTINFOASN_IDX_DIGALGO_SEQ,
17716
    DIGESTINFOASN_IDX_DIGALGO_OID,
17717
    DIGESTINFOASN_IDX_DIGALGO_NULL,
17718
    DIGESTINFOASN_IDX_DIGEST
17719
};
17720
17721
/* Number of items in ASN.1 template for DigestInfo for RSA. */
17722
0
#define digestInfoASN_Length (sizeof(digestInfoASN) / sizeof(ASNItem))
17723
#endif
17724
17725
/* Encode signature.
17726
 *
17727
 * @param [out] out     Buffer to hold encoding.
17728
 * @param [in]  digest  Buffer holding digest.
17729
 * @param [in]  digSz   Length of digest in bytes.
17730
 * @return  Encoded data size on success.
17731
 * @return  0 when dynamic memory allocation fails.
17732
 */
17733
word32 wc_EncodeSignature(byte* out, const byte* digest, word32 digSz,
17734
                          int hashOID)
17735
0
{
17736
#ifndef WOLFSSL_ASN_TEMPLATE
17737
    byte digArray[MAX_ENCODED_DIG_SZ];
17738
    byte algoArray[MAX_ALGO_SZ];
17739
    byte seqArray[MAX_SEQ_SZ];
17740
    word32 encDigSz, algoSz, seqSz;
17741
17742
    encDigSz = SetDigest(digest, digSz, digArray);
17743
    algoSz   = SetAlgoID(hashOID, algoArray, oidHashType, 0);
17744
    seqSz    = SetSequence(encDigSz + algoSz, seqArray);
17745
17746
    XMEMCPY(out, seqArray, seqSz);
17747
    XMEMCPY(out + seqSz, algoArray, algoSz);
17748
    XMEMCPY(out + seqSz + algoSz, digArray, encDigSz);
17749
17750
    return encDigSz + algoSz + seqSz;
17751
#else
17752
0
    DECL_ASNSETDATA(dataASN, digestInfoASN_Length);
17753
0
    int ret = 0;
17754
0
    int sz = 0;
17755
0
    unsigned char dgst[WC_MAX_DIGEST_SIZE];
17756
17757
0
    CALLOC_ASNSETDATA(dataASN, digestInfoASN_Length, ret, NULL);
17758
17759
0
    if (ret == 0) {
17760
        /* Set hash OID and type. */
17761
0
        SetASN_OID(&dataASN[DIGESTINFOASN_IDX_DIGALGO_OID], (word32)hashOID,
17762
0
                   oidHashType);
17763
        /* Set digest. */
17764
0
        if (digest == out) {
17765
0
            XMEMCPY(dgst, digest, digSz);
17766
0
            digest = dgst;
17767
0
        }
17768
0
        SetASN_Buffer(&dataASN[DIGESTINFOASN_IDX_DIGEST], digest, digSz);
17769
17770
        /* Calculate size of encoding. */
17771
0
        ret = SizeASN_Items(digestInfoASN, dataASN, digestInfoASN_Length, &sz);
17772
0
    }
17773
0
    if (ret == 0) {
17774
        /* Encode PKCS#1 v1.5 RSA signature. */
17775
0
        SetASN_Items(digestInfoASN, dataASN, digestInfoASN_Length, out);
17776
0
        ret = sz;
17777
0
    }
17778
0
    else {
17779
        /* Unsigned return type so 0 indicates error. */
17780
0
        ret = 0;
17781
0
    }
17782
17783
0
    FREE_ASNSETDATA(dataASN, NULL);
17784
0
    return (word32)ret;
17785
0
#endif
17786
0
}
17787
17788
17789
#ifndef NO_CERTS
17790
17791
int wc_GetCTC_HashOID(int type)
17792
0
{
17793
0
    int ret;
17794
0
    enum wc_HashType hType;
17795
17796
0
    hType = wc_HashTypeConvert(type);
17797
0
    ret = wc_HashGetOID(hType);
17798
0
    if (ret < 0) {
17799
0
        ret = 0; /* backwards compatibility */
17800
0
    }
17801
17802
0
    return ret;
17803
0
}
17804
17805
/* Initialize a signature context object.
17806
 *
17807
 * Object used for signing and verifying a certificate signature.
17808
 *
17809
 * @param [in, out] sigCtx  Signature context object.
17810
 * @param [in]      heap    Dynamic memory hint.
17811
 * @param [in]      devId   Hardware device identifier.
17812
 */
17813
void InitSignatureCtx(SignatureCtx* sigCtx, void* heap, int devId)
17814
0
{
17815
0
    if (sigCtx) {
17816
0
        XMEMSET(sigCtx, 0, sizeof(SignatureCtx));
17817
0
        sigCtx->devId = devId;
17818
0
        sigCtx->heap = heap;
17819
0
    }
17820
0
}
17821
17822
/* Free dynamic data in a signature context object.
17823
 *
17824
 * @param [in, out] sigCtx  Signature context object.
17825
 */
17826
void FreeSignatureCtx(SignatureCtx* sigCtx)
17827
0
{
17828
0
    if (sigCtx == NULL)
17829
0
        return;
17830
17831
0
#ifndef WOLFSSL_NO_MALLOC
17832
0
    XFREE(sigCtx->digest, sigCtx->heap, DYNAMIC_TYPE_DIGEST);
17833
0
    sigCtx->digest = NULL;
17834
0
#if !defined(NO_RSA) || !defined(NO_DSA)
17835
0
    XFREE(sigCtx->sigCpy, sigCtx->heap, DYNAMIC_TYPE_SIGNATURE);
17836
0
    sigCtx->sigCpy = NULL;
17837
0
#endif
17838
0
#endif
17839
17840
0
#ifndef NO_ASN_CRYPT
17841
0
#ifndef WOLFSSL_NO_MALLOC
17842
0
    if (sigCtx->key.ptr)
17843
0
#endif
17844
0
    {
17845
0
        switch (sigCtx->keyOID) {
17846
0
        #ifndef NO_RSA
17847
0
            #ifdef WC_RSA_PSS
17848
0
            case RSAPSSk:
17849
0
            #endif
17850
0
            case RSAk:
17851
0
                wc_FreeRsaKey(sigCtx->key.rsa);
17852
0
            #ifndef WOLFSSL_NO_MALLOC
17853
0
                XFREE(sigCtx->key.rsa, sigCtx->heap, DYNAMIC_TYPE_RSA);
17854
0
                sigCtx->key.rsa = NULL;
17855
0
            #endif
17856
0
                break;
17857
0
        #endif /* !NO_RSA */
17858
        #ifndef NO_DSA
17859
            case DSAk:
17860
                wc_FreeDsaKey(sigCtx->key.dsa);
17861
            #ifndef WOLFSSL_NO_MALLOC
17862
                XFREE(sigCtx->key.dsa, sigCtx->heap, DYNAMIC_TYPE_DSA);
17863
                sigCtx->key.dsa = NULL;
17864
            #endif
17865
                break;
17866
        #endif
17867
0
        #ifdef HAVE_ECC
17868
0
            case ECDSAk:
17869
        #ifdef WOLFSSL_SM2
17870
            case SM2k:
17871
        #endif
17872
            #if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
17873
                defined(WC_ASYNC_ENABLE_ECC)
17874
                if (sigCtx->key.ecc->nb_ctx != NULL) {
17875
                    XFREE(sigCtx->key.ecc->nb_ctx, sigCtx->heap,
17876
                          DYNAMIC_TYPE_TMP_BUFFER);
17877
                }
17878
            #endif /* WC_ECC_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
17879
                      WC_ASYNC_ENABLE_ECC */
17880
0
                wc_ecc_free(sigCtx->key.ecc);
17881
0
            #ifndef WOLFSSL_NO_MALLOC
17882
0
                XFREE(sigCtx->key.ecc, sigCtx->heap, DYNAMIC_TYPE_ECC);
17883
0
                sigCtx->key.ecc = NULL;
17884
0
            #endif
17885
0
                break;
17886
0
        #endif /* HAVE_ECC */
17887
        #ifdef HAVE_ED25519
17888
            case ED25519k:
17889
                wc_ed25519_free(sigCtx->key.ed25519);
17890
            #ifndef WOLFSSL_NO_MALLOC
17891
                XFREE(sigCtx->key.ed25519, sigCtx->heap, DYNAMIC_TYPE_ED25519);
17892
                sigCtx->key.ed25519 = NULL;
17893
            #endif
17894
                break;
17895
        #endif /* HAVE_ED25519 */
17896
        #ifdef HAVE_ED448
17897
            case ED448k:
17898
                wc_ed448_free(sigCtx->key.ed448);
17899
            #ifndef WOLFSSL_NO_MALLOC
17900
                XFREE(sigCtx->key.ed448, sigCtx->heap, DYNAMIC_TYPE_ED448);
17901
                sigCtx->key.ed448 = NULL;
17902
            #endif
17903
                break;
17904
        #endif /* HAVE_ED448 */
17905
        #if defined(HAVE_FALCON)
17906
            case FALCON_LEVEL1k:
17907
            case FALCON_LEVEL5k:
17908
                wc_falcon_free(sigCtx->key.falcon);
17909
            #ifndef WOLFSSL_NO_MALLOC
17910
                XFREE(sigCtx->key.falcon, sigCtx->heap, DYNAMIC_TYPE_FALCON);
17911
                sigCtx->key.falcon = NULL;
17912
            #endif
17913
                break;
17914
        #endif /* HAVE_FALCON */
17915
        #if defined(HAVE_DILITHIUM)
17916
            #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
17917
            case DILITHIUM_LEVEL2k:
17918
            case DILITHIUM_LEVEL3k:
17919
            case DILITHIUM_LEVEL5k:
17920
            #endif
17921
            case ML_DSA_LEVEL2k:
17922
            case ML_DSA_LEVEL3k:
17923
            case ML_DSA_LEVEL5k:
17924
                wc_dilithium_free(sigCtx->key.dilithium);
17925
            #ifndef WOLFSSL_NO_MALLOC
17926
                XFREE(sigCtx->key.dilithium, sigCtx->heap,
17927
                    DYNAMIC_TYPE_DILITHIUM);
17928
                sigCtx->key.dilithium = NULL;
17929
            #endif
17930
                break;
17931
        #endif /* HAVE_DILITHIUM */
17932
        #if defined(HAVE_SPHINCS)
17933
            case SPHINCS_FAST_LEVEL1k:
17934
            case SPHINCS_FAST_LEVEL3k:
17935
            case SPHINCS_FAST_LEVEL5k:
17936
            case SPHINCS_SMALL_LEVEL1k:
17937
            case SPHINCS_SMALL_LEVEL3k:
17938
            case SPHINCS_SMALL_LEVEL5k:
17939
                wc_sphincs_free(sigCtx->key.sphincs);
17940
            #ifndef WOLFSSL_NO_MALLOC
17941
                XFREE(sigCtx->key.sphincs, sigCtx->heap, DYNAMIC_TYPE_SPHINCS);
17942
                sigCtx->key.sphincs = NULL;
17943
            #endif
17944
                break;
17945
        #endif /* HAVE_SPHINCS */
17946
0
            default:
17947
0
                break;
17948
0
        } /* switch (keyOID) */
17949
0
    #ifndef WOLFSSL_NO_MALLOC
17950
0
        sigCtx->key.ptr = NULL;
17951
0
    #endif
17952
0
    }
17953
0
#endif /* !NO_ASN_CRYPT */
17954
17955
    /* reset state, we are done */
17956
0
    sigCtx->state = SIG_STATE_BEGIN;
17957
0
}
17958
17959
#if !defined(NO_ASN_CRYPT) && !defined(NO_HASH_WRAPPER)
17960
static int HashForSignature(const byte* buf, word32 bufSz, word32 sigOID,
17961
                            byte* digest, int* typeH, int* digestSz, int verify)
17962
0
{
17963
0
    int ret = 0;
17964
17965
0
    switch (sigOID) {
17966
    #if defined(WOLFSSL_MD2)
17967
        case CTC_MD2wRSA:
17968
            if (!verify) {
17969
                ret = HASH_TYPE_E;
17970
                WOLFSSL_MSG("MD2 not supported for signing");
17971
            }
17972
            else if ((ret = wc_Md2Hash(buf, bufSz, digest)) == 0) {
17973
                *typeH    = MD2h;
17974
                *digestSz = WC_MD2_DIGEST_SIZE;
17975
            }
17976
        break;
17977
    #endif
17978
    #ifndef NO_MD5
17979
        case CTC_MD5wRSA:
17980
            if ((ret = wc_Md5Hash(buf, bufSz, digest)) == 0) {
17981
                *typeH    = MD5h;
17982
                *digestSz = WC_MD5_DIGEST_SIZE;
17983
            }
17984
            break;
17985
    #endif
17986
0
    #ifndef NO_SHA
17987
0
        case CTC_SHAwRSA:
17988
0
        case CTC_SHAwDSA:
17989
0
        case CTC_SHAwECDSA:
17990
0
            if ((ret = wc_ShaHash(buf, bufSz, digest)) == 0) {
17991
0
                *typeH    = SHAh;
17992
0
                *digestSz = WC_SHA_DIGEST_SIZE;
17993
0
            }
17994
0
            break;
17995
0
    #endif
17996
0
    #ifdef WOLFSSL_SHA224
17997
0
        case CTC_SHA224wRSA:
17998
0
        case CTC_SHA224wECDSA:
17999
0
            if ((ret = wc_Sha224Hash(buf, bufSz, digest)) == 0) {
18000
0
                *typeH    = SHA224h;
18001
0
                *digestSz = WC_SHA224_DIGEST_SIZE;
18002
0
            }
18003
0
            break;
18004
0
    #endif
18005
0
    #ifndef NO_SHA256
18006
0
        case CTC_SHA256wRSA:
18007
0
        case CTC_SHA256wECDSA:
18008
0
        case CTC_SHA256wDSA:
18009
0
            if ((ret = wc_Sha256Hash(buf, bufSz, digest)) == 0) {
18010
0
                *typeH    = SHA256h;
18011
0
                *digestSz = WC_SHA256_DIGEST_SIZE;
18012
0
            }
18013
0
            break;
18014
0
    #endif
18015
0
    #ifdef WOLFSSL_SHA384
18016
0
        case CTC_SHA384wRSA:
18017
0
        case CTC_SHA384wECDSA:
18018
0
            if ((ret = wc_Sha384Hash(buf, bufSz, digest)) == 0) {
18019
0
                *typeH    = SHA384h;
18020
0
                *digestSz = WC_SHA384_DIGEST_SIZE;
18021
0
            }
18022
0
            break;
18023
0
    #endif
18024
0
    #ifdef WOLFSSL_SHA512
18025
0
        case CTC_SHA512wRSA:
18026
0
        case CTC_SHA512wECDSA:
18027
0
            if ((ret = wc_Sha512Hash(buf, bufSz, digest)) == 0) {
18028
0
                *typeH    = SHA512h;
18029
0
                *digestSz = WC_SHA512_DIGEST_SIZE;
18030
0
            }
18031
0
            break;
18032
0
    #endif
18033
0
    #ifdef WOLFSSL_SHA3
18034
0
    #ifndef WOLFSSL_NOSHA3_224
18035
0
        case CTC_SHA3_224wRSA:
18036
0
        case CTC_SHA3_224wECDSA:
18037
0
            if ((ret = wc_Sha3_224Hash(buf, bufSz, digest)) == 0) {
18038
0
                *typeH    = SHA3_224h;
18039
0
                *digestSz = WC_SHA3_224_DIGEST_SIZE;
18040
0
            }
18041
0
            break;
18042
0
    #endif
18043
0
    #ifndef WOLFSSL_NOSHA3_256
18044
0
        case CTC_SHA3_256wRSA:
18045
0
        case CTC_SHA3_256wECDSA:
18046
0
            if ((ret = wc_Sha3_256Hash(buf, bufSz, digest)) == 0) {
18047
0
                *typeH    = SHA3_256h;
18048
0
                *digestSz = WC_SHA3_256_DIGEST_SIZE;
18049
0
            }
18050
0
            break;
18051
0
    #endif
18052
0
    #ifndef WOLFSSL_NOSHA3_384
18053
0
        case CTC_SHA3_384wRSA:
18054
0
        case CTC_SHA3_384wECDSA:
18055
0
            if ((ret = wc_Sha3_384Hash(buf, bufSz, digest)) == 0) {
18056
0
                *typeH    = SHA3_384h;
18057
0
                *digestSz = WC_SHA3_384_DIGEST_SIZE;
18058
0
            }
18059
0
            break;
18060
0
    #endif
18061
0
    #ifndef WOLFSSL_NOSHA3_512
18062
0
        case CTC_SHA3_512wRSA:
18063
0
        case CTC_SHA3_512wECDSA:
18064
0
            if ((ret = wc_Sha3_512Hash(buf, bufSz, digest)) == 0) {
18065
0
                *typeH    = SHA3_512h;
18066
0
                *digestSz = WC_SHA3_512_DIGEST_SIZE;
18067
0
            }
18068
0
            break;
18069
0
    #endif
18070
0
    #endif
18071
    #if defined(WOLFSSL_SM2) & defined(WOLFSSL_SM3)
18072
        case CTC_SM3wSM2:
18073
            if ((ret = wc_Sm3Hash(buf, bufSz, digest)) == 0) {
18074
                *typeH    = SM3h;
18075
                *digestSz = WC_SM3_DIGEST_SIZE;
18076
            }
18077
            break;
18078
    #endif
18079
    #ifdef HAVE_ED25519
18080
        case CTC_ED25519:
18081
            /* Hashes done in signing operation.
18082
             * Two dependent hashes with prefixes performed.
18083
             */
18084
            break;
18085
    #endif
18086
    #ifdef HAVE_ED448
18087
        case CTC_ED448:
18088
            /* Hashes done in signing operation.
18089
             * Two dependent hashes with prefixes performed.
18090
             */
18091
            break;
18092
    #endif
18093
    #ifdef HAVE_FALCON
18094
        case CTC_FALCON_LEVEL1:
18095
        case CTC_FALCON_LEVEL5:
18096
            /* Hashes done in signing operation. */
18097
            break;
18098
    #endif
18099
    #ifdef HAVE_DILITHIUM
18100
        #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
18101
        case CTC_DILITHIUM_LEVEL2:
18102
        case CTC_DILITHIUM_LEVEL3:
18103
        case CTC_DILITHIUM_LEVEL5:
18104
        #endif
18105
        case CTC_ML_DSA_LEVEL2:
18106
        case CTC_ML_DSA_LEVEL3:
18107
        case CTC_ML_DSA_LEVEL5:
18108
            /* Hashes done in signing operation. */
18109
            break;
18110
    #endif
18111
    #ifdef HAVE_SPHINCS
18112
        case CTC_SPHINCS_FAST_LEVEL1:
18113
        case CTC_SPHINCS_FAST_LEVEL3:
18114
        case CTC_SPHINCS_FAST_LEVEL5:
18115
        case CTC_SPHINCS_SMALL_LEVEL1:
18116
        case CTC_SPHINCS_SMALL_LEVEL3:
18117
        case CTC_SPHINCS_SMALL_LEVEL5:
18118
            /* Hashes done in signing operation. */
18119
            break;
18120
    #endif
18121
18122
0
        default:
18123
0
            ret = HASH_TYPE_E;
18124
0
            WOLFSSL_MSG("Hash for Signature has unsupported type");
18125
0
    }
18126
18127
0
    (void)buf;
18128
0
    (void)bufSz;
18129
0
    (void)sigOID;
18130
0
    (void)digest;
18131
0
    (void)digestSz;
18132
0
    (void)typeH;
18133
0
    (void)verify;
18134
18135
0
    return ret;
18136
0
}
18137
#endif /* !NO_ASN_CRYPT && !NO_HASH_WRAPPER */
18138
18139
#if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
18140
/* Try to parse as ASN.1 bitstring */
18141
static int DecodeDsaAsn1Sig(const byte* sig, word32 sigSz, byte* sigCpy,
18142
    void* heap)
18143
{
18144
    int ret = 0;
18145
    int rSz = 0, sSz = 0, mpinit = 0;
18146
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
18147
    mp_int* r = NULL;
18148
    mp_int* s = NULL;
18149
#else
18150
    mp_int r[1];
18151
    mp_int s[1];
18152
#endif
18153
18154
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
18155
    r = (mp_int*)XMALLOC(sizeof(*r), heap, DYNAMIC_TYPE_TMP_BUFFER);
18156
    s = (mp_int*)XMALLOC(sizeof(*s), heap, DYNAMIC_TYPE_TMP_BUFFER);
18157
    if (r == NULL || s == NULL) {
18158
        ret = MEMORY_E;
18159
    }
18160
#endif
18161
    if (ret == 0) {
18162
        ret = mp_init_multi(r, s, NULL, NULL, NULL, NULL);
18163
    }
18164
    if (ret == 0) {
18165
        mpinit = 1;
18166
18167
        if (DecodeECC_DSA_Sig(sig, sigSz, r, s) != 0) {
18168
            WOLFSSL_MSG("DSA sig decode ASN.1 failed!");
18169
            ret = ASN_SIG_CONFIRM_E;
18170
        }
18171
    }
18172
    if (ret == 0) {
18173
        rSz = mp_unsigned_bin_size(r);
18174
        sSz = mp_unsigned_bin_size(s);
18175
        if (rSz + sSz > (int)sigSz) {
18176
            WOLFSSL_MSG("DSA sig size invalid");
18177
            ret = ASN_SIG_CONFIRM_E;
18178
        }
18179
    }
18180
    if (ret == 0) {
18181
        if (mp_to_unsigned_bin(r, sigCpy) != MP_OKAY ||
18182
            mp_to_unsigned_bin(s, sigCpy + rSz) != MP_OKAY) {
18183
            WOLFSSL_MSG("DSA sig to unsigned bin failed!");
18184
            ret = ASN_SIG_CONFIRM_E;
18185
        }
18186
    }
18187
18188
    if (mpinit) {
18189
        mp_free(r);
18190
        mp_free(s);
18191
    }
18192
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
18193
    XFREE(r, heap, DYNAMIC_TYPE_TMP_BUFFER);
18194
    XFREE(s, heap, DYNAMIC_TYPE_TMP_BUFFER);
18195
#endif
18196
    (void)heap;
18197
    return ret;
18198
}
18199
#endif
18200
18201
/* Return codes: 0=Success, Negative (see error-crypt.h), ASN_SIG_CONFIRM_E */
18202
int ConfirmSignature(SignatureCtx* sigCtx,
18203
    const byte* buf, word32 bufSz,
18204
    const byte* key, word32 keySz, word32 keyOID,
18205
    const byte* sig, word32 sigSz, word32 sigOID,
18206
    const byte* sigParams, word32 sigParamsSz,
18207
    byte* rsaKeyIdx)
18208
0
{
18209
0
    int ret = WC_NO_ERR_TRACE(ASN_SIG_CONFIRM_E); /* default to failure */
18210
18211
#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_FSPSM_TLS)
18212
    CertAttribute* certatt = NULL;
18213
#endif
18214
18215
0
    if (sigCtx == NULL || buf == NULL || bufSz == 0 || key == NULL ||
18216
0
        keySz == 0 || sig == NULL || sigSz == 0) {
18217
0
        return BAD_FUNC_ARG;
18218
0
    }
18219
18220
0
    (void)key;
18221
0
    (void)keySz;
18222
0
    (void)sig;
18223
0
    (void)sigSz;
18224
0
    (void)sigParams;
18225
0
    (void)sigParamsSz;
18226
18227
0
    WOLFSSL_ENTER("ConfirmSignature");
18228
18229
0
#if !defined(WOLFSSL_RENESAS_TSIP_TLS) && !defined(WOLFSSL_RENESAS_FSPSM_TLS)
18230
0
    (void)rsaKeyIdx;
18231
#else
18232
    #if !defined(NO_RSA) || defined(HAVE_ECC)
18233
    certatt = (CertAttribute*)&sigCtx->CertAtt;
18234
    #endif
18235
    if (certatt) {
18236
        certatt->keyIndex = rsaKeyIdx;
18237
        certatt->cert = buf;
18238
        certatt->certSz = bufSz;
18239
    }
18240
#endif
18241
18242
0
#ifndef NO_ASN_CRYPT
18243
0
    switch (sigCtx->state) {
18244
0
        case SIG_STATE_BEGIN:
18245
0
        {
18246
0
            sigCtx->keyOID = keyOID; /* must set early for cleanup */
18247
18248
0
#ifndef WOLFSSL_NO_MALLOC
18249
0
            sigCtx->digest = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, sigCtx->heap,
18250
0
                                                    DYNAMIC_TYPE_DIGEST);
18251
0
            if (sigCtx->digest == NULL) {
18252
0
                ERROR_OUT(MEMORY_E, exit_cs);
18253
0
            }
18254
0
#endif
18255
18256
0
        #if !defined(NO_RSA) && defined(WC_RSA_PSS)
18257
            /* RSA PSS Defaults */
18258
0
            sigCtx->hash = WC_HASH_TYPE_SHA;
18259
0
            sigCtx->mgf = WC_MGF1SHA1;
18260
0
            sigCtx->saltLen = 20;
18261
0
        #endif
18262
18263
0
            sigCtx->state = SIG_STATE_HASH;
18264
0
        } /* SIG_STATE_BEGIN */
18265
0
        FALL_THROUGH;
18266
18267
0
        case SIG_STATE_HASH:
18268
0
        {
18269
0
        #if !defined(NO_RSA) && defined(WC_RSA_PSS)
18270
0
            if (sigOID == RSAPSSk) {
18271
0
                word32 fakeSigOID = 0;
18272
0
                ret = DecodeRsaPssParams(sigParams, sigParamsSz, &sigCtx->hash,
18273
0
                    &sigCtx->mgf, &sigCtx->saltLen);
18274
0
                if (ret != 0) {
18275
0
                    goto exit_cs;
18276
0
                }
18277
0
                ret = RsaPssHashOidToSigOid(sigCtx->hash, &fakeSigOID);
18278
0
                if (ret != 0) {
18279
0
                    goto exit_cs;
18280
0
                }
18281
                /* Decode parameters. */
18282
0
                ret = HashForSignature(buf, bufSz, fakeSigOID, sigCtx->digest,
18283
0
                    &sigCtx->typeH, &sigCtx->digestSz, 1);
18284
0
                if (ret != 0) {
18285
0
                    goto exit_cs;
18286
0
                }
18287
0
            }
18288
0
            else
18289
0
        #endif
18290
        #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
18291
            if (sigOID == CTC_SM3wSM2) {
18292
                ; /* SM2 hash requires public key. Done later. */
18293
            }
18294
            else
18295
        #endif
18296
0
            {
18297
0
                ret = HashForSignature(buf, bufSz, sigOID, sigCtx->digest,
18298
0
                                       &sigCtx->typeH, &sigCtx->digestSz, 1);
18299
0
                if (ret != 0) {
18300
0
                    goto exit_cs;
18301
0
                }
18302
0
            }
18303
18304
0
            sigCtx->state = SIG_STATE_KEY;
18305
0
        } /* SIG_STATE_HASH */
18306
0
        FALL_THROUGH;
18307
18308
0
        case SIG_STATE_KEY:
18309
0
        {
18310
0
            switch (keyOID) {
18311
0
            #ifndef NO_RSA
18312
0
                #ifdef WC_RSA_PSS
18313
0
                case RSAPSSk:
18314
0
                #endif
18315
0
                case RSAk:
18316
0
                {
18317
0
                    word32 idx = 0;
18318
18319
0
                #ifndef WOLFSSL_NO_MALLOC
18320
0
                    sigCtx->key.rsa = (RsaKey*)XMALLOC(sizeof(RsaKey),
18321
0
                                                sigCtx->heap, DYNAMIC_TYPE_RSA);
18322
0
                    if (sigCtx->key.rsa == NULL) {
18323
0
                        ERROR_OUT(MEMORY_E, exit_cs);
18324
0
                    }
18325
0
                #endif
18326
0
                    if ((ret = wc_InitRsaKey_ex(sigCtx->key.rsa, sigCtx->heap,
18327
0
                                                        sigCtx->devId)) != 0) {
18328
0
                        goto exit_cs;
18329
0
                    }
18330
0
                #ifndef WOLFSSL_NO_MALLOC
18331
0
                    sigCtx->sigCpy = (byte*)XMALLOC(sigSz, sigCtx->heap,
18332
0
                                                        DYNAMIC_TYPE_SIGNATURE);
18333
0
                    if (sigCtx->sigCpy == NULL) {
18334
0
                        ERROR_OUT(MEMORY_E, exit_cs);
18335
0
                    }
18336
0
                #endif
18337
0
                    if (sigSz > MAX_ENCODED_SIG_SZ) {
18338
0
                        WOLFSSL_MSG("Verify Signature is too big");
18339
0
                        ERROR_OUT(BUFFER_E, exit_cs);
18340
0
                    }
18341
0
                    if ((ret = wc_RsaPublicKeyDecode(key, &idx, sigCtx->key.rsa,
18342
0
                                                                 keySz)) != 0) {
18343
0
                        WOLFSSL_MSG("ASN Key decode error RSA");
18344
0
                        WOLFSSL_ERROR_VERBOSE(ret);
18345
0
                        goto exit_cs;
18346
0
                    }
18347
0
                    XMEMCPY(sigCtx->sigCpy, sig, sigSz);
18348
0
                    sigCtx->out = NULL;
18349
18350
                #ifdef WOLFSSL_ASYNC_CRYPT
18351
                    sigCtx->asyncDev = &sigCtx->key.rsa->asyncDev;
18352
                #endif
18353
0
                    break;
18354
0
                }
18355
0
            #endif /* !NO_RSA */
18356
            #if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
18357
                case DSAk:
18358
                {
18359
                    word32 idx = 0;
18360
18361
                    if (sigSz < DSA_MIN_SIG_SIZE) {
18362
                        WOLFSSL_MSG("Verify Signature is too small");
18363
                        ERROR_OUT(BUFFER_E, exit_cs);
18364
                    }
18365
                #ifndef WOLFSSL_NO_MALLOC
18366
                    sigCtx->key.dsa = (DsaKey*)XMALLOC(sizeof(DsaKey),
18367
                                                sigCtx->heap, DYNAMIC_TYPE_DSA);
18368
                    if (sigCtx->key.dsa == NULL) {
18369
                        ERROR_OUT(MEMORY_E, exit_cs);
18370
                    }
18371
                #endif
18372
                    if ((ret = wc_InitDsaKey_h(sigCtx->key.dsa, sigCtx->heap)) != 0) {
18373
                        WOLFSSL_MSG("wc_InitDsaKey_h error");
18374
                        goto exit_cs;
18375
                    }
18376
                #ifndef WOLFSSL_NO_MALLOC
18377
                    sigCtx->sigCpy = (byte*)XMALLOC(sigSz,
18378
                                         sigCtx->heap, DYNAMIC_TYPE_SIGNATURE);
18379
                    if (sigCtx->sigCpy == NULL) {
18380
                        ERROR_OUT(MEMORY_E, exit_cs);
18381
                    }
18382
                #endif
18383
                    if ((ret = wc_DsaPublicKeyDecode(key, &idx, sigCtx->key.dsa,
18384
                                                                 keySz)) != 0) {
18385
                        WOLFSSL_MSG("ASN Key decode error DSA");
18386
                        WOLFSSL_ERROR_VERBOSE(ret);
18387
                        goto exit_cs;
18388
                    }
18389
                    if (sigSz != DSA_160_SIG_SIZE &&
18390
                        sigSz != DSA_256_SIG_SIZE) {
18391
                        ret = DecodeDsaAsn1Sig(sig, sigSz, sigCtx->sigCpy,
18392
                            sigCtx->heap);
18393
                    }
18394
                    else {
18395
                        XMEMCPY(sigCtx->sigCpy, sig, sigSz);
18396
                    }
18397
                    break;
18398
                }
18399
            #endif /* !NO_DSA && !HAVE_SELFTEST */
18400
0
            #ifdef HAVE_ECC
18401
            #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
18402
                case SM2k:
18403
            #endif
18404
0
                case ECDSAk:
18405
0
                {
18406
0
                    word32 idx = 0;
18407
            #if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
18408
                defined(WC_ASYNC_ENABLE_ECC)
18409
                    ecc_nb_ctx_t* nbCtx;
18410
            #endif /* WC_ECC_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
18411
                      WC_ASYNC_ENABLE_ECC */
18412
18413
0
                    sigCtx->verify = 0;
18414
0
            #ifndef WOLFSSL_NO_MALLOC
18415
0
                    sigCtx->key.ecc = (ecc_key*)XMALLOC(sizeof(ecc_key),
18416
0
                                                sigCtx->heap, DYNAMIC_TYPE_ECC);
18417
0
                    if (sigCtx->key.ecc == NULL) {
18418
0
                        ERROR_OUT(MEMORY_E, exit_cs);
18419
0
                    }
18420
0
            #endif
18421
0
                    if ((ret = wc_ecc_init_ex(sigCtx->key.ecc, sigCtx->heap,
18422
0
                                                          sigCtx->devId)) < 0) {
18423
0
                        goto exit_cs;
18424
0
                    }
18425
            #if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
18426
                defined(WC_ASYNC_ENABLE_ECC)
18427
                    nbCtx = (ecc_nb_ctx_t*)XMALLOC(sizeof(ecc_nb_ctx_t),
18428
                                sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
18429
                    if (nbCtx == NULL) {
18430
                        ERROR_OUT(MEMORY_E, exit_cs);
18431
                    }
18432
18433
                    ret = wc_ecc_set_nonblock(sigCtx->key.ecc, nbCtx);
18434
                    if (ret != 0) {
18435
                        goto exit_cs;
18436
                    }
18437
18438
            #endif /* WC_ECC_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
18439
                      WC_ASYNC_ENABLE_ECC */
18440
0
                    ret = wc_EccPublicKeyDecode(key, &idx, sigCtx->key.ecc,
18441
0
                                                                         keySz);
18442
0
                    if (ret < 0) {
18443
0
                        WOLFSSL_MSG("ASN Key import error ECC");
18444
0
                        WOLFSSL_ERROR_VERBOSE(ret);
18445
0
                        goto exit_cs;
18446
0
                    }
18447
                #ifdef WOLFSSL_ASYNC_CRYPT
18448
                    sigCtx->asyncDev = &sigCtx->key.ecc->asyncDev;
18449
                #endif
18450
0
                    break;
18451
0
                }
18452
0
            #endif /* HAVE_ECC */
18453
            #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
18454
                case ED25519k:
18455
                {
18456
                    sigCtx->verify = 0;
18457
                #ifndef WOLFSSL_NO_MALLOC
18458
                    sigCtx->key.ed25519 = (ed25519_key*)XMALLOC(
18459
                                              sizeof(ed25519_key), sigCtx->heap,
18460
                                              DYNAMIC_TYPE_ED25519);
18461
                    if (sigCtx->key.ed25519 == NULL) {
18462
                        ERROR_OUT(MEMORY_E, exit_cs);
18463
                    }
18464
                #endif
18465
                    if ((ret = wc_ed25519_init_ex(sigCtx->key.ed25519,
18466
                                            sigCtx->heap, sigCtx->devId)) < 0) {
18467
                        goto exit_cs;
18468
                    }
18469
                    if ((ret = wc_ed25519_import_public(key, keySz,
18470
                                                    sigCtx->key.ed25519)) < 0) {
18471
                        WOLFSSL_MSG("ASN Key import error ED25519");
18472
                        WOLFSSL_ERROR_VERBOSE(ret);
18473
                        goto exit_cs;
18474
                    }
18475
                #ifdef WOLFSSL_ASYNC_CRYPT
18476
                    sigCtx->asyncDev = &sigCtx->key.ed25519->asyncDev;
18477
                #endif
18478
                    break;
18479
                }
18480
            #endif
18481
            #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)
18482
                case ED448k:
18483
                {
18484
                    sigCtx->verify = 0;
18485
                #ifndef WOLFSSL_NO_MALLOC
18486
                    sigCtx->key.ed448 = (ed448_key*)XMALLOC(
18487
                                                sizeof(ed448_key), sigCtx->heap,
18488
                                                DYNAMIC_TYPE_ED448);
18489
                    if (sigCtx->key.ed448 == NULL) {
18490
                        ERROR_OUT(MEMORY_E, exit_cs);
18491
                    }
18492
                #endif
18493
                    if ((ret = wc_ed448_init(sigCtx->key.ed448)) < 0) {
18494
                        goto exit_cs;
18495
                    }
18496
                    if ((ret = wc_ed448_import_public(key, keySz,
18497
                                                      sigCtx->key.ed448)) < 0) {
18498
                        WOLFSSL_MSG("ASN Key import error ED448");
18499
                        WOLFSSL_ERROR_VERBOSE(ret);
18500
                        goto exit_cs;
18501
                    }
18502
                #ifdef WOLFSSL_ASYNC_CRYPT
18503
                    sigCtx->asyncDev = &sigCtx->key.ed448->asyncDev;
18504
                #endif
18505
                    break;
18506
                }
18507
            #endif
18508
            #if defined(HAVE_FALCON)
18509
                case FALCON_LEVEL1k:
18510
                {
18511
                    word32 idx = 0;
18512
                    sigCtx->verify = 0;
18513
                #ifndef WOLFSSL_NO_MALLOC
18514
                    sigCtx->key.falcon =
18515
                        (falcon_key*)XMALLOC(sizeof(falcon_key),
18516
                                             sigCtx->heap,
18517
                                             DYNAMIC_TYPE_FALCON);
18518
                    if (sigCtx->key.falcon == NULL) {
18519
                        ERROR_OUT(MEMORY_E, exit_cs);
18520
                    }
18521
                #endif
18522
                    if ((ret = wc_falcon_init_ex(sigCtx->key.falcon,
18523
                                            sigCtx->heap, sigCtx->devId)) < 0) {
18524
                        goto exit_cs;
18525
                    }
18526
                    if ((ret = wc_falcon_set_level(sigCtx->key.falcon, 1))
18527
                        < 0) {
18528
                        goto exit_cs;
18529
                    }
18530
                    if ((ret = wc_Falcon_PublicKeyDecode(key, &idx,
18531
                        sigCtx->key.falcon, keySz)) < 0) {
18532
                        WOLFSSL_MSG("ASN Key import error Falcon Level 1");
18533
                        WOLFSSL_ERROR_VERBOSE(ret);
18534
                        goto exit_cs;
18535
                    }
18536
                    break;
18537
                }
18538
                case FALCON_LEVEL5k:
18539
                {
18540
                    word32 idx = 0;
18541
                    sigCtx->verify = 0;
18542
                #ifndef WOLFSSL_NO_MALLOC
18543
                    sigCtx->key.falcon =
18544
                        (falcon_key*)XMALLOC(sizeof(falcon_key),
18545
                                             sigCtx->heap,
18546
                                             DYNAMIC_TYPE_FALCON);
18547
                    if (sigCtx->key.falcon == NULL) {
18548
                        ERROR_OUT(MEMORY_E, exit_cs);
18549
                    }
18550
                #endif
18551
                    if ((ret = wc_falcon_init_ex(sigCtx->key.falcon,
18552
                                            sigCtx->heap, sigCtx->devId)) < 0) {
18553
                        goto exit_cs;
18554
                    }
18555
                    if ((ret = wc_falcon_set_level(sigCtx->key.falcon, 5))
18556
                        < 0) {
18557
                        goto exit_cs;
18558
                    }
18559
                    if ((ret = wc_Falcon_PublicKeyDecode(key, &idx,
18560
                        sigCtx->key.falcon, keySz)) < 0) {
18561
                        WOLFSSL_MSG("ASN Key import error Falcon Level 5");
18562
                        WOLFSSL_ERROR_VERBOSE(ret);
18563
                        goto exit_cs;
18564
                    }
18565
                    break;
18566
                }
18567
            #endif /* HAVE_FALCON */
18568
            #if defined(HAVE_DILITHIUM) && \
18569
                !defined(WOLFSSL_DILITHIUM_NO_VERIFY) && \
18570
                !defined(WOLFSSL_DILITHIUM_NO_ASN1)
18571
                #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
18572
                case DILITHIUM_LEVEL2k:
18573
                case DILITHIUM_LEVEL3k:
18574
                case DILITHIUM_LEVEL5k:
18575
                #endif
18576
                case ML_DSA_LEVEL2k:
18577
                case ML_DSA_LEVEL3k:
18578
                case ML_DSA_LEVEL5k:
18579
                {
18580
                    word32 idx = 0;
18581
                    int level;
18582
                    if (keyOID == ML_DSA_LEVEL2k) {
18583
                        level = WC_ML_DSA_44;
18584
                    }
18585
                    else if (keyOID == ML_DSA_LEVEL3k) {
18586
                        level = WC_ML_DSA_65;
18587
                    }
18588
                    else if (keyOID == ML_DSA_LEVEL5k) {
18589
                        level = WC_ML_DSA_87;
18590
                    }
18591
                #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
18592
                    else if (keyOID == DILITHIUM_LEVEL2k) {
18593
                        level = WC_ML_DSA_44_DRAFT;
18594
                    }
18595
                    else if (keyOID == DILITHIUM_LEVEL3k) {
18596
                        level = WC_ML_DSA_65_DRAFT;
18597
                    }
18598
                    else if (keyOID == DILITHIUM_LEVEL5k) {
18599
                        level = WC_ML_DSA_87_DRAFT;
18600
                    }
18601
                #endif
18602
                    else {
18603
                        WOLFSSL_MSG("Invalid Dilithium key OID");
18604
                        goto exit_cs;
18605
                    }
18606
                    sigCtx->verify = 0;
18607
                #ifndef WOLFSSL_NO_MALLOC
18608
                    sigCtx->key.dilithium = (dilithium_key*)XMALLOC(
18609
                        sizeof(dilithium_key), sigCtx->heap,
18610
                        DYNAMIC_TYPE_DILITHIUM);
18611
                    if (sigCtx->key.dilithium == NULL) {
18612
                        ERROR_OUT(MEMORY_E, exit_cs);
18613
                    }
18614
                #endif
18615
                    if ((ret = wc_dilithium_init_ex(sigCtx->key.dilithium,
18616
                            sigCtx->heap, sigCtx->devId)) < 0) {
18617
                        goto exit_cs;
18618
                    }
18619
                    if ((ret = wc_dilithium_set_level(sigCtx->key.dilithium,
18620
                            level)) < 0) {
18621
                        goto exit_cs;
18622
                    }
18623
                    if ((ret = wc_Dilithium_PublicKeyDecode(key, &idx,
18624
                        sigCtx->key.dilithium, keySz)) < 0) {
18625
                        WOLFSSL_MSG("ASN Key import error Dilithium");
18626
                        goto exit_cs;
18627
                    }
18628
                    break;
18629
                }
18630
            #endif /* HAVE_DILITHIUM */
18631
            #if defined(HAVE_SPHINCS)
18632
                case SPHINCS_FAST_LEVEL1k:
18633
                {
18634
                    word32 idx = 0;
18635
                    sigCtx->verify = 0;
18636
                #ifndef WOLFSSL_NO_MALLOC
18637
                    sigCtx->key.sphincs =
18638
                        (sphincs_key*)XMALLOC(sizeof(sphincs_key),
18639
                                             sigCtx->heap,
18640
                                             DYNAMIC_TYPE_SPHINCS);
18641
                    if (sigCtx->key.sphincs == NULL) {
18642
                        ERROR_OUT(MEMORY_E, exit_cs);
18643
                    }
18644
                #endif
18645
18646
                    if ((ret = wc_sphincs_init(sigCtx->key.sphincs)) < 0) {
18647
                        goto exit_cs;
18648
                    }
18649
                    if ((ret = wc_sphincs_set_level_and_optim(
18650
                                   sigCtx->key.sphincs, 1, FAST_VARIANT))
18651
                        < 0) {
18652
                        goto exit_cs;
18653
                    }
18654
                    if ((ret = wc_Sphincs_PublicKeyDecode(key, &idx,
18655
                        sigCtx->key.sphincs, keySz)) < 0) {
18656
                        WOLFSSL_MSG("ASN Key import err: Sphincs-fast Level1");
18657
                        goto exit_cs;
18658
                    }
18659
                    break;
18660
                }
18661
                case SPHINCS_FAST_LEVEL3k:
18662
                {
18663
                    word32 idx = 0;
18664
                    sigCtx->verify = 0;
18665
                #ifndef WOLFSSL_NO_MALLOC
18666
                    sigCtx->key.sphincs =
18667
                        (sphincs_key*)XMALLOC(sizeof(sphincs_key),
18668
                                             sigCtx->heap,
18669
                                             DYNAMIC_TYPE_SPHINCS);
18670
                    if (sigCtx->key.sphincs == NULL) {
18671
                        ERROR_OUT(MEMORY_E, exit_cs);
18672
                    }
18673
                #endif
18674
                    if ((ret = wc_sphincs_init(sigCtx->key.sphincs)) < 0) {
18675
                        goto exit_cs;
18676
                    }
18677
                    if ((ret = wc_sphincs_set_level_and_optim(
18678
                                   sigCtx->key.sphincs, 3, FAST_VARIANT))
18679
                        < 0) {
18680
                        goto exit_cs;
18681
                    }
18682
                    if ((ret = wc_Sphincs_PublicKeyDecode(key, &idx,
18683
                        sigCtx->key.sphincs, keySz)) < 0) {
18684
                        WOLFSSL_MSG("ASN Key import err: Sphincs-fast Level3");
18685
                        goto exit_cs;
18686
                    }
18687
                    break;
18688
                }
18689
                case SPHINCS_FAST_LEVEL5k:
18690
                {
18691
                    word32 idx = 0;
18692
                    sigCtx->verify = 0;
18693
                #ifndef WOLFSSL_NO_MALLOC
18694
                    sigCtx->key.sphincs =
18695
                        (sphincs_key*)XMALLOC(sizeof(sphincs_key),
18696
                                             sigCtx->heap,
18697
                                             DYNAMIC_TYPE_SPHINCS);
18698
                    if (sigCtx->key.sphincs == NULL) {
18699
                        ERROR_OUT(MEMORY_E, exit_cs);
18700
                    }
18701
                #endif
18702
                    if ((ret = wc_sphincs_init(sigCtx->key.sphincs)) < 0) {
18703
                        goto exit_cs;
18704
                    }
18705
                    if ((ret = wc_sphincs_set_level_and_optim(
18706
                                   sigCtx->key.sphincs, 5, FAST_VARIANT))
18707
                        < 0) {
18708
                        goto exit_cs;
18709
                    }
18710
                    if ((ret = wc_Sphincs_PublicKeyDecode(key, &idx,
18711
                        sigCtx->key.sphincs, keySz)) < 0) {
18712
                        WOLFSSL_MSG("ASN Key import err: Sphincs-fast Level5");
18713
                        goto exit_cs;
18714
                    }
18715
                    break;
18716
                }
18717
                case SPHINCS_SMALL_LEVEL1k:
18718
                {
18719
                    word32 idx = 0;
18720
                    sigCtx->verify = 0;
18721
                #ifndef WOLFSSL_NO_MALLOC
18722
                    sigCtx->key.sphincs =
18723
                        (sphincs_key*)XMALLOC(sizeof(sphincs_key),
18724
                                             sigCtx->heap,
18725
                                             DYNAMIC_TYPE_SPHINCS);
18726
                    if (sigCtx->key.sphincs == NULL) {
18727
                        ERROR_OUT(MEMORY_E, exit_cs);
18728
                    }
18729
                #endif
18730
                    if ((ret = wc_sphincs_init(sigCtx->key.sphincs)) < 0) {
18731
                        goto exit_cs;
18732
                    }
18733
                    if ((ret = wc_sphincs_set_level_and_optim(
18734
                                   sigCtx->key.sphincs, 1, SMALL_VARIANT))
18735
                        < 0) {
18736
                        goto exit_cs;
18737
                    }
18738
                    if ((ret = wc_Sphincs_PublicKeyDecode(key, &idx,
18739
                        sigCtx->key.sphincs, keySz)) < 0) {
18740
                        WOLFSSL_MSG("ASN Key import err: Sphincs-fast Level1");
18741
                        goto exit_cs;
18742
                    }
18743
                    break;
18744
                }
18745
                case SPHINCS_SMALL_LEVEL3k:
18746
                {
18747
                    word32 idx = 0;
18748
                    sigCtx->verify = 0;
18749
                #ifndef WOLFSSL_NO_MALLOC
18750
                    sigCtx->key.sphincs =
18751
                        (sphincs_key*)XMALLOC(sizeof(sphincs_key),
18752
                                             sigCtx->heap,
18753
                                             DYNAMIC_TYPE_SPHINCS);
18754
                    if (sigCtx->key.sphincs == NULL) {
18755
                        ERROR_OUT(MEMORY_E, exit_cs);
18756
                    }
18757
                #endif
18758
                    if ((ret = wc_sphincs_init(sigCtx->key.sphincs)) < 0) {
18759
                        goto exit_cs;
18760
                    }
18761
                    if ((ret = wc_sphincs_set_level_and_optim(
18762
                                   sigCtx->key.sphincs, 3, SMALL_VARIANT))
18763
                        < 0) {
18764
                        goto exit_cs;
18765
                    }
18766
                    if ((ret = wc_Sphincs_PublicKeyDecode(key, &idx,
18767
                        sigCtx->key.sphincs, keySz)) < 0) {
18768
                        WOLFSSL_MSG("ASN Key import err: Sphincs-fast Level3");
18769
                        goto exit_cs;
18770
                    }
18771
                    break;
18772
                }
18773
                case SPHINCS_SMALL_LEVEL5k:
18774
                {
18775
                    word32 idx = 0;
18776
                    sigCtx->verify = 0;
18777
                #ifndef WOLFSSL_NO_MALLOC
18778
                    sigCtx->key.sphincs =
18779
                        (sphincs_key*)XMALLOC(sizeof(sphincs_key),
18780
                                             sigCtx->heap,
18781
                                             DYNAMIC_TYPE_SPHINCS);
18782
                    if (sigCtx->key.sphincs == NULL) {
18783
                        ERROR_OUT(MEMORY_E, exit_cs);
18784
                    }
18785
                #endif
18786
                    if ((ret = wc_sphincs_init(sigCtx->key.sphincs)) < 0) {
18787
                        goto exit_cs;
18788
                    }
18789
                    if ((ret = wc_sphincs_set_level_and_optim(
18790
                                   sigCtx->key.sphincs, 5, SMALL_VARIANT))
18791
                        < 0) {
18792
                        goto exit_cs;
18793
                    }
18794
                    if ((ret = wc_Sphincs_PublicKeyDecode(key, &idx,
18795
                        sigCtx->key.sphincs, keySz)) < 0) {
18796
                        WOLFSSL_MSG("ASN Key import err: Sphincs-fast Level5");
18797
                        goto exit_cs;
18798
                    }
18799
                    break;
18800
                }
18801
            #endif /* HAVE_SPHINCS */
18802
0
                default:
18803
0
                    WOLFSSL_MSG("Verify Key type unknown");
18804
0
                    ret = ASN_UNKNOWN_OID_E;
18805
0
                    WOLFSSL_ERROR_VERBOSE(ret);
18806
0
                    break;
18807
0
            } /* switch (keyOID) */
18808
18809
0
            if (ret != 0) {
18810
0
                goto exit_cs;
18811
0
            }
18812
18813
0
            sigCtx->state = SIG_STATE_DO;
18814
18815
        #ifdef WOLFSSL_ASYNC_CRYPT
18816
            if (sigCtx->devId != INVALID_DEVID && sigCtx->asyncDev && sigCtx->asyncCtx) {
18817
                /* make sure event is initialized */
18818
                WOLF_EVENT* event = &sigCtx->asyncDev->event;
18819
                ret = wolfAsync_EventInit(event, WOLF_EVENT_TYPE_ASYNC_WOLFSSL,
18820
                    sigCtx->asyncCtx, WC_ASYNC_FLAG_CALL_AGAIN);
18821
            }
18822
        #endif
18823
0
        } /* SIG_STATE_KEY */
18824
0
        FALL_THROUGH;
18825
18826
0
        case SIG_STATE_DO:
18827
0
        {
18828
0
            switch (keyOID) {
18829
0
            #ifndef NO_RSA
18830
0
                case RSAk:
18831
0
                #ifdef WC_RSA_PSS
18832
0
                case RSAPSSk:
18833
0
                if (sigOID == RSAPSSk) {
18834
                    /* TODO: pkCbRsaPss - RSA PSS callback. */
18835
0
                    ret = wc_RsaPSS_VerifyInline_ex(sigCtx->sigCpy, sigSz,
18836
0
                        &sigCtx->out, sigCtx->hash, sigCtx->mgf,
18837
0
                        sigCtx->saltLen, sigCtx->key.rsa);
18838
0
                }
18839
0
                else
18840
0
                #endif
18841
0
                {
18842
                #if defined(HAVE_PK_CALLBACKS)
18843
                    if (sigCtx->pkCbRsa) {
18844
                        ret = sigCtx->pkCbRsa(
18845
                                sigCtx->sigCpy, sigSz, &sigCtx->out,
18846
                                key, keySz,
18847
                                sigCtx->pkCtxRsa);
18848
                    }
18849
                #if !defined(WOLFSSL_RENESAS_FSPSM_TLS) && \
18850
                    !defined(WOLFSSL_RENESAS_TSIP_TLS)
18851
                    else
18852
                #else
18853
                    if (!sigCtx->pkCbRsa ||
18854
                        ret == WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
18855
                #endif /* WOLFSSL_RENESAS_FSPSM_TLS */
18856
                #endif /* HAVE_PK_CALLBACKS */
18857
0
                    {
18858
0
                        ret = wc_RsaSSL_VerifyInline(sigCtx->sigCpy, sigSz,
18859
0
                                                 &sigCtx->out, sigCtx->key.rsa);
18860
0
                    }
18861
0
                }
18862
0
                break;
18863
0
            #endif /* !NO_RSA */
18864
            #if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
18865
                case DSAk:
18866
                {
18867
                    ret = wc_DsaVerify(sigCtx->digest, sigCtx->sigCpy,
18868
                            sigCtx->key.dsa, &sigCtx->verify);
18869
                    break;
18870
                }
18871
            #endif /* !NO_DSA && !HAVE_SELFTEST */
18872
            #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
18873
                case SM2k:
18874
                {
18875
                    /* OpenSSL creates signature without CERT_SIG_ID. */
18876
                    ret = wc_ecc_sm2_create_digest(CERT_SIG_ID, 0, buf, bufSz,
18877
                        WC_HASH_TYPE_SM3, sigCtx->digest, WC_SM3_DIGEST_SIZE,
18878
                        sigCtx->key.ecc);
18879
                    if (ret == 0) {
18880
                        sigCtx->typeH    = SM3h;
18881
                        sigCtx->digestSz = WC_SM3_DIGEST_SIZE;
18882
                    }
18883
                    else {
18884
                        WOLFSSL_MSG("SM2wSM3 create digest failed");
18885
                        WOLFSSL_ERROR_VERBOSE(ret);
18886
                        goto exit_cs;
18887
                    }
18888
                    ret = wc_ecc_sm2_verify_hash(sig, sigSz, sigCtx->digest,
18889
                        sigCtx->digestSz, &sigCtx->verify, sigCtx->key.ecc);
18890
                    break;
18891
                }
18892
            #endif
18893
0
            #if defined(HAVE_ECC) && defined(HAVE_ECC_VERIFY)
18894
0
                case ECDSAk:
18895
0
                {
18896
                #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
18897
                    if (sigOID == CTC_SM3wSM2) {
18898
                        ret = wc_ecc_sm2_create_digest(CERT_SIG_ID,
18899
                            CERT_SIG_ID_SZ, buf, bufSz, WC_HASH_TYPE_SM3,
18900
                            sigCtx->digest, WC_SM3_DIGEST_SIZE,
18901
                            sigCtx->key.ecc);
18902
                        if (ret == 0) {
18903
                            sigCtx->typeH    = SM3h;
18904
                            sigCtx->digestSz = WC_SM3_DIGEST_SIZE;
18905
                        }
18906
                        else {
18907
                            WOLFSSL_MSG("SM2wSM3 create digest failed");
18908
                            WOLFSSL_ERROR_VERBOSE(ret);
18909
                            goto exit_cs;
18910
                        }
18911
                        ret = wc_ecc_sm2_verify_hash(sig, sigSz, sigCtx->digest,
18912
                            sigCtx->digestSz, &sigCtx->verify, sigCtx->key.ecc);
18913
                    }
18914
                    else
18915
                #endif
18916
                #if defined(HAVE_PK_CALLBACKS)
18917
                    if (sigCtx->pkCbEcc) {
18918
                        ret = sigCtx->pkCbEcc(
18919
                                sig, sigSz,
18920
                                sigCtx->digest, (unsigned int)sigCtx->digestSz,
18921
                                key, keySz, &sigCtx->verify,
18922
                                sigCtx->pkCtxEcc);
18923
                    }
18924
                #if !defined(WOLFSSL_RENESAS_FSPSM_TLS) && \
18925
                    !defined(WOLFSSL_RENESAS_TSIP_TLS)
18926
                    else
18927
                #else
18928
                    if (!sigCtx->pkCbEcc ||
18929
                        ret == WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
18930
                #endif /* WOLFSSL_RENESAS_FSPSM_TLS */
18931
                #endif /* HAVE_PK_CALLBACKS */
18932
0
                    {
18933
0
                        ret = wc_ecc_verify_hash(sig, sigSz, sigCtx->digest,
18934
0
                            (word32)sigCtx->digestSz, &sigCtx->verify,
18935
0
                            sigCtx->key.ecc);
18936
0
                    }
18937
0
                    break;
18938
0
                }
18939
0
            #endif /* HAVE_ECC */
18940
            #if defined(HAVE_ED25519) && defined(HAVE_ED25519_VERIFY)
18941
                case ED25519k:
18942
                {
18943
                    ret = wc_ed25519_verify_msg(sig, sigSz, buf, bufSz,
18944
                                          &sigCtx->verify, sigCtx->key.ed25519);
18945
                    break;
18946
                }
18947
            #endif
18948
            #if defined(HAVE_ED448) && defined(HAVE_ED448_VERIFY)
18949
                case ED448k:
18950
                {
18951
                    ret = wc_ed448_verify_msg(sig, sigSz, buf, bufSz,
18952
                                             &sigCtx->verify, sigCtx->key.ed448,
18953
                                             NULL, 0);
18954
                    break;
18955
                }
18956
            #endif
18957
            #if defined(HAVE_FALCON)
18958
                case FALCON_LEVEL1k:
18959
                case FALCON_LEVEL5k:
18960
                {
18961
                    ret = wc_falcon_verify_msg(sig, sigSz, buf, bufSz,
18962
                                               &sigCtx->verify,
18963
                                               sigCtx->key.falcon);
18964
                    break;
18965
                }
18966
            #endif /* HAVE_FALCON */
18967
            #if defined(HAVE_DILITHIUM) && !defined(WOLFSSL_DILITHIUM_NO_VERIFY)
18968
                #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
18969
                case DILITHIUM_LEVEL2k:
18970
                case DILITHIUM_LEVEL3k:
18971
                case DILITHIUM_LEVEL5k:
18972
                {
18973
                    ret = wc_dilithium_verify_msg(sig, sigSz, buf, bufSz,
18974
                                               &sigCtx->verify,
18975
                                               sigCtx->key.dilithium);
18976
                    break;
18977
                }
18978
                #endif
18979
                case ML_DSA_LEVEL2k:
18980
                case ML_DSA_LEVEL3k:
18981
                case ML_DSA_LEVEL5k:
18982
                {
18983
                    ret = wc_dilithium_verify_ctx_msg(sig, sigSz, NULL, 0, buf,
18984
                        bufSz, &sigCtx->verify, sigCtx->key.dilithium);
18985
                    break;
18986
                }
18987
            #endif /* HAVE_DILITHIUM */
18988
            #if defined(HAVE_SPHINCS)
18989
                case SPHINCS_FAST_LEVEL1k:
18990
                case SPHINCS_FAST_LEVEL3k:
18991
                case SPHINCS_FAST_LEVEL5k:
18992
                case SPHINCS_SMALL_LEVEL1k:
18993
                case SPHINCS_SMALL_LEVEL3k:
18994
                case SPHINCS_SMALL_LEVEL5k:
18995
                {
18996
                    ret = wc_sphincs_verify_msg(sig, sigSz, buf, bufSz,
18997
                                                &sigCtx->verify,
18998
                                                sigCtx->key.sphincs);
18999
                    break;
19000
                }
19001
            #endif /* HAVE_SPHINCS */
19002
0
                default:
19003
0
                    break;
19004
0
            }  /* switch (keyOID) */
19005
19006
        #ifdef WOLFSSL_ASYNC_CRYPT
19007
            if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) {
19008
                goto exit_cs;
19009
            }
19010
        #endif
19011
19012
0
            if (ret < 0) {
19013
                /* treat all errors as ASN_SIG_CONFIRM_E */
19014
0
                ret = ASN_SIG_CONFIRM_E;
19015
0
                WOLFSSL_ERROR_VERBOSE(ret);
19016
0
                goto exit_cs;
19017
0
            }
19018
19019
0
            sigCtx->state = SIG_STATE_CHECK;
19020
0
        } /* SIG_STATE_DO */
19021
0
        FALL_THROUGH;
19022
19023
0
        case SIG_STATE_CHECK:
19024
0
        {
19025
0
            switch (keyOID) {
19026
0
            #ifndef NO_RSA
19027
0
                case RSAk:
19028
0
                #ifdef WC_RSA_PSS
19029
0
                case RSAPSSk:
19030
0
                if (sigOID == RSAPSSk) {
19031
                #if (defined(HAVE_SELFTEST) && \
19032
                     (!defined(HAVE_SELFTEST_VERSION) || \
19033
                      (HAVE_SELFTEST_VERSION < 2))) || \
19034
                    (defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \
19035
                     (HAVE_FIPS_VERSION < 2))
19036
                    ret = wc_RsaPSS_CheckPadding_ex(sigCtx->digest,
19037
                        sigCtx->digestSz, sigCtx->out, ret, sigCtx->hash,
19038
                        sigCtx->saltLen);
19039
                #elif (defined(HAVE_SELFTEST) && \
19040
                       (HAVE_SELFTEST_VERSION == 2)) || \
19041
                      (defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \
19042
                       (HAVE_FIPS_VERSION == 2))
19043
                    ret = wc_RsaPSS_CheckPadding_ex(sigCtx->digest,
19044
                        sigCtx->digestSz, sigCtx->out, ret, sigCtx->hash,
19045
                        sigCtx->saltLen, 0);
19046
                #else
19047
0
                    ret = wc_RsaPSS_CheckPadding_ex2(sigCtx->digest,
19048
0
                        (word32)sigCtx->digestSz, sigCtx->out, (word32)ret, sigCtx->hash,
19049
0
                        sigCtx->saltLen, wc_RsaEncryptSize(sigCtx->key.rsa) * 8,
19050
0
                        sigCtx->heap);
19051
0
                #endif
19052
0
                    break;
19053
0
                }
19054
0
                else
19055
0
                #endif
19056
0
                {
19057
0
                    int encodedSigSz, verifySz;
19058
                #if defined(WOLFSSL_RENESAS_TSIP_TLS) || \
19059
                                            defined(WOLFSSL_RENESAS_FSPSM_TLS)
19060
                    if (sigCtx->CertAtt.verifyByTSIP_SCE == 1) break;
19061
                #endif
19062
                #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
19063
                    byte* encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ,
19064
                                        sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
19065
                    if (encodedSig == NULL) {
19066
                        ERROR_OUT(MEMORY_E, exit_cs);
19067
                    }
19068
                #else
19069
0
                    byte encodedSig[MAX_ENCODED_SIG_SZ];
19070
0
                #endif
19071
19072
0
                    verifySz = ret;
19073
19074
                    /* make sure we're right justified */
19075
0
                    encodedSigSz = (int)wc_EncodeSignature(encodedSig,
19076
0
                            sigCtx->digest, (word32)sigCtx->digestSz,
19077
0
                            sigCtx->typeH);
19078
0
                    if (encodedSigSz == verifySz && sigCtx->out != NULL &&
19079
0
                        XMEMCMP(sigCtx->out, encodedSig,
19080
0
                            (size_t)encodedSigSz) == 0) {
19081
0
                        ret = 0;
19082
0
                    }
19083
0
                    else {
19084
0
                        WOLFSSL_MSG("RSA SSL verify match encode error");
19085
0
                        ret = ASN_SIG_CONFIRM_E;
19086
0
                        WOLFSSL_ERROR_VERBOSE(ret);
19087
0
                    }
19088
19089
                #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
19090
                    XFREE(encodedSig, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
19091
                #endif
19092
0
                    break;
19093
0
                }
19094
0
            #endif /* NO_RSA */
19095
            #if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
19096
                case DSAk:
19097
                {
19098
                    if (sigCtx->verify == 1) {
19099
                        ret = 0;
19100
                    }
19101
                    else {
19102
                        WOLFSSL_MSG("DSA Verify didn't match");
19103
                        ret = ASN_SIG_CONFIRM_E;
19104
                        WOLFSSL_ERROR_VERBOSE(ret);
19105
                    }
19106
                    break;
19107
                }
19108
            #endif /* !NO_DSA && !HAVE_SELFTEST */
19109
0
            #ifdef HAVE_ECC
19110
            #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
19111
                case SM2k:
19112
            #endif
19113
0
                case ECDSAk:
19114
0
                {
19115
0
                    if (sigCtx->verify == 1) {
19116
0
                        ret = 0;
19117
0
                    }
19118
0
                    else {
19119
0
                        WOLFSSL_MSG("ECC Verify didn't match");
19120
0
                        ret = ASN_SIG_CONFIRM_E;
19121
0
                        WOLFSSL_ERROR_VERBOSE(ret);
19122
0
                    }
19123
0
                    break;
19124
0
                }
19125
0
            #endif /* HAVE_ECC */
19126
            #ifdef HAVE_ED25519
19127
                case ED25519k:
19128
                {
19129
                    if (sigCtx->verify == 1) {
19130
                        ret = 0;
19131
                    }
19132
                    else {
19133
                        WOLFSSL_MSG("ED25519 Verify didn't match");
19134
                        ret = ASN_SIG_CONFIRM_E;
19135
                        WOLFSSL_ERROR_VERBOSE(ret);
19136
                    }
19137
                    break;
19138
                }
19139
            #endif /* HAVE_ED25519 */
19140
            #ifdef HAVE_ED448
19141
                case ED448k:
19142
                {
19143
                    if (sigCtx->verify == 1) {
19144
                        ret = 0;
19145
                    }
19146
                    else {
19147
                        WOLFSSL_MSG("ED448 Verify didn't match");
19148
                        ret = ASN_SIG_CONFIRM_E;
19149
                        WOLFSSL_ERROR_VERBOSE(ret);
19150
                    }
19151
                    break;
19152
                }
19153
            #endif /* HAVE_ED448 */
19154
            #ifdef HAVE_FALCON
19155
                case FALCON_LEVEL1k:
19156
                {
19157
                    if (sigCtx->verify == 1) {
19158
                        ret = 0;
19159
                    }
19160
                    else {
19161
                        WOLFSSL_MSG("FALCON_LEVEL1 Verify didn't match");
19162
                        ret = ASN_SIG_CONFIRM_E;
19163
                        WOLFSSL_ERROR_VERBOSE(ret);
19164
                    }
19165
                    break;
19166
                }
19167
                case FALCON_LEVEL5k:
19168
                {
19169
                    if (sigCtx->verify == 1) {
19170
                        ret = 0;
19171
                    }
19172
                    else {
19173
                        WOLFSSL_MSG("FALCON_LEVEL5 Verify didn't match");
19174
                        ret = ASN_SIG_CONFIRM_E;
19175
                        WOLFSSL_ERROR_VERBOSE(ret);
19176
                    }
19177
                    break;
19178
                }
19179
            #endif /* HAVE_FALCON */
19180
            #ifdef HAVE_DILITHIUM
19181
                #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
19182
                case DILITHIUM_LEVEL2k:
19183
                case DILITHIUM_LEVEL3k:
19184
                case DILITHIUM_LEVEL5k:
19185
                #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */
19186
                case ML_DSA_LEVEL2k:
19187
                case ML_DSA_LEVEL3k:
19188
                case ML_DSA_LEVEL5k:
19189
                    if (sigCtx->verify == 1) {
19190
                        ret = 0;
19191
                    }
19192
                    else {
19193
                        WOLFSSL_MSG("DILITHIUM Verify didn't match");
19194
                        ret = ASN_SIG_CONFIRM_E;
19195
                    }
19196
                    break;
19197
            #endif /* HAVE_DILITHIUM */
19198
            #ifdef HAVE_SPHINCS
19199
                case SPHINCS_FAST_LEVEL1k:
19200
                {
19201
                    if (sigCtx->verify == 1) {
19202
                        ret = 0;
19203
                    }
19204
                    else {
19205
                        WOLFSSL_MSG("SPHINCS_FAST_LEVEL1 Verify didn't match");
19206
                        ret = ASN_SIG_CONFIRM_E;
19207
                    }
19208
                    break;
19209
                }
19210
                case SPHINCS_FAST_LEVEL3k:
19211
                {
19212
                    if (sigCtx->verify == 1) {
19213
                        ret = 0;
19214
                    }
19215
                    else {
19216
                        WOLFSSL_MSG("SPHINCS_FAST_LEVEL3 Verify didn't match");
19217
                        ret = ASN_SIG_CONFIRM_E;
19218
                    }
19219
                    break;
19220
                }
19221
                case SPHINCS_FAST_LEVEL5k:
19222
                {
19223
                    if (sigCtx->verify == 1) {
19224
                        ret = 0;
19225
                    }
19226
                    else {
19227
                        WOLFSSL_MSG("SPHINCS_FAST_LEVEL5 Verify didn't match");
19228
                        ret = ASN_SIG_CONFIRM_E;
19229
                    }
19230
                    break;
19231
                }
19232
                case SPHINCS_SMALL_LEVEL1k:
19233
                {
19234
                    if (sigCtx->verify == 1) {
19235
                        ret = 0;
19236
                    }
19237
                    else {
19238
                        WOLFSSL_MSG("SPHINCS_SMALL_LEVEL1 Verify didn't match");
19239
                        ret = ASN_SIG_CONFIRM_E;
19240
                    }
19241
                    break;
19242
                }
19243
                case SPHINCS_SMALL_LEVEL3k:
19244
                {
19245
                    if (sigCtx->verify == 1) {
19246
                        ret = 0;
19247
                    }
19248
                    else {
19249
                        WOLFSSL_MSG("SPHINCS_SMALL_LEVEL3 Verify didn't match");
19250
                        ret = ASN_SIG_CONFIRM_E;
19251
                    }
19252
                    break;
19253
                }
19254
                case SPHINCS_SMALL_LEVEL5k:
19255
                {
19256
                    if (sigCtx->verify == 1) {
19257
                        ret = 0;
19258
                    }
19259
                    else {
19260
                        WOLFSSL_MSG("SPHINCS_SMALL_LEVEL5 Verify didn't match");
19261
                        ret = ASN_SIG_CONFIRM_E;
19262
                    }
19263
                    break;
19264
                }
19265
            #endif /* HAVE_SPHINCS */
19266
0
                default:
19267
0
                    break;
19268
0
            }  /* switch (keyOID) */
19269
19270
0
            break;
19271
0
        } /* SIG_STATE_CHECK */
19272
19273
0
        default:
19274
0
            break;
19275
0
    } /* switch (sigCtx->state) */
19276
19277
0
exit_cs:
19278
19279
#else
19280
    /* For NO_ASN_CRYPT return "not compiled in" */
19281
    ret = NOT_COMPILED_IN;
19282
#endif /* !NO_ASN_CRYPT */
19283
19284
0
    (void)keyOID;
19285
0
    (void)sigOID;
19286
19287
0
    WOLFSSL_LEAVE("ConfirmSignature", ret);
19288
19289
#ifdef WOLFSSL_ASYNC_CRYPT
19290
    if (ret == WC_NO_ERR_TRACE(WC_PENDING_E))
19291
        return ret;
19292
#endif
19293
19294
0
    FreeSignatureCtx(sigCtx);
19295
19296
0
    return ret;
19297
0
}
19298
19299
#ifndef IGNORE_NAME_CONSTRAINTS
19300
19301
static int MatchBaseName(int type, const char* name, int nameSz,
19302
                         const char* base, int baseSz)
19303
0
{
19304
0
    if (base == NULL || baseSz <= 0 || name == NULL || nameSz <= 0 ||
19305
0
            name[0] == '.' || nameSz < baseSz ||
19306
0
            (type != ASN_RFC822_TYPE && type != ASN_DNS_TYPE &&
19307
0
             type != ASN_DIR_TYPE)) {
19308
0
        return 0;
19309
0
    }
19310
19311
0
    if (type == ASN_DIR_TYPE)
19312
0
        return XMEMCMP(name, base, (size_t)baseSz) == 0;
19313
19314
    /* If an email type, handle special cases where the base is only
19315
     * a domain, or is an email address itself. */
19316
0
    if (type == ASN_RFC822_TYPE) {
19317
0
        const char* p = NULL;
19318
0
        int count = 0;
19319
19320
0
        if (base[0] != '.') {
19321
0
            p = base;
19322
0
            count = 0;
19323
19324
            /* find the '@' in the base */
19325
0
            while (*p != '@' && count < baseSz) {
19326
0
                count++;
19327
0
                p++;
19328
0
            }
19329
19330
            /* No '@' in base, reset p to NULL */
19331
0
            if (count >= baseSz)
19332
0
                p = NULL;
19333
0
        }
19334
19335
0
        if (p == NULL) {
19336
            /* Base isn't an email address, it is a domain name,
19337
             * wind the name forward one character past its '@'. */
19338
0
            p = name;
19339
0
            count = 0;
19340
0
            while (*p != '@' && count < baseSz) {
19341
0
                count++;
19342
0
                p++;
19343
0
            }
19344
19345
0
            if (count < baseSz && *p == '@') {
19346
0
                name = p + 1;
19347
0
                nameSz -= count + 1;
19348
0
            }
19349
0
        }
19350
0
    }
19351
19352
    /* RFC 5280 section 4.2.1.10
19353
     * "...Any DNS name that can be constructed by simply adding zero or more
19354
     *  labels to the left-hand side of the name satisfies the name constraint."
19355
     * i.e www.host.example.com works for host.example.com name constraint and
19356
     * host1.example.com does not. */
19357
0
    if (type == ASN_DNS_TYPE || (type == ASN_RFC822_TYPE && base[0] == '.')) {
19358
0
        int szAdjust = nameSz - baseSz;
19359
0
        name += szAdjust;
19360
0
        nameSz -= szAdjust;
19361
0
    }
19362
19363
0
    while (nameSz > 0) {
19364
0
        if (XTOLOWER((unsigned char)*name) !=
19365
0
                                               XTOLOWER((unsigned char)*base))
19366
0
            return 0;
19367
0
        name++;
19368
0
        base++;
19369
0
        nameSz--;
19370
0
    }
19371
19372
0
    return 1;
19373
0
}
19374
19375
19376
/* Search through the list to find if the name is permitted.
19377
 * name     The DNS name to search for
19378
 * dnsList  The list to search through
19379
 * nameType Type of DNS name to currently searching
19380
 * return 1 if found in list or if not needed
19381
 * return 0 if not found in the list but is needed
19382
 */
19383
static int PermittedListOk(DNS_entry* name, Base_entry* dnsList, byte nameType)
19384
0
{
19385
0
    Base_entry* current = dnsList;
19386
0
    int match = 0;
19387
0
    int need  = 0;
19388
0
    int ret   = 1; /* is ok unless needed and no match found */
19389
19390
0
    while (current != NULL) {
19391
0
        if (current->type == nameType) {
19392
0
            need = 1; /* restriction on permitted names is set for this type */
19393
0
            if (name->len >= current->nameSz &&
19394
0
                MatchBaseName(nameType, name->name, name->len,
19395
0
                              current->name, current->nameSz)) {
19396
0
                match = 1; /* found the current name in the permitted list*/
19397
0
                break;
19398
0
            }
19399
0
        }
19400
0
        current = current->next;
19401
0
    }
19402
19403
    /* check if permitted name restriction was set and no matching name found */
19404
0
    if (need && !match)
19405
0
        ret = 0;
19406
19407
0
    return ret;
19408
0
}
19409
19410
19411
/* Search through the list to find if the name is excluded.
19412
 * name     The DNS name to search for
19413
 * dnsList  The list to search through
19414
 * nameType Type of DNS name to currently searching
19415
 * return 1 if found in list and 0 if not found in the list
19416
 */
19417
static int IsInExcludedList(DNS_entry* name, Base_entry* dnsList, byte nameType)
19418
0
{
19419
0
    int ret = 0; /* default of not found in the list */
19420
0
    Base_entry* current = dnsList;
19421
19422
0
    while (current != NULL) {
19423
0
        if (current->type == nameType) {
19424
0
            if (name->len >= current->nameSz &&
19425
0
                MatchBaseName(nameType, name->name, name->len,
19426
0
                              current->name, current->nameSz)) {
19427
0
                ret = 1;
19428
0
                break;
19429
0
            }
19430
0
        }
19431
0
        current = current->next;
19432
0
    }
19433
19434
0
    return ret;
19435
0
}
19436
19437
19438
static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
19439
0
{
19440
0
    const byte nameTypes[] = {ASN_RFC822_TYPE, ASN_DNS_TYPE, ASN_DIR_TYPE};
19441
0
    int i;
19442
19443
0
    if (signer == NULL || cert == NULL)
19444
0
        return 0;
19445
19446
0
    if (signer->excludedNames == NULL && signer->permittedNames == NULL)
19447
0
        return 1;
19448
19449
0
    for (i=0; i < (int)sizeof(nameTypes); i++) {
19450
0
        byte nameType = nameTypes[i];
19451
0
        DNS_entry* name = NULL;
19452
0
        DNS_entry  subjectDnsName; /* temporary node used for subject name */
19453
19454
0
        XMEMSET(&subjectDnsName, 0, sizeof(DNS_entry));
19455
0
        switch (nameType) {
19456
0
            case ASN_DNS_TYPE:
19457
                /* Should it also consider CN in subject? It could use
19458
                 * subjectDnsName too */
19459
0
                name = cert->altNames;
19460
0
                break;
19461
0
            case ASN_RFC822_TYPE:
19462
                /* Shouldn't it validate E= in subject as well? */
19463
0
                name = cert->altEmailNames;
19464
19465
                /* Add subject email for checking. */
19466
0
                if (cert->subjectEmail != NULL) {
19467
                    /* RFC 5280 section 4.2.1.10
19468
                     * "When constraints are imposed on the rfc822Name name
19469
                     * form, but the certificate does not include a subject
19470
                     * alternative name, the rfc822Name constraint MUST be
19471
                     * applied to the attribute of type emailAddress in the
19472
                     * subject distinguished name" */
19473
0
                    subjectDnsName.next = NULL;
19474
0
                    subjectDnsName.type = ASN_RFC822_TYPE;
19475
0
                    subjectDnsName.len  = cert->subjectEmailLen;
19476
0
                    subjectDnsName.name = (char *)cert->subjectEmail;
19477
0
                }
19478
0
                break;
19479
0
            case ASN_DIR_TYPE:
19480
0
            #ifndef WOLFSSL_NO_ASN_STRICT
19481
0
                name = cert->altDirNames;
19482
0
            #endif
19483
19484
                /* RFC 5280 section 4.2.1.10
19485
                    "Restrictions of the form directoryName MUST be
19486
                    applied to the subject field .... and to any names
19487
                    of type directoryName in the subjectAltName
19488
                    extension"
19489
                */
19490
0
                if (cert->subjectRaw != NULL) {
19491
0
                    subjectDnsName.next = NULL;
19492
0
                    subjectDnsName.type = ASN_DIR_TYPE;
19493
0
                    subjectDnsName.len = cert->subjectRawLen;
19494
0
                    subjectDnsName.name = (char *)cert->subjectRaw;
19495
0
                }
19496
0
                break;
19497
0
            default:
19498
                /* Other types of names are ignored for now.
19499
                 * Shouldn't it be rejected if it there is a altNamesByType[nameType]
19500
                 * and signer->extNameConstraintCrit is set? */
19501
0
                return 0;
19502
0
        }
19503
19504
0
        while (name != NULL) {
19505
0
            if (IsInExcludedList(name, signer->excludedNames, nameType) == 1) {
19506
0
                WOLFSSL_MSG("Excluded name was found!");
19507
0
                return 0;
19508
0
            }
19509
19510
            /* Check against the permitted list */
19511
0
            if (PermittedListOk(name, signer->permittedNames, nameType) != 1) {
19512
0
                WOLFSSL_MSG("Permitted name was not found!");
19513
0
                return 0;
19514
0
            }
19515
19516
0
            name = name->next;
19517
0
        }
19518
19519
        /* handle comparing against subject name too */
19520
0
        if (subjectDnsName.len > 0 && subjectDnsName.name != NULL) {
19521
0
            if (IsInExcludedList(&subjectDnsName, signer->excludedNames,
19522
0
                        nameType) == 1) {
19523
0
                WOLFSSL_MSG("Excluded name was found!");
19524
0
                return 0;
19525
0
            }
19526
19527
            /* Check against the permitted list */
19528
0
            if (PermittedListOk(&subjectDnsName, signer->permittedNames,
19529
0
                        nameType) != 1) {
19530
0
                WOLFSSL_MSG("Permitted name was not found!");
19531
0
                return 0;
19532
0
            }
19533
0
        }
19534
0
    }
19535
19536
0
    return 1;
19537
0
}
19538
19539
#endif /* IGNORE_NAME_CONSTRAINTS */
19540
19541
#ifndef WOLFSSL_ASN_TEMPLATE
19542
static void AddAltName(DecodedCert* cert, DNS_entry* dnsEntry)
19543
{
19544
#if (defined(WOLFSSL_ASN_ALL) || defined(OPENSSL_EXTRA)) && \
19545
    !defined(WOLFSSL_ALT_NAMES_NO_REV)
19546
    /* logic to add alt name to end of list */
19547
    dnsEntry->next = NULL;
19548
    if (cert->altNames == NULL) {
19549
        /* First on list */
19550
        cert->altNames = dnsEntry;
19551
    }
19552
    else {
19553
        DNS_entry* temp = cert->altNames;
19554
19555
        /* Find end */
19556
        for (; (temp->next != NULL); temp = temp->next);
19557
19558
        /* Add to end */
19559
        temp->next = dnsEntry;
19560
    }
19561
#else
19562
    dnsEntry->next = cert->altNames;
19563
    cert->altNames = dnsEntry;
19564
#endif
19565
}
19566
#endif
19567
19568
#ifdef WOLFSSL_ASN_TEMPLATE
19569
#if defined(WOLFSSL_SEP) || defined(WOLFSSL_FPKI)
19570
/* ASN.1 template for OtherName of an X.509 certificate.
19571
 * X.509: RFC 5280, 4.2.1.6 - OtherName (without implicit outer SEQUENCE).
19572
 * HW Name: RFC 4108, 5 - Hardware Module Name
19573
 * Only support HW Name where the type is a HW serial number.
19574
 *
19575
 * Other Names handled for FPKI (Federal PKI) use:
19576
 * UPN (Universal Principal Name), a non-standard Other Name
19577
 *  (RFC3280 sec 4.2.1.7). Often used with FIPS 201 smartcard login.
19578
 * FASC-N (Federal Agency Smart Credential Number), defined in the document
19579
 *  fpki-x509-cert-policy-common.pdf. Used for a smart card ID.
19580
 */
19581
static const ASNItem otherNameASN[] = {
19582
/* TYPEID   */ { 0, ASN_OBJECT_ID, 0, 0, 0 },
19583
/* VALUE    */ { 0, ASN_CONTEXT_SPECIFIC | ASN_OTHERNAME_VALUE, 1, 1, 0 },
19584
/* UPN      */     { 1, ASN_UTF8STRING, 0, 0, 2 },
19585
/* FASC-N   */     { 1, ASN_OCTET_STRING, 0, 0, 2 },
19586
/* HWN_SEQ  */     { 1, ASN_SEQUENCE, 1, 0, 2 },
19587
/* HWN_TYPE */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
19588
/* HWN_NUM  */         { 2, ASN_OCTET_STRING, 0, 0, 0 }
19589
};
19590
enum {
19591
    OTHERNAMEASN_IDX_TYPEID = 0,
19592
    OTHERNAMEASN_IDX_VALUE,
19593
    OTHERNAMEASN_IDX_UPN,
19594
    OTHERNAMEASN_IDX_FASCN,
19595
    OTHERNAMEASN_IDX_HWN_SEQ,
19596
    OTHERNAMEASN_IDX_HWN_TYPE,
19597
    OTHERNAMEASN_IDX_HWN_NUM
19598
};
19599
19600
/* Number of items in ASN.1 template for OtherName of an X.509 certificate. */
19601
#define otherNameASN_Length (sizeof(otherNameASN) / sizeof(ASNItem))
19602
19603
#ifdef WOLFSSL_SEP
19604
static int DecodeSEP(ASNGetData* dataASN, DecodedCert* cert)
19605
{
19606
    int ret = 0;
19607
    word32 oidLen, serialLen;
19608
19609
    oidLen = dataASN[OTHERNAMEASN_IDX_HWN_TYPE].data.oid.length;
19610
    serialLen = dataASN[OTHERNAMEASN_IDX_HWN_NUM].data.ref.length;
19611
19612
    /* Allocate space for HW type OID. */
19613
    cert->hwType = (byte*)XMALLOC(oidLen, cert->heap,
19614
                                  DYNAMIC_TYPE_X509_EXT);
19615
    if (cert->hwType == NULL)
19616
        ret = MEMORY_E;
19617
19618
    if (ret == 0) {
19619
        /* Copy, into cert HW type OID */
19620
        XMEMCPY(cert->hwType,
19621
                dataASN[OTHERNAMEASN_IDX_HWN_TYPE].data.oid.data, oidLen);
19622
        cert->hwTypeSz = (int)oidLen;
19623
        /* TODO: check this is the HW serial number OID - no test data. */
19624
19625
        /* Allocate space for HW serial number, +1 for null terminator. */
19626
        cert->hwSerialNum = (byte*)XMALLOC(serialLen + 1, cert->heap,
19627
                                           DYNAMIC_TYPE_X509_EXT);
19628
        if (cert->hwSerialNum == NULL) {
19629
            WOLFSSL_MSG("\tOut of Memory");
19630
            ret = MEMORY_E;
19631
        }
19632
    }
19633
    if (ret == 0) {
19634
        /* Copy into cert HW serial number. */
19635
        XMEMCPY(cert->hwSerialNum,
19636
                dataASN[OTHERNAMEASN_IDX_HWN_NUM].data.ref.data, serialLen);
19637
        cert->hwSerialNum[serialLen] = '\0';
19638
        cert->hwSerialNumSz = (int)serialLen;
19639
    }
19640
    return ret;
19641
}
19642
#endif /* WOLFSSL_SEP */
19643
19644
static int DecodeOtherHelper(ASNGetData* dataASN, DecodedCert* cert, int oid)
19645
{
19646
    DNS_entry* entry = NULL;
19647
    int ret = 0;
19648
    word32 bufLen   = 0;
19649
    const char* buf = NULL;
19650
19651
    switch (oid) {
19652
#ifdef WOLFSSL_FPKI
19653
        case FASCN_OID:
19654
            bufLen = dataASN[OTHERNAMEASN_IDX_FASCN].data.ref.length;
19655
            buf    = (const char*)dataASN[OTHERNAMEASN_IDX_FASCN].data.ref.data;
19656
            break;
19657
#endif /* WOLFSSL_FPKI */
19658
        case UPN_OID:
19659
            bufLen = dataASN[OTHERNAMEASN_IDX_UPN].data.ref.length;
19660
            buf    = (const char*)dataASN[OTHERNAMEASN_IDX_UPN].data.ref.data;
19661
            break;
19662
        default:
19663
            WOLFSSL_ERROR_VERBOSE(ASN_UNKNOWN_OID_E);
19664
            ret = ASN_UNKNOWN_OID_E;
19665
            break;
19666
    }
19667
19668
    if (ret == 0) {
19669
        ret = SetDNSEntry(cert->heap, buf, (int)bufLen, ASN_OTHER_TYPE, &entry);
19670
        if (ret == 0) {
19671
        #ifdef WOLFSSL_FPKI
19672
            entry->oidSum = oid;
19673
        #endif
19674
            AddDNSEntryToList(&cert->altNames, entry);
19675
        }
19676
    }
19677
    return ret;
19678
}
19679
19680
/* Decode data with OtherName format from after implicit SEQUENCE.
19681
 *
19682
 * @param [in, out] cert      Certificate object.
19683
 * @param [in]      input     Buffer containing encoded OtherName.
19684
 * @param [in, out] inOutIdx  On in, the index of the start of the OtherName.
19685
 *                            On out, index after OtherName.
19686
 * @param [in]      maxIdx    Maximum index of data in buffer.
19687
 * @return  0 on success.
19688
 * @return  MEMORY_E on dynamic memory allocation failure.
19689
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
19690
 *          is invalid.
19691
 * @return  ASN_PARSE_E when OID does is not HW Name.
19692
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
19693
 * @return  BUFFER_E when data in buffer is too small.
19694
 */
19695
static int DecodeOtherName(DecodedCert* cert, const byte* input,
19696
                           word32* inOutIdx, int len)
19697
{
19698
    DECL_ASNGETDATA(dataASN, otherNameASN_Length);
19699
    int ret = 0;
19700
    word32 maxIdx = *inOutIdx + (word32)len;
19701
    const char* name = (const char*)input + *inOutIdx;
19702
19703
    CALLOC_ASNGETDATA(dataASN, otherNameASN_Length, ret, cert->heap);
19704
19705
    if (ret == 0) {
19706
        /* Check the first OID is a recognized Alt Cert Name type. */
19707
        GetASN_OID(&dataASN[OTHERNAMEASN_IDX_TYPEID], oidCertAltNameType);
19708
        /* Parse OtherName. */
19709
        ret = GetASN_Items(otherNameASN, dataASN, otherNameASN_Length, 1, input,
19710
                           inOutIdx, maxIdx);
19711
    }
19712
    if (ret == 0) {
19713
        /* Ensure expected OID. */
19714
        switch (dataASN[OTHERNAMEASN_IDX_TYPEID].data.oid.sum) {
19715
        #ifdef WOLFSSL_SEP
19716
            case HW_NAME_OID:
19717
                /* Only support HW serial number. */
19718
                GetASN_OID(&dataASN[OTHERNAMEASN_IDX_HWN_TYPE], oidIgnoreType);
19719
                ret = DecodeSEP(dataASN, cert);
19720
                break;
19721
        #endif /* WOLFSSL_SEP */
19722
        #ifdef WOLFSSL_FPKI
19723
            case FASCN_OID:
19724
        #endif /* WOLFSSL_FPKI */
19725
            case UPN_OID:
19726
                ret = DecodeOtherHelper(dataASN, cert,
19727
                           (int)dataASN[OTHERNAMEASN_IDX_TYPEID].data.oid.sum);
19728
                break;
19729
            default:
19730
                WOLFSSL_MSG("\tadding unsupported OID");
19731
                ret = SetDNSEntry(cert->heap, name, len, ASN_OTHER_TYPE,
19732
                        &cert->altNames);
19733
                break;
19734
        }
19735
    }
19736
19737
    FREE_ASNGETDATA(dataASN, cert->heap);
19738
    return ret;
19739
}
19740
#endif /* WOLFSSL_SEP || WOLFSSL_FPKI */
19741
19742
/* Decode a GeneralName.
19743
 *
19744
 * @param [in]      input     Buffer containing encoded OtherName.
19745
 * @param [in, out] inOutIdx  On in, the index of the start of the OtherName.
19746
 *                            On out, index after OtherName.
19747
 * @param [in]      len       Length of data in buffer.
19748
 * @param [in]      cert      Decoded certificate object.
19749
 * @return  0 on success.
19750
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
19751
 *          is invalid.
19752
 * @return  BUFFER_E when data in buffer is too small.
19753
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
19754
 * @return  MEMORY_E when dynamic memory allocation fails.
19755
 */
19756
static int DecodeGeneralName(const byte* input, word32* inOutIdx, byte tag,
19757
                             int len, DecodedCert* cert)
19758
0
{
19759
0
    int ret = 0;
19760
0
    word32 idx = *inOutIdx;
19761
19762
    /* GeneralName choice: dnsName */
19763
0
    if (tag == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) {
19764
0
        ret = SetDNSEntry(cert->heap, (const char*)(input + idx), len,
19765
0
                ASN_DNS_TYPE, &cert->altNames);
19766
0
        if (ret == 0) {
19767
0
            idx += (word32)len;
19768
0
        }
19769
0
    }
19770
0
#ifndef IGNORE_NAME_CONSTRAINTS
19771
    /* GeneralName choice: directoryName */
19772
0
    else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_DIR_TYPE)) {
19773
0
        int strLen;
19774
0
        word32 idxDir = idx;
19775
19776
        /* Expecting a SEQUENCE using up all data. */
19777
0
        if (GetASN_Sequence(input, &idxDir, &strLen, idx + (word32)len, 1) < 0)
19778
0
        {
19779
0
            WOLFSSL_MSG("\tfail: seq length");
19780
0
            return ASN_PARSE_E;
19781
0
        }
19782
19783
0
        ret = SetDNSEntry(cert->heap, (const char*)(input + idxDir), strLen,
19784
0
                ASN_DIR_TYPE, &cert->altDirNames);
19785
0
        if (ret == 0) {
19786
0
            idx += (word32)len;
19787
0
        }
19788
0
    }
19789
    /* GeneralName choice: rfc822Name */
19790
0
    else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE)) {
19791
0
        ret = SetDNSEntry(cert->heap, (const char*)(input + idx), len,
19792
0
                ASN_RFC822_TYPE, &cert->altEmailNames);
19793
0
        if (ret == 0) {
19794
0
            idx += (word32)len;
19795
0
        }
19796
0
    }
19797
    /* GeneralName choice: uniformResourceIdentifier */
19798
0
    else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_URI_TYPE)) {
19799
0
        WOLFSSL_MSG("\tPutting URI into list but not using");
19800
19801
0
    #if !defined(WOLFSSL_NO_ASN_STRICT) && !defined(WOLFSSL_FPKI)
19802
        /* Verify RFC 5280 Sec 4.2.1.6 rule:
19803
            "The name MUST NOT be a relative URI"
19804
            As per RFC 3986 Sec 4.3, an absolute URI is only required to contain
19805
            a scheme and hier-part.  So the only strict requirement is a ':'
19806
            being present after the scheme.  If a '/' is present as part of the
19807
            hier-part, it must come after the ':' (see RFC 3986 Sec 3). */
19808
0
        {
19809
0
            int i;
19810
19811
            /* skip past scheme (i.e http,ftp,...) finding first ':' char */
19812
0
            for (i = 0; i < len; i++) {
19813
0
                if (input[idx + (word32)i] == ':') {
19814
0
                    break;
19815
0
                }
19816
0
                if (input[idx + (word32)i] == '/') {
19817
0
                    i = len; /* error, found relative path since '/' was
19818
                              * encountered before ':'. Returning error
19819
                              * value in next if statement. */
19820
0
                }
19821
0
            }
19822
19823
            /* test hier-part is empty */
19824
0
            if (i == 0 || i == len) {
19825
0
                WOLFSSL_MSG("\tEmpty or malformed URI");
19826
0
                WOLFSSL_ERROR_VERBOSE(ASN_ALT_NAME_E);
19827
0
                return ASN_ALT_NAME_E;
19828
0
            }
19829
19830
            /* test if scheme is missing  */
19831
0
            if (input[idx + (word32)i] != ':') {
19832
0
                WOLFSSL_MSG("\tAlt Name must be absolute URI");
19833
0
                WOLFSSL_ERROR_VERBOSE(ASN_ALT_NAME_E);
19834
0
                return ASN_ALT_NAME_E;
19835
0
            }
19836
0
        }
19837
0
    #endif
19838
19839
0
        ret = SetDNSEntry(cert->heap, (const char*)(input + idx), len,
19840
0
                ASN_URI_TYPE, &cert->altNames);
19841
0
        if (ret == 0) {
19842
0
            idx += (word32)len;
19843
0
        }
19844
0
    }
19845
    #ifdef WOLFSSL_IP_ALT_NAME
19846
    /* GeneralName choice: iPAddress */
19847
    else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_IP_TYPE)) {
19848
        ret = SetDNSEntry(cert->heap, (const char*)(input + idx), len,
19849
                ASN_IP_TYPE, &cert->altNames);
19850
        if (ret == 0) {
19851
            idx += (word32)len;
19852
        }
19853
    }
19854
    #endif /* WOLFSSL_IP_ALT_NAME */
19855
    #ifdef WOLFSSL_RID_ALT_NAME
19856
    /* GeneralName choice: registeredID */
19857
    else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_RID_TYPE)) {
19858
        ret = SetDNSEntry(cert->heap, (const char*)(input + idx), len,
19859
                ASN_RID_TYPE, &cert->altNames);
19860
        if (ret == 0) {
19861
            idx += (word32)len;
19862
        }
19863
    }
19864
    #endif /* WOLFSSL_RID_ALT_NAME */
19865
0
#endif /* IGNORE_NAME_CONSTRAINTS */
19866
#if defined(WOLFSSL_SEP) || defined(WOLFSSL_FPKI)
19867
    /* GeneralName choice: otherName */
19868
    else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE)) {
19869
        /* TODO: test data for code path */
19870
        ret = DecodeOtherName(cert, input, &idx, len);
19871
    }
19872
#endif
19873
    /* GeneralName choice: dNSName, x400Address, ediPartyName */
19874
0
    else {
19875
0
        WOLFSSL_MSG("\tUnsupported name type, skipping");
19876
0
        idx += (word32)len;
19877
0
    }
19878
19879
0
    if (ret == 0) {
19880
        /* Return index of next encoded byte. */
19881
0
        *inOutIdx = idx;
19882
0
    }
19883
0
    return ret;
19884
0
}
19885
19886
/* ASN.1 choices for GeneralName.
19887
 * X.509: RFC 5280, 4.2.1.6 - GeneralName.
19888
 */
19889
static const byte generalNameChoice[] = {
19890
    ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0,
19891
    ASN_CONTEXT_SPECIFIC                   | 1,
19892
    ASN_CONTEXT_SPECIFIC                   | 2,
19893
    ASN_CONTEXT_SPECIFIC                   | 3,
19894
    ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 4,
19895
    ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 5,
19896
    ASN_CONTEXT_SPECIFIC                   | 6,
19897
    ASN_CONTEXT_SPECIFIC                   | 7,
19898
    ASN_CONTEXT_SPECIFIC                   | 8,
19899
    0
19900
};
19901
19902
/* ASN.1 template for GeneralName.
19903
 * X.509: RFC 5280, 4.2.1.6 - GeneralName.
19904
 */
19905
static const ASNItem altNameASN[] = {
19906
    { 0, ASN_CONTEXT_SPECIFIC | 0, 0, 1, 0 }
19907
};
19908
enum {
19909
    ALTNAMEASN_IDX_GN = 0
19910
};
19911
19912
/* Number of items in ASN.1 template for GeneralName. */
19913
0
#define altNameASN_Length (sizeof(altNameASN) / sizeof(ASNItem))
19914
#endif /* WOLFSSL_ASN_TEMPLATE */
19915
19916
#if defined(WOLFSSL_SEP) && !defined(WOLFSSL_ASN_TEMPLATE)
19917
/* return 0 on success */
19918
static int DecodeSepHwAltName(DecodedCert* cert, const byte* input,
19919
    word32* idxIn, word32 sz)
19920
{
19921
    word32 idx = *idxIn;
19922
    int  strLen;
19923
    int  ret;
19924
    byte tag;
19925
19926
    /* Certificates issued with this OID in the subject alt name are for
19927
     * verifying signatures created on a module.
19928
     * RFC 4108 Section 5. */
19929
    if (cert->hwType != NULL) {
19930
        WOLFSSL_MSG("\tAlready seen Hardware Module Name");
19931
        return ASN_PARSE_E;
19932
    }
19933
19934
    if (GetASNTag(input, &idx, &tag, sz) < 0) {
19935
        return ASN_PARSE_E;
19936
    }
19937
19938
    if (tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
19939
        WOLFSSL_MSG("\twrong type");
19940
        return ASN_PARSE_E;
19941
    }
19942
19943
    if (GetLength(input, &idx, &strLen, sz) < 0) {
19944
        WOLFSSL_MSG("\tfail: str len");
19945
        return ASN_PARSE_E;
19946
    }
19947
19948
    if (GetSequence(input, &idx, &strLen, sz) < 0) {
19949
        WOLFSSL_MSG("\tBad Sequence");
19950
        return ASN_PARSE_E;
19951
    }
19952
19953
    ret = GetASNObjectId(input, &idx, &strLen, sz);
19954
    if (ret != 0) {
19955
        WOLFSSL_MSG("\tbad OID");
19956
        return ret;
19957
    }
19958
19959
    cert->hwType = (byte*)XMALLOC((size_t)strLen, cert->heap,
19960
                                  DYNAMIC_TYPE_X509_EXT);
19961
    if (cert->hwType == NULL) {
19962
        WOLFSSL_MSG("\tOut of Memory");
19963
        return MEMORY_E;
19964
    }
19965
19966
    XMEMCPY(cert->hwType, &input[idx], (size_t)strLen);
19967
    cert->hwTypeSz = strLen;
19968
    idx += (word32)strLen;
19969
19970
    ret = GetOctetString(input, &idx, &strLen, sz);
19971
    if (ret < 0) {
19972
        XFREE(cert->hwType, cert->heap, DYNAMIC_TYPE_X509_EXT);
19973
        cert->hwType = NULL;
19974
        return ret;
19975
    }
19976
19977
    cert->hwSerialNum = (byte*)XMALLOC((size_t)strLen + 1, cert->heap,
19978
                                       DYNAMIC_TYPE_X509_EXT);
19979
    if (cert->hwSerialNum == NULL) {
19980
        WOLFSSL_MSG("\tOut of Memory");
19981
        XFREE(cert->hwType, cert->heap, DYNAMIC_TYPE_X509_EXT);
19982
        cert->hwType = NULL;
19983
        return MEMORY_E;
19984
    }
19985
19986
    XMEMCPY(cert->hwSerialNum, &input[idx], (size_t)strLen);
19987
    cert->hwSerialNum[strLen] = '\0';
19988
    cert->hwSerialNumSz = strLen;
19989
    idx += (word32)strLen;
19990
19991
    *idxIn = idx;
19992
    return 0;
19993
}
19994
#endif /* WOLFSSL_SEP */
19995
19996
#if !defined(WOLFSSL_ASN_TEMPLATE)
19997
/* return 0 on success */
19998
static int DecodeConstructedOtherName(DecodedCert* cert, const byte* input,
19999
        word32* idx, word32 sz, int oid)
20000
{
20001
    int ret    = 0;
20002
    int strLen = 0;
20003
    byte tag;
20004
    DNS_entry* dnsEntry = NULL;
20005
20006
    if (GetASNTag(input, idx, &tag, sz) < 0) {
20007
        ret = ASN_PARSE_E;
20008
    }
20009
20010
    if (ret == 0 && (tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))) {
20011
        ret = ASN_PARSE_E;
20012
    }
20013
20014
    if (ret == 0 && (GetLength(input, idx, &strLen, sz) < 0)) {
20015
        ret = ASN_PARSE_E;
20016
    }
20017
20018
    if (ret == 0) {
20019
        dnsEntry = AltNameNew(cert->heap);
20020
        if (dnsEntry == NULL) {
20021
            WOLFSSL_MSG("\tOut of Memory");
20022
            return MEMORY_E;
20023
        }
20024
20025
        switch (oid) {
20026
        #ifdef WOLFSSL_FPKI
20027
            case FASCN_OID:
20028
                ret = GetOctetString(input, idx, &strLen, sz);
20029
                if (ret > 0) {
20030
                    ret = 0;
20031
                }
20032
                break;
20033
        #endif /* WOLFSSL_FPKI */
20034
            case UPN_OID:
20035
                if (GetASNTag(input, idx, &tag, sz) < 0) {
20036
                    ret = ASN_PARSE_E;
20037
                }
20038
20039
                if (ret == 0 &&
20040
                        tag != ASN_PRINTABLE_STRING && tag != ASN_UTF8STRING &&
20041
                                    tag != ASN_IA5_STRING) {
20042
                    WOLFSSL_MSG("Was expecting a string for UPN");
20043
                    ret = ASN_PARSE_E;
20044
                }
20045
20046
                if (ret == 0 && (GetLength(input, idx, &strLen, sz) < 0)) {
20047
                    WOLFSSL_MSG("Was expecting a string for UPN");
20048
                    ret = ASN_PARSE_E;
20049
                }
20050
                break;
20051
20052
            default:
20053
                WOLFSSL_MSG("Unknown constructed other name, skipping");
20054
                XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
20055
                dnsEntry = NULL;
20056
        }
20057
    }
20058
20059
    if (ret == 0 && dnsEntry != NULL) {
20060
        dnsEntry->type = ASN_OTHER_TYPE;
20061
        dnsEntry->len = strLen;
20062
        dnsEntry->name = (char*)XMALLOC((size_t)strLen + 1, cert->heap,
20063
            DYNAMIC_TYPE_ALTNAME);
20064
    #ifdef WOLFSSL_FPKI
20065
        dnsEntry->oidSum = oid;
20066
    #endif /* WOLFSSL_FPKI */
20067
        if (dnsEntry->name == NULL) {
20068
            WOLFSSL_MSG("\tOut of Memory");
20069
            ret = MEMORY_E;
20070
        }
20071
        else {
20072
            XMEMCPY(dnsEntry->name, &input[*idx], (size_t)strLen);
20073
            dnsEntry->name[strLen] = '\0';
20074
            AddAltName(cert, dnsEntry);
20075
        }
20076
    }
20077
20078
    if (ret == 0) {
20079
        *idx += (word32)strLen;
20080
    }
20081
    else {
20082
        XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
20083
    }
20084
20085
    return ret;
20086
}
20087
#endif
20088
20089
/* Decode subject alternative names extension.
20090
 *
20091
 * RFC 5280 4.2.1.6.  Subject Alternative Name
20092
 *
20093
 * @param [in]      input  Buffer holding encoded data.
20094
 * @param [in]      sz     Size of encoded data in bytes.
20095
 * @param [in, out] cert   Decoded certificate object.
20096
 * @return  0 on success.
20097
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
20098
 *          is invalid.
20099
 * @return  BUFFER_E when data in buffer is too small.
20100
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
20101
 * @return  MEMORY_E when dynamic memory allocation fails.
20102
 */
20103
static int DecodeAltNames(const byte* input, word32 sz, DecodedCert* cert)
20104
0
{
20105
#ifndef WOLFSSL_ASN_TEMPLATE
20106
    word32 idx = 0;
20107
    int length = 0;
20108
    word32 numNames = 0;
20109
20110
    WOLFSSL_ENTER("DecodeAltNames");
20111
20112
    if (GetSequence(input, &idx, &length, sz) < 0) {
20113
        WOLFSSL_MSG("\tBad Sequence");
20114
        return ASN_PARSE_E;
20115
    }
20116
20117
    if (length == 0) {
20118
        /* RFC 5280 4.2.1.6.  Subject Alternative Name
20119
           If the subjectAltName extension is present, the sequence MUST
20120
           contain at least one entry. */
20121
        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
20122
        return ASN_PARSE_E;
20123
    }
20124
20125
#ifdef OPENSSL_ALL
20126
    cert->extSubjAltNameSrc = input;
20127
    cert->extSubjAltNameSz = sz;
20128
#endif
20129
20130
    cert->weOwnAltNames = 1;
20131
20132
    while (length > 0) {
20133
        byte current_byte;
20134
20135
        /* Verify idx can't overflow input buffer */
20136
        if (idx >= (word32)sz) {
20137
            WOLFSSL_MSG("\tBad Index");
20138
            return BUFFER_E;
20139
        }
20140
20141
        numNames++;
20142
        if (numNames > WOLFSSL_MAX_ALT_NAMES) {
20143
            WOLFSSL_MSG("\tToo many subject alternative names");
20144
            return ASN_ALT_NAME_E;
20145
        }
20146
20147
        current_byte = input[idx++];
20148
        length--;
20149
20150
        /* Save DNS Type names in the altNames list. */
20151
        /* Save Other Type names in the cert's OidMap */
20152
        if (current_byte == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) {
20153
            DNS_entry* dnsEntry;
20154
            int strLen;
20155
            word32 lenStartIdx = idx;
20156
20157
            if (GetLength(input, &idx, &strLen, sz) < 0) {
20158
                WOLFSSL_MSG("\tfail: str length");
20159
                return ASN_PARSE_E;
20160
            }
20161
            length -= (int)(idx - lenStartIdx);
20162
20163
            dnsEntry = AltNameNew(cert->heap);
20164
            if (dnsEntry == NULL) {
20165
                WOLFSSL_MSG("\tOut of Memory");
20166
                return MEMORY_E;
20167
            }
20168
20169
            dnsEntry->type = ASN_DNS_TYPE;
20170
            dnsEntry->name = (char*)XMALLOC((size_t)strLen + 1, cert->heap,
20171
                                         DYNAMIC_TYPE_ALTNAME);
20172
            if (dnsEntry->name == NULL) {
20173
                WOLFSSL_MSG("\tOut of Memory");
20174
                XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
20175
                return MEMORY_E;
20176
            }
20177
            dnsEntry->len = strLen;
20178
            XMEMCPY(dnsEntry->name, &input[idx], (size_t)strLen);
20179
            dnsEntry->name[strLen] = '\0';
20180
20181
            AddAltName(cert, dnsEntry);
20182
20183
            length -= strLen;
20184
            idx    += (word32)strLen;
20185
        }
20186
    #ifndef IGNORE_NAME_CONSTRAINTS
20187
        else if (current_byte ==
20188
                (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_DIR_TYPE)) {
20189
            DNS_entry* dirEntry;
20190
            int strLen;
20191
            word32 lenStartIdx = idx;
20192
20193
            if (GetLength(input, &idx, &strLen, sz) < 0) {
20194
                WOLFSSL_MSG("\tfail: str length");
20195
                return ASN_PARSE_E;
20196
            }
20197
20198
            if (GetSequence(input, &idx, &strLen, sz) < 0) {
20199
                WOLFSSL_MSG("\tfail: seq length");
20200
                return ASN_PARSE_E;
20201
            }
20202
            length -= (int)(idx - lenStartIdx);
20203
20204
            dirEntry = AltNameNew(cert->heap);
20205
            if (dirEntry == NULL) {
20206
                WOLFSSL_MSG("\tOut of Memory");
20207
                return MEMORY_E;
20208
            }
20209
20210
            dirEntry->type = ASN_DIR_TYPE;
20211
            dirEntry->name = (char*)XMALLOC((size_t)strLen + 1, cert->heap,
20212
                                         DYNAMIC_TYPE_ALTNAME);
20213
            if (dirEntry->name == NULL) {
20214
                WOLFSSL_MSG("\tOut of Memory");
20215
                XFREE(dirEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
20216
                return MEMORY_E;
20217
            }
20218
            dirEntry->len = strLen;
20219
            XMEMCPY(dirEntry->name, &input[idx], (size_t)strLen);
20220
            dirEntry->name[strLen] = '\0';
20221
            dirEntry->next = cert->altDirNames;
20222
            cert->altDirNames = dirEntry;
20223
20224
            length -= strLen;
20225
            idx    += (word32)strLen;
20226
        }
20227
        else if (current_byte == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE)) {
20228
            DNS_entry* emailEntry;
20229
            int strLen;
20230
            word32 lenStartIdx = idx;
20231
20232
            if (GetLength(input, &idx, &strLen, sz) < 0) {
20233
                WOLFSSL_MSG("\tfail: str length");
20234
                return ASN_PARSE_E;
20235
            }
20236
            length -= (int)(idx - lenStartIdx);
20237
20238
            emailEntry = AltNameNew(cert->heap);
20239
            if (emailEntry == NULL) {
20240
                WOLFSSL_MSG("\tOut of Memory");
20241
                return MEMORY_E;
20242
            }
20243
20244
            emailEntry->type = ASN_RFC822_TYPE;
20245
            emailEntry->name = (char*)XMALLOC((size_t)strLen + 1, cert->heap,
20246
                                         DYNAMIC_TYPE_ALTNAME);
20247
            if (emailEntry->name == NULL) {
20248
                WOLFSSL_MSG("\tOut of Memory");
20249
                XFREE(emailEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
20250
                return MEMORY_E;
20251
            }
20252
            emailEntry->len = strLen;
20253
            XMEMCPY(emailEntry->name, &input[idx], (size_t)strLen);
20254
            emailEntry->name[strLen] = '\0';
20255
20256
            emailEntry->next = cert->altEmailNames;
20257
            cert->altEmailNames = emailEntry;
20258
20259
            length -= strLen;
20260
            idx    += (word32)strLen;
20261
        }
20262
        else if (current_byte == (ASN_CONTEXT_SPECIFIC | ASN_URI_TYPE)) {
20263
            DNS_entry* uriEntry;
20264
            int strLen;
20265
            word32 lenStartIdx = idx;
20266
20267
            WOLFSSL_MSG("\tPutting URI into list but not using");
20268
            if (GetLength(input, &idx, &strLen, sz) < 0) {
20269
                WOLFSSL_MSG("\tfail: str length");
20270
                return ASN_PARSE_E;
20271
            }
20272
            length -= (int)(idx - lenStartIdx);
20273
20274
            /* check that strLen at index is not past input buffer */
20275
            if ((word32)strLen + idx > sz) {
20276
                return BUFFER_E;
20277
            }
20278
20279
        #if !defined(WOLFSSL_NO_ASN_STRICT) && !defined(WOLFSSL_FPKI)
20280
            /* Verify RFC 5280 Sec 4.2.1.6 rule:
20281
                "The name MUST NOT be a relative URI"
20282
                As per RFC 3986 Sec 4.3, an absolute URI is only required to contain
20283
                a scheme and hier-part.  So the only strict requirement is a ':'
20284
                being present after the scheme.  If a '/' is present as part of the
20285
                hier-part, it must come after the ':' (see RFC 3986 Sec 3). */
20286
20287
            {
20288
                word32 i;
20289
20290
                /* skip past scheme (i.e http,ftp,...) finding first ':' char */
20291
                for (i = 0; i < (word32)strLen; i++) {
20292
                    if (input[idx + i] == ':') {
20293
                        break;
20294
                    }
20295
                    if (input[idx + i] == '/') {
20296
                        WOLFSSL_MSG("\tAlt Name must be absolute URI");
20297
                        WOLFSSL_ERROR_VERBOSE(ASN_ALT_NAME_E);
20298
                        return ASN_ALT_NAME_E;
20299
                    }
20300
                }
20301
20302
                /* test hier-part is empty */
20303
                if (i == 0 || i == (word32)strLen) {
20304
                    WOLFSSL_MSG("\tEmpty or malformed URI");
20305
                    WOLFSSL_ERROR_VERBOSE(ASN_ALT_NAME_E);
20306
                    return ASN_ALT_NAME_E;
20307
                }
20308
20309
                /* test if scheme is missing */
20310
                if (input[idx + i] != ':') {
20311
                    WOLFSSL_MSG("\tAlt Name must be absolute URI");
20312
                    WOLFSSL_ERROR_VERBOSE(ASN_ALT_NAME_E);
20313
                    return ASN_ALT_NAME_E;
20314
                }
20315
            }
20316
        #endif
20317
20318
            uriEntry = AltNameNew(cert->heap);
20319
            if (uriEntry == NULL) {
20320
                WOLFSSL_MSG("\tOut of Memory");
20321
                return MEMORY_E;
20322
            }
20323
20324
            uriEntry->type = ASN_URI_TYPE;
20325
            uriEntry->name = (char*)XMALLOC((size_t)strLen + 1, cert->heap,
20326
                                         DYNAMIC_TYPE_ALTNAME);
20327
            if (uriEntry->name == NULL) {
20328
                WOLFSSL_MSG("\tOut of Memory");
20329
                XFREE(uriEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
20330
                return MEMORY_E;
20331
            }
20332
            uriEntry->len = strLen;
20333
            XMEMCPY(uriEntry->name, &input[idx], (size_t)strLen);
20334
            uriEntry->name[strLen] = '\0';
20335
20336
            AddAltName(cert, uriEntry);
20337
20338
            length -= strLen;
20339
            idx    += (word32)strLen;
20340
        }
20341
#ifdef WOLFSSL_IP_ALT_NAME
20342
        else if (current_byte == (ASN_CONTEXT_SPECIFIC | ASN_IP_TYPE)) {
20343
            DNS_entry* ipAddr;
20344
            int strLen;
20345
            word32 lenStartIdx = idx;
20346
            WOLFSSL_MSG("Decoding Subject Alt. Name: IP Address");
20347
20348
            if (GetLength(input, &idx, &strLen, sz) < 0) {
20349
                WOLFSSL_MSG("\tfail: str length");
20350
                return ASN_PARSE_E;
20351
            }
20352
            length -= (idx - lenStartIdx);
20353
            /* check that strLen at index is not past input buffer */
20354
            if (strLen + idx > sz) {
20355
                return BUFFER_E;
20356
            }
20357
20358
            ipAddr = AltNameNew(cert->heap);
20359
            if (ipAddr == NULL) {
20360
                WOLFSSL_MSG("\tOut of Memory");
20361
                return MEMORY_E;
20362
            }
20363
20364
            ipAddr->type = ASN_IP_TYPE;
20365
            ipAddr->name = (char*)XMALLOC((size_t)strLen + 1, cert->heap,
20366
                                         DYNAMIC_TYPE_ALTNAME);
20367
            if (ipAddr->name == NULL) {
20368
                WOLFSSL_MSG("\tOut of Memory");
20369
                XFREE(ipAddr, cert->heap, DYNAMIC_TYPE_ALTNAME);
20370
                return MEMORY_E;
20371
            }
20372
            ipAddr->len = strLen;
20373
            XMEMCPY(ipAddr->name, &input[idx], strLen);
20374
            ipAddr->name[strLen] = '\0';
20375
20376
            if (GenerateDNSEntryIPString(ipAddr, cert->heap) != 0) {
20377
                WOLFSSL_MSG("\tOut of Memory for IP string");
20378
                XFREE(ipAddr->name, cert->heap, DYNAMIC_TYPE_ALTNAME);
20379
                XFREE(ipAddr, cert->heap, DYNAMIC_TYPE_ALTNAME);
20380
                return MEMORY_E;
20381
            }
20382
            AddAltName(cert, ipAddr);
20383
20384
            length -= strLen;
20385
            idx    += (word32)strLen;
20386
        }
20387
#endif /* WOLFSSL_IP_ALT_NAME */
20388
#ifdef WOLFSSL_RID_ALT_NAME
20389
        else if (current_byte == (ASN_CONTEXT_SPECIFIC | ASN_RID_TYPE)) {
20390
            DNS_entry* rid;
20391
            int strLen;
20392
            word32 lenStartIdx = idx;
20393
            WOLFSSL_MSG("Decoding Subject Alt. Name: Registered Id");
20394
20395
            if (GetLength(input, &idx, &strLen, sz) < 0) {
20396
                WOLFSSL_MSG("\tfail: str length");
20397
                return ASN_PARSE_E;
20398
            }
20399
            length -= (idx - lenStartIdx);
20400
            /* check that strLen at index is not past input buffer */
20401
            if (strLen + idx > sz) {
20402
                return BUFFER_E;
20403
            }
20404
20405
            rid = AltNameNew(cert->heap);
20406
            if (rid == NULL) {
20407
                WOLFSSL_MSG("\tOut of Memory");
20408
                return MEMORY_E;
20409
            }
20410
20411
            rid->type = ASN_RID_TYPE;
20412
            rid->name = (char*)XMALLOC((size_t)strLen + 1, cert->heap,
20413
                                         DYNAMIC_TYPE_ALTNAME);
20414
            if (rid->name == NULL) {
20415
                WOLFSSL_MSG("\tOut of Memory");
20416
                XFREE(rid, cert->heap, DYNAMIC_TYPE_ALTNAME);
20417
                return MEMORY_E;
20418
            }
20419
            rid->len = strLen;
20420
            XMEMCPY(rid->name, &input[idx], strLen);
20421
            rid->name[strLen] = '\0';
20422
20423
            if (GenerateDNSEntryRIDString(rid, cert->heap) != 0) {
20424
                WOLFSSL_MSG("\tOut of Memory for registered Id string");
20425
                XFREE(rid->name, cert->heap, DYNAMIC_TYPE_ALTNAME);
20426
                XFREE(rid, cert->heap, DYNAMIC_TYPE_ALTNAME);
20427
                return MEMORY_E;
20428
            }
20429
20430
            AddAltName(cert, rid);
20431
20432
            length -= strLen;
20433
            idx    += (word32)strLen;
20434
        }
20435
#endif /* WOLFSSL_RID_ALT_NAME */
20436
#endif /* IGNORE_NAME_CONSTRAINTS */
20437
        else if (current_byte ==
20438
                (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE)) {
20439
            int strLen;
20440
            word32 lenStartIdx = idx;
20441
            word32 oid = 0;
20442
            int    ret = 0;
20443
20444
            if (GetLength(input, &idx, &strLen, sz) < 0) {
20445
                WOLFSSL_MSG("\tfail: other name length");
20446
                return ASN_PARSE_E;
20447
            }
20448
            /* Consume the rest of this sequence. */
20449
            length -= (int)(((word32)strLen + idx - lenStartIdx));
20450
20451
            if (GetObjectId(input, &idx, &oid, oidCertAltNameType, sz) < 0) {
20452
                WOLFSSL_MSG("\tbad OID");
20453
                return ASN_PARSE_E;
20454
            }
20455
20456
            /* handle parsing other type alt names */
20457
            switch (oid) {
20458
            #ifdef WOLFSSL_SEP
20459
                case HW_NAME_OID:
20460
                    ret = DecodeSepHwAltName(cert, input, &idx, sz);
20461
                    if (ret != 0)
20462
                        return ret;
20463
                    break;
20464
            #endif /* WOLFSSL_SEP */
20465
            #ifdef WOLFSSL_FPKI
20466
                case FASCN_OID:
20467
                case UPN_OID:
20468
                    ret = DecodeConstructedOtherName(cert, input, &idx, sz,
20469
                            oid);
20470
                    if (ret != 0)
20471
                        return ret;
20472
                    break;
20473
            #endif /* WOLFSSL_FPKI */
20474
20475
                default:
20476
                    WOLFSSL_MSG("\tUnsupported other name type, skipping");
20477
                    if (GetLength(input, &idx, &strLen, sz) < 0) {
20478
                        /* check to skip constructed other names too */
20479
                        if (DecodeConstructedOtherName(cert, input, &idx, sz,
20480
                                    (int)oid) != 0) {
20481
                            WOLFSSL_MSG("\tfail: unsupported other name length");
20482
                            return ASN_PARSE_E;
20483
                        }
20484
                    }
20485
                    else {
20486
                        idx += (word32)strLen;
20487
                    }
20488
            }
20489
            (void)ret;
20490
        }
20491
        else {
20492
            int strLen;
20493
            word32 lenStartIdx = idx;
20494
20495
            WOLFSSL_MSG("\tUnsupported name type, skipping");
20496
20497
            if (GetLength(input, &idx, &strLen, sz) < 0) {
20498
                WOLFSSL_MSG("\tfail: unsupported name length");
20499
                return ASN_PARSE_E;
20500
            }
20501
            length -= (int)((word32)strLen + idx - lenStartIdx);
20502
            idx += (word32)strLen;
20503
        }
20504
    }
20505
20506
    return 0;
20507
#else
20508
0
    word32 idx = 0;
20509
0
    int length = 0;
20510
0
    int ret = 0;
20511
0
    word32 numNames = 0;
20512
20513
0
    WOLFSSL_ENTER("DecodeAltNames");
20514
20515
    /* Get SEQUENCE and expect all data to be accounted for. */
20516
0
    if (GetASN_Sequence(input, &idx, &length, sz, 1) != 0) {
20517
0
        WOLFSSL_MSG("\tBad Sequence");
20518
0
        ret = ASN_PARSE_E;
20519
0
    }
20520
20521
0
    if ((ret == 0) && (length == 0)) {
20522
        /* RFC 5280 4.2.1.6.  Subject Alternative Name
20523
           If the subjectAltName extension is present, the sequence MUST
20524
           contain at least one entry. */
20525
0
        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
20526
0
        ret = ASN_PARSE_E;
20527
0
    }
20528
0
    if (ret == 0) {
20529
    #ifdef OPENSSL_ALL
20530
        cert->extSubjAltNameSrc = input;
20531
        cert->extSubjAltNameSz = sz;
20532
    #endif
20533
20534
0
        cert->weOwnAltNames = 1;
20535
20536
0
        if ((word32)length + idx != sz) {
20537
0
            ret = ASN_PARSE_E;
20538
0
        }
20539
0
    }
20540
20541
0
    while ((ret == 0) && (idx < sz)) {
20542
0
        ASNGetData dataASN[altNameASN_Length];
20543
20544
0
        numNames++;
20545
0
        if (numNames > WOLFSSL_MAX_ALT_NAMES) {
20546
0
            WOLFSSL_MSG("\tToo many subject alternative names");
20547
0
            ret = ASN_ALT_NAME_E;
20548
0
            break;
20549
0
        }
20550
20551
        /* Clear dynamic data items. */
20552
0
        XMEMSET(dataASN, 0, sizeof(dataASN));
20553
        /* Parse GeneralName with the choices supported. */
20554
0
        GetASN_Choice(&dataASN[ALTNAMEASN_IDX_GN], generalNameChoice);
20555
        /* Decode a GeneralName choice. */
20556
0
        ret = GetASN_Items(altNameASN, dataASN, altNameASN_Length, 0, input,
20557
0
                           &idx, sz);
20558
0
        if (ret == 0) {
20559
0
            ret = DecodeGeneralName(input, &idx, dataASN[ALTNAMEASN_IDX_GN].tag,
20560
0
                                  (int)dataASN[ALTNAMEASN_IDX_GN].length, cert);
20561
0
        }
20562
0
    }
20563
20564
0
    return ret;
20565
0
#endif
20566
0
}
20567
20568
#ifdef WOLFSSL_ASN_TEMPLATE
20569
/* ASN.1 template for BasicConstraints.
20570
 * X.509: RFC 5280, 4.2.1.9 - BasicConstraints.
20571
 */
20572
static const ASNItem basicConsASN[] = {
20573
/* SEQ  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
20574
/* CA   */     { 1, ASN_BOOLEAN, 0, 0, 1 },
20575
/* PLEN */     { 1, ASN_INTEGER, 0, 0, 1 }
20576
};
20577
enum {
20578
    BASICCONSASN_IDX_SEQ = 0,
20579
    BASICCONSASN_IDX_CA,
20580
    BASICCONSASN_IDX_PLEN
20581
};
20582
20583
/* Number of items in ASN.1 template for BasicContraints. */
20584
0
#define basicConsASN_Length (sizeof(basicConsASN) / sizeof(ASNItem))
20585
#endif
20586
20587
/* Decode basic constraints extension in a certificate.
20588
 *
20589
 * X.509: RFC 5280, 4.2.1.9 - BasicConstraints.
20590
 *
20591
 * @param [in]      input  Buffer holding data.
20592
 * @param [in]      sz     Size of data in buffer.
20593
 * @param [in, out] cert   Certificate object.
20594
 * @return  0 on success.
20595
 * @return  MEMORY_E on dynamic memory allocation failure.
20596
 * @return  ASN_PARSE_E when CA boolean is present and false (default is false).
20597
 * @return  ASN_PARSE_E when CA boolean is not present unless
20598
 *          WOLFSSL_X509_BASICCONS_INT is defined. Only a CA extension.
20599
 * @return  ASN_PARSE_E when path length more than 7 bits.
20600
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
20601
 *          is invalid.
20602
 * @return  BUFFER_E when data in buffer is too small.
20603
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
20604
 *          non-zero length.
20605
 */
20606
static int DecodeBasicCaConstraint(const byte* input, int sz, DecodedCert* cert)
20607
0
{
20608
#ifndef WOLFSSL_ASN_TEMPLATE
20609
    word32 idx = 0;
20610
    int length = 0;
20611
    int ret;
20612
20613
    WOLFSSL_ENTER("DecodeBasicCaConstraint");
20614
20615
    if (GetSequence(input, &idx, &length, (word32)sz) < 0) {
20616
        WOLFSSL_MSG("\tfail: bad SEQUENCE");
20617
        return ASN_PARSE_E;
20618
    }
20619
20620
    if (length == 0)
20621
        return 0;
20622
20623
    /* If the basic ca constraint is false, this extension may be named, but
20624
     * left empty. So, if the length is 0, just return. */
20625
20626
    ret = GetBoolean(input, &idx, (word32)sz);
20627
20628
    /* Removed logic for WOLFSSL_X509_BASICCONS_INT which was mistreating the
20629
     * pathlen value as if it were the CA Boolean value 7/2/2021 - KH.
20630
     * When CA Boolean not asserted use the default value "False" */
20631
    if (ret < 0) {
20632
        WOLFSSL_MSG("\tfail: constraint not valid BOOLEAN, set default FALSE");
20633
        ret = 0;
20634
    }
20635
20636
    cert->isCA = ret ? 1 : 0;
20637
20638
    /* If there isn't any more data, return. */
20639
    if (idx >= (word32)sz) {
20640
        return 0;
20641
    }
20642
20643
    ret = GetInteger16Bit(input, &idx, (word32)sz);
20644
    if (ret < 0)
20645
        return ret;
20646
    else if (ret > WOLFSSL_MAX_PATH_LEN) {
20647
        WOLFSSL_ERROR_VERBOSE(ASN_PATHLEN_SIZE_E);
20648
        return ASN_PATHLEN_SIZE_E;
20649
    }
20650
20651
    cert->pathLength = (word16)ret;
20652
    cert->pathLengthSet = 1;
20653
20654
    return 0;
20655
#else
20656
0
    DECL_ASNGETDATA(dataASN, basicConsASN_Length);
20657
0
    int ret = 0;
20658
0
    word32 idx = 0;
20659
0
    byte isCA = 0;
20660
20661
0
    WOLFSSL_ENTER("DecodeBasicCaConstraint");
20662
20663
0
    CALLOC_ASNGETDATA(dataASN, basicConsASN_Length, ret, cert->heap);
20664
20665
0
    if (ret == 0) {
20666
        /* Get the CA boolean and path length when present. */
20667
0
        GetASN_Boolean(&dataASN[BASICCONSASN_IDX_CA], &isCA);
20668
0
        GetASN_Int16Bit(&dataASN[BASICCONSASN_IDX_PLEN], &cert->pathLength);
20669
20670
0
        ret = GetASN_Items(basicConsASN, dataASN, basicConsASN_Length, 1, input,
20671
0
                           &idx, (word32)sz);
20672
0
    }
20673
20674
    /* Empty SEQUENCE is OK - nothing to store. */
20675
0
    if ((ret == 0) && (dataASN[BASICCONSASN_IDX_SEQ].length != 0)) {
20676
        /* Bad encoding when CA Boolean is false
20677
         * (default when not present). */
20678
0
#if !defined(ASN_TEMPLATE_SKIP_ISCA_CHECK) && \
20679
0
    !defined(WOLFSSL_ALLOW_ENCODING_CA_FALSE)
20680
0
        if ((dataASN[BASICCONSASN_IDX_CA].length != 0) && (!isCA)) {
20681
0
            WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
20682
0
            ret = ASN_PARSE_E;
20683
0
        }
20684
0
#endif
20685
0
        if ((ret == 0) && cert->pathLength > WOLFSSL_MAX_PATH_LEN) {
20686
0
            WOLFSSL_ERROR_VERBOSE(ASN_PATHLEN_SIZE_E);
20687
0
            ret = ASN_PATHLEN_SIZE_E;
20688
0
        }
20689
        /* Store CA boolean and whether a path length was seen. */
20690
0
        if (ret == 0) {
20691
            /* isCA in certificate is a 1 bit of a byte. */
20692
0
            cert->isCA = isCA ? 1 : 0;
20693
0
            cert->pathLengthSet = (dataASN[BASICCONSASN_IDX_PLEN].length > 0);
20694
0
        }
20695
0
    }
20696
20697
0
    FREE_ASNGETDATA(dataASN, cert->heap);
20698
0
    return ret;
20699
0
#endif
20700
0
}
20701
20702
20703
static int DecodePolicyConstraints(const byte* input, int sz, DecodedCert* cert)
20704
0
{
20705
0
    word32 idx = 0;
20706
0
    int length = 0;
20707
0
    int skipLength = 0;
20708
0
    int ret;
20709
0
    byte tag;
20710
20711
0
    WOLFSSL_ENTER("DecodePolicyConstraints");
20712
20713
0
    if (GetSequence(input, &idx, &length, (word32)sz) < 0) {
20714
0
        WOLFSSL_MSG("\tfail: bad SEQUENCE");
20715
0
        return ASN_PARSE_E;
20716
0
    }
20717
20718
0
    if (length == 0)
20719
0
        return ASN_PARSE_E;
20720
20721
0
    if (GetASNTag(input, &idx, &tag, (word32)sz) < 0) {
20722
0
        WOLFSSL_MSG("\tfail: bad TAG");
20723
0
        return ASN_PARSE_E;
20724
0
    }
20725
20726
0
    if (tag == (ASN_CONTEXT_SPECIFIC | 0)) {
20727
        /* requireExplicitPolicy */
20728
0
        cert->extPolicyConstRxpSet = 1;
20729
0
    }
20730
0
    else if (tag == (ASN_CONTEXT_SPECIFIC | 1)) {
20731
        /* inhibitPolicyMapping */
20732
0
        cert->extPolicyConstIpmSet = 1;
20733
0
    }
20734
0
    else {
20735
0
        WOLFSSL_MSG("\tfail: invalid TAG");
20736
0
        return ASN_PARSE_E;
20737
0
    }
20738
20739
0
    ret = GetLength(input, &idx, &skipLength, (word32)sz);
20740
0
    if (ret < 0) {
20741
0
        WOLFSSL_MSG("\tfail: invalid length");
20742
0
        return ret;
20743
0
    }
20744
0
    if (skipLength > 1) {
20745
0
        WOLFSSL_MSG("\tfail: skip value too big");
20746
0
        return BUFFER_E;
20747
0
    }
20748
0
    if (idx >= (word32)sz) {
20749
0
        WOLFSSL_MSG("\tfail: no policy const skip to read");
20750
0
        return BUFFER_E;
20751
0
    }
20752
0
    cert->policyConstSkip = input[idx];
20753
20754
0
    return 0;
20755
0
}
20756
20757
20758
/* Context-Specific value for: DistributionPoint.distributionPoint
20759
 * From RFC5280 SS4.2.1.13, Distribution Point */
20760
#define DISTRIBUTION_POINT  (ASN_CONTEXT_SPECIFIC | 0)
20761
/* Context-Specific value for: DistributionPoint.DistributionPointName.fullName
20762
 *  From RFC3280 SS4.2.1.13, Distribution Point Name */
20763
#define CRLDP_FULL_NAME     (ASN_CONTEXT_SPECIFIC | 0)
20764
/* Context-Specific value for choice: GeneralName.uniformResourceIdentifier
20765
 * From RFC3280 SS4.2.1.7, GeneralName */
20766
0
#define GENERALNAME_URI     (ASN_CONTEXT_SPECIFIC | 6)
20767
20768
#ifdef WOLFSSL_ASN_TEMPLATE
20769
/* ASN.1 template for CRL distribution points.
20770
 * X.509: RFC 5280, 4.2.1.13 - CRL Distribution Points.
20771
 */
20772
static const ASNItem crlDistASN[] = {
20773
/* SEQ                */ { 0, ASN_SEQUENCE, 1, 1, 0 },
20774
/* DP_SEQ             */     { 1, ASN_SEQUENCE, 1, 1, 0 },
20775
                                                /* Distribution point name */
20776
/* DP_DISTPOINT       */         { 2, DISTRIBUTION_POINT, 1, 1, 1 },
20777
                                                    /* fullName */
20778
/* DP_DISTPOINT_FN    */             { 3, CRLDP_FULL_NAME, 1, 1, 2 },
20779
/* DP_DISTPOINT_FN_GN */                 { 4, GENERALNAME_URI, 0, 0, 0 },
20780
                                                    /* nameRelativeToCRLIssuer */
20781
/* DP_DISTPOINT_RN    */             { 3, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 2 },
20782
                                                /* reasons: IMPLICIT BIT STRING */
20783
/* DP_REASONS         */         { 2, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 1 },
20784
                                                /* cRLIssuer */
20785
/* DP_CRLISSUER       */         { 2, ASN_CONTEXT_SPECIFIC | 2, 1, 0, 1 },
20786
};
20787
enum {
20788
    CRLDISTASN_IDX_SEQ = 0,
20789
    CRLDISTASN_IDX_DP_SEQ,
20790
    CRLDISTASN_IDX_DP_DISTPOINT,
20791
    CRLDISTASN_IDX_DP_DISTPOINT_FN,
20792
    CRLDISTASN_IDX_DP_DISTPOINT_FN_GN,
20793
    CRLDISTASN_IDX_DP_DISTPOINT_RN, /* Relative name */
20794
    CRLDISTASN_IDX_DP_REASONS,
20795
    CRLDISTASN_IDX_DP_CRLISSUER
20796
};
20797
20798
/* Number of items in ASN.1 template for CRL distribution points. */
20799
0
#define crlDistASN_Length (sizeof(crlDistASN) / sizeof(ASNItem))
20800
#endif
20801
20802
/* Decode CRL distribution point extension in a certificate.
20803
 *
20804
 * X.509: RFC 5280, 4.2.1.13 - CRL Distribution Points.
20805
 *
20806
 * @param [in]      input  Buffer holding data.
20807
 * @param [in]      sz     Size of data in buffer.
20808
 * @param [in, out] cert   Certificate object.
20809
 * @return  0 on success.
20810
 * @return  MEMORY_E on dynamic memory allocation failure.
20811
 * @return  ASN_PARSE_E when invalid bits of reason are set.
20812
 * @return  ASN_PARSE_E when BITSTRING value is more than 2 bytes.
20813
 * @return  ASN_PARSE_E when unused bits of BITSTRING is invalid.
20814
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
20815
 *          is invalid.
20816
 * @return  BUFFER_E when data in buffer is too small.
20817
 */
20818
static int DecodeCrlDist(const byte* input, word32 sz, DecodedCert* cert)
20819
0
{
20820
#ifndef WOLFSSL_ASN_TEMPLATE
20821
    word32 idx = 0, localIdx;
20822
    int length = 0;
20823
    byte tag   = 0;
20824
20825
    WOLFSSL_ENTER("DecodeCrlDist");
20826
20827
    cert->extCrlInfoRaw = input;
20828
    cert->extCrlInfoRawSz = (int)sz;
20829
20830
    /* Unwrap the list of Distribution Points*/
20831
    if (GetSequence(input, &idx, &length, sz) < 0)
20832
        return ASN_PARSE_E;
20833
20834
    /* Unwrap a single Distribution Point */
20835
    if (GetSequence(input, &idx, &length, sz) < 0)
20836
        return ASN_PARSE_E;
20837
20838
    /* The Distribution Point has three explicit optional members
20839
     *  First check for a DistributionPointName
20840
     */
20841
    localIdx = idx;
20842
    if (GetASNTag(input, &localIdx, &tag, sz) == 0 &&
20843
            tag == (ASN_CONSTRUCTED | DISTRIBUTION_POINT))
20844
    {
20845
        idx++;
20846
        if (GetLength(input, &idx, &length, sz) < 0)
20847
            return ASN_PARSE_E;
20848
20849
        localIdx = idx;
20850
        if (GetASNTag(input, &localIdx, &tag, sz) == 0 &&
20851
                tag == (ASN_CONSTRUCTED | CRLDP_FULL_NAME))
20852
        {
20853
            idx++;
20854
            if (GetLength(input, &idx, &length, sz) < 0)
20855
                return ASN_PARSE_E;
20856
20857
            localIdx = idx;
20858
            if (GetASNTag(input, &localIdx, &tag, sz) == 0 &&
20859
                    tag == GENERALNAME_URI)
20860
            {
20861
                idx++;
20862
                if (GetLength(input, &idx, &length, sz) < 0)
20863
                    return ASN_PARSE_E;
20864
20865
                cert->extCrlInfoSz = length;
20866
                cert->extCrlInfo = input + idx;
20867
                idx += (word32)length;
20868
            }
20869
            else
20870
                /* This isn't a URI, skip it. */
20871
                idx += (word32)length;
20872
        }
20873
        else {
20874
            /* This isn't a FULLNAME, skip it. */
20875
            idx += (word32)length;
20876
        }
20877
    }
20878
20879
    /* Check for reasonFlags */
20880
    localIdx = idx;
20881
    if (idx < (word32)sz &&
20882
        GetASNTag(input, &localIdx, &tag, sz) == 0 &&
20883
        tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
20884
    {
20885
        idx++;
20886
        if (GetLength(input, &idx, &length, sz) < 0)
20887
            return ASN_PARSE_E;
20888
        idx += (word32)length;
20889
    }
20890
20891
    /* Check for cRLIssuer */
20892
    localIdx = idx;
20893
    if (idx < (word32)sz &&
20894
        GetASNTag(input, &localIdx, &tag, sz) == 0 &&
20895
        tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2))
20896
    {
20897
        idx++;
20898
        if (GetLength(input, &idx, &length, sz) < 0)
20899
            return ASN_PARSE_E;
20900
        idx += (word32)length;
20901
    }
20902
20903
    if (idx < (word32)sz)
20904
    {
20905
        WOLFSSL_MSG("\tThere are more CRL Distribution Point records, "
20906
                   "but we only use the first one.");
20907
    }
20908
20909
    return 0;
20910
#else
20911
0
    DECL_ASNGETDATA(dataASN, crlDistASN_Length);
20912
0
    word32 idx = 0;
20913
0
    int ret = 0;
20914
#ifdef CRLDP_VALIDATE_DATA
20915
    word16 reason;
20916
#endif
20917
20918
0
    WOLFSSL_ENTER("DecodeCrlDist");
20919
20920
0
    CALLOC_ASNGETDATA(dataASN, crlDistASN_Length, ret, cert->heap);
20921
20922
0
    cert->extCrlInfoRaw = input;
20923
0
    cert->extCrlInfoRawSz = (int)sz;
20924
20925
0
    if  (ret == 0) {
20926
        /* Get the GeneralName choice */
20927
0
        GetASN_Choice(&dataASN[CRLDISTASN_IDX_DP_DISTPOINT_FN_GN], generalNameChoice);
20928
        /* Parse CRL distribution point. */
20929
0
        ret = GetASN_Items(crlDistASN, dataASN, crlDistASN_Length, 0, input,
20930
0
                           &idx, sz);
20931
0
    }
20932
0
    if (ret == 0) {
20933
        /* If the choice was a URI, store it in certificate. */
20934
0
        if (dataASN[CRLDISTASN_IDX_DP_DISTPOINT_FN_GN].tag == GENERALNAME_URI) {
20935
0
            word32 sz32;
20936
0
            GetASN_GetConstRef(&dataASN[CRLDISTASN_IDX_DP_DISTPOINT_FN_GN],
20937
0
                    &cert->extCrlInfo, &sz32);
20938
0
            cert->extCrlInfoSz = (int)sz32;
20939
0
        }
20940
20941
    #ifdef CRLDP_VALIDATE_DATA
20942
        if (dataASN[CRLDISTASN_IDX_DP_REASONS].data.ref.data != NULL) {
20943
             /* TODO: test case */
20944
             /* Validate ReasonFlags. */
20945
             ret = GetASN_BitString_Int16Bit(&dataASN[CRLDISTASN_IDX_DP_REASONS],
20946
                     &reason);
20947
             /* First bit (LSB) unused and eight other bits defined. */
20948
             if ((ret == 0) && ((reason >> 9) || (reason & 0x01))) {
20949
                WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
20950
                ret = ASN_PARSE_E;
20951
             }
20952
        }
20953
    #endif
20954
0
    }
20955
20956
    /* Only parsing the first one. */
20957
0
    if (ret == 0 && idx < (word32)sz) {
20958
0
        WOLFSSL_MSG("\tThere are more CRL Distribution Point records, "
20959
0
                    "but we only use the first one.");
20960
0
    }
20961
    /* TODO: validate other points. */
20962
20963
0
    FREE_ASNGETDATA(dataASN, cert->heap);
20964
0
    return ret;
20965
0
#endif /* WOLFSSL_ASN_TEMPLATE */
20966
0
}
20967
20968
#ifdef WOLFSSL_ASN_TEMPLATE
20969
/* ASN.1 template for the access description.
20970
 * X.509: RFC 5280, 4.2.2.1 - Authority Information Access.
20971
 */
20972
static const ASNItem accessDescASN[] = {
20973
/* SEQ  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
20974
                                 /* accessMethod */
20975
/* METH */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
20976
                                 /* accessLocation: GeneralName */
20977
/* LOC  */     { 1, ASN_CONTEXT_SPECIFIC | 0, 0, 0, 0 },
20978
};
20979
enum {
20980
    ACCESSDESCASN_IDX_SEQ = 0,
20981
    ACCESSDESCASN_IDX_METH,
20982
    ACCESSDESCASN_IDX_LOC
20983
};
20984
20985
/* Number of items in ASN.1 template for the access description. */
20986
0
#define accessDescASN_Length (sizeof(accessDescASN) / sizeof(ASNItem))
20987
#endif
20988
20989
/* Decode authority information access extension in a certificate.
20990
 *
20991
 * X.509: RFC 5280, 4.2.2.1 - Authority Information Access.
20992
 *
20993
 * @param [in]      input  Buffer holding data.
20994
 * @param [in]      sz     Size of data in buffer.
20995
 * @param [in, out] cert   Certificate object.
20996
 * @return  0 on success.
20997
 * @return  MEMORY_E on dynamic memory allocation failure.
20998
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
20999
 *          is invalid.
21000
 * @return  BUFFER_E when data in buffer is too small.
21001
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
21002
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
21003
 */
21004
static int DecodeAuthInfo(const byte* input, word32 sz, DecodedCert* cert)
21005
0
{
21006
#ifndef WOLFSSL_ASN_TEMPLATE
21007
    word32 idx = 0;
21008
    int length = 0;
21009
    byte b = 0;
21010
    word32 oid;
21011
21012
    WOLFSSL_ENTER("DecodeAuthInfo");
21013
21014
    /* Unwrap the list of AIAs */
21015
    if (GetSequence(input, &idx, &length, sz) < 0)
21016
        return ASN_PARSE_E;
21017
21018
    while ((idx < (word32)sz)) {
21019
        /* Unwrap a single AIA */
21020
        if (GetSequence(input, &idx, &length, sz) < 0)
21021
            return ASN_PARSE_E;
21022
21023
        oid = 0;
21024
        if (GetObjectId(input, &idx, &oid, oidCertAuthInfoType, sz) < 0) {
21025
            return ASN_PARSE_E;
21026
        }
21027
21028
        /* Only supporting URIs right now. */
21029
        if (GetASNTag(input, &idx, &b, sz) < 0)
21030
            return ASN_PARSE_E;
21031
21032
        if (GetLength(input, &idx, &length, sz) < 0)
21033
            return ASN_PARSE_E;
21034
21035
        /* Set ocsp entry */
21036
        if (b == GENERALNAME_URI && oid == AIA_OCSP_OID &&
21037
                cert->extAuthInfo == NULL) {
21038
            cert->extAuthInfoSz = length;
21039
            cert->extAuthInfo = input + idx;
21040
        }
21041
    #ifdef WOLFSSL_ASN_CA_ISSUER
21042
        /* Set CaIssuers entry */
21043
        else if ((b == GENERALNAME_URI) && oid == AIA_CA_ISSUER_OID &&
21044
                cert->extAuthInfoCaIssuer == NULL)
21045
        {
21046
            cert->extAuthInfoCaIssuerSz = length;
21047
            cert->extAuthInfoCaIssuer = input + idx;
21048
        }
21049
    #endif
21050
        idx += (word32)length;
21051
    }
21052
21053
    return 0;
21054
#else
21055
0
    word32 idx = 0;
21056
0
    int length = 0;
21057
0
    int ret    = 0;
21058
21059
0
    WOLFSSL_ENTER("DecodeAuthInfo");
21060
21061
    /* Unwrap the list of AIAs */
21062
0
    if (GetASN_Sequence(input, &idx, &length, sz, 1) < 0) {
21063
0
        ret = ASN_PARSE_E;
21064
0
    }
21065
21066
0
    while ((ret == 0) && (idx < (word32)sz)) {
21067
0
        ASNGetData dataASN[accessDescASN_Length];
21068
21069
        /* Clear dynamic data and retrieve OID and name. */
21070
0
        XMEMSET(dataASN, 0, sizeof(dataASN));
21071
0
        GetASN_OID(&dataASN[ACCESSDESCASN_IDX_METH], oidCertAuthInfoType);
21072
0
        GetASN_Choice(&dataASN[ACCESSDESCASN_IDX_LOC], generalNameChoice);
21073
        /* Parse AccessDescription. */
21074
0
        ret = GetASN_Items(accessDescASN, dataASN, accessDescASN_Length, 0,
21075
0
                           input, &idx, sz);
21076
0
        if (ret == 0) {
21077
0
            word32 sz32;
21078
21079
            /* Check we have OCSP and URI. */
21080
0
            if ((dataASN[ACCESSDESCASN_IDX_METH].data.oid.sum == AIA_OCSP_OID) &&
21081
0
                    (dataASN[ACCESSDESCASN_IDX_LOC].tag == GENERALNAME_URI) &&
21082
0
                    (cert->extAuthInfo == NULL)) {
21083
                /* Store URI for OCSP lookup. */
21084
0
                GetASN_GetConstRef(&dataASN[ACCESSDESCASN_IDX_LOC],
21085
0
                        &cert->extAuthInfo, &sz32);
21086
0
                cert->extAuthInfoSz = (int)sz32;
21087
0
            }
21088
        #ifdef WOLFSSL_ASN_CA_ISSUER
21089
            /* Check we have CA Issuer and URI. */
21090
            else if ((dataASN[ACCESSDESCASN_IDX_METH].data.oid.sum ==
21091
                        AIA_CA_ISSUER_OID) &&
21092
                    (dataASN[ACCESSDESCASN_IDX_LOC].tag == GENERALNAME_URI) &&
21093
                    (cert->extAuthInfoCaIssuer == NULL)) {
21094
                /* Set CaIssuers entry */
21095
                GetASN_GetConstRef(&dataASN[ACCESSDESCASN_IDX_LOC],
21096
                        &cert->extAuthInfoCaIssuer, &sz32);
21097
                cert->extAuthInfoCaIssuerSz = (int)sz32;
21098
            }
21099
        #endif
21100
            /* Otherwise skip. */
21101
0
        }
21102
0
    }
21103
21104
0
    return ret;
21105
0
#endif
21106
0
}
21107
21108
21109
#ifdef WOLFSSL_ASN_TEMPLATE
21110
/* ASN.1 template for AuthorityKeyIdentifier.
21111
 * X.509: RFC 5280, 4.2.1.1 - Authority Key Identifier.
21112
 */
21113
static const ASNItem authKeyIdASN[] = {
21114
/* SEQ    */    { 0, ASN_SEQUENCE, 1, 1, 0 },
21115
                                     /* keyIdentifier */
21116
/* KEYID  */        { 1, ASN_CONTEXT_SPECIFIC | ASN_AUTHKEYID_KEYID, 0, 0, 1 },
21117
                                     /* authorityCertIssuer */
21118
/* ISSUER */        { 1, ASN_CONTEXT_SPECIFIC | ASN_AUTHKEYID_ISSUER, 1, 0, 1 },
21119
                                     /* authorityCertSerialNumber */
21120
/* SERIAL */        { 1, ASN_CONTEXT_SPECIFIC | ASN_AUTHKEYID_SERIAL, 0, 0, 1 },
21121
};
21122
enum {
21123
    AUTHKEYIDASN_IDX_SEQ = 0,
21124
    AUTHKEYIDASN_IDX_KEYID,
21125
    AUTHKEYIDASN_IDX_ISSUER,
21126
    AUTHKEYIDASN_IDX_SERIAL
21127
};
21128
21129
/* Number of items in ASN.1 template for AuthorityKeyIdentifier. */
21130
0
#define authKeyIdASN_Length (sizeof(authKeyIdASN) / sizeof(ASNItem))
21131
#endif
21132
21133
/* Decode authority key identifier extension in a certificate.
21134
 *
21135
 * X.509: RFC 5280, 4.2.1.1 - Authority Key Identifier.
21136
 *
21137
 * @param [in]      input  Buffer holding data.
21138
 * @param [in]      sz     Size of data in buffer.
21139
 * @param [in, out] cert   Certificate object.
21140
 * @return  0 on success.
21141
 * @return  MEMORY_E on dynamic memory allocation failure.
21142
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
21143
 *          is invalid.
21144
 * @return  BUFFER_E when data in buffer is too small.
21145
 */
21146
static int DecodeAuthKeyId(const byte* input, word32 sz, DecodedCert* cert)
21147
0
{
21148
#ifndef WOLFSSL_ASN_TEMPLATE
21149
    word32 idx = 0;
21150
    int length = 0;
21151
    byte tag;
21152
21153
    WOLFSSL_ENTER("DecodeAuthKeyId");
21154
21155
    if (GetSequence(input, &idx, &length, sz) < 0) {
21156
        WOLFSSL_MSG("\tfail: should be a SEQUENCE");
21157
        return ASN_PARSE_E;
21158
    }
21159
21160
    if (GetASNTag(input, &idx, &tag, sz) < 0) {
21161
        return ASN_PARSE_E;
21162
    }
21163
21164
    if (tag != (ASN_CONTEXT_SPECIFIC | 0)) {
21165
        WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available");
21166
        cert->extAuthKeyIdSet = 0;
21167
        return 0;
21168
    }
21169
21170
    if (GetLength(input, &idx, &length, sz) <= 0) {
21171
        WOLFSSL_MSG("\tfail: extension data length");
21172
        return ASN_PARSE_E;
21173
    }
21174
21175
    cert->extAuthKeyIdSz = length;
21176
21177
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
21178
#ifdef WOLFSSL_AKID_NAME
21179
    cert->extRawAuthKeyIdSrc = input;
21180
    cert->extRawAuthKeyIdSz = sz;
21181
#endif
21182
    cert->extAuthKeyIdSrc = &input[idx];
21183
#endif /* OPENSSL_EXTRA */
21184
21185
    return GetHashId(input + idx, length, cert->extAuthKeyId,
21186
        HashIdAlg(cert->signatureOID));
21187
#else
21188
0
    DECL_ASNGETDATA(dataASN, authKeyIdASN_Length);
21189
0
    int ret = 0;
21190
21191
0
    WOLFSSL_ENTER("DecodeAuthKeyId");
21192
21193
0
    CALLOC_ASNGETDATA(dataASN, authKeyIdASN_Length, ret, cert->heap);
21194
21195
0
    if (ret == 0) {
21196
        /* Parse an authority key identifier. */
21197
0
        word32 idx = 0;
21198
0
        ret = GetASN_Items(authKeyIdASN, dataASN, authKeyIdASN_Length, 1, input,
21199
0
                           &idx, sz);
21200
0
    }
21201
    /* Each field is optional */
21202
0
    if (ret == 0 && dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data != NULL) {
21203
#ifdef OPENSSL_EXTRA
21204
        GetASN_GetConstRef(&dataASN[AUTHKEYIDASN_IDX_KEYID],
21205
                &cert->extAuthKeyIdSrc, &cert->extAuthKeyIdSz);
21206
#endif /* OPENSSL_EXTRA */
21207
        /* Get the hash or hash of the hash if wrong size. */
21208
0
        ret = GetHashId(dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data,
21209
0
                    (int)dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.length,
21210
0
                    cert->extAuthKeyId, HashIdAlg(cert->signatureOID));
21211
0
    }
21212
#ifdef WOLFSSL_AKID_NAME
21213
    if (ret == 0 && dataASN[AUTHKEYIDASN_IDX_ISSUER].data.ref.data != NULL) {
21214
        /* We only support using one (first) name. Parse the name to perform
21215
         * a sanity check. */
21216
        word32 idx = 0;
21217
        ASNGetData nameASN[altNameASN_Length];
21218
        XMEMSET(nameASN, 0, sizeof(nameASN));
21219
        /* Parse GeneralName with the choices supported. */
21220
        GetASN_Choice(&nameASN[ALTNAMEASN_IDX_GN], generalNameChoice);
21221
        /* Decode a GeneralName choice. */
21222
        ret = GetASN_Items(altNameASN, nameASN, altNameASN_Length, 0,
21223
                dataASN[AUTHKEYIDASN_IDX_ISSUER].data.ref.data, &idx,
21224
                dataASN[AUTHKEYIDASN_IDX_ISSUER].data.ref.length);
21225
21226
        if (ret == 0) {
21227
            GetASN_GetConstRef(&nameASN[ALTNAMEASN_IDX_GN],
21228
                    &cert->extAuthKeyIdIssuer, &cert->extAuthKeyIdIssuerSz);
21229
        }
21230
    }
21231
    if (ret == 0 && dataASN[AUTHKEYIDASN_IDX_SERIAL].data.ref.data != NULL) {
21232
        GetASN_GetConstRef(&dataASN[AUTHKEYIDASN_IDX_SERIAL],
21233
                &cert->extAuthKeyIdIssuerSN, &cert->extAuthKeyIdIssuerSNSz);
21234
    }
21235
    if (ret == 0) {
21236
        if ((cert->extAuthKeyIdIssuerSz > 0) ^
21237
                (cert->extAuthKeyIdIssuerSNSz > 0)) {
21238
            WOLFSSL_MSG("authorityCertIssuer and authorityCertSerialNumber MUST"
21239
                       " both be present or both be absent");
21240
        }
21241
    }
21242
#endif /* WOLFSSL_AKID_NAME */
21243
0
    if (ret == 0) {
21244
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_AKID_NAME)
21245
        /* Store the raw authority key id. */
21246
        cert->extRawAuthKeyIdSrc = input;
21247
        cert->extRawAuthKeyIdSz = sz;
21248
#endif /* OPENSSL_EXTRA */
21249
0
    }
21250
21251
0
    FREE_ASNGETDATA(dataASN, cert->heap);
21252
0
    return ret;
21253
0
#endif /* WOLFSSL_ASN_TEMPLATE */
21254
0
}
21255
21256
/* Decode subject key id extension in a certificate.
21257
 *
21258
 * X.509: RFC 5280, 4.2.1.2 - Subject Key Identifier.
21259
 *
21260
 * @param [in]      input  Buffer holding data.
21261
 * @param [in]      sz     Size of data in buffer.
21262
 * @param [in, out] cert   Certificate object.
21263
 * @return  0 on success.
21264
 * @return  ASN_PARSE_E when the OCTET_STRING tag is not found or length is
21265
 *          invalid.
21266
 * @return  MEMORY_E on dynamic memory allocation failure.
21267
 */
21268
static int DecodeSubjKeyId(const byte* input, word32 sz, DecodedCert* cert)
21269
0
{
21270
0
    word32 idx = 0;
21271
0
    int length = 0;
21272
0
    int ret = 0;
21273
21274
0
    WOLFSSL_ENTER("DecodeSubjKeyId");
21275
21276
0
    ret = GetOctetString(input, &idx, &length, sz);
21277
0
    if (ret > 0) {
21278
0
        cert->extSubjKeyIdSz = (word32)length;
21279
    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
21280
        cert->extSubjKeyIdSrc = &input[idx];
21281
    #endif /* OPENSSL_EXTRA */
21282
21283
        /* Get the hash or hash of the hash if wrong size. */
21284
0
        ret = GetHashId(input + idx, length, cert->extSubjKeyId,
21285
0
            HashIdAlg(cert->signatureOID));
21286
0
    }
21287
21288
0
    return ret;
21289
0
}
21290
21291
#ifdef WOLFSSL_ASN_TEMPLATE
21292
/* ASN.1 template for KeyUsage.
21293
 * X.509: RFC 5280, 4.2.1.3 - Key Usage.
21294
 */
21295
static const ASNItem keyUsageASN[] = {
21296
/* STR */ { 0, ASN_BIT_STRING, 0, 0, 0 },
21297
};
21298
enum {
21299
    KEYUSAGEASN_IDX_STR = 0
21300
};
21301
21302
/* Number of items in ASN.1 template for KeyUsage. */
21303
0
#define keyUsageASN_Length (sizeof(keyUsageASN) / sizeof(ASNItem))
21304
#endif
21305
21306
/* Decode key usage extension in a certificate.
21307
 *
21308
 * X.509: RFC 5280, 4.2.1.3 - Key Usage.
21309
 *
21310
 * @param [in]      input  Buffer holding data.
21311
 * @param [in]      sz     Size of data in buffer.
21312
 * @param [in, out] cert   Certificate object.
21313
 * @return  0 on success.
21314
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
21315
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
21316
 *          is invalid.
21317
 * @return  MEMORY_E on dynamic memory allocation failure.
21318
 */
21319
static int DecodeKeyUsage(const byte* input, word32 sz, DecodedCert* cert)
21320
0
{
21321
#ifndef WOLFSSL_ASN_TEMPLATE
21322
    word32 idx = 0;
21323
    int length;
21324
    int ret;
21325
    WOLFSSL_ENTER("DecodeKeyUsage");
21326
21327
    ret = CheckBitString(input, &idx, &length, sz, 0, NULL);
21328
    if (ret != 0)
21329
        return ret;
21330
21331
    if (length == 0 || length > 2)
21332
        return ASN_PARSE_E;
21333
21334
    cert->extKeyUsage = (word16)(input[idx]);
21335
    if (length == 2)
21336
        cert->extKeyUsage |= (word16)(input[idx+1] << 8);
21337
21338
    return 0;
21339
#else
21340
0
    ASNGetData dataASN[keyUsageASN_Length];
21341
0
    word32 idx = 0;
21342
0
    byte keyUsage[2];
21343
0
    word32 keyUsageSz = sizeof(keyUsage);
21344
0
    int ret;
21345
0
    WOLFSSL_ENTER("DecodeKeyUsage");
21346
21347
    /* Clear dynamic data and set where to store extended key usage. */
21348
0
    XMEMSET(dataASN, 0, sizeof(dataASN));
21349
0
    XMEMSET(keyUsage, 0, sizeof(keyUsage));
21350
0
    GetASN_Buffer(&dataASN[KEYUSAGEASN_IDX_STR], keyUsage, &keyUsageSz);
21351
    /* Parse key usage. */
21352
0
    ret = GetASN_Items(keyUsageASN, dataASN, keyUsageASN_Length, 0, input,
21353
0
                        &idx, sz);
21354
0
    if (ret == 0) {
21355
        /* Decode the bit string number as LE */
21356
0
        cert->extKeyUsage = (word16)(keyUsage[0]);
21357
0
        if (keyUsageSz == 2)
21358
0
            cert->extKeyUsage |= (word16)(keyUsage[1] << 8);
21359
0
    }
21360
0
    return ret;
21361
0
#endif /* WOLFSSL_ASN_TEMPLATE */
21362
0
}
21363
21364
#ifdef WOLFSSL_ASN_TEMPLATE
21365
/* ASN.1 template for KeyPurposeId.
21366
 * X.509: RFC 5280, 4.2.1.12 - Extended Key Usage.
21367
 */
21368
static const ASNItem keyPurposeIdASN[] = {
21369
/* OID */ { 0, ASN_OBJECT_ID, 0, 0, 0 },
21370
};
21371
enum {
21372
    KEYPURPOSEIDASN_IDX_OID = 0
21373
};
21374
21375
/* Number of items in ASN.1 template for KeyPurposeId. */
21376
0
#define keyPurposeIdASN_Length (sizeof(keyPurposeIdASN) / sizeof(ASNItem))
21377
#endif
21378
21379
/* Decode extended key usage extension in a certificate.
21380
 *
21381
 * X.509: RFC 5280, 4.2.1.12 - Extended Key Usage.
21382
 *
21383
 * @param [in]      input  Buffer holding data.
21384
 * @param [in]      sz     Size of data in buffer.
21385
 * @param [in, out] cert   Certificate object.
21386
 * @return  0 on success.
21387
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
21388
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
21389
 *          is invalid.
21390
 * @return  MEMORY_E on dynamic memory allocation failure.
21391
 */
21392
static int DecodeExtKeyUsage(const byte* input, word32 sz, DecodedCert* cert)
21393
0
{
21394
#ifndef WOLFSSL_ASN_TEMPLATE
21395
    word32 idx = 0, oid;
21396
    int length, ret;
21397
21398
    WOLFSSL_ENTER("DecodeExtKeyUsage");
21399
21400
    if (GetSequence(input, &idx, &length, sz) < 0) {
21401
        WOLFSSL_MSG("\tfail: should be a SEQUENCE");
21402
        return ASN_PARSE_E;
21403
    }
21404
21405
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
21406
    cert->extExtKeyUsageSrc = input + idx;
21407
    cert->extExtKeyUsageSz = length;
21408
#endif
21409
21410
    while (idx < (word32)sz) {
21411
        ret = GetObjectId(input, &idx, &oid, oidCertKeyUseType, sz);
21412
        if (ret == WC_NO_ERR_TRACE(ASN_UNKNOWN_OID_E))
21413
            continue;
21414
        else if (ret < 0)
21415
            return ret;
21416
21417
        switch (oid) {
21418
            case EKU_ANY_OID:
21419
                cert->extExtKeyUsage |= EXTKEYUSE_ANY;
21420
                break;
21421
            case EKU_SERVER_AUTH_OID:
21422
                cert->extExtKeyUsage |= EXTKEYUSE_SERVER_AUTH;
21423
                break;
21424
            case EKU_CLIENT_AUTH_OID:
21425
                cert->extExtKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
21426
                break;
21427
            case EKU_CODESIGNING_OID:
21428
                cert->extExtKeyUsage |= EXTKEYUSE_CODESIGN;
21429
                break;
21430
            case EKU_EMAILPROTECT_OID:
21431
                cert->extExtKeyUsage |= EXTKEYUSE_EMAILPROT;
21432
                break;
21433
            case EKU_TIMESTAMP_OID:
21434
                cert->extExtKeyUsage |= EXTKEYUSE_TIMESTAMP;
21435
                break;
21436
            case EKU_OCSP_SIGN_OID:
21437
                cert->extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN;
21438
                break;
21439
            #ifdef WOLFSSL_WOLFSSH
21440
            case EKU_SSH_CLIENT_AUTH_OID:
21441
                cert->extExtKeyUsageSsh |= EXTKEYUSE_SSH_CLIENT_AUTH;
21442
                break;
21443
            case EKU_SSH_MSCL_OID:
21444
                cert->extExtKeyUsageSsh |= EXTKEYUSE_SSH_MSCL;
21445
                break;
21446
            case EKU_SSH_KP_CLIENT_AUTH_OID:
21447
                cert->extExtKeyUsageSsh |= EXTKEYUSE_SSH_KP_CLIENT_AUTH;
21448
                break;
21449
            #endif /* WOLFSSL_WOLFSSH */
21450
            default:
21451
                break;
21452
        }
21453
21454
    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
21455
        cert->extExtKeyUsageCount++;
21456
    #endif
21457
    }
21458
21459
    return 0;
21460
#else
21461
0
    word32 idx = 0;
21462
0
    int length;
21463
0
    int ret = 0;
21464
21465
0
    WOLFSSL_ENTER("DecodeExtKeyUsage");
21466
21467
    /* Strip SEQUENCE OF and expect to account for all the data. */
21468
0
    if (GetASN_Sequence(input, &idx, &length, sz, 1) < 0) {
21469
0
        WOLFSSL_MSG("\tfail: should be a SEQUENCE");
21470
0
        ret = ASN_PARSE_E;
21471
0
    }
21472
21473
0
    if (ret == 0) {
21474
    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
21475
        /* Keep reference for WOLFSSL_X509. */
21476
        cert->extExtKeyUsageSrc = input + idx;
21477
        cert->extExtKeyUsageSz = (word32)length;
21478
    #endif
21479
0
    }
21480
21481
    /* Check all OIDs. */
21482
0
    while ((ret == 0) && (idx < (word32)sz)) {
21483
0
        ASNGetData dataASN[keyPurposeIdASN_Length];
21484
21485
        /* Clear dynamic data items and set OID type expected. */
21486
0
        XMEMSET(dataASN, 0, sizeof(dataASN));
21487
0
        GetASN_OID(&dataASN[KEYPURPOSEIDASN_IDX_OID], oidIgnoreType);
21488
        /* Decode KeyPurposeId. */
21489
0
        ret = GetASN_Items(keyPurposeIdASN, dataASN, keyPurposeIdASN_Length, 0,
21490
0
                           input, &idx, sz);
21491
        /* Skip unknown OIDs. */
21492
0
        if (ret == WC_NO_ERR_TRACE(ASN_UNKNOWN_OID_E)) {
21493
0
            ret = 0;
21494
0
        }
21495
0
        else if (ret == 0) {
21496
            /* Store the bit for the OID. */
21497
0
            switch (dataASN[KEYPURPOSEIDASN_IDX_OID].data.oid.sum) {
21498
0
                case EKU_ANY_OID:
21499
0
                    cert->extExtKeyUsage |= EXTKEYUSE_ANY;
21500
0
                    break;
21501
0
                case EKU_SERVER_AUTH_OID:
21502
0
                    cert->extExtKeyUsage |= EXTKEYUSE_SERVER_AUTH;
21503
0
                    break;
21504
0
                case EKU_CLIENT_AUTH_OID:
21505
0
                    cert->extExtKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
21506
0
                    break;
21507
0
                case EKU_CODESIGNING_OID:
21508
0
                    cert->extExtKeyUsage |= EXTKEYUSE_CODESIGN;
21509
0
                    break;
21510
0
                case EKU_EMAILPROTECT_OID:
21511
0
                    cert->extExtKeyUsage |= EXTKEYUSE_EMAILPROT;
21512
0
                    break;
21513
0
                case EKU_TIMESTAMP_OID:
21514
0
                    cert->extExtKeyUsage |= EXTKEYUSE_TIMESTAMP;
21515
0
                    break;
21516
0
                case EKU_OCSP_SIGN_OID:
21517
0
                    cert->extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN;
21518
0
                    break;
21519
0
            }
21520
21521
        #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
21522
            /* Keep count for WOLFSSL_X509. */
21523
            cert->extExtKeyUsageCount++;
21524
        #endif
21525
0
        }
21526
0
    }
21527
21528
0
    return ret;
21529
0
#endif /* WOLFSSL_ASN_TEMPLATE */
21530
0
}
21531
21532
#ifndef IGNORE_NETSCAPE_CERT_TYPE
21533
21534
static int DecodeNsCertType(const byte* input, int sz, DecodedCert* cert)
21535
0
{
21536
0
    word32 idx = 0;
21537
0
    int len = 0;
21538
21539
0
    WOLFSSL_ENTER("DecodeNsCertType");
21540
21541
0
    if (CheckBitString(input, &idx, &len, (word32)sz, 0, NULL) < 0)
21542
0
        return ASN_PARSE_E;
21543
21544
    /* Don't need to worry about unused bits as CheckBitString makes sure
21545
     * they're zero. */
21546
0
    if (idx < (word32)sz)
21547
0
        cert->nsCertType = input[idx];
21548
0
    else
21549
0
        return ASN_PARSE_E;
21550
21551
0
    return 0;
21552
0
}
21553
#endif
21554
21555
21556
#ifndef IGNORE_NAME_CONSTRAINTS
21557
#ifdef WOLFSSL_ASN_TEMPLATE
21558
/* ASN.1 template for GeneralSubtree.
21559
 * X.509: RFC 5280, 4.2.1.10 - Name Constraints.
21560
 */
21561
static const ASNItem subTreeASN[] = {
21562
/* SEQ  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
21563
                              /* base     GeneralName */
21564
/* BASE */     { 1, ASN_CONTEXT_SPECIFIC | 0, 0, 0, 0 },
21565
                              /* minimum  BaseDistance DEFAULT 0*/
21566
/* MIN  */     { 1, ASN_CONTEXT_SPECIFIC | ASN_SUBTREE_MIN, 0, 0, 1 },
21567
                              /* maximum  BaseDistance OPTIONAL  */
21568
/* MAX  */     { 1, ASN_CONTEXT_SPECIFIC | ASN_SUBTREE_MAX, 0, 0, 1 },
21569
};
21570
enum {
21571
    SUBTREEASN_IDX_SEQ = 0,
21572
    SUBTREEASN_IDX_BASE,
21573
    SUBTREEASN_IDX_MIN,
21574
    SUBTREEASN_IDX_MAX
21575
};
21576
21577
/* Number of items in ASN.1 template for GeneralSubtree. */
21578
0
#define subTreeASN_Length (sizeof(subTreeASN) / sizeof(ASNItem))
21579
#endif
21580
21581
#ifdef WOLFSSL_ASN_TEMPLATE
21582
/* Decode the Subtree's GeneralName.
21583
 *
21584
 * @param [in]      input  Buffer holding data.
21585
 * @param [in]      sz     Size of data in buffer.
21586
 * @param [in]      tag    BER tag on GeneralName.
21587
 * @param [in, out] head   Linked list of subtree names.
21588
 * @param [in]      heap   Dynamic memory hint.
21589
 * @return  0 on success.
21590
 * @return  MEMORY_E when dynamic memory allocation fails.
21591
 * @return  ASN_PARSE_E when SEQUENCE is not found as expected.
21592
 */
21593
static int DecodeSubtreeGeneralName(const byte* input, word32 sz, byte tag,
21594
                                    Base_entry** head, void* heap)
21595
0
{
21596
0
    Base_entry* entry = NULL;
21597
0
    word32 nameIdx = 0;
21598
0
    word32 len = sz;
21599
0
    int strLen;
21600
0
    int ret = 0;
21601
21602
0
    (void)heap;
21603
21604
    /* if constructed has leading sequence */
21605
0
    if ((tag & ASN_CONSTRUCTED) == ASN_CONSTRUCTED) {
21606
0
        ret = GetASN_Sequence(input, &nameIdx, &strLen, sz, 0);
21607
0
        if (ret < 0) {
21608
0
            ret = ASN_PARSE_E;
21609
0
        }
21610
0
        else {
21611
0
            len = (word32)strLen;
21612
0
            ret = 0;
21613
0
        }
21614
0
    }
21615
0
    if (ret == 0) {
21616
        /* TODO: consider one malloc. */
21617
        /* Allocate Base Entry object. */
21618
0
        entry = (Base_entry*)XMALLOC(sizeof(Base_entry), heap,
21619
0
                                     DYNAMIC_TYPE_ALTNAME);
21620
0
        if (entry == NULL) {
21621
0
            ret = MEMORY_E;
21622
0
        }
21623
0
    }
21624
0
    if (ret == 0) {
21625
        /* Allocate name. */
21626
0
        entry->name = (char*)XMALLOC(len + 1, heap, DYNAMIC_TYPE_ALTNAME);
21627
0
        if (entry->name == NULL) {
21628
0
            XFREE(entry, heap, DYNAMIC_TYPE_ALTNAME);
21629
0
            ret = MEMORY_E;
21630
0
        }
21631
0
    }
21632
0
    if (ret == 0) {
21633
        /* Store name, size and tag in object. */
21634
0
        XMEMCPY(entry->name, &input[nameIdx], len);
21635
0
        entry->name[len] = '\0';
21636
0
        entry->nameSz = (int)len;
21637
0
        entry->type = tag & ASN_TYPE_MASK;
21638
21639
        /* Put entry at front of linked list. */
21640
0
        entry->next = *head;
21641
0
        *head = entry;
21642
0
    }
21643
21644
0
    return ret;
21645
0
}
21646
#endif
21647
21648
/* Decode a subtree of a name constraints in a certificate.
21649
 *
21650
 * X.509: RFC 5280, 4.2.1.10 - Name Constraints.
21651
 *
21652
 * @param [in]      input  Buffer holding data.
21653
 * @param [in]      sz     Size of data in buffer.
21654
 * @param [in, out] head   Linked list of subtree names.
21655
 * @param [in]      limit  If > 0, limit on number of tree
21656
 *                         entries to  process, exceeding
21657
 *                         is an error.
21658
 * @param [in]      heap   Dynamic memory hint.
21659
 * @return  0 on success.
21660
 * @return  MEMORY_E when dynamic memory allocation fails.
21661
 * @return  ASN_PARSE_E when SEQUENCE is not found as expected.
21662
 */
21663
static int DecodeSubtree(const byte* input, word32 sz, Base_entry** head,
21664
                         word32 limit, void* heap)
21665
0
{
21666
#ifndef WOLFSSL_ASN_TEMPLATE
21667
    word32 idx = 0;
21668
    int ret = 0;
21669
    word32 cnt = 0;
21670
21671
    (void)heap;
21672
21673
    while (idx < (word32)sz) {
21674
        int seqLength, strLength;
21675
        word32 nameIdx;
21676
        byte b, bType;
21677
21678
        if (limit > 0) {
21679
            cnt++;
21680
            if (cnt > limit) {
21681
                WOLFSSL_MSG("too many name constraints");
21682
                return ASN_NAME_INVALID_E;
21683
            }
21684
        }
21685
21686
        if (GetSequence(input, &idx, &seqLength, sz) < 0) {
21687
            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
21688
            return ASN_PARSE_E;
21689
        }
21690
21691
        if (idx >= (word32)sz) {
21692
            WOLFSSL_MSG("\tfail: expecting tag");
21693
            return ASN_PARSE_E;
21694
        }
21695
21696
        nameIdx = idx;
21697
        b = input[nameIdx++];
21698
21699
        if (GetLength(input, &nameIdx, &strLength, sz) <= 0) {
21700
            WOLFSSL_MSG("\tinvalid length");
21701
            return ASN_PARSE_E;
21702
        }
21703
21704
        /* Get type, LSB 4-bits */
21705
        bType = (byte)(b & ASN_TYPE_MASK);
21706
21707
        if (bType == ASN_DNS_TYPE || bType == ASN_RFC822_TYPE ||
21708
                                                        bType == ASN_DIR_TYPE) {
21709
            Base_entry* entry;
21710
21711
            /* if constructed has leading sequence */
21712
            if (b & ASN_CONSTRUCTED) {
21713
                if (GetSequence(input, &nameIdx, &strLength, sz) < 0) {
21714
                    WOLFSSL_MSG("\tfail: constructed be a SEQUENCE");
21715
                    return ASN_PARSE_E;
21716
                }
21717
            }
21718
21719
            entry = (Base_entry*)XMALLOC(sizeof(Base_entry), heap,
21720
                                                          DYNAMIC_TYPE_ALTNAME);
21721
            if (entry == NULL) {
21722
                WOLFSSL_MSG("allocate error");
21723
                return MEMORY_E;
21724
            }
21725
21726
            entry->name = (char*)XMALLOC((size_t)strLength+1, heap,
21727
                DYNAMIC_TYPE_ALTNAME);
21728
            if (entry->name == NULL) {
21729
                WOLFSSL_MSG("allocate error");
21730
                XFREE(entry, heap, DYNAMIC_TYPE_ALTNAME);
21731
                return MEMORY_E;
21732
            }
21733
21734
            XMEMCPY(entry->name, &input[nameIdx], (size_t)strLength);
21735
            entry->name[strLength] = '\0';
21736
            entry->nameSz = strLength;
21737
            entry->type = bType;
21738
21739
            entry->next = *head;
21740
            *head = entry;
21741
        }
21742
21743
        idx += (word32)seqLength;
21744
    }
21745
21746
    return ret;
21747
#else
21748
0
    DECL_ASNGETDATA(dataASN, subTreeASN_Length);
21749
0
    word32 idx = 0;
21750
0
    int ret = 0;
21751
0
    word32 cnt = 0;
21752
21753
0
    (void)heap;
21754
21755
0
    ALLOC_ASNGETDATA(dataASN, subTreeASN_Length, ret, heap);
21756
21757
    /* Process all subtrees. */
21758
0
    while ((ret == 0) && (idx < (word32)sz)) {
21759
0
        byte minVal = 0;
21760
0
        byte maxVal = 0;
21761
0
        if (limit > 0) {
21762
0
            cnt++;
21763
0
            if (cnt > limit) {
21764
0
                WOLFSSL_MSG("too many name constraints");
21765
0
                ret = ASN_NAME_INVALID_E;
21766
0
                break;
21767
0
            }
21768
0
        }
21769
21770
        /* Clear dynamic data and set choice for GeneralName and location to
21771
         * store minimum and maximum.
21772
         */
21773
0
        XMEMSET(dataASN, 0, sizeof(*dataASN) * subTreeASN_Length);
21774
0
        GetASN_Choice(&dataASN[SUBTREEASN_IDX_BASE], generalNameChoice);
21775
0
        GetASN_Int8Bit(&dataASN[SUBTREEASN_IDX_MIN], &minVal);
21776
0
        GetASN_Int8Bit(&dataASN[SUBTREEASN_IDX_MAX], &maxVal);
21777
        /* Parse GeneralSubtree. */
21778
0
        ret = GetASN_Items(subTreeASN, dataASN, subTreeASN_Length, 0, input,
21779
0
                           &idx, sz);
21780
0
        if (ret == 0) {
21781
0
            byte t = dataASN[SUBTREEASN_IDX_BASE].tag;
21782
21783
            /* Check GeneralName tag is one of the types we can handle. */
21784
0
            if (t == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE) ||
21785
0
                t == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE) ||
21786
0
                t == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_DIR_TYPE)) {
21787
                /* Parse the general name and store a new entry. */
21788
0
                ret = DecodeSubtreeGeneralName(input +
21789
0
                    GetASNItem_DataIdx(dataASN[SUBTREEASN_IDX_BASE], input),
21790
0
                    dataASN[SUBTREEASN_IDX_BASE].length, t, head, heap);
21791
0
            }
21792
            /* Skip entry. */
21793
0
        }
21794
0
    }
21795
21796
0
    FREE_ASNGETDATA(dataASN, heap);
21797
0
    return ret;
21798
0
#endif
21799
0
}
21800
21801
#ifdef WOLFSSL_ASN_TEMPLATE
21802
/* ASN.1 template for NameConstraints.
21803
 * X.509: RFC 5280, 4.2.1.10 - Name Constraints.
21804
 */
21805
static const ASNItem nameConstraintsASN[] = {
21806
/* SEQ     */ { 0, ASN_SEQUENCE, 1, 1, 0 },
21807
                                         /* permittedSubtrees */
21808
/* PERMIT  */     { 1, ASN_CONTEXT_SPECIFIC | 0, 1, 0, 1 },
21809
                                         /* excludededSubtrees */
21810
/* EXCLUDE */     { 1, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 1 },
21811
};
21812
enum {
21813
    NAMECONSTRAINTSASN_IDX_SEQ = 0,
21814
    NAMECONSTRAINTSASN_IDX_PERMIT,
21815
    NAMECONSTRAINTSASN_IDX_EXCLUDE
21816
};
21817
21818
/* Number of items in ASN.1 template for NameConstraints. */
21819
0
#define nameConstraintsASN_Length (sizeof(nameConstraintsASN) / sizeof(ASNItem))
21820
#endif
21821
21822
/* Decode name constraints extension in a certificate.
21823
 *
21824
 * X.509: RFC 5280, 4.2.1.10 - Name Constraints.
21825
 *
21826
 * @param [in]      input  Buffer holding data.
21827
 * @param [in]      sz     Size of data in buffer.
21828
 * @param [in, out] cert   Certificate object.
21829
 * @return  0 on success.
21830
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
21831
 *          is invalid.
21832
 * @return  MEMORY_E on dynamic memory allocation failure.
21833
 */
21834
static int DecodeNameConstraints(const byte* input, word32 sz,
21835
    DecodedCert* cert)
21836
0
{
21837
#ifndef WOLFSSL_ASN_TEMPLATE
21838
    word32 idx = 0;
21839
    int length = 0;
21840
21841
    WOLFSSL_ENTER("DecodeNameConstraints");
21842
21843
    if (GetSequence(input, &idx, &length, sz) < 0) {
21844
        WOLFSSL_MSG("\tfail: should be a SEQUENCE");
21845
        return ASN_PARSE_E;
21846
    }
21847
21848
    while (idx < (word32)sz) {
21849
        byte b = input[idx++];
21850
        Base_entry** subtree = NULL;
21851
21852
        if (GetLength(input, &idx, &length, sz) <= 0) {
21853
            WOLFSSL_MSG("\tinvalid length");
21854
            return ASN_PARSE_E;
21855
        }
21856
21857
        if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0))
21858
            subtree = &cert->permittedNames;
21859
        else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1))
21860
            subtree = &cert->excludedNames;
21861
        else {
21862
            WOLFSSL_MSG("\tinvalid subtree");
21863
            return ASN_PARSE_E;
21864
        }
21865
21866
        if (DecodeSubtree(input + idx, (word32)length, subtree,
21867
                WOLFSSL_MAX_NAME_CONSTRAINTS, cert->heap) < 0) {
21868
            WOLFSSL_MSG("\terror parsing subtree");
21869
            return ASN_PARSE_E;
21870
        }
21871
21872
        idx += (word32)length;
21873
    }
21874
21875
    return 0;
21876
#else
21877
0
    DECL_ASNGETDATA(dataASN, nameConstraintsASN_Length);
21878
0
    word32 idx = 0;
21879
0
    int    ret = 0;
21880
21881
0
    CALLOC_ASNGETDATA(dataASN, nameConstraintsASN_Length, ret, cert->heap);
21882
21883
0
    if (ret == 0) {
21884
        /* Parse NameConstraints. */
21885
0
        ret = GetASN_Items(nameConstraintsASN, dataASN,
21886
0
                           nameConstraintsASN_Length, 1, input, &idx, sz);
21887
0
    }
21888
0
    if (ret == 0) {
21889
        /* If there was a permittedSubtrees then parse it. */
21890
0
        if (dataASN[NAMECONSTRAINTSASN_IDX_PERMIT].data.ref.data != NULL) {
21891
0
            ret = DecodeSubtree(
21892
0
                    dataASN[NAMECONSTRAINTSASN_IDX_PERMIT].data.ref.data,
21893
0
                    dataASN[NAMECONSTRAINTSASN_IDX_PERMIT].data.ref.length,
21894
0
                    &cert->permittedNames, WOLFSSL_MAX_NAME_CONSTRAINTS,
21895
0
                    cert->heap);
21896
0
        }
21897
0
    }
21898
0
    if (ret == 0) {
21899
        /* If there was a excludedSubtrees then parse it. */
21900
0
        if (dataASN[NAMECONSTRAINTSASN_IDX_EXCLUDE].data.ref.data != NULL) {
21901
0
            ret = DecodeSubtree(
21902
0
                    dataASN[NAMECONSTRAINTSASN_IDX_EXCLUDE].data.ref.data,
21903
0
                    dataASN[NAMECONSTRAINTSASN_IDX_EXCLUDE].data.ref.length,
21904
0
                    &cert->excludedNames, WOLFSSL_MAX_NAME_CONSTRAINTS,
21905
0
                    cert->heap);
21906
0
        }
21907
0
    }
21908
21909
0
    FREE_ASNGETDATA(dataASN, cert->heap);
21910
21911
0
    return ret;
21912
0
#endif /* WOLFSSL_ASN_TEMPLATE */
21913
0
}
21914
#endif /* IGNORE_NAME_CONSTRAINTS */
21915
21916
#if defined(WOLFSSL_CERT_EXT) || \
21917
    defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
21918
21919
/* Decode ITU-T X.690 OID format to a string representation
21920
 * return string length */
21921
int DecodePolicyOID(char *out, word32 outSz, const byte *in, word32 inSz)
21922
{
21923
    word32 val, inIdx = 0, outIdx = 0;
21924
    int w = 0;
21925
21926
    if (out == NULL || in == NULL || outSz < 4 || inSz < 2)
21927
        return BAD_FUNC_ARG;
21928
21929
    /* The first byte expands into b/40 dot b%40. */
21930
    val = in[inIdx++];
21931
21932
    w = XSNPRINTF(out, outSz, "%u.%u", val / 40, val % 40);
21933
    if (w < 0) {
21934
        w = BUFFER_E;
21935
        goto exit;
21936
    }
21937
    outIdx += (word32)w;
21938
    val = 0;
21939
21940
    while (inIdx < inSz && outIdx < outSz) {
21941
        /* extract the next OID digit from in to val */
21942
        /* first bit is used to set if value is coded on 1 or multiple bytes */
21943
        if (in[inIdx] & 0x80) {
21944
            val += in[inIdx] & 0x7F;
21945
            val *= 128;
21946
        }
21947
        else {
21948
            /* write val as text into out */
21949
            val += in[inIdx];
21950
            w = XSNPRINTF(out + outIdx, outSz - outIdx, ".%u", val);
21951
            if (w < 0 || (word32)w > outSz - outIdx) {
21952
                w = BUFFER_E;
21953
                goto exit;
21954
            }
21955
            outIdx += (word32)w;
21956
            val = 0;
21957
        }
21958
        inIdx++;
21959
    }
21960
    if (outIdx == outSz)
21961
        outIdx--;
21962
    out[outIdx] = 0;
21963
21964
    w = (int)outIdx;
21965
21966
exit:
21967
    return w;
21968
}
21969
#endif /* WOLFSSL_CERT_EXT || OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
21970
21971
#if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT)
21972
#ifdef WOLFSSL_ASN_TEMPLATE
21973
    /* ASN.1 template for PolicyInformation.
21974
     * X.509: RFC 5280, 4.2.1.4 - Certificate Policies.
21975
     */
21976
    static const ASNItem policyInfoASN[] = {
21977
    /* SEQ   */ { 0, ASN_SEQUENCE, 1, 1, 0 },
21978
                                      /* policyIdentifier */
21979
    /* ID    */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
21980
                                      /* policyQualifiers */
21981
    /* QUALI */     { 1, ASN_SEQUENCE, 1, 0, 1 },
21982
    };
21983
    enum {
21984
        POLICYINFOASN_IDX_SEQ = 0,
21985
        POLICYINFOASN_IDX_ID,
21986
        POLICYINFOASN_IDX_QUALI
21987
    };
21988
21989
    /* Number of items in ASN.1 template for PolicyInformation. */
21990
    #define policyInfoASN_Length (sizeof(policyInfoASN) / sizeof(ASNItem))
21991
#endif
21992
21993
/* Reference: https://tools.ietf.org/html/rfc5280#section-4.2.1.4 */
21994
static int DecodeCertPolicy(const byte* input, word32 sz, DecodedCert* cert)
21995
{
21996
#ifndef WOLFSSL_ASN_TEMPLATE
21997
    word32 idx = 0;
21998
    word32 oldIdx;
21999
    int policy_length = 0;
22000
    int ret;
22001
    int total_length = 0;
22002
#if defined(WOLFSSL_CERT_EXT) && !defined(WOLFSSL_DUP_CERTPOL)
22003
    int i;
22004
#endif
22005
22006
    WOLFSSL_ENTER("DecodeCertPolicy");
22007
22008
    /* Check if cert is null before dereferencing below */
22009
    if (cert == NULL)
22010
        return BAD_FUNC_ARG;
22011
22012
#if defined(WOLFSSL_CERT_EXT)
22013
        cert->extCertPoliciesNb = 0;
22014
#endif
22015
22016
    if (GetSequence(input, &idx, &total_length, sz) < 0) {
22017
        WOLFSSL_MSG("\tGet CertPolicy total seq failed");
22018
        return ASN_PARSE_E;
22019
    }
22020
22021
    /* Validate total length */
22022
    if (total_length > (int)(sz - idx)) {
22023
        WOLFSSL_MSG("\tCertPolicy length mismatch");
22024
        return ASN_PARSE_E;
22025
    }
22026
22027
    /* Unwrap certificatePolicies */
22028
    do {
22029
        int length = 0;
22030
22031
        if (GetSequence(input, &idx, &policy_length, sz) < 0) {
22032
            WOLFSSL_MSG("\tGet CertPolicy seq failed");
22033
            return ASN_PARSE_E;
22034
        }
22035
22036
        oldIdx = idx;
22037
        ret = GetASNObjectId(input, &idx, &length, sz);
22038
        if (ret != 0)
22039
            return ret;
22040
        policy_length -= (int)(idx - oldIdx);
22041
22042
        if (length > 0) {
22043
            /* Verify length won't overrun buffer */
22044
            if (length > (int)(sz - idx)) {
22045
                WOLFSSL_MSG("\tCertPolicy length exceeds input buffer");
22046
                return ASN_PARSE_E;
22047
            }
22048
22049
    #ifdef WOLFSSL_SEP
22050
            if (cert->deviceType == NULL) {
22051
                cert->deviceType = (byte*)XMALLOC((size_t)length, cert->heap,
22052
                                                        DYNAMIC_TYPE_X509_EXT);
22053
                if (cert->deviceType == NULL) {
22054
                    WOLFSSL_MSG("\tCouldn't alloc memory for deviceType");
22055
                    return MEMORY_E;
22056
                }
22057
                cert->deviceTypeSz = length;
22058
                XMEMCPY(cert->deviceType, input + idx, (size_t)length);
22059
            }
22060
    #endif
22061
22062
    #ifdef WOLFSSL_CERT_EXT
22063
            /* decode cert policy */
22064
            if (DecodePolicyOID(cert->extCertPolicies[
22065
                                cert->extCertPoliciesNb], MAX_CERTPOL_SZ,
22066
                                input + idx, length) <= 0) {
22067
                WOLFSSL_MSG("\tCouldn't decode CertPolicy");
22068
                WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
22069
                return ASN_PARSE_E;
22070
            }
22071
        #ifndef WOLFSSL_DUP_CERTPOL
22072
            /* From RFC 5280 section 4.2.1.4 "A certificate policy OID MUST
22073
             * NOT appear more than once in a certificate policies
22074
             * extension". This is a sanity check for duplicates.
22075
             * extCertPolicies should only have OID values, additional
22076
             * qualifiers need to be stored in a separate array. */
22077
            for (i = 0; i < cert->extCertPoliciesNb; i++) {
22078
                if (XMEMCMP(cert->extCertPolicies[i],
22079
                            cert->extCertPolicies[cert->extCertPoliciesNb],
22080
                            MAX_CERTPOL_SZ) == 0) {
22081
                    WOLFSSL_MSG("Duplicate policy OIDs not allowed");
22082
                    WOLFSSL_MSG("Use WOLFSSL_DUP_CERTPOL if wanted");
22083
                    WOLFSSL_ERROR_VERBOSE(CERTPOLICIES_E);
22084
                    return CERTPOLICIES_E;
22085
                }
22086
            }
22087
        #endif /* !WOLFSSL_DUP_CERTPOL */
22088
            cert->extCertPoliciesNb++;
22089
    #endif
22090
        }
22091
        idx += (word32)policy_length;
22092
    } while((int)idx < total_length
22093
    #ifdef WOLFSSL_CERT_EXT
22094
        && cert->extCertPoliciesNb < MAX_CERTPOL_NB
22095
    #endif
22096
    );
22097
22098
    WOLFSSL_LEAVE("DecodeCertPolicy", 0);
22099
    return 0;
22100
#else /* WOLFSSL_ASN_TEMPLATE */
22101
    word32 idx = 0;
22102
    int ret = 0;
22103
    int total_length = 0;
22104
#if defined(WOLFSSL_CERT_EXT) && !defined(WOLFSSL_DUP_CERTPOL)
22105
    int i;
22106
#endif
22107
22108
    WOLFSSL_ENTER("DecodeCertPolicy");
22109
22110
    /* Check if cert is null before dereferencing below */
22111
    if (cert == NULL) {
22112
        ret = BAD_FUNC_ARG;
22113
    }
22114
22115
    if (ret == 0) {
22116
    #if defined(WOLFSSL_CERT_EXT)
22117
        cert->extCertPoliciesNb = 0;
22118
    #endif
22119
22120
        /* Strip SEQUENCE OF and check using all data. */
22121
        if (GetASN_Sequence(input, &idx, &total_length, (word32)sz, 1) < 0)
22122
        {
22123
            ret = ASN_PARSE_E;
22124
        }
22125
    }
22126
22127
    /* Unwrap certificatePolicies */
22128
    while ((ret == 0) && ((int)idx < total_length)
22129
    #if defined(WOLFSSL_CERT_EXT)
22130
        && (cert->extCertPoliciesNb < MAX_CERTPOL_NB)
22131
    #endif
22132
            ) {
22133
        ASNGetData dataASN[policyInfoASN_Length];
22134
        byte* data = NULL;
22135
        word32 length = 0;
22136
22137
        /* Clear dynamic data and check OID is a cert policy type. */
22138
        XMEMSET(dataASN, 0, sizeof(dataASN));
22139
        GetASN_OID(&dataASN[POLICYINFOASN_IDX_ID], oidCertPolicyType);
22140
        ret = GetASN_Items(policyInfoASN, dataASN, policyInfoASN_Length, 1,
22141
                            input, &idx, (word32)sz);
22142
        if (ret == 0) {
22143
            /* Get the OID. */
22144
            GetASN_OIDData(&dataASN[POLICYINFOASN_IDX_ID], &data, &length);
22145
            if (length == 0) {
22146
                ret = ASN_PARSE_E;
22147
            }
22148
        }
22149
    #ifdef WOLFSSL_SEP
22150
        /* Store OID in device type. */
22151
        if (ret == 0 && cert->deviceType == NULL) {
22152
            cert->deviceType = (byte*)XMALLOC(length, cert->heap,
22153
                                                DYNAMIC_TYPE_X509_EXT);
22154
            if (cert->deviceType != NULL) {
22155
                /* Store device type data and length. */
22156
                cert->deviceTypeSz = (int)length;
22157
                XMEMCPY(cert->deviceType, data, length);
22158
            }
22159
            else {
22160
                WOLFSSL_MSG("\tCouldn't alloc memory for deviceType");
22161
                ret = MEMORY_E;
22162
            }
22163
        }
22164
    #endif /* WOLFSSL_SEP */
22165
22166
    #ifdef WOLFSSL_CERT_EXT
22167
        if (ret == 0) {
22168
            /* Decode cert policy. */
22169
            if (DecodePolicyOID(
22170
                    cert->extCertPolicies[cert->extCertPoliciesNb],
22171
                    MAX_CERTPOL_SZ, data, length) <= 0) {
22172
                WOLFSSL_MSG("\tCouldn't decode CertPolicy");
22173
                WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
22174
                ret = ASN_PARSE_E;
22175
            }
22176
        }
22177
        #ifndef WOLFSSL_DUP_CERTPOL
22178
        /* From RFC 5280 section 4.2.1.4 "A certificate policy OID MUST
22179
         * NOT appear more than once in a certificate policies
22180
         * extension". This is a sanity check for duplicates.
22181
         * extCertPolicies should only have OID values, additional
22182
         * qualifiers need to be stored in a separate array. */
22183
        for (i = 0; (ret == 0) && (i < cert->extCertPoliciesNb); i++) {
22184
            if (XMEMCMP(cert->extCertPolicies[i],
22185
                        cert->extCertPolicies[cert->extCertPoliciesNb],
22186
                        MAX_CERTPOL_SZ) == 0) {
22187
                WOLFSSL_MSG("Duplicate policy OIDs not allowed");
22188
                WOLFSSL_MSG("Use WOLFSSL_DUP_CERTPOL if wanted");
22189
                WOLFSSL_ERROR_VERBOSE(CERTPOLICIES_E);
22190
                ret = CERTPOLICIES_E;
22191
            }
22192
        }
22193
        #endif /* !WOLFSSL_DUP_CERTPOL */
22194
        if (ret == 0) {
22195
            /* Keep count of policies seen. */
22196
            cert->extCertPoliciesNb++;
22197
        }
22198
    #endif /* WOLFSSL_CERT_EXT */
22199
    }
22200
22201
    WOLFSSL_LEAVE("DecodeCertPolicy", 0);
22202
    return ret;
22203
#endif /* WOLFSSL_ASN_TEMPLATE */
22204
}
22205
#endif /* WOLFSSL_SEP || WOLFSSL_CERT_EXT  */
22206
22207
#ifdef WOLFSSL_SUBJ_DIR_ATTR
22208
#ifdef WOLFSSL_ASN_TEMPLATE
22209
/* ASN.1 template for subject dir attribute.
22210
 * X.509: RFC 5280, 4.2.1.8 - Subject Directory Attributes.
22211
 */
22212
static const ASNItem subjDirAttrASN[] = {
22213
/* SEQ  */     { 1, ASN_SEQUENCE, 1, 1, 0 },
22214
/* OID  */          { 2, ASN_OBJECT_ID, 0, 0, 0 },
22215
/* PLEN */          { 2, ASN_SET, 1, 0, 0 },
22216
};
22217
enum {
22218
    SUBJDIRATTRASN_IDX_SEQ = 0,
22219
    SUBJDIRATTRASN_IDX_OID,
22220
    SUBJDIRATTRASN_IDX_SET
22221
};
22222
22223
/* Number of items in ASN.1 template for BasicConstraints. */
22224
#define subjDirAttrASN_Length (sizeof(subjDirAttrASN) / sizeof(ASNItem))
22225
#endif
22226
/* Decode subject directory attributes extension in a certificate.
22227
 *
22228
 * X.509: RFC 5280, 4.2.1.8 - Subject Directory Attributes.
22229
 *
22230
 * @param [in]      input  Buffer holding data.
22231
 * @param [in]      sz     Size of data in buffer.
22232
 * @param [in, out] cert   Certificate object.
22233
 * @return  0 on success.
22234
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
22235
 *          is invalid.
22236
 */
22237
static int DecodeSubjDirAttr(const byte* input, word32 sz, DecodedCert* cert)
22238
{
22239
#ifndef WOLFSSL_ASN_TEMPLATE
22240
    word32 idx = 0;
22241
    int length = 0;
22242
    int ret = 0;
22243
22244
    WOLFSSL_ENTER("DecodeSubjDirAttr");
22245
22246
#ifdef OPENSSL_ALL
22247
    cert->extSubjDirAttrSrc = input;
22248
    cert->extSubjDirAttrSz = sz;
22249
#endif /* OPENSSL_ALL */
22250
22251
    /* Unwrap the list of Attributes */
22252
    if (GetSequence(input, &idx, &length, sz) < 0)
22253
        return ASN_PARSE_E;
22254
22255
    if (length == 0) {
22256
        /* RFC 5280 4.2.1.8.  Subject Directory Attributes
22257
           If the subjectDirectoryAttributes extension is present, the
22258
           sequence MUST contain at least one entry. */
22259
        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
22260
        return ASN_PARSE_E;
22261
    }
22262
22263
    /* length is the length of the list contents */
22264
    while (idx < (word32)sz) {
22265
        word32 oid;
22266
22267
        if (GetSequence(input, &idx, &length, sz) < 0)
22268
            return ASN_PARSE_E;
22269
22270
        if (GetObjectId(input, &idx, &oid, oidSubjDirAttrType, sz) < 0)
22271
            return ASN_PARSE_E;
22272
22273
        if (GetSet(input, &idx, &length, sz) < 0)
22274
            return ASN_PARSE_E;
22275
22276
        /* There may be more than one countryOfCitizenship, but save the
22277
         * first one for now. */
22278
        if (oid == SDA_COC_OID) {
22279
            byte tag;
22280
22281
            if (GetHeader(input, &tag, &idx, &length, sz, 1) < 0)
22282
                return ASN_PARSE_E;
22283
22284
            if (length != COUNTRY_CODE_LEN)
22285
                return ASN_PARSE_E;
22286
22287
            if (tag == ASN_PRINTABLE_STRING) {
22288
                XMEMCPY(cert->countryOfCitizenship,
22289
                        input + idx, COUNTRY_CODE_LEN);
22290
                cert->countryOfCitizenship[COUNTRY_CODE_LEN] = 0;
22291
            }
22292
        }
22293
        idx += length;
22294
    }
22295
22296
    return ret;
22297
#else
22298
    DECL_ASNGETDATA(dataASN, subjDirAttrASN_Length);
22299
    int ret = 0;
22300
    word32 idx = 0;
22301
    int length;
22302
22303
    WOLFSSL_ENTER("DecodeSubjDirAttr");
22304
22305
#ifdef OPENSSL_ALL
22306
    cert->extSubjDirAttrSrc = input;
22307
    cert->extSubjDirAttrSz = sz;
22308
#endif /* OPENSSL_ALL */
22309
22310
    CALLOC_ASNGETDATA(dataASN, subjDirAttrASN_Length, ret, cert->heap);
22311
22312
    /* Strip outer SEQUENCE. */
22313
    if ((ret == 0) && (GetSequence(input, &idx, &length, sz) < 0)) {
22314
        ret = ASN_PARSE_E;
22315
    }
22316
    /* Handle each inner SEQUENCE. */
22317
    while ((ret == 0) && (idx < (word32)sz)) {
22318
        ret = GetASN_Items(subjDirAttrASN, dataASN, subjDirAttrASN_Length, 1,
22319
            input, &idx, sz);
22320
22321
        /* There may be more than one countryOfCitizenship, but save the
22322
         * first one for now. */
22323
        if ((ret == 0) &&
22324
                (dataASN[SUBJDIRATTRASN_IDX_OID].data.oid.sum == SDA_COC_OID)) {
22325
            int cuLen;
22326
            word32 setIdx = 0;
22327
            byte* setData;
22328
            word32 setLen;
22329
22330
            GetASN_GetRef(&dataASN[SUBJDIRATTRASN_IDX_SET], &setData, &setLen);
22331
            if (GetASNHeader(setData, ASN_PRINTABLE_STRING, &setIdx, &cuLen,
22332
                    setLen) < 0) {
22333
                ret = ASN_PARSE_E;
22334
            }
22335
            if ((ret == 0) && (cuLen != COUNTRY_CODE_LEN)) {
22336
                ret = ASN_PARSE_E;
22337
            }
22338
            if (ret == 0) {
22339
                XMEMCPY(cert->countryOfCitizenship, setData + setIdx,
22340
                    (size_t)cuLen);
22341
                cert->countryOfCitizenship[COUNTRY_CODE_LEN] = 0;
22342
            }
22343
        }
22344
    }
22345
    FREE_ASNGETDATA(dataASN, cert->heap);
22346
    return ret;
22347
#endif /* WOLFSSL_ASN_TEMPLATE */
22348
}
22349
#endif /* WOLFSSL_SUBJ_DIR_ATTR */
22350
22351
#ifdef WOLFSSL_SUBJ_INFO_ACC
22352
/* Decode subject information access extension in a certificate.
22353
 *
22354
 * X.509: RFC 5280, 4.2.2.2 - Subject Information Access.
22355
 *
22356
 * @param [in]      input  Buffer holding data.
22357
 * @param [in]      sz     Size of data in buffer.
22358
 * @param [in, out] cert   Certificate object.
22359
 * @return  0 on success.
22360
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
22361
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
22362
 *          is invalid.
22363
 * @return  MEMORY_E on dynamic memory allocation failure.
22364
 */
22365
static int DecodeSubjInfoAcc(const byte* input, word32 sz, DecodedCert* cert)
22366
{
22367
    word32 idx = 0;
22368
    int length = 0;
22369
    int ret = 0;
22370
22371
    WOLFSSL_ENTER("DecodeSubjInfoAcc");
22372
22373
#ifdef OPENSSL_ALL
22374
    cert->extSubjAltNameSrc = input;
22375
    cert->extSubjAltNameSz = sz;
22376
#endif /* OPENSSL_ALL */
22377
22378
    /* Unwrap SubjectInfoAccessSyntax, the list of AccessDescriptions */
22379
    if (GetSequence(input, &idx, &length, sz) < 0)
22380
        return ASN_PARSE_E;
22381
22382
    if (length == 0) {
22383
        /* RFC 5280 4.2.2.2.  Subject Information Access
22384
           If the subjectInformationAccess extension is present, the
22385
           sequence MUST contain at least one entry. */
22386
        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
22387
        return ASN_PARSE_E;
22388
    }
22389
22390
    /* Per fpkx-x509-cert-profile-common... section 5.3.
22391
     * [The] subjectInfoAccess extension must contain at least one
22392
     * instance of the id-ad-caRepository access method containing a
22393
     * publicly accessible HTTP URI which returns as certs-only
22394
     * CMS.
22395
     */
22396
22397
    while (idx < (word32)sz) {
22398
        word32 oid = 0;
22399
        byte b;
22400
22401
        /* Unwrap an AccessDescription */
22402
        if (GetSequence(input, &idx, &length, sz) < 0)
22403
            return ASN_PARSE_E;
22404
22405
        /* Get the accessMethod */
22406
        if (GetObjectId(input, &idx, &oid, oidCertAuthInfoType, sz) < 0)
22407
            return ASN_PARSE_E;
22408
22409
        /* Only supporting URIs right now. */
22410
        if (GetASNTag(input, &idx, &b, sz) < 0)
22411
            return ASN_PARSE_E;
22412
22413
        if (GetLength(input, &idx, &length, sz) < 0)
22414
            return ASN_PARSE_E;
22415
22416
        /* Set caRepo entry */
22417
        if (b == GENERALNAME_URI && oid == AIA_CA_REPO_OID) {
22418
            cert->extSubjInfoAccCaRepoSz = (word32)length;
22419
            cert->extSubjInfoAccCaRepo = input + idx;
22420
            break;
22421
        }
22422
        idx += (word32)length;
22423
    }
22424
22425
    if (cert->extSubjInfoAccCaRepo == NULL ||
22426
            cert->extSubjInfoAccCaRepoSz == 0) {
22427
        WOLFSSL_MSG("SubjectInfoAccess missing an URL.");
22428
        ret = ASN_PARSE_E;
22429
    }
22430
22431
    WOLFSSL_LEAVE("DecodeSubjInfoAcc", ret);
22432
    return ret;
22433
}
22434
#endif /* WOLFSSL_SUBJ_INFO_ACC */
22435
22436
#ifdef WOLFSSL_DUAL_ALG_CERTS
22437
/* The subject alternative public key is an extension that holds the same thing
22438
 * as a subject public key. */
22439
static const ASNItem subjAltPubKeyInfoASN[] = {
22440
                           /* subjectPublicKeyInfo SubjectPublicKeyInfo */
22441
/* ALT_SPUBKEYINFO_SEQ          */      { 0, ASN_SEQUENCE, 1, 1, 0 },
22442
                           /* algorithm          AlgorithmIdentifier */
22443
                           /* AlgorithmIdentifier ::= SEQUENCE */
22444
/* ALT_SPUBKEYINFO_ALGO_SEQ     */         { 1, ASN_SEQUENCE, 1, 1, 0 },
22445
                          /* Algorithm    OBJECT IDENTIFIER */
22446
/* ALT_SPUBKEYINFO_ALGO_OID     */             { 2, ASN_OBJECT_ID, 0, 0, 0 },
22447
                           /* parameters   ANY defined by algorithm OPTIONAL */
22448
/* ALT_SPUBKEYINFO_ALGO_NULL    */             { 2, ASN_TAG_NULL, 0, 0, 1 },
22449
/* ALT_SPUBKEYINFO_ALGO_CURVEID */             { 2, ASN_OBJECT_ID, 0, 0, 1 },
22450
#ifdef WC_RSA_PSS
22451
/* ALT_SPUBKEYINFO_ALGO_P_SEQ   */             { 2, ASN_SEQUENCE, 1, 0, 1 },
22452
#endif
22453
                           /* subjectPublicKey   BIT STRING */
22454
/* ALT_SPUBKEYINFO_PUBKEY       */          { 1, ASN_BIT_STRING, 0, 0, 0 }
22455
};
22456
22457
#define subjAltPubKeyInfoASN_Length (sizeof(subjAltPubKeyInfoASN) / \
22458
                                     sizeof(ASNItem))
22459
22460
enum {
22461
    ALT_SPUBKEYINFO_SEQ = 0,
22462
    ALT_SPUBKEYINFO_ALGO_SEQ,
22463
    ALT_SPUBKEYINFO_ALGO_OID,
22464
    ALT_SPUBKEYINFO_ALGO_NULL,
22465
    ALT_SPUBKEYINFO_ALGO_CURVEID,
22466
#ifdef WC_RSA_PSS
22467
    ALT_SPUBKEYINFO_ALGO_P_SEQ,
22468
#endif
22469
    ALT_SPUBKEYINFO_PUBKEY
22470
};
22471
22472
static int DecodeSubjAltPubKeyInfo(const byte* input, int sz, DecodedCert* cert)
22473
{
22474
    int ret = 0;
22475
    word32 idx = 0;
22476
    DECL_ASNGETDATA(dataASN, subjAltPubKeyInfoASN_Length);
22477
22478
    WOLFSSL_ENTER("DecodeSubjAltPubKeyInfo");
22479
22480
    if (ret == 0) {
22481
        CALLOC_ASNGETDATA(dataASN, subjAltPubKeyInfoASN_Length, ret,
22482
                          cert->heap);
22483
        (void)cert;
22484
    }
22485
22486
    if (ret == 0) {
22487
        GetASN_OID(&dataASN[ALT_SPUBKEYINFO_ALGO_OID], oidKeyType);
22488
        GetASN_OID(&dataASN[ALT_SPUBKEYINFO_ALGO_CURVEID], oidCurveType);
22489
22490
        ret = GetASN_Items(subjAltPubKeyInfoASN, dataASN,
22491
                           subjAltPubKeyInfoASN_Length, 1, input, &idx,
22492
                           (word32)sz);
22493
    }
22494
22495
    if (ret == 0) {
22496
        /* dataASN[ALT_SPUBKEYINFO_SEQ].data.u8 */
22497
        cert->sapkiDer = (byte *)input;
22498
        /* dataASN[ALT_SPUBKEYINFO_SEQ].length */
22499
        cert->sapkiLen = sz;
22500
        cert->sapkiOID = dataASN[ALT_SPUBKEYINFO_ALGO_OID].data.oid.sum;
22501
    }
22502
22503
    FREE_ASNGETDATA(dataASN, cert->heap);
22504
    WOLFSSL_LEAVE("DecodeSubjAltPubKeyInfo", ret);
22505
    return ret;
22506
}
22507
22508
/* The alternative signature algorithm extension holds the same thing as a
22509
 * as a signature algorithm identifier. */
22510
static const ASNItem altSigAlgASN[] = {
22511
                          /* AltSigAlg            AlgorithmIdentifier */
22512
                          /* AlgorithmIdentifier ::= SEQUENCE */
22513
/* ALTSIG_ALGOID_SEQ                */ { 0, ASN_SEQUENCE, 1, 1, 0 },
22514
                          /* Algorithm    OBJECT IDENTIFIER */
22515
/* ALTSIG_ALGOID_OID                */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
22516
                          /* parameters   ANY defined by algorithm OPTIONAL */
22517
/* ALTSIG_ALGOID_PARAMS_NULL        */     { 1, ASN_TAG_NULL, 0, 0, 1 },
22518
#ifdef WC_RSA_PSS
22519
/* ALTSIG_ALGOID_PARAMS             */     { 1, ASN_SEQUENCE, 1, 0, 1 },
22520
#endif
22521
};
22522
22523
#define altSigAlgASN_Length (sizeof(altSigAlgASN) / sizeof(ASNItem))
22524
22525
enum {
22526
    ALTSIG_ALGOID_SEQ = 0,
22527
    ALTSIG_ALGOID_OID,
22528
    ALTSIG_ALGOID_PARAMS_NULL,
22529
#ifdef WC_RSA_PSS
22530
    ALTSIG_ALGOID_PARAMS,
22531
#endif
22532
};
22533
22534
static int DecodeAltSigAlg(const byte* input, int sz, DecodedCert* cert)
22535
{
22536
    int ret = 0;
22537
    word32 idx = 0;
22538
    DECL_ASNGETDATA(dataASN, altSigAlgASN_Length);
22539
22540
    WOLFSSL_ENTER("DecodeAltSigAlg");
22541
22542
    if (ret == 0) {
22543
        CALLOC_ASNGETDATA(dataASN, altSigAlgASN_Length, ret, cert->heap);
22544
        (void)cert;
22545
    }
22546
22547
    /* We do this to make sure the format of the extension is correct. */
22548
    if (ret == 0) {
22549
        GetASN_OID(&dataASN[ALTSIG_ALGOID_OID], oidSigType);
22550
22551
        ret = GetASN_Items(altSigAlgASN, dataASN,
22552
                           altSigAlgASN_Length, 1, input, &idx,
22553
                           (word32)sz);
22554
    }
22555
22556
    if (ret == 0) {
22557
        cert->altSigAlgDer = (byte *)input;
22558
        cert->altSigAlgLen = sz;
22559
        cert->altSigAlgOID = dataASN[ALTSIG_ALGOID_OID].data.oid.sum;
22560
    }
22561
22562
    FREE_ASNGETDATA(dataASN, cert->heap);
22563
    WOLFSSL_LEAVE("DecodeAltSigAlg", ret);
22564
    return ret;
22565
}
22566
22567
/* The alternative signature value extension holds an ASN.1 bitstring just
22568
 * like a traditional signature in the certificate. */
22569
static int DecodeAltSigVal(const byte* input, int sz, DecodedCert* cert)
22570
{
22571
    int ret = 0;
22572
    word32 idx = 0;
22573
    int len = 0;
22574
22575
    (void)cert;
22576
22577
    WOLFSSL_ENTER("DecodeAltSigVal");
22578
22579
    if (ret == 0) {
22580
        ret = CheckBitString(input, &idx, &len, sz, 1, NULL);
22581
    }
22582
22583
    if (ret == 0) {
22584
        cert->altSigValDer = (byte *)input + idx;
22585
        cert->altSigValLen = len;
22586
    }
22587
22588
    WOLFSSL_LEAVE("DecodeAltSigVal", ret);
22589
    return ret;
22590
}
22591
#endif /* WOLFSSL_DUAL_ALG_CERTS */
22592
22593
/* Macro to check if bit is set, if not sets and return success.
22594
    Otherwise returns failure */
22595
/* Macro required here because bit-field operation */
22596
#ifndef WOLFSSL_NO_ASN_STRICT
22597
    #define VERIFY_AND_SET_OID(bit) \
22598
0
        if ((bit) == 0) \
22599
0
            (bit) = 1; \
22600
0
        else \
22601
0
            return ASN_OBJECT_ID_E;
22602
#else
22603
    /* With no strict defined, the verify is skipped */
22604
#define VERIFY_AND_SET_OID(bit) bit = 1;
22605
#endif
22606
22607
/* Parse extension type specific data based on OID sum.
22608
 *
22609
 * Supported extensions:
22610
 *   Basic Constraints - BASIC_CA_OID
22611
 *   CRL Distribution Points - CRL_DIST_OID
22612
 *   Authority Information Access - AUTH_INFO_OID
22613
 *   Subject Alternative Name - ALT_NAMES_OID
22614
 *   Authority Key Identifier - AUTH_KEY_OID
22615
 *   Subject Key Identifier - SUBJ_KEY_OID
22616
 *   Certificate Policies - CERT_POLICY_OID (conditional parsing)
22617
 *   Key Usage - KEY_USAGE_OID
22618
 *   Extended Key Usage - EXT_KEY_USAGE_OID
22619
 *   Name Constraints - NAME_CONS_OID
22620
 *   Inhibit anyPolicy - INHIBIT_ANY_OID
22621
 *   Netscape Certificate Type - NETSCAPE_CT_OID (able to be excluded)
22622
 *   OCSP no check - OCSP_NOCHECK_OID (when compiling OCSP)
22623
 *   Subject Directory Attributes - SUBJ_DIR_ATTR_OID
22624
 *   Subject Information Access - SUBJ_INFO_ACC_OID
22625
 * Unsupported extensions from RFC 5280:
22626
 *   4.2.1.5 - Policy mappings
22627
 *   4.2.1.7 - Issuer Alternative Name
22628
 *   4.2.1.11 - Policy Constraints
22629
 *   4.2.1.15 - Freshest CRL
22630
 *
22631
 * @param [in]      input     Buffer containing extension type specific data.
22632
 * @param [in]      length    Length of data.
22633
 * @param [in]      oid       OID sum for extension.
22634
 * @param [in]      critical  Whether extension is critical.
22635
 * @param [in, out] cert      Certificate object.
22636
 * @return  0 on success.
22637
 * @return  ASN_PARSE_E when BER encoding is invalid.
22638
 * @return  MEMORY_E on dynamic memory allocation failure.
22639
 * @return  Other negative values on error.
22640
 */
22641
static int DecodeExtensionType(const byte* input, word32 length, word32 oid,
22642
                               byte critical, DecodedCert* cert,
22643
                               int *isUnknownExt)
22644
0
{
22645
0
    int ret = 0;
22646
0
    word32 idx = 0;
22647
22648
0
    if (isUnknownExt != NULL)
22649
0
        *isUnknownExt = 0;
22650
22651
0
    switch (oid) {
22652
        /* Basic Constraints. */
22653
0
        case BASIC_CA_OID:
22654
0
            VERIFY_AND_SET_OID(cert->extBasicConstSet);
22655
0
            cert->extBasicConstCrit = critical ? 1 : 0;
22656
0
            if (DecodeBasicCaConstraint(input, (int)length, cert) < 0) {
22657
0
                ret = ASN_PARSE_E;
22658
0
            }
22659
0
            break;
22660
22661
        /* CRL Distribution point. */
22662
0
        case CRL_DIST_OID:
22663
0
            VERIFY_AND_SET_OID(cert->extCRLdistSet);
22664
0
            cert->extCRLdistCrit = critical ? 1 : 0;
22665
0
            if (DecodeCrlDist(input, length, cert) < 0) {
22666
0
                ret = ASN_PARSE_E;
22667
0
            }
22668
0
            break;
22669
22670
        /* Authority information access. */
22671
0
        case AUTH_INFO_OID:
22672
0
            VERIFY_AND_SET_OID(cert->extAuthInfoSet);
22673
0
            cert->extAuthInfoCrit = critical ? 1 : 0;
22674
0
        #ifndef WOLFSSL_ALLOW_CRIT_AIA
22675
            /* This check is added due to RFC 5280 section 4.2.2.1
22676
            * stating that conforming CA's must mark this extension
22677
            * as non-critical. When parsing extensions check that
22678
            * certificate was made in compliance with this. */
22679
0
            if (critical) {
22680
0
                WOLFSSL_MSG("Critical Authority Information Access is not"
22681
0
                            "allowed");
22682
0
                WOLFSSL_MSG("Use macro WOLFSSL_ALLOW_CRIT_AIA if wanted");
22683
0
                ret = ASN_CRIT_EXT_E;
22684
0
            }
22685
0
        #endif
22686
0
            if ((ret == 0) && (DecodeAuthInfo(input, length, cert) < 0)) {
22687
0
                ret = ASN_PARSE_E;
22688
0
            }
22689
0
            break;
22690
22691
        /* Subject alternative name. */
22692
0
        case ALT_NAMES_OID:
22693
0
            VERIFY_AND_SET_OID(cert->extSubjAltNameSet);
22694
0
            cert->extSubjAltNameCrit = critical ? 1 : 0;
22695
0
            ret = DecodeAltNames(input, length, cert);
22696
0
            break;
22697
22698
        /* Authority Key Identifier. */
22699
0
        case AUTH_KEY_OID:
22700
0
            VERIFY_AND_SET_OID(cert->extAuthKeyIdSet);
22701
0
            cert->extAuthKeyIdCrit = critical ? 1 : 0;
22702
0
        #ifndef WOLFSSL_ALLOW_CRIT_AKID
22703
            /* This check is added due to RFC 5280 section 4.2.1.1
22704
             * stating that conforming CA's must mark this extension
22705
             * as non-critical. When parsing extensions check that
22706
             * certificate was made in compliance with this. */
22707
0
            if (critical) {
22708
0
                WOLFSSL_MSG("Critical Auth Key ID is not allowed");
22709
0
                WOLFSSL_MSG("Use macro WOLFSSL_ALLOW_CRIT_AKID if wanted");
22710
0
                ret = ASN_CRIT_EXT_E;
22711
0
            }
22712
0
        #endif
22713
0
            if ((ret == 0) && (DecodeAuthKeyId(input, length, cert) < 0)) {
22714
0
                ret = ASN_PARSE_E;
22715
0
            }
22716
0
            break;
22717
22718
        /* Subject Key Identifier. */
22719
0
        case SUBJ_KEY_OID:
22720
0
            VERIFY_AND_SET_OID(cert->extSubjKeyIdSet);
22721
0
            cert->extSubjKeyIdCrit = critical ? 1 : 0;
22722
0
        #ifndef WOLFSSL_ALLOW_CRIT_SKID
22723
            /* This check is added due to RFC 5280 section 4.2.1.2
22724
             * stating that conforming CA's must mark this extension
22725
             * as non-critical. When parsing extensions check that
22726
             * certificate was made in compliance with this. */
22727
0
            if (critical) {
22728
0
                WOLFSSL_MSG("Critical Subject Key ID is not allowed");
22729
0
                WOLFSSL_MSG("Use macro WOLFSSL_ALLOW_CRIT_SKID if wanted");
22730
0
                ret = ASN_CRIT_EXT_E;
22731
0
            }
22732
0
        #endif
22733
22734
0
            if ((ret == 0) && (DecodeSubjKeyId(input, length, cert) < 0)) {
22735
0
                ret = ASN_PARSE_E;
22736
0
            }
22737
0
            break;
22738
22739
        /* Certificate policies. */
22740
0
        case CERT_POLICY_OID:
22741
        #ifdef WOLFSSL_SEP
22742
            VERIFY_AND_SET_OID(cert->extCertPolicySet);
22743
            cert->extCertPolicyCrit = critical ? 1 : 0;
22744
        #endif
22745
        #if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT)
22746
            if (DecodeCertPolicy(input, length, cert) < 0) {
22747
                ret = ASN_PARSE_E;
22748
            }
22749
        #else
22750
0
            WOLFSSL_MSG("Certificate Policy extension not supported.");
22751
0
            #ifndef WOLFSSL_NO_ASN_STRICT
22752
0
            if (critical) {
22753
0
                WOLFSSL_ERROR_VERBOSE(ASN_CRIT_EXT_E);
22754
0
                ret = ASN_CRIT_EXT_E;
22755
0
            }
22756
0
            #endif
22757
0
        #endif
22758
0
            break;
22759
22760
        /* Key usage. */
22761
0
        case KEY_USAGE_OID:
22762
0
            VERIFY_AND_SET_OID(cert->extKeyUsageSet);
22763
0
            cert->extKeyUsageCrit = critical ? 1 : 0;
22764
0
            if (DecodeKeyUsage(input, length, cert) < 0) {
22765
0
                ret = ASN_PARSE_E;
22766
0
            }
22767
0
            break;
22768
22769
        /* Extended key usage. */
22770
0
        case EXT_KEY_USAGE_OID:
22771
0
            VERIFY_AND_SET_OID(cert->extExtKeyUsageSet);
22772
0
            cert->extExtKeyUsageCrit = critical ? 1 : 0;
22773
0
            if (DecodeExtKeyUsage(input, length, cert) < 0) {
22774
0
                ret = ASN_PARSE_E;
22775
0
            }
22776
0
            break;
22777
22778
0
        #ifndef IGNORE_NAME_CONSTRAINTS
22779
        /* Name constraints. */
22780
0
        case NAME_CONS_OID:
22781
0
        #ifndef WOLFSSL_NO_ASN_STRICT
22782
            /* Verify RFC 5280 Sec 4.2.1.10 rule:
22783
                "The name constraints extension,
22784
                which MUST be used only in a CA certificate" */
22785
0
            if (!cert->isCA) {
22786
0
                WOLFSSL_MSG("Name constraints allowed only for CA certs");
22787
0
                WOLFSSL_ERROR_VERBOSE(ASN_NAME_INVALID_E);
22788
0
                ret = ASN_NAME_INVALID_E;
22789
0
            }
22790
0
        #endif
22791
0
            VERIFY_AND_SET_OID(cert->extNameConstraintSet);
22792
0
            cert->extNameConstraintCrit = critical ? 1 : 0;
22793
0
            if (DecodeNameConstraints(input, length, cert) < 0) {
22794
0
                ret = ASN_PARSE_E;
22795
0
            }
22796
0
            break;
22797
0
        #endif /* IGNORE_NAME_CONSTRAINTS */
22798
22799
        /* Inhibit anyPolicy. */
22800
0
        case INHIBIT_ANY_OID:
22801
0
            VERIFY_AND_SET_OID(cert->inhibitAnyOidSet);
22802
0
            WOLFSSL_MSG("Inhibit anyPolicy extension not supported yet.");
22803
0
            break;
22804
22805
0
   #ifndef IGNORE_NETSCAPE_CERT_TYPE
22806
        /* Netscape's certificate type. */
22807
0
        case NETSCAPE_CT_OID:
22808
0
            if (DecodeNsCertType(input, (int)length, cert) < 0)
22809
0
                ret = ASN_PARSE_E;
22810
0
            break;
22811
0
    #endif
22812
    #ifdef HAVE_OCSP
22813
        /* OCSP no check. */
22814
        case OCSP_NOCHECK_OID:
22815
            VERIFY_AND_SET_OID(cert->ocspNoCheckSet);
22816
            ret = GetASNNull(input, &idx, length);
22817
            if (ret != 0) {
22818
                ret = ASN_PARSE_E;
22819
            }
22820
            break;
22821
    #endif
22822
0
        case POLICY_CONST_OID:
22823
0
            VERIFY_AND_SET_OID(cert->extPolicyConstSet);
22824
0
            cert->extPolicyConstCrit = critical ? 1 : 0;
22825
0
            if (DecodePolicyConstraints(&input[idx], (int)length, cert) < 0)
22826
0
                return ASN_PARSE_E;
22827
0
            break;
22828
    #ifdef WOLFSSL_SUBJ_DIR_ATTR
22829
        case SUBJ_DIR_ATTR_OID:
22830
            VERIFY_AND_SET_OID(cert->extSubjDirAttrSet);
22831
            if (DecodeSubjDirAttr(&input[idx], length, cert) < 0)
22832
                return ASN_PARSE_E;
22833
            break;
22834
    #endif
22835
    #ifdef WOLFSSL_SUBJ_INFO_ACC
22836
        case SUBJ_INFO_ACC_OID:
22837
            VERIFY_AND_SET_OID(cert->extSubjInfoAccSet);
22838
            if (DecodeSubjInfoAcc(&input[idx], length, cert) < 0)
22839
                return ASN_PARSE_E;
22840
            break;
22841
    #endif
22842
    #ifdef WOLFSSL_DUAL_ALG_CERTS
22843
        case SUBJ_ALT_PUB_KEY_INFO_OID:
22844
            VERIFY_AND_SET_OID(cert->extSapkiSet);
22845
            cert->extSapkiCrit = critical ? 1 : 0;
22846
            if (DecodeSubjAltPubKeyInfo(&input[idx], length, cert) < 0)
22847
                return ASN_PARSE_E;
22848
            break;
22849
        case ALT_SIG_ALG_OID:
22850
            VERIFY_AND_SET_OID(cert->extAltSigAlgSet);
22851
            cert->extAltSigAlgCrit = critical ? 1 : 0;
22852
            if (DecodeAltSigAlg(&input[idx], length, cert) < 0)
22853
                return ASN_PARSE_E;
22854
            break;
22855
        case ALT_SIG_VAL_OID:
22856
            VERIFY_AND_SET_OID(cert->extAltSigValSet);
22857
            cert->extAltSigValCrit = critical ? 1 : 0;
22858
            if (DecodeAltSigVal(&input[idx], length, cert) < 0)
22859
                return ASN_PARSE_E;
22860
            break;
22861
    #endif /* WOLFSSL_DUAL_ALG_CERTS */
22862
0
        default:
22863
0
            if (isUnknownExt != NULL)
22864
0
                *isUnknownExt = 1;
22865
0
        #ifndef WOLFSSL_NO_ASN_STRICT
22866
            /* While it is a failure to not support critical extensions,
22867
             * still parse the certificate ignoring the unsupported
22868
             * extension to allow caller to accept it with the verify
22869
             * callback. */
22870
0
            if (critical) {
22871
0
                WOLFSSL_ERROR_VERBOSE(ASN_CRIT_EXT_E);
22872
0
                ret = ASN_CRIT_EXT_E;
22873
0
            }
22874
0
        #endif
22875
0
            break;
22876
0
    }
22877
22878
0
    return ret;
22879
0
}
22880
22881
#ifdef WOLFSSL_ASN_TEMPLATE
22882
/* ASN.1 template for extensions.
22883
 * X.509: RFC 5280, 4.1 - Basic Certificate Fields.
22884
 */
22885
static const ASNItem certExtHdrASN[] = {
22886
/* EXTTAG */ { 0, ASN_CONTEXT_SPECIFIC | 3, 1, 1, 0 },
22887
/* EXTSEQ */     { 1, ASN_SEQUENCE, 1, 1, 0 },
22888
};
22889
enum {
22890
    CERTEXTHDRASN_IDX_EXTTAG = 0,
22891
    CERTEXTHDRASN_IDX_EXTSEQ
22892
};
22893
22894
/* Number of items in ASN.1 template for extensions. */
22895
0
#define certExtHdrASN_Length (sizeof(certExtHdrASN) / sizeof(ASNItem))
22896
22897
/* ASN.1 template for Extension.
22898
 * X.509: RFC 5280, 4.1 - Basic Certificate Fields.
22899
 */
22900
static const ASNItem certExtASN[] = {
22901
/* SEQ  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
22902
                              /* Extension object id */
22903
/* OID  */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
22904
                              /* critical - when true, must be parseable. */
22905
/* CRIT */     { 1, ASN_BOOLEAN, 0, 0, 1 },
22906
                              /* Data for extension - leave index at start of data. */
22907
/* VAL  */     { 1, ASN_OCTET_STRING, 0, 1, 0 },
22908
};
22909
enum {
22910
    CERTEXTASN_IDX_SEQ = 0,
22911
    CERTEXTASN_IDX_OID,
22912
    CERTEXTASN_IDX_CRIT,
22913
    CERTEXTASN_IDX_VAL
22914
};
22915
22916
/* Number of items in ASN.1 template for Extension. */
22917
0
#define certExtASN_Length (sizeof(certExtASN) / sizeof(ASNItem))
22918
#endif
22919
22920
#ifdef WC_ASN_UNKNOWN_EXT_CB
22921
int wc_SetUnknownExtCallback(DecodedCert* cert,
22922
                             wc_UnknownExtCallback cb) {
22923
    if (cert == NULL) {
22924
        return BAD_FUNC_ARG;
22925
    }
22926
22927
    cert->unknownExtCallback = cb;
22928
    return 0;
22929
}
22930
22931
int wc_SetUnknownExtCallbackEx(DecodedCert* cert,
22932
                               wc_UnknownExtCallbackEx cb, void *ctx) {
22933
    if (cert == NULL) {
22934
        return BAD_FUNC_ARG;
22935
    }
22936
22937
    cert->unknownExtCallbackEx = cb;
22938
    cert->unknownExtCallbackExCtx = ctx;
22939
    return 0;
22940
}
22941
#endif /* WC_ASN_UNKNOWN_EXT_CB */
22942
22943
/*
22944
 *  Processing the Certificate Extensions. This does not modify the current
22945
 *  index. It is works starting with the recorded extensions pointer.
22946
 */
22947
static int DecodeCertExtensions(DecodedCert* cert)
22948
0
{
22949
#ifndef WOLFSSL_ASN_TEMPLATE
22950
    int ret = 0;
22951
    word32 idx = 0;
22952
    word32 sz = (word32)cert->extensionsSz;
22953
    const byte* input = cert->extensions;
22954
    int length;
22955
    word32 oid;
22956
    byte critical = 0;
22957
    byte criticalFail = 0;
22958
    byte tag = 0;
22959
22960
    WOLFSSL_ENTER("DecodeCertExtensions");
22961
22962
    if (input == NULL || sz == 0)
22963
        return BAD_FUNC_ARG;
22964
22965
#ifdef WOLFSSL_CERT_REQ
22966
    if (!cert->isCSR)
22967
#endif
22968
    { /* Not included in CSR */
22969
        if (GetASNTag(input, &idx, &tag, sz) < 0) {
22970
            return ASN_PARSE_E;
22971
        }
22972
22973
        if (tag != ASN_EXTENSIONS) {
22974
            WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
22975
            return ASN_PARSE_E;
22976
        }
22977
22978
        if (GetLength(input, &idx, &length, sz) < 0) {
22979
            WOLFSSL_MSG("\tfail: invalid length");
22980
            return ASN_PARSE_E;
22981
        }
22982
    }
22983
22984
    if (GetSequence(input, &idx, &length, sz) < 0) {
22985
        WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
22986
        return ASN_PARSE_E;
22987
    }
22988
22989
    while (idx < (word32)sz) {
22990
        word32 localIdx;
22991
22992
        if (GetSequence(input, &idx, &length, sz) < 0) {
22993
            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
22994
            return ASN_PARSE_E;
22995
        }
22996
22997
        oid = 0;
22998
        if ((ret = GetObjectId(input, &idx, &oid, oidCertExtType, sz)) < 0) {
22999
            WOLFSSL_MSG("\tfail: OBJECT ID");
23000
            return ret;
23001
        }
23002
23003
        /* check for critical flag */
23004
        critical = 0;
23005
        if ((idx + 1) > (word32)sz) {
23006
            WOLFSSL_MSG("\tfail: malformed buffer");
23007
            return BUFFER_E;
23008
        }
23009
23010
        localIdx = idx;
23011
        if (GetASNTag(input, &localIdx, &tag, sz) == 0) {
23012
            if (tag == ASN_BOOLEAN) {
23013
                ret = GetBoolean(input, &idx, sz);
23014
                if (ret < 0) {
23015
                    WOLFSSL_MSG("\tfail: critical boolean");
23016
                    return ret;
23017
                }
23018
23019
                critical = (byte)ret;
23020
            }
23021
        }
23022
23023
        /* process the extension based on the OID */
23024
        ret = GetOctetString(input, &idx, &length, sz);
23025
        if (ret < 0) {
23026
            WOLFSSL_MSG("\tfail: bad OCTET STRING");
23027
            return ret;
23028
        }
23029
23030
        ret = DecodeExtensionType(input + idx, (word32)length, oid, critical,
23031
            cert, NULL);
23032
        if (ret == WC_NO_ERR_TRACE(ASN_CRIT_EXT_E)) {
23033
            ret = 0;
23034
            criticalFail = 1;
23035
        }
23036
        if (ret < 0)
23037
            goto end;
23038
        idx += (word32)length;
23039
    }
23040
23041
    ret = criticalFail ? ASN_CRIT_EXT_E : 0;
23042
end:
23043
    return ret;
23044
#else
23045
0
    DECL_ASNGETDATA(dataASN, certExtASN_Length);
23046
0
    ASNGetData dataExtsASN[certExtHdrASN_Length];
23047
0
    int ret = 0;
23048
0
    const byte* input = cert->extensions;
23049
0
    int sz = cert->extensionsSz;
23050
0
    word32 idx = 0;
23051
0
    int criticalRet = 0;
23052
0
    int offset = 0;
23053
23054
0
    WOLFSSL_ENTER("DecodeCertExtensions");
23055
23056
0
    if (input == NULL || sz == 0)
23057
0
        ret = BAD_FUNC_ARG;
23058
23059
0
    ALLOC_ASNGETDATA(dataASN, certExtASN_Length, ret, cert->heap);
23060
23061
#ifdef WOLFSSL_CERT_REQ
23062
    if (cert->isCSR) {
23063
        offset = CERTEXTHDRASN_IDX_EXTSEQ;
23064
    }
23065
#endif
23066
0
    if (ret == 0) {
23067
        /* Clear dynamic data. */
23068
0
        XMEMSET(dataExtsASN, 0, sizeof(dataExtsASN));
23069
        /* Parse extensions header. */
23070
0
        ret = GetASN_Items(certExtHdrASN + offset, dataExtsASN + offset,
23071
0
                           (int)(certExtHdrASN_Length - (size_t)offset), 0,
23072
0
                           input, &idx, (word32)sz);
23073
0
    }
23074
    /* Parse each extension. */
23075
0
    while ((ret == 0) && (idx < (word32)sz)) {
23076
0
        byte critical = 0;
23077
0
        int isUnknownExt = 0;
23078
23079
        /* Clear dynamic data. */
23080
0
        XMEMSET(dataASN, 0, sizeof(*dataASN) * certExtASN_Length);
23081
        /* Ensure OID is an extension type. */
23082
0
        GetASN_OID(&dataASN[CERTEXTASN_IDX_OID], oidCertExtType);
23083
        /* Set criticality variable. */
23084
0
        GetASN_Int8Bit(&dataASN[CERTEXTASN_IDX_CRIT], &critical);
23085
        /* Parse extension wrapper. */
23086
0
        ret = GetASN_Items(certExtASN, dataASN, certExtASN_Length, 0, input,
23087
0
                           &idx, (word32)sz);
23088
0
        if (ret == 0) {
23089
0
            word32 oid = dataASN[CERTEXTASN_IDX_OID].data.oid.sum;
23090
0
            word32 length = dataASN[CERTEXTASN_IDX_VAL].length;
23091
23092
            /* Decode the extension by type. */
23093
0
            ret = DecodeExtensionType(input + idx, length, oid, critical, cert,
23094
0
                                      &isUnknownExt);
23095
#ifdef WC_ASN_UNKNOWN_EXT_CB
23096
            if (isUnknownExt && (cert->unknownExtCallback != NULL ||
23097
                                 cert->unknownExtCallbackEx != NULL)) {
23098
                word16 decOid[MAX_OID_SZ];
23099
                word32 decOidSz = sizeof(decOid);
23100
                ret = DecodeObjectId(
23101
                          dataASN[CERTEXTASN_IDX_OID].data.oid.data,
23102
                          dataASN[CERTEXTASN_IDX_OID].data.oid.length,
23103
                          decOid, &decOidSz);
23104
                if (ret != 0) {
23105
                    /* Should never get here as the extension was successfully
23106
                     * decoded earlier. Something might be corrupted. */
23107
                    WOLFSSL_MSG("DecodeObjectId() failed. Corruption?");
23108
                    WOLFSSL_ERROR(ret);
23109
                }
23110
23111
                if ((ret == 0) && (cert->unknownExtCallback != NULL)) {
23112
                    ret = cert->unknownExtCallback(decOid, decOidSz, critical,
23113
                              dataASN[CERTEXTASN_IDX_VAL].data.buffer.data,
23114
                              dataASN[CERTEXTASN_IDX_VAL].length);
23115
                }
23116
23117
                if ((ret == 0) && (cert->unknownExtCallbackEx != NULL)) {
23118
                    ret = cert->unknownExtCallbackEx(decOid, decOidSz, critical,
23119
                              dataASN[CERTEXTASN_IDX_VAL].data.buffer.data,
23120
                              dataASN[CERTEXTASN_IDX_VAL].length,
23121
                              cert->unknownExtCallbackExCtx);
23122
                }
23123
            }
23124
#else
23125
0
            (void)isUnknownExt;
23126
0
#endif
23127
23128
            /* Move index on to next extension. */
23129
0
            idx += length;
23130
0
        }
23131
        /* Don't fail criticality until all other extensions have been checked.
23132
         */
23133
0
        if (ret == WC_NO_ERR_TRACE(ASN_CRIT_EXT_E)) {
23134
0
            criticalRet = ASN_CRIT_EXT_E;
23135
0
            ret = 0;
23136
0
        }
23137
0
    }
23138
23139
0
    if (ret == 0) {
23140
        /* Use criticality return. */
23141
0
        ret = criticalRet;
23142
0
    }
23143
23144
0
    FREE_ASNGETDATA(dataASN, cert->heap);
23145
0
    return ret;
23146
0
#endif
23147
0
}
23148
23149
#ifdef WOLFSSL_ASN_TEMPLATE
23150
23151
#if defined(HAVE_RPK)
23152
/* ASN template for a Raw Public Key certificate defined RFC7250. */
23153
static const ASNItem RPKCertASN[] = {
23154
/* SubjectPublicKeyInfo ::= SEQUENCE */ { 0, ASN_SEQUENCE, 1, 1, 0 },
23155
    /* algorithm    AlgorithmIdentifier */
23156
    /* AlgorithmIdentifier ::= SEQUENCE */   { 1, ASN_SEQUENCE, 1, 1, 0 },
23157
        /* Algorithm  OBJECT IDENTIFIER */
23158
        /* TBS_SPUBKEYINFO_ALGO_OID     */       { 2, ASN_OBJECT_ID, 0, 0, 0 },
23159
        /* parameters   ANY defined by algorithm OPTIONAL */
23160
        /* TBS_SPUBKEYINFO_ALGO_NULL     */      { 2, ASN_TAG_NULL, 0, 0, 1 },
23161
        /* TBS_SPUBKEYINFO_ALGO_CURVEID  */      { 2, ASN_OBJECT_ID, 0, 0, 1 },
23162
#ifdef WC_RSA_PSS
23163
        /* TBS_SPUBKEYINFO_ALGO_P_SEQ    */      { 2, ASN_SEQUENCE, 1, 0, 1 },
23164
#endif
23165
        /* subjectPublicKey   BIT STRING */
23166
        /* TBS_SPUBKEYINFO_PUBKEY        */   { 1, ASN_BIT_STRING, 0, 0, 0 },
23167
};
23168
/* Number of items in ASN template for a RawPublicKey certificate. */
23169
#define RPKCertASN_Length (sizeof(RPKCertASN) / sizeof(ASNItem))
23170
23171
enum {
23172
    RPKCERTASN_IDX_SPUBKEYINFO_SEQ = 0,
23173
    RPKCERTASN_IDX_SPUBKEYINFO_ALGO_SEQ,
23174
    RPKCERTASN_IDX_SPUBKEYINFO_ALGO_OID,
23175
    RPKCERTASN_IDX_SPUBKEYINFO_ALGO_NULL,
23176
    RPKCERTASN_IDX_SPUBKEYINFO_ALGO_CURVEID,
23177
#ifdef WC_RSA_PSS
23178
    RPKCERTASN_IDX_SPUBKEYINFO_ALGO_P_SEQ,
23179
#endif
23180
    RPKCERTASN_IDX_SPUBKEYINFO_PUBKEY
23181
};
23182
23183
#endif /* HAVE_RPK */
23184
23185
/* ASN template for an X509 certificate.
23186
 * X.509: RFC 5280, 4.1 - Basic Certificate Fields.
23187
 */
23188
static const ASNItem x509CertASN[] = {
23189
        /* Certificate ::= SEQUENCE */
23190
/* SEQ                           */    { 0, ASN_SEQUENCE, 1, 1, 0 },
23191
                                                   /* tbsCertificate       TBSCertificate */
23192
                                                   /* TBSCertificate ::= SEQUENCE */
23193
/* TBS_SEQ                       */        { 1, ASN_SEQUENCE, 1, 1, 0 },
23194
                                                   /* version         [0]  EXPLICIT Version DEFAULT v1 */
23195
/* TBS_VER                       */            { 2, ASN_CONTEXT_SPECIFIC | ASN_X509_CERT_VERSION, 1, 1, 1 },
23196
                                                   /* Version ::= INTEGER { v1(0), v2(1), v3(2) */
23197
/* TBS_VER_INT                   */                { 3, ASN_INTEGER, 0, 0, 0 },
23198
                                                   /* serialNumber         CertificateSerialNumber */
23199
                                                   /* CertificateSerialNumber ::= INTEGER */
23200
/* TBS_SERIAL                    */            { 2, ASN_INTEGER, 0, 0, 0 },
23201
                                                   /* signature            AlgorithmIdentifier */
23202
                                                   /* AlgorithmIdentifier ::= SEQUENCE */
23203
/* TBS_ALGOID_SEQ                */            { 2, ASN_SEQUENCE, 1, 1, 0 },
23204
                                                   /* Algorithm    OBJECT IDENTIFIER */
23205
/* TBS_ALGOID_OID                */                { 3, ASN_OBJECT_ID, 0, 0, 0 },
23206
                                                   /* parameters   ANY defined by algorithm OPTIONAL */
23207
/* TBS_ALGOID_PARAMS_NULL        */                { 3, ASN_TAG_NULL, 0, 0, 2 },
23208
#ifdef WC_RSA_PSS
23209
/* TBS_ALGOID_PARAMS             */                { 3, ASN_SEQUENCE, 1, 0, 2 },
23210
#endif
23211
                                                   /* issuer               Name */
23212
/* TBS_ISSUER_SEQ                */            { 2, ASN_SEQUENCE, 1, 0, 0 },
23213
                                                   /* validity             Validity */
23214
                                                   /* Validity ::= SEQUENCE */
23215
/* TBS_VALIDITY_SEQ              */            { 2, ASN_SEQUENCE, 1, 1, 0 },
23216
                                                   /* notBefore   Time */
23217
                                                   /* Time :: CHOICE { UTCTime, GeneralizedTime } */
23218
/* TBS_VALIDITY_NOTB_UTC         */                { 3, ASN_UTC_TIME, 0, 0, 2 },
23219
/* TBS_VALIDITY_NOTB_GT          */                { 3, ASN_GENERALIZED_TIME, 0, 0, 2 },
23220
                                                   /* notAfter   Time */
23221
                                                   /* Time :: CHOICE { UTCTime, GeneralizedTime } */
23222
/* TBS_VALIDITY_NOTA_UTC         */                { 3, ASN_UTC_TIME, 0, 0, 3 },
23223
/* TBS_VALIDITY_NOTA_GT          */                { 3, ASN_GENERALIZED_TIME, 0, 0, 3 },
23224
                                                   /* subject              Name */
23225
/* TBS_SUBJECT_SEQ               */            { 2, ASN_SEQUENCE, 1, 0, 0 },
23226
                                                   /* subjectPublicKeyInfo SubjectPublicKeyInfo */
23227
/* TBS_SPUBKEYINFO_SEQ           */            { 2, ASN_SEQUENCE, 1, 1, 0 },
23228
                                                   /* algorithm          AlgorithmIdentifier */
23229
                                                   /* AlgorithmIdentifier ::= SEQUENCE */
23230
/* TBS_SPUBKEYINFO_ALGO_SEQ      */                { 3, ASN_SEQUENCE, 1, 1, 0 },
23231
                                                   /* Algorithm    OBJECT IDENTIFIER */
23232
/* TBS_SPUBKEYINFO_ALGO_OID      */                    { 4, ASN_OBJECT_ID, 0, 0, 0 },
23233
                                                   /* parameters   ANY defined by algorithm OPTIONAL */
23234
/* TBS_SPUBKEYINFO_ALGO_NULL     */                    { 4, ASN_TAG_NULL, 0, 0, 2 },
23235
/* TBS_SPUBKEYINFO_ALGO_CURVEID  */                    { 4, ASN_OBJECT_ID, 0, 0, 2 },
23236
#ifdef WC_RSA_PSS
23237
/* TBS_SPUBKEYINFO_ALGO_P_SEQ    */                    { 4, ASN_SEQUENCE, 1, 0, 2 },
23238
#endif
23239
                                                   /* subjectPublicKey   BIT STRING */
23240
/* TBS_SPUBKEYINFO_PUBKEY        */                { 3, ASN_BIT_STRING, 0, 0, 0 },
23241
                                                   /* issuerUniqueID       UniqueIdentfier OPTIONAL */
23242
/* TBS_ISSUERUID                 */            { 2, ASN_CONTEXT_SPECIFIC | 1, 0, 0, 1 },
23243
                                                   /* subjectUniqueID      UniqueIdentfier OPTIONAL */
23244
/* TBS_SUBJECTUID                */            { 2, ASN_CONTEXT_SPECIFIC | 2, 0, 0, 1 },
23245
                                                   /* extensions           Extensions OPTIONAL */
23246
/* TBS_EXT                       */            { 2, ASN_CONTEXT_SPECIFIC | 3, 1, 1, 1 },
23247
/* TBS_EXT_SEQ                   */                { 3, ASN_SEQUENCE, 1, 0, 0 },
23248
                                                   /* signatureAlgorithm   AlgorithmIdentifier */
23249
                                                   /* AlgorithmIdentifier ::= SEQUENCE */
23250
/* SIGALGO_SEQ                   */        { 1, ASN_SEQUENCE, 1, 1, 0 },
23251
                                                   /* Algorithm    OBJECT IDENTIFIER */
23252
/* SIGALGO_OID                   */            { 2, ASN_OBJECT_ID, 0, 0, 0 },
23253
                                                   /* parameters   ANY defined by algorithm OPTIONAL */
23254
/* SIGALGO_PARAMS_NULL           */            { 2, ASN_TAG_NULL, 0, 0, 2 },
23255
#ifdef WC_RSA_PSS
23256
/* SIGALGO_PARAMS                */            { 2, ASN_SEQUENCE, 1, 0, 2 },
23257
#endif
23258
                                                   /* signature            BIT STRING */
23259
/* SIGNATURE                     */        { 1, ASN_BIT_STRING, 0, 0, 0 },
23260
};
23261
enum {
23262
    X509CERTASN_IDX_SEQ = 0,
23263
    X509CERTASN_IDX_TBS_SEQ,
23264
    X509CERTASN_IDX_TBS_VER,
23265
    X509CERTASN_IDX_TBS_VER_INT,
23266
    X509CERTASN_IDX_TBS_SERIAL,
23267
    X509CERTASN_IDX_TBS_ALGOID_SEQ,
23268
    X509CERTASN_IDX_TBS_ALGOID_OID,
23269
    X509CERTASN_IDX_TBS_ALGOID_PARAMS_NULL,
23270
#ifdef WC_RSA_PSS
23271
    X509CERTASN_IDX_TBS_ALGOID_PARAMS,
23272
#endif
23273
    X509CERTASN_IDX_TBS_ISSUER_SEQ,
23274
    X509CERTASN_IDX_TBS_VALIDITY_SEQ,
23275
    X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC,
23276
    X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT,
23277
    X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC,
23278
    X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT,
23279
    X509CERTASN_IDX_TBS_SUBJECT_SEQ,
23280
    X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ,
23281
    X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_SEQ,
23282
    X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_OID,
23283
    X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_NULL,
23284
    X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_CURVEID,
23285
#ifdef WC_RSA_PSS
23286
    X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_P_SEQ,
23287
#endif
23288
    X509CERTASN_IDX_TBS_SPUBKEYINFO_PUBKEY,
23289
    X509CERTASN_IDX_TBS_ISSUERUID,
23290
    X509CERTASN_IDX_TBS_SUBJECTUID,
23291
    X509CERTASN_IDX_TBS_EXT,
23292
    X509CERTASN_IDX_TBS_EXT_SEQ,
23293
    X509CERTASN_IDX_SIGALGO_SEQ,
23294
    X509CERTASN_IDX_SIGALGO_OID,
23295
    X509CERTASN_IDX_SIGALGO_PARAMS_NULL,
23296
#ifdef WC_RSA_PSS
23297
    X509CERTASN_IDX_SIGALGO_PARAMS,
23298
#endif
23299
    X509CERTASN_IDX_SIGNATURE,
23300
    WOLF_ENUM_DUMMY_LAST_ELEMENT(X509CERTASN_IDX)
23301
};
23302
23303
/* Number of items in ASN template for an X509 certificate. */
23304
0
#define x509CertASN_Length (sizeof(x509CertASN) / sizeof(ASNItem))
23305
23306
/* Check the data data.
23307
 *
23308
 * @param [in] dataASN   ASN template dynamic data item.
23309
 * @param [in] dataType  ASN_BEFORE or ASN_AFTER date.
23310
 * @return  0 on success.
23311
 * @return  ASN_TIME_E when BER tag is nor UTC or GENERALIZED time.
23312
 * @return  ASN_DATE_SZ_E when time data is not supported.
23313
 * @return  ASN_BEFORE_DATE_E when ASN_BEFORE date is invalid.
23314
 * @return  ASN_AFTER_DATE_E when ASN_AFTER date is invalid.
23315
 */
23316
static int CheckDate(ASNGetData *dataASN, int dateType)
23317
0
{
23318
0
    int ret = 0;
23319
23320
    /* Check BER tag is valid. */
23321
0
    if ((dataASN->tag != ASN_UTC_TIME) &&
23322
0
            (dataASN->tag != ASN_GENERALIZED_TIME)) {
23323
0
        ret = ASN_TIME_E;
23324
0
    }
23325
    /* Check date length is valid. */
23326
0
    if ((ret == 0) && ((dataASN->length > MAX_DATE_SIZE) ||
23327
0
                       (dataASN->length < MIN_DATE_SIZE))) {
23328
0
        ret = ASN_DATE_SZ_E;
23329
0
    }
23330
23331
0
#ifndef NO_ASN_TIME_CHECK
23332
    /* Check date is a valid string and ASN_BEFORE or ASN_AFTER now. */
23333
0
    if ((ret == 0) && (! AsnSkipDateCheck)) {
23334
0
        if (!XVALIDATE_DATE(dataASN->data.ref.data, dataASN->tag, dateType)) {
23335
0
            if (dateType == ASN_BEFORE) {
23336
0
                ret = ASN_BEFORE_DATE_E;
23337
0
            }
23338
0
            else if (dateType == ASN_AFTER) {
23339
0
                ret = ASN_AFTER_DATE_E;
23340
0
            }
23341
0
            else {
23342
0
                ret = ASN_TIME_E;
23343
0
            }
23344
0
        }
23345
0
    }
23346
0
#endif
23347
0
    (void)dateType;
23348
23349
0
    return ret;
23350
0
}
23351
23352
/* Decode a certificate. Internal/non-public API.
23353
 *
23354
 * @param [in]  cert             Certificate object.
23355
 * @param [in]  verify           Whether to verify dates before and after now.
23356
 * @param [out] criticalExt      Critical extension return code.
23357
 * @param [out] badDateRet       Bad date return code.
23358
 * @param [in]  stopAtPubKey     Stop parsing before subjectPublicKeyInfo.
23359
 * @param [in]  stopAfterPubKey  Stop parsing after subjectPublicKeyInfo.
23360
 * @return  0 on success if of the stop arguments is not set, otherwise set to
23361
 *          the corresponding byte offset at which the parsing stopped.
23362
 * @return  ASN_CRIT_EXT_E when a critical extension was not recognized.
23363
 * @return  ASN_TIME_E when date BER tag is nor UTC or GENERALIZED time.
23364
 * @return  ASN_DATE_SZ_E when time data is not supported.
23365
 * @return  ASN_BEFORE_DATE_E when ASN_BEFORE date is invalid.
23366
 * @return  ASN_AFTER_DATE_E when ASN_AFTER date is invalid.
23367
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
23368
 *          is invalid.
23369
 * @return  BUFFER_E when data in buffer is too small.
23370
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
23371
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
23372
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
23373
 *          non-zero length.
23374
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
23375
 */
23376
static int DecodeCertInternal(DecodedCert* cert, int verify, int* criticalExt,
23377
                              int* badDateRet, int stopAtPubKey,
23378
                              int stopAfterPubKey)
23379
0
{
23380
0
    DECL_ASNGETDATA(dataASN, x509CertASN_Length);
23381
0
    int ret = 0;
23382
0
    int badDate = 0;
23383
0
    byte version = 0;
23384
0
    word32 idx;
23385
0
    word32 serialSz = 0;
23386
0
    const unsigned char* issuer = NULL;
23387
0
    word32 issuerSz = 0;
23388
0
    const unsigned char* subject = NULL;
23389
0
    word32 subjectSz = 0;
23390
0
    word32 pubKeyOffset = 0;
23391
0
    word32 pubKeyEnd = 0;
23392
0
    int done = 0;
23393
23394
#if defined(HAVE_RPK)
23395
    /* try to parse the cert as Raw Public Key cert */
23396
    DECL_ASNGETDATA(RPKdataASN, RPKCertASN_Length);
23397
    CALLOC_ASNGETDATA(RPKdataASN, RPKCertASN_Length, ret, cert->heap);
23398
    GetASN_OID(&RPKdataASN[RPKCERTASN_IDX_SPUBKEYINFO_ALGO_OID],
23399
                                                                oidKeyType);
23400
    GetASN_OID(&RPKdataASN[RPKCERTASN_IDX_SPUBKEYINFO_ALGO_CURVEID],
23401
                                                                oidCurveType);
23402
    ret = GetASN_Items(RPKCertASN, RPKdataASN, RPKCertASN_Length, 1,
23403
                           cert->source, &cert->srcIdx, cert->maxIdx);
23404
23405
    if (ret == 0) {
23406
        if (( RPKdataASN[RPKCERTASN_IDX_SPUBKEYINFO_ALGO_NULL].length &&
23407
              RPKdataASN[RPKCERTASN_IDX_SPUBKEYINFO_ALGO_CURVEID].length)
23408
#ifdef WC_RSA_PSS
23409
         || ( RPKdataASN[RPKCERTASN_IDX_SPUBKEYINFO_ALGO_P_SEQ].length &&
23410
            ( RPKdataASN[RPKCERTASN_IDX_SPUBKEYINFO_ALGO_NULL].length ||
23411
              RPKdataASN[RPKCERTASN_IDX_SPUBKEYINFO_ALGO_CURVEID].length))
23412
#endif
23413
        ) {
23414
            WOLFSSL_MSG("Multiple RPK algorithm parameters set.");
23415
            ret = ASN_PARSE_E;
23416
        }
23417
    }
23418
    if (ret == 0) {
23419
        cert->keyOID =
23420
                RPKdataASN[RPKCERTASN_IDX_SPUBKEYINFO_ALGO_OID].data.oid.sum;
23421
23422
        /* Parse the public key. */
23423
        pubKeyOffset = RPKdataASN[RPKCERTASN_IDX_SPUBKEYINFO_SEQ].offset;
23424
        pubKeyEnd = cert->maxIdx;
23425
        ret = GetCertKey(cert, cert->source, &pubKeyOffset, pubKeyEnd);
23426
        if (ret == 0) {
23427
            WOLFSSL_MSG("Raw Public Key certificate found and parsed");
23428
            cert->isRPK = 1;
23429
        }
23430
    }
23431
    /* Dispose of memory before allocating for extension decoding. */
23432
    FREE_ASNGETDATA(RPKdataASN, cert->heap);
23433
23434
    if (ret == 0) {
23435
        return ret;
23436
    }
23437
    else {
23438
        ret = 0;    /* proceed to the original x509 parsing */
23439
    }
23440
#endif /* HAVE_RPK */
23441
23442
0
    CALLOC_ASNGETDATA(dataASN, x509CertASN_Length, ret, cert->heap);
23443
23444
0
    if (ret == 0) {
23445
0
        version = 0;
23446
0
        serialSz = EXTERNAL_SERIAL_SIZE;
23447
23448
        /* Get the version and put the serial number into the buffer. */
23449
0
        GetASN_Int8Bit(&dataASN[X509CERTASN_IDX_TBS_VER_INT], &version);
23450
0
        GetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_SERIAL], cert->serial,
23451
0
                &serialSz);
23452
        /* Check OID types for signature, algorithm, ECC curve and sigAlg. */
23453
0
        GetASN_OID(&dataASN[X509CERTASN_IDX_TBS_ALGOID_OID], oidSigType);
23454
0
        GetASN_OID(&dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_OID],
23455
0
                oidKeyType);
23456
0
        GetASN_OID(&dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_CURVEID],
23457
0
                oidCurveType);
23458
0
        GetASN_OID(&dataASN[X509CERTASN_IDX_SIGALGO_OID], oidSigType);
23459
        /* Parse the X509 certificate. */
23460
0
        ret = GetASN_Items(x509CertASN, dataASN, x509CertASN_Length, 1,
23461
0
                           cert->source, &cert->srcIdx, cert->maxIdx);
23462
#ifdef WOLFSSL_CLANG_TIDY
23463
        /* work around clang-tidy false positive re cert->source. */
23464
        if ((ret == 0) && (cert->source == NULL)) {
23465
            ret = ASN_PARSE_E;
23466
        }
23467
#endif
23468
0
    }
23469
    /* Check version is valid/supported - can't be negative. */
23470
0
    if ((ret == 0) && (version > MAX_X509_VERSION)) {
23471
0
        WOLFSSL_MSG("Unexpected certificate version");
23472
0
        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
23473
0
        ret = ASN_PARSE_E;
23474
0
    }
23475
0
    if (ret == 0) {
23476
0
        int i;
23477
23478
0
        pubKeyOffset = dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ].offset;
23479
        /* Set fields extracted from data. */
23480
0
        cert->version = version;
23481
0
        cert->serialSz = (int)serialSz;
23482
23483
0
    #if !defined(WOLFSSL_NO_ASN_STRICT) && !defined(WOLFSSL_PYTHON) && \
23484
0
        !defined(WOLFSSL_ASN_ALLOW_0_SERIAL)
23485
        /* RFC 5280 section 4.1.2.2 states that non-conforming CAs may issue
23486
         * a negative or zero serial number and should be handled gracefully.
23487
         * Since it is a non-conforming CA that issues a serial of 0 then we
23488
         * treat it as an error here. */
23489
0
        if (cert->serialSz == 1 && cert->serial[0] == 0) {
23490
0
            WOLFSSL_MSG("Error serial number of 0, use WOLFSSL_NO_ASN_STRICT "
23491
0
                "if wanted");
23492
0
            ret = ASN_PARSE_E;
23493
0
        }
23494
0
    #endif
23495
0
        if (cert->serialSz == 0) {
23496
0
            WOLFSSL_MSG("Error serial size is zero. Should be at least one "
23497
0
                        "even with no serial number.");
23498
0
            ret = ASN_PARSE_E;
23499
0
        }
23500
23501
0
        cert->signatureOID = dataASN[X509CERTASN_IDX_TBS_ALGOID_OID].data.oid.sum;
23502
0
        cert->keyOID = dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_OID].data.oid.sum;
23503
0
        cert->certBegin = dataASN[X509CERTASN_IDX_TBS_SEQ].offset;
23504
23505
        /* No bad date error - don't always care. */
23506
0
        badDate = 0;
23507
        /* Find the item with the ASN_BEFORE date and check it. */
23508
0
        i = (dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC].tag != 0)
23509
0
                ? X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC
23510
0
                : X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT;
23511
0
        if ((CheckDate(&dataASN[i], ASN_BEFORE) < 0) && (verify != NO_VERIFY) &&
23512
0
                (verify != VERIFY_SKIP_DATE) && (! AsnSkipDateCheck)) {
23513
0
            badDate = ASN_BEFORE_DATE_E;
23514
0
        }
23515
        /* Store reference to ASN_BEFORE date. */
23516
0
        cert->beforeDate = GetASNItem_Addr(dataASN[i], cert->source);
23517
0
        cert->beforeDateLen = (int)GetASNItem_Length(dataASN[i], cert->source);
23518
23519
        /* Find the item with the ASN_AFTER date and check it. */
23520
0
        i = (dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC].tag != 0)
23521
0
                ? X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC
23522
0
                : X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT;
23523
0
        if ((CheckDate(&dataASN[i], ASN_AFTER) < 0) && (verify != NO_VERIFY) &&
23524
0
                (verify != VERIFY_SKIP_DATE) && (! AsnSkipDateCheck)) {
23525
0
            badDate = ASN_AFTER_DATE_E;
23526
0
        }
23527
        /* Store reference to ASN_AFTER date. */
23528
0
        cert->afterDate = GetASNItem_Addr(dataASN[i], cert->source);
23529
0
        cert->afterDateLen = (int)GetASNItem_Length(dataASN[i], cert->source);
23530
23531
        /* Get the issuer name. */
23532
0
        issuer = cert->source + dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ].offset;
23533
0
        issuerSz = dataASN[X509CERTASN_IDX_TBS_VALIDITY_SEQ].offset -
23534
0
            dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ].offset;
23535
23536
        /* Get the subject name. */
23537
0
        subject = cert->source +
23538
0
            dataASN[X509CERTASN_IDX_TBS_SUBJECT_SEQ].offset;
23539
0
        subjectSz = dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ].offset -
23540
0
            dataASN[X509CERTASN_IDX_TBS_SUBJECT_SEQ].offset;
23541
0
    }
23542
0
    if ((ret == 0) && stopAtPubKey) {
23543
        /* Return any bad date error through badDateRet and return offset of
23544
         * subjectPublicKeyInfo.
23545
         */
23546
0
        if (badDateRet != NULL) {
23547
0
            *badDateRet = badDate;
23548
0
        }
23549
0
        done = 1;
23550
0
    }
23551
23552
0
    if ((ret == 0) && (!done)) {
23553
        /* Store the signature information. */
23554
0
        cert->sigIndex = dataASN[X509CERTASN_IDX_SIGALGO_SEQ].offset;
23555
0
        GetASN_GetConstRef(&dataASN[X509CERTASN_IDX_SIGNATURE],
23556
0
                &cert->signature, &cert->sigLength);
23557
        /* Make sure 'signature' and 'signatureAlgorithm' are the same. */
23558
0
        if (dataASN[X509CERTASN_IDX_SIGALGO_OID].data.oid.sum
23559
0
                != cert->signatureOID) {
23560
0
            WOLFSSL_ERROR_VERBOSE(ASN_SIG_OID_E);
23561
0
            ret = ASN_SIG_OID_E;
23562
0
        }
23563
        /* Parameters not allowed after ECDSA or EdDSA algorithm OID. */
23564
0
        else if (IsSigAlgoECC(cert->signatureOID)) {
23565
0
        #ifndef WOLFSSL_ECC_SIGALG_PARAMS_NULL_ALLOWED
23566
0
            if (dataASN[X509CERTASN_IDX_SIGALGO_PARAMS_NULL].tag != 0) {
23567
0
                WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
23568
0
                ret = ASN_PARSE_E;
23569
0
            }
23570
0
        #endif
23571
0
        #ifdef WC_RSA_PSS
23572
0
            if (dataASN[X509CERTASN_IDX_SIGALGO_PARAMS].tag != 0) {
23573
0
                WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
23574
0
                ret = ASN_PARSE_E;
23575
0
            }
23576
0
        #endif
23577
0
        }
23578
0
    #ifdef WC_RSA_PSS
23579
        /* Check parameters starting with a SEQUENCE. */
23580
0
        else if (dataASN[X509CERTASN_IDX_SIGALGO_PARAMS].tag != 0) {
23581
0
            word32 oid = dataASN[X509CERTASN_IDX_SIGALGO_OID].data.oid.sum;
23582
0
            word32 sigAlgParamsSz = 0;
23583
23584
            /* Parameters only with RSA PSS. */
23585
0
            if (oid != CTC_RSASSAPSS) {
23586
0
                WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
23587
0
                ret = ASN_PARSE_E;
23588
0
            }
23589
0
            if (ret == 0) {
23590
0
                const byte* tbsParams;
23591
0
                word32 tbsParamsSz;
23592
0
                const byte* sigAlgParams;
23593
23594
                /* Check RSA PSS parameters are the same. */
23595
0
                tbsParams =
23596
0
                    GetASNItem_Addr(dataASN[X509CERTASN_IDX_TBS_ALGOID_PARAMS],
23597
0
                        cert->source);
23598
0
                tbsParamsSz =
23599
0
                    GetASNItem_Length(dataASN[X509CERTASN_IDX_TBS_ALGOID_PARAMS],
23600
0
                        cert->source);
23601
0
                sigAlgParams =
23602
0
                    GetASNItem_Addr(dataASN[X509CERTASN_IDX_SIGALGO_PARAMS],
23603
0
                        cert->source);
23604
0
                sigAlgParamsSz =
23605
0
                    GetASNItem_Length(dataASN[X509CERTASN_IDX_SIGALGO_PARAMS],
23606
0
                        cert->source);
23607
0
                if ((tbsParamsSz != sigAlgParamsSz) ||
23608
0
                        (XMEMCMP(tbsParams, sigAlgParams, tbsParamsSz) != 0)) {
23609
0
                    WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
23610
0
                    ret = ASN_PARSE_E;
23611
0
                }
23612
0
            }
23613
0
            if (ret == 0) {
23614
                /* Store parameters for use in signature verification. */
23615
0
                cert->sigParamsIndex =
23616
0
                    dataASN[X509CERTASN_IDX_SIGALGO_PARAMS].offset;
23617
0
                cert->sigParamsLength = sigAlgParamsSz;
23618
0
            }
23619
0
        }
23620
0
    #endif
23621
0
    }
23622
0
    if ((ret == 0) && (!done)) {
23623
0
        pubKeyEnd = dataASN[X509CERTASN_IDX_TBS_ISSUERUID].offset;
23624
0
        if (stopAfterPubKey) {
23625
            /* Return any bad date error through badDateRed and return offset
23626
             * after subjectPublicKeyInfo.
23627
             */
23628
0
            if (badDateRet != NULL) {
23629
0
                *badDateRet = badDate;
23630
0
            }
23631
0
            done = 1;
23632
0
        }
23633
0
    }
23634
0
    if ((ret == 0) && (!done) &&
23635
0
            (dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].data.ref.data != NULL)) {
23636
0
    #ifndef ALLOW_V1_EXTENSIONS
23637
        /* Certificate extensions were only defined in version 2. */
23638
0
        if (cert->version < 2) {
23639
0
            WOLFSSL_MSG("\tv1 and v2 certs not allowed extensions");
23640
0
            WOLFSSL_ERROR_VERBOSE(ASN_VERSION_E);
23641
0
            ret = ASN_VERSION_E;
23642
0
        }
23643
0
    #endif
23644
0
        if (ret == 0) {
23645
            /* Save references to extension data. */
23646
0
            cert->extensions    = GetASNItem_Addr(
23647
0
                    dataASN[X509CERTASN_IDX_TBS_EXT], cert->source);
23648
0
            cert->extensionsSz  = (int)GetASNItem_Length(
23649
0
                    dataASN[X509CERTASN_IDX_TBS_EXT], cert->source);
23650
0
            cert->extensionsIdx = dataASN[X509CERTASN_IDX_TBS_EXT].offset;
23651
            /* Advance past extensions. */
23652
0
            cert->srcIdx = dataASN[X509CERTASN_IDX_SIGALGO_SEQ].offset;
23653
0
        }
23654
0
    }
23655
23656
    /* Dispose of memory before allocating for extension decoding. */
23657
0
    FREE_ASNGETDATA(dataASN, cert->heap);
23658
23659
0
    if ((ret == 0) && (issuer != NULL)) {
23660
0
        idx = 0;
23661
        /* Put issuer into cert and calculate hash. */
23662
0
        ret = GetCertName(cert, cert->issuer, cert->issuerHash, ASN_ISSUER, issuer,
23663
0
            &idx, issuerSz);
23664
0
    }
23665
0
    if ((ret == 0) && (subject != NULL)) {
23666
0
        idx = 0;
23667
        /* Put subject into cert and calculate hash. */
23668
0
        ret = GetCertName(cert, cert->subject, cert->subjectHash, ASN_SUBJECT,
23669
0
            subject, &idx, subjectSz);
23670
0
    }
23671
0
    if (ret == 0) {
23672
        /* Determine if self signed by comparing issuer and subject hashes. */
23673
    #ifdef WOLFSSL_CERT_REQ
23674
        if (cert->isCSR) {
23675
            cert->selfSigned = 1;
23676
        }
23677
        else
23678
    #endif
23679
0
        {
23680
0
            cert->selfSigned = (XMEMCMP(cert->issuerHash, cert->subjectHash,
23681
0
                                        KEYID_SIZE) == 0);
23682
0
        }
23683
0
        if (stopAtPubKey) {
23684
0
            ret = (int)pubKeyOffset;
23685
0
        }
23686
0
    }
23687
23688
0
    if ((ret == 0) && (!stopAtPubKey)) {
23689
        /* Parse the public key. */
23690
0
        idx = pubKeyOffset;
23691
0
        ret = GetCertKey(cert, cert->source, &idx, pubKeyEnd);
23692
0
    }
23693
0
    if ((ret == 0) && (!stopAtPubKey) && (!stopAfterPubKey) &&
23694
0
            (cert->extensions != NULL)) {
23695
        /* Decode the extension data starting at [3]. */
23696
0
        ret = DecodeCertExtensions(cert);
23697
0
        if (criticalExt != NULL) {
23698
0
            if (ret == WC_NO_ERR_TRACE(ASN_CRIT_EXT_E)) {
23699
                /* Return critical extension not recognized. */
23700
0
                *criticalExt = ret;
23701
0
                ret = 0;
23702
0
            }
23703
0
            else {
23704
                /* No critical extension error. */
23705
0
                *criticalExt = 0;
23706
0
            }
23707
0
        }
23708
0
    }
23709
23710
0
    if ((ret == 0) && (!done) && (badDate != 0)) {
23711
        /* Parsed whole certificate fine but return any date errors. */
23712
0
        ret = badDate;
23713
0
    }
23714
23715
0
    return ret;
23716
0
}
23717
23718
/* Decode BER/DER data into certificate object.
23719
 *
23720
 * BER/DER data information held in source, srcIdx and maxIdx fields of
23721
 * certificate object.
23722
 *
23723
 * @param [in] cert         Decoded certificate object.
23724
 * @param [in] verify       Whether to find CA and verify certificate.
23725
 * @param [in] criticalExt  Any error for critical extensions not recognized.
23726
 * @return  0 on success.
23727
 * @return  ASN_CRIT_EXT_E when a critical extension was not recognized.
23728
 * @return  ASN_TIME_E when date BER tag is nor UTC or GENERALIZED time.
23729
 * @return  ASN_DATE_SZ_E when time data is not supported.
23730
 * @return  ASN_BEFORE_DATE_E when ASN_BEFORE date is invalid.
23731
 * @return  ASN_AFTER_DATE_E when ASN_AFTER date is invalid.
23732
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
23733
 *          is invalid.
23734
 * @return  BUFFER_E when data in buffer is too small.
23735
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
23736
 * @return  ASN_BITSTR_E when the expected BIT_STRING tag is not found.
23737
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
23738
 *          non-zero length.
23739
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
23740
 */
23741
int DecodeCert(DecodedCert* cert, int verify, int* criticalExt)
23742
0
{
23743
0
    return DecodeCertInternal(cert, verify, criticalExt, NULL, 0, 0);
23744
0
}
23745
23746
#ifdef WOLFSSL_CERT_REQ
23747
/* ASN.1 template for certificate request Attribute.
23748
 * PKCS #10: RFC 2986, 4.1 - CertificationRequestInfo
23749
 */
23750
static const ASNItem reqAttrASN[] = {
23751
/* SEQ  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
23752
                              /* type */
23753
/* TYPE */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
23754
                              /* values */
23755
/* VALS */     { 1, ASN_SET, 1, 0, 0 },
23756
};
23757
enum {
23758
    REQATTRASN_IDX_SEQ = 0,
23759
    REQATTRASN_IDX_TYPE,
23760
    REQATTRASN_IDX_VALS
23761
};
23762
23763
/* Number of items in ASN.1 template for certificate request Attribute. */
23764
#define reqAttrASN_Length (sizeof(reqAttrASN) / sizeof(ASNItem))
23765
23766
/* ASN.1 template for a string choice. */
23767
static const ASNItem strAttrASN[] = {
23768
    { 0, 0, 0, 0, 0 },
23769
};
23770
enum {
23771
    STRATTRASN_IDX_STR = 0
23772
};
23773
23774
/* Number of items in ASN.1 template for a string choice. */
23775
#define strAttrASN_Length (sizeof(strAttrASN) / sizeof(ASNItem))
23776
23777
/* ASN.1 choices for types for a string in an attribute. */
23778
static const byte strAttrChoice[] = {
23779
    ASN_PRINTABLE_STRING, ASN_IA5_STRING, ASN_UTF8STRING, 0
23780
};
23781
23782
/* Decode a certificate request attribute's value.
23783
 *
23784
 * @param [in]  cert         Certificate request object.
23785
 * @param [out] criticalExt  Critical extension return code.
23786
 * @param [in]  oid          OID describing which attribute was found.
23787
 * @param [in]  aIdx         Index into certificate source to start parsing.
23788
 * @param [in]  input        Attribute value data.
23789
 * @param [in]  maxIdx       Maximum index to parse to.
23790
 * @return  0 on success.
23791
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
23792
 *          is invalid.
23793
 */
23794
static int DecodeCertReqAttrValue(DecodedCert* cert, int* criticalExt,
23795
    word32 oid, word32 aIdx, const byte* input, word32 maxIdx)
23796
{
23797
    int ret = 0;
23798
    word32 idx = 0;
23799
    ASNGetData strDataASN[strAttrASN_Length];
23800
23801
    switch (oid) {
23802
        case PKCS9_CONTENT_TYPE_OID:
23803
            /* Clear dynamic data and specify choices acceptable. */
23804
            XMEMSET(strDataASN, 0, sizeof(strDataASN));
23805
            GetASN_Choice(&strDataASN[STRATTRASN_IDX_STR], strAttrChoice);
23806
            /* Parse a string. */
23807
            ret = GetASN_Items(strAttrASN, strDataASN, strAttrASN_Length,
23808
                               1, input, &idx, maxIdx);
23809
            if (ret == 0) {
23810
                /* Store references to password data. */
23811
                cert->contentType =
23812
                        (char*)strDataASN[STRATTRASN_IDX_STR].data.ref.data;
23813
                cert->contentTypeLen =
23814
                        (int)strDataASN[STRATTRASN_IDX_STR].data.ref.length;
23815
            }
23816
            break;
23817
23818
        /* A password by which the entity may request certificate revocation.
23819
         * PKCS#9: RFC 2985, 5.4.1 - Challenge password
23820
         */
23821
        case CHALLENGE_PASSWORD_OID:
23822
            /* Clear dynamic data and specify choices acceptable. */
23823
            XMEMSET(strDataASN, 0, sizeof(strDataASN));
23824
            GetASN_Choice(&strDataASN[STRATTRASN_IDX_STR], strAttrChoice);
23825
            /* Parse a string. */
23826
            ret = GetASN_Items(strAttrASN, strDataASN, strAttrASN_Length,
23827
                               1, input, &idx, maxIdx);
23828
            if (ret == 0) {
23829
                /* Store references to password data. */
23830
                cert->cPwd =
23831
                        (char*)strDataASN[STRATTRASN_IDX_STR].data.ref.data;
23832
                cert->cPwdLen = (int)strDataASN[STRATTRASN_IDX_STR].
23833
                    data.ref.length;
23834
            }
23835
            break;
23836
23837
        /* Requested serial number to issue with.
23838
         * PKCS#9: RFC 2985, 5.2.10 - Serial Number
23839
         * (References: ISO/IEC 9594-6:1997)
23840
         */
23841
        case SERIAL_NUMBER_OID:
23842
            /* Clear dynamic data and specify choices acceptable. */
23843
            XMEMSET(strDataASN, 0, sizeof(strDataASN));
23844
            GetASN_Choice(&strDataASN[STRATTRASN_IDX_STR], strAttrChoice);
23845
            /* Parse a string. */
23846
            ret = GetASN_Items(strAttrASN, strDataASN, strAttrASN_Length,
23847
                               1, input, &idx, maxIdx);
23848
            if (ret == 0) {
23849
                /* Store references to serial number. */
23850
                cert->sNum =
23851
                        (char*)strDataASN[STRATTRASN_IDX_STR].data.ref.data;
23852
                cert->sNumLen = (int)strDataASN[STRATTRASN_IDX_STR].
23853
                    data.ref.length;
23854
                /* Store serial number if small enough. */
23855
                if (cert->sNumLen <= EXTERNAL_SERIAL_SIZE) {
23856
                    XMEMCPY(cert->serial, cert->sNum, (size_t)cert->sNumLen);
23857
                    cert->serialSz = cert->sNumLen;
23858
                }
23859
            }
23860
            break;
23861
23862
        case UNSTRUCTURED_NAME_OID:
23863
            /* Clear dynamic data and specify choices acceptable. */
23864
            XMEMSET(strDataASN, 0, sizeof(strDataASN));
23865
            GetASN_Choice(&strDataASN[STRATTRASN_IDX_STR], strAttrChoice);
23866
            /* Parse a string. */
23867
            ret = GetASN_Items(strAttrASN, strDataASN, strAttrASN_Length,
23868
                               1, input, &idx, maxIdx);
23869
            if (ret == 0) {
23870
                /* Store references to unstructured name. */
23871
                cert->unstructuredName =
23872
                        (char*)strDataASN[STRATTRASN_IDX_STR].data.ref.data;
23873
                cert->unstructuredNameLen = (int)strDataASN[STRATTRASN_IDX_STR].
23874
                    data.ref.length;
23875
            }
23876
            break;
23877
23878
        /* Certificate extensions to be included in generated certificate.
23879
         * PKCS#9: RFC 2985, 5.4.2 - Extension request
23880
         */
23881
        case EXTENSION_REQUEST_OID:
23882
            /* Store references to all extensions. */
23883
            cert->extensions    = input;
23884
            cert->extensionsSz  = (int)maxIdx;
23885
            cert->extensionsIdx = aIdx;
23886
23887
            /* Decode and validate extensions. */
23888
            ret = DecodeCertExtensions(cert);
23889
            if (ret == WC_NO_ERR_TRACE(ASN_CRIT_EXT_E)) {
23890
                /* Return critical extension not recognized. */
23891
                *criticalExt = ret;
23892
                ret = 0;
23893
            }
23894
            else {
23895
                /* No critical extension error. */
23896
                *criticalExt = 0;
23897
            }
23898
            break;
23899
23900
        default:
23901
            ret = ASN_PARSE_E;
23902
            break;
23903
    }
23904
23905
    return ret;
23906
}
23907
23908
/* Decode attributes of a BER encoded certificate request.
23909
 *
23910
 * RFC 2986 - PKCS #10: Certification Request Syntax Specification Version 1.7
23911
 *
23912
 * Outer sequence has been removed.
23913
 *
23914
 * @param [in]  cert         Certificate request object.
23915
 * @param [out] criticalExt  Critical extension return code.
23916
 * @param [in]  idx          Index into certificate source to start parsing.
23917
 * @param [in]  maxIdx       Maximum index to parse to.
23918
 * @return  0 on success.
23919
 * @return  ASN_CRIT_EXT_E when a critical extension was not recognized.
23920
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
23921
 *          is invalid.
23922
 * @return  BUFFER_E when data in buffer is too small.
23923
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
23924
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
23925
 *          non-zero length.
23926
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
23927
 */
23928
static int DecodeCertReqAttributes(DecodedCert* cert, int* criticalExt,
23929
                                   word32 idx, word32 maxIdx)
23930
{
23931
    DECL_ASNGETDATA(dataASN, reqAttrASN_Length);
23932
    int ret = 0;
23933
23934
    WOLFSSL_ENTER("DecodeCertReqAttributes");
23935
23936
    ALLOC_ASNGETDATA(dataASN, reqAttrASN_Length, ret, cert->heap);
23937
23938
    /* Parse each attribute until all data used up. */
23939
    while ((ret == 0) && (idx < maxIdx)) {
23940
        /* Clear dynamic data. */
23941
        XMEMSET(dataASN, 0, sizeof(ASNGetData) * reqAttrASN_Length);
23942
        GetASN_OID(&dataASN[REQATTRASN_IDX_TYPE], oidIgnoreType);
23943
23944
        /* Parse an attribute. */
23945
        ret = GetASN_Items(reqAttrASN, dataASN, reqAttrASN_Length, 0,
23946
                           cert->source, &idx, maxIdx);
23947
        /* idx is now at end of attribute data. */
23948
        if (ret == 0) {
23949
            ret = DecodeCertReqAttrValue(cert, criticalExt,
23950
                dataASN[REQATTRASN_IDX_TYPE].data.oid.sum,
23951
                GetASNItem_DataIdx(dataASN[REQATTRASN_IDX_VALS], cert->source),
23952
                dataASN[REQATTRASN_IDX_VALS].data.ref.data,
23953
                dataASN[REQATTRASN_IDX_VALS].data.ref.length);
23954
        }
23955
    }
23956
23957
    FREE_ASNGETDATA(dataASN, cert->heap);
23958
    return ret;
23959
}
23960
23961
/* ASN.1 template for a certificate request.
23962
 * PKCS#10: RFC 2986, 4.1 - CertificationRequestInfo
23963
 * PKCS#10: RFC 2986, 4.2 - CertificationRequest
23964
 */
23965
static const ASNItem certReqASN[] = {
23966
            /* CertificationRequest */
23967
/* SEQ                              */ { 0, ASN_SEQUENCE, 1, 1, 0 },
23968
                                                          /* CertificationRequestInfo */
23969
/* INFO_SEQ                         */     { 1, ASN_SEQUENCE, 1, 1, 0 },
23970
                                                              /* version              INTEGER { v1(0), v2(1), v3(2) */
23971
/* INFO_VER                         */         { 2, ASN_INTEGER, 0, 0, 0 },
23972
                                                              /* subject              Name */
23973
/* INFO_SUBJ_SEQ                    */         { 2, ASN_SEQUENCE, 1, 0, 0 },
23974
                                                              /* subjectPublicKeyInfo SubjectPublicKeyInfo */
23975
/* INFO_SPUBKEYINFO_SEQ             */         { 2, ASN_SEQUENCE, 1, 1, 0 },
23976
                                                                  /* algorithm          AlgorithmIdentifier */
23977
/* INFO_SPUBKEYINFO_ALGOID_SEQ      */             { 3, ASN_SEQUENCE, 1, 1, 0 },
23978
                                                                      /* Algorithm    OBJECT IDENTIFIER */
23979
/* INFO_SPUBKEYINFO_ALGOID_OID      */                 { 4, ASN_OBJECT_ID, 0, 0, 0 },
23980
                                                                      /* parameters   ANY defined by algorithm OPTIONAL */
23981
/* INFO_SPUBKEYINFO_ALGOID_NULL     */                 { 4, ASN_TAG_NULL, 0, 0, 1 },
23982
/* INFO_SPUBKEYINFO_ALGOID_CURVEID  */                 { 4, ASN_OBJECT_ID, 0, 0, 1 },
23983
/* INFO_SPUBKEYINFO_ALGOID_PARAMS   */                 { 4, ASN_SEQUENCE, 1, 0, 1 },
23984
                                                                  /* subjectPublicKey   BIT STRING */
23985
/* INFO_SPUBKEYINFO_PUBKEY          */             { 3, ASN_BIT_STRING, 0, 0, 0 },
23986
                                                              /* attributes       [0] Attributes */
23987
/* INFO_ATTRS                       */         { 2, ASN_CONTEXT_SPECIFIC | 0, 1, 0, 1 },
23988
                                                          /* signatureAlgorithm   AlgorithmIdentifier */
23989
/* INFO_SIGALGO_SEQ                 */     { 1, ASN_SEQUENCE, 1, 1, 0 },
23990
                                                              /* Algorithm    OBJECT IDENTIFIER */
23991
/* INFO_SIGALGO_OID                 */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
23992
                                                              /* parameters   ANY defined by algorithm OPTIONAL */
23993
/* INFO_SIGALGO_NULL                */         { 2, ASN_TAG_NULL, 0, 0, 1 },
23994
                                                          /* signature            BIT STRING */
23995
/* INFO_SIGNATURE                   */     { 1, ASN_BIT_STRING, 0, 0, 0 },
23996
};
23997
enum {
23998
    CERTREQASN_IDX_SEQ = 0,
23999
    CERTREQASN_IDX_INFO_SEQ,
24000
    CERTREQASN_IDX_INFO_VER,
24001
    CERTREQASN_IDX_INFO_SUBJ_SEQ,
24002
    CERTREQASN_IDX_INFO_SPUBKEYINFO_SEQ,
24003
    CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_SEQ,
24004
    CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_OID,
24005
    CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_NULL,
24006
    CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_CURVEID,
24007
    CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_PARAMS,
24008
    CERTREQASN_IDX_INFO_SPUBKEYINFO_PUBKEY,
24009
    CERTREQASN_IDX_INFO_ATTRS,
24010
    CERTREQASN_IDX_INFO_SIGALGO_SEQ,
24011
    CERTREQASN_IDX_INFO_SIGALGO_OID,
24012
    CERTREQASN_IDX_INFO_SIGALGO_NULL,
24013
    CERTREQASN_IDX_INFO_SIGNATURE
24014
};
24015
24016
/* Number of items in ASN.1 template for a certificate request. */
24017
#define certReqASN_Length (sizeof(certReqASN) / sizeof(ASNItem))
24018
24019
/* Parse BER encoded certificate request.
24020
 *
24021
 * RFC 2986 - PKCS #10: Certification Request Syntax Specification Version 1.7
24022
 *
24023
 * @param [in]  cert         Certificate request object.
24024
 * @param [out] criticalExt  Critical extension return code.
24025
 * @return  0 on success.
24026
 * @return  ASN_CRIT_EXT_E when a critical extension was not recognized.
24027
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
24028
 *          is invalid.
24029
 * @return  BUFFER_E when data in buffer is too small.
24030
 * @return  ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
24031
 * @return  ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
24032
 *          non-zero length.
24033
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
24034
 * @return  MEMORY_E on dynamic memory allocation failure.
24035
 */
24036
static int DecodeCertReq(DecodedCert* cert, int* criticalExt)
24037
{
24038
    DECL_ASNGETDATA(dataASN, certReqASN_Length);
24039
    int ret = 0;
24040
    byte version = 0;
24041
    word32 idx;
24042
24043
    CALLOC_ASNGETDATA(dataASN, certReqASN_Length, ret, cert->heap);
24044
24045
    if (ret == 0) {
24046
        /* Default version is 0. */
24047
        version = 0;
24048
24049
        /* Set version var and OID types to expect. */
24050
        GetASN_Int8Bit(&dataASN[CERTREQASN_IDX_INFO_VER], &version);
24051
        GetASN_OID(&dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_OID],
24052
                oidKeyType);
24053
        GetASN_OID(&dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_CURVEID],
24054
                oidCurveType);
24055
        GetASN_OID(&dataASN[CERTREQASN_IDX_INFO_SIGALGO_OID], oidSigType);
24056
        /* Parse a certificate request. */
24057
        ret = GetASN_Items(certReqASN, dataASN, certReqASN_Length, 1,
24058
                           cert->source, &cert->srcIdx, cert->maxIdx);
24059
    }
24060
    /* Check version is valid/supported - can't be negative. */
24061
    if ((ret == 0) && (version > MAX_X509_VERSION)) {
24062
        WOLFSSL_MSG("Unexpected certificate request version");
24063
        ret = ASN_PARSE_E;
24064
    }
24065
    if (ret == 0) {
24066
        /* Set fields of certificate request. */
24067
        cert->version = version;
24068
        cert->signatureOID =
24069
              dataASN[CERTREQASN_IDX_INFO_SIGALGO_OID].data.oid.sum;
24070
        cert->keyOID =
24071
              dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_OID].data.oid.sum;
24072
        cert->certBegin = dataASN[CERTREQASN_IDX_INFO_SEQ].offset;
24073
24074
        /* Parse the subject name. */
24075
        idx = dataASN[CERTREQASN_IDX_INFO_SUBJ_SEQ].offset;
24076
        ret = GetCertName(cert, cert->subject, cert->subjectHash, ASN_SUBJECT,
24077
                          cert->source, &idx,
24078
                          dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_SEQ].offset);
24079
    }
24080
    if (ret == 0) {
24081
        /* Parse the certificate request Attributes. */
24082
        ret = DecodeCertReqAttributes(cert, criticalExt,
24083
                GetASNItem_DataIdx(dataASN[CERTREQASN_IDX_INFO_ATTRS],
24084
                        cert->source),
24085
                dataASN[CERTREQASN_IDX_INFO_SIGALGO_SEQ].offset);
24086
    }
24087
    if (ret == 0) {
24088
        /* Parse the certificate request's key. */
24089
        idx = dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_SEQ].offset;
24090
        ret = GetCertKey(cert, cert->source, &idx,
24091
                dataASN[CERTREQASN_IDX_INFO_ATTRS].offset);
24092
    }
24093
    if (ret == 0) {
24094
        /* Store references to signature. */
24095
        cert->sigIndex = dataASN[CERTREQASN_IDX_INFO_SIGALGO_SEQ].offset;
24096
        GetASN_GetConstRef(&dataASN[CERTREQASN_IDX_INFO_SIGNATURE],
24097
                &cert->signature, &cert->sigLength);
24098
    }
24099
24100
    FREE_ASNGETDATA(dataASN, cert->heap);
24101
    return ret;
24102
}
24103
24104
#endif /* WOLFSSL_CERT_REQ */
24105
24106
#endif
24107
24108
int ParseCert(DecodedCert* cert, int type, int verify, void* cm)
24109
0
{
24110
0
    int   ret;
24111
0
#if (!defined(WOLFSSL_NO_MALLOC) && !defined(NO_WOLFSSL_CM_VERIFY)) || \
24112
0
    defined(WOLFSSL_DYN_CERT)
24113
0
    char* ptr;
24114
0
#endif
24115
24116
0
    ret = ParseCertRelative(cert, type, verify, cm, NULL);
24117
0
    if (ret < 0)
24118
0
        return ret;
24119
24120
0
#if (!defined(WOLFSSL_NO_MALLOC) && !defined(NO_WOLFSSL_CM_VERIFY)) || \
24121
0
    defined(WOLFSSL_DYN_CERT)
24122
    /* cert->subjectCN not stored as copy of WOLFSSL_NO_MALLOC defined */
24123
0
    if (cert->subjectCNLen > 0) {
24124
0
        ptr = (char*)XMALLOC((size_t)cert->subjectCNLen + 1, cert->heap,
24125
0
                              DYNAMIC_TYPE_SUBJECT_CN);
24126
0
        if (ptr == NULL)
24127
0
            return MEMORY_E;
24128
0
        XMEMCPY(ptr, cert->subjectCN, (size_t)cert->subjectCNLen);
24129
0
        ptr[cert->subjectCNLen] = '\0';
24130
0
        cert->subjectCN = ptr;
24131
0
        cert->subjectCNStored = 1;
24132
0
    }
24133
0
#endif
24134
24135
0
#if (!defined(WOLFSSL_NO_MALLOC) && !defined(NO_WOLFSSL_CM_VERIFY)) || \
24136
0
    defined(WOLFSSL_DYN_CERT)
24137
    /* cert->publicKey not stored as copy if WOLFSSL_NO_MALLOC defined */
24138
0
    if ((cert->keyOID == RSAk
24139
0
    #ifdef WC_RSA_PSS
24140
0
         || cert->keyOID == RSAPSSk
24141
0
    #endif
24142
0
         ) && cert->publicKey != NULL && cert->pubKeySize > 0) {
24143
0
        ptr = (char*)XMALLOC(cert->pubKeySize, cert->heap,
24144
0
                              DYNAMIC_TYPE_PUBLIC_KEY);
24145
0
        if (ptr == NULL)
24146
0
            return MEMORY_E;
24147
0
        XMEMCPY(ptr, cert->publicKey, cert->pubKeySize);
24148
0
        cert->publicKey = (byte *)ptr;
24149
0
        cert->pubKeyStored = 1;
24150
0
    }
24151
0
#endif
24152
24153
0
    return ret;
24154
0
}
24155
24156
int wc_ParseCert(DecodedCert* cert, int type, int verify, void* cm)
24157
0
{
24158
0
    return ParseCert(cert, type, verify, cm);
24159
0
}
24160
24161
#ifdef WOLFCRYPT_ONLY
24162
24163
/* dummy functions, not using wolfSSL so don't need actual ones */
24164
Signer* GetCA(void* signers, byte* hash);
24165
Signer* GetCA(void* signers, byte* hash)
24166
{
24167
    (void)hash;
24168
24169
    return (Signer*)signers;
24170
}
24171
24172
#ifndef NO_SKID
24173
Signer* GetCAByName(void* signers, byte* hash);
24174
Signer* GetCAByName(void* signers, byte* hash)
24175
{
24176
    (void)hash;
24177
24178
    return (Signer*)signers;
24179
}
24180
#endif /* NO_SKID */
24181
24182
#ifdef WOLFSSL_AKID_NAME
24183
Signer* GetCAByAKID(void* vp, const byte* issuer, word32 issuerSz,
24184
        const byte* serial, word32 serialSz);
24185
Signer* GetCAByAKID(void* vp, const byte* issuer, word32 issuerSz,
24186
        const byte* serial, word32 serialSz)
24187
{
24188
    (void)issuer;
24189
    (void)issuerSz;
24190
    (void)serial;
24191
    (void)serialSz;
24192
24193
    return (Signer*)vp;
24194
}
24195
#endif
24196
24197
#endif /* WOLFCRYPT_ONLY */
24198
24199
#if defined(WOLFSSL_NO_TRUSTED_CERTS_VERIFY) && !defined(NO_SKID)
24200
static Signer* GetCABySubjectAndPubKey(DecodedCert* cert, void* cm)
24201
{
24202
    Signer* ca = NULL;
24203
    if (cert->extSubjKeyIdSet)
24204
        ca = GetCA(cm, cert->extSubjKeyId);
24205
    if (ca == NULL)
24206
        ca = GetCAByName(cm, cert->subjectHash);
24207
    if (ca) {
24208
        if ((ca->pubKeySize == cert->pubKeySize) &&
24209
               (XMEMCMP(ca->publicKey, cert->publicKey, ca->pubKeySize) == 0)) {
24210
            return ca;
24211
        }
24212
    }
24213
    return NULL;
24214
}
24215
#endif
24216
24217
#if defined(WOLFSSL_SMALL_CERT_VERIFY) || defined(OPENSSL_EXTRA)
24218
#ifdef WOLFSSL_ASN_TEMPLATE
24219
/* Get the Hash of the Authority Key Identifier from the list of extensions.
24220
 *
24221
 * @param [in]  input   Input data.
24222
 * @param [in]  maxIdx  Maximum index for data.
24223
 * @param [in]  sigOID  Signature OID for determining hash algorithm.
24224
 * @param [out] hash    Hash of AKI.
24225
 * @param [out] set     Whether the hash buffer was set.
24226
 * @param [in]  heap    Dynamic memory allocation hint.
24227
 * @return  0 on success.
24228
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
24229
 *          is invalid.
24230
 * @return  MEMORY_E on dynamic memory allocation failure.
24231
 */
24232
static int GetAKIHash(const byte* input, word32 maxIdx, word32 sigOID,
24233
                      byte* hash, int* set, void* heap)
24234
{
24235
    /* AKI and Certificate Extension ASN.1 templates are the same length. */
24236
    DECL_ASNGETDATA(dataASN, certExtASN_Length);
24237
    int ret = 0;
24238
    word32 idx = 0;
24239
    word32 extEndIdx;
24240
    byte* extData;
24241
    word32 extDataSz;
24242
    byte critical;
24243
24244
    ALLOC_ASNGETDATA(dataASN, certExtASN_Length, ret, heap);
24245
    (void)heap;
24246
24247
    extEndIdx = idx + maxIdx;
24248
24249
    /* Step through each extension looking for AKI. */
24250
    while ((ret == 0) && (idx < extEndIdx)) {
24251
        /* Clear dynamic data and check for certificate extension type OIDs. */
24252
        XMEMSET(dataASN, 0, sizeof(*dataASN) * certExtASN_Length);
24253
        GetASN_OID(&dataASN[CERTEXTASN_IDX_OID], oidCertExtType);
24254
        /* Set criticality variable. */
24255
        GetASN_Int8Bit(&dataASN[CERTEXTASN_IDX_CRIT], &critical);
24256
        /* Parse an extension. */
24257
        ret = GetASN_Items(certExtASN, dataASN, certExtASN_Length, 0, input,
24258
                &idx, extEndIdx);
24259
        if (ret == 0) {
24260
            /* Get reference to extension data and move index on past this
24261
             * extension. */
24262
            GetASN_GetRef(&dataASN[CERTEXTASN_IDX_VAL], &extData, &extDataSz);
24263
            idx += extDataSz;
24264
24265
            /* Check whether we have the AKI extension. */
24266
            if (dataASN[CERTEXTASN_IDX_OID].data.oid.sum == AUTH_KEY_OID) {
24267
                /* Clear dynamic data. */
24268
                XMEMSET(dataASN, 0, sizeof(*dataASN) * authKeyIdASN_Length);
24269
                /* Start parsing extension data from the start. */
24270
                idx = 0;
24271
                /* Parse AKI extension data. */
24272
                ret = GetASN_Items(authKeyIdASN, dataASN, authKeyIdASN_Length,
24273
                        1, extData, &idx, extDataSz);
24274
                if ((ret == 0) &&
24275
                        (dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data
24276
                                != NULL)) {
24277
                    /* We parsed successfully and have data. */
24278
                    *set = 1;
24279
                    /* Get the hash or hash of the hash if wrong size. */
24280
                    ret = GetHashId(
24281
                        dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data,
24282
                        (int)dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.length,
24283
                        hash, HashIdAlg(sigOID));
24284
                }
24285
                break;
24286
            }
24287
        }
24288
    }
24289
24290
    FREE_ASNGETDATA(dataASN, heap);
24291
    return ret;
24292
}
24293
#endif
24294
24295
/* Only quick step through the certificate to find fields that are then used
24296
 * in certificate signature verification.
24297
 * Must use the signature OID from the signed part of the certificate.
24298
 * Works also on certificate signing requests.
24299
 *
24300
 * This is only for minimizing dynamic memory usage during TLS certificate
24301
 * chain processing.
24302
 * Doesn't support:
24303
 *   OCSP Only: alt lookup using subject and pub key w/o sig check
24304
 */
24305
static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap,
24306
        void* cm, const byte* pubKey, word32 pubKeySz, int pubKeyOID, int req)
24307
{
24308
#ifndef WOLFSSL_ASN_TEMPLATE
24309
#if !defined(WOLFSSL_SMALL_STACK) || defined(WOLFSSL_NO_MALLOC)
24310
    SignatureCtx  sigCtx[1];
24311
#else
24312
    SignatureCtx* sigCtx;
24313
#endif
24314
    byte          hash[KEYID_SIZE];
24315
    Signer*       ca = NULL;
24316
    word32        idx = 0;
24317
    int           len;
24318
    word32        tbsCertIdx = 0;
24319
    word32        sigIndex   = 0;
24320
    word32        signatureOID = 0;
24321
    word32        oid = 0;
24322
    word32        issuerIdx = 0;
24323
    word32        issuerSz  = 0;
24324
#ifndef NO_SKID
24325
    int           extLen = 0;
24326
    word32        extIdx = 0;
24327
    word32        extEndIdx = 0;
24328
    int           extAuthKeyIdSet = 0;
24329
#endif
24330
    int           ret = 0;
24331
    word32        localIdx;
24332
    byte          tag;
24333
    const byte*   sigParams = NULL;
24334
    word32        sigParamsSz = 0;
24335
24336
24337
    if (cert == NULL) {
24338
        return BAD_FUNC_ARG;
24339
    }
24340
24341
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
24342
    sigCtx = (SignatureCtx*)XMALLOC(sizeof(*sigCtx), heap, DYNAMIC_TYPE_SIGNATURE);
24343
    if (sigCtx == NULL)
24344
        return MEMORY_E;
24345
#endif
24346
24347
    InitSignatureCtx(sigCtx, heap, INVALID_DEVID);
24348
24349
    /* Certificate SEQUENCE */
24350
    if (GetSequence(cert, &idx, &len, certSz) < 0)
24351
        ret = ASN_PARSE_E;
24352
    if (ret == 0) {
24353
        tbsCertIdx = idx;
24354
24355
        /* TBSCertificate SEQUENCE */
24356
        if (GetSequence(cert, &idx, &len, certSz) < 0)
24357
            ret = ASN_PARSE_E;
24358
    }
24359
    if (ret == 0) {
24360
        sigIndex = len + idx;
24361
24362
        if ((idx + 1) > certSz)
24363
            ret = BUFFER_E;
24364
    }
24365
    if (ret == 0) {
24366
        /* version - optional */
24367
        localIdx = idx;
24368
        if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) {
24369
            if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
24370
                idx++;
24371
                if (GetLength(cert, &idx, &len, certSz) < 0)
24372
                    ret = ASN_PARSE_E;
24373
                idx += len;
24374
            }
24375
        }
24376
    }
24377
24378
    if (ret == 0) {
24379
        /* serialNumber */
24380
        if (GetASNHeader(cert, ASN_INTEGER, &idx, &len, certSz) < 0)
24381
            ret = ASN_PARSE_E;
24382
    }
24383
    if (ret == 0) {
24384
        idx += len;
24385
24386
        /* signature */
24387
        if (!req) {
24388
            if (GetAlgoId(cert, &idx, &signatureOID, oidSigType, certSz) < 0)
24389
                ret = ASN_PARSE_E;
24390
        #ifdef WC_RSA_PSS
24391
            else if (signatureOID == CTC_RSASSAPSS) {
24392
                int start = idx;
24393
                sigParams = cert + idx;
24394
                if (GetSequence(cert, &idx, &len, certSz) < 0)
24395
                    ret = ASN_PARSE_E;
24396
                if (ret == 0) {
24397
                    idx += len;
24398
                    sigParamsSz = idx - start;
24399
                }
24400
            }
24401
        #endif
24402
        }
24403
    }
24404
24405
    if (ret == 0) {
24406
        issuerIdx = idx;
24407
        /* issuer for cert or subject for csr */
24408
        if (GetSequence(cert, &idx, &len, certSz) < 0)
24409
            ret = ASN_PARSE_E;
24410
    }
24411
    if (ret == 0) {
24412
        issuerSz = len + idx - issuerIdx;
24413
    }
24414
#ifndef NO_SKID
24415
    if (!req && ret == 0) {
24416
        idx += len;
24417
24418
        /* validity */
24419
        if (GetSequence(cert, &idx, &len, certSz) < 0)
24420
            ret = ASN_PARSE_E;
24421
    }
24422
    if (!req && ret == 0) {
24423
        idx += len;
24424
24425
        /* subject */
24426
        if (GetSequence(cert, &idx, &len, certSz) < 0)
24427
            ret = ASN_PARSE_E;
24428
    }
24429
    if (ret == 0) {
24430
        idx += len;
24431
24432
        /* subjectPublicKeyInfo */
24433
        if (GetSequence(cert, &idx, &len, certSz) < 0)
24434
            ret = ASN_PARSE_E;
24435
    }
24436
    if (req && ret == 0) {
24437
        idx += len;
24438
24439
        /* attributes */
24440
        if (GetASNHeader_ex(cert,
24441
                ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED, &idx,
24442
                &len, certSz, 1) < 0)
24443
            ret = ASN_PARSE_E;
24444
    }
24445
    if (!req) {
24446
        if (ret == 0) {
24447
            idx += len;
24448
24449
            if ((idx + 1) > certSz)
24450
                ret = BUFFER_E;
24451
        }
24452
        if (ret == 0) {
24453
            /* issuerUniqueID - optional */
24454
            localIdx = idx;
24455
            if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) {
24456
                if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) {
24457
                    idx++;
24458
                    if (GetLength(cert, &idx, &len, certSz) < 0)
24459
                        ret = ASN_PARSE_E;
24460
                    idx += len;
24461
                }
24462
            }
24463
        }
24464
        if (ret == 0) {
24465
            if ((idx + 1) > certSz)
24466
                ret = BUFFER_E;
24467
        }
24468
        if (ret == 0) {
24469
            /* subjectUniqueID - optional */
24470
            localIdx = idx;
24471
            if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) {
24472
                if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)) {
24473
                    idx++;
24474
                    if (GetLength(cert, &idx, &len, certSz) < 0)
24475
                        ret = ASN_PARSE_E;
24476
                    idx += len;
24477
                }
24478
            }
24479
        }
24480
24481
        if (ret == 0) {
24482
            if ((idx + 1) > certSz)
24483
                ret = BUFFER_E;
24484
        }
24485
        /* extensions - optional */
24486
        localIdx = idx;
24487
        if (ret == 0 && GetASNTag(cert, &localIdx, &tag, certSz) == 0 &&
24488
                tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 3)) {
24489
            idx++;
24490
            if (GetLength(cert, &idx, &extLen, certSz) < 0)
24491
                ret = ASN_PARSE_E;
24492
            if (ret == 0) {
24493
                if (GetSequence(cert, &idx, &extLen, certSz) < 0)
24494
                    ret = ASN_PARSE_E;
24495
            }
24496
            if (ret == 0) {
24497
                extEndIdx = idx + extLen;
24498
24499
                /* Check each extension for the ones we want. */
24500
                while (ret == 0 && idx < extEndIdx) {
24501
                    if (GetSequence(cert, &idx, &len, certSz) < 0)
24502
                        ret = ASN_PARSE_E;
24503
                    if (ret == 0) {
24504
                        extIdx = idx;
24505
                        if (GetObjectId(cert, &extIdx, &oid, oidCertExtType,
24506
                                                                  certSz) < 0) {
24507
                            ret = ASN_PARSE_E;
24508
                        }
24509
24510
                        if (ret == 0) {
24511
                            if ((extIdx + 1) > certSz)
24512
                                ret = BUFFER_E;
24513
                        }
24514
                    }
24515
24516
                    if (ret == 0) {
24517
                        localIdx = extIdx;
24518
                        if (GetASNTag(cert, &localIdx, &tag, certSz) == 0 &&
24519
                                tag == ASN_BOOLEAN) {
24520
                            if (GetBoolean(cert, &extIdx, certSz) < 0)
24521
                                ret = ASN_PARSE_E;
24522
                        }
24523
                    }
24524
                    if (ret == 0) {
24525
                        if (GetOctetString(cert, &extIdx, &extLen, certSz) < 0)
24526
                            ret = ASN_PARSE_E;
24527
                    }
24528
24529
                    if (ret == 0) {
24530
                        switch (oid) {
24531
                        case AUTH_KEY_OID:
24532
                            if (GetSequence(cert, &extIdx, &extLen, certSz) < 0)
24533
                                ret = ASN_PARSE_E;
24534
24535
                            if (ret == 0 && (extIdx + 1) >= certSz)
24536
                                ret = BUFFER_E;
24537
24538
                            if (ret == 0 &&
24539
                                    GetASNTag(cert, &extIdx, &tag, certSz) == 0 &&
24540
                                    tag == (ASN_CONTEXT_SPECIFIC | 0)) {
24541
                                if (GetLength(cert, &extIdx, &extLen, certSz) <= 0)
24542
                                    ret = ASN_PARSE_E;
24543
                                if (ret == 0) {
24544
                                    extAuthKeyIdSet = 1;
24545
                                    /* Get the hash or hash of the hash if wrong
24546
                                     * size. */
24547
                                    ret = GetHashId(cert + extIdx, extLen,
24548
                                        hash, HashIdAlg(signatureOID));
24549
                                }
24550
                            }
24551
                            break;
24552
24553
                        default:
24554
                            break;
24555
                        }
24556
                    }
24557
                    idx += len;
24558
                }
24559
            }
24560
        }
24561
    }
24562
    else if (ret == 0) {
24563
        idx += len;
24564
    }
24565
24566
    if (ret == 0 && pubKey == NULL) {
24567
        if (extAuthKeyIdSet)
24568
            ca = GetCA(cm, hash);
24569
        if (ca == NULL) {
24570
            ret = CalcHashId_ex(cert + issuerIdx, issuerSz, hash,
24571
                HashIdAlg(signatureOID));
24572
            if (ret == 0)
24573
                ca = GetCAByName(cm, hash);
24574
        }
24575
    }
24576
#else
24577
    if (ret == 0 && pubKey == NULL) {
24578
        ret = CalcHashId_ex(cert + issuerIdx, issuerSz, hash,
24579
            HashIdAlg(signatureOID));
24580
        if (ret == 0)
24581
            ca = GetCA(cm, hash);
24582
    }
24583
#endif /* !NO_SKID */
24584
    if (ca == NULL && pubKey == NULL)
24585
        ret = ASN_NO_SIGNER_E;
24586
24587
    if (ret == 0) {
24588
        idx = sigIndex;
24589
        /* signatureAlgorithm */
24590
        if (GetAlgoId(cert, &idx, &oid, oidSigType, certSz) < 0)
24591
            ret = ASN_PARSE_E;
24592
    #ifdef WC_RSA_PSS
24593
        else if (signatureOID == CTC_RSASSAPSS) {
24594
            word32 sz = idx;
24595
            const byte* params = cert + idx;
24596
            if (GetSequence(cert, &idx, &len, certSz) < 0)
24597
                ret = ASN_PARSE_E;
24598
            if (ret == 0) {
24599
                idx += len;
24600
                sz = idx - sz;
24601
24602
                if (req) {
24603
                    if ((sz != sigParamsSz) ||
24604
                                        (XMEMCMP(sigParams, params, sz) != 0)) {
24605
                        ret = ASN_PARSE_E;
24606
                    }
24607
                }
24608
                else {
24609
                    sigParams = params;
24610
                    sigParamsSz = sz;
24611
                }
24612
            }
24613
        }
24614
    #endif
24615
        /* In CSR signature data is not present in body */
24616
        if (req)
24617
            signatureOID = oid;
24618
    }
24619
    if (ret == 0) {
24620
        if (oid != signatureOID)
24621
            ret = ASN_SIG_OID_E;
24622
    }
24623
    if (ret == 0) {
24624
        /* signatureValue */
24625
        if (CheckBitString(cert, &idx, &len, certSz, 1, NULL) < 0)
24626
            ret = ASN_PARSE_E;
24627
    }
24628
24629
    if (ret == 0) {
24630
        if (pubKey != NULL) {
24631
            ret = ConfirmSignature(sigCtx, cert + tbsCertIdx,
24632
                sigIndex - tbsCertIdx, pubKey, pubKeySz, pubKeyOID,
24633
                cert + idx, len, signatureOID, sigParams, sigParamsSz, NULL);
24634
        }
24635
        else {
24636
            ret = ConfirmSignature(sigCtx, cert + tbsCertIdx,
24637
                sigIndex - tbsCertIdx, ca->publicKey, ca->pubKeySize,
24638
                ca->keyOID, cert + idx, len, signatureOID, sigParams,
24639
                sigParamsSz, NULL);
24640
        }
24641
        if (ret != 0) {
24642
            WOLFSSL_ERROR_VERBOSE(ret);
24643
            WOLFSSL_MSG("Confirm signature failed");
24644
        }
24645
    }
24646
24647
    FreeSignatureCtx(sigCtx);
24648
#ifdef WOLFSSL_SMALL_STACK
24649
    XFREE(sigCtx, heap, DYNAMIC_TYPE_SIGNATURE);
24650
#endif
24651
    return ret;
24652
#else /* WOLFSSL_ASN_TEMPLATE */
24653
    /* X509 ASN.1 template longer than Certificate Request template. */
24654
    DECL_ASNGETDATA(dataASN, x509CertASN_Length);
24655
#ifndef WOLFSSL_SMALL_STACK
24656
    SignatureCtx  sigCtx[1];
24657
#else
24658
    SignatureCtx* sigCtx = NULL;
24659
#endif
24660
    byte hash[KEYID_SIZE];
24661
    Signer* ca = NULL;
24662
    int ret = 0;
24663
    word32 idx = 0;
24664
#ifndef NO_SKID
24665
    int extAuthKeyIdSet = 0;
24666
#endif
24667
    const byte* tbs = NULL;
24668
    word32 tbsSz = 0;
24669
#ifdef WC_RSA_PSS
24670
    const byte* tbsParams = NULL;
24671
    word32 tbsParamsSz = 0;
24672
#endif
24673
    const byte* sig = NULL;
24674
    word32 sigSz = 0;
24675
    word32 sigOID = 0;
24676
    const byte* sigParams = NULL;
24677
    word32 sigParamsSz = 0;
24678
    const byte* caName = NULL;
24679
    word32 caNameLen = 0;
24680
#ifndef NO_SKID
24681
    const byte* akiData = NULL;
24682
    word32 akiLen = 0;
24683
#endif
24684
24685
    (void)req;
24686
    (void)heap;
24687
24688
    if (cert == NULL) {
24689
        ret = BAD_FUNC_ARG;
24690
    }
24691
24692
    ALLOC_ASNGETDATA(dataASN, x509CertASN_Length, ret, heap);
24693
24694
    if ((ret == 0) && (!req)) {
24695
        /* Clear dynamic data for certificate items. */
24696
        XMEMSET(dataASN, 0, sizeof(ASNGetData) * x509CertASN_Length);
24697
        /* Set OID types expected for signature and public key. */
24698
        GetASN_OID(&dataASN[X509CERTASN_IDX_TBS_ALGOID_OID], oidSigType);
24699
        GetASN_OID(&dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_OID],
24700
                oidKeyType);
24701
        GetASN_OID(&dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_CURVEID],
24702
                oidCurveType);
24703
        GetASN_OID(&dataASN[X509CERTASN_IDX_SIGALGO_OID], oidSigType);
24704
        /* Parse certificate. */
24705
        ret = GetASN_Items(x509CertASN, dataASN, x509CertASN_Length, 1, cert,
24706
                           &idx, certSz);
24707
24708
        /* Check signature OIDs match. */
24709
        if ((ret == 0) && dataASN[X509CERTASN_IDX_TBS_ALGOID_OID].data.oid.sum
24710
                != dataASN[X509CERTASN_IDX_SIGALGO_OID].data.oid.sum) {
24711
            ret = ASN_SIG_OID_E;
24712
        }
24713
        /* Store the data for verification in the certificate. */
24714
        if (ret == 0) {
24715
            tbs = GetASNItem_Addr(dataASN[X509CERTASN_IDX_TBS_SEQ], cert);
24716
            tbsSz = GetASNItem_Length(dataASN[X509CERTASN_IDX_TBS_SEQ], cert);
24717
            caName = GetASNItem_Addr(dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ],
24718
                    cert);
24719
            caNameLen = GetASNItem_Length(dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ],
24720
                    cert);
24721
            sigOID = dataASN[X509CERTASN_IDX_SIGALGO_OID].data.oid.sum;
24722
        #ifdef WC_RSA_PSS
24723
            if (dataASN[X509CERTASN_IDX_TBS_ALGOID_PARAMS].tag != 0) {
24724
                tbsParams =
24725
                    GetASNItem_Addr(dataASN[X509CERTASN_IDX_TBS_ALGOID_PARAMS],
24726
                        cert);
24727
                tbsParamsSz =
24728
                    GetASNItem_Length(dataASN[X509CERTASN_IDX_TBS_ALGOID_PARAMS],
24729
                        cert);
24730
            }
24731
            if (dataASN[X509CERTASN_IDX_SIGALGO_PARAMS].tag != 0) {
24732
                sigParams =
24733
                    GetASNItem_Addr(dataASN[X509CERTASN_IDX_SIGALGO_PARAMS],
24734
                        cert);
24735
                sigParamsSz =
24736
                    GetASNItem_Length(dataASN[X509CERTASN_IDX_SIGALGO_PARAMS],
24737
                        cert);
24738
            }
24739
        #endif
24740
            GetASN_GetConstRef(&dataASN[X509CERTASN_IDX_SIGNATURE], &sig, &sigSz);
24741
        #ifdef WC_RSA_PSS
24742
            if (tbsParamsSz != sigParamsSz) {
24743
                ret = ASN_PARSE_E;
24744
            }
24745
            else if ((tbsParamsSz > 0) && (sigOID != CTC_RSASSAPSS)) {
24746
                ret = ASN_PARSE_E;
24747
            }
24748
            else if ((tbsParamsSz > 0) &&
24749
                     (XMEMCMP(tbsParams, sigParams, tbsParamsSz) != 0)) {
24750
                ret = ASN_PARSE_E;
24751
            }
24752
        #endif
24753
        }
24754
    }
24755
    else if (ret == 0) {
24756
#ifndef WOLFSSL_CERT_REQ
24757
        ret = NOT_COMPILED_IN;
24758
#else
24759
        /* Clear dynamic data for certificate request items. */
24760
        XMEMSET(dataASN, 0, sizeof(ASNGetData) * certReqASN_Length);
24761
        /* Set OID types expected for signature and public key. */
24762
        GetASN_OID(&dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_OID],
24763
                oidKeyType);
24764
        GetASN_OID(&dataASN[CERTREQASN_IDX_INFO_SPUBKEYINFO_ALGOID_CURVEID],
24765
                oidCurveType);
24766
        GetASN_OID(&dataASN[CERTREQASN_IDX_INFO_SIGALGO_OID], oidSigType);
24767
        /* Parse certificate request. */
24768
        ret = GetASN_Items(certReqASN, dataASN, certReqASN_Length, 1, cert,
24769
                           &idx, certSz);
24770
        if (ret == 0) {
24771
            /* Store the data for verification in the certificate. */
24772
            tbs = GetASNItem_Addr(dataASN[CERTREQASN_IDX_INFO_SEQ], cert);
24773
            tbsSz = GetASNItem_Length(dataASN[CERTREQASN_IDX_INFO_SEQ], cert);
24774
            caName = GetASNItem_Addr(
24775
                    dataASN[CERTREQASN_IDX_INFO_SUBJ_SEQ], cert);
24776
            caNameLen = GetASNItem_Length(
24777
                    dataASN[CERTREQASN_IDX_INFO_SUBJ_SEQ], cert);
24778
            sigOID = dataASN[CERTREQASN_IDX_INFO_SIGALGO_OID].data.oid.sum;
24779
        #ifdef WC_RSA_PSS
24780
            sigParams = GetASNItem_Addr(dataASN[X509CERTASN_IDX_SIGALGO_PARAMS],
24781
                cert);
24782
            sigParamsSz =
24783
                GetASNItem_Length(dataASN[X509CERTASN_IDX_SIGALGO_PARAMS],
24784
                    cert);
24785
        #endif
24786
            GetASN_GetConstRef(&dataASN[CERTREQASN_IDX_INFO_SIGNATURE], &sig,
24787
                    &sigSz);
24788
        }
24789
#endif
24790
    }
24791
24792
#ifndef NO_SKID
24793
    if ((ret == 0) && (pubKey == NULL) && !req) {
24794
        akiData = dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].data.ref.data;
24795
        akiLen = dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].data.ref.length;
24796
    }
24797
#endif
24798
24799
    FREE_ASNGETDATA(dataASN, heap);
24800
24801
    /* If no public passed, then find the CA. */
24802
    if ((ret == 0) && (pubKey == NULL)) {
24803
#ifndef NO_SKID
24804
        /* Find the AKI extension in list of extensions and get hash. */
24805
        if ((!req) && (akiData != NULL)) {
24806
            /* TODO: test case */
24807
            ret = GetAKIHash(akiData, akiLen, sigOID, hash, &extAuthKeyIdSet,
24808
                heap);
24809
        }
24810
24811
        /* Get the CA by hash one was found. */
24812
        if (extAuthKeyIdSet) {
24813
            ca = GetCA(cm, hash);
24814
        }
24815
        if (ca == NULL)
24816
#endif
24817
        {
24818
            /* Try hash of issuer name. */
24819
            ret = CalcHashId_ex(caName, caNameLen, hash, HashIdAlg(sigOID));
24820
            if (ret == 0) {
24821
                ca = GetCAByName(cm, hash);
24822
            }
24823
        }
24824
24825
        if (ca != NULL) {
24826
            /* Extract public key information. */
24827
            pubKey = ca->publicKey;
24828
            pubKeySz = ca->pubKeySize;
24829
            pubKeyOID = (int)ca->keyOID;
24830
        }
24831
        else {
24832
            /* No public key to verify with. */
24833
            ret = ASN_NO_SIGNER_E;
24834
        }
24835
    }
24836
24837
    if (ret == 0) {
24838
    #ifdef WOLFSSL_SMALL_STACK
24839
        sigCtx = (SignatureCtx*)XMALLOC(sizeof(*sigCtx), heap,
24840
            DYNAMIC_TYPE_SIGNATURE);
24841
        if (sigCtx == NULL) {
24842
            ret = MEMORY_E;
24843
        }
24844
        if (ret == 0)
24845
    #endif
24846
        {
24847
            InitSignatureCtx(sigCtx, heap, INVALID_DEVID);
24848
24849
            /* Check signature. */
24850
            ret = ConfirmSignature(sigCtx, tbs, tbsSz, pubKey, pubKeySz,
24851
                (word32)pubKeyOID, sig, sigSz, sigOID, sigParams, sigParamsSz,
24852
                NULL);
24853
            if (ret != 0) {
24854
                WOLFSSL_MSG("Confirm signature failed");
24855
            }
24856
24857
            FreeSignatureCtx(sigCtx);
24858
        #ifdef WOLFSSL_SMALL_STACK
24859
            XFREE(sigCtx, heap, DYNAMIC_TYPE_SIGNATURE);
24860
        #endif
24861
        }
24862
    }
24863
24864
    return ret;
24865
#endif /* WOLFSSL_ASN_TEMPLATE */
24866
}
24867
24868
/* Call CheckCertSignature_ex using a public key buffer for verification */
24869
int CheckCertSignaturePubKey(const byte* cert, word32 certSz, void* heap,
24870
        const byte* pubKey, word32 pubKeySz, int pubKeyOID)
24871
{
24872
    return CheckCertSignature_ex(cert, certSz, heap, NULL,
24873
            pubKey, pubKeySz, pubKeyOID, 0);
24874
}
24875
24876
/* Call CheckCertSignature_ex using a public key and oid */
24877
int wc_CheckCertSigPubKey(const byte* cert, word32 certSz, void* heap,
24878
        const byte* pubKey, word32 pubKeySz, int pubKeyOID)
24879
{
24880
        return CheckCertSignaturePubKey(cert, certSz, heap, pubKey, pubKeySz,
24881
                                        pubKeyOID);
24882
}
24883
24884
#ifdef WOLFSSL_CERT_REQ
24885
int CheckCSRSignaturePubKey(const byte* cert, word32 certSz, void* heap,
24886
        const byte* pubKey, word32 pubKeySz, int pubKeyOID)
24887
{
24888
    return CheckCertSignature_ex(cert, certSz, heap, NULL,
24889
            pubKey, pubKeySz, pubKeyOID, 1);
24890
}
24891
#endif /* WOLFSSL_CERT_REQ */
24892
24893
/* Call CheckCertSignature_ex using a certificate manager (cm) */
24894
int wc_CheckCertSignature(const byte* cert, word32 certSz, void* heap, void* cm)
24895
{
24896
    return CheckCertSignature_ex(cert, certSz, heap, cm, NULL, 0, 0, 0);
24897
}
24898
#endif /* WOLFSSL_SMALL_CERT_VERIFY || OPENSSL_EXTRA */
24899
24900
#if (defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) || \
24901
    (defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)))
24902
/* ASN.1 DER decode instruction. */
24903
typedef struct DecodeInstr {
24904
    /* Tag expected. */
24905
    byte tag;
24906
    /* Operation to perform: step in or go over */
24907
    WC_BITFIELD op:1;
24908
    /* ASN.1 item is optional. */
24909
    WC_BITFIELD optional:1;
24910
} DecodeInstr;
24911
24912
/* Step into ASN.1 item. */
24913
#define DECODE_INSTR_IN    0
24914
/* Step over ASN.1 item. */
24915
#define DECODE_INSTR_OVER  1
24916
24917
/* Get the public key data from the DER encoded X.509 certificate.
24918
 *
24919
 * Assumes data has previously been parsed for complete validity.
24920
 *
24921
 * @param [in]  cert      DER encoded X.509 certificate data.
24922
 * @param [in]  certSz    Length of DER encoding.
24923
 * @param [out] pubKey    Public key data. (From the BIT_STRING.)
24924
 * @param [out] pubKeySz  Length of public key data in bytes.
24925
 * @return  0 on success.
24926
 * @return  BAD_FUNC_ARG when cert, pubKey or pubKeySz is NULL.
24927
 * @return  ASN_PARSE_E when certificate encoding is invalid.
24928
 */
24929
int wc_CertGetPubKey(const byte* cert, word32 certSz,
24930
    const unsigned char** pubKey, word32* pubKeySz)
24931
{
24932
    int ret = 0;
24933
    int l = 0;
24934
    word32 o = 0;
24935
    int i;
24936
    static DecodeInstr ops[] = {
24937
        /* Outer SEQ */
24938
        { ASN_SEQUENCE | ASN_CONSTRUCTED, DECODE_INSTR_IN  , 0 },
24939
        /* TBSCertificate: SEQ */
24940
        { ASN_SEQUENCE | ASN_CONSTRUCTED, DECODE_INSTR_IN  , 0 },
24941
        /* Version: [0] */
24942
        { ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_X509_CERT_VERSION,
24943
          DECODE_INSTR_OVER, 1 },
24944
        /* CertificateSerialNumber: INT  */
24945
        { ASN_INTEGER,                    DECODE_INSTR_OVER, 0 },
24946
        /* AlgorithmIdentifier: SEQ */
24947
        { ASN_SEQUENCE | ASN_CONSTRUCTED, DECODE_INSTR_OVER, 0 },
24948
        /* issuer: SEQ */
24949
        { ASN_SEQUENCE | ASN_CONSTRUCTED, DECODE_INSTR_OVER, 0 },
24950
        /* Validity: SEQ */
24951
        { ASN_SEQUENCE | ASN_CONSTRUCTED, DECODE_INSTR_OVER, 0 },
24952
        /* subject: SEQ */
24953
        { ASN_SEQUENCE | ASN_CONSTRUCTED, DECODE_INSTR_OVER, 0 },
24954
        /* subjectPublicKeyInfo SEQ */
24955
        { ASN_SEQUENCE | ASN_CONSTRUCTED, DECODE_INSTR_IN  , 0 },
24956
        /* AlgorithmIdentifier: SEQ */
24957
        { ASN_SEQUENCE | ASN_CONSTRUCTED, DECODE_INSTR_OVER, 0 },
24958
        /* PublicKey: BIT_STRING  */
24959
        { ASN_BIT_STRING,                 DECODE_INSTR_IN  , 0 },
24960
    };
24961
24962
    /* Validate parameters. */
24963
    if ((cert == NULL) || (pubKey == NULL) || (pubKeySz == NULL)) {
24964
        ret = BAD_FUNC_ARG;
24965
    }
24966
24967
    /* Process each instruction to take us to public key data. */
24968
    for (i = 0; (ret == 0) && (i < (int)(sizeof(ops) / sizeof(*ops))); i++) {
24969
        DecodeInstr op = ops[i];
24970
24971
        /* Check the current ASN.1 item has the expected tag. */
24972
        if (cert[o] != op.tag) {
24973
            /* If not optional then error, otherwise skip op. */
24974
            if (!op.optional) {
24975
                ret = ASN_PARSE_E;
24976
            }
24977
        }
24978
        else {
24979
            /* Move past tag. */
24980
            o++;
24981
            /* Get the length of ASN.1 item and move past length encoding. */
24982
            if (GetLength(cert, &o, &l, certSz) < 0) {
24983
                ret = ASN_PARSE_E;
24984
            }
24985
            /* Skip data if required. */
24986
            else if (op.op == DECODE_INSTR_OVER) {
24987
                o += (word32)l;
24988
            }
24989
        }
24990
    }
24991
24992
    if (ret == 0) {
24993
        /* Return the public key data and length.
24994
         * Skip first byte of BIT_STRING data: unused bits. */
24995
        *pubKey = cert + o + 1;
24996
        *pubKeySz = (word32)(l - 1);
24997
    }
24998
24999
    return ret;
25000
}
25001
#endif
25002
25003
/*
25004
 * @brief Export the SubjectPublicKeyInfo from an X.509 certificate
25005
 *
25006
 * This function extracts the SubjectPublicKeyInfo (SPKI) section from an X.509
25007
 * certificate in DER format. The SPKI contains the public key algorithm and
25008
 * the public key itself.
25009
 *
25010
 * @param certDer      [in]  Pointer to the DER encoded certificate
25011
 * @param certSz       [in]  Size of the DER encoded certificate
25012
 * @param pubKeyDer    [out] Buffer to hold the extracted SPKI (can be NULL to
25013
 *                           get size)
25014
 * @param pubKeyDerSz  [in,out] On input, size of pubKeyDer buffer
25015
 *                              On output, actual size of the SPKI
25016
 *
25017
 * @return 0 on success, negative on error
25018
 * @return BAD_FUNC_ARG if certDer is NULL, certSz is 0, or pubKeyDerSz is NULL
25019
 * @return BUFFER_E if the provided buffer is too small
25020
 */
25021
WOLFSSL_API int wc_GetSubjectPubKeyInfoDerFromCert(const byte* certDer,
25022
                                                   word32 certDerSz,
25023
                                                   byte* pubKeyDer,
25024
                                                   word32* pubKeyDerSz)
25025
0
{
25026
#ifdef WOLFSSL_SMALL_STACK
25027
    DecodedCert* cert;
25028
#else
25029
0
    DecodedCert cert[1];
25030
0
#endif
25031
0
    int         ret;
25032
0
    word32      startIdx;
25033
0
    word32      idx;
25034
0
    word32      length;
25035
0
    int         badDate;
25036
25037
0
    if (certDer == NULL || certDerSz == 0 || pubKeyDerSz == NULL) {
25038
0
        return BAD_FUNC_ARG;
25039
0
    }
25040
25041
#ifdef WOLFSSL_SMALL_STACK
25042
    cert = (DecodedCert*)XMALLOC(sizeof(*cert), NULL, DYNAMIC_TYPE_TMP_BUFFER);
25043
    if (cert == NULL)
25044
        return MEMORY_E;
25045
#endif
25046
25047
0
    length = 0;
25048
0
    badDate = 0;
25049
25050
0
    wc_InitDecodedCert(cert, certDer, certDerSz, NULL);
25051
25052
    /* Parse up to the SubjectPublicKeyInfo */
25053
0
    ret = wc_GetPubX509(cert, 0, &badDate);
25054
0
    if (ret >= 0) {
25055
        /* Save the starting index of SubjectPublicKeyInfo */
25056
0
        startIdx = cert->srcIdx;
25057
25058
        /* Get the length of the SubjectPublicKeyInfo sequence */
25059
0
        idx = startIdx;
25060
0
        ret = GetSequence(certDer, &idx, (int*)&length, certDerSz);
25061
0
        if (ret >= 0) {
25062
            /* Calculate total length including sequence header */
25063
0
            length += (idx - startIdx);
25064
25065
            /* Copy the SubjectPublicKeyInfo if buffer provided */
25066
0
            if (pubKeyDer != NULL) {
25067
0
                if (*pubKeyDerSz < (word32)length) {
25068
0
                    ret = BUFFER_E;
25069
0
                }
25070
0
                else {
25071
0
                    XMEMCPY(pubKeyDer, &certDer[startIdx], length);
25072
0
                }
25073
0
            }
25074
0
        }
25075
0
    }
25076
25077
0
    if (ret >= 0) {
25078
0
        ret = 0;
25079
0
    }
25080
25081
0
    *pubKeyDerSz = length;
25082
0
    wc_FreeDecodedCert(cert);
25083
25084
#ifdef WOLFSSL_SMALL_STACK
25085
    XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
25086
#endif
25087
25088
0
    return ret;
25089
0
}
25090
25091
25092
#ifdef HAVE_OCSP
25093
Signer* findSignerByKeyHash(Signer *list, byte *hash)
25094
{
25095
    Signer *s;
25096
    for (s = list; s != NULL; s = s->next) {
25097
        if (XMEMCMP(s->subjectKeyHash, hash, KEYID_SIZE) == 0) {
25098
            return s;
25099
        }
25100
    }
25101
    return NULL;
25102
}
25103
#endif /* WOLFSSL_OCSP */
25104
25105
Signer* findSignerByName(Signer *list, byte *hash)
25106
0
{
25107
0
    Signer *s;
25108
0
    for (s = list; s != NULL; s = s->next) {
25109
0
        if (XMEMCMP(s->subjectNameHash, hash, SIGNER_DIGEST_SIZE) == 0) {
25110
0
            return s;
25111
0
        }
25112
0
    }
25113
0
    return NULL;
25114
0
}
25115
25116
int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm,
25117
                      Signer *extraCAList)
25118
0
{
25119
0
    int    ret = 0;
25120
#ifndef WOLFSSL_ASN_TEMPLATE
25121
    word32 confirmOID = 0;
25122
#ifdef WOLFSSL_CERT_REQ
25123
    int    len = 0;
25124
#endif
25125
#endif
25126
#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_FSPSM_TLS)
25127
    int    idx = 0;
25128
#endif
25129
0
    byte*  sce_tsip_encRsaKeyIdx;
25130
0
    (void)extraCAList;
25131
25132
0
    if (cert == NULL) {
25133
0
        return BAD_FUNC_ARG;
25134
0
    }
25135
25136
#ifdef WOLFSSL_CERT_REQ
25137
    if (type == CERTREQ_TYPE)
25138
        cert->isCSR = 1;
25139
#endif
25140
25141
0
    if (cert->sigCtx.state == SIG_STATE_BEGIN) {
25142
#ifndef WOLFSSL_ASN_TEMPLATE
25143
        cert->badDate = 0;
25144
        cert->criticalExt = 0;
25145
        if ((ret = DecodeToKey(cert, verify)) < 0) {
25146
            if (ret == WC_NO_ERR_TRACE(ASN_BEFORE_DATE_E) ||
25147
                ret == WC_NO_ERR_TRACE(ASN_AFTER_DATE_E)) {
25148
                cert->badDate = ret;
25149
                if ((verify == VERIFY_SKIP_DATE) || AsnSkipDateCheck)
25150
                    ret = 0;
25151
            }
25152
            else
25153
                return ret;
25154
        }
25155
25156
        WOLFSSL_MSG("Parsed Past Key");
25157
#if defined(HAVE_RPK)
25158
        if (cert->isRPK) {
25159
            return ret;
25160
        }
25161
#endif /* HAVE_RPK */
25162
25163
#ifdef WOLFSSL_CERT_REQ
25164
        /* Read attributes */
25165
        if (cert->isCSR) {
25166
            if (GetASNHeader_ex(cert->source,
25167
                    ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED, &cert->srcIdx,
25168
                    &len, cert->maxIdx, 1) < 0) {
25169
                WOLFSSL_MSG("GetASNHeader_ex error");
25170
                return ASN_PARSE_E;
25171
            }
25172
25173
            if (len) {
25174
                word32 attrMaxIdx = cert->srcIdx + (word32)len;
25175
                word32 oid;
25176
                byte   tag;
25177
25178
                if (attrMaxIdx > cert->maxIdx) {
25179
                    WOLFSSL_MSG("Attribute length greater than CSR length");
25180
                    return ASN_PARSE_E;
25181
                }
25182
25183
                while (cert->srcIdx < attrMaxIdx) {
25184
                    /* Attributes have the structure:
25185
                     * SEQ -> OID -> SET -> ATTRIBUTE */
25186
                    if (GetSequence(cert->source, &cert->srcIdx, &len,
25187
                            attrMaxIdx) < 0) {
25188
                        WOLFSSL_MSG("attr GetSequence error");
25189
                        return ASN_PARSE_E;
25190
                    }
25191
                    if (GetObjectId(cert->source, &cert->srcIdx, &oid,
25192
                            oidCsrAttrType, attrMaxIdx) < 0) {
25193
                        WOLFSSL_MSG("attr GetObjectId error");
25194
                        return ASN_PARSE_E;
25195
                    }
25196
                    if (GetSet(cert->source, &cert->srcIdx, &len,
25197
                            attrMaxIdx) < 0) {
25198
                        WOLFSSL_MSG("attr GetSet error");
25199
                        return ASN_PARSE_E;
25200
                    }
25201
                    switch (oid) {
25202
                    case PKCS9_CONTENT_TYPE_OID:
25203
                        if (GetHeader(cert->source, &tag,
25204
                                &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
25205
                            WOLFSSL_MSG("attr GetHeader error");
25206
                            return ASN_PARSE_E;
25207
                        }
25208
                        if (tag != ASN_PRINTABLE_STRING && tag != ASN_UTF8STRING &&
25209
                                tag != ASN_IA5_STRING) {
25210
                            WOLFSSL_MSG("Unsupported attribute value format");
25211
                            return ASN_PARSE_E;
25212
                        }
25213
                        cert->contentType = (char*)cert->source + cert->srcIdx;
25214
                        cert->contentTypeLen = len;
25215
                        cert->srcIdx += (word32)len;
25216
                        break;
25217
                    case CHALLENGE_PASSWORD_OID:
25218
                        if (GetHeader(cert->source, &tag,
25219
                                &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
25220
                            WOLFSSL_MSG("attr GetHeader error");
25221
                            return ASN_PARSE_E;
25222
                        }
25223
                        if (tag != ASN_PRINTABLE_STRING && tag != ASN_UTF8STRING &&
25224
                                tag != ASN_IA5_STRING) {
25225
                            WOLFSSL_MSG("Unsupported attribute value format");
25226
                            return ASN_PARSE_E;
25227
                        }
25228
                        cert->cPwd = (char*)cert->source + cert->srcIdx;
25229
                        cert->cPwdLen = len;
25230
                        cert->srcIdx += (word32)len;
25231
                        break;
25232
                    case SERIAL_NUMBER_OID:
25233
                        if (GetHeader(cert->source, &tag,
25234
                                &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
25235
                            WOLFSSL_MSG("attr GetHeader error");
25236
                            return ASN_PARSE_E;
25237
                        }
25238
                        if (tag != ASN_PRINTABLE_STRING && tag != ASN_UTF8STRING &&
25239
                                tag != ASN_IA5_STRING) {
25240
                            WOLFSSL_MSG("Unsupported attribute value format");
25241
                            return ASN_PARSE_E;
25242
                        }
25243
                        cert->sNum = (char*)cert->source + cert->srcIdx;
25244
                        cert->sNumLen = len;
25245
                        cert->srcIdx += (word32)len;
25246
                        if (cert->sNumLen <= EXTERNAL_SERIAL_SIZE) {
25247
                            XMEMCPY(cert->serial, cert->sNum,
25248
                                    (size_t)cert->sNumLen);
25249
                            cert->serialSz = cert->sNumLen;
25250
                        }
25251
                        break;
25252
                    case DNQUALIFIER_OID:
25253
                        if (GetHeader(cert->source, &tag,
25254
                                &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
25255
                            WOLFSSL_MSG("attr GetHeader error");
25256
                            return ASN_PARSE_E;
25257
                        }
25258
                        cert->dnQualifier = (char*)cert->source + cert->srcIdx;
25259
                        cert->dnQualifierLen = len;
25260
                        cert->srcIdx += (word32)len;
25261
                        break;
25262
                    case INITIALS_OID:
25263
                        if (GetHeader(cert->source, &tag,
25264
                                &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
25265
                            WOLFSSL_MSG("attr GetHeader error");
25266
                            return ASN_PARSE_E;
25267
                        }
25268
                        cert->initials = (char*)cert->source + cert->srcIdx;
25269
                        cert->initialsLen = len;
25270
                        cert->srcIdx += (word32)len;
25271
                        break;
25272
                    case SURNAME_OID:
25273
                        if (GetHeader(cert->source, &tag,
25274
                                &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
25275
                            WOLFSSL_MSG("attr GetHeader error");
25276
                            return ASN_PARSE_E;
25277
                        }
25278
                        cert->surname = (char*)cert->source + cert->srcIdx;
25279
                        cert->surnameLen = len;
25280
                        cert->srcIdx += (word32)len;
25281
                        break;
25282
                    case GIVEN_NAME_OID:
25283
                        if (GetHeader(cert->source, &tag,
25284
                                &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
25285
                            WOLFSSL_MSG("attr GetHeader error");
25286
                            return ASN_PARSE_E;
25287
                        }
25288
                        cert->givenName = (char*)cert->source + cert->srcIdx;
25289
                        cert->givenNameLen = len;
25290
                        cert->srcIdx += (word32)len;
25291
                        break;
25292
                    case UNSTRUCTURED_NAME_OID:
25293
                        if (GetHeader(cert->source, &tag,
25294
                                &cert->srcIdx, &len, attrMaxIdx, 1) < 0) {
25295
                            WOLFSSL_MSG("attr GetHeader error");
25296
                            return ASN_PARSE_E;
25297
                        }
25298
                        cert->unstructuredName =
25299
                            (char*)cert->source + cert->srcIdx;
25300
                        cert->unstructuredNameLen = len;
25301
                        cert->srcIdx += (word32)len;
25302
                        break;
25303
                    case EXTENSION_REQUEST_OID:
25304
                        /* save extensions */
25305
                        cert->extensions    = &cert->source[cert->srcIdx];
25306
                        cert->extensionsSz  = len;
25307
                        cert->extensionsIdx = cert->srcIdx; /* for potential later use */
25308
25309
                        if ((ret = DecodeCertExtensions(cert)) < 0) {
25310
                            if (ret == WC_NO_ERR_TRACE(ASN_CRIT_EXT_E)) {
25311
                                cert->criticalExt = ret;
25312
                            }
25313
                            else {
25314
                                return ret;
25315
                            }
25316
                        }
25317
                        cert->srcIdx += (word32)len;
25318
                        break;
25319
                    default:
25320
                        WOLFSSL_MSG("Unsupported attribute type");
25321
                        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
25322
                        return ASN_PARSE_E;
25323
                    }
25324
                }
25325
            }
25326
        }
25327
#endif
25328
25329
        if (cert->srcIdx < cert->sigIndex) {
25330
        #ifndef ALLOW_V1_EXTENSIONS
25331
            if (cert->version < 2) {
25332
                WOLFSSL_MSG("\tv1 and v2 certs not allowed extensions");
25333
                WOLFSSL_ERROR_VERBOSE(ASN_VERSION_E);
25334
                return ASN_VERSION_E;
25335
            }
25336
        #endif
25337
25338
            /* save extensions */
25339
            cert->extensions    = &cert->source[cert->srcIdx];
25340
            cert->extensionsSz  = (int)(cert->sigIndex - cert->srcIdx);
25341
            cert->extensionsIdx = cert->srcIdx;   /* for potential later use */
25342
25343
            if ((ret = DecodeCertExtensions(cert)) < 0) {
25344
                if (ret == WC_NO_ERR_TRACE(ASN_CRIT_EXT_E))
25345
                    cert->criticalExt = ret;
25346
                else
25347
                    return ret;
25348
            }
25349
25350
        #ifdef HAVE_OCSP
25351
            if (verify == VERIFY_OCSP_CERT) {
25352
                /* trust for the lifetime of the responder's cert*/
25353
                if (cert->ocspNoCheckSet)
25354
                    verify = VERIFY;
25355
                else
25356
                    verify = VERIFY_OCSP;
25357
            }
25358
        #endif
25359
            /* advance past extensions */
25360
            cert->srcIdx = cert->sigIndex;
25361
        }
25362
25363
        if ((ret = GetSigAlg(cert,
25364
#ifdef WOLFSSL_CERT_REQ
25365
                !cert->isCSR ? &confirmOID : &cert->signatureOID,
25366
#else
25367
                &confirmOID,
25368
#endif
25369
                cert->maxIdx)) < 0) {
25370
            return ret;
25371
        }
25372
25373
        if ((ret = GetSignature(cert)) < 0) {
25374
            return ret;
25375
        }
25376
25377
        if (confirmOID != cert->signatureOID
25378
#ifdef WOLFSSL_CERT_REQ
25379
                && !cert->isCSR
25380
#endif
25381
                ) {
25382
            WOLFSSL_ERROR_VERBOSE(ASN_SIG_OID_E);
25383
            return ASN_SIG_OID_E;
25384
        }
25385
#else
25386
#ifdef WOLFSSL_CERT_REQ
25387
        if (cert->isCSR) {
25388
            ret = DecodeCertReq(cert, &cert->criticalExt);
25389
            if (ret < 0) {
25390
                return ret;
25391
            }
25392
        }
25393
        else
25394
#endif
25395
0
        {
25396
0
            ret = DecodeCert(cert, verify, &cert->criticalExt);
25397
0
            if (ret == WC_NO_ERR_TRACE(ASN_BEFORE_DATE_E) ||
25398
0
                ret == WC_NO_ERR_TRACE(ASN_AFTER_DATE_E)) {
25399
0
                cert->badDate = ret;
25400
0
                if ((verify == VERIFY_SKIP_DATE) || AsnSkipDateCheck)
25401
0
                    ret = 0;
25402
0
            }
25403
0
            else if (ret < 0) {
25404
0
                WOLFSSL_ERROR_VERBOSE(ret);
25405
0
                return ret;
25406
0
            }
25407
#if defined(HAVE_RPK)
25408
            if (cert->isRPK) {
25409
                return ret;
25410
            }
25411
#endif /* HAVE_RPK */
25412
0
        }
25413
0
#endif
25414
25415
0
    #ifndef ALLOW_INVALID_CERTSIGN
25416
        /* https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.9
25417
         *   If the cA boolean is not asserted, then the keyCertSign bit in the
25418
         *   key usage extension MUST NOT be asserted. */
25419
0
        if (!cert->isCA && cert->extKeyUsageSet &&
25420
0
                (cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) != 0) {
25421
0
            WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E);
25422
0
            return KEYUSAGE_E;
25423
0
        }
25424
0
    #endif
25425
25426
0
    #ifndef NO_SKID
25427
0
        if (cert->extSubjKeyIdSet == 0 && cert->publicKey != NULL &&
25428
0
                                                         cert->pubKeySize > 0) {
25429
0
            if (cert->signatureOID == CTC_SM3wSM2) {
25430
                /* TODO: GmSSL creates IDs this way but whole public key info
25431
                 * block should be hashed. */
25432
0
                ret = CalcHashId_ex(cert->publicKey + cert->pubKeySize - 65, 65,
25433
0
                    cert->extSubjKeyId, HashIdAlg(cert->signatureOID));
25434
0
            }
25435
0
            else {
25436
0
                ret = CalcHashId_ex(cert->publicKey, cert->pubKeySize,
25437
0
                    cert->extSubjKeyId, HashIdAlg(cert->signatureOID));
25438
0
            }
25439
0
            if (ret != 0) {
25440
0
                WOLFSSL_ERROR_VERBOSE(ret);
25441
0
                return ret;
25442
0
            }
25443
0
        }
25444
0
    #endif /* !NO_SKID */
25445
25446
0
        if (!cert->selfSigned || (verify != NO_VERIFY && type != CA_TYPE &&
25447
0
                                                   type != TRUSTED_PEER_TYPE)) {
25448
0
            cert->ca = NULL;
25449
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
25450
        if (extraCAList != NULL) {
25451
            cert->ca = findSignerByName(extraCAList, cert->issuerHash);
25452
        }
25453
#endif
25454
0
    #ifndef NO_SKID
25455
0
            if (cert->ca == NULL && cert->extAuthKeyIdSet) {
25456
0
                cert->ca = GetCA(cm, cert->extAuthKeyId);
25457
        #ifdef WOLFSSL_AKID_NAME
25458
                if (cert->ca == NULL) {
25459
                    cert->ca = GetCAByAKID(cm, cert->extAuthKeyIdIssuer,
25460
                        cert->extAuthKeyIdIssuerSz, cert->extAuthKeyIdIssuerSN,
25461
                        cert->extAuthKeyIdIssuerSNSz);
25462
                }
25463
        #endif
25464
0
            }
25465
0
            if (cert->ca == NULL && cert->extSubjKeyIdSet
25466
0
                                 && verify != VERIFY_OCSP) {
25467
0
                cert->ca = GetCA(cm, cert->extSubjKeyId);
25468
0
            }
25469
0
            if (cert->ca != NULL && XMEMCMP(cert->issuerHash,
25470
0
                    cert->ca->subjectNameHash, KEYID_SIZE) != 0) {
25471
0
                cert->ca = NULL;
25472
0
            }
25473
0
            if (cert->ca == NULL) {
25474
0
                cert->ca = GetCAByName(cm, cert->issuerHash);
25475
                /* If AKID is available then this CA doesn't have the public
25476
                 * key required */
25477
0
                if (cert->ca && cert->extAuthKeyIdSet) {
25478
0
                    WOLFSSL_MSG("CA SKID doesn't match AKID");
25479
0
                    cert->ca = NULL;
25480
0
                }
25481
0
            }
25482
25483
            /* OCSP Only: alt lookup using subject and pub key w/o sig check */
25484
        #ifdef WOLFSSL_NO_TRUSTED_CERTS_VERIFY
25485
            if (cert->ca == NULL && verify == VERIFY_OCSP) {
25486
                cert->ca = GetCABySubjectAndPubKey(cert, cm);
25487
                if (cert->ca) {
25488
                    ret = 0; /* success */
25489
                    goto exit_pcr;
25490
                }
25491
            }
25492
        #endif /* WOLFSSL_NO_TRUSTED_CERTS_VERIFY */
25493
    #else
25494
            cert->ca = GetCA(cm, cert->issuerHash);
25495
    #endif /* !NO_SKID */
25496
25497
0
            if (cert->ca) {
25498
0
                WOLFSSL_MSG("CA found");
25499
0
            }
25500
0
        }
25501
25502
        /* Set to WOLFSSL_MAX_PATH_LEN by default in InitDecodedCert_ex */
25503
0
        if (cert->pathLengthSet)
25504
0
            cert->maxPathLen = cert->pathLength;
25505
25506
0
        if (!cert->selfSigned) {
25507
            /* Need to perform a pathlen check on anything that will be used
25508
             * to sign certificates later on. Otherwise, pathLen doesn't
25509
             * mean anything.
25510
             * Nothing to check if we don't have the issuer of this cert. */
25511
0
            if (type != CERT_TYPE && cert->isCA && cert->extKeyUsageSet &&
25512
0
                (cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) != 0 && cert->ca) {
25513
0
                if (cert->ca->maxPathLen == 0) {
25514
                    /* This cert CAN NOT be used as an intermediate cert. The
25515
                     * issuer does not allow it. */
25516
0
                    cert->maxPathLen = 0;
25517
0
                    if (verify != NO_VERIFY) {
25518
0
                        WOLFSSL_MSG("\tNon-entity cert, maxPathLen is 0");
25519
0
                        WOLFSSL_MSG("\tmaxPathLen status: ERROR");
25520
0
                        WOLFSSL_ERROR_VERBOSE(ASN_PATHLEN_INV_E);
25521
0
                        return ASN_PATHLEN_INV_E;
25522
0
                    }
25523
0
                }
25524
0
                else {
25525
0
                    cert->maxPathLen = (byte)min(cert->ca->maxPathLen - 1U,
25526
0
                                           cert->maxPathLen);
25527
0
                }
25528
0
            }
25529
0
        }
25530
25531
        #ifdef HAVE_OCSP
25532
        if (verify != NO_VERIFY && type != CA_TYPE &&
25533
                                                type != TRUSTED_PEER_TYPE) {
25534
            if (cert->ca) {
25535
                /* Need the CA's public key hash for OCSP */
25536
                XMEMCPY(cert->issuerKeyHash, cert->ca->subjectKeyHash,
25537
                    KEYID_SIZE);
25538
            }
25539
        }
25540
        #endif /* HAVE_OCSP */
25541
0
    }
25542
#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_FSPSM_TLS)
25543
    /* prepare for TSIP TLS cert verification API use */
25544
    if (cert->keyOID == RSAk) {
25545
        /* to call TSIP API, it needs keys position info in bytes */
25546
        if ((ret = RsaPublicKeyDecodeRawIndex(cert->publicKey, (word32*)&idx,
25547
                                   cert->pubKeySize,
25548
                                   &cert->sigCtx.CertAtt.pubkey_n_start,
25549
                                   &cert->sigCtx.CertAtt.pubkey_n_len,
25550
                                   &cert->sigCtx.CertAtt.pubkey_e_start,
25551
                                   &cert->sigCtx.CertAtt.pubkey_e_len)) != 0) {
25552
            WOLFSSL_MSG("Decoding index from cert failed.");
25553
            return ret;
25554
        }
25555
        cert->sigCtx.CertAtt.certBegin = cert->certBegin;
25556
    }
25557
    else if (cert->keyOID == ECDSAk) {
25558
        cert->sigCtx.CertAtt.certBegin = cert->certBegin;
25559
    }
25560
    /* check if we can use TSIP for cert verification */
25561
    /* if the ca is verified as tsip root ca.         */
25562
    /* TSIP can only handle 2048 bits(256 byte) key.  */
25563
    if (cert->ca && Renesas_cmn_checkCA(cert->ca->cm_idx) != 0 &&
25564
        (cert->sigCtx.CertAtt.pubkey_n_len == 256 ||
25565
         cert->sigCtx.CertAtt.curve_id == ECC_SECP256R1)) {
25566
25567
        /* assign memory to encrypted tsip Rsa key index */
25568
        if (!cert->sce_tsip_encRsaKeyIdx)
25569
            cert->sce_tsip_encRsaKeyIdx =
25570
                            (byte*)XMALLOC(TSIP_TLS_ENCPUBKEY_SZ_BY_CERTVRFY,
25571
                             cert->heap, DYNAMIC_TYPE_RSA);
25572
        if (cert->sce_tsip_encRsaKeyIdx == NULL)
25573
                return MEMORY_E;
25574
    }
25575
    else {
25576
        if (cert->ca) {
25577
            /* TSIP isn't usable */
25578
            if (Renesas_cmn_checkCA(cert->ca->cm_idx) == 0)
25579
                WOLFSSL_MSG("SCE-TSIP isn't usable because the ca isn't verified "
25580
                            "by TSIP.");
25581
            else if (cert->sigCtx.CertAtt.pubkey_n_len != 256)
25582
                WOLFSSL_MSG("SCE-TSIP isn't usable because the ca isn't signed by "
25583
                            "RSA 2048.");
25584
            else
25585
                WOLFSSL_MSG("SCE-TSIP isn't usable");
25586
        }
25587
        cert->sce_tsip_encRsaKeyIdx = NULL;
25588
    }
25589
25590
    sce_tsip_encRsaKeyIdx = cert->sce_tsip_encRsaKeyIdx;
25591
25592
#else
25593
0
    sce_tsip_encRsaKeyIdx = NULL;
25594
0
#endif
25595
25596
0
    if (verify != NO_VERIFY && type != CA_TYPE && type != TRUSTED_PEER_TYPE) {
25597
0
        if (cert->ca) {
25598
0
            if (verify == VERIFY || verify == VERIFY_OCSP ||
25599
0
                                                 verify == VERIFY_SKIP_DATE) {
25600
0
                word32 keyOID = cert->ca->keyOID;
25601
            #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
25602
                if (cert->selfSigned && (cert->signatureOID == CTC_SM3wSM2)) {
25603
                    keyOID = SM2k;
25604
                }
25605
            #endif
25606
                /* try to confirm/verify signature */
25607
0
                if ((ret = ConfirmSignature(&cert->sigCtx,
25608
0
                        cert->source + cert->certBegin,
25609
0
                        cert->sigIndex - cert->certBegin,
25610
0
                        cert->ca->publicKey, cert->ca->pubKeySize,
25611
0
                        keyOID, cert->signature, cert->sigLength,
25612
0
                        cert->signatureOID,
25613
0
                    #ifdef WC_RSA_PSS
25614
0
                        cert->source + cert->sigParamsIndex,
25615
0
                        cert->sigParamsLength,
25616
                    #else
25617
                        NULL, 0,
25618
                    #endif
25619
0
                        sce_tsip_encRsaKeyIdx)) != 0) {
25620
0
                    if (ret != WC_NO_ERR_TRACE(WC_PENDING_E)) {
25621
0
                        WOLFSSL_MSG("Confirm signature failed");
25622
0
                    }
25623
0
                    WOLFSSL_ERROR_VERBOSE(ret);
25624
0
                    return ret;
25625
0
                }
25626
25627
            #ifdef WOLFSSL_DUAL_ALG_CERTS
25628
                if ((ret == 0) && cert->extAltSigAlgSet &&
25629
                    cert->extAltSigValSet) {
25630
                #ifndef WOLFSSL_SMALL_STACK
25631
                    byte der[WC_MAX_CERT_VERIFY_SZ];
25632
                #else
25633
                    byte *der = (byte*)XMALLOC(WC_MAX_CERT_VERIFY_SZ, cert->heap,
25634
                                            DYNAMIC_TYPE_DCERT);
25635
                    if (der == NULL) {
25636
                        ret = MEMORY_E;
25637
                    } else
25638
                #endif /* ! WOLFSSL_SMALL_STACK */
25639
                    {
25640
                        ret = wc_GeneratePreTBS(cert, der, WC_MAX_CERT_VERIFY_SZ);
25641
25642
                        if (ret > 0) {
25643
                            ret = ConfirmSignature(&cert->sigCtx, der, ret,
25644
                                    cert->ca->sapkiDer, cert->ca->sapkiLen,
25645
                                    cert->ca->sapkiOID, cert->altSigValDer,
25646
                                    cert->altSigValLen, cert->altSigAlgOID,
25647
                                    NULL, 0, NULL);
25648
                        }
25649
                #ifdef WOLFSSL_SMALL_STACK
25650
                        XFREE(der, cert->heap, DYNAMIC_TYPE_DCERT);
25651
                #endif /* WOLFSSL_SMALL_STACK */
25652
25653
                        if (ret != 0) {
25654
                            WOLFSSL_MSG("Confirm alternative signature failed");
25655
                            WOLFSSL_ERROR_VERBOSE(ret);
25656
                            return ret;
25657
                        }
25658
                        else {
25659
                            WOLFSSL_MSG("Alt signature has been verified!");
25660
                        }
25661
                    }
25662
                }
25663
            #endif /* WOLFSSL_DUAL_ALG_CERTS */
25664
0
            }
25665
0
        #ifndef IGNORE_NAME_CONSTRAINTS
25666
0
            if (verify == VERIFY || verify == VERIFY_OCSP ||
25667
0
                        verify == VERIFY_NAME || verify == VERIFY_SKIP_DATE) {
25668
                /* check that this cert's name is permitted by the signer's
25669
                 * name constraints */
25670
0
                if (!ConfirmNameConstraints(cert->ca, cert)) {
25671
0
                    WOLFSSL_MSG("Confirm name constraint failed");
25672
0
                    WOLFSSL_ERROR_VERBOSE(ASN_NAME_INVALID_E);
25673
0
                    return ASN_NAME_INVALID_E;
25674
0
                }
25675
0
            }
25676
0
        #endif /* IGNORE_NAME_CONSTRAINTS */
25677
0
        }
25678
#ifdef WOLFSSL_CERT_REQ
25679
        else if (type == CERTREQ_TYPE) {
25680
            /* try to confirm/verify signature */
25681
            if ((ret = ConfirmSignature(&cert->sigCtx,
25682
                    cert->source + cert->certBegin,
25683
                    cert->sigIndex - cert->certBegin,
25684
                    cert->publicKey, cert->pubKeySize,
25685
                    cert->keyOID, cert->signature,
25686
                    cert->sigLength, cert->signatureOID,
25687
                #ifdef WC_RSA_PSS
25688
                    cert->source + cert->sigParamsIndex, cert->sigParamsLength,
25689
                #else
25690
                    NULL, 0,
25691
                #endif
25692
                    sce_tsip_encRsaKeyIdx)) != 0) {
25693
                if (ret != WC_NO_ERR_TRACE(WC_PENDING_E)) {
25694
                    WOLFSSL_MSG("Confirm signature failed");
25695
                }
25696
                WOLFSSL_ERROR_VERBOSE(ret);
25697
                return ret;
25698
            }
25699
25700
        #ifdef WOLFSSL_DUAL_ALG_CERTS
25701
            if ((ret == 0) && cert->extAltSigAlgSet &&
25702
                cert->extAltSigValSet) {
25703
            #ifndef WOLFSSL_SMALL_STACK
25704
                byte der[WC_MAX_CERT_VERIFY_SZ];
25705
            #else
25706
                byte *der = (byte*)XMALLOC(WC_MAX_CERT_VERIFY_SZ, cert->heap,
25707
                                        DYNAMIC_TYPE_DCERT);
25708
                if (der == NULL) {
25709
                    ret = MEMORY_E;
25710
                } else
25711
            #endif /* ! WOLFSSL_SMALL_STACK */
25712
                {
25713
                    ret = wc_GeneratePreTBS(cert, der, WC_MAX_CERT_VERIFY_SZ);
25714
25715
                    if (ret > 0) {
25716
                        ret = ConfirmSignature(&cert->sigCtx, der, ret,
25717
                                cert->sapkiDer, cert->sapkiLen,
25718
                                cert->sapkiOID, cert->altSigValDer,
25719
                                cert->altSigValLen, cert->altSigAlgOID,
25720
                                NULL, 0, NULL);
25721
                    }
25722
            #ifdef WOLFSSL_SMALL_STACK
25723
                    XFREE(der, cert->heap, DYNAMIC_TYPE_DCERT);
25724
            #endif /* WOLFSSL_SMALL_STACK */
25725
25726
                    if (ret != 0) {
25727
                        WOLFSSL_MSG("Confirm alternative signature failed");
25728
                        WOLFSSL_ERROR_VERBOSE(ret);
25729
                        return ret;
25730
                    }
25731
                    else {
25732
                        WOLFSSL_MSG("Alt signature has been verified!");
25733
                    }
25734
                }
25735
            }
25736
        #endif /* WOLFSSL_DUAL_ALG_CERTS */
25737
        }
25738
#endif
25739
0
        else {
25740
            /* no signer */
25741
0
            WOLFSSL_MSG("No CA signer to verify with");
25742
            /* If you end up here with error -188,
25743
             * consider using WOLFSSL_ALT_CERT_CHAINS. */
25744
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
25745
            /* ret needs to be self-signer error for openssl compatibility */
25746
            if (cert->selfSigned) {
25747
                WOLFSSL_ERROR_VERBOSE(ASN_SELF_SIGNED_E);
25748
                return ASN_SELF_SIGNED_E;
25749
            }
25750
            else
25751
#endif
25752
0
            {
25753
0
                WOLFSSL_ERROR_VERBOSE(ASN_NO_SIGNER_E);
25754
0
                return ASN_NO_SIGNER_E;
25755
0
            }
25756
0
        }
25757
0
    }
25758
25759
#if defined(WOLFSSL_NO_TRUSTED_CERTS_VERIFY) && !defined(NO_SKID)
25760
exit_pcr:
25761
#endif
25762
25763
0
    if (cert->badDate != 0) {
25764
0
        if (verify != VERIFY_SKIP_DATE) {
25765
0
            return cert->badDate;
25766
0
        }
25767
0
        WOLFSSL_MSG("Date error: Verify option is skipping");
25768
0
    }
25769
25770
0
    if (cert->criticalExt != 0)
25771
0
        return cert->criticalExt;
25772
25773
0
    return ret;
25774
0
}
25775
25776
int FillSigner(Signer* signer, DecodedCert* cert, int type, DerBuffer *der)
25777
0
{
25778
0
    int ret = 0;
25779
25780
0
    if (signer == NULL || cert == NULL)
25781
0
        return BAD_FUNC_ARG;
25782
25783
#ifdef WOLFSSL_DUAL_ALG_CERTS
25784
    if (ret == 0 && signer != NULL) {
25785
        if (cert->extSapkiSet && cert->sapkiLen > 0) {
25786
            /* Allocated space for alternative public key. */
25787
            signer->sapkiDer = (byte*)XMALLOC(cert->sapkiLen, cert->heap,
25788
                                              DYNAMIC_TYPE_PUBLIC_KEY);
25789
            if (signer->sapkiDer == NULL) {
25790
                ret = MEMORY_E;
25791
            }
25792
            else {
25793
                XMEMCPY(signer->sapkiDer, cert->sapkiDer, cert->sapkiLen);
25794
                signer->sapkiLen = cert->sapkiLen;
25795
                signer->sapkiOID = cert->sapkiOID;
25796
            }
25797
        }
25798
    }
25799
#endif /* WOLFSSL_DUAL_ALG_CERTS */
25800
25801
#if defined(WOLFSSL_AKID_NAME) || defined(HAVE_CRL)
25802
    if (ret == 0 && signer != NULL)
25803
        ret = CalcHashId(cert->serial, (word32)cert->serialSz,
25804
                         signer->serialHash);
25805
#endif
25806
0
    if (ret == 0 && signer != NULL) {
25807
    #ifdef WOLFSSL_SIGNER_DER_CERT
25808
        ret = AllocDer(&signer->derCert, der->length, der->type, NULL);
25809
    }
25810
    if (ret == 0 && signer != NULL) {
25811
        XMEMCPY(signer->derCert->buffer, der->buffer, der->length);
25812
    #else
25813
0
    (void)der;
25814
0
    #endif
25815
0
        signer->keyOID         = cert->keyOID;
25816
0
        if (cert->pubKeyStored) {
25817
0
            signer->publicKey      = cert->publicKey;
25818
0
            signer->pubKeySize     = cert->pubKeySize;
25819
0
        }
25820
25821
0
        if (cert->subjectCNStored) {
25822
0
            signer->nameLen        = cert->subjectCNLen;
25823
0
            signer->name           = cert->subjectCN;
25824
0
        }
25825
0
        signer->maxPathLen     = cert->maxPathLen;
25826
0
        signer->selfSigned     = cert->selfSigned;
25827
0
    #ifndef IGNORE_NAME_CONSTRAINTS
25828
0
        signer->permittedNames = cert->permittedNames;
25829
0
        signer->excludedNames  = cert->excludedNames;
25830
0
    #endif
25831
0
    #ifndef NO_SKID
25832
0
        XMEMCPY(signer->subjectKeyIdHash, cert->extSubjKeyId,
25833
0
                SIGNER_DIGEST_SIZE);
25834
0
    #endif
25835
0
        XMEMCPY(signer->subjectNameHash, cert->subjectHash,
25836
0
                SIGNER_DIGEST_SIZE);
25837
    #if defined(HAVE_OCSP) || defined(HAVE_CRL)
25838
        XMEMCPY(signer->issuerNameHash, cert->issuerHash,
25839
                SIGNER_DIGEST_SIZE);
25840
    #endif
25841
    #ifdef HAVE_OCSP
25842
        XMEMCPY(signer->subjectKeyHash, cert->subjectKeyHash,
25843
                KEYID_SIZE);
25844
    #endif
25845
0
        signer->keyUsage = cert->extKeyUsageSet ? cert->extKeyUsage
25846
0
                                                : 0xFFFF;
25847
0
        signer->next    = NULL; /* If Key Usage not set, all uses valid. */
25848
0
        cert->publicKey = 0;    /* in case lock fails don't free here.   */
25849
0
        cert->subjectCN = 0;
25850
0
    #ifndef IGNORE_NAME_CONSTRAINTS
25851
0
        cert->permittedNames = NULL;
25852
0
        cert->excludedNames = NULL;
25853
0
    #endif
25854
0
        signer->type = (byte)type;
25855
0
    }
25856
0
    return ret;
25857
0
}
25858
25859
/* Create and init an new signer */
25860
Signer* MakeSigner(void* heap)
25861
0
{
25862
0
    Signer* signer = (Signer*) XMALLOC(sizeof(Signer), heap,
25863
0
                                       DYNAMIC_TYPE_SIGNER);
25864
0
    if (signer) {
25865
0
        XMEMSET(signer, 0, sizeof(Signer));
25866
0
    }
25867
0
    (void)heap;
25868
25869
0
    return signer;
25870
0
}
25871
25872
25873
/* Free an individual signer.
25874
 *
25875
 * Used by Certificate Manager.
25876
 *
25877
 * @param [in, out] signer  On in, signer object.
25878
 *                          On out, pointer is no longer valid.
25879
 * @param [in]      heap    Dynamic memory hint.
25880
 */
25881
void FreeSigner(Signer* signer, void* heap)
25882
0
{
25883
0
    (void)signer;
25884
0
    (void)heap;
25885
0
    XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
25886
0
    XFREE((void*)signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
25887
#ifdef WOLFSSL_DUAL_ALG_CERTS
25888
    XFREE(signer->sapkiDer, heap, DYNAMIC_TYPE_PUBLIC_KEY);
25889
#endif
25890
0
#ifndef IGNORE_NAME_CONSTRAINTS
25891
0
    if (signer->permittedNames)
25892
0
        FreeNameSubtrees(signer->permittedNames, heap);
25893
0
    if (signer->excludedNames)
25894
0
        FreeNameSubtrees(signer->excludedNames, heap);
25895
0
#endif
25896
#ifdef WOLFSSL_SIGNER_DER_CERT
25897
    FreeDer(&signer->derCert);
25898
#endif
25899
0
    XFREE(signer, heap, DYNAMIC_TYPE_SIGNER);
25900
0
}
25901
25902
25903
/* Free the whole singer table with number of rows.
25904
 *
25905
 * Each table entry is a linked list of signers.
25906
 * Used by Certificate Manager.
25907
 *
25908
 * @param [in, out] table   Array of signer objects.
25909
 * @param [in]      rows    Number of entries in table.
25910
 * @param [in]      heap    Dynamic memory hint.
25911
 */
25912
void FreeSignerTable(Signer** table, int rows, void* heap)
25913
0
{
25914
0
    int i;
25915
25916
0
    for (i = 0; i < rows; i++) {
25917
0
        Signer* signer = table[i];
25918
0
        while (signer) {
25919
0
            Signer* next = signer->next;
25920
0
            FreeSigner(signer, heap);
25921
0
            signer = next;
25922
0
        }
25923
0
        table[i] = NULL;
25924
0
    }
25925
0
}
25926
25927
void FreeSignerTableType(Signer** table, int rows, byte type, void* heap)
25928
0
{
25929
0
    int i;
25930
25931
0
    for (i = 0; i < rows; i++) {
25932
0
        Signer* signer = table[i];
25933
0
        Signer** next = &table[i];
25934
25935
0
        while (signer) {
25936
0
            if (signer->type == type) {
25937
0
                *next = signer->next;
25938
0
                FreeSigner(signer, heap);
25939
0
                signer = *next;
25940
0
            }
25941
0
            else {
25942
0
                next = &signer->next;
25943
0
                signer = signer->next;
25944
0
            }
25945
0
        }
25946
0
    }
25947
0
}
25948
25949
#ifdef WOLFSSL_TRUST_PEER_CERT
25950
/* Free an individual trusted peer cert.
25951
 *
25952
 * @param [in, out] tp    Trusted peer certificate object.
25953
 * @param [in]      heap  Dynamic memory hint.
25954
 */
25955
void FreeTrustedPeer(TrustedPeerCert* tp, void* heap)
25956
{
25957
    if (tp == NULL) {
25958
        return;
25959
    }
25960
25961
    XFREE(tp->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
25962
25963
    XFREE(tp->sig, heap, DYNAMIC_TYPE_SIGNATURE);
25964
#ifndef IGNORE_NAME_CONSTRAINTS
25965
    if (tp->permittedNames)
25966
        FreeNameSubtrees(tp->permittedNames, heap);
25967
    if (tp->excludedNames)
25968
        FreeNameSubtrees(tp->excludedNames, heap);
25969
#endif
25970
    XFREE(tp, heap, DYNAMIC_TYPE_CERT);
25971
25972
    (void)heap;
25973
}
25974
25975
/* Free the whole Trusted Peer linked list.
25976
 *
25977
 * Each table entry is a linked list of trusted peer certificates.
25978
 * Used by Certificate Manager.
25979
 *
25980
 * @param [in, out] table   Array of trusted peer certificate objects.
25981
 * @param [in]      rows    Number of entries in table.
25982
 * @param [in]      heap    Dynamic memory hint.
25983
 */
25984
void FreeTrustedPeerTable(TrustedPeerCert** table, int rows, void* heap)
25985
{
25986
    int i;
25987
25988
    for (i = 0; i < rows; i++) {
25989
        TrustedPeerCert* tp = table[i];
25990
        while (tp) {
25991
            TrustedPeerCert* next = tp->next;
25992
            FreeTrustedPeer(tp, heap);
25993
            tp = next;
25994
        }
25995
        table[i] = NULL;
25996
    }
25997
}
25998
#endif /* WOLFSSL_TRUST_PEER_CERT */
25999
26000
#if !defined(WOLFSSL_ASN_TEMPLATE) || defined(HAVE_PKCS7)
26001
int SetSerialNumber(const byte* sn, word32 snSz, byte* output,
26002
    word32 outputSz, int maxSnSz)
26003
{
26004
    int i;
26005
    int snSzInt = (int)snSz;
26006
26007
    if (sn == NULL || output == NULL || snSzInt < 0)
26008
        return BAD_FUNC_ARG;
26009
26010
    /* remove leading zeros */
26011
    while (snSzInt > 0 && sn[0] == 0) {
26012
        snSzInt--;
26013
        sn++;
26014
    }
26015
    /* RFC 5280 - 4.1.2.2:
26016
     *   Serial numbers must be a positive value (and not zero) */
26017
    if (snSzInt == 0) {
26018
        WOLFSSL_ERROR_VERBOSE(BAD_FUNC_ARG);
26019
        return BAD_FUNC_ARG;
26020
    }
26021
26022
    if (sn[0] & 0x80)
26023
        maxSnSz--;
26024
    /* truncate if input is too long */
26025
    if (snSzInt > maxSnSz)
26026
        snSzInt = maxSnSz;
26027
26028
    i = SetASNInt(snSzInt, sn[0], NULL);
26029
    /* truncate if input is too long */
26030
    if (snSzInt > (int)outputSz - i)
26031
        snSzInt = (int)outputSz - i;
26032
    /* sanity check number of bytes to copy */
26033
    if (snSzInt <= 0) {
26034
        return BUFFER_E;
26035
    }
26036
26037
    /* write out ASN.1 Integer */
26038
    (void)SetASNInt(snSzInt, sn[0], output);
26039
    XMEMCPY(output + i, sn, (size_t)snSzInt);
26040
26041
    /* compute final length */
26042
    i += snSzInt;
26043
26044
    return i;
26045
}
26046
#endif /* !WOLFSSL_ASN_TEMPLATE */
26047
26048
#endif /* !NO_CERTS */
26049
26050
#if defined(WOLFSSL_ASN_TEMPLATE) || defined(HAVE_PKCS12) || \
26051
    (defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT)) || \
26052
    (!defined(NO_RSA) && defined(WOLFSSL_KEY_GEN))
26053
int SetMyVersion(word32 version, byte* output, int header)
26054
0
{
26055
0
    int i = 0;
26056
26057
0
    if (output == NULL)
26058
0
        return BAD_FUNC_ARG;
26059
26060
0
    if (header) {
26061
0
        output[i++] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED;
26062
0
        output[i++] = 3;
26063
0
    }
26064
0
    output[i++] = ASN_INTEGER;
26065
0
    output[i++] = 0x01;
26066
0
    output[i++] = (byte)version;
26067
26068
0
    return i;
26069
0
}
26070
#endif
26071
26072
#ifndef WOLFSSL_ASN_TEMPLATE
26073
int wc_GetSerialNumber(const byte* input, word32* inOutIdx,
26074
    byte* serial, int* serialSz, word32 maxIdx)
26075
{
26076
    int result = 0;
26077
    int ret;
26078
26079
    WOLFSSL_ENTER("wc_GetSerialNumber");
26080
26081
    if (serial == NULL || input == NULL || serialSz == NULL) {
26082
        return BAD_FUNC_ARG;
26083
    }
26084
26085
    /* First byte is ASN type */
26086
    if ((*inOutIdx+1) > maxIdx) {
26087
        WOLFSSL_MSG("Bad idx first");
26088
        return BUFFER_E;
26089
    }
26090
26091
    ret = GetASNInt(input, inOutIdx, serialSz, maxIdx);
26092
    if (ret != 0)
26093
        return ret;
26094
26095
    if (*serialSz > EXTERNAL_SERIAL_SIZE || *serialSz <= 0) {
26096
        WOLFSSL_MSG("Serial size bad");
26097
        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
26098
        return ASN_PARSE_E;
26099
    }
26100
26101
    /* return serial */
26102
    XMEMCPY(serial, &input[*inOutIdx], (size_t)*serialSz);
26103
    *inOutIdx += (word32)*serialSz;
26104
26105
    return result;
26106
}
26107
#endif
26108
26109
#ifndef NO_CERTS
26110
26111
/* TODO: consider moving PEM code out to a different file. */
26112
26113
int AllocDer(DerBuffer** pDer, word32 length, int type, void* heap)
26114
0
{
26115
0
    int ret = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
26116
0
    if (pDer) {
26117
0
        int dynType = 0;
26118
0
        DerBuffer* der;
26119
26120
        /* Determine dynamic type */
26121
0
        switch (type) {
26122
0
            case CA_TYPE:   dynType = DYNAMIC_TYPE_CA;   break;
26123
0
            case CHAIN_CERT_TYPE:
26124
0
            case CERT_TYPE: dynType = DYNAMIC_TYPE_CERT; break;
26125
0
            case CRL_TYPE:  dynType = DYNAMIC_TYPE_CRL;  break;
26126
0
            case DSA_TYPE:  dynType = DYNAMIC_TYPE_DSA;  break;
26127
0
            case ECC_TYPE:  dynType = DYNAMIC_TYPE_ECC;  break;
26128
0
            case RSA_TYPE:  dynType = DYNAMIC_TYPE_RSA;  break;
26129
0
            default:        dynType = DYNAMIC_TYPE_KEY;  break;
26130
0
        }
26131
26132
        /* Setup new buffer */
26133
0
        *pDer = (DerBuffer*)XMALLOC(sizeof(DerBuffer) + length, heap, dynType);
26134
0
        if (*pDer == NULL) {
26135
0
            return MEMORY_E;
26136
0
        }
26137
0
        XMEMSET(*pDer, 0, sizeof(DerBuffer) + length);
26138
26139
0
        der = *pDer;
26140
0
        der->type = type;
26141
0
        der->dynType = dynType; /* Cache this for FreeDer */
26142
0
        der->heap = heap;
26143
0
        der->buffer = (byte*)der + sizeof(DerBuffer);
26144
0
        der->length = length;
26145
0
        ret = 0; /* Success */
26146
0
    } else {
26147
0
        ret = BAD_FUNC_ARG;
26148
0
    }
26149
0
    return ret;
26150
0
}
26151
26152
int AllocCopyDer(DerBuffer** pDer, const unsigned char* buff, word32 length,
26153
    int type, void* heap)
26154
0
{
26155
0
    int ret = AllocDer(pDer, length, type, heap);
26156
0
    if (ret == 0) {
26157
0
        XMEMCPY((*pDer)->buffer, buff, length);
26158
0
    }
26159
26160
0
    return ret;
26161
0
}
26162
26163
void FreeDer(DerBuffer** pDer)
26164
0
{
26165
0
    if (pDer && *pDer) {
26166
0
        DerBuffer* der = (DerBuffer*)*pDer;
26167
26168
        /* ForceZero private keys */
26169
0
        if (((der->type == PRIVATEKEY_TYPE) ||
26170
0
             (der->type == ALT_PRIVATEKEY_TYPE)) && der->buffer != NULL) {
26171
0
            ForceZero(der->buffer, der->length);
26172
0
        }
26173
0
        der->buffer = NULL;
26174
0
        der->length = 0;
26175
0
        XFREE(der, der->heap, der->dynType);
26176
26177
0
        *pDer = NULL;
26178
0
    }
26179
0
}
26180
26181
int wc_AllocDer(DerBuffer** pDer, word32 length, int type, void* heap)
26182
0
{
26183
0
    return AllocDer(pDer, length, type, heap);
26184
0
}
26185
void wc_FreeDer(DerBuffer** pDer)
26186
0
{
26187
0
    FreeDer(pDer);
26188
0
}
26189
26190
26191
#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
26192
26193
/* Note: If items added make sure MAX_X509_HEADER_SZ is
26194
    updated to reflect maximum length and pem_struct_min_sz
26195
    to reflect minimum size */
26196
static wcchar BEGIN_CERT           = "-----BEGIN CERTIFICATE-----";
26197
static wcchar END_CERT             = "-----END CERTIFICATE-----";
26198
#ifdef WOLFSSL_CERT_REQ
26199
    static wcchar BEGIN_CERT_REQ   = "-----BEGIN CERTIFICATE REQUEST-----";
26200
    static wcchar END_CERT_REQ     = "-----END CERTIFICATE REQUEST-----";
26201
#endif
26202
#if defined(WOLFSSL_ACERT)
26203
    static wcchar BEGIN_ACERT      = "-----BEGIN ATTRIBUTE CERTIFICATE-----";
26204
    static wcchar END_ACERT        = "-----END ATTRIBUTE CERTIFICATE-----";
26205
#endif /* WOLFSSL_ACERT */
26206
#ifndef NO_DH
26207
    static wcchar BEGIN_DH_PARAM   = "-----BEGIN DH PARAMETERS-----";
26208
    static wcchar END_DH_PARAM     = "-----END DH PARAMETERS-----";
26209
    static wcchar BEGIN_X942_PARAM = "-----BEGIN X9.42 DH PARAMETERS-----";
26210
    static wcchar END_X942_PARAM   = "-----END X9.42 DH PARAMETERS-----";
26211
#endif
26212
#ifndef NO_DSA
26213
    static wcchar BEGIN_DSA_PARAM  = "-----BEGIN DSA PARAMETERS-----";
26214
    static wcchar END_DSA_PARAM    = "-----END DSA PARAMETERS-----";
26215
#endif
26216
static wcchar BEGIN_X509_CRL       = "-----BEGIN X509 CRL-----";
26217
static wcchar END_X509_CRL         = "-----END X509 CRL-----";
26218
static wcchar BEGIN_TRUSTED_CERT   = "-----BEGIN TRUSTED CERTIFICATE-----";
26219
static wcchar END_TRUSTED_CERT     = "-----END TRUSTED CERTIFICATE-----";
26220
static wcchar BEGIN_RSA_PRIV       = "-----BEGIN RSA PRIVATE KEY-----";
26221
static wcchar END_RSA_PRIV         = "-----END RSA PRIVATE KEY-----";
26222
static wcchar BEGIN_RSA_PUB        = "-----BEGIN RSA PUBLIC KEY-----";
26223
static wcchar END_RSA_PUB          = "-----END RSA PUBLIC KEY-----";
26224
static wcchar BEGIN_PRIV_KEY       = "-----BEGIN PRIVATE KEY-----";
26225
static wcchar END_PRIV_KEY         = "-----END PRIVATE KEY-----";
26226
static wcchar BEGIN_ENC_PRIV_KEY   = "-----BEGIN ENCRYPTED PRIVATE KEY-----";
26227
static wcchar END_ENC_PRIV_KEY     = "-----END ENCRYPTED PRIVATE KEY-----";
26228
#ifdef HAVE_ECC
26229
    static wcchar BEGIN_EC_PRIV    = "-----BEGIN EC PRIVATE KEY-----";
26230
    static wcchar END_EC_PRIV      = "-----END EC PRIVATE KEY-----";
26231
#ifdef OPENSSL_EXTRA
26232
    static wcchar BEGIN_EC_PARAM   = "-----BEGIN EC PARAMETERS-----";
26233
    static wcchar END_EC_PARAM     = "-----END EC PARAMETERS-----";
26234
#endif
26235
#endif
26236
#ifdef HAVE_PKCS7
26237
static wcchar BEGIN_PKCS7          = "-----BEGIN PKCS7-----";
26238
static wcchar END_PKCS7            = "-----END PKCS7-----";
26239
#endif
26240
#if defined(HAVE_ECC) || !defined(NO_DSA)
26241
    static wcchar BEGIN_DSA_PRIV   = "-----BEGIN DSA PRIVATE KEY-----";
26242
    static wcchar END_DSA_PRIV     = "-----END DSA PRIVATE KEY-----";
26243
#endif
26244
#ifdef OPENSSL_EXTRA
26245
    static wcchar BEGIN_PRIV_KEY_PREFIX = "-----BEGIN";
26246
    static wcchar PRIV_KEY_SUFFIX = "PRIVATE KEY-----";
26247
    static wcchar END_PRIV_KEY_PREFIX   = "-----END";
26248
#endif
26249
static wcchar BEGIN_PUB_KEY        = "-----BEGIN PUBLIC KEY-----";
26250
static wcchar END_PUB_KEY          = "-----END PUBLIC KEY-----";
26251
#if defined(HAVE_ED25519) || defined(HAVE_ED448)
26252
    static wcchar BEGIN_EDDSA_PRIV = "-----BEGIN EDDSA PRIVATE KEY-----";
26253
    static wcchar END_EDDSA_PRIV   = "-----END EDDSA PRIVATE KEY-----";
26254
#endif
26255
#if defined(HAVE_FALCON)
26256
    static wcchar BEGIN_FALCON_LEVEL1_PRIV  = "-----BEGIN FALCON_LEVEL1 PRIVATE KEY-----";
26257
    static wcchar END_FALCON_LEVEL1_PRIV    = "-----END FALCON_LEVEL1 PRIVATE KEY-----";
26258
    static wcchar BEGIN_FALCON_LEVEL5_PRIV  = "-----BEGIN FALCON_LEVEL5 PRIVATE KEY-----";
26259
    static wcchar END_FALCON_LEVEL5_PRIV    = "-----END FALCON_LEVEL5 PRIVATE KEY-----";
26260
#endif /* HAVE_FALCON */
26261
#if defined(HAVE_DILITHIUM)
26262
    #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
26263
    static wcchar BEGIN_DILITHIUM_LEVEL2_PRIV = "-----BEGIN DILITHIUM_LEVEL2 PRIVATE KEY-----";
26264
    static wcchar END_DILITHIUM_LEVEL2_PRIV   = "-----END DILITHIUM_LEVEL2 PRIVATE KEY-----";
26265
    static wcchar BEGIN_DILITHIUM_LEVEL3_PRIV = "-----BEGIN DILITHIUM_LEVEL3 PRIVATE KEY-----";
26266
    static wcchar END_DILITHIUM_LEVEL3_PRIV   = "-----END DILITHIUM_LEVEL3 PRIVATE KEY-----";
26267
    static wcchar BEGIN_DILITHIUM_LEVEL5_PRIV = "-----BEGIN DILITHIUM_LEVEL5 PRIVATE KEY-----";
26268
    static wcchar END_DILITHIUM_LEVEL5_PRIV   = "-----END DILITHIUM_LEVEL5 PRIVATE KEY-----";
26269
    #endif
26270
    static wcchar BEGIN_ML_DSA_LEVEL2_PRIV = "-----BEGIN ML_DSA_LEVEL2 PRIVATE KEY-----";
26271
    static wcchar END_ML_DSA_LEVEL2_PRIV   = "-----END ML_DSA_LEVEL2 PRIVATE KEY-----";
26272
    static wcchar BEGIN_ML_DSA_LEVEL3_PRIV = "-----BEGIN ML_DSA_LEVEL3 PRIVATE KEY-----";
26273
    static wcchar END_ML_DSA_LEVEL3_PRIV   = "-----END ML_DSA_LEVEL3 PRIVATE KEY-----";
26274
    static wcchar BEGIN_ML_DSA_LEVEL5_PRIV = "-----BEGIN ML_DSA_LEVEL5 PRIVATE KEY-----";
26275
    static wcchar END_ML_DSA_LEVEL5_PRIV   = "-----END ML_DSA_LEVEL5 PRIVATE KEY-----";
26276
#endif /* HAVE_DILITHIUM */
26277
#if defined(HAVE_SPHINCS)
26278
    static wcchar BEGIN_SPHINCS_FAST_LEVEL1_PRIV = "-----BEGIN SPHINCS_FAST_LEVEL1 PRIVATE KEY-----";
26279
    static wcchar END_SPHINCS_FAST_LEVEL1_PRIV   = "-----END SPHINCS_FAST_LEVEL1 PRIVATE KEY-----";
26280
    static wcchar BEGIN_SPHINCS_FAST_LEVEL3_PRIV = "-----BEGIN SPHINCS_FAST_LEVEL3 PRIVATE KEY-----";
26281
    static wcchar END_SPHINCS_FAST_LEVEL3_PRIV   = "-----END SPHINCS_FAST_LEVEL3 PRIVATE KEY-----";
26282
    static wcchar BEGIN_SPHINCS_FAST_LEVEL5_PRIV = "-----BEGIN SPHINCS_FAST_LEVEL5 PRIVATE KEY-----";
26283
    static wcchar END_SPHINCS_FAST_LEVEL5_PRIV   = "-----END SPHINCS_FAST_LEVEL5 PRIVATE KEY-----";
26284
26285
    static wcchar BEGIN_SPHINCS_SMALL_LEVEL1_PRIV = "-----BEGIN SPHINCS_SMALL_LEVEL1 PRIVATE KEY-----";
26286
    static wcchar END_SPHINCS_SMALL_LEVEL1_PRIV   = "-----END SPHINCS_SMALL_LEVEL1 PRIVATE KEY-----";
26287
    static wcchar BEGIN_SPHINCS_SMALL_LEVEL3_PRIV = "-----BEGIN SPHINCS_SMALL_LEVEL3 PRIVATE KEY-----";
26288
    static wcchar END_SPHINCS_SMALL_LEVEL3_PRIV   = "-----END SPHINCS_SMALL_LEVEL3 PRIVATE KEY-----";
26289
    static wcchar BEGIN_SPHINCS_SMALL_LEVEL5_PRIV = "-----BEGIN SPHINCS_SMALL_LEVEL5 PRIVATE KEY-----";
26290
    static wcchar END_SPHINCS_SMALL_LEVEL5_PRIV   = "-----END SPHINCS_SMALL_LEVEL5 PRIVATE KEY-----";
26291
#endif /* HAVE_SPHINCS */
26292
26293
const int pem_struct_min_sz = XSTR_SIZEOF("-----BEGIN X509 CRL-----"
26294
                                             "-----END X509 CRL-----");
26295
26296
#ifdef WOLFSSL_PEM_TO_DER
26297
static WC_INLINE const char* SkipEndOfLineChars(const char* line,
26298
                                                const char* endOfLine)
26299
0
{
26300
    /* eat end of line characters */
26301
0
    while (line < endOfLine &&
26302
0
              (line[0] == '\r' || line[0] == '\n')) {
26303
0
        line++;
26304
0
    }
26305
0
    return line;
26306
0
}
26307
#endif
26308
26309
int wc_PemGetHeaderFooter(int type, const char** header, const char** footer)
26310
0
{
26311
0
    int ret = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
26312
26313
0
    switch (type) {
26314
0
        case CA_TYPE:       /* same as below */
26315
0
        case TRUSTED_PEER_TYPE:
26316
0
        case CHAIN_CERT_TYPE:
26317
0
        case CERT_TYPE:
26318
0
            if (header) *header = BEGIN_CERT;
26319
0
            if (footer) *footer = END_CERT;
26320
0
            ret = 0;
26321
0
            break;
26322
26323
0
        case CRL_TYPE:
26324
0
            if (header) *header = BEGIN_X509_CRL;
26325
0
            if (footer) *footer = END_X509_CRL;
26326
0
            ret = 0;
26327
0
            break;
26328
0
    #ifndef NO_DH
26329
0
        case DH_PARAM_TYPE:
26330
0
            if (header) *header = BEGIN_DH_PARAM;
26331
0
            if (footer) *footer = END_DH_PARAM;
26332
0
            ret = 0;
26333
0
            break;
26334
0
        case X942_PARAM_TYPE:
26335
0
            if (header) *header = BEGIN_X942_PARAM;
26336
0
            if (footer) *footer = END_X942_PARAM;
26337
0
            ret = 0;
26338
0
            break;
26339
0
    #endif
26340
    #ifndef NO_DSA
26341
        case DSA_PARAM_TYPE:
26342
            if (header) *header = BEGIN_DSA_PARAM;
26343
            if (footer) *footer = END_DSA_PARAM;
26344
            ret = 0;
26345
            break;
26346
    #endif
26347
    #ifdef WOLFSSL_CERT_REQ
26348
        case CERTREQ_TYPE:
26349
            if (header) *header = BEGIN_CERT_REQ;
26350
            if (footer) *footer = END_CERT_REQ;
26351
            ret = 0;
26352
            break;
26353
    #endif
26354
    #ifdef HAVE_PKCS7
26355
        case PKCS7_TYPE:
26356
            if (header) *header = BEGIN_PKCS7;
26357
            if (footer) *footer = END_PKCS7;
26358
            ret = 0;
26359
            break;
26360
    #endif
26361
    #if defined(WOLFSSL_ACERT)
26362
        case ACERT_TYPE:
26363
            if (header) *header = BEGIN_ACERT;
26364
            if (footer) *footer = END_ACERT;
26365
            ret = 0;
26366
            break;
26367
    #endif /* WOLFSSL_ACERT */
26368
    #ifndef NO_DSA
26369
        case DSA_TYPE:
26370
        case DSA_PRIVATEKEY_TYPE:
26371
            if (header) *header = BEGIN_DSA_PRIV;
26372
            if (footer) *footer = END_DSA_PRIV;
26373
            ret = 0;
26374
            break;
26375
    #endif
26376
0
    #ifdef HAVE_ECC
26377
0
        case ECC_TYPE:
26378
0
        case ECC_PRIVATEKEY_TYPE:
26379
0
            if (header) *header = BEGIN_EC_PRIV;
26380
0
            if (footer) *footer = END_EC_PRIV;
26381
0
            ret = 0;
26382
0
            break;
26383
    #ifdef OPENSSL_EXTRA
26384
        case ECC_PARAM_TYPE:
26385
            if (header) *header = BEGIN_EC_PARAM;
26386
            if (footer) *footer = END_EC_PARAM;
26387
            ret = 0;
26388
            break;
26389
    #endif
26390
0
    #endif
26391
0
        case RSA_TYPE:
26392
0
        case PRIVATEKEY_TYPE:
26393
    #ifdef WOLFSSL_DUAL_ALG_CERTS
26394
        case ALT_PRIVATEKEY_TYPE:
26395
    #endif
26396
0
            if (header) *header = BEGIN_RSA_PRIV;
26397
0
            if (footer) *footer = END_RSA_PRIV;
26398
0
            ret = 0;
26399
0
            break;
26400
    #ifdef HAVE_ED25519
26401
        case ED25519_TYPE:
26402
    #endif
26403
    #ifdef HAVE_ED448
26404
        case ED448_TYPE:
26405
    #endif
26406
    #if defined(HAVE_ED25519) || defined(HAVE_ED448)
26407
        case EDDSA_PRIVATEKEY_TYPE:
26408
            if (header) *header = BEGIN_EDDSA_PRIV;
26409
            if (footer) *footer = END_EDDSA_PRIV;
26410
            ret = 0;
26411
            break;
26412
    #endif
26413
#ifdef HAVE_FALCON
26414
        case FALCON_LEVEL1_TYPE:
26415
            if (header) *header = BEGIN_FALCON_LEVEL1_PRIV;
26416
            if (footer) *footer = END_FALCON_LEVEL1_PRIV;
26417
            ret = 0;
26418
            break;
26419
        case FALCON_LEVEL5_TYPE:
26420
            if (header) *header = BEGIN_FALCON_LEVEL5_PRIV;
26421
            if (footer) *footer = END_FALCON_LEVEL5_PRIV;
26422
            ret = 0;
26423
            break;
26424
#endif /* HAVE_FALCON */
26425
#ifdef HAVE_DILITHIUM
26426
    #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
26427
        case DILITHIUM_LEVEL2_TYPE:
26428
            if (header) *header = BEGIN_DILITHIUM_LEVEL2_PRIV;
26429
            if (footer) *footer = END_DILITHIUM_LEVEL2_PRIV;
26430
            ret = 0;
26431
            break;
26432
        case DILITHIUM_LEVEL3_TYPE:
26433
            if (header) *header = BEGIN_DILITHIUM_LEVEL3_PRIV;
26434
            if (footer) *footer = END_DILITHIUM_LEVEL3_PRIV;
26435
            ret = 0;
26436
            break;
26437
        case DILITHIUM_LEVEL5_TYPE:
26438
            if (header) *header = BEGIN_DILITHIUM_LEVEL5_PRIV;
26439
            if (footer) *footer = END_DILITHIUM_LEVEL5_PRIV;
26440
            ret = 0;
26441
            break;
26442
    #endif
26443
        case ML_DSA_LEVEL2_TYPE:
26444
            if (header) *header = BEGIN_ML_DSA_LEVEL2_PRIV;
26445
            if (footer) *footer = END_ML_DSA_LEVEL2_PRIV;
26446
            ret = 0;
26447
            break;
26448
        case ML_DSA_LEVEL3_TYPE:
26449
            if (header) *header = BEGIN_ML_DSA_LEVEL3_PRIV;
26450
            if (footer) *footer = END_ML_DSA_LEVEL3_PRIV;
26451
            ret = 0;
26452
            break;
26453
        case ML_DSA_LEVEL5_TYPE:
26454
            if (header) *header = BEGIN_ML_DSA_LEVEL5_PRIV;
26455
            if (footer) *footer = END_ML_DSA_LEVEL5_PRIV;
26456
            ret = 0;
26457
            break;
26458
#endif /* HAVE_DILITHIUM */
26459
#ifdef HAVE_SPHINCS
26460
        case SPHINCS_FAST_LEVEL1_TYPE:
26461
            if (header) *header = BEGIN_SPHINCS_FAST_LEVEL1_PRIV;
26462
            if (footer) *footer = END_SPHINCS_FAST_LEVEL1_PRIV;
26463
            ret = 0;
26464
            break;
26465
        case SPHINCS_FAST_LEVEL3_TYPE:
26466
            if (header) *header = BEGIN_SPHINCS_FAST_LEVEL3_PRIV;
26467
            if (footer) *footer = END_SPHINCS_FAST_LEVEL3_PRIV;
26468
            ret = 0;
26469
            break;
26470
        case SPHINCS_FAST_LEVEL5_TYPE:
26471
            if (header) *header = BEGIN_SPHINCS_FAST_LEVEL5_PRIV;
26472
            if (footer) *footer = END_SPHINCS_FAST_LEVEL5_PRIV;
26473
            ret = 0;
26474
            break;
26475
        case SPHINCS_SMALL_LEVEL1_TYPE:
26476
            if (header) *header = BEGIN_SPHINCS_SMALL_LEVEL1_PRIV;
26477
            if (footer) *footer = END_SPHINCS_SMALL_LEVEL1_PRIV;
26478
            ret = 0;
26479
            break;
26480
        case SPHINCS_SMALL_LEVEL3_TYPE:
26481
            if (header) *header = BEGIN_SPHINCS_SMALL_LEVEL3_PRIV;
26482
            if (footer) *footer = END_SPHINCS_SMALL_LEVEL3_PRIV;
26483
            ret = 0;
26484
            break;
26485
        case SPHINCS_SMALL_LEVEL5_TYPE:
26486
            if (header) *header = BEGIN_SPHINCS_SMALL_LEVEL5_PRIV;
26487
            if (footer) *footer = END_SPHINCS_SMALL_LEVEL5_PRIV;
26488
            ret = 0;
26489
            break;
26490
#endif /* HAVE_SPHINCS */
26491
0
        case PUBLICKEY_TYPE:
26492
0
        case ECC_PUBLICKEY_TYPE:
26493
0
            if (header) *header = BEGIN_PUB_KEY;
26494
0
            if (footer) *footer = END_PUB_KEY;
26495
0
            ret = 0;
26496
0
            break;
26497
0
        case RSA_PUBLICKEY_TYPE:
26498
0
            if (header) *header = BEGIN_RSA_PUB;
26499
0
            if (footer) *footer = END_RSA_PUB;
26500
0
            ret = 0;
26501
0
            break;
26502
0
    #ifndef NO_DH
26503
0
        case DH_PRIVATEKEY_TYPE:
26504
0
    #endif
26505
0
        case PKCS8_PRIVATEKEY_TYPE:
26506
0
            if (header) *header = BEGIN_PRIV_KEY;
26507
0
            if (footer) *footer = END_PRIV_KEY;
26508
0
            ret = 0;
26509
0
            break;
26510
0
        case PKCS8_ENC_PRIVATEKEY_TYPE:
26511
0
            if (header) *header = BEGIN_ENC_PRIV_KEY;
26512
0
            if (footer) *footer = END_ENC_PRIV_KEY;
26513
0
            ret = 0;
26514
0
            break;
26515
0
        case TRUSTED_CERT_TYPE:
26516
0
            if (header) *header = BEGIN_TRUSTED_CERT;
26517
0
            if (footer) *footer = END_TRUSTED_CERT;
26518
0
            ret = 0;
26519
0
            break;
26520
0
        default:
26521
0
            ret = BAD_FUNC_ARG;
26522
0
            break;
26523
0
    }
26524
0
    return ret;
26525
0
}
26526
26527
#ifdef WOLFSSL_ENCRYPTED_KEYS
26528
26529
static wcchar kProcTypeHeader = "Proc-Type";
26530
static wcchar kDecInfoHeader = "DEK-Info";
26531
26532
#ifdef WOLFSSL_PEM_TO_DER
26533
#ifndef NO_DES3
26534
    static wcchar kEncTypeDes = "DES-CBC";
26535
    static wcchar kEncTypeDes3 = "DES-EDE3-CBC";
26536
#endif
26537
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)
26538
    static wcchar kEncTypeAesCbc128 = "AES-128-CBC";
26539
#endif
26540
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_192)
26541
    static wcchar kEncTypeAesCbc192 = "AES-192-CBC";
26542
#endif
26543
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
26544
    static wcchar kEncTypeAesCbc256 = "AES-256-CBC";
26545
#endif
26546
26547
int wc_EncryptedInfoGet(EncryptedInfo* info, const char* cipherInfo)
26548
{
26549
    int ret = 0;
26550
26551
    if (info == NULL || cipherInfo == NULL)
26552
        return BAD_FUNC_ARG;
26553
26554
    /* determine cipher information */
26555
#ifndef NO_DES3
26556
    if (XSTRCMP(cipherInfo, kEncTypeDes) == 0) {
26557
        info->cipherType = WC_CIPHER_DES;
26558
        info->keySz = DES_KEY_SIZE;
26559
/* DES_IV_SIZE is incorrectly 16 in FIPS v2. It should be 8, same as the
26560
 * block size. */
26561
#if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION == 2)
26562
        if (info->ivSz == 0) info->ivSz  = DES_BLOCK_SIZE;
26563
#else
26564
        if (info->ivSz == 0) info->ivSz  = DES_IV_SIZE;
26565
#endif
26566
    }
26567
    else if (XSTRCMP(cipherInfo, kEncTypeDes3) == 0) {
26568
        info->cipherType = WC_CIPHER_DES3;
26569
        info->keySz = DES3_KEY_SIZE;
26570
#if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION == 2)
26571
        if (info->ivSz == 0) info->ivSz  = DES_BLOCK_SIZE;
26572
#else
26573
        if (info->ivSz == 0) info->ivSz  = DES_IV_SIZE;
26574
#endif
26575
    }
26576
    else
26577
#endif /* !NO_DES3 */
26578
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)
26579
    if (XSTRCMP(cipherInfo, kEncTypeAesCbc128) == 0) {
26580
        info->cipherType = WC_CIPHER_AES_CBC;
26581
        info->keySz = AES_128_KEY_SIZE;
26582
        if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;
26583
    }
26584
    else
26585
#endif
26586
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_192)
26587
    if (XSTRCMP(cipherInfo, kEncTypeAesCbc192) == 0) {
26588
        info->cipherType = WC_CIPHER_AES_CBC;
26589
        info->keySz = AES_192_KEY_SIZE;
26590
        if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;
26591
    }
26592
    else
26593
#endif
26594
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
26595
    if (XSTRCMP(cipherInfo, kEncTypeAesCbc256) == 0) {
26596
        info->cipherType = WC_CIPHER_AES_CBC;
26597
        info->keySz = AES_256_KEY_SIZE;
26598
        if (info->ivSz == 0) info->ivSz  = AES_IV_SIZE;
26599
    }
26600
    else
26601
#endif
26602
    {
26603
        ret = NOT_COMPILED_IN;
26604
    }
26605
    return ret;
26606
}
26607
26608
int wc_EncryptedInfoParse(EncryptedInfo* info, const char** pBuffer,
26609
                          size_t bufSz)
26610
{
26611
    int         err = 0;
26612
    const char* bufferStart;
26613
    const char* bufferEnd;
26614
    char*       line;
26615
26616
    if (info == NULL || pBuffer == NULL || bufSz == 0)
26617
        return BAD_FUNC_ARG;
26618
26619
    bufferStart = *pBuffer;
26620
    bufferEnd = bufferStart + bufSz;
26621
26622
    /* find encrypted info marker */
26623
    line = XSTRNSTR(bufferStart, kProcTypeHeader,
26624
                    min((word32)bufSz, PEM_LINE_LEN));
26625
    if (line != NULL) {
26626
        word32      lineSz;
26627
        char*       finish;
26628
        char*       start;
26629
        word32      startSz;
26630
        const char* newline = NULL;
26631
26632
        if (line >= bufferEnd) {
26633
            return BUFFER_E;
26634
        }
26635
26636
        lineSz = (word32)(bufferEnd - line);
26637
26638
        /* find DEC-Info marker */
26639
        start = XSTRNSTR(line, kDecInfoHeader, min(lineSz, PEM_LINE_LEN));
26640
26641
        if (start == NULL)
26642
            return BUFFER_E;
26643
26644
        /* skip dec-info and ": " */
26645
        start += XSTRLEN(kDecInfoHeader);
26646
        if (start >= bufferEnd)
26647
            return BUFFER_E;
26648
26649
        if (start[0] == ':') {
26650
            start++;
26651
            if (start >= bufferEnd)
26652
                return BUFFER_E;
26653
        }
26654
        if (start[0] == ' ')
26655
            start++;
26656
26657
        startSz = (word32)(bufferEnd - start);
26658
        finish = XSTRNSTR(start, ",", min(startSz, PEM_LINE_LEN));
26659
26660
        if ((start != NULL) && (finish != NULL) && (start < finish)) {
26661
            word32 finishSz;
26662
26663
            if (finish >= bufferEnd) {
26664
                return BUFFER_E;
26665
            }
26666
26667
            finishSz = (word32)(bufferEnd - finish);
26668
            newline = XSTRNSTR(finish, "\r", min(finishSz, PEM_LINE_LEN));
26669
26670
            /* get cipher name */
26671
            if (NAME_SZ <= (finish - start)) /* buffer size of info->name */
26672
                return BUFFER_E;
26673
            if (XMEMCPY(info->name, start, (size_t)(finish - start)) == NULL)
26674
                return BUFFER_E;
26675
            info->name[finish - start] = '\0'; /* null term */
26676
26677
            /* populate info */
26678
            err = wc_EncryptedInfoGet(info, info->name);
26679
            if (err != 0)
26680
                return err;
26681
26682
            /* get IV */
26683
            if (finishSz < info->ivSz + 1)
26684
                return BUFFER_E;
26685
26686
            if (newline == NULL) {
26687
                newline = XSTRNSTR(finish, "\n", min(finishSz,
26688
                                                     PEM_LINE_LEN));
26689
            }
26690
            if ((newline != NULL) && (newline > finish)) {
26691
                finish++;
26692
                info->ivSz = (word32)(newline - finish);
26693
                if (info->ivSz > IV_SZ)
26694
                    return BUFFER_E;
26695
                if (XMEMCPY(info->iv, finish, info->ivSz) == NULL)
26696
                    return BUFFER_E;
26697
                info->set = 1;
26698
            }
26699
            else
26700
                return BUFFER_E;
26701
        }
26702
        else
26703
            return BUFFER_E;
26704
26705
        /* eat end of line characters */
26706
        newline = SkipEndOfLineChars(newline, bufferEnd);
26707
26708
        /* return new headerEnd */
26709
26710
        *pBuffer = newline;
26711
    }
26712
26713
    return err;
26714
}
26715
#endif /* WOLFSSL_PEM_TO_DER */
26716
26717
#ifdef WOLFSSL_DER_TO_PEM
26718
static int wc_EncryptedInfoAppend(char* dest, int destSz, char* cipherInfo)
26719
{
26720
    if (cipherInfo != NULL) {
26721
        int cipherInfoStrLen = (int)XSTRLEN((char*)cipherInfo);
26722
26723
        if (cipherInfoStrLen > HEADER_ENCRYPTED_KEY_SIZE - (9+14+10+3))
26724
            cipherInfoStrLen = HEADER_ENCRYPTED_KEY_SIZE - (9+14+10+3);
26725
26726
        if (destSz - (int)XSTRLEN(dest) >= cipherInfoStrLen + (9+14+8+2+2+1)) {
26727
            /* strncat's src length needs to include the NULL */
26728
            XSTRNCAT(dest, kProcTypeHeader, 10);
26729
            XSTRNCAT(dest, ": 4,ENCRYPTED\n", 15);
26730
            XSTRNCAT(dest, kDecInfoHeader, 9);
26731
            XSTRNCAT(dest, ": ", 3);
26732
            XSTRNCAT(dest, cipherInfo, (size_t)destSz - XSTRLEN(dest) - 1);
26733
            XSTRNCAT(dest, "\n\n", 4);
26734
        }
26735
    }
26736
    return 0;
26737
}
26738
#endif /* WOLFSSL_DER_TO_PEM */
26739
#endif /* WOLFSSL_ENCRYPTED_KEYS */
26740
26741
#ifdef WOLFSSL_DER_TO_PEM
26742
26743
/* Used for compatibility API */
26744
WOLFSSL_ABI
26745
int wc_DerToPem(const byte* der, word32 derSz,
26746
                byte* output, word32 outSz, int type)
26747
{
26748
    return wc_DerToPemEx(der, derSz, output, outSz, NULL, type);
26749
}
26750
26751
/* convert der buffer to pem into output, can't do inplace, der and output
26752
   need to be different */
26753
int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz,
26754
             byte *cipher_info, int type)
26755
{
26756
    const char* headerStr = NULL;
26757
    const char* footerStr = NULL;
26758
#ifdef WOLFSSL_SMALL_STACK
26759
    char* header = NULL;
26760
    char* footer = NULL;
26761
#else
26762
    char header[MAX_X509_HEADER_SZ + HEADER_ENCRYPTED_KEY_SIZE];
26763
    char footer[MAX_X509_HEADER_SZ];
26764
#endif
26765
    size_t headerLen = MAX_X509_HEADER_SZ + HEADER_ENCRYPTED_KEY_SIZE;
26766
    size_t footerLen = MAX_X509_HEADER_SZ;
26767
    int i;
26768
    int err;
26769
    int outLen;   /* return length or error */
26770
26771
    (void)cipher_info;
26772
26773
    if (der == output)      /* no in place conversion */
26774
        return BAD_FUNC_ARG;
26775
26776
    err = wc_PemGetHeaderFooter(type, &headerStr, &footerStr);
26777
    if (err != 0)
26778
        return err;
26779
26780
#ifdef WOLFSSL_SMALL_STACK
26781
    header = (char*)XMALLOC(headerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
26782
    if (header == NULL)
26783
        return MEMORY_E;
26784
26785
    footer = (char*)XMALLOC(footerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
26786
    if (footer == NULL) {
26787
        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
26788
        return MEMORY_E;
26789
    }
26790
#endif
26791
26792
    /* build header and footer based on type */
26793
    XSTRNCPY(header, headerStr, headerLen - 1);
26794
    header[headerLen - 2] = 0;
26795
    XSTRNCPY(footer, footerStr, footerLen - 1);
26796
    footer[footerLen - 2] = 0;
26797
26798
    /* add new line to end */
26799
    XSTRNCAT(header, "\n", 2);
26800
    XSTRNCAT(footer, "\n", 2);
26801
26802
#ifdef WOLFSSL_ENCRYPTED_KEYS
26803
    err = wc_EncryptedInfoAppend(header, (int)headerLen, (char*)cipher_info);
26804
    if (err != 0) {
26805
    #ifdef WOLFSSL_SMALL_STACK
26806
        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
26807
        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
26808
    #endif
26809
        return err;
26810
    }
26811
#endif
26812
26813
    headerLen = XSTRLEN(header);
26814
    footerLen = XSTRLEN(footer);
26815
26816
    /* if null output and 0 size passed in then return size needed */
26817
    if (!output && outSz == 0) {
26818
#ifdef WOLFSSL_SMALL_STACK
26819
        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
26820
        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
26821
#endif
26822
        outLen = 0;
26823
        if ((err = Base64_Encode(der, derSz, NULL, (word32*)&outLen))
26824
                != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
26825
            WOLFSSL_ERROR_VERBOSE(err);
26826
            return err;
26827
        }
26828
        return (int)headerLen + (int)footerLen + outLen;
26829
    }
26830
26831
    if (!der || !output) {
26832
#ifdef WOLFSSL_SMALL_STACK
26833
        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
26834
        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
26835
#endif
26836
        return BAD_FUNC_ARG;
26837
    }
26838
26839
    /* don't even try if outSz too short */
26840
    if (outSz < (word32)headerLen + (word32)footerLen + derSz) {
26841
#ifdef WOLFSSL_SMALL_STACK
26842
        XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
26843
        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
26844
#endif
26845
        return BAD_FUNC_ARG;
26846
    }
26847
26848
    /* header */
26849
    XMEMCPY(output, header, (size_t)headerLen);
26850
    i = (int)headerLen;
26851
26852
#ifdef WOLFSSL_SMALL_STACK
26853
    XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
26854
#endif
26855
26856
    /* body */
26857
    outLen = (int)outSz - (int)(headerLen + footerLen);  /* input to Base64_Encode */
26858
    if ( (err = Base64_Encode(der, derSz, output + i, (word32*)&outLen)) < 0) {
26859
#ifdef WOLFSSL_SMALL_STACK
26860
        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
26861
#endif
26862
        WOLFSSL_ERROR_VERBOSE(err);
26863
        return err;
26864
    }
26865
    i += outLen;
26866
26867
    /* footer */
26868
    if ( (i + (int)footerLen) > (int)outSz) {
26869
#ifdef WOLFSSL_SMALL_STACK
26870
        XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
26871
#endif
26872
        return BAD_FUNC_ARG;
26873
    }
26874
    XMEMCPY(output + i, footer, (size_t)footerLen);
26875
26876
#ifdef WOLFSSL_SMALL_STACK
26877
    XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
26878
#endif
26879
26880
    return outLen + (int)headerLen + (int)footerLen;
26881
}
26882
26883
#endif /* WOLFSSL_DER_TO_PEM */
26884
26885
#ifdef WOLFSSL_PEM_TO_DER
26886
26887
/* Remove PEM header/footer, convert to ASN1, store any encrypted data
26888
   info->consumed tracks of PEM bytes consumed in case multiple parts */
26889
int PemToDer(const unsigned char* buff, long longSz, int type,
26890
              DerBuffer** pDer, void* heap, EncryptedInfo* info, int* keyFormat)
26891
0
{
26892
0
    const char* header      = NULL;
26893
0
    const char* footer      = NULL;
26894
0
    const char* headerEnd   = NULL;
26895
0
    const char* footerEnd   = NULL;
26896
0
    const char* consumedEnd = NULL;
26897
0
    const char* bufferEnd   = (const char*)(buff + longSz);
26898
0
    long        neededSz;
26899
0
    int         ret         = 0;
26900
0
    word32      sz          = (word32)longSz;
26901
0
    int         encrypted_key = 0;
26902
0
    DerBuffer*  der;
26903
0
    word32      algId = 0;
26904
0
    word32      idx;
26905
#ifdef OPENSSL_EXTRA
26906
    char        beginBuf[PEM_LINE_LEN + 1]; /* add 1 for null terminator */
26907
    char        endBuf[PEM_LINE_LEN + 1];   /* add 1 for null terminator */
26908
#endif
26909
#ifdef WOLFSSL_ENCRYPTED_KEYS
26910
    int hashType = WC_HASH_TYPE_NONE;
26911
#if !defined(NO_MD5)
26912
    hashType = WC_MD5;
26913
#elif !defined(NO_SHA)
26914
    hashType = WC_SHA;
26915
#endif
26916
#endif
26917
26918
0
    WOLFSSL_ENTER("PemToDer");
26919
26920
    /* get PEM header and footer based on type */
26921
0
    ret = wc_PemGetHeaderFooter(type, &header, &footer);
26922
0
    if (ret != 0)
26923
0
        return ret;
26924
26925
    /* map header if not found for type */
26926
0
    for (;;) {
26927
0
        headerEnd = XSTRNSTR((char*)buff, header, sz);
26928
0
        if (headerEnd) {
26929
0
            break;
26930
0
        }
26931
26932
0
        if (type == PRIVATEKEY_TYPE
26933
#ifdef WOLFSSL_DUAL_ALG_CERTS
26934
            || type == ALT_PRIVATEKEY_TYPE
26935
#endif
26936
0
           ) {
26937
0
            if (header == BEGIN_RSA_PRIV) {
26938
0
                header = BEGIN_PRIV_KEY;
26939
0
                footer = END_PRIV_KEY;
26940
0
            }
26941
0
            else if (header == BEGIN_PRIV_KEY) {
26942
0
                header = BEGIN_ENC_PRIV_KEY;
26943
0
                footer = END_ENC_PRIV_KEY;
26944
0
            }
26945
0
#ifdef HAVE_ECC
26946
0
            else if (header == BEGIN_ENC_PRIV_KEY) {
26947
0
                header = BEGIN_EC_PRIV;
26948
0
                footer = END_EC_PRIV;
26949
0
            }
26950
0
            else if (header == BEGIN_EC_PRIV) {
26951
0
                header = BEGIN_DSA_PRIV;
26952
0
                footer = END_DSA_PRIV;
26953
0
            }
26954
0
#endif
26955
#if defined(HAVE_ED25519) || defined(HAVE_ED448)
26956
    #ifdef HAVE_ECC
26957
            else if (header == BEGIN_DSA_PRIV) {
26958
    #else
26959
            else if (header == BEGIN_ENC_PRIV_KEY) {
26960
    #endif
26961
                header = BEGIN_EDDSA_PRIV;
26962
                footer = END_EDDSA_PRIV;
26963
            }
26964
#endif
26965
0
            else {
26966
            #ifdef WOLF_PRIVATE_KEY_ID
26967
                /* allow loading a public key for use with crypto or PK callbacks */
26968
                type = PUBLICKEY_TYPE;
26969
                header = BEGIN_PUB_KEY;
26970
                footer = END_PUB_KEY;
26971
            #else
26972
0
                break;
26973
0
            #endif
26974
0
            }
26975
0
        }
26976
0
        else if (type == PUBLICKEY_TYPE) {
26977
0
            if (header == BEGIN_PUB_KEY) {
26978
0
                header = BEGIN_RSA_PUB;
26979
0
                footer = END_RSA_PUB;
26980
0
            }
26981
0
            else {
26982
0
                break;
26983
0
            }
26984
0
        }
26985
#if defined(HAVE_ECC) && defined(OPENSSL_EXTRA)
26986
        else if (type == ECC_PARAM_TYPE) {
26987
            if (header == BEGIN_EC_PARAM) {
26988
                header = BEGIN_EC_PARAM;
26989
                footer = END_EC_PARAM;
26990
            }
26991
            else {
26992
                break;
26993
            }
26994
        }
26995
#endif
26996
#ifdef HAVE_CRL
26997
        else if ((type == CRL_TYPE) && (header != BEGIN_X509_CRL)) {
26998
            header =  BEGIN_X509_CRL;
26999
            footer = END_X509_CRL;
27000
        }
27001
#endif
27002
0
        else {
27003
0
            break;
27004
0
        }
27005
0
    }
27006
27007
0
    if (!headerEnd) {
27008
#ifdef OPENSSL_EXTRA
27009
        if (type == PRIVATEKEY_TYPE
27010
#ifdef WOLFSSL_DUAL_ALG_CERTS
27011
            || type == ALT_PRIVATEKEY_TYPE
27012
#endif
27013
           ) {
27014
            /* see if there is a -----BEGIN * PRIVATE KEY----- header */
27015
            headerEnd = XSTRNSTR((char*)buff, PRIV_KEY_SUFFIX, sz);
27016
            if (headerEnd) {
27017
                const char* beginEnd;
27018
                unsigned int endLen;
27019
27020
                beginEnd = headerEnd + XSTR_SIZEOF(PRIV_KEY_SUFFIX);
27021
                if (beginEnd >= (char*)buff + sz) {
27022
                    return BUFFER_E;
27023
                }
27024
27025
                /* back up to BEGIN_PRIV_KEY_PREFIX */
27026
                while (headerEnd > (char*)buff &&
27027
                        XSTRNCMP(headerEnd, BEGIN_PRIV_KEY_PREFIX,
27028
                                XSTR_SIZEOF(BEGIN_PRIV_KEY_PREFIX)) != 0 &&
27029
                        *headerEnd != '\n') {
27030
                    headerEnd--;
27031
                }
27032
                if (headerEnd <= (char*)buff ||
27033
                        XSTRNCMP(headerEnd, BEGIN_PRIV_KEY_PREFIX,
27034
                        XSTR_SIZEOF(BEGIN_PRIV_KEY_PREFIX)) != 0 ||
27035
                        beginEnd - headerEnd > PEM_LINE_LEN) {
27036
                    WOLFSSL_MSG("Couldn't find PEM header");
27037
                    WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
27038
                    return ASN_NO_PEM_HEADER;
27039
                }
27040
27041
                /* headerEnd now points to beginning of header */
27042
                XMEMCPY(beginBuf, headerEnd, (size_t)(beginEnd - headerEnd));
27043
                beginBuf[beginEnd - headerEnd] = '\0';
27044
                /* look for matching footer */
27045
                footer = XSTRNSTR(beginEnd,
27046
                                beginBuf + XSTR_SIZEOF(BEGIN_PRIV_KEY_PREFIX),
27047
                                (unsigned int)((char*)buff + sz - beginEnd));
27048
                if (!footer) {
27049
                    WOLFSSL_MSG("Couldn't find PEM footer");
27050
                    WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
27051
                    return ASN_NO_PEM_HEADER;
27052
                }
27053
27054
                footer -= XSTR_SIZEOF(END_PRIV_KEY_PREFIX);
27055
                if (footer > (char*)buff + sz - XSTR_SIZEOF(END_PRIV_KEY_PREFIX)
27056
                        || XSTRNCMP(footer, END_PRIV_KEY_PREFIX,
27057
                            XSTR_SIZEOF(END_PRIV_KEY_PREFIX)) != 0) {
27058
                    WOLFSSL_MSG("Unexpected footer for PEM");
27059
                    return BUFFER_E;
27060
                }
27061
27062
                endLen = (unsigned int)((size_t)(beginEnd - headerEnd) -
27063
                            (XSTR_SIZEOF(BEGIN_PRIV_KEY_PREFIX) -
27064
                                    XSTR_SIZEOF(END_PRIV_KEY_PREFIX)));
27065
                XMEMCPY(endBuf, footer, (size_t)endLen);
27066
                endBuf[endLen] = '\0';
27067
27068
                header = beginBuf;
27069
                footer = endBuf;
27070
                headerEnd = beginEnd;
27071
            }
27072
        }
27073
27074
        if (!headerEnd) {
27075
            WOLFSSL_MSG("Couldn't find PEM header");
27076
            WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
27077
            return ASN_NO_PEM_HEADER;
27078
        }
27079
#else
27080
0
        WOLFSSL_MSG("Couldn't find PEM header");
27081
0
        return ASN_NO_PEM_HEADER;
27082
0
#endif
27083
0
    } else {
27084
0
        headerEnd += XSTRLEN(header);
27085
0
    }
27086
27087
    /* eat end of line characters */
27088
0
    headerEnd = SkipEndOfLineChars(headerEnd, bufferEnd);
27089
27090
0
    if (keyFormat) {
27091
        /* keyFormat is Key_Sum enum */
27092
0
        if (type == PRIVATEKEY_TYPE
27093
        #ifdef WOLFSSL_DUAL_ALG_CERTS
27094
            || type == ALT_PRIVATEKEY_TYPE
27095
        #endif
27096
0
           ) {
27097
0
        #ifndef NO_RSA
27098
0
            if (header == BEGIN_RSA_PRIV)
27099
0
                *keyFormat = RSAk;
27100
0
        #endif
27101
0
        #ifdef HAVE_ECC
27102
0
            if (header == BEGIN_EC_PRIV)
27103
0
                *keyFormat = ECDSAk;
27104
0
        #endif
27105
        #ifndef NO_DSA
27106
            if (header == BEGIN_DSA_PRIV)
27107
                *keyFormat = DSAk;
27108
        #endif
27109
0
        }
27110
    #ifdef WOLF_PRIVATE_KEY_ID
27111
        else if (type == PUBLICKEY_TYPE) {
27112
        #ifndef NO_RSA
27113
            if (header == BEGIN_RSA_PUB)
27114
                *keyFormat = RSAk;
27115
        #endif
27116
        }
27117
    #endif
27118
0
    }
27119
27120
#ifdef WOLFSSL_ENCRYPTED_KEYS
27121
    if (info) {
27122
        ret = wc_EncryptedInfoParse(info, &headerEnd,
27123
                                    (size_t)(bufferEnd - headerEnd));
27124
        if (ret < 0)
27125
            return ret;
27126
        if (info->set)
27127
            encrypted_key = 1;
27128
    }
27129
#endif /* WOLFSSL_ENCRYPTED_KEYS */
27130
27131
    /* find footer */
27132
0
    footerEnd = XSTRNSTR(headerEnd, footer, (unsigned int)((char*)buff +
27133
0
        sz - headerEnd));
27134
0
    if (!footerEnd) {
27135
0
        if (info)
27136
0
            info->consumed = longSz; /* No more certs if no footer */
27137
0
        return BUFFER_E;
27138
0
    }
27139
27140
0
    consumedEnd = footerEnd + XSTRLEN(footer);
27141
27142
0
    if (consumedEnd < bufferEnd) { /* handle no end of line on last line */
27143
        /* eat end of line characters */
27144
0
        consumedEnd = SkipEndOfLineChars(consumedEnd, bufferEnd);
27145
        /* skip possible null term */
27146
0
        if (consumedEnd < bufferEnd && consumedEnd[0] == '\0')
27147
0
            consumedEnd++;
27148
0
    }
27149
27150
0
    if (info)
27151
0
        info->consumed = (long)(consumedEnd - (const char*)buff);
27152
27153
    /* set up der buffer */
27154
0
    neededSz = (long)(footerEnd - headerEnd);
27155
0
    if (neededSz > (long)sz || neededSz <= 0)
27156
0
        return BUFFER_E;
27157
27158
0
    ret = AllocDer(pDer, (word32)neededSz, type, heap);
27159
0
    if (ret < 0) {
27160
0
        return ret;
27161
0
    }
27162
0
    der = *pDer;
27163
27164
0
    switch (type) {
27165
0
    case PUBLICKEY_TYPE:
27166
0
    case ECC_PUBLICKEY_TYPE:
27167
0
    case RSA_PUBLICKEY_TYPE:
27168
0
    case CERT_TYPE:
27169
0
    case TRUSTED_CERT_TYPE:
27170
0
    case CRL_TYPE:
27171
0
        if (Base64_Decode_nonCT((byte*)headerEnd, (word32)neededSz,
27172
0
                          der->buffer, &der->length) < 0)
27173
0
        {
27174
0
            WOLFSSL_ERROR(BUFFER_E);
27175
0
            return BUFFER_E;
27176
0
        }
27177
0
        break;
27178
0
    default:
27179
0
        if (Base64_Decode((byte*)headerEnd, (word32)neededSz,
27180
0
                          der->buffer, &der->length) < 0) {
27181
0
            WOLFSSL_ERROR(BUFFER_E);
27182
0
            return BUFFER_E;
27183
0
        }
27184
0
        break;
27185
0
    }
27186
27187
0
    if ((header == BEGIN_PRIV_KEY
27188
#ifdef OPENSSL_EXTRA
27189
         || header == beginBuf
27190
#endif
27191
0
#ifdef HAVE_ECC
27192
0
         || header == BEGIN_EC_PRIV
27193
0
#endif
27194
0
        ) && !encrypted_key)
27195
0
    {
27196
        /* detect pkcs8 key and get alg type */
27197
        /* keep PKCS8 header */
27198
0
        idx = 0;
27199
0
        ret = ToTraditionalInline_ex(der->buffer, &idx, der->length, &algId);
27200
0
        if (ret > 0) {
27201
0
            if (keyFormat)
27202
0
                *keyFormat = (int)algId;
27203
0
        }
27204
0
        else {
27205
            /* ignore failure here and assume key is not pkcs8 wrapped */
27206
0
        }
27207
0
        return 0;
27208
0
    }
27209
27210
#ifdef WOLFSSL_ENCRYPTED_KEYS
27211
    if (encrypted_key || header == BEGIN_ENC_PRIV_KEY) {
27212
        int   passwordSz = NAME_SZ;
27213
    #ifdef WOLFSSL_SMALL_STACK
27214
        char* password = NULL;
27215
    #else
27216
        char  password[NAME_SZ];
27217
    #endif
27218
27219
        if (!info || !info->passwd_cb) {
27220
            WOLFSSL_MSG("No password callback set");
27221
            WOLFSSL_ERROR_VERBOSE(NO_PASSWORD);
27222
            return NO_PASSWORD;
27223
        }
27224
27225
    #ifdef WOLFSSL_SMALL_STACK
27226
        password = (char*)XMALLOC((size_t)passwordSz, heap, DYNAMIC_TYPE_STRING);
27227
        if (password == NULL) {
27228
            return MEMORY_E;
27229
        }
27230
    #endif
27231
27232
        /* get password */
27233
        ret = info->passwd_cb(password, passwordSz, PEM_PASS_READ,
27234
            info->passwd_userdata);
27235
        if (ret >= 0) {
27236
            passwordSz = ret;
27237
        #ifdef WOLFSSL_CHECK_MEM_ZERO
27238
            wc_MemZero_Add("PEM password", password, passwordSz);
27239
        #endif
27240
27241
            /* convert and adjust length */
27242
            if (header == BEGIN_ENC_PRIV_KEY) {
27243
            #ifndef NO_PWDBASED
27244
                ret = wc_DecryptPKCS8Key(der->buffer, der->length,
27245
                    password, passwordSz);
27246
                if (ret > 0) {
27247
                    /* update length by decrypted content */
27248
                    der->length = (word32)ret;
27249
                    idx = 0;
27250
                    /* detect pkcs8 key and get alg type */
27251
                    /* keep PKCS8 header */
27252
                    ret = ToTraditionalInline_ex(der->buffer, &idx, der->length,
27253
                        &algId);
27254
                    if (ret >= 0) {
27255
                        if (keyFormat)
27256
                            *keyFormat = (int)algId;
27257
                        ret = 0;
27258
                    }
27259
                }
27260
            #else
27261
                WOLFSSL_ERROR_VERBOSE(NOT_COMPILED_IN);
27262
                ret = NOT_COMPILED_IN;
27263
            #endif
27264
            }
27265
            /* decrypt the key */
27266
            else {
27267
                if (passwordSz == 0) {
27268
                    /* The key is encrypted but does not have a password */
27269
                    WOLFSSL_MSG("No password for encrypted key");
27270
                    WOLFSSL_ERROR_VERBOSE(NO_PASSWORD);
27271
                    ret = NO_PASSWORD;
27272
                }
27273
                else {
27274
                #if ((defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_DES3)) || \
27275
                         (!defined(NO_AES) && defined(HAVE_AES_CBC) && \
27276
                          defined(HAVE_AES_DECRYPT))) && \
27277
                        !defined(NO_WOLFSSL_SKIP_TRAILING_PAD)
27278
                    int     padVal = 0;
27279
                #endif
27280
27281
                    ret = wc_BufferKeyDecrypt(info, der->buffer, der->length,
27282
                        (byte*)password, passwordSz, hashType);
27283
27284
#ifndef NO_WOLFSSL_SKIP_TRAILING_PAD
27285
                #ifndef NO_DES3
27286
                    if (info->cipherType == WC_CIPHER_DES3) {
27287
                        /* Assuming there is padding:
27288
                         *      (der->length > 0 && der->length > DES_BLOCK_SIZE &&
27289
                         *       (der->length % DES_BLOCK_SIZE) != 0)
27290
                         * and assuming the last value signifies the number of
27291
                         * padded bytes IE if last value is 0x08 then there are
27292
                         * 8 bytes of padding:
27293
                         *      padVal = der->buffer[der->length-1];
27294
                         * then strip this padding before proceeding:
27295
                         * der->length -= padVal;
27296
                         */
27297
                        if (der->length > DES_BLOCK_SIZE &&
27298
                            (der->length % DES_BLOCK_SIZE) != 0) {
27299
                            padVal = der->buffer[der->length-1];
27300
                            if (padVal < DES_BLOCK_SIZE) {
27301
                                der->length -= (word32)padVal;
27302
                            }
27303
                        }
27304
                    }
27305
                #endif /* !NO_DES3 */
27306
                #if !defined(NO_AES) && defined(HAVE_AES_CBC) && \
27307
                    defined(HAVE_AES_DECRYPT)
27308
                    if (info->cipherType == WC_CIPHER_AES_CBC) {
27309
                        if (der->length > WC_AES_BLOCK_SIZE) {
27310
                            padVal = der->buffer[der->length-1];
27311
                            if (padVal <= WC_AES_BLOCK_SIZE) {
27312
                                der->length -= (word32)padVal;
27313
                            }
27314
                        }
27315
                    }
27316
                #endif
27317
#endif /* !NO_WOLFSSL_SKIP_TRAILING_PAD */
27318
                }
27319
            }
27320
#ifdef OPENSSL_EXTRA
27321
            if (ret) {
27322
                WOLFSSL_PEMerr(0, WOLFSSL_PEM_R_BAD_DECRYPT_E);
27323
            }
27324
#endif
27325
            ForceZero(password, (word32)passwordSz);
27326
        }
27327
#ifdef OPENSSL_EXTRA
27328
        else {
27329
            WOLFSSL_PEMerr(0, WOLFSSL_PEM_R_BAD_PASSWORD_READ_E);
27330
        }
27331
#endif
27332
27333
    #ifdef WOLFSSL_SMALL_STACK
27334
        XFREE(password, heap, DYNAMIC_TYPE_STRING);
27335
    #elif defined(WOLFSSL_CHECK_MEM_ZERO)
27336
        wc_MemZero_Check(password, NAME_SZ);
27337
    #endif
27338
    }
27339
#endif /* WOLFSSL_ENCRYPTED_KEYS */
27340
27341
0
    return ret;
27342
0
}
27343
27344
int wc_PemToDer(const unsigned char* buff, long longSz, int type,
27345
              DerBuffer** pDer, void* heap, EncryptedInfo* info, int* keyFormat)
27346
0
{
27347
0
    int ret = PemToDer(buff, longSz, type, pDer, heap, info, keyFormat);
27348
0
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
27349
0
    if (ret == 0 && type == PRIVATEKEY_TYPE) {
27350
0
        DerBuffer* der = *pDer;
27351
        /* if a PKCS8 key header exists remove it */
27352
0
        ret = ToTraditional(der->buffer, der->length);
27353
0
        if (ret > 0) {
27354
0
            der->length = (word32)ret;
27355
0
        }
27356
0
        ret = 0; /* ignore error removing PKCS8 header */
27357
0
    }
27358
0
#endif
27359
0
    return ret;
27360
0
}
27361
27362
#ifdef WOLFSSL_ENCRYPTED_KEYS
27363
/* our KeyPemToDer password callback, password in userData */
27364
static int KeyPemToDerPassCb(char* passwd, int sz, int rw, void* userdata)
27365
{
27366
    (void)rw;
27367
27368
    if (userdata == NULL)
27369
        return 0;
27370
27371
    XSTRNCPY(passwd, (char*)userdata, (size_t)sz);
27372
    return (int)min((word32)sz, (word32)XSTRLEN((char*)userdata));
27373
}
27374
#endif
27375
27376
/* Return bytes written to buff or < 0 for error */
27377
int wc_KeyPemToDer(const unsigned char* pem, int pemSz,
27378
                        unsigned char* buff, int buffSz, const char* pass)
27379
0
{
27380
0
    int ret;
27381
0
    DerBuffer* der = NULL;
27382
#ifdef WOLFSSL_SMALL_STACK
27383
    EncryptedInfo* info = NULL;
27384
#else
27385
0
    EncryptedInfo  info[1];
27386
0
#endif
27387
27388
0
    WOLFSSL_ENTER("wc_KeyPemToDer");
27389
27390
0
    if (pem == NULL || (buff != NULL && buffSz <= 0)) {
27391
0
        WOLFSSL_MSG("Bad pem der args");
27392
0
        return BAD_FUNC_ARG;
27393
0
    }
27394
27395
#ifdef WOLFSSL_SMALL_STACK
27396
    info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
27397
                                   DYNAMIC_TYPE_ENCRYPTEDINFO);
27398
    if (info == NULL)
27399
        return MEMORY_E;
27400
#endif
27401
27402
0
    XMEMSET(info, 0, sizeof(EncryptedInfo));
27403
#ifdef WOLFSSL_ENCRYPTED_KEYS
27404
    info->passwd_cb = KeyPemToDerPassCb;
27405
    info->passwd_userdata = (void*)pass;
27406
#else
27407
0
    (void)pass;
27408
0
#endif
27409
27410
0
    ret = PemToDer(pem, pemSz, PRIVATEKEY_TYPE, &der, NULL, info, NULL);
27411
27412
#ifdef WOLFSSL_SMALL_STACK
27413
    XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
27414
#endif
27415
27416
0
    if (ret < 0 || der == NULL) {
27417
0
        WOLFSSL_MSG("Bad Pem To Der");
27418
0
    }
27419
0
    else if (buff == NULL) {
27420
0
        WOLFSSL_MSG("Return needed der buff length");
27421
0
        ret = (int)der->length;
27422
0
    }
27423
0
    else if (der->length <= (word32)buffSz) {
27424
0
        XMEMCPY(buff, der->buffer, der->length);
27425
0
        ret = (int)der->length;
27426
0
    }
27427
0
    else {
27428
0
        WOLFSSL_MSG("Bad der length");
27429
0
        ret = BAD_FUNC_ARG;
27430
0
    }
27431
27432
0
    FreeDer(&der);
27433
0
    return ret;
27434
0
}
27435
27436
27437
/* Return bytes written to buff or < 0 for error */
27438
int wc_CertPemToDer(const unsigned char* pem, int pemSz,
27439
                        unsigned char* buff, int buffSz, int type)
27440
0
{
27441
0
    int ret;
27442
0
    DerBuffer* der = NULL;
27443
27444
0
    WOLFSSL_ENTER("wc_CertPemToDer");
27445
27446
0
    if (pem == NULL || buff == NULL || buffSz <= 0) {
27447
0
        WOLFSSL_MSG("Bad pem der args");
27448
0
        return BAD_FUNC_ARG;
27449
0
    }
27450
27451
0
    if (type != CERT_TYPE && type != CHAIN_CERT_TYPE && type != CA_TYPE &&
27452
0
            type != CERTREQ_TYPE && type != PKCS7_TYPE) {
27453
0
        WOLFSSL_MSG("Bad cert type");
27454
0
        return BAD_FUNC_ARG;
27455
0
    }
27456
27457
27458
0
    ret = PemToDer(pem, pemSz, type, &der, NULL, NULL, NULL);
27459
0
    if (ret < 0 || der == NULL) {
27460
0
        WOLFSSL_MSG("Bad Pem To Der");
27461
0
    }
27462
0
    else {
27463
0
        if (der->length <= (word32)buffSz) {
27464
0
            XMEMCPY(buff, der->buffer, der->length);
27465
0
            ret = (int)der->length;
27466
0
        }
27467
0
        else {
27468
0
            WOLFSSL_MSG("Bad der length");
27469
0
            ret = BAD_FUNC_ARG;
27470
0
        }
27471
0
    }
27472
27473
0
    FreeDer(&der);
27474
0
    return ret;
27475
0
}
27476
27477
#endif /* WOLFSSL_PEM_TO_DER */
27478
#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
27479
27480
27481
#ifdef WOLFSSL_PEM_TO_DER
27482
#if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER)
27483
/* Return bytes written to buff, needed buff size if buff is NULL, or less than
27484
   zero for error */
27485
int wc_PubKeyPemToDer(const unsigned char* pem, int pemSz,
27486
                           unsigned char* buff, int buffSz)
27487
{
27488
    int ret;
27489
    DerBuffer* der = NULL;
27490
27491
    WOLFSSL_ENTER("wc_PubKeyPemToDer");
27492
27493
    if (pem == NULL || (buff != NULL && buffSz <= 0)) {
27494
        WOLFSSL_MSG("Bad pem der args");
27495
        return BAD_FUNC_ARG;
27496
    }
27497
27498
    ret = PemToDer(pem, pemSz, PUBLICKEY_TYPE, &der, NULL, NULL, NULL);
27499
    if (ret < 0 || der == NULL) {
27500
        WOLFSSL_MSG("Bad Pem To Der");
27501
    }
27502
    else if (buff == NULL) {
27503
        WOLFSSL_MSG("Return needed der buff length");
27504
        ret = (int)der->length;
27505
    }
27506
    else if (der->length <= (word32)buffSz) {
27507
        XMEMCPY(buff, der->buffer, der->length);
27508
        ret = (int)der->length;
27509
    }
27510
    else {
27511
        WOLFSSL_MSG("Bad der length");
27512
        ret = BAD_FUNC_ARG;
27513
    }
27514
27515
    FreeDer(&der);
27516
    return ret;
27517
}
27518
#endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */
27519
#endif /* WOLFSSL_PEM_TO_DER */
27520
27521
#if !defined(NO_FILESYSTEM) && defined(WOLFSSL_PEM_TO_DER)
27522
27523
#ifdef WOLFSSL_CERT_GEN
27524
int wc_PemCertToDer_ex(const char* fileName, DerBuffer** der)
27525
{
27526
#ifndef WOLFSSL_SMALL_STACK
27527
    byte   staticBuffer[FILE_BUFFER_SIZE];
27528
#endif
27529
    byte*  fileBuf = NULL;
27530
    int    ret     = 0;
27531
    XFILE  file    = XBADFILE;
27532
    int    dynamic = 0;
27533
    long   sz      = 0;
27534
27535
    WOLFSSL_ENTER("wc_PemCertToDer");
27536
27537
    if (fileName == NULL) {
27538
        ret = BAD_FUNC_ARG;
27539
    }
27540
    else {
27541
        file = XFOPEN(fileName, "rb");
27542
        if (file == XBADFILE) {
27543
            ret = IO_FAILED_E;
27544
        }
27545
    }
27546
27547
    if (ret == 0) {
27548
        if (XFSEEK(file, 0, XSEEK_END) != 0) {
27549
            ret = IO_FAILED_E;
27550
        }
27551
    }
27552
    if (ret == 0) {
27553
        sz = XFTELL(file);
27554
        if (sz <= 0) {
27555
            ret = IO_FAILED_E;
27556
        }
27557
    }
27558
    if (ret == 0) {
27559
        if (XFSEEK(file, 0, XSEEK_SET) != 0) {
27560
            ret = IO_FAILED_E;
27561
        }
27562
    }
27563
    if (ret == 0) {
27564
#ifndef WOLFSSL_SMALL_STACK
27565
        if (sz <= (long)sizeof(staticBuffer))
27566
            fileBuf = staticBuffer;
27567
        else
27568
#endif
27569
        {
27570
            fileBuf = (byte*)XMALLOC((size_t)sz, NULL, DYNAMIC_TYPE_FILE);
27571
            if (fileBuf == NULL)
27572
                ret = MEMORY_E;
27573
            else
27574
                dynamic = 1;
27575
        }
27576
    }
27577
    if (ret == 0) {
27578
        if ((size_t)XFREAD(fileBuf, 1, (size_t)sz, file) != (size_t)sz) {
27579
            ret = IO_FAILED_E;
27580
        }
27581
        else {
27582
            ret = PemToDer(fileBuf, sz, CA_TYPE, der,  0, NULL,NULL);
27583
        }
27584
    }
27585
27586
    if (file != XBADFILE)
27587
        XFCLOSE(file);
27588
    if (dynamic)
27589
        XFREE(fileBuf, NULL, DYNAMIC_TYPE_FILE);
27590
27591
    return ret;
27592
}
27593
/* load pem cert from file into der buffer, return der size or error */
27594
int wc_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz)
27595
{
27596
    int ret;
27597
    DerBuffer* converted = NULL;
27598
    ret = wc_PemCertToDer_ex(fileName, &converted);
27599
    if (ret == 0) {
27600
        if (converted->length < (word32)derSz) {
27601
            XMEMCPY(derBuf, converted->buffer, converted->length);
27602
            ret = (int)converted->length;
27603
        }
27604
        else
27605
            ret = BUFFER_E;
27606
27607
        FreeDer(&converted);
27608
    }
27609
    return ret;
27610
}
27611
#endif /* WOLFSSL_CERT_GEN */
27612
27613
#if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER)
27614
/* load pem public key from file into der buffer, return der size or error */
27615
int wc_PemPubKeyToDer_ex(const char* fileName, DerBuffer** der)
27616
{
27617
#ifndef WOLFSSL_SMALL_STACK
27618
    byte   staticBuffer[FILE_BUFFER_SIZE];
27619
#endif
27620
    byte*  fileBuf = NULL;
27621
    int    dynamic = 0;
27622
    int    ret     = 0;
27623
    long   sz      = 0;
27624
    XFILE  file    = XBADFILE;
27625
27626
    WOLFSSL_ENTER("wc_PemPubKeyToDer");
27627
27628
    if (fileName == NULL) {
27629
        ret = BAD_FUNC_ARG;
27630
    }
27631
    else {
27632
        file = XFOPEN(fileName, "rb");
27633
        if (file == XBADFILE) {
27634
            ret = IO_FAILED_E;
27635
        }
27636
    }
27637
27638
    if (ret == 0) {
27639
        if (XFSEEK(file, 0, XSEEK_END) != 0) {
27640
            ret = IO_FAILED_E;
27641
        }
27642
    }
27643
    if (ret == 0) {
27644
        sz = XFTELL(file);
27645
        if (sz <= 0) {
27646
            ret = IO_FAILED_E;
27647
        }
27648
    }
27649
    if (ret == 0) {
27650
        if (XFSEEK(file, 0, XSEEK_SET) != 0) {
27651
            ret = IO_FAILED_E;
27652
        }
27653
    }
27654
    if (ret == 0) {
27655
#ifndef WOLFSSL_SMALL_STACK
27656
        if (sz <= (long)sizeof(staticBuffer))
27657
            fileBuf = staticBuffer;
27658
        else
27659
#endif
27660
        {
27661
            fileBuf = (byte*)XMALLOC((size_t)sz, NULL, DYNAMIC_TYPE_FILE);
27662
            if (fileBuf == NULL)
27663
                ret = MEMORY_E;
27664
            else
27665
                dynamic = 1;
27666
        }
27667
    }
27668
    if (ret == 0) {
27669
        if ((size_t)XFREAD(fileBuf, 1, (size_t)sz, file) != (size_t)sz) {
27670
            ret = BUFFER_E;
27671
        }
27672
        else {
27673
            ret = PemToDer(fileBuf, sz, PUBLICKEY_TYPE, der,
27674
                           0, NULL, NULL);
27675
        }
27676
    }
27677
27678
    if (file != XBADFILE)
27679
        XFCLOSE(file);
27680
    if (dynamic)
27681
        XFREE(fileBuf, NULL, DYNAMIC_TYPE_FILE);
27682
27683
    return ret;
27684
}
27685
/* load pem public key from file into der buffer, return der size or error */
27686
int wc_PemPubKeyToDer(const char* fileName,
27687
                           unsigned char* derBuf, int derSz)
27688
{
27689
    int ret;
27690
    DerBuffer* converted = NULL;
27691
    ret = wc_PemPubKeyToDer_ex(fileName, &converted);
27692
    if (ret == 0) {
27693
        if (converted->length < (word32)derSz) {
27694
            XMEMCPY(derBuf, converted->buffer, converted->length);
27695
            ret = (int)converted->length;
27696
        }
27697
        else
27698
            ret = BUFFER_E;
27699
27700
        FreeDer(&converted);
27701
    }
27702
    return ret;
27703
}
27704
#endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */
27705
27706
#endif /* !NO_FILESYSTEM && WOLFSSL_PEM_TO_DER */
27707
27708
/* Get public key in DER format from a populated DecodedCert struct.
27709
 *
27710
 * Users must call wc_InitDecodedCert() and wc_ParseCert() before calling
27711
 * this API. wc_InitDecodedCert() accepts a DER/ASN.1 encoded certificate.
27712
 * To convert a PEM cert to DER first use wc_CertPemToDer() before calling
27713
 * wc_InitDecodedCert().
27714
 *
27715
 * cert   - populated DecodedCert struct holding X.509 certificate
27716
 * derKey - output buffer to place DER/ASN.1 encoded public key
27717
 * derKeySz [IN/OUT] - size of derKey buffer on input, size of public key
27718
 *                     on return. If derKey is passed in as NULL, derKeySz
27719
 *                     will be set to required buffer size for public key
27720
 *                     and LENGTH_ONLY_E will be returned from function.
27721
 * Returns 0 on success, or negative error code on failure. LENGTH_ONLY_E
27722
 * if derKey is NULL and returning length only.
27723
 */
27724
int wc_GetPubKeyDerFromCert(struct DecodedCert* cert,
27725
                            byte* derKey, word32* derKeySz)
27726
0
{
27727
0
    int ret = 0;
27728
27729
    /* derKey may be NULL to return length only */
27730
0
    if (cert == NULL || derKeySz == NULL ||
27731
0
        (derKey != NULL && *derKeySz == 0)) {
27732
0
        return BAD_FUNC_ARG;
27733
0
    }
27734
27735
0
    if (cert->publicKey == NULL) {
27736
0
        WOLFSSL_MSG("DecodedCert does not contain public key\n");
27737
0
        return BAD_FUNC_ARG;
27738
0
    }
27739
27740
    /* if derKey is NULL, return required output buffer size in derKeySz */
27741
0
    if (derKey == NULL) {
27742
0
        *derKeySz = cert->pubKeySize;
27743
0
        ret = WC_NO_ERR_TRACE(LENGTH_ONLY_E);
27744
0
    }
27745
27746
0
    if (ret == 0) {
27747
0
        if (cert->pubKeySize > *derKeySz) {
27748
0
            WOLFSSL_MSG("Output buffer not large enough for public key DER");
27749
0
            ret = BAD_FUNC_ARG;
27750
0
        }
27751
0
        else {
27752
0
            XMEMCPY(derKey, cert->publicKey, cert->pubKeySize);
27753
0
            *derKeySz = cert->pubKeySize;
27754
0
        }
27755
0
    }
27756
27757
0
    return ret;
27758
0
}
27759
27760
#ifdef WOLFSSL_FPKI
27761
/* Search through list for first matching alt name of the same type
27762
 * If 'current' is null then the search starts at the head of the list
27763
 * otherwise the search starts from the node after 'current' alt name.
27764
 * Returns 0 on success
27765
 */
27766
static DNS_entry* FindAltName(struct DecodedCert* cert, int nameType,
27767
    DNS_entry* current)
27768
{
27769
    DNS_entry* entry;
27770
27771
    if (current == NULL) {
27772
        entry = cert->altNames;
27773
    }
27774
    else {
27775
        entry = current->next;
27776
    }
27777
27778
    /* cycle through alt names to check for needed types */
27779
    while (entry != NULL) {
27780
        if (entry->type == nameType) {
27781
            break;
27782
        }
27783
        entry = entry->next;
27784
    }
27785
27786
    return entry;
27787
}
27788
27789
27790
/* returns 0 on success */
27791
int wc_GetUUIDFromCert(struct DecodedCert* cert, byte* uuid, word32* uuidSz)
27792
{
27793
    int ret = WC_NO_ERR_TRACE(ALT_NAME_E);
27794
    DNS_entry* id = NULL;
27795
27796
    do {
27797
        id = FindAltName(cert, ASN_URI_TYPE, id);
27798
        if (id != NULL) {
27799
            /* check if URI string matches expected format for UUID */
27800
            if (id->len != DEFAULT_UUID_SZ) {
27801
                continue; /* size not right not a UUID URI */
27802
            }
27803
27804
            if (XMEMCMP(id->name, "urn:uuid:", 9) != 0) {
27805
                continue; /* beginning text not right for a UUID URI */
27806
            }
27807
27808
            if (uuid == NULL) {
27809
                *uuidSz = (word32)id->len;
27810
                return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
27811
            }
27812
27813
            if ((int)*uuidSz < id->len) {
27814
                return BUFFER_E;
27815
            }
27816
27817
            XMEMCPY(uuid, id->name, (size_t)id->len);
27818
            ret = 0; /* success */
27819
            break;
27820
        }
27821
    } while (id != NULL);
27822
27823
    return ret;
27824
}
27825
27826
27827
/* returns 0 on success */
27828
int wc_GetFASCNFromCert(struct DecodedCert* cert, byte* fascn, word32* fascnSz)
27829
{
27830
    int ret = WC_NO_ERR_TRACE(ALT_NAME_E);
27831
    DNS_entry* id = NULL;
27832
27833
    do {
27834
        id = FindAltName(cert, ASN_OTHER_TYPE, id);
27835
        if (id != NULL && id->oidSum == FASCN_OID) {
27836
            if (fascn == NULL) {
27837
                *fascnSz = (word32)id->len;
27838
                return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
27839
            }
27840
27841
            if ((int)*fascnSz < id->len) {
27842
                return BUFFER_E;
27843
            }
27844
27845
            XMEMCPY(fascn, id->name, (size_t)id->len);
27846
            ret = 0; /* success */
27847
        }
27848
    } while (id != NULL);
27849
27850
    return ret;
27851
}
27852
#endif /* WOLFSSL_FPKI */
27853
27854
#if !defined(NO_RSA) && (defined(WOLFSSL_CERT_GEN) || \
27855
    defined(WOLFSSL_KCAPI_RSA) || \
27856
    ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA))))
27857
/* USER RSA ifdef portions used instead of refactor in consideration for
27858
   possible fips build */
27859
/* Encode a public RSA key to output.
27860
 *
27861
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
27862
 * PKCS #1: RFC 8017, A.1.1 - RSAPublicKey
27863
 *
27864
 * Encoded data can either be SubjectPublicKeyInfo (with header) or just the key
27865
 * (RSAPublicKey).
27866
 *
27867
 * @param [out] output       Buffer to put encoded data in.
27868
 * @param [in]  key          RSA key object.
27869
 * @param [in]  outLen       Size of the output buffer in bytes.
27870
 * @param [in]  with_header  Whether to include SubjectPublicKeyInfo around key.
27871
 * @return  Size of encoded data in bytes on success.
27872
 * @return  BAD_FUNC_ARG when output or key is NULL, or outLen is less than
27873
 *          minimum length (5 bytes).
27874
 * @return  MEMORY_E when dynamic memory allocation failed.
27875
 */
27876
static int SetRsaPublicKey(byte* output, RsaKey* key, int outLen,
27877
                           int with_header)
27878
{
27879
#ifndef WOLFSSL_ASN_TEMPLATE
27880
    int  nSz, eSz;
27881
    word32 seqSz, algoSz = 0, headSz = 0, bitStringSz = 0, idx;
27882
    byte seq[MAX_SEQ_SZ];
27883
    byte headSeq[MAX_SEQ_SZ];
27884
    byte bitString[1 + MAX_LENGTH_SZ + 1];
27885
    byte algo[MAX_ALGO_SZ]; /* 20 bytes */
27886
27887
    if (key == NULL) {
27888
        return BAD_FUNC_ARG;
27889
    }
27890
27891
    nSz = SetASNIntMP(&key->n, MAX_RSA_INT_SZ, NULL);
27892
27893
    if (nSz < 0)
27894
        return nSz;
27895
27896
    eSz = SetASNIntMP(&key->e, MAX_RSA_INT_SZ, NULL);
27897
27898
    if (eSz < 0)
27899
        return eSz;
27900
    seqSz = SetSequence((word32)(nSz + eSz), seq);
27901
27902
    /* headers */
27903
    if (with_header) {
27904
        algoSz = SetAlgoID(RSAk, algo, oidKeyType, 0);
27905
        bitStringSz = SetBitString(seqSz + (word32)(nSz + eSz), 0, bitString);
27906
        headSz = SetSequence((word32)(nSz + eSz) + seqSz + bitStringSz + algoSz,
27907
                             headSeq);
27908
    }
27909
27910
    /* if getting length only */
27911
    if (output == NULL) {
27912
        return (int)(headSz + algoSz + bitStringSz + seqSz) + nSz + eSz;
27913
    }
27914
27915
    /* check output size */
27916
    if (((int)(headSz + algoSz + bitStringSz + seqSz) + nSz + eSz) > outLen) {
27917
        return BUFFER_E;
27918
    }
27919
27920
    /* write output */
27921
    idx = 0;
27922
    if (with_header) {
27923
        /* header size */
27924
        XMEMCPY(output + idx, headSeq, headSz);
27925
        idx += headSz;
27926
        /* algo */
27927
        XMEMCPY(output + idx, algo, algoSz);
27928
        idx += algoSz;
27929
        /* bit string */
27930
        XMEMCPY(output + idx, bitString, bitStringSz);
27931
        idx += bitStringSz;
27932
    }
27933
27934
    /* seq */
27935
    XMEMCPY(output + idx, seq, seqSz);
27936
    idx += seqSz;
27937
    /* n */
27938
    nSz = SetASNIntMP(&key->n, nSz, output + idx);
27939
    idx += (word32)nSz;
27940
    /* e */
27941
    eSz = SetASNIntMP(&key->e, eSz, output + idx);
27942
    idx += (word32)eSz;
27943
27944
    return (int)idx;
27945
#else
27946
    DECL_ASNSETDATA(dataASN, rsaPublicKeyASN_Length);
27947
    int sz = 0;
27948
    int ret = 0;
27949
    int o = 0;
27950
27951
    /* Check parameter validity. */
27952
    if ((key == NULL) || ((output != NULL) && (outLen < MAX_SEQ_SZ))) {
27953
        ret = BAD_FUNC_ARG;
27954
    }
27955
27956
    CALLOC_ASNSETDATA(dataASN, rsaPublicKeyASN_Length, ret, key->heap);
27957
27958
    if (ret == 0) {
27959
        if (!with_header) {
27960
            /* Start encoding with items after header. */
27961
            o = RSAPUBLICKEYASN_IDX_PUBKEY_RSA_SEQ;
27962
        }
27963
        /* Set OID for RSA key. */
27964
        SetASN_OID(&dataASN[RSAPUBLICKEYASN_IDX_ALGOID_OID], RSAk, oidKeyType);
27965
    #ifdef WC_RSA_PSS
27966
        dataASN[RSAPUBLICKEYASN_IDX_ALGOID_P_SEQ].noOut = 1;
27967
    #endif
27968
        /* Set public key mp_ints. */
27969
        SetASN_MP(&dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_N], &key->n);
27970
        SetASN_MP(&dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_E], &key->e);
27971
        /* Calculate size of RSA public key. */
27972
        ret = SizeASN_Items(rsaPublicKeyASN + o, dataASN + o,
27973
                            (int)rsaPublicKeyASN_Length - o, &sz);
27974
    }
27975
    /* Check output buffer is big enough for encoding. */
27976
    if ((ret == 0) && (output != NULL) && (sz > outLen)) {
27977
        ret = BUFFER_E;
27978
    }
27979
    if ((ret == 0) && (output != NULL)) {
27980
        /* Encode RSA public key. */
27981
        SetASN_Items(rsaPublicKeyASN + o, dataASN + o,
27982
                     (int)rsaPublicKeyASN_Length - o, output);
27983
    }
27984
    if (ret == 0) {
27985
        /* Return size of encoding. */
27986
        ret = sz;
27987
    }
27988
27989
    FREE_ASNSETDATA(dataASN, key->heap);
27990
    return ret;
27991
#endif /* WOLFSSL_ASN_TEMPLATE */
27992
}
27993
27994
/* Calculate size of encoded public RSA key in bytes.
27995
 *
27996
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
27997
 * PKCS #1: RFC 8017, A.1.1 - RSAPublicKey
27998
 *
27999
 * Encoded data can either be SubjectPublicKeyInfo (with header) or just the key
28000
 * (RSAPublicKey).
28001
 *
28002
 * @param [in]  key          RSA key object.
28003
 * @param [in]  with_header  Whether to include SubjectPublicKeyInfo around key.
28004
 * @return  Size of encoded data in bytes on success.
28005
 * @return  BAD_FUNC_ARG when key is NULL.
28006
 * @return  MEMORY_E when dynamic memory allocation failed.
28007
 */
28008
int wc_RsaPublicKeyDerSize(RsaKey* key, int with_header)
28009
{
28010
    return SetRsaPublicKey(NULL, key, 0, with_header);
28011
}
28012
28013
/* Encode public RSA key in DER format.
28014
 *
28015
 * X.509: RFC 5280, 4.1 - SubjectPublicKeyInfo
28016
 * PKCS #1: RFC 8017, A.1.1 - RSAPublicKey
28017
 *
28018
 * @param [in]  key     RSA key object.
28019
 * @param [out] output  Buffer to put encoded data in.
28020
 * @param [in]  inLen   Size of buffer in bytes.
28021
 * @return  Size of encoded data in bytes on success.
28022
 * @return  BAD_FUNC_ARG when key or output is NULL.
28023
 * @return  MEMORY_E when dynamic memory allocation failed.
28024
 */
28025
int wc_RsaKeyToPublicDer(RsaKey* key, byte* output, word32 inLen)
28026
{
28027
    return SetRsaPublicKey(output, key, (int)inLen, 1);
28028
}
28029
28030
/* Returns public DER version of the RSA key. If with_header is 0 then only a
28031
 * seq + n + e is returned in ASN.1 DER format */
28032
int wc_RsaKeyToPublicDer_ex(RsaKey* key, byte* output, word32 inLen,
28033
    int with_header)
28034
{
28035
    return SetRsaPublicKey(output, key, (int)inLen, with_header);
28036
}
28037
28038
#endif /* !NO_RSA && (WOLFSSL_CERT_GEN || WOLFSSL_KCAPI_RSA ||
28039
            ((OPENSSL_EXTRA || WOLFSSL_KEY_GEN))) */
28040
#endif /* NO_CERTS */
28041
28042
#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || \
28043
     defined(WOLFSSL_KCAPI_RSA) || defined(WOLFSSL_SE050)) && \
28044
     !defined(NO_RSA)
28045
28046
/* Encode private RSA key in DER format.
28047
 *
28048
 * PKCS #1: RFC 8017, A.1.2 - RSAPrivateKey
28049
 *
28050
 * @param [in]  key     RSA key object.
28051
 * @param [out] output  Buffer to put encoded data in.
28052
 * @param [in]  inLen   Size of buffer in bytes.
28053
 * @return  Size of encoded data in bytes on success.
28054
 * @return  BAD_FUNC_ARG when key is NULL or not a private key.
28055
 * @return  MEMORY_E when dynamic memory allocation failed.
28056
 */
28057
int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)
28058
{
28059
#ifndef WOLFSSL_ASN_TEMPLATE
28060
    int ret = 0, i;
28061
    int mpSz;
28062
    word32 seqSz = 0, verSz = 0, intTotalLen = 0, outLen = 0;
28063
    byte  seq[MAX_SEQ_SZ];
28064
    byte  ver[MAX_VERSION_SZ];
28065
    mp_int* keyInt;
28066
#ifndef WOLFSSL_NO_MALLOC
28067
    word32 rawLen;
28068
    byte* tmps[RSA_INTS];
28069
    word32 sizes[RSA_INTS];
28070
#endif
28071
28072
    if (key == NULL)
28073
        return BAD_FUNC_ARG;
28074
28075
    if (key->type != RSA_PRIVATE)
28076
        return BAD_FUNC_ARG;
28077
28078
#ifndef WOLFSSL_NO_MALLOC
28079
    for (i = 0; i < RSA_INTS; i++)
28080
        tmps[i] = NULL;
28081
#endif
28082
28083
    /* write all big ints from key to DER tmps */
28084
    for (i = 0; i < RSA_INTS; i++) {
28085
        keyInt = GetRsaInt(key, i);
28086
        ret = mp_unsigned_bin_size(keyInt);
28087
        if (ret < 0)
28088
            break;
28089
#ifndef WOLFSSL_NO_MALLOC
28090
        rawLen = (word32)ret + 1;
28091
        ret = 0;
28092
        if (output != NULL) {
28093
            tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
28094
                                 DYNAMIC_TYPE_RSA);
28095
            if (tmps[i] == NULL) {
28096
                ret = MEMORY_E;
28097
                break;
28098
            }
28099
        }
28100
        mpSz = SetASNIntMP(keyInt, MAX_RSA_INT_SZ, tmps[i]);
28101
#else
28102
        ret = 0;
28103
        mpSz = SetASNIntMP(keyInt, MAX_RSA_INT_SZ, NULL);
28104
#endif
28105
        if (mpSz < 0) {
28106
            ret = mpSz;
28107
            break;
28108
        }
28109
    #ifndef WOLFSSL_NO_MALLOC
28110
        sizes[i] = (word32)mpSz;
28111
    #endif
28112
        intTotalLen += (word32)mpSz;
28113
    }
28114
28115
    if (ret == 0) {
28116
        /* make headers */
28117
        ret = SetMyVersion(0, ver, FALSE);
28118
    }
28119
28120
    if (ret >= 0) {
28121
        verSz = (word32)ret;
28122
        ret = 0;
28123
        seqSz = SetSequence(verSz + intTotalLen, seq);
28124
        outLen = seqSz + verSz + intTotalLen;
28125
        if (output != NULL && outLen > inLen)
28126
            ret = BUFFER_E;
28127
    }
28128
    if (ret == 0 && output != NULL) {
28129
        word32 j;
28130
28131
        /* write to output */
28132
        XMEMCPY(output, seq, seqSz);
28133
        j = seqSz;
28134
        XMEMCPY(output + j, ver, verSz);
28135
        j += verSz;
28136
28137
        for (i = 0; i < RSA_INTS; i++) {
28138
/* copy from tmps if we have malloc, otherwise re-export with buffer */
28139
#ifndef WOLFSSL_NO_MALLOC
28140
            XMEMCPY(output + j, tmps[i], sizes[i]);
28141
            j += sizes[i];
28142
#else
28143
            keyInt = GetRsaInt(key, i);
28144
            ret = mp_unsigned_bin_size(keyInt);
28145
            if (ret < 0)
28146
                break;
28147
            ret = 0;
28148
            /* This won't overrun output due to the outLen check above */
28149
            mpSz = SetASNIntMP(keyInt, MAX_RSA_INT_SZ, output + j);
28150
            if (mpSz < 0) {
28151
                ret = mpSz;
28152
                break;
28153
            }
28154
            j += mpSz;
28155
#endif
28156
        }
28157
    }
28158
28159
#ifndef WOLFSSL_NO_MALLOC
28160
    for (i = 0; i < RSA_INTS; i++) {
28161
        if (tmps[i])
28162
            XFREE(tmps[i], key->heap, DYNAMIC_TYPE_RSA);
28163
    }
28164
#endif
28165
28166
    if (ret == 0)
28167
        ret = (int)outLen;
28168
    return ret;
28169
#else
28170
    DECL_ASNSETDATA(dataASN, rsaKeyASN_Length);
28171
    int i;
28172
    int sz = 0;
28173
    int ret = 0;
28174
28175
    if ((key == NULL) || (key->type != RSA_PRIVATE)) {
28176
        ret = BAD_FUNC_ARG;
28177
    }
28178
28179
    CALLOC_ASNSETDATA(dataASN, rsaKeyASN_Length, ret, key->heap);
28180
28181
    if (ret == 0) {
28182
        /* Set the version. */
28183
        SetASN_Int8Bit(&dataASN[RSAKEYASN_IDX_VER], 0);
28184
        /* Set all the mp_ints in private key. */
28185
        for (i = 0; i < RSA_INTS; i++) {
28186
            SetASN_MP(&dataASN[(byte)RSAKEYASN_IDX_N + i], GetRsaInt(key, i));
28187
        }
28188
28189
        /* Calculate size of RSA private key encoding. */
28190
        ret = SizeASN_Items(rsaKeyASN, dataASN, rsaKeyASN_Length, &sz);
28191
    }
28192
    /* Check output buffer has enough space for encoding. */
28193
    if ((ret == 0) && (output != NULL) && (sz > (int)inLen)) {
28194
        ret = BAD_FUNC_ARG;
28195
    }
28196
    if ((ret == 0) && (output != NULL)) {
28197
        /* Encode RSA private key. */
28198
        SetASN_Items(rsaKeyASN, dataASN, rsaKeyASN_Length, output);
28199
    }
28200
28201
    if (ret == 0) {
28202
        /* Return size of encoding. */
28203
        ret = sz;
28204
    }
28205
28206
    FREE_ASNSETDATA(dataASN, key->heap);
28207
    return ret;
28208
#endif
28209
}
28210
28211
#endif /* (WOLFSSL_KEY_GEN || OPENSSL_EXTRA) && !NO_RSA */
28212
28213
#ifndef NO_CERTS
28214
28215
#ifdef WOLFSSL_CERT_GEN
28216
28217
/* Initialize and Set Certificate defaults:
28218
   version    = 3 (0x2)
28219
   serial     = 0
28220
   sigType    = SHA_WITH_RSA
28221
   issuer     = blank
28222
   daysValid  = 500
28223
   selfSigned = 1 (true) use subject as issuer
28224
   subject    = blank
28225
*/
28226
int wc_InitCert_ex(Cert* cert, void* heap, int devId)
28227
{
28228
#ifdef WOLFSSL_MULTI_ATTRIB
28229
    int i = 0;
28230
#endif
28231
    if (cert == NULL) {
28232
        return BAD_FUNC_ARG;
28233
    }
28234
28235
    XMEMSET(cert, 0, sizeof(Cert));
28236
28237
    cert->version    = 2;   /* version 3 is hex 2 */
28238
#ifndef NO_SHA
28239
    cert->sigType    = CTC_SHAwRSA;
28240
#elif !defined(NO_SHA256)
28241
    cert->sigType    = CTC_SHA256wRSA;
28242
#else
28243
    cert->sigType    = 0;
28244
#endif
28245
    cert->daysValid  = 500;
28246
    cert->selfSigned = 1;
28247
    cert->keyType    = RSA_KEY;
28248
28249
    cert->issuer.countryEnc = CTC_PRINTABLE;
28250
    cert->issuer.stateEnc = CTC_UTF8;
28251
    cert->issuer.streetEnc = CTC_UTF8;
28252
    cert->issuer.localityEnc = CTC_UTF8;
28253
    cert->issuer.surEnc = CTC_UTF8;
28254
#ifdef WOLFSSL_CERT_NAME_ALL
28255
    cert->issuer.givenNameEnc = CTC_UTF8;
28256
    cert->issuer.initialsEnc = CTC_UTF8;
28257
    cert->issuer.dnQualifierEnc = CTC_UTF8;
28258
    cert->issuer.dnNameEnc = CTC_UTF8;
28259
#endif
28260
    cert->issuer.orgEnc = CTC_UTF8;
28261
    cert->issuer.unitEnc = CTC_UTF8;
28262
    cert->issuer.commonNameEnc = CTC_UTF8;
28263
    cert->issuer.serialDevEnc = CTC_PRINTABLE;
28264
    cert->issuer.userIdEnc = CTC_UTF8;
28265
    cert->issuer.postalCodeEnc = CTC_UTF8;
28266
#ifdef WOLFSSL_CERT_EXT
28267
    cert->issuer.busCatEnc = CTC_UTF8;
28268
    cert->issuer.joiCEnc = CTC_UTF8;
28269
    cert->issuer.joiStEnc = CTC_UTF8;
28270
#endif
28271
28272
    cert->subject.countryEnc = CTC_PRINTABLE;
28273
    cert->subject.stateEnc = CTC_UTF8;
28274
    cert->subject.streetEnc = CTC_UTF8;
28275
    cert->subject.localityEnc = CTC_UTF8;
28276
    cert->subject.surEnc = CTC_UTF8;
28277
#ifdef WOLFSSL_CERT_NAME_ALL
28278
    cert->subject.givenNameEnc = CTC_UTF8;
28279
    cert->subject.initialsEnc = CTC_UTF8;
28280
    cert->subject.dnQualifierEnc = CTC_UTF8;
28281
    cert->subject.dnNameEnc = CTC_UTF8;
28282
#endif
28283
    cert->subject.orgEnc = CTC_UTF8;
28284
    cert->subject.unitEnc = CTC_UTF8;
28285
    cert->subject.commonNameEnc = CTC_UTF8;
28286
    cert->subject.serialDevEnc = CTC_PRINTABLE;
28287
    cert->subject.userIdEnc = CTC_UTF8;
28288
    cert->subject.postalCodeEnc = CTC_UTF8;
28289
#ifdef WOLFSSL_CERT_EXT
28290
    cert->subject.busCatEnc = CTC_UTF8;
28291
    cert->subject.joiCEnc = CTC_UTF8;
28292
    cert->subject.joiStEnc = CTC_UTF8;
28293
#endif
28294
28295
#ifdef WOLFSSL_MULTI_ATTRIB
28296
    for (i = 0; i < CTC_MAX_ATTRIB; i++) {
28297
        cert->issuer.name[i].type   = CTC_UTF8;
28298
        cert->subject.name[i].type  = CTC_UTF8;
28299
    }
28300
#endif /* WOLFSSL_MULTI_ATTRIB */
28301
28302
    cert->heap = heap;
28303
    (void)devId; /* future */
28304
28305
    return 0;
28306
}
28307
28308
WOLFSSL_ABI
28309
int wc_InitCert(Cert* cert)
28310
{
28311
    return wc_InitCert_ex(cert, NULL, INVALID_DEVID);
28312
}
28313
28314
WOLFSSL_ABI
28315
Cert* wc_CertNew(void* heap)
28316
{
28317
    Cert* certNew;
28318
28319
    certNew = (Cert*)XMALLOC(sizeof(Cert), heap, DYNAMIC_TYPE_CERT);
28320
28321
    if (certNew) {
28322
        if (wc_InitCert_ex(certNew, heap, INVALID_DEVID) != 0) {
28323
            XFREE(certNew, heap, DYNAMIC_TYPE_CERT);
28324
            certNew = NULL;
28325
        }
28326
    }
28327
28328
    return certNew;
28329
}
28330
28331
WOLFSSL_ABI
28332
void  wc_CertFree(Cert* cert)
28333
{
28334
    if (cert) {
28335
         void* heap = cert->heap;
28336
28337
         ForceZero(cert, sizeof(Cert));
28338
         XFREE(cert, heap, DYNAMIC_TYPE_CERT);
28339
         (void)heap;
28340
     }
28341
}
28342
28343
/* DER encoded x509 Certificate */
28344
typedef struct DerCert {
28345
    byte size[MAX_LENGTH_SZ];          /* length encoded */
28346
    byte version[MAX_VERSION_SZ];      /* version encoded */
28347
    byte serial[(int)CTC_SERIAL_SIZE + (int)MAX_LENGTH_SZ]; /* serial number encoded */
28348
    byte sigAlgo[MAX_ALGO_SZ];         /* signature algo encoded */
28349
    byte issuer[WC_ASN_NAME_MAX];         /* issuer  encoded */
28350
    byte subject[WC_ASN_NAME_MAX];        /* subject encoded */
28351
    byte validity[MAX_DATE_SIZE*2 + MAX_SEQ_SZ*2];  /* before and after dates */
28352
    byte publicKey[MAX_PUBLIC_KEY_SZ]; /* rsa public key encoded */
28353
    byte ca[MAX_CA_SZ];                /* basic constraint CA true size */
28354
    byte extensions[MAX_EXTENSIONS_SZ]; /* all extensions */
28355
#ifdef WOLFSSL_CERT_EXT
28356
    byte skid[MAX_KID_SZ];             /* Subject Key Identifier extension */
28357
    byte akid[MAX_KID_SZ
28358
#ifdef WOLFSSL_AKID_NAME
28359
              + sizeof(CertName) + CTC_SERIAL_SIZE
28360
#endif
28361
              ]; /* Authority Key Identifier extension */
28362
    byte keyUsage[MAX_KEYUSAGE_SZ];    /* Key Usage extension */
28363
    byte extKeyUsage[MAX_EXTKEYUSAGE_SZ]; /* Extended Key Usage extension */
28364
#ifndef IGNORE_NETSCAPE_CERT_TYPE
28365
    byte nsCertType[MAX_NSCERTTYPE_SZ]; /* Extended Key Usage extension */
28366
#endif
28367
    byte certPolicies[MAX_CERTPOL_NB*MAX_CERTPOL_SZ]; /* Certificate Policies */
28368
    byte crlInfo[CTC_MAX_CRLINFO_SZ];  /* CRL Distribution Points */
28369
#endif
28370
#ifdef WOLFSSL_CERT_REQ
28371
    byte attrib[MAX_ATTRIB_SZ];        /* Cert req attributes encoded */
28372
    #ifdef WOLFSSL_CUSTOM_OID
28373
    byte extCustom[MAX_ATTRIB_SZ];     /* Encoded user oid and value */
28374
    #endif
28375
#endif
28376
#ifdef WOLFSSL_ALT_NAMES
28377
    byte altNames[CTC_MAX_ALT_SIZE];   /* Alternative Names encoded */
28378
#endif
28379
    int  sizeSz;                       /* encoded size length */
28380
    int  versionSz;                    /* encoded version length */
28381
    int  serialSz;                     /* encoded serial length */
28382
    int  sigAlgoSz;                    /* encoded sig algo length */
28383
    int  issuerSz;                     /* encoded issuer length */
28384
    int  subjectSz;                    /* encoded subject length */
28385
    int  validitySz;                   /* encoded validity length */
28386
    int  publicKeySz;                  /* encoded public key length */
28387
    int  caSz;                         /* encoded CA extension length */
28388
#ifdef WOLFSSL_CERT_EXT
28389
    int  skidSz;                       /* encoded SKID extension length */
28390
    int  akidSz;                       /* encoded SKID extension length */
28391
    int  keyUsageSz;                   /* encoded KeyUsage extension length */
28392
    int  extKeyUsageSz;                /* encoded ExtendedKeyUsage extension length */
28393
#ifndef IGNORE_NETSCAPE_CERT_TYPE
28394
    int  nsCertTypeSz;                 /* encoded Netscape Certificate Type
28395
                                        * extension length */
28396
#endif
28397
    int  certPoliciesSz;               /* encoded CertPolicies extension length*/
28398
    int  crlInfoSz;                    /* encoded CRL Dist Points length */
28399
#endif
28400
#ifdef WOLFSSL_ALT_NAMES
28401
    int  altNamesSz;                   /* encoded AltNames extension length */
28402
#endif
28403
    int  extensionsSz;                 /* encoded extensions total length */
28404
    int  total;                        /* total encoded lengths */
28405
#ifdef WOLFSSL_CERT_REQ
28406
    int  attribSz;
28407
    #ifdef WOLFSSL_CUSTOM_OID
28408
    int  extCustomSz;
28409
    #endif
28410
#endif
28411
} DerCert;
28412
28413
28414
#ifdef WOLFSSL_CERT_REQ
28415
#ifndef WOLFSSL_ASN_TEMPLATE
28416
28417
/* Write a set header to output */
28418
static word32 SetPrintableString(word32 len, byte* output)
28419
{
28420
    output[0] = ASN_PRINTABLE_STRING;
28421
    return SetLength(len, output + 1) + 1;
28422
}
28423
28424
static word32 SetUTF8String(word32 len, byte* output)
28425
{
28426
    output[0] = ASN_UTF8STRING;
28427
    return SetLength(len, output + 1) + 1;
28428
}
28429
28430
#endif
28431
#endif /* WOLFSSL_CERT_REQ */
28432
28433
28434
#ifndef WOLFSSL_CERT_GEN_CACHE
28435
/* wc_SetCert_Free is only public when WOLFSSL_CERT_GEN_CACHE is not defined */
28436
static
28437
#endif
28438
WOLFSSL_ABI
28439
void wc_SetCert_Free(Cert* cert)
28440
{
28441
    if (cert != NULL) {
28442
        cert->der = NULL;
28443
        if (cert->decodedCert) {
28444
            FreeDecodedCert((DecodedCert*)cert->decodedCert);
28445
28446
            XFREE(cert->decodedCert, cert->heap, DYNAMIC_TYPE_DCERT);
28447
            cert->decodedCert = NULL;
28448
        }
28449
    }
28450
}
28451
28452
static int wc_SetCert_LoadDer(Cert* cert, const byte* der, word32 derSz,
28453
    int devId)
28454
{
28455
    int ret;
28456
28457
    if (cert == NULL) {
28458
        ret = BAD_FUNC_ARG;
28459
    }
28460
    else {
28461
        /* Allocate DecodedCert struct and Zero */
28462
        cert->decodedCert = (void*)XMALLOC(sizeof(DecodedCert), cert->heap,
28463
            DYNAMIC_TYPE_DCERT);
28464
28465
        if (cert->decodedCert == NULL) {
28466
            ret = MEMORY_E;
28467
        }
28468
        else {
28469
            XMEMSET(cert->decodedCert, 0, sizeof(DecodedCert));
28470
28471
            InitDecodedCert_ex((DecodedCert*)cert->decodedCert, der, derSz,
28472
                    cert->heap, devId);
28473
            ret = ParseCertRelative((DecodedCert*)cert->decodedCert,
28474
                    CERT_TYPE, 0, NULL, NULL);
28475
            if (ret >= 0) {
28476
                cert->der = (byte*)der;
28477
            }
28478
            else {
28479
                wc_SetCert_Free(cert);
28480
            }
28481
        }
28482
    }
28483
28484
    return ret;
28485
}
28486
28487
#endif /* WOLFSSL_CERT_GEN */
28488
28489
#ifdef WOLFSSL_CERT_GEN
28490
28491
#ifndef NO_ASN_TIME
28492
static WC_INLINE byte itob(int number)
28493
{
28494
    return (byte)(number + 0x30);
28495
}
28496
28497
28498
/* write time to output, format */
28499
static void SetTime(struct tm* date, byte* output)
28500
{
28501
    int i = 0;
28502
28503
    output[i++] = itob((date->tm_year % 10000) / 1000);
28504
    output[i++] = itob((date->tm_year % 1000)  /  100);
28505
    output[i++] = itob((date->tm_year % 100)   /   10);
28506
    output[i++] = itob( date->tm_year % 10);
28507
28508
    output[i++] = itob(date->tm_mon / 10);
28509
    output[i++] = itob(date->tm_mon % 10);
28510
28511
    output[i++] = itob(date->tm_mday / 10);
28512
    output[i++] = itob(date->tm_mday % 10);
28513
28514
    output[i++] = itob(date->tm_hour / 10);
28515
    output[i++] = itob(date->tm_hour % 10);
28516
28517
    output[i++] = itob(date->tm_min / 10);
28518
    output[i++] = itob(date->tm_min % 10);
28519
28520
    output[i++] = itob(date->tm_sec / 10);
28521
    output[i++] = itob(date->tm_sec % 10);
28522
28523
    output[i] = 'Z';  /* Zulu profile */
28524
}
28525
#endif
28526
28527
#ifndef WOLFSSL_ASN_TEMPLATE
28528
28529
/* Copy Dates from cert, return bytes written */
28530
static int CopyValidity(byte* output, Cert* cert)
28531
{
28532
    word32 seqSz;
28533
28534
    WOLFSSL_ENTER("CopyValidity");
28535
28536
    /* headers and output */
28537
    seqSz = SetSequence((word32)(cert->beforeDateSz + cert->afterDateSz),
28538
                        output);
28539
    if (output) {
28540
        XMEMCPY(output + seqSz, cert->beforeDate, (size_t)cert->beforeDateSz);
28541
        XMEMCPY(output + seqSz + cert->beforeDateSz, cert->afterDate,
28542
                (size_t)cert->afterDateSz);
28543
    }
28544
    return (int)seqSz + cert->beforeDateSz + cert->afterDateSz;
28545
}
28546
28547
#endif /* !WOLFSSL_ASN_TEMPLATE */
28548
28549
28550
/* Simple name OID size. */
28551
#define NAME_OID_SZ     3
28552
28553
/* Domain name OIDs. */
28554
static const byte nameOid[][NAME_OID_SZ] = {
28555
    { 0x55, 0x04, ASN_COUNTRY_NAME },
28556
    { 0x55, 0x04, ASN_STATE_NAME },
28557
    { 0x55, 0x04, ASN_STREET_ADDR },
28558
    { 0x55, 0x04, ASN_LOCALITY_NAME },
28559
#ifdef WOLFSSL_CERT_NAME_ALL
28560
    { 0x55, 0x04, ASN_NAME },
28561
    { 0x55, 0x04, ASN_GIVEN_NAME },
28562
    { 0x55, 0x04, ASN_INITIALS },
28563
    { 0x55, 0x04, ASN_DNQUALIFIER },
28564
#endif
28565
    { 0x55, 0x04, ASN_SUR_NAME },
28566
    { 0x55, 0x04, ASN_ORG_NAME },
28567
    { 0x00, 0x00, ASN_DOMAIN_COMPONENT}, /* not actual OID - see dcOid */
28568
                                         /* list all DC values before OUs */
28569
    { 0x55, 0x04, ASN_ORGUNIT_NAME },
28570
    { 0x55, 0x04, ASN_COMMON_NAME },
28571
    { 0x55, 0x04, ASN_SERIAL_NUMBER },
28572
#ifdef WOLFSSL_CERT_EXT
28573
    { 0x55, 0x04, ASN_BUS_CAT },
28574
#endif
28575
    { 0x55, 0x04, ASN_POSTAL_CODE },
28576
    { 0x00, 0x00, ASN_EMAIL_NAME},       /* not actual OID - see attrEmailOid */
28577
    { 0x00, 0x00, ASN_USER_ID},          /* not actual OID - see uidOid */
28578
#ifdef WOLFSSL_CUSTOM_OID
28579
    { 0x00, 0x00, ASN_CUSTOM_NAME} /* OID comes from CertOidField */
28580
#endif
28581
};
28582
#define NAME_ENTRIES (int)(sizeof(nameOid)/NAME_OID_SZ)
28583
28584
28585
/* Get ASN Name from index */
28586
byte GetCertNameId(int idx)
28587
{
28588
    if (idx < NAME_ENTRIES)
28589
        return nameOid[idx][2];
28590
    return 0;
28591
}
28592
28593
/* Get Which Name from index */
28594
const char* GetOneCertName(CertName* name, int idx)
28595
{
28596
    byte type = GetCertNameId(idx);
28597
    switch (type) {
28598
    case ASN_COUNTRY_NAME:
28599
       return name->country;
28600
    case ASN_STATE_NAME:
28601
       return name->state;
28602
    case ASN_STREET_ADDR:
28603
       return name->street;
28604
    case ASN_LOCALITY_NAME:
28605
       return name->locality;
28606
#ifdef WOLFSSL_CERT_NAME_ALL
28607
    case ASN_NAME:
28608
       return name->dnName;
28609
    case ASN_GIVEN_NAME:
28610
       return name->givenName;
28611
    case ASN_INITIALS:
28612
       return name->initials;
28613
    case ASN_DNQUALIFIER:
28614
       return name->dnQualifier;
28615
#endif /* WOLFSSL_CERT_NAME_ALL */
28616
    case ASN_SUR_NAME:
28617
       return name->sur;
28618
    case ASN_ORG_NAME:
28619
       return name->org;
28620
    case ASN_ORGUNIT_NAME:
28621
       return name->unit;
28622
    case ASN_COMMON_NAME:
28623
       return name->commonName;
28624
    case ASN_SERIAL_NUMBER:
28625
       return name->serialDev;
28626
    case ASN_USER_ID:
28627
       return name->userId;
28628
    case ASN_POSTAL_CODE:
28629
       return name->postalCode;
28630
    case ASN_EMAIL_NAME:
28631
       return name->email;
28632
#ifdef WOLFSSL_CERT_EXT
28633
    case ASN_BUS_CAT:
28634
       return name->busCat;
28635
#endif
28636
#ifdef WOLFSSL_CUSTOM_OID
28637
    case ASN_CUSTOM_NAME:
28638
        return (const char*)name->custom.val;
28639
#endif
28640
    default:
28641
       return NULL;
28642
    }
28643
}
28644
28645
28646
/* Get Which Name Encoding from index */
28647
static char GetNameType(CertName* name, int idx)
28648
{
28649
    byte type = GetCertNameId(idx);
28650
    switch (type) {
28651
    case ASN_COUNTRY_NAME:
28652
       return name->countryEnc;
28653
    case ASN_STATE_NAME:
28654
       return name->stateEnc;
28655
    case ASN_STREET_ADDR:
28656
       return name->streetEnc;
28657
    case ASN_LOCALITY_NAME:
28658
       return name->localityEnc;
28659
#ifdef WOLFSSL_CERT_NAME_ALL
28660
    case ASN_NAME:
28661
       return name->dnNameEnc;
28662
    case ASN_GIVEN_NAME:
28663
       return name->givenNameEnc;
28664
    case ASN_INITIALS:
28665
       return name->initialsEnc;
28666
    case ASN_DNQUALIFIER:
28667
       return name->dnQualifierEnc;
28668
#endif /* WOLFSSL_CERT_NAME_ALL */
28669
    case ASN_SUR_NAME:
28670
       return name->surEnc;
28671
    case ASN_ORG_NAME:
28672
       return name->orgEnc;
28673
    case ASN_ORGUNIT_NAME:
28674
       return name->unitEnc;
28675
    case ASN_COMMON_NAME:
28676
       return name->commonNameEnc;
28677
    case ASN_SERIAL_NUMBER:
28678
       return name->serialDevEnc;
28679
    case ASN_USER_ID:
28680
       return name->userIdEnc;
28681
    case ASN_POSTAL_CODE:
28682
       return name->postalCodeEnc;
28683
    case ASN_EMAIL_NAME:
28684
       return 0; /* special */
28685
#ifdef WOLFSSL_CERT_EXT
28686
    case ASN_BUS_CAT:
28687
       return name->busCatEnc;
28688
#endif
28689
#ifdef WOLFSSL_CUSTOM_OID
28690
    case ASN_CUSTOM_NAME:
28691
        return name->custom.enc;
28692
#endif
28693
    default:
28694
       return 0;
28695
    }
28696
}
28697
28698
#ifndef WOLFSSL_ASN_TEMPLATE
28699
/*
28700
 Extensions ::= SEQUENCE OF Extension
28701
28702
 Extension ::= SEQUENCE {
28703
 extnId     OBJECT IDENTIFIER,
28704
 critical   BOOLEAN DEFAULT FALSE,
28705
 extnValue  OCTET STRING }
28706
 */
28707
28708
/* encode all extensions, return total bytes written */
28709
static int SetExtensions(byte* out, word32 outSz, int *IdxInOut,
28710
                         const byte* ext, int extSz)
28711
{
28712
    if (out == NULL || IdxInOut == NULL || ext == NULL)
28713
        return BAD_FUNC_ARG;
28714
28715
    if (outSz < (word32)(*IdxInOut+extSz))
28716
        return BUFFER_E;
28717
28718
    XMEMCPY(&out[*IdxInOut], ext, (size_t)extSz);  /* extensions */
28719
    *IdxInOut += extSz;
28720
28721
    return *IdxInOut;
28722
}
28723
28724
/* encode extensions header, return total bytes written */
28725
static int SetExtensionsHeader(byte* out, word32 outSz, word32 extSz)
28726
{
28727
    byte sequence[MAX_SEQ_SZ];
28728
    byte len[MAX_LENGTH_SZ];
28729
    word32 seqSz, lenSz, idx = 0;
28730
28731
    if (out == NULL)
28732
        return BAD_FUNC_ARG;
28733
28734
    if (outSz < 3)
28735
        return BUFFER_E;
28736
28737
    seqSz = SetSequence(extSz, sequence);
28738
28739
    /* encode extensions length provided */
28740
    lenSz = SetLength(extSz+seqSz, len);
28741
28742
    if (outSz < (word32)(lenSz+seqSz+1))
28743
        return BUFFER_E;
28744
28745
    out[idx++] = ASN_EXTENSIONS; /* extensions id */
28746
    XMEMCPY(&out[idx], len, lenSz);  /* length */
28747
    idx += lenSz;
28748
28749
    XMEMCPY(&out[idx], sequence, seqSz);  /* sequence */
28750
    idx += seqSz;
28751
28752
    return (int)idx;
28753
}
28754
28755
28756
/* encode CA basic constraints true with path length
28757
 * return total bytes written */
28758
static int SetCaWithPathLen(byte* out, word32 outSz, byte pathLen)
28759
{
28760
    /* ASN1->DER sequence for Basic Constraints True and path length */
28761
    const byte caPathLenBasicConstASN1[] = {
28762
        0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x04,
28763
        0x08, 0x30, 0x06, 0x01, 0x01, 0xFF, 0x02, 0x01,
28764
        0x00
28765
    };
28766
28767
    if (out == NULL)
28768
        return BAD_FUNC_ARG;
28769
28770
    if (outSz < sizeof(caPathLenBasicConstASN1))
28771
        return BUFFER_E;
28772
28773
    XMEMCPY(out, caPathLenBasicConstASN1, sizeof(caPathLenBasicConstASN1));
28774
28775
    out[sizeof(caPathLenBasicConstASN1)-1] = pathLen;
28776
28777
    return (int)sizeof(caPathLenBasicConstASN1);
28778
}
28779
28780
/* encode CA basic constraints
28781
 * return total bytes written */
28782
static int SetCaEx(byte* out, word32 outSz, byte isCa)
28783
{
28784
    /* ASN1->DER sequence for Basic Constraints True */
28785
    const byte caBasicConstASN1[] = {
28786
        0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,
28787
        0x05, 0x30, 0x03, 0x01, 0x01, 0xff
28788
    };
28789
28790
    if (out == NULL)
28791
        return BAD_FUNC_ARG;
28792
28793
    if (outSz < sizeof(caBasicConstASN1))
28794
        return BUFFER_E;
28795
28796
    XMEMCPY(out, caBasicConstASN1, sizeof(caBasicConstASN1));
28797
28798
    if (!isCa) {
28799
        out[sizeof(caBasicConstASN1)-1] = isCa;
28800
    }
28801
28802
    return (int)sizeof(caBasicConstASN1);
28803
}
28804
28805
/* encode CA basic constraints true
28806
 * return total bytes written */
28807
static int SetCa(byte* out, word32 outSz)
28808
{
28809
    return SetCaEx(out, outSz, 1);
28810
}
28811
28812
/* encode basic constraints without CA Boolean
28813
 * return total bytes written */
28814
static int SetBC(byte* out, word32 outSz)
28815
{
28816
    /* ASN1->DER sequence for Basic Constraint without CA Boolean */
28817
 const byte BasicConstASN1[] = {
28818
        0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,
28819
        0x02, 0x30, 0x00
28820
    };
28821
28822
    if (out == NULL)
28823
        return BAD_FUNC_ARG;
28824
28825
    if (outSz < sizeof(BasicConstASN1))
28826
        return BUFFER_E;
28827
28828
    XMEMCPY(out, BasicConstASN1, sizeof(BasicConstASN1));
28829
28830
    return (int)sizeof(BasicConstASN1);
28831
}
28832
#endif
28833
28834
28835
#ifdef WOLFSSL_CERT_EXT
28836
#ifndef WOLFSSL_ASN_TEMPLATE
28837
/* encode OID and associated value, return total bytes written */
28838
static int SetOidValue(byte* out, word32 outSz, const byte *oid, word32 oidSz,
28839
                       byte *in, word32 inSz)
28840
{
28841
    word32 idx = 0;
28842
28843
    if (out == NULL || oid == NULL || in == NULL)
28844
        return BAD_FUNC_ARG;
28845
28846
    if (outSz < 3)
28847
        return BUFFER_E;
28848
28849
    /* sequence,  + 1 => byte to put value size */
28850
    idx = SetSequence(inSz + oidSz + 1, out);
28851
28852
    if ((idx + inSz + oidSz + 1) > outSz)
28853
        return BUFFER_E;
28854
28855
    XMEMCPY(out+idx, oid, oidSz);
28856
    idx += oidSz;
28857
    out[idx++] = (byte)inSz;
28858
    XMEMCPY(out+idx, in, inSz);
28859
28860
    return (int)(idx+inSz);
28861
}
28862
28863
/* encode Subject Key Identifier, return total bytes written
28864
 * RFC5280 : non-critical */
28865
static int SetSKID(byte* output, word32 outSz, const byte *input, word32 length)
28866
{
28867
    byte skid_len[1 + MAX_LENGTH_SZ];
28868
    byte skid_enc_len[MAX_LENGTH_SZ];
28869
    word32 idx = 0, skid_lenSz, skid_enc_lenSz;
28870
    const byte skid_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04 };
28871
28872
    if (output == NULL || input == NULL)
28873
        return BAD_FUNC_ARG;
28874
28875
    /* Octet String header */
28876
    skid_lenSz = SetOctetString(length, skid_len);
28877
28878
    /* length of encoded value */
28879
    skid_enc_lenSz = SetLength(length + skid_lenSz, skid_enc_len);
28880
28881
    if (outSz < 3)
28882
        return BUFFER_E;
28883
28884
    idx = SetSequence(length + (word32)sizeof(skid_oid) + skid_lenSz +
28885
                      skid_enc_lenSz, output);
28886
28887
    if ((length + sizeof(skid_oid) + skid_lenSz + skid_enc_lenSz) > outSz)
28888
        return BUFFER_E;
28889
28890
    /* put oid */
28891
    XMEMCPY(output+idx, skid_oid, sizeof(skid_oid));
28892
    idx += sizeof(skid_oid);
28893
28894
    /* put encoded len */
28895
    XMEMCPY(output+idx, skid_enc_len, skid_enc_lenSz);
28896
    idx += skid_enc_lenSz;
28897
28898
    /* put octet header */
28899
    XMEMCPY(output+idx, skid_len, skid_lenSz);
28900
    idx += skid_lenSz;
28901
28902
    /* put value */
28903
    XMEMCPY(output+idx, input, length);
28904
    idx += length;
28905
28906
    return (int)idx;
28907
}
28908
28909
/* encode Authority Key Identifier, return total bytes written
28910
 * RFC5280 : non-critical */
28911
static int SetAKID(byte* output, word32 outSz, byte *input, word32 length,
28912
                   byte rawAkid)
28913
{
28914
    int     enc_valSz;
28915
    byte enc_val_buf[MAX_KID_SZ];
28916
    byte* enc_val;
28917
    const byte akid_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x23 };
28918
    const byte akid_cs[] = { 0x80 };
28919
    word32 inSeqSz, idx;
28920
28921
    (void)rawAkid;
28922
28923
    if (output == NULL || input == NULL)
28924
        return BAD_FUNC_ARG;
28925
28926
#ifdef WOLFSSL_AKID_NAME
28927
    if (rawAkid) {
28928
        enc_val = input;
28929
        enc_valSz = length;
28930
    }
28931
    else
28932
#endif
28933
    {
28934
        enc_val = enc_val_buf;
28935
        enc_valSz = (int)length + 3 + (int)sizeof(akid_cs);
28936
        if (enc_valSz > (int)sizeof(enc_val_buf))
28937
            return BAD_FUNC_ARG;
28938
28939
        /* sequence for ContentSpec & value */
28940
        enc_valSz = SetOidValue(enc_val, (word32)enc_valSz, akid_cs,
28941
                                sizeof(akid_cs), input, length);
28942
        if (enc_valSz <= 0)
28943
            return enc_valSz;
28944
    }
28945
28946
    /* The size of the extension sequence contents */
28947
    inSeqSz = (word32)sizeof(akid_oid) +
28948
        SetOctetString((word32)enc_valSz, NULL) + (word32)enc_valSz;
28949
28950
    if (SetSequence(inSeqSz, NULL) + inSeqSz > outSz)
28951
        return BAD_FUNC_ARG;
28952
28953
    /* Write out the sequence header */
28954
    idx = SetSequence(inSeqSz, output);
28955
28956
    /* Write out OID */
28957
    XMEMCPY(output + idx, akid_oid, sizeof(akid_oid));
28958
    idx += sizeof(akid_oid);
28959
28960
    /* Write out AKID */
28961
    idx += SetOctetString((word32)enc_valSz, output + idx);
28962
    XMEMCPY(output + idx, enc_val, (size_t)enc_valSz);
28963
28964
    return (int)idx + enc_valSz;
28965
}
28966
28967
/* encode Key Usage, return total bytes written
28968
 * RFC5280 : critical */
28969
static int SetKeyUsage(byte* output, word32 outSz, word16 input)
28970
{
28971
    byte ku[5];
28972
    word32 idx;
28973
    const byte keyusage_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x0f,
28974
                                         0x01, 0x01, 0xff, 0x04};
28975
    if (output == NULL)
28976
        return BAD_FUNC_ARG;
28977
28978
    idx = SetBitString16Bit(input, ku);
28979
    return SetOidValue(output, outSz, keyusage_oid, sizeof(keyusage_oid),
28980
                       ku, idx);
28981
}
28982
28983
static int SetOjectIdValue(byte* output, word32 outSz, word32* idx,
28984
    const byte* oid, word32 oidSz)
28985
{
28986
    /* verify room */
28987
    if (*idx + 2 + oidSz >= outSz)
28988
        return ASN_PARSE_E;
28989
28990
    *idx += (word32)SetObjectId((int)oidSz, &output[*idx]);
28991
    XMEMCPY(&output[*idx], oid, oidSz);
28992
    *idx += oidSz;
28993
28994
    return 0;
28995
}
28996
#endif
28997
28998
#ifdef WOLFSSL_ASN_TEMPLATE
28999
/* ASN.1 template for extended key usage.
29000
 * X.509: RFC 5280, 4.2.12 - Extended Key Usage
29001
 * Dynamic creation of template for encoding.
29002
 */
29003
static const ASNItem ekuASN[] = {
29004
/* SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 },
29005
/* OID */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
29006
};
29007
enum {
29008
    EKUASN_IDX_SEQ = 0,
29009
    EKUASN_IDX_OID
29010
};
29011
29012
/* OIDs corresponding to extended key usage. */
29013
struct {
29014
    const byte* oid;
29015
    word32 oidSz;
29016
} ekuOid[] = {
29017
    { extExtKeyUsageServerAuthOid,   sizeof(extExtKeyUsageServerAuthOid) },
29018
    { extExtKeyUsageClientAuthOid,   sizeof(extExtKeyUsageClientAuthOid) },
29019
    { extExtKeyUsageCodeSigningOid,  sizeof(extExtKeyUsageCodeSigningOid) },
29020
    { extExtKeyUsageEmailProtectOid, sizeof(extExtKeyUsageEmailProtectOid) },
29021
    { extExtKeyUsageTimestampOid,    sizeof(extExtKeyUsageTimestampOid) },
29022
    { extExtKeyUsageOcspSignOid,     sizeof(extExtKeyUsageOcspSignOid) },
29023
};
29024
29025
#define EKU_OID_LO      1
29026
#define EKU_OID_HI      6
29027
#endif /* WOLFSSL_ASN_TEMPLATE */
29028
29029
/* encode Extended Key Usage (RFC 5280 4.2.1.12), return total bytes written */
29030
static int SetExtKeyUsage(Cert* cert, byte* output, word32 outSz, byte input)
29031
{
29032
#ifndef WOLFSSL_ASN_TEMPLATE
29033
    word32 idx = 0, oidListSz = 0, totalSz;
29034
    int ret = 0;
29035
    const byte extkeyusage_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x25 };
29036
29037
    if (output == NULL)
29038
        return BAD_FUNC_ARG;
29039
29040
    /* Skip to OID List */
29041
    totalSz = 2 + sizeof(extkeyusage_oid) + 4;
29042
    idx = totalSz;
29043
29044
    /* Build OID List */
29045
    /* If any set, then just use it */
29046
    if (input & EXTKEYUSE_ANY) {
29047
        ret |= SetOjectIdValue(output, outSz, &idx,
29048
            extExtKeyUsageAnyOid, sizeof(extExtKeyUsageAnyOid));
29049
    }
29050
    else {
29051
        if (input & EXTKEYUSE_SERVER_AUTH)
29052
            ret |= SetOjectIdValue(output, outSz, &idx,
29053
                extExtKeyUsageServerAuthOid, sizeof(extExtKeyUsageServerAuthOid));
29054
        if (input & EXTKEYUSE_CLIENT_AUTH)
29055
            ret |= SetOjectIdValue(output, outSz, &idx,
29056
                extExtKeyUsageClientAuthOid, sizeof(extExtKeyUsageClientAuthOid));
29057
        if (input & EXTKEYUSE_CODESIGN)
29058
            ret |= SetOjectIdValue(output, outSz, &idx,
29059
                extExtKeyUsageCodeSigningOid, sizeof(extExtKeyUsageCodeSigningOid));
29060
        if (input & EXTKEYUSE_EMAILPROT)
29061
            ret |= SetOjectIdValue(output, outSz, &idx,
29062
                extExtKeyUsageEmailProtectOid, sizeof(extExtKeyUsageEmailProtectOid));
29063
        if (input & EXTKEYUSE_TIMESTAMP)
29064
            ret |= SetOjectIdValue(output, outSz, &idx,
29065
                extExtKeyUsageTimestampOid, sizeof(extExtKeyUsageTimestampOid));
29066
        if (input & EXTKEYUSE_OCSP_SIGN)
29067
            ret |= SetOjectIdValue(output, outSz, &idx,
29068
                extExtKeyUsageOcspSignOid, sizeof(extExtKeyUsageOcspSignOid));
29069
    #ifdef WOLFSSL_EKU_OID
29070
        /* iterate through OID values */
29071
        if (input & EXTKEYUSE_USER) {
29072
            int i, sz;
29073
            for (i = 0; i < CTC_MAX_EKU_NB; i++) {
29074
                sz = cert->extKeyUsageOIDSz[i];
29075
                if (sz > 0) {
29076
                    ret |= SetOjectIdValue(output, outSz, &idx,
29077
                        cert->extKeyUsageOID[i], sz);
29078
                }
29079
            }
29080
        }
29081
    #endif /* WOLFSSL_EKU_OID */
29082
    }
29083
    if (ret != 0)
29084
        return ASN_PARSE_E;
29085
29086
    /* Calculate Sizes */
29087
    oidListSz = idx - totalSz;
29088
    totalSz = idx - 2; /* exclude first seq/len (2) */
29089
29090
    /* 1. Seq + Total Len (2) */
29091
    idx = SetSequence(totalSz, output);
29092
29093
    /* 2. Object ID (2) */
29094
    XMEMCPY(&output[idx], extkeyusage_oid, sizeof(extkeyusage_oid));
29095
    idx += sizeof(extkeyusage_oid);
29096
29097
    /* 3. Octet String (2) */
29098
    idx += SetOctetString(totalSz - idx, &output[idx]);
29099
29100
    /* 4. Seq + OidListLen (2) */
29101
    idx += SetSequence(oidListSz, &output[idx]);
29102
29103
    /* 5. Oid List (already set in-place above) */
29104
    idx += oidListSz;
29105
29106
    (void)cert;
29107
    return (int)idx;
29108
#else
29109
    /* TODO: consider calculating size of OBJECT_IDs, setting length into
29110
     * SEQUENCE, encode SEQUENCE, encode OBJECT_IDs into buffer.  */
29111
    ASNSetData* dataASN;
29112
    ASNItem* extKuASN = NULL;
29113
    int asnIdx = 1;
29114
    size_t cnt = 1 + EKU_OID_HI;
29115
    int i;
29116
    int ret = 0;
29117
    int sz = 0;
29118
29119
#ifdef WOLFSSL_EKU_OID
29120
    cnt += CTC_MAX_EKU_NB;
29121
#endif
29122
29123
    /* Allocate memory for dynamic data items. */
29124
    dataASN = (ASNSetData*)XMALLOC(cnt * sizeof(ASNSetData), cert->heap,
29125
                                                       DYNAMIC_TYPE_TMP_BUFFER);
29126
    if (dataASN == NULL) {
29127
        ret = MEMORY_E;
29128
    }
29129
    if (ret == 0) {
29130
        /* Allocate memory for dynamic ASN.1 template. */
29131
        extKuASN = (ASNItem*)XMALLOC(cnt * sizeof(ASNItem), cert->heap,
29132
                                                       DYNAMIC_TYPE_TMP_BUFFER);
29133
        if (extKuASN == NULL) {
29134
            ret = MEMORY_E;
29135
        }
29136
    }
29137
29138
    if (ret == 0) {
29139
        /* Copy Sequence into dynamic ASN.1 template. */
29140
        XMEMCPY(&extKuASN[EKUASN_IDX_SEQ], ekuASN, sizeof(ASNItem));
29141
        /* Clear dynamic data. */
29142
        XMEMSET(dataASN, 0, cnt * sizeof(ASNSetData));
29143
29144
        /* Build up the template and data. */
29145
        /* If 'any' set, then just use it. */
29146
        if ((input & EXTKEYUSE_ANY) == EXTKEYUSE_ANY) {
29147
            /* Set template item. */
29148
            XMEMCPY(&extKuASN[EKUASN_IDX_OID], &ekuASN[EKUASN_IDX_OID],
29149
                    sizeof(ASNItem));
29150
            /* Set data item. */
29151
            SetASN_Buffer(&dataASN[asnIdx], extExtKeyUsageAnyOid,
29152
                sizeof(extExtKeyUsageAnyOid));
29153
            asnIdx++;
29154
        }
29155
        else {
29156
            /* Step through the flagged purposes. */
29157
            for (i = EKU_OID_LO; i <= EKU_OID_HI; i++) {
29158
                if ((input & (1 << i)) != 0) {
29159
                    /* Set template item. */
29160
                    XMEMCPY(&extKuASN[asnIdx], &ekuASN[EKUASN_IDX_OID],
29161
                            sizeof(ASNItem));
29162
                    /* Set data item. */
29163
                    SetASN_Buffer(&dataASN[asnIdx], ekuOid[i - 1].oid,
29164
                        ekuOid[i - 1].oidSz);
29165
                    asnIdx++;
29166
                }
29167
            }
29168
        #ifdef WOLFSSL_EKU_OID
29169
            if (input & EXTKEYUSE_USER) {
29170
                /* Iterate through OID values */
29171
                for (i = 0; i < CTC_MAX_EKU_NB; i++) {
29172
                    sz = cert->extKeyUsageOIDSz[i];
29173
                    if (sz > 0) {
29174
                        /* Set template item. */
29175
                        XMEMCPY(&extKuASN[asnIdx], &ekuASN[EKUASN_IDX_OID],
29176
                                sizeof(ASNItem));
29177
                        /* Set data item. */
29178
                        SetASN_Buffer(&dataASN[asnIdx], cert->extKeyUsageOID[i],
29179
                            sz);
29180
                        asnIdx++;
29181
                    }
29182
                }
29183
            }
29184
        #endif /* WOLFSSL_EKU_OID */
29185
            (void)cert;
29186
        }
29187
29188
        /* Calculate size of encoding. */
29189
        sz = 0;
29190
        ret = SizeASN_Items(extKuASN, dataASN, asnIdx, &sz);
29191
    }
29192
    /* When buffer to write to, ensure it's big enough. */
29193
    if ((ret == 0) && (output != NULL) && (sz > (int)outSz)) {
29194
        ret = BUFFER_E;
29195
    }
29196
    if ((ret == 0) && (output != NULL)) {
29197
        /* Encode extended key usage. */
29198
        SetASN_Items(extKuASN, dataASN, asnIdx, output);
29199
    }
29200
    if (ret == 0) {
29201
        /* Return the encoding size. */
29202
        ret = sz;
29203
    }
29204
29205
    /* Dispose of allocated data. */
29206
    XFREE(extKuASN, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
29207
    XFREE(dataASN, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
29208
29209
    return ret;
29210
#endif
29211
}
29212
29213
#ifndef IGNORE_NETSCAPE_CERT_TYPE
29214
#ifndef WOLFSSL_ASN_TEMPLATE
29215
static int SetNsCertType(Cert* cert, byte* output, word32 outSz, byte input)
29216
{
29217
    word32 idx;
29218
    byte unusedBits = 0;
29219
    byte nsCertType = input;
29220
    word32 totalSz;
29221
    word32 bitStrSz;
29222
    const byte nscerttype_oid[] = { 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
29223
                                    0x86, 0xF8, 0x42, 0x01, 0x01 };
29224
29225
    if (cert == NULL || output == NULL ||
29226
            input == 0)
29227
        return BAD_FUNC_ARG;
29228
29229
    totalSz = sizeof(nscerttype_oid);
29230
29231
    /* Get amount of lsb zero's */
29232
    for (;(input & 1) == 0; input >>= 1)
29233
        unusedBits++;
29234
29235
    /* 1 byte of NS Cert Type extension */
29236
    bitStrSz = SetBitString(1, unusedBits, NULL) + 1;
29237
    totalSz += SetOctetString(bitStrSz, NULL) + bitStrSz;
29238
29239
    if (SetSequence(totalSz, NULL) + totalSz > outSz)
29240
        return BAD_FUNC_ARG;
29241
29242
    /* 1. Seq + Total Len */
29243
    idx = SetSequence(totalSz, output);
29244
29245
    /* 2. Object ID */
29246
    XMEMCPY(&output[idx], nscerttype_oid, sizeof(nscerttype_oid));
29247
    idx += sizeof(nscerttype_oid);
29248
29249
    /* 3. Octet String */
29250
    idx += SetOctetString(bitStrSz, &output[idx]);
29251
29252
    /* 4. Bit String */
29253
    idx += SetBitString(1, unusedBits, &output[idx]);
29254
    output[idx++] = nsCertType;
29255
29256
    return (int)idx;
29257
}
29258
#endif
29259
#endif
29260
29261
#ifndef WOLFSSL_ASN_TEMPLATE
29262
static int SetCRLInfo(Cert* cert, byte* output, word32 outSz, byte* input,
29263
                      int inSz)
29264
{
29265
    word32 idx;
29266
    word32 totalSz;
29267
    const byte crlinfo_oid[] = { 0x06, 0x03, 0x55, 0x1D, 0x1F };
29268
29269
    if (cert == NULL || output == NULL ||
29270
            input == 0 || inSz <= 0)
29271
        return BAD_FUNC_ARG;
29272
29273
    totalSz = (word32)sizeof(crlinfo_oid) + SetOctetString((word32)inSz, NULL) +
29274
        (word32)inSz;
29275
29276
    if (SetSequence(totalSz, NULL) + totalSz > outSz)
29277
        return BAD_FUNC_ARG;
29278
29279
    /* 1. Seq + Total Len */
29280
    idx = SetSequence(totalSz, output);
29281
29282
    /* 2. Object ID */
29283
    XMEMCPY(&output[idx], crlinfo_oid, sizeof(crlinfo_oid));
29284
    idx += sizeof(crlinfo_oid);
29285
29286
    /* 3. Octet String */
29287
    idx += SetOctetString((word32)inSz, &output[idx]);
29288
29289
    /* 4. CRL Info */
29290
    XMEMCPY(&output[idx], input, (size_t)inSz);
29291
    idx += (word32)inSz;
29292
29293
    return (int)idx;
29294
}
29295
#endif
29296
29297
/* encode Certificate Policies, return total bytes written
29298
 * each input value must be ITU-T X.690 formatted : a.b.c...
29299
 * input must be an array of values with a NULL terminated for the latest
29300
 * RFC5280 : non-critical */
29301
static int SetCertificatePolicies(byte *output,
29302
                                  word32 outputSz,
29303
                                  char input[MAX_CERTPOL_NB][MAX_CERTPOL_SZ],
29304
                                  word16 nb_certpol,
29305
                                  void* heap)
29306
{
29307
#ifndef WOLFSSL_ASN_TEMPLATE
29308
    byte    oid[MAX_OID_SZ];
29309
    byte    der_oid[MAX_CERTPOL_NB][MAX_OID_SZ];
29310
    byte    out[MAX_CERTPOL_SZ];
29311
    word32  oidSz;
29312
    word32  outSz;
29313
    word32  i = 0;
29314
    word32  der_oidSz[MAX_CERTPOL_NB];
29315
    int     ret;
29316
29317
    const byte certpol_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04 };
29318
    const byte oid_oid[] = { 0x06 };
29319
29320
    if (output == NULL || input == NULL || nb_certpol > MAX_CERTPOL_NB)
29321
        return BAD_FUNC_ARG;
29322
29323
    for (i = 0; i < nb_certpol; i++) {
29324
        oidSz = sizeof(oid);
29325
        XMEMSET(oid, 0, oidSz);
29326
29327
        ret = EncodePolicyOID(oid, &oidSz, input[i], heap);
29328
        if (ret != 0)
29329
            return ret;
29330
29331
        /* compute sequence value for the oid */
29332
        ret = SetOidValue(der_oid[i], MAX_OID_SZ, oid_oid,
29333
                          sizeof(oid_oid), oid, oidSz);
29334
        if (ret <= 0)
29335
            return ret;
29336
        else
29337
            der_oidSz[i] = (word32)ret;
29338
    }
29339
29340
    /* concatenate oid, keep two byte for sequence/size of the created value */
29341
    for (i = 0, outSz = 2; i < nb_certpol; i++) {
29342
        XMEMCPY(out+outSz, der_oid[i], der_oidSz[i]);
29343
        outSz += der_oidSz[i];
29344
    }
29345
29346
    /* add sequence */
29347
    ret = (int)SetSequence(outSz-2, out);
29348
    if (ret <= 0)
29349
        return ret;
29350
29351
    /* add Policy OID to compute final value */
29352
    return SetOidValue(output, outputSz, certpol_oid, sizeof(certpol_oid),
29353
                      out, outSz);
29354
#else
29355
    int    i;
29356
    int    ret = 0;
29357
    byte   oid[MAX_OID_SZ];
29358
    word32 oidSz;
29359
    word32 sz = 0;
29360
    int    piSz = 0;
29361
29362
    if ((input == NULL) || (nb_certpol > MAX_CERTPOL_NB)) {
29363
        ret = BAD_FUNC_ARG;
29364
    }
29365
    /* Put in policyIdentifier but not policyQualifiers. */
29366
    for (i = 0; (ret == 0) && (i < nb_certpol); i++) {
29367
        ASNSetData dataASN[policyInfoASN_Length];
29368
29369
        oidSz = sizeof(oid);
29370
        XMEMSET(oid, 0, oidSz);
29371
        dataASN[POLICYINFOASN_IDX_QUALI].noOut = 1;
29372
29373
        ret = EncodePolicyOID(oid, &oidSz, input[i], heap);
29374
        if (ret == 0) {
29375
            XMEMSET(dataASN, 0, sizeof(dataASN));
29376
            SetASN_Buffer(&dataASN[POLICYINFOASN_IDX_ID], oid, oidSz);
29377
            ret = SizeASN_Items(policyInfoASN, dataASN, policyInfoASN_Length,
29378
                                &piSz);
29379
        }
29380
        if ((ret == 0) && (output != NULL) && (sz + (word32)piSz > outputSz)) {
29381
            ret = BUFFER_E;
29382
        }
29383
        if (ret == 0) {
29384
            if (output != NULL) {
29385
                SetASN_Items(policyInfoASN, dataASN, policyInfoASN_Length,
29386
                    output);
29387
                output += piSz;
29388
            }
29389
            sz += (word32)piSz;
29390
        }
29391
    }
29392
29393
    if (ret == 0) {
29394
        ret = (int)sz;
29395
    }
29396
    return ret;
29397
#endif
29398
}
29399
#endif /* WOLFSSL_CERT_EXT */
29400
29401
29402
#ifdef WOLFSSL_ALT_NAMES
29403
29404
#ifndef WOLFSSL_ASN_TEMPLATE
29405
/* encode Alternative Names, return total bytes written */
29406
static int SetAltNames(byte *output, word32 outSz,
29407
        const byte *input, word32 length, int critical)
29408
{
29409
    byte san_len[1 + MAX_LENGTH_SZ];
29410
    const byte san_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x11 };
29411
    const byte san_crit[] = { 0x01, 0x01, 0xff };
29412
    word32 seqSz, san_lenSz, idx = 0;
29413
29414
    if (output == NULL || input == NULL)
29415
        return BAD_FUNC_ARG;
29416
29417
    if (outSz < length)
29418
        return BUFFER_E;
29419
29420
    /* Octet String header */
29421
    san_lenSz = SetOctetString(length, san_len);
29422
29423
    if (outSz < MAX_SEQ_SZ)
29424
        return BUFFER_E;
29425
29426
    seqSz = length + (word32)sizeof(san_oid) + san_lenSz;
29427
    if (critical)
29428
        seqSz += sizeof(san_crit);
29429
    idx = SetSequence(seqSz, output);
29430
29431
    if (seqSz > outSz)
29432
        return BUFFER_E;
29433
29434
    /* put oid */
29435
    XMEMCPY(output+idx, san_oid, sizeof(san_oid));
29436
    idx += sizeof(san_oid);
29437
29438
    if (critical) {
29439
        XMEMCPY(output+idx, san_crit, sizeof(san_crit));
29440
        idx += sizeof(san_crit);
29441
    }
29442
29443
    /* put octet header */
29444
    XMEMCPY(output+idx, san_len, san_lenSz);
29445
    idx += san_lenSz;
29446
29447
    /* put value */
29448
    XMEMCPY(output+idx, input, length);
29449
    idx += length;
29450
29451
    return (int)idx;
29452
}
29453
#endif /* WOLFSSL_ASN_TEMPLATE */
29454
29455
29456
int FlattenAltNames(byte* output, word32 outputSz, const DNS_entry* names)
29457
{
29458
    word32 idx;
29459
    const DNS_entry* curName;
29460
    word32 namesSz = 0;
29461
#ifdef WOLFSSL_ALT_NAMES_NO_REV
29462
    word32 i;
29463
#endif
29464
29465
    if (output == NULL)
29466
        return BAD_FUNC_ARG;
29467
29468
    if (names == NULL)
29469
        return 0;
29470
29471
    curName = names;
29472
    do {
29473
        namesSz += (word32)curName->len + 2 +
29474
            ((curName->len < ASN_LONG_LENGTH) ? 0
29475
             : BytePrecision((word32)curName->len));
29476
        curName = curName->next;
29477
    } while (curName != NULL);
29478
29479
    if (outputSz < MAX_SEQ_SZ + namesSz)
29480
        return BUFFER_E;
29481
29482
    idx = SetSequence(namesSz, output);
29483
#ifdef WOLFSSL_ALT_NAMES_NO_REV
29484
    namesSz += idx;
29485
    i = namesSz;
29486
#endif
29487
29488
    curName = names;
29489
    do {
29490
#ifdef WOLFSSL_ALT_NAMES_NO_REV
29491
        word32 len = SetLength(curName->len, NULL);
29492
        idx = i - curName->len - len - 1;
29493
        i = idx;
29494
#endif
29495
        output[idx] = (byte) (ASN_CONTEXT_SPECIFIC | curName->type);
29496
        if (curName->type == ASN_DIR_TYPE || curName->type == ASN_OTHER_TYPE) {
29497
            output[idx] |= ASN_CONSTRUCTED;
29498
        }
29499
        idx++;
29500
        idx += SetLength((word32)curName->len, output + idx);
29501
        XMEMCPY(output + idx, curName->name, (size_t)curName->len);
29502
#ifndef WOLFSSL_ALT_NAMES_NO_REV
29503
        idx += (word32)curName->len;
29504
#endif
29505
        curName = curName->next;
29506
    } while (curName != NULL);
29507
29508
#ifdef WOLFSSL_ALT_NAMES_NO_REV
29509
    idx = namesSz;
29510
#endif
29511
    return (int)idx;
29512
}
29513
29514
#endif /* WOLFSSL_ALT_NAMES */
29515
#endif /* WOLFSSL_CERT_GEN */
29516
29517
#if defined(WOLFSSL_CERT_GEN) || defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
29518
/* Simple domain name OID size. */
29519
#define DN_OID_SZ     3
29520
29521
/* Encodes one attribute of the name (issuer/subject)
29522
 *
29523
 * name     structure to hold result of encoding
29524
 * nameStr  value to be encoded
29525
 * nameTag  tag of encoding i.e CTC_UTF8
29526
 * type     id of attribute i.e ASN_COMMON_NAME
29527
 * emailTag tag of email i.e CTC_UTF8
29528
 * returns length on success
29529
 */
29530
static int EncodeName(EncodedName* name, const char* nameStr,
29531
                    byte nameTag, byte type, byte emailTag, CertName* cname)
29532
{
29533
#if !defined(WOLFSSL_ASN_TEMPLATE)
29534
    word32 idx = 0;
29535
    /* bottom up */
29536
    byte firstLen[1 + MAX_LENGTH_SZ];
29537
    byte secondLen[MAX_LENGTH_SZ];
29538
    byte sequence[MAX_SEQ_SZ];
29539
    byte set[MAX_SET_SZ];
29540
29541
    word32 strLen;
29542
    word32 thisLen;
29543
    word32 firstSz, secondSz, seqSz, setSz;
29544
29545
    if (nameStr == NULL) {
29546
        name->used = 0;
29547
        return 0;
29548
    }
29549
29550
    thisLen = strLen = (word32)XSTRLEN(nameStr);
29551
#ifdef WOLFSSL_CUSTOM_OID
29552
    if (type == ASN_CUSTOM_NAME) {
29553
        if (cname == NULL || cname->custom.oidSz == 0) {
29554
            name->used = 0;
29555
            return 0;
29556
        }
29557
        thisLen = strLen = (word32)cname->custom.valSz;
29558
    }
29559
#else
29560
    (void)cname;
29561
#endif
29562
29563
    if (strLen == 0) { /* no user data for this item */
29564
        name->used = 0;
29565
        return 0;
29566
    }
29567
29568
    /* Restrict country code size */
29569
    if (type == ASN_COUNTRY_NAME && strLen != CTC_COUNTRY_SIZE) {
29570
        WOLFSSL_MSG("Country code size error");
29571
        WOLFSSL_ERROR_VERBOSE(ASN_COUNTRY_SIZE_E);
29572
        return ASN_COUNTRY_SIZE_E;
29573
    }
29574
29575
    secondSz = SetLength(strLen, secondLen);
29576
    thisLen += secondSz;
29577
    switch (type) {
29578
        case ASN_EMAIL_NAME: /* email */
29579
            thisLen += (int)sizeof(attrEmailOid);
29580
            firstSz  = (int)sizeof(attrEmailOid);
29581
            break;
29582
        case ASN_DOMAIN_COMPONENT:
29583
            thisLen += (int)sizeof(dcOid);
29584
            firstSz  = (int)sizeof(dcOid);
29585
            break;
29586
        case ASN_USER_ID:
29587
            thisLen += (int)sizeof(uidOid);
29588
            firstSz  = (int)sizeof(uidOid);
29589
            break;
29590
        case ASN_RFC822_MAILBOX:
29591
            thisLen += (int)sizeof(rfc822Mlbx);
29592
            firstSz  = (int)sizeof(rfc822Mlbx);
29593
            break;
29594
        case ASN_FAVOURITE_DRINK:
29595
            thisLen += (int)sizeof(fvrtDrk);
29596
            firstSz  = (int)sizeof(fvrtDrk);
29597
            break;
29598
    #ifdef WOLFSSL_CUSTOM_OID
29599
        case ASN_CUSTOM_NAME:
29600
            thisLen += cname->custom.oidSz;
29601
            firstSz = cname->custom.oidSz;
29602
            break;
29603
    #endif
29604
    #ifdef WOLFSSL_CERT_REQ
29605
        case ASN_CONTENT_TYPE:
29606
            thisLen += (int)sizeof(attrPkcs9ContentTypeOid);
29607
            firstSz  = (int)sizeof(attrPkcs9ContentTypeOid);
29608
            break;
29609
    #endif
29610
        default:
29611
            thisLen += DN_OID_SZ;
29612
            firstSz  = DN_OID_SZ;
29613
    }
29614
    thisLen++; /* id  type */
29615
    firstSz  = (word32)SetObjectId((int)firstSz, firstLen);
29616
    thisLen += firstSz;
29617
29618
    seqSz = SetSequence(thisLen, sequence);
29619
    thisLen += seqSz;
29620
    setSz = SetSet(thisLen, set);
29621
    thisLen += setSz;
29622
29623
    if (thisLen > (int)sizeof(name->encoded)) {
29624
        return BUFFER_E;
29625
    }
29626
29627
    /* store it */
29628
    idx = 0;
29629
    /* set */
29630
    XMEMCPY(name->encoded, set, setSz);
29631
    idx += setSz;
29632
    /* seq */
29633
    XMEMCPY(name->encoded + idx, sequence, seqSz);
29634
    idx += seqSz;
29635
    /* asn object id */
29636
    XMEMCPY(name->encoded + idx, firstLen, firstSz);
29637
    idx += firstSz;
29638
    switch (type) {
29639
        case ASN_EMAIL_NAME:
29640
            /* email joint id */
29641
            XMEMCPY(name->encoded + idx, attrEmailOid, sizeof(attrEmailOid));
29642
            idx += (int)sizeof(attrEmailOid);
29643
            name->encoded[idx++] = emailTag;
29644
            break;
29645
        case ASN_DOMAIN_COMPONENT:
29646
            XMEMCPY(name->encoded + idx, dcOid, sizeof(dcOid)-1);
29647
            idx += (int)sizeof(dcOid)-1;
29648
            /* id type */
29649
            name->encoded[idx++] = type;
29650
            /* str type */
29651
            name->encoded[idx++] = nameTag;
29652
            break;
29653
        case ASN_USER_ID:
29654
            XMEMCPY(name->encoded + idx, uidOid, sizeof(uidOid));
29655
            idx += (int)sizeof(uidOid);
29656
            /* str type */
29657
            name->encoded[idx++] = nameTag;
29658
            break;
29659
        case ASN_RFC822_MAILBOX:
29660
            XMEMCPY(name->encoded + idx, rfc822Mlbx, sizeof(rfc822Mlbx));
29661
            idx += (int)sizeof(rfc822Mlbx);
29662
            /* str type */
29663
            name->encoded[idx++] = nameTag;
29664
            break;
29665
        case ASN_FAVOURITE_DRINK:
29666
            XMEMCPY(name->encoded + idx, fvrtDrk, sizeof(fvrtDrk));
29667
            idx += (int)sizeof(fvrtDrk);
29668
            /* str type */
29669
            name->encoded[idx++] = nameTag;
29670
            break;
29671
    #ifdef WOLFSSL_CUSTOM_OID
29672
        case ASN_CUSTOM_NAME:
29673
            XMEMCPY(name->encoded + idx, cname->custom.oid,
29674
                    cname->custom.oidSz);
29675
            idx += cname->custom.oidSz;
29676
            /* str type */
29677
            name->encoded[idx++] = nameTag;
29678
            break;
29679
    #endif
29680
    #ifdef WOLFSSL_CERT_REQ
29681
        case ASN_CONTENT_TYPE:
29682
            XMEMCPY(name->encoded + idx, attrPkcs9ContentTypeOid,
29683
                    sizeof(attrPkcs9ContentTypeOid));
29684
            idx += (int)sizeof(attrPkcs9ContentTypeOid);
29685
            /* str type */
29686
            name->encoded[idx++] = nameTag;
29687
            break;
29688
    #endif
29689
        default:
29690
            name->encoded[idx++] = 0x55;
29691
            name->encoded[idx++] = 0x04;
29692
            /* id type */
29693
            name->encoded[idx++] = type;
29694
            /* str type */
29695
            name->encoded[idx++] = nameTag;
29696
    }
29697
    /* second length */
29698
    XMEMCPY(name->encoded + idx, secondLen, secondSz);
29699
    idx += secondSz;
29700
    /* str value */
29701
    XMEMCPY(name->encoded + idx, nameStr, strLen);
29702
    idx += strLen;
29703
29704
    name->type = type;
29705
    name->totalLen = (int)idx;
29706
    name->used = 1;
29707
29708
    return (int)idx;
29709
#else
29710
    DECL_ASNSETDATA(dataASN, rdnASN_Length);
29711
    ASNItem namesASN[rdnASN_Length];
29712
    byte dnOid[DN_OID_SZ] = { 0x55, 0x04, 0x00 };
29713
    int ret = 0;
29714
    int sz = 0;
29715
    const byte* oid;
29716
    word32 oidSz = 0;
29717
    word32 nameSz = 0;
29718
29719
    /* Validate input parameters. */
29720
    if ((name == NULL) || (nameStr == NULL)) {
29721
        ret = BAD_FUNC_ARG;
29722
    }
29723
29724
#ifdef WOLFSSL_CUSTOM_OID
29725
    if (ret == 0 && type == ASN_CUSTOM_NAME) {
29726
        if (cname == NULL || cname->custom.oidSz == 0) {
29727
            name->used = 0;
29728
            return 0;
29729
        }
29730
    }
29731
#else
29732
    (void)cname;
29733
#endif
29734
29735
    CALLOC_ASNSETDATA(dataASN, rdnASN_Length, ret, NULL);
29736
    if (ret == 0) {
29737
        nameSz = (word32)XSTRLEN(nameStr);
29738
        /* Copy the RDN encoding template. ASN.1 tag for the name string is set
29739
         * based on type. */
29740
        XMEMCPY(namesASN, rdnASN, sizeof(namesASN));
29741
29742
        /* Set OID and ASN.1 tag for name depending on type. */
29743
        switch (type) {
29744
            case ASN_EMAIL_NAME:
29745
                /* email OID different to standard types. */
29746
                oid = attrEmailOid;
29747
                oidSz = sizeof(attrEmailOid);
29748
                /* Use email specific type/tag. */
29749
                nameTag = emailTag;
29750
                break;
29751
            case ASN_DOMAIN_COMPONENT:
29752
                /* Domain component OID different to standard types. */
29753
                oid = dcOid;
29754
                oidSz = sizeof(dcOid);
29755
                break;
29756
            case ASN_USER_ID:
29757
                /* Domain component OID different to standard types. */
29758
                oid = uidOid;
29759
                oidSz = sizeof(uidOid);
29760
                break;
29761
            case ASN_RFC822_MAILBOX:
29762
                oid = rfc822Mlbx;
29763
                oidSz = sizeof(rfc822Mlbx);
29764
                break;
29765
            case ASN_FAVOURITE_DRINK:
29766
                oid = fvrtDrk;
29767
                oidSz = sizeof(fvrtDrk);
29768
                break;
29769
        #ifdef WOLFSSL_CUSTOM_OID
29770
            case ASN_CUSTOM_NAME:
29771
                nameSz = (word32)cname->custom.valSz;
29772
                oid = cname->custom.oid;
29773
                oidSz = (word32)cname->custom.oidSz;
29774
                break;
29775
        #endif
29776
        #ifdef WOLFSSL_CERT_REQ
29777
            case ASN_CONTENT_TYPE:
29778
                oid = attrPkcs9ContentTypeOid;
29779
                oidSz = sizeof(attrPkcs9ContentTypeOid);
29780
                break;
29781
        #endif
29782
            default:
29783
                /* Construct OID using type. */
29784
                dnOid[2] = type;
29785
                oid = dnOid;
29786
                oidSz = DN_OID_SZ;
29787
                break;
29788
        }
29789
29790
        /* Set OID corresponding to the name type. */
29791
        SetASN_Buffer(&dataASN[RDNASN_IDX_ATTR_TYPE], oid, oidSz);
29792
        /* Set name string. */
29793
        SetASN_Buffer(&dataASN[RDNASN_IDX_ATTR_VAL], (const byte *)nameStr, nameSz);
29794
        /* Set the ASN.1 tag for the name string. */
29795
        namesASN[RDNASN_IDX_ATTR_VAL].tag = nameTag;
29796
29797
        /* Calculate size of encoded name and indexes of components. */
29798
        ret = SizeASN_Items(namesASN, dataASN, rdnASN_Length, &sz);
29799
    }
29800
    /* Check if name's buffer is big enough. */
29801
    if ((ret == 0) && (sz > (int)sizeof(name->encoded))) {
29802
        ret = BUFFER_E;
29803
    }
29804
    if (ret == 0) {
29805
        /* Encode name into the buffer. */
29806
        SetASN_Items(namesASN, dataASN, rdnASN_Length, name->encoded);
29807
        /* Cache the type and size, and set that it is used. */
29808
        name->type = type;
29809
        name->totalLen = sz;
29810
        name->used = 1;
29811
29812
        /* Return size of encoding. */
29813
        ret = sz;
29814
    }
29815
    (void)cname;
29816
29817
    FREE_ASNSETDATA(dataASN, NULL);
29818
    return ret;
29819
#endif /* WOLFSSL_ASN_TEMPLATE */
29820
}
29821
29822
/* canonical encoding one attribute of the name (issuer/subject)
29823
 * call EncodeName with CTC_UTF8 for email type
29824
 *
29825
 * name     structure to hold result of encoding
29826
 * nameStr  value to be encoded
29827
 * nameType type of encoding i.e CTC_UTF8
29828
 * type     id of attribute i.e ASN_COMMON_NAME
29829
 *
29830
 * returns length on success
29831
 */
29832
int wc_EncodeNameCanonical(EncodedName* name, const char* nameStr,
29833
                           char nameType, byte type)
29834
{
29835
    return EncodeName(name, nameStr, (byte)nameType, type,
29836
        ASN_UTF8STRING, NULL);
29837
}
29838
#endif /* WOLFSSL_CERT_GEN || OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
29839
29840
#ifdef WOLFSSL_ASN_PARSE_KEYUSAGE
29841
29842
/* Convert key usage string (comma delimited, null terminated) to word16
29843
 * Returns 0 on success, negative on error */
29844
int ParseKeyUsageStr(const char* value, word16* keyUsage, void* heap)
29845
{
29846
    int ret = 0;
29847
    char *token, *str, *ptr;
29848
    word32 len = 0;
29849
    word16 usage = 0;
29850
29851
    if (value == NULL || keyUsage == NULL) {
29852
        return BAD_FUNC_ARG;
29853
    }
29854
29855
    /* duplicate string (including terminator) */
29856
    len = (word32)XSTRLEN(value);
29857
    str = (char*)XMALLOC(len + 1, heap, DYNAMIC_TYPE_TMP_BUFFER);
29858
    if (str == NULL) {
29859
        return MEMORY_E;
29860
    }
29861
    XMEMCPY(str, value, len + 1);
29862
29863
    /* parse value, and set corresponding Key Usage value */
29864
    if ((token = XSTRTOK(str, ",", &ptr)) == NULL) {
29865
        XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
29866
        return KEYUSAGE_E;
29867
    }
29868
    while (token != NULL) {
29869
        if (!XSTRCASECMP(token, "digitalSignature"))
29870
            usage |= KEYUSE_DIGITAL_SIG;
29871
        else if (!XSTRCASECMP(token, "nonRepudiation") ||
29872
                 !XSTRCASECMP(token, "contentCommitment"))
29873
            usage |= KEYUSE_CONTENT_COMMIT;
29874
        else if (!XSTRCASECMP(token, "keyEncipherment"))
29875
            usage |= KEYUSE_KEY_ENCIPHER;
29876
        else if (!XSTRCASECMP(token, "dataEncipherment"))
29877
            usage |= KEYUSE_DATA_ENCIPHER;
29878
        else if (!XSTRCASECMP(token, "keyAgreement"))
29879
            usage |= KEYUSE_KEY_AGREE;
29880
        else if (!XSTRCASECMP(token, "keyCertSign"))
29881
            usage |= KEYUSE_KEY_CERT_SIGN;
29882
        else if (!XSTRCASECMP(token, "cRLSign"))
29883
            usage |= KEYUSE_CRL_SIGN;
29884
        else if (!XSTRCASECMP(token, "encipherOnly"))
29885
            usage |= KEYUSE_ENCIPHER_ONLY;
29886
        else if (!XSTRCASECMP(token, "decipherOnly"))
29887
            usage |= KEYUSE_DECIPHER_ONLY;
29888
        else {
29889
            ret = KEYUSAGE_E;
29890
            break;
29891
        }
29892
29893
        token = XSTRTOK(NULL, ",", &ptr);
29894
    }
29895
29896
    XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
29897
29898
    if (ret == 0) {
29899
        *keyUsage = usage;
29900
    }
29901
29902
    return ret;
29903
}
29904
29905
/* Convert extended key usage string (comma delimited, null terminated) to byte
29906
 * Returns 0 on success, negative on error */
29907
int ParseExtKeyUsageStr(const char* value, byte* extKeyUsage, void* heap)
29908
{
29909
    int ret = 0;
29910
    char *token, *str, *ptr;
29911
    word32 len = 0;
29912
    byte usage = 0;
29913
29914
    if (value == NULL || extKeyUsage == NULL) {
29915
        return BAD_FUNC_ARG;
29916
    }
29917
29918
    /* duplicate string (including terminator) */
29919
    len = (word32)XSTRLEN(value);
29920
    str = (char*)XMALLOC(len + 1, heap, DYNAMIC_TYPE_TMP_BUFFER);
29921
    if (str == NULL) {
29922
        return MEMORY_E;
29923
    }
29924
    XMEMCPY(str, value, len + 1);
29925
29926
    /* parse value, and set corresponding Key Usage value */
29927
    if ((token = XSTRTOK(str, ",", &ptr)) == NULL) {
29928
        XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
29929
        return EXTKEYUSAGE_E;
29930
    }
29931
    while (token != NULL) {
29932
        if (!XSTRCASECMP(token, "any"))
29933
            usage |= EXTKEYUSE_ANY;
29934
        else if (!XSTRCASECMP(token, "serverAuth"))
29935
            usage |= EXTKEYUSE_SERVER_AUTH;
29936
        else if (!XSTRCASECMP(token, "clientAuth"))
29937
            usage |= EXTKEYUSE_CLIENT_AUTH;
29938
        else if (!XSTRCASECMP(token, "codeSigning"))
29939
            usage |= EXTKEYUSE_CODESIGN;
29940
        else if (!XSTRCASECMP(token, "emailProtection"))
29941
            usage |= EXTKEYUSE_EMAILPROT;
29942
        else if (!XSTRCASECMP(token, "timeStamping"))
29943
            usage |= EXTKEYUSE_TIMESTAMP;
29944
        else if (!XSTRCASECMP(token, "OCSPSigning"))
29945
            usage |= EXTKEYUSE_OCSP_SIGN;
29946
        else {
29947
            ret = EXTKEYUSAGE_E;
29948
            break;
29949
        }
29950
29951
        token = XSTRTOK(NULL, ",", &ptr);
29952
    }
29953
29954
    XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
29955
29956
    if (ret == 0) {
29957
        *extKeyUsage = usage;
29958
    }
29959
29960
    return ret;
29961
}
29962
29963
#endif /* WOLFSSL_ASN_PARSE_KEYUSAGE */
29964
29965
#ifdef WOLFSSL_CERT_GEN
29966
/* Encodes one attribute of the name (issuer/subject)
29967
 * call we_EncodeName_ex with 0x16, IA5String for email type
29968
 * name     structure to hold result of encoding
29969
 * nameStr  value to be encoded
29970
 * nameType type of encoding i.e CTC_UTF8
29971
 * type     id of attribute i.e ASN_COMMON_NAME
29972
 *
29973
 * returns length on success
29974
 */
29975
int wc_EncodeName(EncodedName* name, const char* nameStr, char nameType,
29976
                  byte type)
29977
{
29978
    return EncodeName(name, nameStr, (byte)nameType, type,
29979
        ASN_IA5_STRING, NULL);
29980
}
29981
29982
#ifdef WOLFSSL_ASN_TEMPLATE
29983
static void SetRdnItems(ASNItem* namesASN, ASNSetData* dataASN, const byte* oid,
29984
    word32 oidSz, byte tag, const byte* data, word32 sz)
29985
{
29986
    XMEMCPY(namesASN, rdnASN, sizeof(rdnASN));
29987
    SetASN_Buffer(&dataASN[RDNASN_IDX_ATTR_TYPE], oid, oidSz);
29988
    namesASN[RDNASN_IDX_ATTR_VAL].tag = tag;
29989
    SetASN_Buffer(&dataASN[RDNASN_IDX_ATTR_VAL], data, sz);
29990
}
29991
29992
#ifdef WOLFSSL_MULTI_ATTRIB
29993
static int FindMultiAttrib(CertName* name, int id, int* idx)
29994
{
29995
    int i;
29996
    for (i = *idx + 1; i < CTC_MAX_ATTRIB; i++) {
29997
        if (name->name[i].sz > 0 && name->name[i].id == id) {
29998
            break;
29999
        }
30000
    }
30001
    if (i == CTC_MAX_ATTRIB) {
30002
        i = -1;
30003
    }
30004
    *idx = i;
30005
    return i >= 0;
30006
}
30007
#endif
30008
30009
/* ASN.1 template for the SEQUENCE around the RDNs.
30010
 * X.509: RFC 5280, 4.1.2.4 - RDNSequence
30011
 */
30012
static const ASNItem nameASN[] = {
30013
    { 0, ASN_SEQUENCE, 1, 1, 0 },
30014
};
30015
enum {
30016
    NAMEASN_IDX_SEQ = 0
30017
};
30018
30019
/* Number of items in ASN.1 template for the SEQUENCE around the RDNs. */
30020
#define nameASN_Length (sizeof(nameASN) / sizeof(ASNItem))
30021
30022
static int SetNameRdnItems(ASNSetData* dataASN, ASNItem* namesASN,
30023
        int maxIdx, CertName* name)
30024
{
30025
    int         i;
30026
    int         idx;
30027
    int         ret = 0;
30028
    word32      nameLen[NAME_ENTRIES];
30029
#ifdef WOLFSSL_MULTI_ATTRIB
30030
    int         j;
30031
#endif
30032
30033
    for (i = 0; i < NAME_ENTRIES; i++) {
30034
        /* Keep name length to identify component is to be encoded. */
30035
        const char* nameStr = GetOneCertName(name, i);
30036
        nameLen[i] = nameStr ? (word32)XSTRLEN(nameStr) : 0;
30037
    }
30038
30039
    idx = nameASN_Length;
30040
    for (i = 0; i < NAME_ENTRIES; i++) {
30041
        int type = GetCertNameId(i);
30042
30043
    #ifdef WOLFSSL_MULTI_ATTRIB
30044
        j = -1;
30045
        /* Put DomainComponents before OrgUnitName. */
30046
        while (FindMultiAttrib(name, type, &j)) {
30047
            if (GetCertNameId(i) != ASN_DOMAIN_COMPONENT) {
30048
                continue;
30049
            }
30050
            if (dataASN != NULL && namesASN != NULL) {
30051
                if (idx > maxIdx - (int)rdnASN_Length) {
30052
                    WOLFSSL_MSG("Wanted to write more ASN than allocated");
30053
                    ret = BUFFER_E;
30054
                    break;
30055
                }
30056
                /* Copy data into dynamic vars. */
30057
                SetRdnItems(namesASN + idx, dataASN + idx, dcOid,
30058
                            sizeof(dcOid), (byte)name->name[j].type,
30059
                            (byte*)name->name[j].value,
30060
                            (word32)name->name[j].sz);
30061
            }
30062
            idx += (int)rdnASN_Length;
30063
        }
30064
        if (ret != 0)
30065
            break;
30066
    #endif
30067
30068
        if (nameLen[i] > 0) {
30069
            if (dataASN != NULL) {
30070
                if (idx > maxIdx - (int)rdnASN_Length) {
30071
                    WOLFSSL_MSG("Wanted to write more ASN than allocated");
30072
                    ret = BUFFER_E;
30073
                    break;
30074
                }
30075
                /* Write out first instance of attribute type. */
30076
                if (type == ASN_EMAIL_NAME) {
30077
                    /* Copy email data into dynamic vars. */
30078
                    SetRdnItems(namesASN + idx, dataASN + idx, attrEmailOid,
30079
                        sizeof(attrEmailOid), ASN_IA5_STRING,
30080
                        (const byte*)GetOneCertName(name, i), nameLen[i]);
30081
                }
30082
                else if (type == ASN_USER_ID) {
30083
                    /* Copy userID data into dynamic vars. */
30084
                    SetRdnItems(namesASN + idx, dataASN + idx, uidOid,
30085
                                sizeof(uidOid), (byte)GetNameType(name, i),
30086
                        (const byte*)GetOneCertName(name, i), nameLen[i]);
30087
                }
30088
                else if (type == ASN_RFC822_MAILBOX) {
30089
                    /* Copy RFC822 mailbox data into dynamic vars. */
30090
                    SetRdnItems(namesASN + idx, dataASN + idx, rfc822Mlbx,
30091
                                sizeof(rfc822Mlbx), (byte)GetNameType(name, i),
30092
                        (const byte*)GetOneCertName(name, i), nameLen[i]);
30093
                }
30094
                else if (type == ASN_FAVOURITE_DRINK) {
30095
                    /* Copy favourite drink data into dynamic vars. */
30096
                    SetRdnItems(namesASN + idx, dataASN + idx, fvrtDrk,
30097
                                sizeof(fvrtDrk), (byte)GetNameType(name, i),
30098
                        (const byte*)GetOneCertName(name, i), nameLen[i]);
30099
                }
30100
                else if (type == ASN_CUSTOM_NAME) {
30101
                #ifdef WOLFSSL_CUSTOM_OID
30102
                    SetRdnItems(namesASN + idx, dataASN + idx, name->custom.oid,
30103
                        (word32)name->custom.oidSz, (byte)name->custom.enc,
30104
                        name->custom.val, (word32)name->custom.valSz);
30105
                #endif
30106
                }
30107
                else {
30108
                    /* Copy name data into dynamic vars. */
30109
                    SetRdnItems(namesASN + idx, dataASN + idx, nameOid[i],
30110
                        NAME_OID_SZ, (byte)GetNameType(name, i),
30111
                        (const byte*)GetOneCertName(name, i), nameLen[i]);
30112
                }
30113
            }
30114
            idx += (int)rdnASN_Length;
30115
        }
30116
30117
    #ifdef WOLFSSL_MULTI_ATTRIB
30118
        j = -1;
30119
        /* Write all other attributes of this type. */
30120
        while (FindMultiAttrib(name, type, &j)) {
30121
            if (GetCertNameId(i) == ASN_DOMAIN_COMPONENT) {
30122
                continue;
30123
            }
30124
            if (dataASN != NULL && namesASN != NULL) {
30125
                if (idx > maxIdx - (int)rdnASN_Length) {
30126
                    WOLFSSL_MSG("Wanted to write more ASN than allocated");
30127
                    ret = BUFFER_E;
30128
                    break;
30129
                }
30130
                /* Copy data into dynamic vars. */
30131
                SetRdnItems(namesASN + idx, dataASN + idx, nameOid[i],
30132
                    NAME_OID_SZ, (byte)name->name[j].type,
30133
                    (byte*)name->name[j].value, (word32)name->name[j].sz);
30134
            }
30135
            idx += (int)rdnASN_Length;
30136
        }
30137
        if (ret != 0)
30138
            break;
30139
    #endif
30140
    }
30141
    if (ret == 0)
30142
        ret = idx;
30143
    return ret;
30144
}
30145
#endif
30146
30147
/* encode CertName into output, return total bytes written */
30148
int SetNameEx(byte* output, word32 outputSz, CertName* name, void* heap)
30149
{
30150
#ifndef WOLFSSL_ASN_TEMPLATE
30151
    int ret;
30152
    int i;
30153
    word32 idx, totalBytes = 0;
30154
#ifdef WOLFSSL_SMALL_STACK
30155
    EncodedName* names = NULL;
30156
#else
30157
    EncodedName  names[NAME_ENTRIES];
30158
#endif
30159
#ifdef WOLFSSL_MULTI_ATTRIB
30160
    EncodedName addNames[CTC_MAX_ATTRIB];
30161
    int j, type;
30162
#endif
30163
30164
    if (output == NULL || name == NULL)
30165
        return BAD_FUNC_ARG;
30166
30167
    if (outputSz < 3)
30168
        return BUFFER_E;
30169
30170
#ifdef WOLFSSL_SMALL_STACK
30171
    names = (EncodedName*)XMALLOC(sizeof(EncodedName) * NAME_ENTRIES, NULL,
30172
                                                       DYNAMIC_TYPE_TMP_BUFFER);
30173
    if (names == NULL)
30174
        return MEMORY_E;
30175
#endif
30176
30177
    for (i = 0; i < NAME_ENTRIES; i++) {
30178
        const char* nameStr = GetOneCertName(name, i);
30179
30180
        ret = EncodeName(&names[i], nameStr, (byte)GetNameType(name, i),
30181
                          GetCertNameId(i), ASN_IA5_STRING, name);
30182
        if (ret < 0) {
30183
        #ifdef WOLFSSL_SMALL_STACK
30184
            XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
30185
        #endif
30186
            WOLFSSL_MSG("EncodeName failed");
30187
            return BUFFER_E;
30188
        }
30189
        totalBytes += (word32)ret;
30190
    }
30191
#ifdef WOLFSSL_MULTI_ATTRIB
30192
    for (i = 0; i < CTC_MAX_ATTRIB; i++) {
30193
        if (name->name[i].sz > 0) {
30194
            ret = EncodeName(&addNames[i], name->name[i].value,
30195
                             (byte)name->name[i].type, (byte)name->name[i].id,
30196
                        ASN_IA5_STRING, NULL);
30197
            if (ret < 0) {
30198
            #ifdef WOLFSSL_SMALL_STACK
30199
                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
30200
            #endif
30201
                WOLFSSL_MSG("EncodeName on multiple attributes failed");
30202
                return BUFFER_E;
30203
            }
30204
            totalBytes += (word32)ret;
30205
        }
30206
        else {
30207
            addNames[i].used = 0;
30208
        }
30209
    }
30210
#endif /* WOLFSSL_MULTI_ATTRIB */
30211
30212
    /* header */
30213
    idx = SetSequence(totalBytes, output);
30214
    totalBytes += idx;
30215
    if (totalBytes > WC_ASN_NAME_MAX) {
30216
#ifdef WOLFSSL_SMALL_STACK
30217
        XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
30218
#endif
30219
        WOLFSSL_MSG("Total Bytes is greater than WC_ASN_NAME_MAX");
30220
        return BUFFER_E;
30221
    }
30222
30223
    for (i = 0; i < NAME_ENTRIES; i++) {
30224
    #ifdef WOLFSSL_MULTI_ATTRIB
30225
        type = GetCertNameId(i);
30226
        for (j = 0; j < CTC_MAX_ATTRIB; j++) {
30227
            if (name->name[j].sz > 0 && type == name->name[j].id) {
30228
                if (outputSz < idx + (word32)addNames[j].totalLen) {
30229
                #ifdef WOLFSSL_SMALL_STACK
30230
                    XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
30231
                #endif
30232
                    WOLFSSL_MSG("Not enough space left for DC value");
30233
                    return BUFFER_E;
30234
                }
30235
30236
                XMEMCPY(output + idx, addNames[j].encoded,
30237
                        (size_t)addNames[j].totalLen);
30238
                idx += (word32)addNames[j].totalLen;
30239
            }
30240
        }
30241
    #endif /* WOLFSSL_MULTI_ATTRIB */
30242
30243
        if (names[i].used) {
30244
            if (outputSz < idx + (word32)names[i].totalLen) {
30245
#ifdef WOLFSSL_SMALL_STACK
30246
                XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
30247
#endif
30248
                return BUFFER_E;
30249
            }
30250
30251
            XMEMCPY(output + idx, names[i].encoded, (size_t)names[i].totalLen);
30252
            idx += (word32)names[i].totalLen;
30253
        }
30254
    }
30255
30256
#ifdef WOLFSSL_SMALL_STACK
30257
    XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
30258
#endif
30259
    (void)heap;
30260
30261
    return (int)totalBytes;
30262
#else
30263
    /* TODO: consider calculating size of entries, putting length into
30264
     * SEQUENCE, encode SEQUENCE, encode entries into buffer.  */
30265
    ASNSetData* dataASN = NULL; /* Can't use DECL_ASNSETDATA. Always dynamic. */
30266
    ASNItem*    namesASN = NULL;
30267
    word32      items = 0;
30268
    int         ret = 0;
30269
    int         sz = 0;
30270
30271
    /* Calculate length of name entries and size for allocating. */
30272
    ret = SetNameRdnItems(NULL, NULL, 0, name);
30273
    if (ret > 0) {
30274
        items = (word32)ret;
30275
        ret = 0;
30276
    }
30277
30278
    if (items == 0) {
30279
        /* if zero items, short-circuit return to avoid frivolous zero-size
30280
         * allocations.
30281
         */
30282
        return 0;
30283
    }
30284
30285
    /* Allocate dynamic data items. */
30286
    dataASN = (ASNSetData*)XMALLOC(items * sizeof(ASNSetData), heap,
30287
                                   DYNAMIC_TYPE_TMP_BUFFER);
30288
    if (dataASN == NULL) {
30289
        ret = MEMORY_E;
30290
    }
30291
    else {
30292
        /* Allocate dynamic ASN.1 template items. */
30293
        namesASN = (ASNItem*)XMALLOC(items * sizeof(ASNItem), heap,
30294
                                     DYNAMIC_TYPE_TMP_BUFFER);
30295
        if (namesASN == NULL) {
30296
            ret = MEMORY_E;
30297
        }
30298
    }
30299
30300
    if (ret == 0) {
30301
        /* Clear the dynamic data. */
30302
        XMEMSET(dataASN, 0, items * sizeof(ASNSetData));
30303
        /* Copy in the outer sequence. */
30304
        XMEMCPY(namesASN, nameASN, sizeof(nameASN));
30305
30306
        ret = SetNameRdnItems(dataASN, namesASN, (int)items, name);
30307
        if (ret == (int)items)
30308
            ret = 0;
30309
        else if (ret > 0) {
30310
            WOLFSSL_MSG("SetNameRdnItems returned different length");
30311
            ret = BUFFER_E;
30312
        }
30313
    }
30314
    if (ret == 0) {
30315
        /* Calculate size of encoding. */
30316
        ret = SizeASN_Items(namesASN, dataASN, (int)items, &sz);
30317
    }
30318
    /* Check buffer size if passed in. */
30319
    if (ret == 0 && output != NULL && sz > (int)outputSz) {
30320
        ret = BUFFER_E;
30321
    }
30322
    if (ret == 0) {
30323
        if (output != NULL) {
30324
            /* Encode Name. */
30325
            ret = SetASN_Items(namesASN, dataASN, (int)items, output);
30326
        }
30327
        else {
30328
            /* Return the encoding size. */
30329
            ret = sz;
30330
        }
30331
    }
30332
30333
    XFREE(namesASN, heap, DYNAMIC_TYPE_TMP_BUFFER);
30334
    XFREE(dataASN, heap, DYNAMIC_TYPE_TMP_BUFFER);
30335
    (void)heap;
30336
    return ret;
30337
#endif
30338
}
30339
int SetName(byte* output, word32 outputSz, CertName* name)
30340
{
30341
    return SetNameEx(output, outputSz, name, NULL);
30342
}
30343
30344
#ifdef WOLFSSL_ASN_TEMPLATE
30345
static int EncodePublicKey(int keyType, byte* output, int outLen,
30346
                           RsaKey* rsaKey, ecc_key* eccKey,
30347
                           ed25519_key* ed25519Key, ed448_key* ed448Key,
30348
                           DsaKey* dsaKey, falcon_key* falconKey,
30349
                           dilithium_key* dilithiumKey, sphincs_key* sphincsKey)
30350
{
30351
    int ret = 0;
30352
30353
    (void)outLen;
30354
    (void)rsaKey;
30355
    (void)eccKey;
30356
    (void)ed25519Key;
30357
    (void)ed448Key;
30358
    (void)dsaKey;
30359
    (void)falconKey;
30360
    (void)dilithiumKey;
30361
    (void)sphincsKey;
30362
30363
    switch (keyType) {
30364
    #ifndef NO_RSA
30365
        case RSA_KEY:
30366
            ret = SetRsaPublicKey(output, rsaKey, outLen, 1);
30367
            if (ret <= 0) {
30368
                ret = PUBLIC_KEY_E;
30369
            }
30370
            break;
30371
    #endif
30372
    #ifdef HAVE_ECC
30373
        case ECC_KEY:
30374
            ret = SetEccPublicKey(output, eccKey, outLen, 1, 0);
30375
            if (ret <= 0) {
30376
                ret = PUBLIC_KEY_E;
30377
            }
30378
            break;
30379
    #endif /* HAVE_ECC */
30380
    #ifdef HAVE_ED25519
30381
        case ED25519_KEY:
30382
            ret = wc_Ed25519PublicKeyToDer(ed25519Key, output,
30383
                                           (word32)outLen, 1);
30384
            if (ret <= 0) {
30385
                ret = PUBLIC_KEY_E;
30386
            }
30387
            break;
30388
    #endif
30389
    #ifdef HAVE_ED448
30390
        case ED448_KEY:
30391
            ret = wc_Ed448PublicKeyToDer(ed448Key, output, (word32)outLen, 1);
30392
            if (ret <= 0) {
30393
                ret = PUBLIC_KEY_E;
30394
            }
30395
            break;
30396
    #endif
30397
    #if defined(HAVE_FALCON)
30398
        case FALCON_LEVEL1_KEY:
30399
        case FALCON_LEVEL5_KEY:
30400
            ret = wc_Falcon_PublicKeyToDer(falconKey, output,
30401
                                           (word32)outLen, 1);
30402
            if (ret <= 0) {
30403
                ret = PUBLIC_KEY_E;
30404
            }
30405
            break;
30406
    #endif /* HAVE_FALCON */
30407
    #if defined(HAVE_DILITHIUM) && !defined(WOLFSSL_DILITHIUM_NO_ASN1)
30408
        #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
30409
        case DILITHIUM_LEVEL2_KEY:
30410
        case DILITHIUM_LEVEL3_KEY:
30411
        case DILITHIUM_LEVEL5_KEY:
30412
        #endif
30413
        case ML_DSA_LEVEL2_KEY:
30414
        case ML_DSA_LEVEL3_KEY:
30415
        case ML_DSA_LEVEL5_KEY:
30416
            ret = wc_Dilithium_PublicKeyToDer(dilithiumKey, output,
30417
                                              (word32)outLen, 1);
30418
            if (ret <= 0) {
30419
                ret = PUBLIC_KEY_E;
30420
            }
30421
            break;
30422
    #endif /* HAVE_DILITHIUM */
30423
    #if defined(HAVE_SPHINCS)
30424
        case SPHINCS_FAST_LEVEL1_KEY:
30425
        case SPHINCS_FAST_LEVEL3_KEY:
30426
        case SPHINCS_FAST_LEVEL5_KEY:
30427
        case SPHINCS_SMALL_LEVEL1_KEY:
30428
        case SPHINCS_SMALL_LEVEL3_KEY:
30429
        case SPHINCS_SMALL_LEVEL5_KEY:
30430
            ret = wc_Sphincs_PublicKeyToDer(sphincsKey, output,
30431
                                            (word32)outLen, 1);
30432
            if (ret <= 0) {
30433
                ret = PUBLIC_KEY_E;
30434
            }
30435
            break;
30436
    #endif /* HAVE_SPHINCS */
30437
        default:
30438
            ret = PUBLIC_KEY_E;
30439
            break;
30440
    }
30441
30442
    return ret;
30443
}
30444
30445
/* ASN.1 template for certificate extensions.
30446
 * X.509: RFC 5280, 4.1 - Basic Certificate Fields.
30447
 * All extensions supported for encoding are described.
30448
 */
30449
static const ASNItem static_certExtsASN[] = {
30450
            /* Basic Constraints Extension - 4.2.1.9 */
30451
/* BC_SEQ        */    { 0, ASN_SEQUENCE, 1, 1, 0 },
30452
/* BC_OID        */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
30453
/* BC_CRIT       */        { 1, ASN_BOOLEAN, 0, 0, 0 },
30454
/* BC_STR        */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
30455
/* BC_STR_SEQ    */            { 2, ASN_SEQUENCE, 1, 1, 0 },
30456
                                                   /* cA */
30457
/* BC_CA         */                { 3, ASN_BOOLEAN, 0, 0, 0 },
30458
                                                   /* pathLenConstraint */
30459
/* BC_PATHLEN    */                { 3, ASN_INTEGER, 0, 0, 1 },
30460
                                       /* Subject Alternative Name - 4.2.1.6  */
30461
/* SAN_SEQ       */    { 0, ASN_SEQUENCE, 1, 1, 0 },
30462
/* SAN_OID       */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
30463
/* SAN_CRIT      */        { 1, ASN_BOOLEAN, 0, 0, 0 },
30464
/* SAN_STR       */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
30465
            /* Subject Key Identifier - 4.2.1.2 */
30466
/* SKID_SEQ      */    { 0, ASN_SEQUENCE, 1, 1, 0 },
30467
/* SKID_OID      */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
30468
/* SKID_STR      */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
30469
/* SKID_KEYID    */            { 2, ASN_OCTET_STRING, 0, 0, 0 },
30470
                                       /* Authority Key Identifier - 4.2.1.1 */
30471
/* AKID_SEQ      */    { 0, ASN_SEQUENCE, 1, 1, 0 },
30472
/* AKID_OID      */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
30473
/* AKID_STR      */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
30474
/* AKID_STR_SEQ, */            { 2, ASN_SEQUENCE, 1, 1, 0 },
30475
/* AKID_KEYID    */                { 3, ASN_CONTEXT_SPECIFIC | 0, 0, 0, 0 },
30476
                                       /* Key Usage - 4.2.1.3 */
30477
/* KU_SEQ        */    { 0, ASN_SEQUENCE, 1, 1, 0 },
30478
/* KU_OID        */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
30479
/* KU_CRIT       */        { 1, ASN_BOOLEAN, 0, 0, 0 },
30480
/* KU_STR        */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
30481
/* KU_USAGE      */            { 2, ASN_BIT_STRING, 0, 0, 0 },
30482
                                       /* Extended Key Usage - 4,2,1,12 */
30483
/* EKU_SEQ       */    { 0, ASN_SEQUENCE, 1, 1, 0 },
30484
/* EKU_OID       */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
30485
/* EKU_STR       */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
30486
                                       /* Certificate Policies - 4.2.1.4 */
30487
/* POLICIES_SEQ, */    { 0, ASN_SEQUENCE, 1, 1, 0 },
30488
/* POLICIES_OID, */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
30489
/* POLICIES_STR, */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
30490
/* POLICIES_INFO */            { 2, ASN_SEQUENCE, 1, 0, 0 },
30491
                                       /* Netscape Certificate Type */
30492
/* NSTYPE_SEQ    */    { 0, ASN_SEQUENCE, 1, 1, 0 },
30493
/* NSTYPE_OID    */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
30494
/* NSTYPE_STR    */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
30495
/* NSTYPE_USAGE, */            { 2, ASN_BIT_STRING, 0, 0, 0 },
30496
/* CRLINFO_SEQ   */    { 0, ASN_SEQUENCE, 1, 1, 0 },
30497
/* CRLINFO_OID   */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
30498
/* CRLINFO_STR   */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
30499
#ifdef WOLFSSL_DUAL_ALG_CERTS
30500
/* SAPKI_SEQ     */    { 0, ASN_SEQUENCE, 1, 1, 0 },
30501
/* SAPKI_OID     */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
30502
/* SAPKI_CRIT    */        { 1, ASN_BOOLEAN, 0, 0, 0 },
30503
/* SAPKI_STR     */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
30504
/* ALTSIGALG_SEQ */    { 0, ASN_SEQUENCE, 1, 1, 0 },
30505
/* ALTSIGALG_OID */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
30506
/* ALTSIGALG_CRIT*/        { 1, ASN_BOOLEAN, 0, 0, 0 },
30507
/* ALTSIGALG_STR */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
30508
/* ALTSIGVAL_SEQ */    { 0, ASN_SEQUENCE, 1, 1, 0 },
30509
/* ALTSIGVAL_OID */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
30510
/* ALTSIGVAL_CRIT*/        { 1, ASN_BOOLEAN, 0, 0, 0 },
30511
/* ALTSIGVAL_STR */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
30512
#endif /* WOLFSSL_DUAL_ALG_CERTS */
30513
/* CUSTOM_SEQ    */    { 0, ASN_SEQUENCE, 1, 1, 0 },
30514
/* CUSTOM_OID    */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
30515
/* CUSTOM_STR    */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
30516
};
30517
enum {
30518
    CERTEXTSASN_IDX_BC_SEQ = 0,
30519
    CERTEXTSASN_IDX_BC_OID,
30520
    CERTEXTSASN_IDX_BC_CRIT,
30521
    CERTEXTSASN_IDX_BC_STR,
30522
    CERTEXTSASN_IDX_BC_STR_SEQ,
30523
    CERTEXTSASN_IDX_BC_CA,
30524
    CERTEXTSASN_IDX_BC_PATHLEN,
30525
    CERTEXTSASN_IDX_SAN_SEQ,
30526
    CERTEXTSASN_IDX_SAN_OID,
30527
    CERTEXTSASN_IDX_SAN_CRIT,
30528
    CERTEXTSASN_IDX_SAN_STR,
30529
    CERTEXTSASN_IDX_SKID_SEQ,
30530
    CERTEXTSASN_IDX_SKID_OID,
30531
    CERTEXTSASN_IDX_SKID_STR,
30532
    CERTEXTSASN_IDX_SKID_KEYID,
30533
    CERTEXTSASN_IDX_AKID_SEQ,
30534
    CERTEXTSASN_IDX_AKID_OID,
30535
    CERTEXTSASN_IDX_AKID_STR,
30536
    CERTEXTSASN_IDX_AKID_STR_SEQ,
30537
    CERTEXTSASN_IDX_AKID_KEYID,
30538
    CERTEXTSASN_IDX_KU_SEQ,
30539
    CERTEXTSASN_IDX_KU_OID,
30540
    CERTEXTSASN_IDX_KU_CRIT,
30541
    CERTEXTSASN_IDX_KU_STR,
30542
    CERTEXTSASN_IDX_KU_USAGE,
30543
    CERTEXTSASN_IDX_EKU_SEQ,
30544
    CERTEXTSASN_IDX_EKU_OID,
30545
    CERTEXTSASN_IDX_EKU_STR,
30546
    CERTEXTSASN_IDX_POLICIES_SEQ,
30547
    CERTEXTSASN_IDX_POLICIES_OID,
30548
    CERTEXTSASN_IDX_POLICIES_STR,
30549
    CERTEXTSASN_IDX_POLICIES_INFO,
30550
    CERTEXTSASN_IDX_NSTYPE_SEQ,
30551
    CERTEXTSASN_IDX_NSTYPE_OID,
30552
    CERTEXTSASN_IDX_NSTYPE_STR,
30553
    CERTEXTSASN_IDX_NSTYPE_USAGE,
30554
    CERTEXTSASN_IDX_CRLINFO_SEQ,
30555
    CERTEXTSASN_IDX_CRLINFO_OID,
30556
    CERTEXTSASN_IDX_CRLINFO_STR,
30557
#ifdef WOLFSSL_DUAL_ALG_CERTS
30558
    CERTEXTSASN_IDX_SAPKI_SEQ,
30559
    CERTEXTSASN_IDX_SAPKI_OID,
30560
    CERTEXTSASN_IDX_SAPKI_CRIT,
30561
    CERTEXTSASN_IDX_SAPKI_STR,
30562
    CERTEXTSASN_IDX_ALTSIGALG_SEQ,
30563
    CERTEXTSASN_IDX_ALTSIGALG_OID,
30564
    CERTEXTSASN_IDX_ALTSIGALG_CRIT,
30565
    CERTEXTSASN_IDX_ALTSIGALG_STR,
30566
    CERTEXTSASN_IDX_ALTSIGVAL_SEQ,
30567
    CERTEXTSASN_IDX_ALTSIGVAL_OID,
30568
    CERTEXTSASN_IDX_ALTSIGVAL_CRIT,
30569
    CERTEXTSASN_IDX_ALTSIGVAL_STR,
30570
#endif /* WOLFSSL_DUAL_ALG_CERTS */
30571
    CERTEXTSASN_IDX_CUSTOM_SEQ,
30572
    CERTEXTSASN_IDX_CUSTOM_OID,
30573
    CERTEXTSASN_IDX_CUSTOM_STR,
30574
    CERTEXTSASN_IDX_START_CUSTOM
30575
};
30576
30577
/* Number of items in ASN.1 template for certificate extensions. We multiply
30578
 * by 4 because there are 4 things (seq, OID, crit flag, octet string). */
30579
#define certExtsASN_Length ((sizeof(static_certExtsASN) / sizeof(ASNItem)) \
30580
                            + (NUM_CUSTOM_EXT * 4))
30581
30582
static const ASNItem customExtASN[] = {
30583
/* CUSTOM_SEQ    */    { 0, ASN_SEQUENCE, 1, 1, 0 },
30584
/* CUSTOM_OID    */        { 1, ASN_OBJECT_ID, 0, 0, 0 },
30585
/* CUSTOM_CRIT   */        { 1, ASN_BOOLEAN, 0, 0, 0 },
30586
/* CUSTOM_STR    */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
30587
};
30588
30589
static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz,
30590
                            int forRequest)
30591
{
30592
    DECL_ASNSETDATA(dataASN, certExtsASN_Length);
30593
    int sz = 0;
30594
    int ret = 0;
30595
    int i = 0;
30596
    static const byte bcOID[]   = { 0x55, 0x1d, 0x13 };
30597
#ifdef WOLFSSL_ALT_NAMES
30598
    static const byte sanOID[]  = { 0x55, 0x1d, 0x11 };
30599
#endif
30600
#ifdef WOLFSSL_CERT_EXT
30601
    static const byte skidOID[] = { 0x55, 0x1d, 0x0e };
30602
    static const byte akidOID[] = { 0x55, 0x1d, 0x23 };
30603
    static const byte kuOID[]   = { 0x55, 0x1d, 0x0f };
30604
    static const byte ekuOID[]  = { 0x55, 0x1d, 0x25 };
30605
    static const byte cpOID[]   = { 0x55, 0x1d, 0x20 };
30606
    static const byte nsCertOID[] = { 0x60, 0x86, 0x48, 0x01,
30607
                                      0x86, 0xF8, 0x42, 0x01, 0x01 };
30608
    static const byte crlInfoOID[] = { 0x55, 0x1D, 0x1F };
30609
#ifdef WOLFSSL_DUAL_ALG_CERTS
30610
    static const byte sapkiOID[] = { 0x55, 0x1d, 0x48 };
30611
    static const byte altSigAlgOID[] = { 0x55, 0x1d, 0x49 };
30612
    static const byte altSigValOID[] = { 0x55, 0x1d, 0x4a };
30613
#endif /* WOLFSSL_DUAL_ALG_CERTS */
30614
#endif /* WOLFSSL_CERT_EXT */
30615
30616
#ifdef WOLFSSL_SMALL_STACK
30617
#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_CERT_EXT)
30618
    byte *encodedOids;
30619
#endif
30620
    ASNItem *certExtsASN = (ASNItem *)XMALLOC(certExtsASN_Length *
30621
                                              sizeof(ASNItem), cert->heap,
30622
                                              DYNAMIC_TYPE_TMP_BUFFER);
30623
    if (certExtsASN == NULL) {
30624
        return MEMORY_E;
30625
    }
30626
30627
#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_CERT_EXT)
30628
    encodedOids = (byte *)XMALLOC(NUM_CUSTOM_EXT * MAX_OID_SZ, cert->heap,
30629
                                  DYNAMIC_TYPE_TMP_BUFFER);
30630
    if (encodedOids == NULL) {
30631
        XFREE(certExtsASN, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
30632
        return MEMORY_E;
30633
    }
30634
#endif
30635
#else
30636
    ASNItem certExtsASN[certExtsASN_Length];
30637
#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_CERT_EXT)
30638
    byte encodedOids[NUM_CUSTOM_EXT * MAX_OID_SZ];
30639
#endif
30640
#endif
30641
30642
    /* Clone static_certExtsASN into a certExtsASN and then fill the rest of it
30643
     * with (NUM_CUSTOM_EXT*4) more ASNItems specifying extensions. See comment
30644
     * above definition of certExtsASN_Length. */
30645
    XMEMCPY(certExtsASN, static_certExtsASN, sizeof(static_certExtsASN));
30646
    for (i = sizeof(static_certExtsASN) / sizeof(ASNItem);
30647
         i < (int)certExtsASN_Length; i += 4) {
30648
        XMEMCPY(&certExtsASN[i], customExtASN, sizeof(customExtASN));
30649
    }
30650
30651
    (void)forRequest;
30652
30653
    CALLOC_ASNSETDATA(dataASN, certExtsASN_Length, ret, cert->heap);
30654
30655
    if (ret == 0) {
30656
        if (cert->isCA) {
30657
            /* Set Basic Constraints to be a Certificate Authority. */
30658
            SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_BC_CA], 1);
30659
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_BC_OID], bcOID, sizeof(bcOID));
30660
            if (cert->basicConstCrit) {
30661
                SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_BC_CRIT], 1);
30662
            }
30663
            else {
30664
                dataASN[CERTEXTSASN_IDX_BC_CRIT].noOut = 1;
30665
            }
30666
            if (cert->pathLenSet
30667
            #ifdef WOLFSSL_CERT_EXT
30668
                && ((cert->keyUsage & KEYUSE_KEY_CERT_SIGN) || (!cert->keyUsage))
30669
            #endif
30670
            ) {
30671
                SetASN_Int8Bit(&dataASN[CERTEXTSASN_IDX_BC_PATHLEN],
30672
                        cert->pathLen);
30673
            }
30674
            else {
30675
                dataASN[CERTEXTSASN_IDX_BC_PATHLEN].noOut = 1;
30676
            }
30677
        }
30678
    #ifdef WOLFSSL_ALLOW_ENCODING_CA_FALSE
30679
        else if (cert->isCaSet) {
30680
            SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_BC_CA], 0);
30681
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_BC_OID], bcOID, sizeof(bcOID));
30682
            if (cert->basicConstCrit) {
30683
                SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_BC_CRIT], 1);
30684
            }
30685
            else {
30686
                dataASN[CERTEXTSASN_IDX_BC_CRIT].noOut = 1;
30687
            }
30688
            dataASN[CERTEXTSASN_IDX_BC_PATHLEN].noOut = 1;
30689
        }
30690
    #endif
30691
        else if (cert->basicConstSet) {
30692
            /* Set Basic Constraints to be a non Certificate Authority. */
30693
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_BC_OID], bcOID, sizeof(bcOID));
30694
            if (cert->basicConstCrit) {
30695
                SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_BC_CRIT], 1);
30696
            }
30697
            else {
30698
                dataASN[CERTEXTSASN_IDX_BC_CRIT].noOut = 1;
30699
            }
30700
            dataASN[CERTEXTSASN_IDX_BC_CA].noOut = 1;
30701
            dataASN[CERTEXTSASN_IDX_BC_PATHLEN].noOut = 1;
30702
        }
30703
        else {
30704
            /* Don't write out Basic Constraints extension items. */
30705
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_BC_SEQ,
30706
                    CERTEXTSASN_IDX_BC_PATHLEN);
30707
        }
30708
    #ifdef WOLFSSL_ALT_NAMES
30709
        if (cert->altNamesSz > 0) {
30710
            /* Set Subject Alternative Name OID and data. */
30711
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_SAN_OID],
30712
                    sanOID, sizeof(sanOID));
30713
            if (cert->altNamesCrit) {
30714
                SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_SAN_CRIT], 1);
30715
            }
30716
            else {
30717
                dataASN[CERTEXTSASN_IDX_SAN_CRIT].noOut = 1;
30718
            }
30719
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_SAN_STR],
30720
                          cert->altNames, (word32)cert->altNamesSz);
30721
        }
30722
        else
30723
    #endif
30724
        {
30725
            /* Don't write out Subject Alternative Name extension items. */
30726
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_SAN_SEQ,
30727
                    CERTEXTSASN_IDX_SAN_STR);
30728
        }
30729
    #ifdef WOLFSSL_CERT_EXT
30730
        if (cert->skidSz > 0) {
30731
            /* Set Subject Key Identifier OID and data. */
30732
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_SKID_OID],
30733
                    skidOID, sizeof(skidOID));
30734
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_SKID_KEYID],
30735
                          cert->skid, (word32)cert->skidSz);
30736
        }
30737
        else
30738
    #endif
30739
        {
30740
            /* Don't write out Subject Key Identifier extension items. */
30741
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_SKID_SEQ,
30742
                    CERTEXTSASN_IDX_SKID_KEYID);
30743
        }
30744
    #ifdef WOLFSSL_CERT_EXT
30745
        if (cert->akidSz > 0) {
30746
            /* Set Authority Key Identifier OID and data. */
30747
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_AKID_OID],
30748
                    akidOID, sizeof(akidOID));
30749
        #ifdef WOLFSSL_AKID_NAME
30750
            if (cert->rawAkid) {
30751
                SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_AKID_STR],
30752
                        cert->akid, (word32)cert->akidSz);
30753
                /* cert->akid contains the internal ext structure */
30754
                SetASNItem_NoOutBelow(dataASN, certExtsASN,
30755
                        CERTEXTSASN_IDX_AKID_STR, certExtsASN_Length);
30756
            }
30757
            else
30758
        #endif
30759
            {
30760
                SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_AKID_KEYID],
30761
                        cert->akid, (word32)cert->akidSz);
30762
            }
30763
        }
30764
        else
30765
    #endif
30766
        {
30767
            /* Don't write out Authority Key Identifier extension items. */
30768
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_AKID_SEQ,
30769
                    CERTEXTSASN_IDX_AKID_KEYID);
30770
        }
30771
    #ifdef WOLFSSL_CERT_EXT
30772
        if (cert->keyUsage != 0) {
30773
            /* Set Key Usage OID, critical and value. */
30774
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_KU_OID],
30775
                    kuOID, sizeof(kuOID));
30776
            SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_KU_CRIT], 1);
30777
            SetASN_Int16Bit(&dataASN[CERTEXTSASN_IDX_KU_USAGE],
30778
                    cert->keyUsage);
30779
        }
30780
        else
30781
    #endif
30782
        {
30783
            /* Don't write out Key Usage extension items. */
30784
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_KU_SEQ,
30785
                    CERTEXTSASN_IDX_KU_USAGE);
30786
        }
30787
    #ifdef WOLFSSL_CERT_EXT
30788
        if (cert->extKeyUsage != 0) {
30789
            /* Calculate size of Extended Key Usage data. */
30790
            sz = SetExtKeyUsage(cert, NULL, 0, cert->extKeyUsage);
30791
            if (sz <= 0) {
30792
                ret = KEYUSAGE_E;
30793
            }
30794
            /* Set Extended Key Usage OID and data. */
30795
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_EKU_OID],
30796
                    ekuOID, sizeof(ekuOID));
30797
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_EKU_STR],
30798
                    NULL, (word32)sz);
30799
        }
30800
        else
30801
    #endif
30802
        {
30803
            /* Don't write out Extended Key Usage extension items. */
30804
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_EKU_SEQ,
30805
                    CERTEXTSASN_IDX_EKU_STR);
30806
        }
30807
30808
    #ifdef WOLFSSL_CERT_EXT
30809
        if ((!forRequest) && (cert->certPoliciesNb > 0)) {
30810
            /* Calculate size of certificate policies. */
30811
            sz = SetCertificatePolicies(NULL, 0, cert->certPolicies,
30812
                    cert->certPoliciesNb, cert->heap);
30813
            if (sz > 0) {
30814
                /* Set Certificate Policies OID. */
30815
                SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_POLICIES_OID],
30816
                        cpOID, sizeof(cpOID));
30817
                /* Make space for data. */
30818
                SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_POLICIES_INFO],
30819
                        NULL, (word32)sz);
30820
            }
30821
            else {
30822
                ret = CERTPOLICIES_E;
30823
            }
30824
        }
30825
        else
30826
    #endif
30827
        {
30828
            /* Don't write out Certificate Policies extension items. */
30829
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_POLICIES_SEQ,
30830
                    CERTEXTSASN_IDX_POLICIES_INFO);
30831
        }
30832
    #if defined(WOLFSSL_CERT_EXT) && !defined(IGNORE_NETSCAPE_CERT_TYPE)
30833
        /* Netscape Certificate Type */
30834
        if (cert->nsCertType != 0) {
30835
            /* Set Netscape Certificate Type OID and data. */
30836
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_NSTYPE_OID],
30837
                    nsCertOID, sizeof(nsCertOID));
30838
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_NSTYPE_USAGE],
30839
                    &cert->nsCertType, 1);
30840
        }
30841
        else
30842
    #endif
30843
        {
30844
            /* Don't write out Netscape Certificate Type. */
30845
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_NSTYPE_SEQ,
30846
                    CERTEXTSASN_IDX_NSTYPE_USAGE);
30847
        }
30848
    #ifdef WOLFSSL_CERT_EXT
30849
        if (cert->crlInfoSz > 0) {
30850
            /* Set CRL Distribution Points OID and data. */
30851
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_CRLINFO_OID],
30852
                    crlInfoOID, sizeof(crlInfoOID));
30853
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_CRLINFO_STR],
30854
                    cert->crlInfo, (word32)cert->crlInfoSz);
30855
        }
30856
        else
30857
    #endif
30858
        {
30859
            /* Don't write out CRL Distribution Points. */
30860
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_CRLINFO_SEQ,
30861
                    CERTEXTSASN_IDX_CRLINFO_STR);
30862
        }
30863
30864
    #ifdef WOLFSSL_DUAL_ALG_CERTS
30865
        if (cert->sapkiDer != NULL) {
30866
            /* Set subject alternative public key info OID, criticality and
30867
             * data. */
30868
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_SAPKI_OID], sapkiOID,
30869
                    sizeof(sapkiOID));
30870
            if (cert->sapkiCrit) {
30871
                SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_SAPKI_CRIT], 1);
30872
            }
30873
            else {
30874
                dataASN[CERTEXTSASN_IDX_SAPKI_CRIT].noOut = 1;
30875
            }
30876
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_SAPKI_STR], cert->sapkiDer,
30877
                    cert->sapkiLen);
30878
        }
30879
        else {
30880
            /* Don't write out subject alternative public key info. */
30881
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_SAPKI_SEQ,
30882
                    CERTEXTSASN_IDX_SAPKI_STR);
30883
        }
30884
30885
        if (cert->altSigAlgDer != NULL) {
30886
            /* Set alternative signature algorithm OID, criticality and data. */
30887
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_ALTSIGALG_OID], altSigAlgOID,
30888
                    sizeof(altSigAlgOID));
30889
            if (cert->altSigAlgCrit) {
30890
                SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_ALTSIGALG_CRIT], 1);
30891
            }
30892
            else {
30893
                dataASN[CERTEXTSASN_IDX_ALTSIGALG_CRIT].noOut = 1;
30894
            }
30895
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_ALTSIGALG_STR],
30896
                    cert->altSigAlgDer, cert->altSigAlgLen);
30897
        }
30898
        else {
30899
            /* Don't write out alternative signature algorithm. */
30900
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_ALTSIGALG_SEQ,
30901
                    CERTEXTSASN_IDX_ALTSIGALG_STR);
30902
        }
30903
30904
        if (cert->altSigValDer != NULL) {
30905
            /* Set alternative signature value OID, criticality and data. */
30906
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_ALTSIGVAL_OID], altSigValOID,
30907
                    sizeof(altSigValOID));
30908
            if (cert->altSigValCrit) {
30909
                SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_ALTSIGVAL_CRIT], 1);
30910
            }
30911
            else {
30912
                dataASN[CERTEXTSASN_IDX_ALTSIGVAL_CRIT].noOut = 1;
30913
            }
30914
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_ALTSIGVAL_STR],
30915
                    cert->altSigValDer, cert->altSigValLen);
30916
        }
30917
        else {
30918
            /* Don't write out alternative signature value. */
30919
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_ALTSIGVAL_SEQ,
30920
                    CERTEXTSASN_IDX_ALTSIGVAL_STR);
30921
        }
30922
    #endif /* WOLFSSL_DUAL_ALG_CERTS */
30923
30924
    #if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CUSTOM_OID)
30925
        /* encode a custom oid and value */
30926
        if (cert->extCustom.oidSz > 0) {
30927
            /* Set CRL Distribution Points OID and data. */
30928
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_CUSTOM_OID],
30929
                    cert->extCustom.oid, cert->extCustom.oidSz);
30930
            SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_CUSTOM_STR],
30931
                    cert->extCustom.val, cert->extCustom.valSz);
30932
        }
30933
        else
30934
    #endif
30935
        {
30936
            /* Don't write out custom OID. */
30937
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_CUSTOM_SEQ,
30938
                    CERTEXTSASN_IDX_CUSTOM_STR);
30939
        }
30940
30941
        i = 0;
30942
    #if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CUSTOM_OID)
30943
        for (; i < cert->customCertExtCount; i++) {
30944
             int idx = CERTEXTSASN_IDX_START_CUSTOM + (i * 4);
30945
             word32 encodedOidSz = MAX_OID_SZ;
30946
             idx++; /* Skip one for for SEQ. */
30947
             /* EncodePolicyOID() will never return error since we parsed this
30948
              * OID when it was set. */
30949
             EncodePolicyOID(&encodedOids[i * MAX_OID_SZ], &encodedOidSz,
30950
                             cert->customCertExt[i].oid, NULL);
30951
             SetASN_Buffer(&dataASN[idx], &encodedOids[i * MAX_OID_SZ],
30952
                           encodedOidSz);
30953
             idx++;
30954
             if (cert->customCertExt[i].crit) {
30955
                 SetASN_Boolean(&dataASN[idx], 1);
30956
             } else {
30957
                 dataASN[idx].noOut = 1;
30958
             }
30959
             idx++;
30960
             SetASN_Buffer(&dataASN[idx], cert->customCertExt[i].val,
30961
                           cert->customCertExt[i].valSz);
30962
        }
30963
    #endif
30964
30965
        while (i < NUM_CUSTOM_EXT) {
30966
            SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_START_CUSTOM + (i * 4),
30967
                             CERTEXTSASN_IDX_START_CUSTOM + (i * 4) + 3);
30968
            i++;
30969
        }
30970
    }
30971
30972
    if (ret == 0) {
30973
        /* Calculate size of encoded extensions. */
30974
        ret = SizeASN_Items(certExtsASN, dataASN, certExtsASN_Length, &sz);
30975
    }
30976
    if (ret == 0) {
30977
        /* Only SEQUENCE - don't encode extensions. */
30978
        if (sz == 2) {
30979
            sz = 0;
30980
        }
30981
        /* Check buffer is big enough. */
30982
        else if ((output != NULL) && (sz > (int)maxSz)) {
30983
            ret = BUFFER_E;
30984
        }
30985
    }
30986
30987
    if ((ret == 0) && (output != NULL) && (sz > 0)) {
30988
        /* Encode certificate extensions into buffer. */
30989
        SetASN_Items(certExtsASN, dataASN, certExtsASN_Length, output);
30990
30991
    #ifdef WOLFSSL_CERT_EXT
30992
        if (cert->extKeyUsage != 0){
30993
            /* Encode Extended Key Usage into space provided. */
30994
            if (SetExtKeyUsage(cert,
30995
                    (byte*)dataASN[CERTEXTSASN_IDX_EKU_STR].data.buffer.data,
30996
                    dataASN[CERTEXTSASN_IDX_EKU_STR].data.buffer.length,
30997
                    cert->extKeyUsage) <= 0) {
30998
                ret = KEYUSAGE_E;
30999
            }
31000
        }
31001
        if ((!forRequest) && (cert->certPoliciesNb > 0)) {
31002
            /* Encode Certificate Policies into space provided. */
31003
            if (SetCertificatePolicies(
31004
                    (byte*)dataASN[CERTEXTSASN_IDX_POLICIES_INFO].data.buffer.data,
31005
                    dataASN[CERTEXTSASN_IDX_POLICIES_INFO].data.buffer.length,
31006
                    cert->certPolicies, cert->certPoliciesNb, cert->heap) <= 0) {
31007
                ret = CERTPOLICIES_E;
31008
            }
31009
        }
31010
    #endif
31011
    }
31012
    if (ret == 0) {
31013
        /* Return the encoding size. */
31014
        ret = sz;
31015
    }
31016
31017
    FREE_ASNSETDATA(dataASN, cert->heap);
31018
#ifdef WOLFSSL_SMALL_STACK
31019
#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_CERT_EXT)
31020
    XFREE(encodedOids, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
31021
#endif
31022
    XFREE(certExtsASN, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
31023
#endif
31024
31025
    return ret;
31026
}
31027
#endif /* WOLFSSL_ASN_TEMPLATE */
31028
31029
#ifndef WOLFSSL_ASN_TEMPLATE
31030
/* Set Date validity from now until now + daysValid
31031
 * return size in bytes written to output, 0 on error */
31032
/* TODO https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.5
31033
 * "MUST always encode certificate validity dates through the year 2049 as
31034
 *  UTCTime; certificate validity dates in 2050 or later MUST be encoded as
31035
 *  GeneralizedTime." */
31036
static int SetValidity(byte* output, int daysValid)
31037
{
31038
#ifndef NO_ASN_TIME
31039
    byte before[MAX_DATE_SIZE];
31040
    byte  after[MAX_DATE_SIZE];
31041
31042
    word32 beforeSz, afterSz, seqSz;
31043
31044
    time_t now;
31045
    time_t then;
31046
    struct tm* tmpTime;
31047
    struct tm* expandedTime;
31048
    struct tm localTime;
31049
31050
#if defined(NEED_TMP_TIME)
31051
    /* for use with gmtime_r */
31052
    struct tm tmpTimeStorage;
31053
    tmpTime = &tmpTimeStorage;
31054
#else
31055
    tmpTime = NULL;
31056
#endif
31057
    (void)tmpTime;
31058
31059
    now = wc_Time(0);
31060
31061
    /* before now */
31062
    before[0] = ASN_GENERALIZED_TIME;
31063
    beforeSz = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1;  /* gen tag */
31064
31065
    /* subtract 1 day of seconds for more compliance */
31066
    then = now - 86400;
31067
    expandedTime = XGMTIME(&then, tmpTime);
31068
    if (ValidateGmtime(expandedTime)) {
31069
        WOLFSSL_MSG("XGMTIME failed");
31070
        return 0;   /* error */
31071
    }
31072
    localTime = *expandedTime;
31073
31074
    /* adjust */
31075
    localTime.tm_year += 1900;
31076
    localTime.tm_mon +=    1;
31077
31078
    SetTime(&localTime, before + beforeSz);
31079
    beforeSz += ASN_GEN_TIME_SZ;
31080
31081
    after[0] = ASN_GENERALIZED_TIME;
31082
    afterSz  = SetLength(ASN_GEN_TIME_SZ, after + 1) + 1;  /* gen tag */
31083
31084
    /* add daysValid of seconds */
31085
    then = now + (daysValid * (time_t)86400);
31086
    expandedTime = XGMTIME(&then, tmpTime);
31087
    if (ValidateGmtime(expandedTime)) {
31088
        WOLFSSL_MSG("XGMTIME failed");
31089
        return 0;   /* error */
31090
    }
31091
    localTime = *expandedTime;
31092
31093
    /* adjust */
31094
    localTime.tm_year += 1900;
31095
    localTime.tm_mon  +=    1;
31096
31097
    SetTime(&localTime, after + afterSz);
31098
    afterSz += ASN_GEN_TIME_SZ;
31099
31100
    /* headers and output */
31101
    seqSz = SetSequence(beforeSz + afterSz, output);
31102
    XMEMCPY(output + seqSz, before, beforeSz);
31103
    XMEMCPY(output + seqSz + beforeSz, after, afterSz);
31104
31105
    return (int)(seqSz + beforeSz + afterSz);
31106
#else
31107
    (void)output;
31108
    (void)daysValid;
31109
    return NOT_COMPILED_IN;
31110
#endif
31111
}
31112
#else
31113
static int SetValidity(byte* before, byte* after, int daysValid)
31114
{
31115
#ifndef NO_ASN_TIME
31116
    int ret = 0;
31117
    time_t now;
31118
    time_t then;
31119
    struct tm* tmpTime;
31120
    struct tm* expandedTime;
31121
    struct tm localTime;
31122
#if defined(NEED_TMP_TIME)
31123
    /* for use with gmtime_r */
31124
    struct tm tmpTimeStorage;
31125
    tmpTime = &tmpTimeStorage;
31126
#else
31127
    tmpTime = NULL;
31128
#endif
31129
    (void)tmpTime;
31130
31131
    now = wc_Time(0);
31132
31133
    /* subtract 1 day of seconds for more compliance */
31134
    then = now - 86400;
31135
    expandedTime = XGMTIME(&then, tmpTime);
31136
    if (ValidateGmtime(expandedTime)) {
31137
        WOLFSSL_MSG("XGMTIME failed");
31138
        ret = DATE_E;
31139
    }
31140
    if (ret == 0) {
31141
        localTime = *expandedTime;
31142
31143
        /* adjust */
31144
        localTime.tm_year += 1900;
31145
        localTime.tm_mon +=    1;
31146
31147
        SetTime(&localTime, before);
31148
31149
        /* add daysValid of seconds */
31150
        then = now + (daysValid * (time_t)86400);
31151
        expandedTime = XGMTIME(&then, tmpTime);
31152
        if (ValidateGmtime(expandedTime)) {
31153
            WOLFSSL_MSG("XGMTIME failed");
31154
            ret = DATE_E;
31155
        }
31156
    }
31157
    if (ret == 0) {
31158
        localTime = *expandedTime;
31159
31160
        /* adjust */
31161
        localTime.tm_year += 1900;
31162
        localTime.tm_mon  +=    1;
31163
31164
        SetTime(&localTime, after);
31165
    }
31166
31167
    return ret;
31168
#else
31169
    (void)before;
31170
    (void)after;
31171
    (void)daysValid;
31172
    return NOT_COMPILED_IN;
31173
#endif
31174
}
31175
#endif /* WOLFSSL_ASN_TEMPLATE */
31176
31177
31178
#ifndef WOLFSSL_ASN_TEMPLATE
31179
/* encode info from cert into DER encoded format */
31180
static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
31181
                      WC_RNG* rng, DsaKey* dsaKey, ed25519_key* ed25519Key,
31182
                      ed448_key* ed448Key, falcon_key* falconKey,
31183
                      dilithium_key* dilithiumKey, sphincs_key* sphincsKey)
31184
{
31185
    int ret;
31186
31187
    if (cert == NULL || der == NULL || rng == NULL)
31188
        return BAD_FUNC_ARG;
31189
31190
    /* make sure at least one key type is provided */
31191
    if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL &&
31192
        dsaKey == NULL && ed448Key == NULL && falconKey == NULL &&
31193
        dilithiumKey == NULL && sphincsKey == NULL) {
31194
        return PUBLIC_KEY_E;
31195
    }
31196
31197
    /* init */
31198
    XMEMSET(der, 0, sizeof(DerCert));
31199
31200
    /* version */
31201
    der->versionSz = SetMyVersion((word32)cert->version, der->version, TRUE);
31202
31203
    /* serial number (must be positive) */
31204
    if (cert->serialSz == 0) {
31205
        /* generate random serial */
31206
        cert->serialSz = CTC_GEN_SERIAL_SZ;
31207
        ret = wc_RNG_GenerateBlock(rng, cert->serial, (word32)cert->serialSz);
31208
        if (ret != 0)
31209
            return ret;
31210
        /* Clear the top bit to avoid a negative value */
31211
        cert->serial[0] &= 0x7f;
31212
    }
31213
    der->serialSz = SetSerialNumber(cert->serial, (word32)cert->serialSz,
31214
                                    der->serial, sizeof(der->serial),
31215
                                    CTC_SERIAL_SIZE);
31216
    if (der->serialSz < 0)
31217
        return der->serialSz;
31218
31219
    /* signature algo */
31220
    der->sigAlgoSz = (int)SetAlgoID(cert->sigType, der->sigAlgo, oidSigType, 0);
31221
    if (der->sigAlgoSz <= 0)
31222
        return ALGO_ID_E;
31223
31224
    /* public key */
31225
#ifndef NO_RSA
31226
    if (cert->keyType == RSA_KEY) {
31227
        if (rsaKey == NULL)
31228
            return PUBLIC_KEY_E;
31229
        der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey,
31230
                                           sizeof(der->publicKey), 1);
31231
    }
31232
#endif
31233
31234
#ifdef HAVE_ECC
31235
    if (cert->keyType == ECC_KEY) {
31236
        if (eccKey == NULL)
31237
            return PUBLIC_KEY_E;
31238
        der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey,
31239
                                           sizeof(der->publicKey), 1, 0);
31240
    }
31241
#endif
31242
31243
#if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
31244
    if (cert->keyType == DSA_KEY) {
31245
        if (dsaKey == NULL)
31246
            return PUBLIC_KEY_E;
31247
        der->publicKeySz = wc_SetDsaPublicKey(der->publicKey, dsaKey,
31248
                                              sizeof(der->publicKey), 1);
31249
    }
31250
#endif
31251
31252
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
31253
    if (cert->keyType == ED25519_KEY) {
31254
        if (ed25519Key == NULL)
31255
            return PUBLIC_KEY_E;
31256
        der->publicKeySz = wc_Ed25519PublicKeyToDer(ed25519Key, der->publicKey,
31257
            (word32)sizeof(der->publicKey), 1);
31258
    }
31259
#endif
31260
31261
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
31262
    if (cert->keyType == ED448_KEY) {
31263
        if (ed448Key == NULL)
31264
            return PUBLIC_KEY_E;
31265
        der->publicKeySz = wc_Ed448PublicKeyToDer(ed448Key, der->publicKey,
31266
            (word32)sizeof(der->publicKey), 1);
31267
    }
31268
#endif
31269
31270
#if defined(HAVE_FALCON)
31271
    if ((cert->keyType == FALCON_LEVEL1_KEY) ||
31272
        (cert->keyType == FALCON_LEVEL5_KEY)) {
31273
        if (falconKey == NULL)
31274
            return PUBLIC_KEY_E;
31275
31276
        der->publicKeySz =
31277
            wc_Falcon_PublicKeyToDer(falconKey, der->publicKey,
31278
                                     (word32)sizeof(der->publicKey), 1);
31279
    }
31280
#endif /* HAVE_FALCON */
31281
#if defined(HAVE_DILITHIUM) && !defined(WOLFSSL_DILITHIUM_NO_ASN1)
31282
    if ((cert->keyType == ML_DSA_LEVEL2_KEY) ||
31283
        (cert->keyType == ML_DSA_LEVEL3_KEY) ||
31284
        (cert->keyType == ML_DSA_LEVEL5_KEY)
31285
    #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
31286
     || (cert->keyType == DILITHIUM_LEVEL2_KEY)
31287
     || (cert->keyType == DILITHIUM_LEVEL3_KEY)
31288
     || (cert->keyType == DILITHIUM_LEVEL5_KEY)
31289
    #endif
31290
        ) {
31291
        if (dilithiumKey == NULL)
31292
            return PUBLIC_KEY_E;
31293
31294
        der->publicKeySz =
31295
            wc_Dilithium_PublicKeyToDer(dilithiumKey, der->publicKey,
31296
                                     (word32)sizeof(der->publicKey), 1);
31297
    }
31298
#endif /* HAVE_DILITHIUM */
31299
#if defined(HAVE_SPHINCS)
31300
    if ((cert->keyType == SPHINCS_FAST_LEVEL1_KEY) ||
31301
        (cert->keyType == SPHINCS_FAST_LEVEL3_KEY) ||
31302
        (cert->keyType == SPHINCS_FAST_LEVEL5_KEY) ||
31303
        (cert->keyType == SPHINCS_SMALL_LEVEL1_KEY) ||
31304
        (cert->keyType == SPHINCS_SMALL_LEVEL3_KEY) ||
31305
        (cert->keyType == SPHINCS_SMALL_LEVEL5_KEY)) {
31306
        if (sphincsKey == NULL)
31307
            return PUBLIC_KEY_E;
31308
31309
        der->publicKeySz =
31310
            wc_Sphincs_PublicKeyToDer(sphincsKey, der->publicKey,
31311
                                      (word32)sizeof(der->publicKey), 1);
31312
    }
31313
#endif /* HAVE_SPHINCS */
31314
31315
    if (der->publicKeySz <= 0)
31316
        return PUBLIC_KEY_E;
31317
31318
    der->validitySz = 0;
31319
    /* copy date validity if already set in cert struct */
31320
    if (cert->beforeDateSz && cert->afterDateSz) {
31321
        der->validitySz = CopyValidity(der->validity, cert);
31322
        if (der->validitySz <= 0)
31323
            return DATE_E;
31324
    }
31325
31326
    /* set date validity using daysValid if not set already */
31327
    if (der->validitySz == 0) {
31328
        der->validitySz = SetValidity(der->validity, cert->daysValid);
31329
        if (der->validitySz <= 0)
31330
            return DATE_E;
31331
    }
31332
31333
    /* subject name */
31334
#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
31335
    if (XSTRLEN((const char*)cert->sbjRaw) > 0) {
31336
        /* Use the raw subject */
31337
        word32 idx;
31338
31339
        der->subjectSz = (int)min((word32)sizeof(der->subject),
31340
                                  (word32)XSTRLEN((const char*)cert->sbjRaw));
31341
        /* header */
31342
        idx = SetSequence((word32)der->subjectSz, der->subject);
31343
        if ((word32)der->subjectSz + idx > (word32)sizeof(der->subject)) {
31344
            return SUBJECT_E;
31345
        }
31346
31347
        XMEMCPY((char*)der->subject + idx, (const char*)cert->sbjRaw,
31348
                (size_t)der->subjectSz);
31349
        der->subjectSz += (int)idx;
31350
    }
31351
    else
31352
#endif
31353
    {
31354
        /* Use the name structure */
31355
        der->subjectSz = SetNameEx(der->subject, sizeof(der->subject),
31356
                &cert->subject, cert->heap);
31357
    }
31358
    if (der->subjectSz <= 0)
31359
        return SUBJECT_E;
31360
31361
    /* issuer name */
31362
#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
31363
    if (XSTRLEN((const char*)cert->issRaw) > 0) {
31364
        /* Use the raw issuer */
31365
        word32 idx;
31366
31367
        der->issuerSz = (int)min((word32)sizeof(der->issuer),
31368
                                 (word32)XSTRLEN((const char*)cert->issRaw));
31369
31370
        /* header */
31371
        idx = SetSequence((word32)der->issuerSz, der->issuer);
31372
        if ((word32)der->issuerSz + idx > (word32)sizeof(der->issuer)) {
31373
            return ISSUER_E;
31374
        }
31375
31376
        XMEMCPY((char*)der->issuer + idx, (const char*)cert->issRaw,
31377
                (size_t)der->issuerSz);
31378
        der->issuerSz += (int)idx;
31379
    }
31380
    else
31381
#endif
31382
    {
31383
        /* Use the name structure */
31384
        der->issuerSz = SetNameEx(der->issuer, sizeof(der->issuer),
31385
                cert->selfSigned ? &cert->subject : &cert->issuer, cert->heap);
31386
    }
31387
    if (der->issuerSz <= 0)
31388
        return ISSUER_E;
31389
31390
    /* set the extensions */
31391
    der->extensionsSz = 0;
31392
31393
    /* RFC 5280 : 4.2.1.9. Basic Constraints
31394
     * The pathLenConstraint field is meaningful only if the CA boolean is
31395
     * asserted and the key usage extension, if present, asserts the
31396
     * keyCertSign bit */
31397
    /* Set CA and path length */
31398
    if ((cert->isCA) && (cert->pathLenSet)
31399
#ifdef WOLFSSL_CERT_EXT
31400
        && ((cert->keyUsage & KEYUSE_KEY_CERT_SIGN) || (!cert->keyUsage))
31401
#endif
31402
        ) {
31403
        der->caSz = SetCaWithPathLen(der->ca, sizeof(der->ca), cert->pathLen);
31404
        if (der->caSz <= 0)
31405
            return CA_TRUE_E;
31406
31407
        der->extensionsSz += der->caSz;
31408
    }
31409
#ifdef WOLFSSL_ALLOW_ENCODING_CA_FALSE
31410
    /* Set CA */
31411
    else if (cert->isCaSet) {
31412
        der->caSz = SetCaEx(der->ca, sizeof(der->ca), cert->isCA);
31413
        if (der->caSz <= 0)
31414
            return EXTENSIONS_E;
31415
31416
        der->extensionsSz += der->caSz;
31417
    }
31418
#endif
31419
    /* Set CA true */
31420
    else if (cert->isCA) {
31421
        der->caSz = SetCa(der->ca, sizeof(der->ca));
31422
        if (der->caSz <= 0)
31423
            return CA_TRUE_E;
31424
31425
        der->extensionsSz += der->caSz;
31426
    }
31427
    /* Set Basic Constraint */
31428
    else if (cert->basicConstSet) {
31429
        der->caSz = SetBC(der->ca, sizeof(der->ca));
31430
        if (der->caSz <= 0)
31431
            return EXTENSIONS_E;
31432
31433
        der->extensionsSz += der->caSz;
31434
    }
31435
    else
31436
        der->caSz = 0;
31437
31438
#ifdef WOLFSSL_ALT_NAMES
31439
    /* Alternative Name */
31440
    if (cert->altNamesSz) {
31441
        der->altNamesSz = SetAltNames(der->altNames, sizeof(der->altNames),
31442
                                      cert->altNames, (word32)cert->altNamesSz,
31443
                                      cert->altNamesCrit);
31444
        if (der->altNamesSz <= 0)
31445
            return ALT_NAME_E;
31446
31447
        der->extensionsSz += der->altNamesSz;
31448
    }
31449
    else
31450
        der->altNamesSz = 0;
31451
#endif
31452
31453
#ifdef WOLFSSL_CERT_EXT
31454
    /* SKID */
31455
    if (cert->skidSz) {
31456
        /* check the provided SKID size */
31457
        if (cert->skidSz > (int)min(CTC_MAX_SKID_SIZE, sizeof(der->skid)))
31458
            return SKID_E;
31459
31460
        /* Note: different skid buffers sizes for der (MAX_KID_SZ) and
31461
            cert (CTC_MAX_SKID_SIZE). */
31462
        der->skidSz = SetSKID(der->skid, sizeof(der->skid),
31463
                              cert->skid, (word32)cert->skidSz);
31464
        if (der->skidSz <= 0)
31465
            return SKID_E;
31466
31467
        der->extensionsSz += der->skidSz;
31468
    }
31469
    else
31470
        der->skidSz = 0;
31471
31472
    /* AKID */
31473
    if (cert->akidSz) {
31474
        /* check the provided AKID size */
31475
        if ((
31476
#ifdef WOLFSSL_AKID_NAME
31477
             !cert->rawAkid &&
31478
#endif
31479
              cert->akidSz > (int)min(CTC_MAX_AKID_SIZE, sizeof(der->akid)))
31480
#ifdef WOLFSSL_AKID_NAME
31481
          || (cert->rawAkid && cert->akidSz > (int)sizeof(der->akid))
31482
#endif
31483
             )
31484
            return AKID_E;
31485
31486
        der->akidSz = SetAKID(der->akid, sizeof(der->akid), cert->akid,
31487
                              (word32)cert->akidSz,
31488
#ifdef WOLFSSL_AKID_NAME
31489
                              cert->rawAkid
31490
#else
31491
                              0
31492
#endif
31493
                              );
31494
        if (der->akidSz <= 0)
31495
            return AKID_E;
31496
31497
        der->extensionsSz += der->akidSz;
31498
    }
31499
    else
31500
        der->akidSz = 0;
31501
31502
    /* Key Usage */
31503
    if (cert->keyUsage != 0){
31504
        der->keyUsageSz = SetKeyUsage(der->keyUsage, sizeof(der->keyUsage),
31505
                                      cert->keyUsage);
31506
        if (der->keyUsageSz <= 0)
31507
            return KEYUSAGE_E;
31508
31509
        der->extensionsSz += der->keyUsageSz;
31510
    }
31511
    else
31512
        der->keyUsageSz = 0;
31513
31514
    /* Extended Key Usage */
31515
    if (cert->extKeyUsage != 0){
31516
        der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage,
31517
                                sizeof(der->extKeyUsage), cert->extKeyUsage);
31518
        if (der->extKeyUsageSz <= 0)
31519
            return EXTKEYUSAGE_E;
31520
31521
        der->extensionsSz += der->extKeyUsageSz;
31522
    }
31523
    else
31524
        der->extKeyUsageSz = 0;
31525
31526
#ifndef IGNORE_NETSCAPE_CERT_TYPE
31527
    /* Netscape Certificate Type */
31528
    if (cert->nsCertType != 0) {
31529
        der->nsCertTypeSz = SetNsCertType(cert, der->nsCertType,
31530
                                sizeof(der->nsCertType), cert->nsCertType);
31531
        if (der->nsCertTypeSz <= 0)
31532
            return EXTENSIONS_E;
31533
31534
        der->extensionsSz += der->nsCertTypeSz;
31535
    }
31536
    else
31537
        der->nsCertTypeSz = 0;
31538
#endif
31539
31540
    if (cert->crlInfoSz > 0) {
31541
        der->crlInfoSz = SetCRLInfo(cert, der->crlInfo, sizeof(der->crlInfo),
31542
                                cert->crlInfo, cert->crlInfoSz);
31543
        if (der->crlInfoSz <= 0)
31544
            return EXTENSIONS_E;
31545
31546
        der->extensionsSz += der->crlInfoSz;
31547
    }
31548
    else
31549
        der->crlInfoSz = 0;
31550
31551
    /* Certificate Policies */
31552
    if (cert->certPoliciesNb != 0) {
31553
        der->certPoliciesSz = SetCertificatePolicies(der->certPolicies,
31554
                                                     sizeof(der->certPolicies),
31555
                                                     cert->certPolicies,
31556
                                                     cert->certPoliciesNb,
31557
                                                     cert->heap);
31558
        if (der->certPoliciesSz <= 0)
31559
            return CERTPOLICIES_E;
31560
31561
        der->extensionsSz += der->certPoliciesSz;
31562
    }
31563
    else
31564
        der->certPoliciesSz = 0;
31565
#endif /* WOLFSSL_CERT_EXT */
31566
31567
    /* put extensions */
31568
    if (der->extensionsSz > 0) {
31569
31570
        /* put the start of extensions sequence (ID, Size) */
31571
        der->extensionsSz = SetExtensionsHeader(der->extensions,
31572
                                                sizeof(der->extensions),
31573
                                                (word32)der->extensionsSz);
31574
        if (der->extensionsSz <= 0)
31575
            return EXTENSIONS_E;
31576
31577
        /* put CA */
31578
        if (der->caSz) {
31579
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
31580
                                &der->extensionsSz,
31581
                                der->ca, der->caSz);
31582
            if (ret == 0)
31583
                return EXTENSIONS_E;
31584
        }
31585
31586
#ifdef WOLFSSL_ALT_NAMES
31587
        /* put Alternative Names */
31588
        if (der->altNamesSz) {
31589
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
31590
                                &der->extensionsSz,
31591
                                der->altNames, der->altNamesSz);
31592
            if (ret <= 0)
31593
                return EXTENSIONS_E;
31594
        }
31595
#endif
31596
31597
#ifdef WOLFSSL_CERT_EXT
31598
        /* put SKID */
31599
        if (der->skidSz) {
31600
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
31601
                                &der->extensionsSz,
31602
                                der->skid, der->skidSz);
31603
            if (ret <= 0)
31604
                return EXTENSIONS_E;
31605
        }
31606
31607
        /* put AKID */
31608
        if (der->akidSz) {
31609
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
31610
                                &der->extensionsSz,
31611
                                der->akid, der->akidSz);
31612
            if (ret <= 0)
31613
                return EXTENSIONS_E;
31614
        }
31615
31616
        /* put CRL Distribution Points */
31617
        if (der->crlInfoSz) {
31618
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
31619
                                &der->extensionsSz,
31620
                                der->crlInfo, der->crlInfoSz);
31621
            if (ret <= 0)
31622
                return EXTENSIONS_E;
31623
        }
31624
31625
        /* put KeyUsage */
31626
        if (der->keyUsageSz) {
31627
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
31628
                                &der->extensionsSz,
31629
                                der->keyUsage, der->keyUsageSz);
31630
            if (ret <= 0)
31631
                return EXTENSIONS_E;
31632
        }
31633
31634
        /* put ExtendedKeyUsage */
31635
        if (der->extKeyUsageSz) {
31636
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
31637
                                &der->extensionsSz,
31638
                                der->extKeyUsage, der->extKeyUsageSz);
31639
            if (ret <= 0)
31640
                return EXTENSIONS_E;
31641
        }
31642
31643
        /* put Netscape Cert Type */
31644
#ifndef IGNORE_NETSCAPE_CERT_TYPE
31645
        if (der->nsCertTypeSz) {
31646
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
31647
                                &der->extensionsSz,
31648
                                der->nsCertType, der->nsCertTypeSz);
31649
            if (ret <= 0)
31650
                return EXTENSIONS_E;
31651
        }
31652
#endif
31653
31654
        /* put Certificate Policies */
31655
        if (der->certPoliciesSz) {
31656
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
31657
                                &der->extensionsSz,
31658
                                der->certPolicies, der->certPoliciesSz);
31659
            if (ret <= 0)
31660
                return EXTENSIONS_E;
31661
        }
31662
#endif /* WOLFSSL_CERT_EXT */
31663
    }
31664
31665
    der->total = der->versionSz + der->serialSz + der->sigAlgoSz +
31666
        der->publicKeySz + der->validitySz + der->subjectSz + der->issuerSz +
31667
        der->extensionsSz;
31668
31669
    return 0;
31670
}
31671
31672
31673
/* write DER encoded cert to buffer, size already checked */
31674
static int WriteCertBody(DerCert* der, byte* buf)
31675
{
31676
    word32 idx;
31677
31678
    /* signed part header */
31679
    idx = SetSequence((word32)der->total, buf);
31680
    /* version */
31681
    XMEMCPY(buf + idx, der->version, (size_t)der->versionSz);
31682
    idx += (word32)der->versionSz;
31683
    /* serial */
31684
    XMEMCPY(buf + idx, der->serial, (size_t)der->serialSz);
31685
    idx += (word32)der->serialSz;
31686
    /* sig algo */
31687
    XMEMCPY(buf + idx, der->sigAlgo, (size_t)der->sigAlgoSz);
31688
    idx += (word32)der->sigAlgoSz;
31689
    /* issuer */
31690
    XMEMCPY(buf + idx, der->issuer, (size_t)der->issuerSz);
31691
    idx += (word32)der->issuerSz;
31692
    /* validity */
31693
    XMEMCPY(buf + idx, der->validity, (size_t)der->validitySz);
31694
    idx += (word32)der->validitySz;
31695
    /* subject */
31696
    XMEMCPY(buf + idx, der->subject, (size_t)der->subjectSz);
31697
    idx += (word32)der->subjectSz;
31698
    /* public key */
31699
    XMEMCPY(buf + idx, der->publicKey, (size_t)der->publicKeySz);
31700
    idx += (word32)der->publicKeySz;
31701
    if (der->extensionsSz) {
31702
        /* extensions */
31703
        XMEMCPY(buf + idx, der->extensions,
31704
                min((word32)der->extensionsSz,
31705
                    (word32)sizeof(der->extensions)));
31706
        idx += (word32)der->extensionsSz;
31707
    }
31708
31709
    return (int)idx;
31710
}
31711
#endif /* !WOLFSSL_ASN_TEMPLATE */
31712
31713
31714
/* Make signature from buffer (sz), write to sig (sigSz) */
31715
static int MakeSignature(CertSignCtx* certSignCtx, const byte* buf, word32 sz,
31716
    byte* sig, word32 sigSz, RsaKey* rsaKey, ecc_key* eccKey,
31717
    ed25519_key* ed25519Key, ed448_key* ed448Key, falcon_key* falconKey,
31718
    dilithium_key* dilithiumKey, sphincs_key* sphincsKey, WC_RNG* rng,
31719
    word32 sigAlgoType, void* heap)
31720
{
31721
    int digestSz = 0, typeH = 0, ret = 0;
31722
31723
    (void)digestSz;
31724
    (void)typeH;
31725
    (void)buf;
31726
    (void)sz;
31727
    (void)sig;
31728
    (void)sigSz;
31729
    (void)rsaKey;
31730
    (void)eccKey;
31731
    (void)ed25519Key;
31732
    (void)ed448Key;
31733
    (void)falconKey;
31734
    (void)dilithiumKey;
31735
    (void)sphincsKey;
31736
    (void)rng;
31737
    (void)heap;
31738
31739
    switch (certSignCtx->state) {
31740
    case CERTSIGN_STATE_BEGIN:
31741
    case CERTSIGN_STATE_DIGEST:
31742
31743
        certSignCtx->state = CERTSIGN_STATE_DIGEST;
31744
    #ifndef WOLFSSL_NO_MALLOC
31745
        certSignCtx->digest = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap,
31746
            DYNAMIC_TYPE_TMP_BUFFER);
31747
        if (certSignCtx->digest == NULL) {
31748
            ret = MEMORY_E; goto exit_ms;
31749
        }
31750
    #endif
31751
31752
        ret = HashForSignature(buf, sz, sigAlgoType, certSignCtx->digest,
31753
                               &typeH, &digestSz, 0);
31754
        /* set next state, since WC_PENDING_E rentry for these are not "call again" */
31755
        certSignCtx->state = CERTSIGN_STATE_ENCODE;
31756
        if (ret != 0) {
31757
            goto exit_ms;
31758
        }
31759
        FALL_THROUGH;
31760
31761
    case CERTSIGN_STATE_ENCODE:
31762
    #ifndef NO_RSA
31763
        if (rsaKey) {
31764
        #ifndef WOLFSSL_NO_MALLOC
31765
            certSignCtx->encSig = (byte*)XMALLOC(MAX_DER_DIGEST_SZ, heap,
31766
                DYNAMIC_TYPE_TMP_BUFFER);
31767
            if (certSignCtx->encSig == NULL) {
31768
                ret = MEMORY_E; goto exit_ms;
31769
            }
31770
        #endif
31771
31772
            /* signature */
31773
            certSignCtx->encSigSz = (int)wc_EncodeSignature(certSignCtx->encSig,
31774
                                  certSignCtx->digest, (word32)digestSz, typeH);
31775
        }
31776
    #endif /* !NO_RSA */
31777
        FALL_THROUGH;
31778
31779
    case CERTSIGN_STATE_DO:
31780
        certSignCtx->state = CERTSIGN_STATE_DO;
31781
        ret = -1; /* default to error, reassigned to ALGO_ID_E below. */
31782
31783
    #if !defined(NO_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(WOLFSSL_RSA_VERIFY_ONLY)
31784
        if (rsaKey) {
31785
            /* signature */
31786
            ret = wc_RsaSSL_Sign(certSignCtx->encSig,
31787
                                 (word32)certSignCtx->encSigSz,
31788
                                 sig, sigSz, rsaKey, rng);
31789
        }
31790
    #endif /* !NO_RSA */
31791
31792
    #if defined(HAVE_ECC) && defined(HAVE_ECC_SIGN)
31793
        if (!rsaKey && eccKey) {
31794
            word32 outSz = sigSz;
31795
31796
            ret = wc_ecc_sign_hash(certSignCtx->digest, (word32)digestSz,
31797
                                   sig, &outSz, rng, eccKey);
31798
            if (ret == 0)
31799
                ret = (int)outSz;
31800
        }
31801
    #endif /* HAVE_ECC && HAVE_ECC_SIGN */
31802
31803
    #if defined(HAVE_ED25519) && defined(HAVE_ED25519_SIGN)
31804
        if (!rsaKey && !eccKey && ed25519Key) {
31805
            word32 outSz = sigSz;
31806
31807
            ret = wc_ed25519_sign_msg(buf, sz, sig, &outSz, ed25519Key);
31808
            if (ret == 0)
31809
                ret = (int)outSz;
31810
        }
31811
    #endif /* HAVE_ED25519 && HAVE_ED25519_SIGN */
31812
31813
    #if defined(HAVE_ED448) && defined(HAVE_ED448_SIGN)
31814
        if (!rsaKey && !eccKey && !ed25519Key && ed448Key) {
31815
            word32 outSz = sigSz;
31816
31817
            ret = wc_ed448_sign_msg(buf, sz, sig, &outSz, ed448Key, NULL, 0);
31818
            if (ret == 0)
31819
                ret = (int)outSz;
31820
        }
31821
    #endif /* HAVE_ED448 && HAVE_ED448_SIGN */
31822
31823
    #if defined(HAVE_FALCON)
31824
        if (!rsaKey && !eccKey && !ed25519Key && !ed448Key && falconKey) {
31825
            word32 outSz = sigSz;
31826
            ret = wc_falcon_sign_msg(buf, sz, sig, &outSz, falconKey, rng);
31827
            if (ret == 0)
31828
                ret = outSz;
31829
        }
31830
    #endif /* HAVE_FALCON */
31831
    #if defined(HAVE_DILITHIUM) && !defined(WOLFSSL_DILITHIUM_NO_SIGN)
31832
        if (!rsaKey && !eccKey && !ed25519Key && !ed448Key && !falconKey &&
31833
            dilithiumKey) {
31834
            word32 outSz = sigSz;
31835
            #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
31836
            if ((dilithiumKey->params->level == WC_ML_DSA_44_DRAFT) ||
31837
                    (dilithiumKey->params->level == WC_ML_DSA_65_DRAFT) ||
31838
                    (dilithiumKey->params->level == WC_ML_DSA_87_DRAFT)) {
31839
                ret = wc_dilithium_sign_msg(buf, sz, sig, &outSz, dilithiumKey,
31840
                    rng);
31841
                if (ret == 0)
31842
                    ret = outSz;
31843
            }
31844
            else
31845
            #endif
31846
            {
31847
                ret = wc_dilithium_sign_ctx_msg(NULL, 0, buf, sz, sig,
31848
                    &outSz, dilithiumKey, rng);
31849
                if (ret == 0)
31850
                    ret = outSz;
31851
            }
31852
        }
31853
    #endif /* HAVE_DILITHIUM && !WOLFSSL_DILITHIUM_NO_SIGN */
31854
    #if defined(HAVE_SPHINCS)
31855
        if (!rsaKey && !eccKey && !ed25519Key && !ed448Key && !falconKey &&
31856
            !dilithiumKey && sphincsKey) {
31857
            word32 outSz = sigSz;
31858
            ret = wc_sphincs_sign_msg(buf, sz, sig, &outSz, sphincsKey, rng);
31859
            if (ret == 0)
31860
                ret = outSz;
31861
        }
31862
    #endif /* HAVE_SPHINCS */
31863
31864
        if (ret == -1)
31865
            ret = ALGO_ID_E;
31866
31867
        break;
31868
    }
31869
31870
exit_ms:
31871
31872
#ifdef WOLFSSL_ASYNC_CRYPT
31873
    if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) {
31874
        return ret;
31875
    }
31876
#endif
31877
31878
#ifndef WOLFSSL_NO_MALLOC
31879
#ifndef NO_RSA
31880
    if (rsaKey) {
31881
        XFREE(certSignCtx->encSig, heap, DYNAMIC_TYPE_TMP_BUFFER);
31882
        certSignCtx->encSig = NULL;
31883
    }
31884
#endif /* !NO_RSA */
31885
31886
    XFREE(certSignCtx->digest, heap, DYNAMIC_TYPE_TMP_BUFFER);
31887
    certSignCtx->digest = NULL;
31888
#endif /* !WOLFSSL_NO_MALLOC */
31889
31890
    /* reset state */
31891
    certSignCtx->state = CERTSIGN_STATE_BEGIN;
31892
31893
    if (ret < 0) {
31894
        WOLFSSL_ERROR_VERBOSE(ret);
31895
    }
31896
31897
    return ret;
31898
}
31899
31900
31901
#ifdef WOLFSSL_ASN_TEMPLATE
31902
/* Generate a random integer value of at most len bytes.
31903
 *
31904
 * Most-significant bit will not be set when maximum size.
31905
 * Random value may be smaller than maximum size in bytes.
31906
 *
31907
 * @param [in]  rng  Random number generator.
31908
 * @param [out] out  Buffer to hold integer value.
31909
 * @param [in]  len  Maximum number of bytes of integer.
31910
 * @return  0 on success.
31911
 * @return  -ve when random number generation failed.
31912
 */
31913
static int GenerateInteger(WC_RNG* rng, byte* out, word32 len)
31914
{
31915
    int ret;
31916
31917
    /* Generate random number. */
31918
    ret = wc_RNG_GenerateBlock(rng, out, len);
31919
    if (ret == 0) {
31920
        int i;
31921
31922
        /* Clear the top bit to make positive. */
31923
        out[0] &= 0x7f;
31924
31925
        /* Find first non-zero byte. One zero byte is valid though. */
31926
        for (i = 0; i < (int)len - 1; i++) {
31927
            if (out[i] != 0) {
31928
                break;
31929
            }
31930
        }
31931
        if (i != 0) {
31932
            /* Remove leading zeros. */
31933
            XMEMMOVE(out, out + i, (size_t)len - (size_t)i);
31934
        }
31935
    }
31936
31937
    return ret;
31938
}
31939
31940
/* ASN.1 template for a Certificate.
31941
 * X.509: RFC 5280, 4.1 - Basic Certificate Fields.
31942
 */
31943
static const ASNItem sigASN[] = {
31944
/* SEQ          */    { 0, ASN_SEQUENCE, 1, 1, 0 },
31945
                                     /* tbsCertificate */
31946
/* TBS_SEQ      */        { 1, ASN_SEQUENCE, 1, 0, 0 },
31947
                                     /* signatureAlgorithm */
31948
/* SIGALGO_SEQ  */        { 1, ASN_SEQUENCE, 1, 1, 0 },
31949
/* SIGALGO_OID  */            { 2, ASN_OBJECT_ID, 0, 0, 0 },
31950
/* SIGALGO_NULL */            { 2, ASN_TAG_NULL, 0, 0, 0 },
31951
                                     /* signatureValue */
31952
/* SIGNATURE    */        { 1, ASN_BIT_STRING, 0, 0, 0 },
31953
};
31954
enum {
31955
    SIGASN_IDX_SEQ = 0,
31956
    SIGASN_IDX_TBS_SEQ,
31957
    SIGASN_IDX_SIGALGO_SEQ,
31958
    SIGASN_IDX_SIGALGO_OID,
31959
    SIGASN_IDX_SIGALGO_NULL,
31960
    SIGASN_IDX_SIGNATURE
31961
};
31962
31963
/* Number of items in ASN.1 template for a Certificate. */
31964
#define sigASN_Length (sizeof(sigASN) / sizeof(ASNItem))
31965
#endif
31966
31967
/* add signature to end of buffer, size of buffer assumed checked, return
31968
   new length */
31969
int AddSignature(byte* buf, int bodySz, const byte* sig, int sigSz,
31970
                        int sigAlgoType)
31971
{
31972
#ifndef WOLFSSL_ASN_TEMPLATE
31973
    byte seq[MAX_SEQ_SZ];
31974
    word32 idx, seqSz;
31975
31976
    if ((bodySz < 0) || (sigSz < 0))
31977
        return BUFFER_E;
31978
31979
    idx = (word32)bodySz;
31980
31981
    /* algo */
31982
    idx += SetAlgoID(sigAlgoType, buf ? buf + idx : NULL, oidSigType, 0);
31983
    /* bit string */
31984
    idx += SetBitString((word32)sigSz, 0, buf ? buf + idx : NULL);
31985
    /* signature */
31986
    if (buf)
31987
        XMEMCPY(buf + idx, sig, (size_t)sigSz);
31988
    idx += (word32)sigSz;
31989
31990
    /* make room for overall header */
31991
    seqSz = SetSequence(idx, seq);
31992
    if (buf) {
31993
        XMEMMOVE(buf + seqSz, buf, idx);
31994
        XMEMCPY(buf, seq, seqSz);
31995
    }
31996
31997
    return (int)(idx + seqSz);
31998
#else
31999
    DECL_ASNSETDATA(dataASN, sigASN_Length);
32000
    word32 seqSz = 0;
32001
    int sz = 0;
32002
    int ret = 0;
32003
32004
    CALLOC_ASNSETDATA(dataASN, sigASN_Length, ret, NULL);
32005
32006
    /* In place, put body between SEQUENCE and signature. */
32007
    if (ret == 0) {
32008
        /* Set signature OID and signature data. */
32009
        SetASN_OID(&dataASN[SIGASN_IDX_SIGALGO_OID], (word32)sigAlgoType,
32010
                   oidSigType);
32011
        if (dataASN[SIGASN_IDX_SIGALGO_OID].data.buffer.data == NULL) {
32012
            /* The OID was not found or compiled in! */
32013
            ret = ASN_UNKNOWN_OID_E;
32014
        }
32015
    }
32016
    if (ret == 0) {
32017
        if (IsSigAlgoECC((word32)sigAlgoType)) {
32018
            /* ECDSA and EdDSA doesn't have NULL tagged item. */
32019
            dataASN[SIGASN_IDX_SIGALGO_NULL].noOut = 1;
32020
        }
32021
        SetASN_Buffer(&dataASN[SIGASN_IDX_SIGNATURE], sig, (word32)sigSz);
32022
        /* Calculate size of signature data. */
32023
        ret = SizeASN_Items(&sigASN[SIGASN_IDX_SIGALGO_SEQ],
32024
                &dataASN[SIGASN_IDX_SIGALGO_SEQ], sigASN_Length - 2, &sz);
32025
    }
32026
    if (ret == 0) {
32027
        /* Calculate size of outer sequence by calculating size of the encoded
32028
         * length and adding 1 for tag. */
32029
        seqSz = SizeASNHeader((word32)bodySz + (word32)sz);
32030
        if (buf != NULL) {
32031
            /* Move body to after sequence. */
32032
            XMEMMOVE(buf + seqSz, buf, (size_t)bodySz);
32033
        }
32034
        /* Leave space for body in encoding. */
32035
        SetASN_ReplaceBuffer(&dataASN[SIGASN_IDX_TBS_SEQ], NULL,
32036
                             (word32)bodySz);
32037
32038
        /* Calculate overall size and put in offsets and lengths. */
32039
        ret = SizeASN_Items(sigASN, dataASN, sigASN_Length, &sz);
32040
    }
32041
    if ((ret == 0) && (buf != NULL)) {
32042
        /* Write SEQUENCE and signature around body. */
32043
        SetASN_Items(sigASN, dataASN, sigASN_Length, buf);
32044
    }
32045
32046
    if (ret == 0) {
32047
        /* Return the encoding size. */
32048
        ret = sz;
32049
    }
32050
32051
    FREE_ASNSETDATA(dataASN, NULL);
32052
    return ret;
32053
#endif /* WOLFSSL_ASN_TEMPLATE */
32054
}
32055
32056
32057
/* Make an x509 Certificate v3 any key type from cert input, write to buffer */
32058
static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
32059
                       RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng,
32060
                       DsaKey* dsaKey, ed25519_key* ed25519Key,
32061
                       ed448_key* ed448Key, falcon_key* falconKey,
32062
                       dilithium_key* dilithiumKey, sphincs_key* sphincsKey)
32063
{
32064
#ifndef WOLFSSL_ASN_TEMPLATE
32065
    int ret;
32066
#ifdef WOLFSSL_SMALL_STACK
32067
    DerCert* der;
32068
#else
32069
    DerCert der[1];
32070
#endif
32071
32072
    if (derBuffer == NULL)
32073
        return BAD_FUNC_ARG;
32074
32075
    if (eccKey)
32076
        cert->keyType = ECC_KEY;
32077
    else if (rsaKey)
32078
        cert->keyType = RSA_KEY;
32079
    else if (dsaKey)
32080
        cert->keyType = DSA_KEY;
32081
    else if (ed25519Key)
32082
        cert->keyType = ED25519_KEY;
32083
    else if (ed448Key)
32084
        cert->keyType = ED448_KEY;
32085
#ifdef HAVE_FALCON
32086
    else if ((falconKey != NULL) && (falconKey->level == 1))
32087
        cert->keyType = FALCON_LEVEL1_KEY;
32088
    else if ((falconKey != NULL) && (falconKey->level == 5))
32089
        cert->keyType = FALCON_LEVEL5_KEY;
32090
#endif /* HAVE_FALCON */
32091
#ifdef HAVE_DILITHIUM
32092
    #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
32093
    else if ((dilithiumKey != NULL) &&
32094
                (dilithiumKey->params->level == WC_ML_DSA_44_DRAFT)) {
32095
        cert->keyType = DILITHIUM_LEVEL2_KEY;
32096
    }
32097
    else if ((dilithiumKey != NULL) &&
32098
                (dilithiumKey->params->level == WC_ML_DSA_65_DRAFT)) {
32099
        cert->keyType = DILITHIUM_LEVEL3_KEY;
32100
    }
32101
    else if ((dilithiumKey != NULL) &&
32102
                (dilithiumKey->params->level == WC_ML_DSA_87_DRAFT)) {
32103
        cert->keyType = DILITHIUM_LEVEL5_KEY;
32104
    }
32105
    #endif
32106
    else if ((dilithiumKey != NULL) &&
32107
                (dilithiumKey->params->level == WC_ML_DSA_44)) {
32108
        cert->keyType = ML_DSA_LEVEL2_KEY;
32109
    }
32110
    else if ((dilithiumKey != NULL) &&
32111
                (dilithiumKey->params->level == WC_ML_DSA_65)) {
32112
        cert->keyType = ML_DSA_LEVEL3_KEY;
32113
    }
32114
    else if ((dilithiumKey != NULL) &&
32115
                (dilithiumKey->params->level == WC_ML_DSA_87)) {
32116
        cert->keyType = ML_DSA_LEVEL5_KEY;
32117
    }
32118
#endif /* HAVE_DILITHIUM */
32119
#ifdef HAVE_SPHINCS
32120
    else if ((sphincsKey != NULL) && (sphincsKey->level == 1)
32121
             && (sphincsKey->optim == FAST_VARIANT))
32122
        cert->keyType = SPHINCS_FAST_LEVEL1_KEY;
32123
    else if ((sphincsKey != NULL) && (sphincsKey->level == 3)
32124
             && (sphincsKey->optim == FAST_VARIANT))
32125
        cert->keyType = SPHINCS_FAST_LEVEL3_KEY;
32126
    else if ((sphincsKey != NULL) && (sphincsKey->level == 5)
32127
             && (sphincsKey->optim == FAST_VARIANT))
32128
        cert->keyType = SPHINCS_FAST_LEVEL5_KEY;
32129
    else if ((sphincsKey != NULL) && (sphincsKey->level == 1)
32130
             && (sphincsKey->optim == SMALL_VARIANT))
32131
        cert->keyType = SPHINCS_SMALL_LEVEL1_KEY;
32132
    else if ((sphincsKey != NULL) && (sphincsKey->level == 3)
32133
             && (sphincsKey->optim == SMALL_VARIANT))
32134
        cert->keyType = SPHINCS_SMALL_LEVEL3_KEY;
32135
    else if ((sphincsKey != NULL) && (sphincsKey->level == 5)
32136
             && (sphincsKey->optim == SMALL_VARIANT))
32137
        cert->keyType = SPHINCS_SMALL_LEVEL5_KEY;
32138
#endif /* HAVE_SPHINCS */
32139
    else
32140
        return BAD_FUNC_ARG;
32141
32142
#ifdef WOLFSSL_SMALL_STACK
32143
    der = (DerCert*)XMALLOC(sizeof(DerCert), cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
32144
    if (der == NULL)
32145
        return MEMORY_E;
32146
#endif
32147
32148
    ret = EncodeCert(cert, der, rsaKey, eccKey, rng, dsaKey, ed25519Key,
32149
                     ed448Key, falconKey, dilithiumKey, sphincsKey);
32150
    if (ret == 0) {
32151
        if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
32152
            ret = BUFFER_E;
32153
        else
32154
            ret = cert->bodySz = WriteCertBody(der, derBuffer);
32155
    }
32156
32157
#ifdef WOLFSSL_SMALL_STACK
32158
    XFREE(der, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
32159
#endif
32160
32161
    return ret;
32162
#else
32163
    /* TODO: issRaw and sbjRaw should be NUL terminated. */
32164
    DECL_ASNSETDATA(dataASN, x509CertASN_Length);
32165
    word32 publicKeySz = 0;
32166
    word32 issuerSz = 0;
32167
    word32 subjectSz = 0;
32168
    word32 extSz = 0;
32169
    int sz = 0;
32170
    int ret = 0;
32171
    word32 issRawLen = 0;
32172
    word32 sbjRawLen = 0;
32173
32174
    /* Unused without OQS */
32175
    (void)falconKey;
32176
    (void)dilithiumKey;
32177
    (void)sphincsKey;
32178
32179
    CALLOC_ASNSETDATA(dataASN, x509CertASN_Length, ret, cert->heap);
32180
32181
    if (ret == 0) {
32182
        /* Set key type into certificate object based on key passed in. */
32183
        if (rsaKey) {
32184
            cert->keyType = RSA_KEY;
32185
        }
32186
        else if (eccKey) {
32187
            cert->keyType = ECC_KEY;
32188
        }
32189
        else if (dsaKey) {
32190
            cert->keyType = DSA_KEY;
32191
        }
32192
        else if (ed25519Key) {
32193
            cert->keyType = ED25519_KEY;
32194
        }
32195
        else if (ed448Key) {
32196
            cert->keyType = ED448_KEY;
32197
        }
32198
#ifdef HAVE_FALCON
32199
        else if ((falconKey != NULL) && (falconKey->level == 1)) {
32200
            cert->keyType = FALCON_LEVEL1_KEY;
32201
        }
32202
        else if ((falconKey != NULL) && (falconKey->level == 5)) {
32203
            cert->keyType = FALCON_LEVEL5_KEY;
32204
        }
32205
#endif /* HAVE_FALCON */
32206
#ifdef HAVE_DILITHIUM
32207
    #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
32208
        else if ((dilithiumKey != NULL) &&
32209
                    (dilithiumKey->params->level == WC_ML_DSA_44_DRAFT)) {
32210
            cert->keyType = DILITHIUM_LEVEL2_KEY;
32211
        }
32212
        else if ((dilithiumKey != NULL) &&
32213
                    (dilithiumKey->params->level == WC_ML_DSA_65_DRAFT)) {
32214
            cert->keyType = DILITHIUM_LEVEL3_KEY;
32215
        }
32216
        else if ((dilithiumKey != NULL) &&
32217
                    (dilithiumKey->params->level == WC_ML_DSA_87_DRAFT)) {
32218
            cert->keyType = DILITHIUM_LEVEL5_KEY;
32219
        }
32220
    #endif
32221
        else if ((dilithiumKey != NULL) &&
32222
                    (dilithiumKey->level == WC_ML_DSA_44)) {
32223
            cert->keyType = ML_DSA_LEVEL2_KEY;
32224
        }
32225
        else if ((dilithiumKey != NULL) &&
32226
                    (dilithiumKey->level == WC_ML_DSA_65)) {
32227
            cert->keyType = ML_DSA_LEVEL3_KEY;
32228
        }
32229
        else if ((dilithiumKey != NULL) &&
32230
                    (dilithiumKey->level == WC_ML_DSA_87)) {
32231
            cert->keyType = ML_DSA_LEVEL5_KEY;
32232
        }
32233
#endif /* HAVE_DILITHIUM */
32234
#ifdef HAVE_SPHINCS
32235
        else if ((sphincsKey != NULL) && (sphincsKey->level == 1)
32236
                 && (sphincsKey->optim == FAST_VARIANT)) {
32237
            cert->keyType = SPHINCS_FAST_LEVEL1_KEY;
32238
        }
32239
        else if ((sphincsKey != NULL) && (sphincsKey->level == 3)
32240
                 && (sphincsKey->optim == FAST_VARIANT)) {
32241
            cert->keyType = SPHINCS_FAST_LEVEL3_KEY;
32242
        }
32243
        else if ((sphincsKey != NULL) && (sphincsKey->level == 5)
32244
                 && (sphincsKey->optim == FAST_VARIANT)) {
32245
            cert->keyType = SPHINCS_FAST_LEVEL5_KEY;
32246
        }
32247
        else if ((sphincsKey != NULL) && (sphincsKey->level == 1)
32248
                 && (sphincsKey->optim == SMALL_VARIANT)) {
32249
            cert->keyType = SPHINCS_SMALL_LEVEL1_KEY;
32250
        }
32251
        else if ((sphincsKey != NULL) && (sphincsKey->level == 3)
32252
                 && (sphincsKey->optim == SMALL_VARIANT)) {
32253
            cert->keyType = SPHINCS_SMALL_LEVEL3_KEY;
32254
        }
32255
        else if ((sphincsKey != NULL) && (sphincsKey->level == 5)
32256
                 && (sphincsKey->optim == SMALL_VARIANT)) {
32257
            cert->keyType = SPHINCS_SMALL_LEVEL5_KEY;
32258
        }
32259
#endif /* HAVE_SPHINCS */
32260
        else {
32261
            ret = BAD_FUNC_ARG;
32262
        }
32263
    }
32264
    if ((ret == 0) && (cert->serialSz == 0)) {
32265
        /* Generate random serial number. */
32266
        cert->serialSz = CTC_GEN_SERIAL_SZ;
32267
        ret = GenerateInteger(rng, cert->serial, CTC_GEN_SERIAL_SZ);
32268
    }
32269
    if (ret == 0) {
32270
        /* Determine issuer name size. */
32271
    #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) || \
32272
        defined(WOLFSSL_CERT_REQ)
32273
        issRawLen = (word32)XSTRLEN((const char*)cert->issRaw);
32274
        if (issRawLen > 0) {
32275
            issuerSz = min(sizeof(cert->issRaw), issRawLen);
32276
        }
32277
        else
32278
    #endif
32279
        {
32280
            /* Calculate issuer name encoding size. If the cert is self-signed
32281
             * use the subject instead of the issuer. */
32282
            ret = SetNameEx(NULL, WC_ASN_NAME_MAX, cert->selfSigned ?
32283
                                 &cert->subject : &cert->issuer, cert->heap);
32284
            issuerSz = (word32)ret;
32285
        }
32286
    }
32287
    if (ret >= 0) {
32288
        /* Determine subject name size. */
32289
    #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) || \
32290
        defined(WOLFSSL_CERT_REQ)
32291
        sbjRawLen = (word32)XSTRLEN((const char*)cert->sbjRaw);
32292
        if (sbjRawLen > 0) {
32293
            subjectSz = min(sizeof(cert->sbjRaw), sbjRawLen);
32294
        }
32295
        else
32296
    #endif
32297
        {
32298
            /* Calculate subject name encoding size. */
32299
            ret = SetNameEx(NULL, WC_ASN_NAME_MAX, &cert->subject,
32300
                                  cert->heap);
32301
            subjectSz = (word32)ret;
32302
        }
32303
    }
32304
    if (ret >= 0) {
32305
        /* Calculate public key encoding size. */
32306
        ret = EncodePublicKey(cert->keyType, NULL, 0, rsaKey,
32307
                eccKey, ed25519Key, ed448Key, dsaKey, falconKey,
32308
                dilithiumKey, sphincsKey);
32309
        publicKeySz = (word32)ret;
32310
    }
32311
    if (ret >= 0) {
32312
        /* Calculate extensions encoding size - may be 0. */
32313
        ret = EncodeExtensions(cert, NULL, 0, 0);
32314
        extSz = (word32)ret;
32315
    }
32316
    if (ret >= 0) {
32317
        /* Don't write out outer sequence - only doing body. */
32318
        dataASN[X509CERTASN_IDX_SEQ].noOut = 1;
32319
        /* Set version, serial number and signature OID */
32320
        SetASN_Int8Bit(&dataASN[X509CERTASN_IDX_TBS_VER_INT],
32321
                       (byte)cert->version);
32322
        SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_SERIAL], cert->serial,
32323
                (word32)cert->serialSz);
32324
#ifdef WOLFSSL_DUAL_ALG_CERTS
32325
        if (cert->sigType == 0) {
32326
            /* sigOID being 0 indicates preTBS. Do not encode signature. */
32327
            dataASN[X509CERTASN_IDX_TBS_ALGOID_SEQ].noOut = 1;
32328
            dataASN[X509CERTASN_IDX_TBS_ALGOID_OID].noOut = 1;
32329
            dataASN[X509CERTASN_IDX_TBS_ALGOID_PARAMS_NULL].noOut = 1;
32330
    #ifdef WC_RSA_PSS
32331
            dataASN[X509CERTASN_IDX_TBS_ALGOID_PARAMS].noOut = 1;
32332
    #endif
32333
32334
        }
32335
        else
32336
#endif /* WOLFSSL_DUAL_ALG_CERTS */
32337
        {
32338
            SetASN_OID(&dataASN[X509CERTASN_IDX_TBS_ALGOID_OID],
32339
                       (word32)cert->sigType, oidSigType);
32340
        }
32341
32342
        if (IsSigAlgoECC((word32)cert->sigType)) {
32343
            /* No NULL tagged item with ECDSA and EdDSA signature OIDs. */
32344
            dataASN[X509CERTASN_IDX_TBS_ALGOID_PARAMS_NULL].noOut = 1;
32345
        }
32346
    #ifdef WC_RSA_PSS
32347
        /* TODO: Encode RSA PSS parameters. */
32348
        dataASN[X509CERTASN_IDX_TBS_ALGOID_PARAMS].noOut = 1;
32349
    #endif
32350
        if (issRawLen > 0) {
32351
    #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) || \
32352
        defined(WOLFSSL_CERT_REQ)
32353
            /* Put in encoded issuer name. */
32354
            SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ],
32355
                    cert->issRaw, issuerSz);
32356
    #endif
32357
        }
32358
        else {
32359
            /* Leave space for issuer name. */
32360
            SetASN_ReplaceBuffer(&dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ],
32361
                    NULL, issuerSz);
32362
        }
32363
32364
        if (cert->beforeDateSz && cert->afterDateSz) {
32365
            if (cert->beforeDate[0] == ASN_UTC_TIME) {
32366
                /* Make space for before date data. */
32367
                SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC],
32368
                        cert->beforeDate + 2, ASN_UTC_TIME_SIZE - 1);
32369
                /* Don't put out Generalized Time before data. */
32370
                dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT].noOut = 1;
32371
            }
32372
            else {
32373
                /* Don't put out UTC before data. */
32374
                dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC].noOut = 1;
32375
                /* Make space for before date data. */
32376
                SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT],
32377
                        cert->beforeDate + 2, ASN_GEN_TIME_SZ);
32378
            }
32379
            if (cert->afterDate[0] == ASN_UTC_TIME) {
32380
                /* Make space for after date data. */
32381
                SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC],
32382
                        cert->afterDate + 2, ASN_UTC_TIME_SIZE - 1);
32383
                /* Don't put out UTC Generalized Time after data. */
32384
                dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT].noOut = 1;
32385
            }
32386
            else {
32387
                /* Don't put out UTC after data. */
32388
                dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC].noOut = 1;
32389
                /* Make space for after date data. */
32390
                SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT],
32391
                        cert->afterDate + 2, ASN_GEN_TIME_SZ);
32392
            }
32393
        }
32394
        else
32395
        {
32396
            /* Don't put out UTC before data. */
32397
            dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC].noOut = 1;
32398
            /* Make space for before date data. */
32399
            SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT],
32400
                    NULL, ASN_GEN_TIME_SZ);
32401
            /* Don't put out UTC after data. */
32402
            dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC].noOut = 1;
32403
            /* Make space for after date data. */
32404
            SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT],
32405
                    NULL, ASN_GEN_TIME_SZ);
32406
        }
32407
        if (sbjRawLen > 0) {
32408
            /* Put in encoded subject name. */
32409
    #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA) || \
32410
        defined(WOLFSSL_CERT_REQ)
32411
            SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_SUBJECT_SEQ],
32412
                    cert->sbjRaw, subjectSz);
32413
    #endif
32414
        }
32415
        else {
32416
            /* Leave space for subject name. */
32417
            SetASN_ReplaceBuffer(&dataASN[X509CERTASN_IDX_TBS_SUBJECT_SEQ],
32418
                    NULL, subjectSz);
32419
        }
32420
        /* Leave space for public key. */
32421
        SetASN_ReplaceBuffer(&dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ],
32422
                NULL, publicKeySz);
32423
        /* Replacement buffer instead of algorithm identifier items. */
32424
        SetASNItem_NoOut(dataASN,
32425
                X509CERTASN_IDX_TBS_SPUBKEYINFO_ALGO_SEQ,
32426
                X509CERTASN_IDX_TBS_SPUBKEYINFO_PUBKEY);
32427
        /* issuerUniqueID and subjectUniqueID not supported. */
32428
        dataASN[X509CERTASN_IDX_TBS_ISSUERUID].noOut = 1;
32429
        dataASN[X509CERTASN_IDX_TBS_SUBJECTUID].noOut = 1;
32430
        /* Leave space for extensions if any set into certificate object. */
32431
        if (extSz > 0) {
32432
            SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_EXT_SEQ], NULL, extSz);
32433
        }
32434
        else {
32435
            SetASNItem_NoOutNode(dataASN, x509CertASN,
32436
                    X509CERTASN_IDX_TBS_EXT, x509CertASN_Length);
32437
        }
32438
        /* No signature - added later. */
32439
        SetASNItem_NoOut(dataASN, X509CERTASN_IDX_SIGALGO_SEQ,
32440
                X509CERTASN_IDX_SIGNATURE);
32441
32442
        /* Calculate encoded certificate body size. */
32443
        ret = SizeASN_Items(x509CertASN, dataASN, x509CertASN_Length, &sz);
32444
    }
32445
    /* Check buffer is big enough for encoded data. */
32446
    if ((ret == 0) && (sz > (int)derSz)) {
32447
        ret = BUFFER_E;
32448
    }
32449
    if (ret == 0) {
32450
        /* Encode certificate body into buffer. */
32451
        SetASN_Items(x509CertASN, dataASN, x509CertASN_Length, derBuffer);
32452
32453
        if (issRawLen == 0) {
32454
            /* Encode issuer name into buffer. Use the subject as the issuer
32455
             * if it is self-signed. Size will be correct because we did the
32456
             * same for size. */
32457
            ret = SetNameEx(
32458
                (byte*)dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ].data.buffer.data,
32459
                dataASN[X509CERTASN_IDX_TBS_ISSUER_SEQ].data.buffer.length,
32460
                cert->selfSigned ? &cert->subject : &cert->issuer, cert->heap);
32461
        }
32462
    }
32463
    if ((ret >= 0) && (sbjRawLen == 0)) {
32464
        /* Encode subject name into buffer. */
32465
        ret = SetNameEx(
32466
            (byte*)dataASN[X509CERTASN_IDX_TBS_SUBJECT_SEQ].data.buffer.data,
32467
            dataASN[X509CERTASN_IDX_TBS_SUBJECT_SEQ].data.buffer.length,
32468
            &cert->subject, cert->heap);
32469
    }
32470
    if (ret >= 0) {
32471
        if (cert->beforeDateSz == 0 || cert->afterDateSz == 0)
32472
        {
32473
            /* Encode validity into buffer. */
32474
            ret = SetValidity(
32475
                (byte*)dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT]
32476
                               .data.buffer.data,
32477
                (byte*)dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT]
32478
                               .data.buffer.data, cert->daysValid);
32479
        }
32480
    }
32481
    if (ret >= 0) {
32482
        /* Encode public key into buffer. */
32483
        ret = EncodePublicKey(cert->keyType,
32484
            (byte*)dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ]
32485
                           .data.buffer.data,
32486
            (int)dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ]
32487
                           .data.buffer.length,
32488
            rsaKey, eccKey, ed25519Key, ed448Key, dsaKey,
32489
            falconKey, dilithiumKey, sphincsKey);
32490
    }
32491
    if ((ret >= 0) && (!dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].noOut)) {
32492
        /* Encode extensions into buffer. */
32493
        ret = EncodeExtensions(cert,
32494
                (byte*)dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].data.buffer.data,
32495
                dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].data.buffer.length, 0);
32496
    }
32497
    if (ret >= 0) {
32498
        /* Store encoded certificate body size. */
32499
        cert->bodySz = sz;
32500
        /* Return the encoding size. */
32501
        ret = sz;
32502
    }
32503
32504
    FREE_ASNSETDATA(dataASN, cert->heap);
32505
    return ret;
32506
#endif
32507
}
32508
32509
/* Make an x509 Certificate v3 from cert input using any
32510
 * key type, and write to buffer.
32511
 *
32512
 * @param [in, out] cert      Certificate object.
32513
 * @param [out]     derBuffer Buffer to write der in.
32514
 * @param [in]      derSz     Der buffer size.
32515
 * @param [in]      keyType   The type of key.
32516
 * @param [in]      key       Key data.
32517
 * @param [in]      rng       Random number generator.
32518
 * @return          Size of encoded data in bytes on success.
32519
 * @return          < 0 on error
32520
 * */
32521
int wc_MakeCert_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType,
32522
                   void* key, WC_RNG* rng)
32523
{
32524
    RsaKey*            rsaKey = NULL;
32525
    DsaKey*            dsaKey = NULL;
32526
    ecc_key*           eccKey = NULL;
32527
    ed25519_key*       ed25519Key = NULL;
32528
    ed448_key*         ed448Key = NULL;
32529
    falcon_key*        falconKey = NULL;
32530
    dilithium_key*     dilithiumKey = NULL;
32531
    sphincs_key*       sphincsKey = NULL;
32532
32533
    if (keyType == RSA_TYPE)
32534
        rsaKey = (RsaKey*)key;
32535
    else if (keyType == DSA_TYPE)
32536
        dsaKey = (DsaKey*)key;
32537
    else if (keyType == ECC_TYPE)
32538
        eccKey = (ecc_key*)key;
32539
    else if (keyType == ED25519_TYPE)
32540
        ed25519Key = (ed25519_key*)key;
32541
    else if (keyType == ED448_TYPE)
32542
        ed448Key = (ed448_key*)key;
32543
    else if (keyType == FALCON_LEVEL1_TYPE)
32544
        falconKey = (falcon_key*)key;
32545
    else if (keyType == FALCON_LEVEL5_TYPE)
32546
        falconKey = (falcon_key*)key;
32547
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
32548
    else if (keyType == DILITHIUM_LEVEL2_TYPE)
32549
        dilithiumKey = (dilithium_key*)key;
32550
    else if (keyType == DILITHIUM_LEVEL3_TYPE)
32551
        dilithiumKey = (dilithium_key*)key;
32552
    else if (keyType == DILITHIUM_LEVEL5_TYPE)
32553
        dilithiumKey = (dilithium_key*)key;
32554
#endif
32555
    else if (keyType == ML_DSA_LEVEL2_TYPE)
32556
        dilithiumKey = (dilithium_key*)key;
32557
    else if (keyType == ML_DSA_LEVEL3_TYPE)
32558
        dilithiumKey = (dilithium_key*)key;
32559
    else if (keyType == ML_DSA_LEVEL5_TYPE)
32560
        dilithiumKey = (dilithium_key*)key;
32561
    else if (keyType == SPHINCS_FAST_LEVEL1_TYPE)
32562
        sphincsKey = (sphincs_key*)key;
32563
    else if (keyType == SPHINCS_FAST_LEVEL3_TYPE)
32564
        sphincsKey = (sphincs_key*)key;
32565
    else if (keyType == SPHINCS_FAST_LEVEL5_TYPE)
32566
        sphincsKey = (sphincs_key*)key;
32567
    else if (keyType == SPHINCS_SMALL_LEVEL1_TYPE)
32568
        sphincsKey = (sphincs_key*)key;
32569
    else if (keyType == SPHINCS_SMALL_LEVEL3_TYPE)
32570
        sphincsKey = (sphincs_key*)key;
32571
    else if (keyType == SPHINCS_SMALL_LEVEL5_TYPE)
32572
        sphincsKey = (sphincs_key*)key;
32573
32574
    return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, dsaKey,
32575
                       ed25519Key, ed448Key, falconKey, dilithiumKey,
32576
                       sphincsKey);
32577
}
32578
32579
/* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */
32580
WOLFSSL_ABI
32581
int wc_MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey,
32582
             ecc_key* eccKey, WC_RNG* rng)
32583
{
32584
    return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, NULL,
32585
                       NULL, NULL, NULL, NULL);
32586
}
32587
32588
32589
#ifdef WOLFSSL_CERT_REQ
32590
32591
#ifndef WOLFSSL_ASN_TEMPLATE
32592
/* return size of data set on success
32593
 * if getting size only then attr and oid should be NULL
32594
 */
32595
static word32 SetReqAttribSingle(byte* output, word32* idx, char* attr,
32596
        word32 attrSz, const byte* oid, word32 oidSz, byte printable,
32597
        word32 extSz)
32598
{
32599
    word32 totalSz = 0;
32600
    word32 seqSz = 0;
32601
    word32 setSz = 0;
32602
    word32 strSz = 0;
32603
    byte seq[MAX_SEQ_SZ];
32604
    byte set[MAX_SET_SZ];
32605
    byte str[MAX_PRSTR_SZ];
32606
32607
    totalSz = (word32)SetObjectId((int)oidSz, NULL);
32608
    totalSz += oidSz;
32609
    if (extSz > 0) {
32610
        totalSz += setSz = SetSet(extSz, set);
32611
        totalSz += seqSz = SetSequence(totalSz + extSz, seq);
32612
        totalSz += extSz;
32613
    }
32614
    else {
32615
        if (printable) {
32616
            strSz = SetPrintableString(attrSz, str);
32617
            totalSz += strSz;
32618
        }
32619
        else {
32620
            totalSz += strSz = SetUTF8String(attrSz, str);
32621
        }
32622
        totalSz += setSz = SetSet(strSz + attrSz, set);
32623
        totalSz += seqSz = SetSequence(totalSz + attrSz, seq);
32624
        totalSz += attrSz;
32625
    }
32626
32627
    if (oid) {
32628
        XMEMCPY(&output[*idx], seq, seqSz);
32629
        *idx += seqSz;
32630
        *idx += (word32)SetObjectId((int)oidSz, output + *idx);
32631
        XMEMCPY(&output[*idx], oid, oidSz);
32632
        *idx += oidSz;
32633
        XMEMCPY(&output[*idx], set, setSz);
32634
        *idx += setSz;
32635
        if (strSz > 0) {
32636
            XMEMCPY(&output[*idx], str, strSz);
32637
            *idx += strSz;
32638
            if (attrSz > 0) {
32639
                XMEMCPY(&output[*idx], attr, attrSz);
32640
                *idx += attrSz;
32641
            }
32642
        }
32643
    }
32644
    return totalSz;
32645
}
32646
32647
32648
32649
static int SetReqAttrib(byte* output, Cert* cert, word32 extSz)
32650
{
32651
    word32 sz      = 0; /* overall size */
32652
    word32 setSz   = 0;
32653
32654
    output[0] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED;
32655
    sz++;
32656
32657
    if (cert->challengePw[0]) {
32658
        setSz += SetReqAttribSingle(output, &sz, NULL,
32659
                (word32)XSTRLEN(cert->challengePw), NULL,
32660
                sizeof(attrChallengePasswordOid),
32661
                (byte)cert->challengePwPrintableString, 0);
32662
    }
32663
32664
    if (cert->unstructuredName[0]) {
32665
        setSz += SetReqAttribSingle(output, &sz, NULL,
32666
                (word32)XSTRLEN(cert->unstructuredName), NULL,
32667
                sizeof(attrUnstructuredNameOid), 1, 0);
32668
    }
32669
32670
    if (extSz) {
32671
        setSz += SetReqAttribSingle(output, &sz, NULL, 0, NULL,
32672
                sizeof(attrExtensionRequestOid), 1, extSz);
32673
    }
32674
32675
    /* Put the pieces together. */
32676
    sz += SetLength(setSz, &output[sz]);
32677
    if (sz + setSz - extSz > MAX_ATTRIB_SZ) {
32678
        WOLFSSL_MSG("Attribute Buffer is not big enough!");
32679
        return REQ_ATTRIBUTE_E;
32680
    }
32681
32682
    if (cert->challengePw[0]) {
32683
        SetReqAttribSingle(output, &sz, cert->challengePw,
32684
                (word32)XSTRLEN(cert->challengePw),
32685
                &attrChallengePasswordOid[0],
32686
                sizeof(attrChallengePasswordOid),
32687
                (byte)cert->challengePwPrintableString, 0);
32688
    }
32689
32690
    if (cert->unstructuredName[0]) {
32691
        SetReqAttribSingle(output, &sz, cert->unstructuredName,
32692
                (word32)XSTRLEN(cert->unstructuredName),
32693
                &attrUnstructuredNameOid[0],
32694
                sizeof(attrUnstructuredNameOid), 1, 0);
32695
    }
32696
32697
    if (extSz) {
32698
        SetReqAttribSingle(output, &sz, NULL, 0, &attrExtensionRequestOid[0],
32699
                sizeof(attrExtensionRequestOid), 1, extSz);
32700
        /* The actual extension data will be tacked onto the output later. */
32701
    }
32702
32703
    return (int)sz;
32704
}
32705
32706
#ifdef WOLFSSL_CUSTOM_OID
32707
/* encode a custom oid and value */
32708
static int SetCustomObjectId(Cert* cert, byte* output, word32 outSz,
32709
    CertOidField* custom)
32710
{
32711
    int idx = 0, cust_lenSz, cust_oidSz;
32712
32713
    if (cert == NULL || output == NULL || custom == NULL) {
32714
        return BAD_FUNC_ARG;
32715
    }
32716
    if (custom->oid == NULL || custom->oidSz <= 0) {
32717
        return 0; /* none set */
32718
    }
32719
32720
    /* Octet String header */
32721
    cust_lenSz = SetOctetString(custom->valSz, NULL);
32722
    cust_oidSz = SetObjectId(custom->oidSz, NULL);
32723
32724
    /* check for output buffer room */
32725
    if ((word32)(custom->valSz + custom->oidSz + cust_lenSz + cust_oidSz) >
32726
                                                                        outSz) {
32727
        return BUFFER_E;
32728
    }
32729
32730
    /* put sequence with total */
32731
    idx = SetSequence(custom->valSz + custom->oidSz + cust_lenSz + cust_oidSz,
32732
                      output);
32733
32734
    /* put oid header */
32735
    idx += SetObjectId(custom->oidSz, output+idx);
32736
    XMEMCPY(output+idx, custom->oid, custom->oidSz);
32737
    idx += custom->oidSz;
32738
32739
    /* put value */
32740
    idx += SetOctetString(custom->valSz, output+idx);
32741
    XMEMCPY(output+idx, custom->val, custom->valSz);
32742
    idx += custom->valSz;
32743
32744
    return idx;
32745
}
32746
#endif /* WOLFSSL_CUSTOM_OID */
32747
32748
32749
/* encode info from cert into DER encoded format */
32750
static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
32751
                         DsaKey* dsaKey, ecc_key* eccKey,
32752
                         ed25519_key* ed25519Key, ed448_key* ed448Key,
32753
                         falcon_key* falconKey, dilithium_key* dilithiumKey,
32754
                         sphincs_key* sphincsKey)
32755
{
32756
    int ret;
32757
32758
    (void)eccKey;
32759
    (void)ed25519Key;
32760
    (void)ed448Key;
32761
    (void)falconKey;
32762
    (void)dilithiumKey;
32763
    (void)sphincsKey;
32764
32765
    if (cert == NULL || der == NULL)
32766
        return BAD_FUNC_ARG;
32767
32768
    if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL &&
32769
        dsaKey == NULL && ed448Key == NULL && falconKey == NULL &&
32770
        falconKey == NULL) {
32771
        return PUBLIC_KEY_E;
32772
    }
32773
32774
    /* init */
32775
    XMEMSET(der, 0, sizeof(DerCert));
32776
32777
    /* version */
32778
    der->versionSz = SetMyVersion((word32)cert->version, der->version, FALSE);
32779
32780
    /* subject name */
32781
#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
32782
    if (XSTRLEN((const char*)cert->sbjRaw) > 0) {
32783
        /* Use the raw subject */
32784
        int idx;
32785
32786
        der->subjectSz = (int)min(sizeof(der->subject),
32787
                (word32)XSTRLEN((const char*)cert->sbjRaw));
32788
        /* header */
32789
        idx = (int)SetSequence((word32)der->subjectSz, der->subject);
32790
        if (der->subjectSz + idx > (int)sizeof(der->subject)) {
32791
            return SUBJECT_E;
32792
        }
32793
32794
        XMEMCPY((char*)der->subject + idx, (const char*)cert->sbjRaw,
32795
                (size_t)der->subjectSz);
32796
        der->subjectSz += idx;
32797
    }
32798
    else
32799
#endif
32800
    {
32801
        der->subjectSz = SetNameEx(der->subject, sizeof(der->subject),
32802
                &cert->subject, cert->heap);
32803
    }
32804
    if (der->subjectSz <= 0)
32805
        return SUBJECT_E;
32806
32807
    /* public key */
32808
#ifndef NO_RSA
32809
    if (cert->keyType == RSA_KEY) {
32810
        if (rsaKey == NULL)
32811
            return PUBLIC_KEY_E;
32812
        der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey,
32813
                                           sizeof(der->publicKey), 1);
32814
    }
32815
#endif
32816
32817
#if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
32818
    if (cert->keyType == DSA_KEY) {
32819
        if (dsaKey == NULL)
32820
            return PUBLIC_KEY_E;
32821
        der->publicKeySz = wc_SetDsaPublicKey(der->publicKey, dsaKey,
32822
                                           sizeof(der->publicKey), 1);
32823
    }
32824
#endif
32825
32826
#ifdef HAVE_ECC
32827
    if (cert->keyType == ECC_KEY) {
32828
        if (eccKey == NULL)
32829
            return PUBLIC_KEY_E;
32830
        der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey,
32831
                                           sizeof(der->publicKey), 1, 0);
32832
    }
32833
#endif
32834
32835
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
32836
    if (cert->keyType == ED25519_KEY) {
32837
        if (ed25519Key == NULL)
32838
            return PUBLIC_KEY_E;
32839
        der->publicKeySz = wc_Ed25519PublicKeyToDer(ed25519Key, der->publicKey,
32840
            (word32)sizeof(der->publicKey), 1);
32841
    }
32842
#endif
32843
32844
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
32845
    if (cert->keyType == ED448_KEY) {
32846
        if (ed448Key == NULL)
32847
            return PUBLIC_KEY_E;
32848
        der->publicKeySz = wc_Ed448PublicKeyToDer(ed448Key, der->publicKey,
32849
            (word32)sizeof(der->publicKey), 1);
32850
    }
32851
#endif
32852
#if defined(HAVE_FALCON)
32853
    if ((cert->keyType == FALCON_LEVEL1_KEY) ||
32854
        (cert->keyType == FALCON_LEVEL5_KEY)) {
32855
        if (falconKey == NULL)
32856
            return PUBLIC_KEY_E;
32857
        der->publicKeySz = wc_Falcon_PublicKeyToDer(falconKey,
32858
            der->publicKey, (word32)sizeof(der->publicKey), 1);
32859
    }
32860
#endif
32861
#if defined(HAVE_DILITHIUM) && !defined(WOLFSSL_DILITHIUM_NO_ASN1)
32862
    if ((cert->keyType == ML_DSA_LEVEL2_KEY) ||
32863
        (cert->keyType == ML_DSA_LEVEL3_KEY) ||
32864
        (cert->keyType == ML_DSA_LEVEL5_KEY)
32865
    #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
32866
     || (cert->keyType == DILITHIUM_LEVEL2_KEY)
32867
     || (cert->keyType == DILITHIUM_LEVEL3_KEY)
32868
     || (cert->keyType == DILITHIUM_LEVEL5_KEY)
32869
   #endif
32870
        ) {
32871
        if (dilithiumKey == NULL)
32872
            return PUBLIC_KEY_E;
32873
        der->publicKeySz = wc_Dilithium_PublicKeyToDer(dilithiumKey,
32874
            der->publicKey, (word32)sizeof(der->publicKey), 1);
32875
    }
32876
#endif
32877
#if defined(HAVE_SPHINCS)
32878
    if ((cert->keyType == SPHINCS_FAST_LEVEL1_KEY) ||
32879
        (cert->keyType == SPHINCS_FAST_LEVEL3_KEY) ||
32880
        (cert->keyType == SPHINCS_FAST_LEVEL5_KEY) ||
32881
        (cert->keyType == SPHINCS_SMALL_LEVEL1_KEY) ||
32882
        (cert->keyType == SPHINCS_SMALL_LEVEL3_KEY) ||
32883
        (cert->keyType == SPHINCS_SMALL_LEVEL5_KEY)) {
32884
        if (sphincsKey == NULL)
32885
            return PUBLIC_KEY_E;
32886
        der->publicKeySz = wc_Sphincs_PublicKeyToDer(sphincsKey,
32887
            der->publicKey, (word32)sizeof(der->publicKey), 1);
32888
    }
32889
#endif
32890
32891
    if (der->publicKeySz <= 0)
32892
        return PUBLIC_KEY_E;
32893
32894
    /* set the extensions */
32895
    der->extensionsSz = 0;
32896
32897
    /* RFC 5280 : 4.2.1.9. Basic Constraints
32898
     * The pathLenConstraint field is meaningful only if the CA boolean is
32899
     * asserted and the key usage extension, if present, asserts the
32900
     * keyCertSign bit */
32901
    /* Set CA and path length */
32902
    if ((cert->isCA) && (cert->pathLenSet)
32903
#ifdef WOLFSSL_CERT_EXT
32904
        && ((cert->keyUsage & KEYUSE_KEY_CERT_SIGN) || (!cert->keyUsage))
32905
#endif
32906
        ) {
32907
        der->caSz = SetCaWithPathLen(der->ca, sizeof(der->ca), cert->pathLen);
32908
        if (der->caSz <= 0)
32909
            return CA_TRUE_E;
32910
32911
        der->extensionsSz += der->caSz;
32912
    }
32913
#ifdef WOLFSSL_ALLOW_ENCODING_CA_FALSE
32914
    /* Set CA */
32915
    else if (cert->isCaSet) {
32916
        der->caSz = SetCaEx(der->ca, sizeof(der->ca), cert->isCA);
32917
        if (der->caSz <= 0)
32918
            return EXTENSIONS_E;
32919
32920
        der->extensionsSz += der->caSz;
32921
    }
32922
#endif
32923
    /* Set CA true */
32924
    else if (cert->isCA) {
32925
        der->caSz = SetCa(der->ca, sizeof(der->ca));
32926
        if (der->caSz <= 0)
32927
            return CA_TRUE_E;
32928
32929
        der->extensionsSz += der->caSz;
32930
    }
32931
    /* Set Basic Constraint */
32932
    else if (cert->basicConstSet) {
32933
        der->caSz = SetBC(der->ca, sizeof(der->ca));
32934
        if (der->caSz <= 0)
32935
            return EXTENSIONS_E;
32936
32937
        der->extensionsSz += der->caSz;
32938
    }
32939
    else
32940
        der->caSz = 0;
32941
32942
#ifdef WOLFSSL_ALT_NAMES
32943
    /* Alternative Name */
32944
    if (cert->altNamesSz) {
32945
        der->altNamesSz = SetAltNames(der->altNames, sizeof(der->altNames),
32946
                                      cert->altNames, (word32)cert->altNamesSz,
32947
                                      cert->altNamesCrit);
32948
        if (der->altNamesSz <= 0)
32949
            return ALT_NAME_E;
32950
32951
        der->extensionsSz += der->altNamesSz;
32952
    }
32953
    else
32954
        der->altNamesSz = 0;
32955
#endif
32956
32957
#ifdef WOLFSSL_CERT_EXT
32958
    /* SKID */
32959
    if (cert->skidSz) {
32960
        /* check the provided SKID size */
32961
        if (cert->skidSz > (int)min(CTC_MAX_SKID_SIZE, sizeof(der->skid)))
32962
            return SKID_E;
32963
32964
        der->skidSz = SetSKID(der->skid, sizeof(der->skid),
32965
                              cert->skid, (word32)cert->skidSz);
32966
        if (der->skidSz <= 0)
32967
            return SKID_E;
32968
32969
        der->extensionsSz += der->skidSz;
32970
    }
32971
    else
32972
        der->skidSz = 0;
32973
32974
    /* Key Usage */
32975
    if (cert->keyUsage != 0) {
32976
        der->keyUsageSz = SetKeyUsage(der->keyUsage, sizeof(der->keyUsage),
32977
                                      cert->keyUsage);
32978
        if (der->keyUsageSz <= 0)
32979
            return KEYUSAGE_E;
32980
32981
        der->extensionsSz += der->keyUsageSz;
32982
    }
32983
    else
32984
        der->keyUsageSz = 0;
32985
32986
    /* Extended Key Usage */
32987
    if (cert->extKeyUsage != 0) {
32988
        der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage,
32989
                                sizeof(der->extKeyUsage), cert->extKeyUsage);
32990
        if (der->extKeyUsageSz <= 0)
32991
            return EXTKEYUSAGE_E;
32992
32993
        der->extensionsSz += der->extKeyUsageSz;
32994
    }
32995
    else
32996
        der->extKeyUsageSz = 0;
32997
32998
#endif /* WOLFSSL_CERT_EXT */
32999
33000
#ifdef WOLFSSL_CUSTOM_OID
33001
    /* encode a custom oid and value */
33002
    /* zero returns, means none set */
33003
    ret = SetCustomObjectId(cert, der->extCustom,
33004
        sizeof(der->extCustom), &cert->extCustom);
33005
    if (ret < 0)
33006
        return ret;
33007
    der->extCustomSz = ret;
33008
    der->extensionsSz += der->extCustomSz;
33009
#endif
33010
33011
    /* put extensions */
33012
    if (der->extensionsSz > 0) {
33013
        /* put the start of sequence (ID, Size) */
33014
        der->extensionsSz = (int)SetSequence((word32)der->extensionsSz,
33015
                                             der->extensions);
33016
        if (der->extensionsSz <= 0)
33017
            return EXTENSIONS_E;
33018
33019
        /* put CA */
33020
        if (der->caSz) {
33021
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
33022
                                &der->extensionsSz,
33023
                                der->ca, der->caSz);
33024
            if (ret <= 0)
33025
                return EXTENSIONS_E;
33026
        }
33027
33028
#ifdef WOLFSSL_ALT_NAMES
33029
        /* put Alternative Names */
33030
        if (der->altNamesSz) {
33031
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
33032
                                &der->extensionsSz,
33033
                                der->altNames, der->altNamesSz);
33034
            if (ret <= 0)
33035
                return EXTENSIONS_E;
33036
        }
33037
#endif
33038
33039
#ifdef WOLFSSL_CERT_EXT
33040
        /* put SKID */
33041
        if (der->skidSz) {
33042
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
33043
                                &der->extensionsSz,
33044
                                der->skid, der->skidSz);
33045
            if (ret <= 0)
33046
                return EXTENSIONS_E;
33047
        }
33048
33049
        /* put AKID */
33050
        if (der->akidSz) {
33051
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
33052
                                &der->extensionsSz,
33053
                                der->akid, der->akidSz);
33054
            if (ret <= 0)
33055
                return EXTENSIONS_E;
33056
        }
33057
33058
        /* put KeyUsage */
33059
        if (der->keyUsageSz) {
33060
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
33061
                                &der->extensionsSz,
33062
                                der->keyUsage, der->keyUsageSz);
33063
            if (ret <= 0)
33064
                return EXTENSIONS_E;
33065
        }
33066
33067
        /* put ExtendedKeyUsage */
33068
        if (der->extKeyUsageSz) {
33069
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
33070
                                &der->extensionsSz,
33071
                                der->extKeyUsage, der->extKeyUsageSz);
33072
            if (ret <= 0)
33073
                return EXTENSIONS_E;
33074
        }
33075
33076
    #ifdef WOLFSSL_CUSTOM_OID
33077
        if (der->extCustomSz) {
33078
            ret = SetExtensions(der->extensions, sizeof(der->extensions),
33079
                                &der->extensionsSz,
33080
                                der->extCustom, der->extCustomSz);
33081
            if (ret <= 0)
33082
                return EXTENSIONS_E;
33083
        }
33084
    #endif
33085
#endif /* WOLFSSL_CERT_EXT */
33086
    }
33087
33088
    der->attribSz = SetReqAttrib(der->attrib, cert, (word32)der->extensionsSz);
33089
    if (der->attribSz <= 0)
33090
        return REQ_ATTRIBUTE_E;
33091
33092
    der->total = der->versionSz + der->subjectSz + der->publicKeySz +
33093
        der->extensionsSz + der->attribSz;
33094
33095
    return 0;
33096
}
33097
33098
33099
/* write DER encoded cert req to buffer, size already checked */
33100
static int WriteCertReqBody(DerCert* der, byte* buf)
33101
{
33102
    int idx;
33103
33104
    /* signed part header */
33105
    idx = (int)SetSequence((word32)der->total, buf);
33106
    /* version */
33107
    if (buf)
33108
        XMEMCPY(buf + idx, der->version, (size_t)der->versionSz);
33109
    idx += der->versionSz;
33110
    /* subject */
33111
    if (buf)
33112
        XMEMCPY(buf + idx, der->subject, (size_t)der->subjectSz);
33113
    idx += der->subjectSz;
33114
    /* public key */
33115
    if (buf)
33116
        XMEMCPY(buf + idx, der->publicKey, (size_t)der->publicKeySz);
33117
    idx += der->publicKeySz;
33118
    /* attributes */
33119
    if (buf)
33120
        XMEMCPY(buf + idx, der->attrib, (size_t)der->attribSz);
33121
    idx += der->attribSz;
33122
    /* extensions */
33123
    if (der->extensionsSz) {
33124
        if (buf)
33125
            XMEMCPY(buf + idx, der->extensions, min((word32)der->extensionsSz,
33126
                                               sizeof(der->extensions)));
33127
        idx += der->extensionsSz;
33128
    }
33129
33130
    return idx;
33131
}
33132
#endif
33133
33134
#ifdef WOLFSSL_ASN_TEMPLATE
33135
/* ASN.1 template for Certificate Request body.
33136
 * PKCS #10: RFC 2986, 4.1 - CertificationRequestInfo
33137
 */
33138
static const ASNItem certReqBodyASN[] = {
33139
/* SEQ             */ { 0, ASN_SEQUENCE, 1, 1, 0 },
33140
                                             /* version */
33141
/* VER             */     { 1, ASN_INTEGER, 0, 0, 0 },
33142
                                             /* subject */
33143
/* SUBJ_SEQ        */     { 1, ASN_SEQUENCE, 1, 0, 0 },
33144
                                             /* subjectPKInfo */
33145
/* SPUBKEYINFO_SEQ */     { 1, ASN_SEQUENCE, 1, 0, 0 },
33146
                                             /*  attributes*/
33147
/* ATTRS           */     { 1, ASN_CONTEXT_SPECIFIC | 0, 1, 1, 1 },
33148
                                                 /* Challenge Password Attribute */
33149
/* ATTRS_CPW_SEQ   */         { 2, ASN_SEQUENCE, 1, 1, 1 },
33150
/* ATTRS_CPW_OID   */             { 3, ASN_OBJECT_ID, 0, 0, 0 },
33151
/* ATTRS_CPW_SET   */             { 3, ASN_SET, 1, 1, 0 },
33152
/* ATTRS_CPW_PS    */                 { 4, ASN_PRINTABLE_STRING, 0, 0, 0 },
33153
/* ATTRS_CPW_UTF   */                 { 4, ASN_UTF8STRING, 0, 0, 0 },
33154
/* ATTRS_USN_SEQ   */         { 2, ASN_SEQUENCE, 1, 1, 1 },
33155
/* ATTRS_USN_OID   */             { 3, ASN_OBJECT_ID, 0, 0, 0 },
33156
/* ATTRS_USN_SET   */             { 3, ASN_SET, 1, 1, 0 },
33157
/* ATTRS_USN_PS    */                 { 4, ASN_PRINTABLE_STRING, 0, 0, 0 },
33158
/* ATTRS_USN_UTF   */                 { 4, ASN_UTF8STRING, 0, 0, 0 },
33159
                                                 /* Extensions Attribute */
33160
/* EXT_SEQ         */         { 2, ASN_SEQUENCE, 1, 1, 1 },
33161
/* EXT_OID         */             { 3, ASN_OBJECT_ID, 0, 0, 0 },
33162
/* EXT_SET         */             { 3, ASN_SET, 1, 1, 0 },
33163
/* EXT_BODY        */                 { 4, ASN_SEQUENCE, 1, 0, 0 },
33164
};
33165
enum {
33166
    CERTREQBODYASN_IDX_SEQ = 0,
33167
    CERTREQBODYASN_IDX_VER,
33168
    CERTREQBODYASN_IDX_SUBJ_SEQ,
33169
    CERTREQBODYASN_IDX_SPUBKEYINFO_SEQ,
33170
    CERTREQBODYASN_IDX_ATTRS,
33171
    CERTREQBODYASN_IDX_ATTRS_CPW_SEQ,
33172
    CERTREQBODYASN_IDX_ATTRS_CPW_OID,
33173
    CERTREQBODYASN_IDX_ATTRS_CPW_SET,
33174
    CERTREQBODYASN_IDX_ATTRS_CPW_PS,
33175
    CERTREQBODYASN_IDX_ATTRS_CPW_UTF,
33176
    CERTREQBODYASN_IDX_ATTRS_USN_SEQ,
33177
    CERTREQBODYASN_IDX_ATTRS_USN_OID,
33178
    CERTREQBODYASN_IDX_ATTRS_USN_SET,
33179
    CERTREQBODYASN_IDX_ATTRS_USN_PS,
33180
    CERTREQBODYASN_IDX_ATTRS_USN_UTF,
33181
    CERTREQBODYASN_IDX_EXT_SEQ,
33182
    CERTREQBODYASN_IDX_EXT_OID,
33183
    CERTREQBODYASN_IDX_EXT_SET,
33184
    CERTREQBODYASN_IDX_EXT_BODY
33185
};
33186
33187
/* Number of items in ASN.1 template for Certificate Request body. */
33188
#define certReqBodyASN_Length (sizeof(certReqBodyASN) / sizeof(ASNItem))
33189
#endif
33190
33191
static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
33192
                   RsaKey* rsaKey, DsaKey* dsaKey, ecc_key* eccKey,
33193
                   ed25519_key* ed25519Key, ed448_key* ed448Key,
33194
                   falcon_key* falconKey, dilithium_key* dilithiumKey,
33195
                   sphincs_key* sphincsKey)
33196
{
33197
#ifndef WOLFSSL_ASN_TEMPLATE
33198
    int ret;
33199
#ifdef WOLFSSL_SMALL_STACK
33200
    DerCert* der;
33201
#else
33202
    DerCert der[1];
33203
#endif
33204
33205
    if (eccKey)
33206
        cert->keyType = ECC_KEY;
33207
    else if (rsaKey)
33208
        cert->keyType = RSA_KEY;
33209
    else if (dsaKey)
33210
        cert->keyType = DSA_KEY;
33211
    else if (ed25519Key)
33212
        cert->keyType = ED25519_KEY;
33213
    else if (ed448Key)
33214
        cert->keyType = ED448_KEY;
33215
#ifdef HAVE_FALCON
33216
    else if ((falconKey != NULL) && (falconKey->level == 1))
33217
        cert->keyType = FALCON_LEVEL1_KEY;
33218
    else if ((falconKey != NULL) && (falconKey->level == 5))
33219
        cert->keyType = FALCON_LEVEL5_KEY;
33220
#endif /* HAVE_FALCON */
33221
#ifdef HAVE_DILITHIUM
33222
    #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
33223
    else if ((dilithiumKey != NULL) &&
33224
                (dilithiumKey->params->level == WC_ML_DSA_44_DRAFT)) {
33225
        cert->keyType = DILITHIUM_LEVEL2_KEY;
33226
    }
33227
    else if ((dilithiumKey != NULL) &&
33228
                (dilithiumKey->params->level == WC_ML_DSA_65_DRAFT)) {
33229
        cert->keyType = DILITHIUM_LEVEL3_KEY;
33230
    }
33231
    else if ((dilithiumKey != NULL) &&
33232
                (dilithiumKey->params->level == WC_ML_DSA_87_DRAFT)) {
33233
        cert->keyType = DILITHIUM_LEVEL5_KEY;
33234
    }
33235
    #endif
33236
    else if ((dilithiumKey != NULL) &&
33237
                (dilithiumKey->params->level == WC_ML_DSA_44)) {
33238
        cert->keyType = ML_DSA_LEVEL2_KEY;
33239
    }
33240
    else if ((dilithiumKey != NULL) &&
33241
                (dilithiumKey->params->level == WC_ML_DSA_65)) {
33242
        cert->keyType = ML_DSA_LEVEL3_KEY;
33243
    }
33244
    else if ((dilithiumKey != NULL) &&
33245
                (dilithiumKey->params->level == WC_ML_DSA_87)) {
33246
        cert->keyType = ML_DSA_LEVEL5_KEY;
33247
    }
33248
#endif /* HAVE_DILITHIUM */
33249
#ifdef HAVE_SPHINCS
33250
    else if ((sphincsKey != NULL) && (sphincsKey->level == 1)
33251
             && (sphincsKey->optim == FAST_VARIANT))
33252
        cert->keyType = SPHINCS_FAST_LEVEL1_KEY;
33253
    else if ((sphincsKey != NULL) && (sphincsKey->level == 3)
33254
             && (sphincsKey->optim == FAST_VARIANT))
33255
        cert->keyType = SPHINCS_FAST_LEVEL3_KEY;
33256
    else if ((sphincsKey != NULL) && (sphincsKey->level == 5)
33257
             && (sphincsKey->optim == FAST_VARIANT))
33258
        cert->keyType = SPHINCS_FAST_LEVEL5_KEY;
33259
    else if ((sphincsKey != NULL) && (sphincsKey->level == 1)
33260
             && (sphincsKey->optim == SMALL_VARIANT))
33261
        cert->keyType = SPHINCS_SMALL_LEVEL1_KEY;
33262
    else if ((sphincsKey != NULL) && (sphincsKey->level == 3)
33263
             && (sphincsKey->optim == SMALL_VARIANT))
33264
        cert->keyType = SPHINCS_SMALL_LEVEL3_KEY;
33265
    else if ((sphincsKey != NULL) && (sphincsKey->level == 5)
33266
             && (sphincsKey->optim == SMALL_VARIANT))
33267
        cert->keyType = SPHINCS_SMALL_LEVEL5_KEY;
33268
#endif /* HAVE_SPHINCS */
33269
    else
33270
        return BAD_FUNC_ARG;
33271
33272
#ifdef WOLFSSL_SMALL_STACK
33273
    der = (DerCert*)XMALLOC(sizeof(DerCert), cert->heap,
33274
                                                    DYNAMIC_TYPE_TMP_BUFFER);
33275
    if (der == NULL)
33276
        return MEMORY_E;
33277
#endif
33278
33279
    ret = EncodeCertReq(cert, der, rsaKey, dsaKey, eccKey, ed25519Key, ed448Key,
33280
                        falconKey, dilithiumKey, sphincsKey);
33281
33282
    if (ret == 0) {
33283
        if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
33284
            ret = BUFFER_E;
33285
        else
33286
            ret = cert->bodySz = WriteCertReqBody(der, derBuffer);
33287
    }
33288
33289
#ifdef WOLFSSL_SMALL_STACK
33290
    XFREE(der, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
33291
#endif
33292
33293
    return ret;
33294
#else
33295
    DECL_ASNSETDATA(dataASN, certReqBodyASN_Length);
33296
    word32 publicKeySz = 0;
33297
    word32 subjectSz = 0;
33298
    word32 extSz = 0;
33299
    int sz = 0;
33300
    int ret = 0;
33301
#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
33302
    word32 sbjRawSz = 0;
33303
#endif
33304
33305
    /* Unused without OQS */
33306
    (void)falconKey;
33307
    (void)dilithiumKey;
33308
    (void)sphincsKey;
33309
33310
    CALLOC_ASNSETDATA(dataASN, certReqBodyASN_Length, ret, cert->heap);
33311
33312
    if (ret == 0) {
33313
        /* Set key type into certificate object based on key passed in. */
33314
        if (rsaKey != NULL) {
33315
            cert->keyType = RSA_KEY;
33316
        }
33317
        else if (eccKey != NULL) {
33318
            cert->keyType = ECC_KEY;
33319
        }
33320
        else if (dsaKey != NULL) {
33321
            cert->keyType = DSA_KEY;
33322
        }
33323
        else if (ed25519Key != NULL) {
33324
            cert->keyType = ED25519_KEY;
33325
        }
33326
        else if (ed448Key != NULL) {
33327
            cert->keyType = ED448_KEY;
33328
        }
33329
#ifdef HAVE_FALCON
33330
        else if ((falconKey != NULL) && (falconKey->level == 1)) {
33331
            cert->keyType = FALCON_LEVEL1_KEY;
33332
        }
33333
        else if ((falconKey != NULL) && (falconKey->level == 5)) {
33334
            cert->keyType = FALCON_LEVEL5_KEY;
33335
        }
33336
#endif /* HAVE_FALCON */
33337
#ifdef HAVE_DILITHIUM
33338
    #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
33339
        else if ((dilithiumKey != NULL) &&
33340
                    (dilithiumKey->params->level == WC_ML_DSA_44_DRAFT)) {
33341
            cert->keyType = DILITHIUM_LEVEL2_KEY;
33342
        }
33343
        else if ((dilithiumKey != NULL) &&
33344
                    (dilithiumKey->params->level == WC_ML_DSA_65_DRAFT)) {
33345
            cert->keyType = DILITHIUM_LEVEL3_KEY;
33346
        }
33347
        else if ((dilithiumKey != NULL) &&
33348
                    (dilithiumKey->params->level == WC_ML_DSA_87_DRAFT)) {
33349
            cert->keyType = DILITHIUM_LEVEL5_KEY;
33350
        }
33351
    #endif
33352
        else if ((dilithiumKey != NULL) &&
33353
                    (dilithiumKey->level == WC_ML_DSA_44)) {
33354
            cert->keyType = ML_DSA_LEVEL2_KEY;
33355
        }
33356
        else if ((dilithiumKey != NULL) &&
33357
                    (dilithiumKey->level == WC_ML_DSA_65)) {
33358
            cert->keyType = ML_DSA_LEVEL3_KEY;
33359
        }
33360
        else if ((dilithiumKey != NULL) &&
33361
                    (dilithiumKey->level == WC_ML_DSA_87)) {
33362
            cert->keyType = ML_DSA_LEVEL5_KEY;
33363
        }
33364
#endif /* HAVE_DILITHIUM */
33365
#ifdef HAVE_SPHINCS
33366
        else if ((sphincsKey != NULL) && (sphincsKey->level == 1)
33367
                 && (sphincsKey->optim == FAST_VARIANT)) {
33368
            cert->keyType = SPHINCS_FAST_LEVEL1_KEY;
33369
        }
33370
        else if ((sphincsKey != NULL) && (sphincsKey->level == 3)
33371
                 && (sphincsKey->optim == FAST_VARIANT)) {
33372
            cert->keyType = SPHINCS_FAST_LEVEL3_KEY;
33373
        }
33374
        else if ((sphincsKey != NULL) && (sphincsKey->level == 5)
33375
                 && (sphincsKey->optim == FAST_VARIANT)) {
33376
            cert->keyType = SPHINCS_FAST_LEVEL5_KEY;
33377
        }
33378
        else if ((sphincsKey != NULL) && (sphincsKey->level == 1)
33379
                 && (sphincsKey->optim == SMALL_VARIANT)) {
33380
            cert->keyType = SPHINCS_SMALL_LEVEL1_KEY;
33381
        }
33382
        else if ((sphincsKey != NULL) && (sphincsKey->level == 3)
33383
                 && (sphincsKey->optim == SMALL_VARIANT)) {
33384
            cert->keyType = SPHINCS_SMALL_LEVEL3_KEY;
33385
        }
33386
        else if ((sphincsKey != NULL) && (sphincsKey->level == 5)
33387
                 && (sphincsKey->optim == SMALL_VARIANT)) {
33388
            cert->keyType = SPHINCS_SMALL_LEVEL5_KEY;
33389
        }
33390
#endif /* HAVE_SPHINCS */
33391
        else {
33392
            ret = BAD_FUNC_ARG;
33393
        }
33394
    }
33395
    if (ret == 0) {
33396
        /* Determine subject name size. */
33397
    #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
33398
        sbjRawSz = (word32)XSTRLEN((const char*)cert->sbjRaw);
33399
        if (sbjRawSz > 0) {
33400
            subjectSz = min(sizeof(cert->sbjRaw), sbjRawSz);
33401
        }
33402
        else
33403
    #endif
33404
        {
33405
            ret = SetNameEx(NULL, WC_ASN_NAME_MAX, &cert->subject, cert->heap);
33406
            subjectSz = (word32)ret;
33407
        }
33408
    }
33409
    if (ret >= 0) {
33410
        /* Determine encode public key size. */
33411
         ret = EncodePublicKey(cert->keyType, NULL, 0, rsaKey,
33412
             eccKey, ed25519Key, ed448Key, dsaKey, falconKey,
33413
             dilithiumKey, sphincsKey);
33414
         publicKeySz = (word32)ret;
33415
    }
33416
    if (ret >= 0) {
33417
        /* Determine encode extensions size. */
33418
        ret = EncodeExtensions(cert, NULL, 0, 1);
33419
        extSz = (word32)ret;
33420
    }
33421
    if (ret >= 0) {
33422
        /* Set version. */
33423
        SetASN_Int8Bit(&dataASN[CERTREQBODYASN_IDX_VER], (byte)cert->version);
33424
    #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
33425
        if (sbjRawSz > 0) {
33426
            /* Put in encoded subject name. */
33427
            SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_SUBJ_SEQ], cert->sbjRaw,
33428
                    subjectSz);
33429
        }
33430
        else
33431
    #endif
33432
        {
33433
            /* Leave space for subject name. */
33434
            SetASN_ReplaceBuffer(&dataASN[CERTREQBODYASN_IDX_SUBJ_SEQ], NULL,
33435
                    subjectSz);
33436
        }
33437
        /* Leave space for public key. */
33438
        SetASN_ReplaceBuffer(&dataASN[CERTREQBODYASN_IDX_SPUBKEYINFO_SEQ],
33439
                NULL, publicKeySz);
33440
        if (cert->challengePw[0] != '\0') {
33441
            /* Add challenge password attribute. */
33442
            /* Set challenge password OID. */
33443
            SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_ATTRS_CPW_OID],
33444
                attrChallengePasswordOid, sizeof(attrChallengePasswordOid));
33445
            /* Enable the ASN template item with the appropriate tag. */
33446
            if (cert->challengePwPrintableString) {
33447
                /* PRINTABLE_STRING - set buffer */
33448
                SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_ATTRS_CPW_PS],
33449
                        (byte*)cert->challengePw,
33450
                        (word32)XSTRLEN(cert->challengePw));
33451
                /* UTF8STRING - don't encode */
33452
                dataASN[CERTREQBODYASN_IDX_ATTRS_CPW_UTF].noOut = 1;
33453
            }
33454
            else {
33455
                /* PRINTABLE_STRING - don't encode */
33456
                dataASN[CERTREQBODYASN_IDX_ATTRS_CPW_PS].noOut = 1;
33457
                /* UTF8STRING - set buffer */
33458
                SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_ATTRS_CPW_UTF],
33459
                        (byte*)cert->challengePw,
33460
                        (word32)XSTRLEN(cert->challengePw));
33461
            }
33462
        }
33463
        else {
33464
            /* Leave out challenge password attribute items. */
33465
            SetASNItem_NoOutNode(dataASN, certReqBodyASN,
33466
                    CERTREQBODYASN_IDX_ATTRS_CPW_SEQ, certReqBodyASN_Length);
33467
        }
33468
        if (cert->unstructuredName[0] != '\0') {
33469
            /* Add unstructured name attribute. */
33470
            /* Set unstructured name OID. */
33471
            SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_ATTRS_USN_OID],
33472
                attrUnstructuredNameOid, sizeof(attrUnstructuredNameOid));
33473
                /* PRINTABLE_STRING - set buffer */
33474
                SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_ATTRS_USN_PS],
33475
                        (byte*)cert->unstructuredName,
33476
                        (word32)XSTRLEN(cert->unstructuredName));
33477
                /* UTF8STRING - don't encode */
33478
                dataASN[CERTREQBODYASN_IDX_ATTRS_USN_UTF].noOut = 1;
33479
        }
33480
        else {
33481
            /* Leave out unstructured name attribute item. */
33482
            SetASNItem_NoOutNode(dataASN, certReqBodyASN,
33483
                    CERTREQBODYASN_IDX_ATTRS_USN_SEQ, certReqBodyASN_Length);
33484
        }
33485
        if (extSz > 0) {
33486
            /* Set extension attribute OID. */
33487
            SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_EXT_OID], attrExtensionRequestOid,
33488
                sizeof(attrExtensionRequestOid));
33489
            /* Leave space for data. */
33490
            SetASN_Buffer(&dataASN[CERTREQBODYASN_IDX_EXT_BODY], NULL, extSz);
33491
        }
33492
        else {
33493
            /* Leave out extension attribute items. */
33494
            SetASNItem_NoOutNode(dataASN, certReqBodyASN,
33495
                    CERTREQBODYASN_IDX_EXT_SEQ, certReqBodyASN_Length);
33496
        }
33497
33498
        /* Calculate size of encoded certificate request body. */
33499
        ret = SizeASN_Items(certReqBodyASN, dataASN, certReqBodyASN_Length,
33500
                            &sz);
33501
    }
33502
    /* Check buffer is big enough for encoded data. */
33503
    if ((ret == 0) && (sz > (int)derSz)) {
33504
        ret = BUFFER_E;
33505
    }
33506
    if (ret == 0 && derBuffer != NULL) {
33507
        /* Encode certificate request body into buffer. */
33508
        SetASN_Items(certReqBodyASN, dataASN, certReqBodyASN_Length, derBuffer);
33509
33510
        /* Put in generated data */
33511
    #if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
33512
        if (sbjRawSz == 0)
33513
    #endif
33514
        {
33515
            /* Encode subject name into space in buffer. */
33516
            ret = SetNameEx(
33517
                (byte*)dataASN[CERTREQBODYASN_IDX_SUBJ_SEQ].data.buffer.data,
33518
                dataASN[CERTREQBODYASN_IDX_SUBJ_SEQ].data.buffer.length,
33519
                &cert->subject, cert->heap);
33520
        }
33521
    }
33522
    if (ret >= 0 && derBuffer != NULL) {
33523
        /* Encode public key into space in buffer. */
33524
        ret = EncodePublicKey(cert->keyType,
33525
            (byte*)dataASN[CERTREQBODYASN_IDX_SPUBKEYINFO_SEQ].data.buffer.data,
33526
            (int)dataASN[CERTREQBODYASN_IDX_SPUBKEYINFO_SEQ].data.buffer.length,
33527
            rsaKey, eccKey, ed25519Key, ed448Key, dsaKey, falconKey,
33528
            dilithiumKey, sphincsKey);
33529
    }
33530
    if ((ret >= 0 && derBuffer != NULL) &&
33531
            (!dataASN[CERTREQBODYASN_IDX_EXT_BODY].noOut)) {
33532
        /* Encode extensions into space in buffer. */
33533
        ret = EncodeExtensions(cert,
33534
                (byte*)dataASN[CERTREQBODYASN_IDX_EXT_BODY].data.buffer.data,
33535
                dataASN[CERTREQBODYASN_IDX_EXT_BODY].data.buffer.length, 1);
33536
    }
33537
    if (ret >= 0) {
33538
        /* Store encoded certificate request body size. */
33539
        cert->bodySz = sz;
33540
        /* Return the encoding size. */
33541
        ret = sz;
33542
    }
33543
33544
    FREE_ASNSETDATA(dataASN, cert->heap);
33545
    return ret;
33546
#endif /* WOLFSSL_ASN_TEMPLATE */
33547
}
33548
33549
int wc_MakeCertReq_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType,
33550
                      void* key)
33551
{
33552
    RsaKey*        rsaKey = NULL;
33553
    DsaKey*        dsaKey = NULL;
33554
    ecc_key*       eccKey = NULL;
33555
    ed25519_key*   ed25519Key = NULL;
33556
    ed448_key*     ed448Key = NULL;
33557
    falcon_key*    falconKey = NULL;
33558
    dilithium_key* dilithiumKey = NULL;
33559
    sphincs_key*   sphincsKey = NULL;
33560
33561
    if (keyType == RSA_TYPE)
33562
        rsaKey = (RsaKey*)key;
33563
    else if (keyType == DSA_TYPE)
33564
        dsaKey = (DsaKey*)key;
33565
    else if (keyType == ECC_TYPE)
33566
        eccKey = (ecc_key*)key;
33567
    else if (keyType == ED25519_TYPE)
33568
        ed25519Key = (ed25519_key*)key;
33569
    else if (keyType == ED448_TYPE)
33570
        ed448Key = (ed448_key*)key;
33571
    else if (keyType == FALCON_LEVEL1_TYPE)
33572
        falconKey = (falcon_key*)key;
33573
    else if (keyType == FALCON_LEVEL5_TYPE)
33574
        falconKey = (falcon_key*)key;
33575
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
33576
    else if (keyType == DILITHIUM_LEVEL2_TYPE)
33577
        dilithiumKey = (dilithium_key*)key;
33578
    else if (keyType == DILITHIUM_LEVEL3_TYPE)
33579
        dilithiumKey = (dilithium_key*)key;
33580
    else if (keyType == DILITHIUM_LEVEL5_TYPE)
33581
        dilithiumKey = (dilithium_key*)key;
33582
#endif
33583
    else if (keyType == ML_DSA_LEVEL2_TYPE)
33584
        dilithiumKey = (dilithium_key*)key;
33585
    else if (keyType == ML_DSA_LEVEL3_TYPE)
33586
        dilithiumKey = (dilithium_key*)key;
33587
    else if (keyType == ML_DSA_LEVEL5_TYPE)
33588
        dilithiumKey = (dilithium_key*)key;
33589
    else if (keyType == SPHINCS_FAST_LEVEL1_TYPE)
33590
        sphincsKey = (sphincs_key*)key;
33591
    else if (keyType == SPHINCS_FAST_LEVEL3_TYPE)
33592
        sphincsKey = (sphincs_key*)key;
33593
    else if (keyType == SPHINCS_FAST_LEVEL5_TYPE)
33594
        sphincsKey = (sphincs_key*)key;
33595
    else if (keyType == SPHINCS_SMALL_LEVEL1_TYPE)
33596
        sphincsKey = (sphincs_key*)key;
33597
    else if (keyType == SPHINCS_SMALL_LEVEL3_TYPE)
33598
        sphincsKey = (sphincs_key*)key;
33599
    else if (keyType == SPHINCS_SMALL_LEVEL5_TYPE)
33600
        sphincsKey = (sphincs_key*)key;
33601
33602
    return MakeCertReq(cert, derBuffer, derSz, rsaKey, dsaKey, eccKey,
33603
                       ed25519Key, ed448Key, falconKey, dilithiumKey,
33604
                       sphincsKey);
33605
}
33606
33607
WOLFSSL_ABI
33608
int wc_MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
33609
                   RsaKey* rsaKey, ecc_key* eccKey)
33610
{
33611
    return MakeCertReq(cert, derBuffer, derSz, rsaKey, NULL, eccKey, NULL,
33612
                       NULL, NULL, NULL, NULL);
33613
}
33614
#endif /* WOLFSSL_CERT_REQ */
33615
33616
33617
static int SignCert(int requestSz, int sType, byte* buf, word32 buffSz,
33618
                    RsaKey* rsaKey, ecc_key* eccKey, ed25519_key* ed25519Key,
33619
                    ed448_key* ed448Key, falcon_key* falconKey,
33620
                    dilithium_key* dilithiumKey, sphincs_key* sphincsKey,
33621
                    WC_RNG* rng)
33622
{
33623
    int sigSz = 0;
33624
    void* heap = NULL;
33625
    CertSignCtx  certSignCtx_lcl;
33626
    CertSignCtx* certSignCtx = &certSignCtx_lcl;
33627
33628
    XMEMSET(certSignCtx, 0, sizeof(*certSignCtx));
33629
33630
    if (requestSz < 0)
33631
        return requestSz;
33632
33633
    /* locate ctx */
33634
    if (rsaKey) {
33635
    #ifndef NO_RSA
33636
    #ifdef WOLFSSL_ASYNC_CRYPT
33637
        certSignCtx = &rsaKey->certSignCtx;
33638
    #endif
33639
        heap = rsaKey->heap;
33640
    #else
33641
        return NOT_COMPILED_IN;
33642
    #endif /* NO_RSA */
33643
    }
33644
    else if (eccKey) {
33645
    #ifdef HAVE_ECC
33646
    #ifdef WOLFSSL_ASYNC_CRYPT
33647
        certSignCtx = &eccKey->certSignCtx;
33648
    #endif
33649
        heap = eccKey->heap;
33650
    #else
33651
        return NOT_COMPILED_IN;
33652
    #endif /* HAVE_ECC */
33653
    }
33654
33655
#ifndef WOLFSSL_NO_MALLOC
33656
    if (certSignCtx->sig == NULL) {
33657
        certSignCtx->sig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, heap,
33658
            DYNAMIC_TYPE_TMP_BUFFER);
33659
        if (certSignCtx->sig == NULL)
33660
            return MEMORY_E;
33661
    }
33662
#endif
33663
33664
    sigSz = MakeSignature(certSignCtx, buf, (word32)requestSz, certSignCtx->sig,
33665
        MAX_ENCODED_SIG_SZ, rsaKey, eccKey, ed25519Key, ed448Key,
33666
        falconKey, dilithiumKey, sphincsKey, rng, (word32)sType, heap);
33667
#ifdef WOLFSSL_ASYNC_CRYPT
33668
    if (sigSz == WC_NO_ERR_TRACE(WC_PENDING_E)) {
33669
        /* Not free'ing certSignCtx->sig here because it could still be in use
33670
         * with async operations. */
33671
        return sigSz;
33672
    }
33673
#endif
33674
33675
    if (sigSz >= 0) {
33676
        if (requestSz + MAX_SEQ_SZ * 2 + sigSz > (int)buffSz)
33677
            sigSz = BUFFER_E;
33678
        else
33679
            sigSz = AddSignature(buf, requestSz, certSignCtx->sig, sigSz,
33680
                                 sType);
33681
    }
33682
33683
#ifndef WOLFSSL_NO_MALLOC
33684
    XFREE(certSignCtx->sig, heap, DYNAMIC_TYPE_TMP_BUFFER);
33685
    certSignCtx->sig = NULL;
33686
#endif
33687
33688
    return sigSz;
33689
}
33690
33691
#ifdef WOLFSSL_DUAL_ALG_CERTS
33692
/* Generate a signature from input buffer using
33693
 * any key type.
33694
 *
33695
 * @param [out] sig     The signature buffer to write in.
33696
 * @param [out] sigsz   The signature buffer size.
33697
 * @param [in]  sType   The signature type.
33698
 * @param [in]  buf     The input buf to sign.
33699
 * @param [in]  bufSz   The buffer size
33700
 * @param [in]  keyType The key type.
33701
 * @param [in]  key     Key data.
33702
 * @param [in]  rng     Random number generator.
33703
 *
33704
 * @return  Size of signature on success.
33705
 * @return  < 0 on error.
33706
 * */
33707
int wc_MakeSigWithBitStr(byte *sig, int sigSz, int sType, byte* buf,
33708
                         word32 bufSz, int keyType, void* key, WC_RNG* rng)
33709
{
33710
    RsaKey*            rsaKey = NULL;
33711
    ecc_key*           eccKey = NULL;
33712
    ed25519_key*       ed25519Key = NULL;
33713
    ed448_key*         ed448Key = NULL;
33714
    falcon_key*        falconKey = NULL;
33715
    dilithium_key*     dilithiumKey = NULL;
33716
    sphincs_key*       sphincsKey = NULL;
33717
    int ret = 0;
33718
    int headerSz;
33719
    void* heap = NULL;
33720
    CertSignCtx  certSignCtx_lcl;
33721
    CertSignCtx* certSignCtx = &certSignCtx_lcl;
33722
33723
    WOLFSSL_ENTER("wc_MakeSigWithBitStr");
33724
33725
    if ((sig == NULL) || (sigSz <= 0)) {
33726
        return BAD_FUNC_ARG;
33727
    }
33728
33729
    XMEMSET(certSignCtx, 0, sizeof(*certSignCtx));
33730
33731
    switch (keyType)
33732
    {
33733
        case RSA_TYPE:
33734
            rsaKey = (RsaKey*)key;
33735
            break;
33736
        case ECC_TYPE:
33737
            eccKey = (ecc_key*)key;
33738
            break;
33739
        case ED25519_TYPE:
33740
            ed25519Key = (ed25519_key*)key;
33741
            break;
33742
        case ED448_TYPE:
33743
            ed448Key = (ed448_key*)key;
33744
            break;
33745
        case FALCON_LEVEL1_TYPE:
33746
        case FALCON_LEVEL5_TYPE:
33747
            falconKey = (falcon_key*)key;
33748
            break;
33749
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
33750
        case DILITHIUM_LEVEL2_TYPE:
33751
        case DILITHIUM_LEVEL3_TYPE:
33752
        case DILITHIUM_LEVEL5_TYPE:
33753
#endif
33754
        case ML_DSA_LEVEL2_TYPE:
33755
        case ML_DSA_LEVEL3_TYPE:
33756
        case ML_DSA_LEVEL5_TYPE:
33757
            dilithiumKey = (dilithium_key*)key;
33758
            break;
33759
        case SPHINCS_FAST_LEVEL1_TYPE:
33760
        case SPHINCS_FAST_LEVEL3_TYPE:
33761
        case SPHINCS_FAST_LEVEL5_TYPE:
33762
        case SPHINCS_SMALL_LEVEL1_TYPE:
33763
        case SPHINCS_SMALL_LEVEL3_TYPE:
33764
        case SPHINCS_SMALL_LEVEL5_TYPE:
33765
            sphincsKey = (sphincs_key*)key;
33766
            break;
33767
        default:
33768
            return BAD_FUNC_ARG;
33769
    }
33770
33771
    /* locate ctx */
33772
    if (rsaKey) {
33773
    #ifndef NO_RSA
33774
    #ifdef WOLFSSL_ASYNC_CRYPT
33775
        certSignCtx = &rsaKey->certSignCtx;
33776
    #endif
33777
        heap = rsaKey->heap;
33778
    #else
33779
        return NOT_COMPILED_IN;
33780
    #endif /* NO_RSA */
33781
    }
33782
    else if (eccKey) {
33783
    #ifdef HAVE_ECC
33784
    #ifdef WOLFSSL_ASYNC_CRYPT
33785
        certSignCtx = &eccKey->certSignCtx;
33786
    #endif
33787
        heap = eccKey->heap;
33788
    #else
33789
        return NOT_COMPILED_IN;
33790
    #endif /* HAVE_ECC */
33791
    }
33792
33793
#ifndef WOLFSSL_NO_MALLOC
33794
    if (certSignCtx->sig == NULL) {
33795
        certSignCtx->sig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, heap,
33796
            DYNAMIC_TYPE_TMP_BUFFER);
33797
        if (certSignCtx->sig == NULL)
33798
            return MEMORY_E;
33799
    }
33800
#endif
33801
33802
    ret = MakeSignature(certSignCtx, buf, (word32)bufSz, certSignCtx->sig,
33803
        MAX_ENCODED_SIG_SZ, rsaKey, eccKey, ed25519Key, ed448Key,
33804
        falconKey, dilithiumKey, sphincsKey, rng, (word32)sType, heap);
33805
#ifdef WOLFSSL_ASYNC_CRYPT
33806
    if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) {
33807
        /* Not free'ing certSignCtx->sig here because it could still be in use
33808
         * with async operations. */
33809
        return ret;
33810
    }
33811
#endif
33812
33813
    if (ret <= 0) {
33814
    #ifndef WOLFSSL_NO_MALLOC
33815
        XFREE(certSignCtx->sig, heap, DYNAMIC_TYPE_TMP_BUFFER);
33816
        certSignCtx->sig = NULL;
33817
    #endif
33818
        return ret;
33819
    }
33820
33821
    headerSz = SetBitString(ret, 0, NULL);
33822
    if (headerSz + ret > sigSz) {
33823
        ret = BUFFER_E;
33824
    }
33825
33826
    if (ret > 0) {
33827
       sig += SetBitString(ret, 0, sig);
33828
       XMEMCPY(sig, certSignCtx->sig, ret);
33829
       ret += headerSz;
33830
    }
33831
33832
#ifndef WOLFSSL_NO_MALLOC
33833
    XFREE(certSignCtx->sig, heap, DYNAMIC_TYPE_TMP_BUFFER);
33834
    certSignCtx->sig = NULL;
33835
#endif
33836
    return ret;
33837
}
33838
#endif /* WOLFSSL_DUAL_ALG_CERTS */
33839
33840
/* Sign an x509 Certificate v3 from cert input using any
33841
 * key type, and write to buffer.
33842
 *
33843
 * @param [in]     requestSz Size of requested data to sign.
33844
 * @param [in]     sType     The signature type.
33845
 * @param [in,out] buf       Der buffer to sign.
33846
 * @param [in]     buffSz    Der buffer size.
33847
 * @param [in]     keyType   The type of key.
33848
 * @param [in]     key       Key data.
33849
 * @param [in]     rng       Random number generator.
33850
 *
33851
 * @return  Size of signature on success.
33852
 * @return  < 0 on error
33853
 * */
33854
int wc_SignCert_ex(int requestSz, int sType, byte* buf, word32 buffSz,
33855
                   int keyType, void* key, WC_RNG* rng)
33856
{
33857
    RsaKey*            rsaKey = NULL;
33858
    ecc_key*           eccKey = NULL;
33859
    ed25519_key*       ed25519Key = NULL;
33860
    ed448_key*         ed448Key = NULL;
33861
    falcon_key*        falconKey = NULL;
33862
    dilithium_key*     dilithiumKey = NULL;
33863
    sphincs_key*       sphincsKey = NULL;
33864
33865
    if (keyType == RSA_TYPE)
33866
        rsaKey = (RsaKey*)key;
33867
    else if (keyType == ECC_TYPE)
33868
        eccKey = (ecc_key*)key;
33869
    else if (keyType == ED25519_TYPE)
33870
        ed25519Key = (ed25519_key*)key;
33871
    else if (keyType == ED448_TYPE)
33872
        ed448Key = (ed448_key*)key;
33873
    else if (keyType == FALCON_LEVEL1_TYPE)
33874
        falconKey = (falcon_key*)key;
33875
    else if (keyType == FALCON_LEVEL5_TYPE)
33876
        falconKey = (falcon_key*)key;
33877
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
33878
    else if (keyType == DILITHIUM_LEVEL2_TYPE)
33879
        dilithiumKey = (dilithium_key*)key;
33880
    else if (keyType == DILITHIUM_LEVEL3_TYPE)
33881
        dilithiumKey = (dilithium_key*)key;
33882
    else if (keyType == DILITHIUM_LEVEL5_TYPE)
33883
        dilithiumKey = (dilithium_key*)key;
33884
#endif
33885
    else if (keyType == ML_DSA_LEVEL2_TYPE)
33886
        dilithiumKey = (dilithium_key*)key;
33887
    else if (keyType == ML_DSA_LEVEL3_TYPE)
33888
        dilithiumKey = (dilithium_key*)key;
33889
    else if (keyType == ML_DSA_LEVEL5_TYPE)
33890
        dilithiumKey = (dilithium_key*)key;
33891
    else if (keyType == SPHINCS_FAST_LEVEL1_TYPE)
33892
        sphincsKey = (sphincs_key*)key;
33893
    else if (keyType == SPHINCS_FAST_LEVEL3_TYPE)
33894
        sphincsKey = (sphincs_key*)key;
33895
    else if (keyType == SPHINCS_FAST_LEVEL5_TYPE)
33896
        sphincsKey = (sphincs_key*)key;
33897
    else if (keyType == SPHINCS_SMALL_LEVEL1_TYPE)
33898
        sphincsKey = (sphincs_key*)key;
33899
    else if (keyType == SPHINCS_SMALL_LEVEL3_TYPE)
33900
        sphincsKey = (sphincs_key*)key;
33901
    else if (keyType == SPHINCS_SMALL_LEVEL5_TYPE)
33902
        sphincsKey = (sphincs_key*)key;
33903
33904
    return SignCert(requestSz, sType, buf, buffSz, rsaKey, eccKey, ed25519Key,
33905
                    ed448Key, falconKey, dilithiumKey, sphincsKey, rng);
33906
}
33907
33908
int wc_SignCert(int requestSz, int sType, byte* buf, word32 buffSz,
33909
                RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng)
33910
{
33911
    return SignCert(requestSz, sType, buf, buffSz, rsaKey, eccKey, NULL, NULL,
33912
                    NULL, NULL, NULL, rng);
33913
}
33914
33915
33916
WOLFSSL_ABI
33917
int wc_MakeSelfCert(Cert* cert, byte* buf, word32 buffSz,
33918
                    RsaKey* key, WC_RNG* rng)
33919
{
33920
    int ret;
33921
33922
    ret = wc_MakeCert(cert, buf, buffSz, key, NULL, rng);
33923
    if (ret < 0)
33924
        return ret;
33925
33926
    return wc_SignCert(cert->bodySz, cert->sigType,
33927
                       buf, buffSz, key, NULL, rng);
33928
}
33929
33930
33931
#ifdef WOLFSSL_CERT_EXT
33932
33933
/* Get raw subject from cert, which may contain OIDs not parsed by Decode.
33934
   The raw subject pointer will only be valid while "cert" is valid. */
33935
WOLFSSL_ABI
33936
int wc_GetSubjectRaw(byte **subjectRaw, Cert *cert)
33937
{
33938
    int rc = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
33939
    if ((subjectRaw != NULL) && (cert != NULL)) {
33940
        *subjectRaw = cert->sbjRaw;
33941
        rc = 0;
33942
    }
33943
    return rc;
33944
}
33945
33946
/* Set KID from public key */
33947
static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey,
33948
                                 ed25519_key* ed25519Key, ed448_key* ed448Key,
33949
                                 falcon_key* falconKey,
33950
                                 dilithium_key* dilithiumKey,
33951
                                 sphincs_key *sphincsKey, int kid_type)
33952
{
33953
    byte *buf;
33954
    int   bufferSz, ret;
33955
33956
    if (cert == NULL ||
33957
        (rsakey == NULL && eckey == NULL && ed25519Key == NULL &&
33958
         ed448Key == NULL && falconKey == NULL && dilithiumKey == NULL &&
33959
         sphincsKey == NULL) ||
33960
        (kid_type != SKID_TYPE && kid_type != AKID_TYPE))
33961
        return BAD_FUNC_ARG;
33962
33963
    buf = (byte *)XMALLOC(MAX_PUBLIC_KEY_SZ, cert->heap,
33964
                                                       DYNAMIC_TYPE_TMP_BUFFER);
33965
    if (buf == NULL)
33966
        return MEMORY_E;
33967
33968
    /* Public Key */
33969
    bufferSz = -1;
33970
#ifndef NO_RSA
33971
    /* RSA public key */
33972
    if (rsakey != NULL)
33973
        bufferSz = SetRsaPublicKey(buf, rsakey, MAX_PUBLIC_KEY_SZ, 0);
33974
#endif
33975
#ifdef HAVE_ECC
33976
    /* ECC public key */
33977
    if (eckey != NULL)
33978
        bufferSz = SetEccPublicKey(buf, eckey, MAX_PUBLIC_KEY_SZ, 0, 0);
33979
#endif
33980
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
33981
    /* ED25519 public key */
33982
    if (ed25519Key != NULL) {
33983
        bufferSz = wc_Ed25519PublicKeyToDer(ed25519Key, buf, MAX_PUBLIC_KEY_SZ, 0);
33984
    }
33985
#endif
33986
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
33987
    /* ED448 public key */
33988
    if (ed448Key != NULL) {
33989
        bufferSz = wc_Ed448PublicKeyToDer(ed448Key, buf, MAX_PUBLIC_KEY_SZ, 0);
33990
    }
33991
#endif
33992
#if defined(HAVE_FALCON)
33993
    if (falconKey != NULL) {
33994
        bufferSz = wc_Falcon_PublicKeyToDer(falconKey, buf, MAX_PUBLIC_KEY_SZ,
33995
                                            0);
33996
    }
33997
#endif
33998
#if defined(HAVE_DILITHIUM) && !defined(WOLFSSL_DILITHIUM_NO_ASN1)
33999
    if (dilithiumKey != NULL) {
34000
        bufferSz = wc_Dilithium_PublicKeyToDer(dilithiumKey, buf,
34001
                                               MAX_PUBLIC_KEY_SZ, 0);
34002
    }
34003
#endif
34004
#if defined(HAVE_SPHINCS)
34005
    if (sphincsKey != NULL) {
34006
        bufferSz = wc_Sphincs_PublicKeyToDer(sphincsKey, buf,
34007
                                               MAX_PUBLIC_KEY_SZ, 0);
34008
    }
34009
#endif
34010
34011
    if (bufferSz <= 0) {
34012
        XFREE(buf, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
34013
        return PUBLIC_KEY_E;
34014
    }
34015
34016
    /* Compute SKID by hashing public key */
34017
    if (kid_type == SKID_TYPE) {
34018
        int hashId = HashIdAlg((word32)cert->sigType);
34019
        ret = CalcHashId_ex(buf, (word32)bufferSz, cert->skid, hashId);
34020
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
34021
        cert->skidSz = wc_HashGetDigestSize(wc_HashTypeConvert(hashId));
34022
    #else
34023
        cert->skidSz = KEYID_SIZE;
34024
    #endif
34025
    }
34026
    else if (kid_type == AKID_TYPE) {
34027
        int hashId = HashIdAlg((word32)cert->sigType);
34028
        ret = CalcHashId_ex(buf, (word32)bufferSz, cert->akid, hashId);
34029
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
34030
        cert->akidSz = wc_HashGetDigestSize(wc_HashTypeConvert(hashId));
34031
    #else
34032
        cert->akidSz = KEYID_SIZE;
34033
    #endif
34034
    }
34035
    else
34036
        ret = BAD_FUNC_ARG;
34037
34038
    XFREE(buf, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
34039
    return ret;
34040
}
34041
34042
int wc_SetSubjectKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key)
34043
{
34044
    RsaKey*            rsaKey = NULL;
34045
    ecc_key*           eccKey = NULL;
34046
    ed25519_key*       ed25519Key = NULL;
34047
    ed448_key*         ed448Key = NULL;
34048
    falcon_key*        falconKey = NULL;
34049
    dilithium_key*     dilithiumKey = NULL;
34050
    sphincs_key*       sphincsKey = NULL;
34051
34052
    if (keyType == RSA_TYPE)
34053
        rsaKey = (RsaKey*)key;
34054
    else if (keyType == ECC_TYPE)
34055
        eccKey = (ecc_key*)key;
34056
    else if (keyType == ED25519_TYPE)
34057
        ed25519Key = (ed25519_key*)key;
34058
    else if (keyType == ED448_TYPE)
34059
        ed448Key = (ed448_key*)key;
34060
    else if (keyType == FALCON_LEVEL1_TYPE)
34061
        falconKey = (falcon_key*)key;
34062
    else if (keyType == FALCON_LEVEL5_TYPE)
34063
        falconKey = (falcon_key*)key;
34064
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
34065
    else if (keyType == DILITHIUM_LEVEL2_TYPE)
34066
        dilithiumKey = (dilithium_key*)key;
34067
    else if (keyType == DILITHIUM_LEVEL3_TYPE)
34068
        dilithiumKey = (dilithium_key*)key;
34069
    else if (keyType == DILITHIUM_LEVEL5_TYPE)
34070
        dilithiumKey = (dilithium_key*)key;
34071
#endif
34072
    else if (keyType == ML_DSA_LEVEL2_TYPE)
34073
        dilithiumKey = (dilithium_key*)key;
34074
    else if (keyType == ML_DSA_LEVEL3_TYPE)
34075
        dilithiumKey = (dilithium_key*)key;
34076
    else if (keyType == ML_DSA_LEVEL5_TYPE)
34077
        dilithiumKey = (dilithium_key*)key;
34078
    else if (keyType == SPHINCS_FAST_LEVEL1_TYPE)
34079
        sphincsKey = (sphincs_key*)key;
34080
    else if (keyType == SPHINCS_FAST_LEVEL3_TYPE)
34081
        sphincsKey = (sphincs_key*)key;
34082
    else if (keyType == SPHINCS_FAST_LEVEL5_TYPE)
34083
        sphincsKey = (sphincs_key*)key;
34084
    else if (keyType == SPHINCS_SMALL_LEVEL1_TYPE)
34085
        sphincsKey = (sphincs_key*)key;
34086
    else if (keyType == SPHINCS_SMALL_LEVEL3_TYPE)
34087
        sphincsKey = (sphincs_key*)key;
34088
    else if (keyType == SPHINCS_SMALL_LEVEL5_TYPE)
34089
        sphincsKey = (sphincs_key*)key;
34090
34091
    return SetKeyIdFromPublicKey(cert, rsaKey, eccKey, ed25519Key, ed448Key,
34092
                                 falconKey, dilithiumKey, sphincsKey,
34093
                                 SKID_TYPE);
34094
}
34095
34096
/* Set SKID from RSA or ECC public key */
34097
int wc_SetSubjectKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey)
34098
{
34099
    return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, NULL, NULL, NULL,
34100
                                 NULL, SKID_TYPE);
34101
}
34102
34103
int wc_SetAuthKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key)
34104
{
34105
    RsaKey*            rsaKey = NULL;
34106
    ecc_key*           eccKey = NULL;
34107
    ed25519_key*       ed25519Key = NULL;
34108
    ed448_key*         ed448Key = NULL;
34109
    falcon_key*        falconKey = NULL;
34110
    dilithium_key*     dilithiumKey = NULL;
34111
    sphincs_key*       sphincsKey = NULL;
34112
34113
    if (keyType == RSA_TYPE)
34114
        rsaKey = (RsaKey*)key;
34115
    else if (keyType == ECC_TYPE)
34116
        eccKey = (ecc_key*)key;
34117
    else if (keyType == ED25519_TYPE)
34118
        ed25519Key = (ed25519_key*)key;
34119
    else if (keyType == ED448_TYPE)
34120
        ed448Key = (ed448_key*)key;
34121
    else if (keyType == FALCON_LEVEL1_TYPE)
34122
        falconKey = (falcon_key*)key;
34123
    else if (keyType == FALCON_LEVEL5_TYPE)
34124
        falconKey = (falcon_key*)key;
34125
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
34126
    else if (keyType == DILITHIUM_LEVEL2_TYPE)
34127
        dilithiumKey = (dilithium_key*)key;
34128
    else if (keyType == DILITHIUM_LEVEL3_TYPE)
34129
        dilithiumKey = (dilithium_key*)key;
34130
    else if (keyType == DILITHIUM_LEVEL5_TYPE)
34131
        dilithiumKey = (dilithium_key*)key;
34132
#endif
34133
    else if (keyType == ML_DSA_LEVEL2_TYPE)
34134
        dilithiumKey = (dilithium_key*)key;
34135
    else if (keyType == ML_DSA_LEVEL3_TYPE)
34136
        dilithiumKey = (dilithium_key*)key;
34137
    else if (keyType == ML_DSA_LEVEL5_TYPE)
34138
        dilithiumKey = (dilithium_key*)key;
34139
    else if (keyType == SPHINCS_FAST_LEVEL1_TYPE)
34140
        sphincsKey = (sphincs_key*)key;
34141
    else if (keyType == SPHINCS_FAST_LEVEL3_TYPE)
34142
        sphincsKey = (sphincs_key*)key;
34143
    else if (keyType == SPHINCS_FAST_LEVEL5_TYPE)
34144
        sphincsKey = (sphincs_key*)key;
34145
    else if (keyType == SPHINCS_SMALL_LEVEL1_TYPE)
34146
        sphincsKey = (sphincs_key*)key;
34147
    else if (keyType == SPHINCS_SMALL_LEVEL3_TYPE)
34148
        sphincsKey = (sphincs_key*)key;
34149
    else if (keyType == SPHINCS_SMALL_LEVEL5_TYPE)
34150
        sphincsKey = (sphincs_key*)key;
34151
34152
    return SetKeyIdFromPublicKey(cert, rsaKey, eccKey, ed25519Key, ed448Key,
34153
                                 falconKey, dilithiumKey, sphincsKey,
34154
                                 AKID_TYPE);
34155
}
34156
34157
/* Set SKID from RSA or ECC public key */
34158
int wc_SetAuthKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey)
34159
{
34160
    return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, NULL, NULL, NULL,
34161
                                 NULL, AKID_TYPE);
34162
}
34163
34164
34165
#if !defined(NO_FILESYSTEM) && !defined(NO_ASN_CRYPT)
34166
34167
/* Set SKID from public key file in PEM */
34168
int wc_SetSubjectKeyId(Cert *cert, const char* file)
34169
{
34170
    int     ret, derSz;
34171
    byte*   der;
34172
    word32  idx;
34173
    RsaKey  *rsakey = NULL;
34174
    ecc_key *eckey = NULL;
34175
34176
    if (cert == NULL || file == NULL)
34177
        return BAD_FUNC_ARG;
34178
34179
    der = (byte*)XMALLOC(MAX_PUBLIC_KEY_SZ, cert->heap, DYNAMIC_TYPE_CERT);
34180
    if (der == NULL) {
34181
        WOLFSSL_MSG("wc_SetSubjectKeyId memory Problem");
34182
        return MEMORY_E;
34183
    }
34184
    derSz = MAX_PUBLIC_KEY_SZ;
34185
34186
    XMEMSET(der, 0, (size_t)derSz);
34187
    derSz = wc_PemPubKeyToDer(file, der, derSz);
34188
    if (derSz <= 0) {
34189
        XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
34190
        return derSz;
34191
    }
34192
34193
    /* Load PubKey in internal structure */
34194
#ifndef NO_RSA
34195
    rsakey = (RsaKey*) XMALLOC(sizeof(RsaKey), cert->heap, DYNAMIC_TYPE_RSA);
34196
    if (rsakey == NULL) {
34197
        XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
34198
        return MEMORY_E;
34199
    }
34200
34201
    if (wc_InitRsaKey(rsakey, cert->heap) != 0) {
34202
        WOLFSSL_MSG("wc_InitRsaKey failure");
34203
        XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);
34204
        XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
34205
        return MEMORY_E;
34206
    }
34207
34208
    idx = 0;
34209
    ret = wc_RsaPublicKeyDecode(der, &idx, rsakey, (word32)derSz);
34210
    if (ret != 0)
34211
#endif
34212
    {
34213
#ifndef NO_RSA
34214
        WOLFSSL_MSG("wc_RsaPublicKeyDecode failed");
34215
        wc_FreeRsaKey(rsakey);
34216
        XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);
34217
        rsakey = NULL;
34218
#endif
34219
#ifdef HAVE_ECC
34220
        /* Check to load ecc public key */
34221
        eckey = (ecc_key*) XMALLOC(sizeof(ecc_key), cert->heap,
34222
                                                              DYNAMIC_TYPE_ECC);
34223
        if (eckey == NULL) {
34224
            XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
34225
            return MEMORY_E;
34226
        }
34227
34228
        if (wc_ecc_init(eckey) != 0) {
34229
            WOLFSSL_MSG("wc_ecc_init failure");
34230
            wc_ecc_free(eckey);
34231
            XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);
34232
            XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
34233
            return MEMORY_E;
34234
        }
34235
34236
        idx = 0;
34237
        ret = wc_EccPublicKeyDecode(der, &idx, eckey, (word32)derSz);
34238
        if (ret != 0) {
34239
            WOLFSSL_MSG("wc_EccPublicKeyDecode failed");
34240
            XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
34241
            wc_ecc_free(eckey);
34242
            XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);
34243
            return PUBLIC_KEY_E;
34244
        }
34245
#else
34246
        XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
34247
        return PUBLIC_KEY_E;
34248
#endif /* HAVE_ECC */
34249
    }
34250
34251
    XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
34252
34253
    ret = wc_SetSubjectKeyIdFromPublicKey(cert, rsakey, eckey);
34254
34255
#ifndef NO_RSA
34256
    wc_FreeRsaKey(rsakey);
34257
    XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);
34258
#endif
34259
#ifdef HAVE_ECC
34260
    wc_ecc_free(eckey);
34261
    XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);
34262
#endif
34263
#if defined(NO_RSA) && !defined(HAVE_ECC)
34264
    (void)idx;
34265
#endif
34266
    return ret;
34267
}
34268
34269
#endif /* !NO_FILESYSTEM && !NO_ASN_CRYPT */
34270
34271
static int SetAuthKeyIdFromDcert(Cert* cert, DecodedCert* decoded)
34272
{
34273
    int ret = 0;
34274
34275
    /* Subject Key Id not found !! */
34276
    if (decoded->extSubjKeyIdSet == 0) {
34277
        ret = ASN_NO_SKID;
34278
    }
34279
34280
    /* SKID invalid size */
34281
    else if (sizeof(cert->akid) < sizeof(decoded->extSubjKeyId)) {
34282
        ret = MEMORY_E;
34283
    }
34284
34285
    else {
34286
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
34287
        cert->akidSz = wc_HashGetDigestSize(wc_HashTypeConvert(HashIdAlg(
34288
            cert->sigType)));
34289
    #else
34290
        cert->akidSz = KEYID_SIZE;
34291
    #endif
34292
        /* Put the SKID of CA to AKID of certificate */
34293
        XMEMCPY(cert->akid, decoded->extSubjKeyId, (size_t)cert->akidSz);
34294
    }
34295
34296
    return ret;
34297
}
34298
34299
/* Set AKID from certificate contains in buffer (DER encoded) */
34300
int wc_SetAuthKeyIdFromCert(Cert *cert, const byte *der, int derSz)
34301
{
34302
    int ret = 0;
34303
34304
    if (cert == NULL) {
34305
        ret = BAD_FUNC_ARG;
34306
    }
34307
    else {
34308
        /* Check if decodedCert is cached */
34309
        if (cert->der != der) {
34310
            /* Allocate cache for the decoded cert */
34311
            ret = wc_SetCert_LoadDer(cert, der, (word32)derSz, INVALID_DEVID);
34312
        }
34313
34314
        if (ret >= 0) {
34315
            ret = SetAuthKeyIdFromDcert(cert, (DecodedCert*)cert->decodedCert);
34316
#ifndef WOLFSSL_CERT_GEN_CACHE
34317
            wc_SetCert_Free(cert);
34318
#endif
34319
        }
34320
    }
34321
34322
    return ret;
34323
}
34324
34325
34326
#ifndef NO_FILESYSTEM
34327
34328
/* Set AKID from certificate file in PEM */
34329
int wc_SetAuthKeyId(Cert *cert, const char* file)
34330
{
34331
    int         ret;
34332
    DerBuffer*  der = NULL;
34333
34334
    if (cert == NULL || file == NULL)
34335
        return BAD_FUNC_ARG;
34336
34337
    ret = wc_PemCertToDer_ex(file, &der);
34338
    if (ret == 0)
34339
    {
34340
        ret = wc_SetAuthKeyIdFromCert(cert, der->buffer, (int)der->length);
34341
        FreeDer(&der);
34342
    }
34343
34344
    return ret;
34345
}
34346
34347
#endif /* !NO_FILESYSTEM */
34348
34349
/* Set KeyUsage from human readable string */
34350
int wc_SetKeyUsage(Cert *cert, const char *value)
34351
{
34352
    int ret = 0;
34353
34354
    if (cert == NULL || value == NULL)
34355
        return BAD_FUNC_ARG;
34356
34357
    cert->keyUsage = 0;
34358
34359
    ret = ParseKeyUsageStr(value, &cert->keyUsage, cert->heap);
34360
34361
    return ret;
34362
}
34363
34364
/* Set ExtendedKeyUsage from human readable string */
34365
int wc_SetExtKeyUsage(Cert *cert, const char *value)
34366
{
34367
    int ret = 0;
34368
34369
    if (cert == NULL || value == NULL)
34370
        return BAD_FUNC_ARG;
34371
34372
    cert->extKeyUsage = 0;
34373
34374
    ret = ParseExtKeyUsageStr(value, &cert->extKeyUsage, cert->heap);
34375
34376
    return ret;
34377
}
34378
34379
#ifdef WOLFSSL_EKU_OID
34380
/*
34381
 * cert structure to set EKU oid in
34382
 * oid  the oid in byte representation
34383
 * sz   size of oid buffer
34384
 * idx  index of array to place oid
34385
 *
34386
 * returns 0 on success
34387
 */
34388
int wc_SetExtKeyUsageOID(Cert *cert, const char *in, word32 sz, byte idx,
34389
        void* heap)
34390
{
34391
    byte oid[CTC_MAX_EKU_OID_SZ];
34392
    word32 oidSz = CTC_MAX_EKU_OID_SZ;
34393
34394
    XMEMSET(oid, 0, sizeof(oid));
34395
34396
    if (idx >= CTC_MAX_EKU_NB || sz >= CTC_MAX_EKU_OID_SZ) {
34397
        WOLFSSL_MSG("Either idx or sz was too large");
34398
        return BAD_FUNC_ARG;
34399
    }
34400
34401
    if (EncodePolicyOID(oid, &oidSz, in, heap) != 0) {
34402
        return BUFFER_E;
34403
    }
34404
34405
    XMEMCPY(cert->extKeyUsageOID[idx], oid, oidSz);
34406
    cert->extKeyUsageOIDSz[idx] = (byte)oidSz;
34407
    cert->extKeyUsage |= EXTKEYUSE_USER;
34408
34409
    return 0;
34410
}
34411
#endif /* WOLFSSL_EKU_OID */
34412
34413
#if defined(WOLFSSL_ASN_TEMPLATE) && defined(WOLFSSL_CERT_GEN) && \
34414
    defined(WOLFSSL_CUSTOM_OID) && defined(HAVE_OID_ENCODING) && \
34415
    defined(WOLFSSL_CERT_EXT)
34416
int wc_SetCustomExtension(Cert *cert, int critical, const char *oid,
34417
                          const byte *der, word32 derSz) {
34418
    CertExtension *ext;
34419
    byte encodedOid[MAX_OID_SZ];
34420
    word32 encodedOidSz = MAX_OID_SZ;
34421
    int ret;
34422
34423
    XMEMSET(encodedOid, 0, sizeof(encodedOid));
34424
34425
    if (cert == NULL || oid == NULL || der == NULL || derSz == 0) {
34426
        return BAD_FUNC_ARG;
34427
    }
34428
34429
    if (cert->customCertExtCount >= NUM_CUSTOM_EXT) {
34430
        return MEMORY_E;
34431
    }
34432
34433
    /* Make sure we can properly parse the OID. */
34434
    ret = EncodePolicyOID(encodedOid, &encodedOidSz, oid, NULL);
34435
    if (ret != 0) {
34436
        return ret;
34437
    }
34438
34439
    ext = &cert->customCertExt[cert->customCertExtCount];
34440
34441
    ext->oid = (char*)oid;
34442
    ext->crit = (critical == 0) ? 0 : 1;
34443
    ext->val = (byte*)der;
34444
    ext->valSz = (int)derSz;
34445
34446
    cert->customCertExtCount++;
34447
    return 0;
34448
}
34449
#endif
34450
34451
#endif /* WOLFSSL_CERT_EXT */
34452
34453
34454
#ifdef WOLFSSL_ALT_NAMES
34455
34456
static int SetAltNamesFromDcert(Cert* cert, DecodedCert* decoded)
34457
{
34458
    int ret = 0;
34459
34460
    cert->altNamesSz = 0;
34461
    if (decoded->altNames) {
34462
        ret = FlattenAltNames(cert->altNames,
34463
            sizeof(cert->altNames), decoded->altNames);
34464
        if (ret >= 0) {
34465
            cert->altNamesSz = ret;
34466
            ret = 0;
34467
        }
34468
    }
34469
34470
    return ret;
34471
}
34472
34473
#ifndef NO_FILESYSTEM
34474
34475
/* Set Alt Names from der cert, return 0 on success */
34476
static int SetAltNamesFromCert(Cert* cert, const byte* der, int derSz,
34477
    int devId)
34478
{
34479
    int ret;
34480
#ifdef WOLFSSL_SMALL_STACK
34481
    DecodedCert* decoded;
34482
#else
34483
    DecodedCert decoded[1];
34484
#endif
34485
34486
    if (derSz < 0)
34487
        return derSz;
34488
34489
#ifdef WOLFSSL_SMALL_STACK
34490
    decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cert->heap,
34491
                                                       DYNAMIC_TYPE_TMP_BUFFER);
34492
    if (decoded == NULL)
34493
        return MEMORY_E;
34494
#endif
34495
34496
    InitDecodedCert_ex(decoded, der, (word32)derSz, NULL, devId);
34497
    ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0, NULL);
34498
34499
    if (ret < 0) {
34500
        WOLFSSL_MSG("ParseCertRelative error");
34501
    }
34502
    else {
34503
        ret = SetAltNamesFromDcert(cert, decoded);
34504
    }
34505
34506
    FreeDecodedCert(decoded);
34507
#ifdef WOLFSSL_SMALL_STACK
34508
    XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
34509
#endif
34510
34511
    return ret < 0 ? ret : 0;
34512
}
34513
34514
#endif
34515
34516
static int SetDatesFromDcert(Cert* cert, DecodedCert* decoded)
34517
{
34518
    int ret = 0;
34519
34520
    if (decoded->beforeDate == NULL || decoded->afterDate == NULL) {
34521
        WOLFSSL_MSG("Couldn't extract dates");
34522
        ret = -1;
34523
    }
34524
    else if (decoded->beforeDateLen > MAX_DATE_SIZE ||
34525
                                        decoded->afterDateLen > MAX_DATE_SIZE) {
34526
        WOLFSSL_MSG("Bad date size");
34527
        ret = -1;
34528
    }
34529
    else {
34530
        XMEMCPY(cert->beforeDate, decoded->beforeDate,
34531
                (size_t)decoded->beforeDateLen);
34532
        XMEMCPY(cert->afterDate,  decoded->afterDate,
34533
                (size_t)decoded->afterDateLen);
34534
34535
        cert->beforeDateSz = decoded->beforeDateLen;
34536
        cert->afterDateSz  = decoded->afterDateLen;
34537
    }
34538
34539
    return ret;
34540
}
34541
34542
#endif /* WOLFSSL_ALT_NAMES */
34543
34544
static void SetNameFromDcert(CertName* cn, DecodedCert* decoded)
34545
{
34546
    int sz;
34547
34548
    if (decoded->subjectCN) {
34549
        sz = (decoded->subjectCNLen < CTC_NAME_SIZE) ? decoded->subjectCNLen
34550
                                                     : CTC_NAME_SIZE - 1;
34551
        XSTRNCPY(cn->commonName, decoded->subjectCN, (size_t)sz);
34552
        cn->commonName[sz] = '\0';
34553
        cn->commonNameEnc = decoded->subjectCNEnc;
34554
    }
34555
    if (decoded->subjectC) {
34556
        sz = (decoded->subjectCLen < CTC_NAME_SIZE) ? decoded->subjectCLen
34557
                                                    : CTC_NAME_SIZE - 1;
34558
        XSTRNCPY(cn->country, decoded->subjectC, (size_t)sz);
34559
        cn->country[sz] = '\0';
34560
        cn->countryEnc = decoded->subjectCEnc;
34561
    }
34562
    if (decoded->subjectST) {
34563
        sz = (decoded->subjectSTLen < CTC_NAME_SIZE) ? decoded->subjectSTLen
34564
                                                     : CTC_NAME_SIZE - 1;
34565
        XSTRNCPY(cn->state, decoded->subjectST, (size_t)sz);
34566
        cn->state[sz] = '\0';
34567
        cn->stateEnc = decoded->subjectSTEnc;
34568
    }
34569
    if (decoded->subjectL) {
34570
        sz = (decoded->subjectLLen < CTC_NAME_SIZE) ? decoded->subjectLLen
34571
                                                    : CTC_NAME_SIZE - 1;
34572
        XSTRNCPY(cn->locality, decoded->subjectL, (size_t)sz);
34573
        cn->locality[sz] = '\0';
34574
        cn->localityEnc = decoded->subjectLEnc;
34575
    }
34576
    if (decoded->subjectO) {
34577
        sz = (decoded->subjectOLen < CTC_NAME_SIZE) ? decoded->subjectOLen
34578
                                                    : CTC_NAME_SIZE - 1;
34579
        XSTRNCPY(cn->org, decoded->subjectO, (size_t)sz);
34580
        cn->org[sz] = '\0';
34581
        cn->orgEnc = decoded->subjectOEnc;
34582
    }
34583
    if (decoded->subjectOU) {
34584
        sz = (decoded->subjectOULen < CTC_NAME_SIZE) ? decoded->subjectOULen
34585
                                                     : CTC_NAME_SIZE - 1;
34586
        XSTRNCPY(cn->unit, decoded->subjectOU, (size_t)sz);
34587
        cn->unit[sz] = '\0';
34588
        cn->unitEnc = decoded->subjectOUEnc;
34589
    }
34590
    if (decoded->subjectSN) {
34591
        sz = (decoded->subjectSNLen < CTC_NAME_SIZE) ? decoded->subjectSNLen
34592
                                                     : CTC_NAME_SIZE - 1;
34593
        XSTRNCPY(cn->sur, decoded->subjectSN, (size_t)sz);
34594
        cn->sur[sz] = '\0';
34595
        cn->surEnc = decoded->subjectSNEnc;
34596
    }
34597
    if (decoded->subjectSND) {
34598
        sz = (decoded->subjectSNDLen < CTC_NAME_SIZE) ? decoded->subjectSNDLen
34599
                                                     : CTC_NAME_SIZE - 1;
34600
        XSTRNCPY(cn->serialDev, decoded->subjectSND, (size_t)sz);
34601
        cn->serialDev[sz] = '\0';
34602
        cn->serialDevEnc = decoded->subjectSNDEnc;
34603
    }
34604
    if (decoded->subjectUID) {
34605
        sz = (decoded->subjectUIDLen < CTC_NAME_SIZE) ? decoded->subjectUIDLen
34606
                                                     : CTC_NAME_SIZE - 1;
34607
        XSTRNCPY(cn->userId, decoded->subjectUID, (size_t)sz);
34608
        cn->userId[sz] = '\0';
34609
        cn->userIdEnc = decoded->subjectUIDEnc;
34610
    }
34611
#ifdef WOLFSSL_CERT_EXT
34612
    if (decoded->subjectBC) {
34613
        sz = (decoded->subjectBCLen < CTC_NAME_SIZE) ? decoded->subjectBCLen
34614
                                                     : CTC_NAME_SIZE - 1;
34615
        XSTRNCPY(cn->busCat, decoded->subjectBC, (size_t)sz);
34616
        cn->busCat[sz] = '\0';
34617
        cn->busCatEnc = decoded->subjectBCEnc;
34618
    }
34619
    if (decoded->subjectJC) {
34620
        sz = (decoded->subjectJCLen < CTC_NAME_SIZE) ? decoded->subjectJCLen
34621
                                                     : CTC_NAME_SIZE - 1;
34622
        XSTRNCPY(cn->joiC, decoded->subjectJC, (size_t)sz);
34623
        cn->joiC[sz] = '\0';
34624
        cn->joiCEnc = decoded->subjectJCEnc;
34625
    }
34626
    if (decoded->subjectJS) {
34627
        sz = (decoded->subjectJSLen < CTC_NAME_SIZE) ? decoded->subjectJSLen
34628
                                                     : CTC_NAME_SIZE - 1;
34629
        XSTRNCPY(cn->joiSt, decoded->subjectJS, (size_t)sz);
34630
        cn->joiSt[sz] = '\0';
34631
        cn->joiStEnc = decoded->subjectJSEnc;
34632
    }
34633
#endif
34634
    if (decoded->subjectEmail) {
34635
        sz = (decoded->subjectEmailLen < CTC_NAME_SIZE)
34636
           ?  decoded->subjectEmailLen : CTC_NAME_SIZE - 1;
34637
        XSTRNCPY(cn->email, decoded->subjectEmail, (size_t)sz);
34638
        cn->email[sz] = '\0';
34639
    }
34640
#if defined(WOLFSSL_CERT_NAME_ALL) && \
34641
    (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT))
34642
    if (decoded->subjectN) {
34643
        sz = (decoded->subjectNLen < CTC_NAME_SIZE) ? decoded->subjectNLen
34644
                                                     : CTC_NAME_SIZE - 1;
34645
        XSTRNCPY(cn->dnName, decoded->subjectN, (size_t)sz);
34646
        cn->dnName[sz] = '\0';
34647
        cn->dnNameEnc = decoded->subjectNEnc;
34648
    }
34649
    if (decoded->subjectI) {
34650
        sz = (decoded->subjectILen < CTC_NAME_SIZE) ? decoded->subjectILen
34651
                                                     : CTC_NAME_SIZE - 1;
34652
        XSTRNCPY(cn->initials, decoded->subjectI, (size_t)sz);
34653
        cn->initials[sz] = '\0';
34654
        cn->initialsEnc = decoded->subjectIEnc;
34655
    }
34656
    if (decoded->subjectGN) {
34657
        sz = (decoded->subjectGNLen < CTC_NAME_SIZE) ? decoded->subjectGNLen
34658
                                                     : CTC_NAME_SIZE - 1;
34659
        XSTRNCPY(cn->givenName, decoded->subjectGN, (size_t)sz);
34660
        cn->givenName[sz] = '\0';
34661
        cn->givenNameEnc = decoded->subjectGNEnc;
34662
    }
34663
    if (decoded->subjectDNQ) {
34664
        sz = (decoded->subjectDNQLen < CTC_NAME_SIZE) ? decoded->subjectDNQLen
34665
                                                     : CTC_NAME_SIZE - 1;
34666
        XSTRNCPY(cn->dnQualifier, decoded->subjectDNQ, (size_t)sz);
34667
        cn->dnQualifier[sz] = '\0';
34668
        cn->dnQualifierEnc = decoded->subjectDNQEnc;
34669
    }
34670
#endif /* WOLFSSL_CERT_NAME_ALL */
34671
}
34672
34673
#ifndef NO_FILESYSTEM
34674
34675
/* Set cn name from der buffer, return 0 on success */
34676
static int SetNameFromCert(CertName* cn, const byte* der, int derSz, int devId)
34677
{
34678
    int ret;
34679
#ifdef WOLFSSL_SMALL_STACK
34680
    DecodedCert* decoded;
34681
#else
34682
    DecodedCert decoded[1];
34683
#endif
34684
34685
    if (derSz < 0)
34686
        return derSz;
34687
34688
#ifdef WOLFSSL_SMALL_STACK
34689
    decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
34690
                                                       DYNAMIC_TYPE_TMP_BUFFER);
34691
    if (decoded == NULL)
34692
        return MEMORY_E;
34693
#endif
34694
34695
    InitDecodedCert_ex(decoded, der, (word32)derSz, NULL, devId);
34696
    ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0, NULL);
34697
34698
    if (ret < 0) {
34699
        WOLFSSL_MSG("ParseCertRelative error");
34700
    }
34701
    else {
34702
        SetNameFromDcert(cn, decoded);
34703
    }
34704
34705
    FreeDecodedCert(decoded);
34706
34707
#ifdef WOLFSSL_SMALL_STACK
34708
    XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
34709
#endif
34710
34711
    return ret < 0 ? ret : 0;
34712
}
34713
34714
/* Set cert issuer from issuerFile in PEM */
34715
WOLFSSL_ABI
34716
int wc_SetIssuer(Cert* cert, const char* issuerFile)
34717
{
34718
    int         ret;
34719
    DerBuffer*  der = NULL;
34720
34721
    if (cert == NULL || issuerFile == NULL)
34722
        return BAD_FUNC_ARG;
34723
34724
    ret = wc_PemCertToDer_ex(issuerFile, &der);
34725
    if (ret == 0) {
34726
        cert->selfSigned = 0;
34727
        ret = SetNameFromCert(&cert->issuer, der->buffer, (int)der->length,
34728
            INVALID_DEVID);
34729
34730
        FreeDer(&der);
34731
    }
34732
34733
    return ret;
34734
}
34735
34736
34737
/* Set cert subject from subjectFile in PEM */
34738
WOLFSSL_ABI
34739
int wc_SetSubject(Cert* cert, const char* subjectFile)
34740
{
34741
    int         ret;
34742
    DerBuffer*  der = NULL;
34743
34744
    if (cert == NULL || subjectFile == NULL)
34745
        return BAD_FUNC_ARG;
34746
34747
    ret = wc_PemCertToDer_ex(subjectFile, &der);
34748
    if (ret == 0) {
34749
        ret = SetNameFromCert(&cert->subject, der->buffer, (int)der->length,
34750
            INVALID_DEVID);
34751
34752
        FreeDer(&der);
34753
    }
34754
34755
    return ret;
34756
}
34757
34758
#ifdef WOLFSSL_ALT_NAMES
34759
34760
/* Set alt names from file in PEM */
34761
WOLFSSL_ABI
34762
int wc_SetAltNames(Cert* cert, const char* file)
34763
{
34764
    int         ret;
34765
    DerBuffer*  der = NULL;
34766
34767
    if (cert == NULL) {
34768
        return BAD_FUNC_ARG;
34769
    }
34770
34771
    ret = wc_PemCertToDer_ex(file, &der);
34772
    if (ret == 0) {
34773
        ret = SetAltNamesFromCert(cert, der->buffer, (int)der->length,
34774
            INVALID_DEVID);
34775
34776
        FreeDer(&der);
34777
    }
34778
34779
    return ret;
34780
}
34781
34782
#endif /* WOLFSSL_ALT_NAMES */
34783
34784
#endif /* !NO_FILESYSTEM */
34785
34786
/* Set cert issuer from DER buffer */
34787
WOLFSSL_ABI
34788
int wc_SetIssuerBuffer(Cert* cert, const byte* der, int derSz)
34789
{
34790
    int ret = 0;
34791
34792
    if (cert == NULL) {
34793
        ret = BAD_FUNC_ARG;
34794
    }
34795
    else {
34796
        cert->selfSigned = 0;
34797
34798
        /* Check if decodedCert is cached */
34799
        if (cert->der != der) {
34800
            /* Allocate cache for the decoded cert */
34801
            ret = wc_SetCert_LoadDer(cert, der, (word32)derSz, INVALID_DEVID);
34802
        }
34803
34804
        if (ret >= 0) {
34805
            SetNameFromDcert(&cert->issuer, (DecodedCert*)cert->decodedCert);
34806
#ifndef WOLFSSL_CERT_GEN_CACHE
34807
            wc_SetCert_Free(cert);
34808
#endif
34809
        }
34810
    }
34811
34812
    return ret;
34813
}
34814
34815
/* Set cert subject from DER buffer */
34816
WOLFSSL_ABI
34817
int wc_SetSubjectBuffer(Cert* cert, const byte* der, int derSz)
34818
{
34819
    int ret = 0;
34820
34821
    if (cert == NULL) {
34822
        ret = BAD_FUNC_ARG;
34823
    }
34824
    else {
34825
        /* Check if decodedCert is cached */
34826
        if (cert->der != der) {
34827
            /* Allocate cache for the decoded cert */
34828
            ret = wc_SetCert_LoadDer(cert, der, (word32)derSz, INVALID_DEVID);
34829
        }
34830
34831
        if (ret >= 0) {
34832
            SetNameFromDcert(&cert->subject, (DecodedCert*)cert->decodedCert);
34833
#ifndef WOLFSSL_CERT_GEN_CACHE
34834
            wc_SetCert_Free(cert);
34835
#endif
34836
        }
34837
    }
34838
34839
    return ret;
34840
}
34841
#ifdef WOLFSSL_CERT_EXT
34842
/* Set cert raw subject from DER buffer */
34843
WOLFSSL_ABI
34844
int wc_SetSubjectRaw(Cert* cert, const byte* der, int derSz)
34845
{
34846
    int ret = 0;
34847
34848
    if (cert == NULL) {
34849
        ret = BAD_FUNC_ARG;
34850
    }
34851
    else {
34852
        /* Check if decodedCert is cached */
34853
        if (cert->der != der) {
34854
            /* Allocate cache for the decoded cert */
34855
            ret = wc_SetCert_LoadDer(cert, der, (word32)derSz, INVALID_DEVID);
34856
        }
34857
34858
        if (ret >= 0) {
34859
            if ((((DecodedCert*)cert->decodedCert)->subjectRaw) &&
34860
                (((DecodedCert*)cert->decodedCert)->subjectRawLen <=
34861
                        (int)sizeof(CertName))) {
34862
                XMEMCPY(cert->sbjRaw,
34863
                        ((DecodedCert*)cert->decodedCert)->subjectRaw,
34864
                        (size_t)((DecodedCert*)cert->decodedCert)->
34865
                        subjectRawLen);
34866
            }
34867
#ifndef WOLFSSL_CERT_GEN_CACHE
34868
            wc_SetCert_Free(cert);
34869
#endif
34870
        }
34871
    }
34872
34873
    return ret;
34874
}
34875
34876
/* Set cert raw issuer from DER buffer */
34877
WOLFSSL_ABI
34878
int wc_SetIssuerRaw(Cert* cert, const byte* der, int derSz)
34879
{
34880
    int ret = 0;
34881
34882
    if (cert == NULL) {
34883
        ret = BAD_FUNC_ARG;
34884
    }
34885
    else {
34886
        /* Check if decodedCert is cached */
34887
        if (cert->der != der) {
34888
            /* Allocate cache for the decoded cert */
34889
            ret = wc_SetCert_LoadDer(cert, der, (word32)derSz, INVALID_DEVID);
34890
        }
34891
34892
        if (ret >= 0) {
34893
            if ((((DecodedCert*)cert->decodedCert)->subjectRaw) &&
34894
                (((DecodedCert*)cert->decodedCert)->subjectRawLen <=
34895
                        (int)sizeof(CertName))) {
34896
                /* Copy the subject to the issuer field */
34897
                XMEMCPY(cert->issRaw,
34898
                        ((DecodedCert*)cert->decodedCert)->subjectRaw,
34899
                        (size_t)((DecodedCert*)cert->decodedCert)->
34900
                        subjectRawLen);
34901
            }
34902
#ifndef WOLFSSL_CERT_GEN_CACHE
34903
            wc_SetCert_Free(cert);
34904
#endif
34905
        }
34906
    }
34907
    return ret;
34908
}
34909
#endif
34910
34911
#ifdef WOLFSSL_ALT_NAMES
34912
34913
/* Set cert alt names from DER buffer */
34914
WOLFSSL_ABI
34915
int wc_SetAltNamesBuffer(Cert* cert, const byte* der, int derSz)
34916
{
34917
    int ret = 0;
34918
34919
    if (cert == NULL) {
34920
       ret = BAD_FUNC_ARG;
34921
    }
34922
    else {
34923
        /* Check if decodedCert is cached */
34924
        if (cert->der != der) {
34925
            /* Allocate cache for the decoded cert */
34926
            ret = wc_SetCert_LoadDer(cert, der, (word32)derSz, INVALID_DEVID);
34927
        }
34928
34929
        if (ret >= 0) {
34930
            ret = SetAltNamesFromDcert(cert, (DecodedCert*)cert->decodedCert);
34931
#ifndef WOLFSSL_CERT_GEN_CACHE
34932
            wc_SetCert_Free(cert);
34933
#endif
34934
       }
34935
    }
34936
34937
    return(ret);
34938
}
34939
34940
/* Set cert dates from DER buffer */
34941
WOLFSSL_ABI
34942
int wc_SetDatesBuffer(Cert* cert, const byte* der, int derSz)
34943
{
34944
    int ret = 0;
34945
34946
    if (cert == NULL) {
34947
     ret = BAD_FUNC_ARG;
34948
    }
34949
    else {
34950
        /* Check if decodedCert is cached */
34951
        if (cert->der != der) {
34952
            /* Allocate cache for the decoded cert */
34953
            ret = wc_SetCert_LoadDer(cert, der, (word32)derSz, INVALID_DEVID);
34954
        }
34955
34956
        if (ret >= 0) {
34957
            ret = SetDatesFromDcert(cert, (DecodedCert*)cert->decodedCert);
34958
#ifndef WOLFSSL_CERT_GEN_CACHE
34959
            wc_SetCert_Free(cert);
34960
#endif
34961
        }
34962
    }
34963
34964
    return(ret);
34965
}
34966
34967
#endif /* WOLFSSL_ALT_NAMES */
34968
34969
#endif /* WOLFSSL_CERT_GEN */
34970
34971
#if (defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT)) \
34972
        || defined(OPENSSL_EXTRA)
34973
/* Encode OID string representation to ITU-T X.690 format */
34974
int EncodePolicyOID(byte *out, word32 *outSz, const char *in, void* heap)
34975
{
34976
    word32 idx = 0, nb_val;
34977
    char *token, *str, *ptr;
34978
    word32 len;
34979
34980
    (void)heap;
34981
34982
    if (out == NULL || outSz == NULL || *outSz < 2 || in == NULL)
34983
        return BAD_FUNC_ARG;
34984
34985
    /* duplicate string (including terminator) */
34986
    len = (word32)XSTRLEN(in);
34987
    str = (char *)XMALLOC(len+1, heap, DYNAMIC_TYPE_TMP_BUFFER);
34988
    if (str == NULL)
34989
        return MEMORY_E;
34990
    XMEMCPY(str, in, len+1);
34991
34992
    nb_val = 0;
34993
34994
    /* parse value, and set corresponding Policy OID value */
34995
    token = XSTRTOK(str, ".", &ptr);
34996
    while (token != NULL)
34997
    {
34998
        word32 val = (word32)XATOI(token);
34999
35000
        if (nb_val == 0) {
35001
            if (val > 2) {
35002
                XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
35003
                return ASN_OBJECT_ID_E;
35004
            }
35005
35006
            out[idx] = (byte)(40 * val);
35007
        }
35008
        else if (nb_val == 1) {
35009
            if (val > 127) {
35010
                XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
35011
                return ASN_OBJECT_ID_E;
35012
            }
35013
35014
            if (idx > *outSz) {
35015
                XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
35016
                return BUFFER_E;
35017
            }
35018
35019
            out[idx] = (byte)(out[idx] + val);
35020
            ++idx;
35021
        }
35022
        else {
35023
            word32  tb = 0;
35024
            int     i = 0;
35025
            byte    oid[MAX_OID_SZ];
35026
35027
            while (val >= 128) {
35028
                word32 x = val % 128;
35029
                val /= 128;
35030
                oid[i++] = (byte) (((tb++) ? 0x80 : 0) | x);
35031
            }
35032
35033
            if ((idx+(word32)i) >= *outSz) {
35034
                XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
35035
                return BUFFER_E;
35036
            }
35037
35038
            oid[i] = (byte) (((tb++) ? 0x80 : 0) | val);
35039
35040
            /* push value in the right order */
35041
            while (i >= 0)
35042
                out[idx++] = oid[i--];
35043
        }
35044
35045
        token = XSTRTOK(NULL, ".", &ptr);
35046
        nb_val++;
35047
    }
35048
35049
    *outSz = idx;
35050
35051
    XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
35052
    return 0;
35053
}
35054
#endif /* WOLFSSL_CERT_EXT || OPENSSL_EXTRA */
35055
35056
#endif /* !NO_CERTS */
35057
35058
#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL))
35059
/* Helper function for wolfSSL_i2d_DHparams */
35060
int StoreDHparams(byte* out, word32* outLen, mp_int* p, mp_int* g)
35061
{
35062
#ifndef WOLFSSL_ASN_TEMPLATE
35063
    word32 idx = 0;
35064
    word32 total;
35065
35066
    WOLFSSL_ENTER("StoreDHparams");
35067
35068
    if (out == NULL) {
35069
        WOLFSSL_MSG("Null buffer error");
35070
        return BUFFER_E;
35071
    }
35072
35073
    /* determine size */
35074
    /* integer - g */
35075
    idx = SetASNIntMP(g, -1, NULL);
35076
    /* integer - p */
35077
    idx += SetASNIntMP(p, -1, NULL);
35078
    total = idx;
35079
     /* sequence */
35080
    idx += SetSequence(idx, NULL);
35081
35082
    /* make sure output fits in buffer */
35083
    if (idx > *outLen) {
35084
        return BUFFER_E;
35085
    }
35086
35087
    /* write DH parameters */
35088
    /* sequence - for P and G only */
35089
    idx = SetSequence(total, out);
35090
    /* integer - p */
35091
    idx += SetASNIntMP(p, -1, out + idx);
35092
    /* integer - g */
35093
    idx += SetASNIntMP(g, -1, out + idx);
35094
    *outLen = idx;
35095
35096
    return 0;
35097
#else
35098
    ASNSetData dataASN[dhParamASN_Length];
35099
    int ret = 0;
35100
    int sz = 0;
35101
35102
    WOLFSSL_ENTER("StoreDHparams");
35103
    if (out == NULL) {
35104
        ret = BUFFER_E;
35105
    }
35106
    if (ret == 0) {
35107
        XMEMSET(dataASN, 0, sizeof(dataASN));
35108
        /* Set mp_int containing p and g. */
35109
        SetASN_MP(&dataASN[DHPARAMASN_IDX_PRIME], p);
35110
        SetASN_MP(&dataASN[DHPARAMASN_IDX_BASE], g);
35111
        /* privateValueLength not encoded. */
35112
        dataASN[DHPARAMASN_IDX_PRIVLEN].noOut = 1;
35113
35114
        /* Calculate the size of the DH parameters. */
35115
        ret = SizeASN_Items(dhParamASN, dataASN, dhParamASN_Length, &sz);
35116
    }
35117
    /* Check buffer is big enough for encoding. */
35118
    if ((ret == 0) && ((int)*outLen < sz)) {
35119
        ret = BUFFER_E;
35120
    }
35121
    if (ret == 0) {
35122
        /* Encode the DH parameters into buffer. */
35123
        SetASN_Items(dhParamASN, dataASN, dhParamASN_Length, out);
35124
        /* Set the actual encoding size. */
35125
        *outLen = (word32)sz;
35126
    }
35127
35128
    return ret;
35129
#endif /* WOLFSSL_ASN_TEMPLATE */
35130
}
35131
#endif /* !NO_DH && (WOLFSSL_QT || OPENSSL_ALL) */
35132
35133
#if defined(HAVE_ECC) || !defined(NO_DSA)
35134
35135
#ifdef WOLFSSL_ASN_TEMPLATE
35136
/* ASN.1 template for DSA signature.
35137
 * RFC 5912, 6 - DSA-Sig-Value
35138
 */
35139
static const ASNItem dsaSigASN[] = {
35140
/* SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 },
35141
                            /* r */
35142
/* R   */     { 1, ASN_INTEGER, 0, 0, 0 },
35143
                            /* s */
35144
/* S   */     { 1, ASN_INTEGER, 0, 0, 0 },
35145
};
35146
enum {
35147
    DSASIGASN_IDX_SEQ = 0,
35148
    DSASIGASN_IDX_R,
35149
    DSASIGASN_IDX_S
35150
};
35151
35152
0
#define dsaSigASN_Length (sizeof(dsaSigASN) / sizeof(ASNItem))
35153
#endif
35154
35155
/* Der Encode r & s ints into out, outLen is (in/out) size */
35156
int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s)
35157
0
{
35158
#ifndef WOLFSSL_ASN_TEMPLATE
35159
    word32 idx = 0;
35160
    int    rSz;                           /* encoding size */
35161
    int    sSz;
35162
    int    headerSz = 4;   /* 2*ASN_TAG + 2*LEN(ENUM) */
35163
35164
    /* If the leading bit on the INTEGER is a 1, add a leading zero */
35165
    int rLeadingZero = mp_leading_bit(r);
35166
    int sLeadingZero = mp_leading_bit(s);
35167
    int rLen = mp_unsigned_bin_size(r);   /* big int size */
35168
    int sLen = mp_unsigned_bin_size(s);
35169
35170
    if (*outLen < (word32)((rLen + rLeadingZero + sLen + sLeadingZero +
35171
            headerSz + 2)))  /* SEQ_TAG + LEN(ENUM) */
35172
        return BUFFER_E;
35173
35174
    idx = SetSequence((word32)(rLen + rLeadingZero + sLen + sLeadingZero +
35175
        headerSz), out);
35176
35177
    /* store r */
35178
    rSz = SetASNIntMP(r, (int)(*outLen - idx), &out[idx]);
35179
    if (rSz < 0)
35180
        return rSz;
35181
    idx += (word32)rSz;
35182
35183
    /* store s */
35184
    sSz = SetASNIntMP(s, (int)(*outLen - idx), &out[idx]);
35185
    if (sSz < 0)
35186
        return sSz;
35187
    idx += (word32)sSz;
35188
35189
    *outLen = idx;
35190
35191
    return 0;
35192
#else
35193
0
    ASNSetData dataASN[dsaSigASN_Length];
35194
0
    int ret;
35195
0
    int sz;
35196
35197
    /* Clear dynamic data and set mp_ints r and s */
35198
0
    XMEMSET(dataASN, 0, sizeof(dataASN));
35199
0
    SetASN_MP(&dataASN[DSASIGASN_IDX_R], r);
35200
0
    SetASN_MP(&dataASN[DSASIGASN_IDX_S], s);
35201
35202
    /* Calculate size of encoding. */
35203
0
    ret = SizeASN_Items(dsaSigASN, dataASN, dsaSigASN_Length, &sz);
35204
    /* Check buffer is big enough for encoding. */
35205
0
    if ((ret == 0) && ((int)*outLen < sz)) {
35206
0
       ret = BUFFER_E;
35207
0
    }
35208
0
    if (ret == 0) {
35209
        /* Encode DSA signature into buffer. */
35210
0
        ret = SetASN_Items(dsaSigASN, dataASN, dsaSigASN_Length, out);
35211
0
        if (ret >= 0) {
35212
0
            if (ret == sz) {
35213
                /* Set the actual encoding size. */
35214
0
                *outLen = (word32)sz;
35215
0
                ret = 0;
35216
0
            } else {
35217
0
                ret = BAD_STATE_E;
35218
0
            }
35219
0
        }
35220
0
    }
35221
35222
0
    return ret;
35223
0
#endif /* WOLFSSL_ASN_TEMPLATE */
35224
0
}
35225
35226
#ifndef WOLFSSL_ASN_TEMPLATE
35227
/* determine if leading bit is set */
35228
static word32 is_leading_bit_set(const byte* input, word32 sz)
35229
{
35230
    byte c = 0;
35231
    if (sz > 0)
35232
        c = input[0];
35233
    return (c & 0x80) != 0;
35234
}
35235
static word32 trim_leading_zeros(const byte** input, word32 sz)
35236
{
35237
    int i;
35238
    word32 leadingZeroCount = 0;
35239
    const byte* tmp = *input;
35240
    for (i=0; i<(int)sz; i++) {
35241
        if (tmp[i] != 0)
35242
            break;
35243
        leadingZeroCount++;
35244
    }
35245
    /* catch all zero case */
35246
    if (sz > 0 && leadingZeroCount == sz) {
35247
        leadingZeroCount--;
35248
    }
35249
    *input += leadingZeroCount;
35250
    sz -= leadingZeroCount;
35251
    return sz;
35252
}
35253
#endif
35254
35255
/* Der Encode r & s ints into out, outLen is (in/out) size */
35256
/* All input/outputs are assumed to be big-endian */
35257
int StoreECC_DSA_Sig_Bin(byte* out, word32* outLen, const byte* r, word32 rLen,
35258
    const byte* s, word32 sLen)
35259
0
{
35260
#ifndef WOLFSSL_ASN_TEMPLATE
35261
    int ret;
35262
    word32 idx;
35263
    word32 headerSz = 4;   /* 2*ASN_TAG + 2*LEN(ENUM) */
35264
    word32 rAddLeadZero, sAddLeadZero;
35265
35266
    if ((out == NULL) || (outLen == NULL) || (r == NULL) || (s == NULL))
35267
        return BAD_FUNC_ARG;
35268
35269
    /* Trim leading zeros */
35270
    rLen = trim_leading_zeros(&r, rLen);
35271
    sLen = trim_leading_zeros(&s, sLen);
35272
    /* If the leading bit on the INTEGER is a 1, add a leading zero */
35273
    /* Add leading zero if MSB is set */
35274
    rAddLeadZero = is_leading_bit_set(r, rLen);
35275
    sAddLeadZero = is_leading_bit_set(s, sLen);
35276
35277
    if (*outLen < (rLen + rAddLeadZero + sLen + sAddLeadZero +
35278
                   headerSz + 2))  /* SEQ_TAG + LEN(ENUM) */
35279
        return BUFFER_E;
35280
35281
    idx = SetSequence(rLen+rAddLeadZero + sLen+sAddLeadZero + headerSz, out);
35282
35283
    /* store r */
35284
    ret = SetASNInt((int)rLen, (byte)(rAddLeadZero ? 0x80U : 0x00U), &out[idx]);
35285
    if (ret < 0)
35286
        return ret;
35287
    idx += (word32)ret;
35288
    XMEMCPY(&out[idx], r, rLen);
35289
    idx += rLen;
35290
35291
    /* store s */
35292
    ret = SetASNInt((int)sLen, (byte)(sAddLeadZero ? 0x80U : 0x00U), &out[idx]);
35293
    if (ret < 0)
35294
        return ret;
35295
    idx += (word32)ret;
35296
    XMEMCPY(&out[idx], s, sLen);
35297
    idx += sLen;
35298
35299
    *outLen = idx;
35300
35301
    return 0;
35302
#else
35303
0
    ASNSetData dataASN[dsaSigASN_Length];
35304
0
    int ret;
35305
0
    int sz;
35306
35307
    /* Clear dynamic data and set buffers for r and s */
35308
0
    XMEMSET(dataASN, 0, sizeof(dataASN));
35309
0
    while ((rLen > 1) && (r[0] == 0)) {
35310
0
        rLen--;
35311
0
        r++;
35312
0
    }
35313
0
    while ((sLen > 1) && (s[0] == 0)) {
35314
0
        sLen--;
35315
0
        s++;
35316
0
    }
35317
0
    SetASN_Buffer(&dataASN[DSASIGASN_IDX_R], r, rLen);
35318
0
    SetASN_Buffer(&dataASN[DSASIGASN_IDX_S], s, sLen);
35319
35320
    /* Calculate size of encoding. */
35321
0
    ret = SizeASN_Items(dsaSigASN, dataASN, dsaSigASN_Length, &sz);
35322
    /* Check buffer is big enough for encoding. */
35323
0
    if ((ret == 0) && ((int)*outLen < sz)) {
35324
0
       ret = BUFFER_E;
35325
0
    }
35326
0
    if (ret == 0) {
35327
        /* Encode DSA signature into buffer. */
35328
0
        SetASN_Items(dsaSigASN, dataASN, dsaSigASN_Length, out);
35329
        /* Set the actual encoding size. */
35330
0
        *outLen = (word32)sz;
35331
0
    }
35332
35333
0
    return ret;
35334
0
#endif /* WOLFSSL_ASN_TEMPLATE */
35335
0
}
35336
35337
/* Der Decode ECC-DSA Signature with R/S as unsigned bin */
35338
/* All input/outputs are assumed to be big-endian */
35339
int DecodeECC_DSA_Sig_Bin(const byte* sig, word32 sigLen, byte* r, word32* rLen,
35340
    byte* s, word32* sLen)
35341
0
{
35342
#ifndef WOLFSSL_ASN_TEMPLATE
35343
    int    ret;
35344
    word32 idx = 0;
35345
    int    len = 0;
35346
35347
    if (GetSequence(sig, &idx, &len, sigLen) < 0) {
35348
        return ASN_ECC_KEY_E;
35349
    }
35350
35351
#ifndef NO_STRICT_ECDSA_LEN
35352
    /* enable strict length checking for signature */
35353
    if (sigLen != idx + (word32)len) {
35354
        return ASN_ECC_KEY_E;
35355
    }
35356
#else
35357
    /* allow extra signature bytes at end */
35358
    if ((word32)len > (sigLen - idx)) {
35359
        return ASN_ECC_KEY_E;
35360
    }
35361
#endif
35362
35363
    ret = GetASNInt(sig, &idx, &len, sigLen);
35364
    if (ret != 0)
35365
        return ret;
35366
    if (rLen) {
35367
        if (*rLen >= (word32)len)
35368
            *rLen = (word32)len;
35369
        else {
35370
            /* Buffer too small to hold r value */
35371
            return BUFFER_E;
35372
        }
35373
    }
35374
    if (r)
35375
        XMEMCPY(r, (byte*)sig + idx, (size_t)len);
35376
    idx += (word32)len;
35377
35378
    ret = GetASNInt(sig, &idx, &len, sigLen);
35379
    if (ret != 0)
35380
        return ret;
35381
    if (sLen) {
35382
        if (*sLen >= (word32)len)
35383
            *sLen = (word32)len;
35384
        else {
35385
            /* Buffer too small to hold s value */
35386
            return BUFFER_E;
35387
        }
35388
    }
35389
    if (s)
35390
        XMEMCPY(s, (byte*)sig + idx, (size_t)len);
35391
35392
#ifndef NO_STRICT_ECDSA_LEN
35393
    /* sanity check that the index has been advanced all the way to the end of
35394
     * the buffer */
35395
    if (idx + (word32)len != sigLen) {
35396
        ret = ASN_ECC_KEY_E;
35397
    }
35398
#endif
35399
35400
    return ret;
35401
#else
35402
0
    ASNGetData dataASN[dsaSigASN_Length];
35403
0
    word32 idx = 0;
35404
35405
    /* Clear dynamic data and set buffers to put r and s into. */
35406
0
    XMEMSET(dataASN, 0, sizeof(dataASN));
35407
0
    GetASN_Buffer(&dataASN[DSASIGASN_IDX_R], r, rLen);
35408
0
    GetASN_Buffer(&dataASN[DSASIGASN_IDX_S], s, sLen);
35409
35410
    /* Decode the DSA signature. */
35411
0
    return GetASN_Items(dsaSigASN, dataASN, dsaSigASN_Length, 1, sig, &idx,
35412
0
                        sigLen);
35413
0
#endif /* WOLFSSL_ASN_TEMPLATE */
35414
0
}
35415
35416
int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s)
35417
0
{
35418
0
    return DecodeECC_DSA_Sig_Ex(sig, sigLen, r, s, 1);
35419
0
}
35420
35421
int DecodeECC_DSA_Sig_Ex(const byte* sig, word32 sigLen, mp_int* r, mp_int* s,
35422
    int init)
35423
0
{
35424
#ifndef WOLFSSL_ASN_TEMPLATE
35425
    word32 idx = 0;
35426
    int    len = 0;
35427
35428
    if (GetSequence(sig, &idx, &len, sigLen) < 0) {
35429
        return ASN_ECC_KEY_E;
35430
    }
35431
35432
#ifndef NO_STRICT_ECDSA_LEN
35433
    /* enable strict length checking for signature */
35434
    if (sigLen != idx + (word32)len) {
35435
        return ASN_ECC_KEY_E;
35436
    }
35437
#else
35438
    /* allow extra signature bytes at end */
35439
    if ((word32)len > (sigLen - idx)) {
35440
        return ASN_ECC_KEY_E;
35441
    }
35442
#endif
35443
35444
    if (GetIntPositive(r, sig, &idx, sigLen, init) < 0) {
35445
        return ASN_ECC_KEY_E;
35446
    }
35447
35448
    if (GetIntPositive(s, sig, &idx, sigLen, init) < 0) {
35449
        mp_clear(r);
35450
        return ASN_ECC_KEY_E;
35451
    }
35452
35453
#ifndef NO_STRICT_ECDSA_LEN
35454
    /* sanity check that the index has been advanced all the way to the end of
35455
     * the buffer */
35456
    if (idx != sigLen) {
35457
        mp_clear(r);
35458
        mp_clear(s);
35459
        return ASN_ECC_KEY_E;
35460
    }
35461
#endif
35462
35463
    return 0;
35464
#else
35465
0
    ASNGetData dataASN[dsaSigASN_Length];
35466
0
    word32 idx = 0;
35467
0
    int ret;
35468
35469
    /* Clear dynamic data and set mp_ints to put r and s into. */
35470
0
    XMEMSET(dataASN, 0, sizeof(dataASN));
35471
0
    if (init) {
35472
0
        GetASN_MP(&dataASN[DSASIGASN_IDX_R], r);
35473
0
        GetASN_MP(&dataASN[DSASIGASN_IDX_S], s);
35474
0
    }
35475
0
    else {
35476
0
        GetASN_MP_Inited(&dataASN[DSASIGASN_IDX_R], r);
35477
0
        GetASN_MP_Inited(&dataASN[DSASIGASN_IDX_S], s);
35478
0
    }
35479
35480
    /* Decode the DSA signature. */
35481
0
    ret = GetASN_Items(dsaSigASN, dataASN, dsaSigASN_Length, 0, sig, &idx,
35482
0
                       sigLen);
35483
35484
0
    if (ret != 0) {
35485
0
        ret = ASN_ECC_KEY_E;
35486
0
    }
35487
35488
0
#ifndef NO_STRICT_ECDSA_LEN
35489
    /* sanity check that the index has been advanced all the way to the end of
35490
     * the buffer */
35491
0
    if ((ret == 0) && (idx != sigLen)) {
35492
0
        ret = ASN_ECC_KEY_E;
35493
0
    }
35494
0
#endif
35495
0
    if (ret != 0) {
35496
0
        mp_clear(r);
35497
0
        mp_clear(s);
35498
0
    }
35499
35500
0
    return ret;
35501
0
#endif /* WOLFSSL_ASN_TEMPLATE */
35502
0
}
35503
#endif
35504
35505
35506
#ifdef WOLFSSL_ASN_TEMPLATE
35507
#if defined(HAVE_ECC) && defined(WOLFSSL_CUSTOM_CURVES)
35508
/* Convert data to hex string.
35509
 *
35510
 * Big-endian byte array is converted to big-endian hexadecimal string.
35511
 *
35512
 * @param [in]  input  Buffer containing data.
35513
 * @param [in]  inSz   Size of data in buffer.
35514
 * @param [out] out    Buffer to hold hex string.
35515
 */
35516
static void DataToHexString(const byte* input, word32 inSz, char* out)
35517
{
35518
    static const char hexChar[] = { '0', '1', '2', '3', '4', '5', '6', '7',
35519
                                    '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
35520
    word32 i;
35521
35522
    /* Converting a byte of data at a time to two hex characters. */
35523
    for (i = 0; i < inSz; i++) {
35524
        out[i*2 + 0] = hexChar[input[i] >> 4];
35525
        out[i*2 + 1] = hexChar[input[i] & 0xf];
35526
    }
35527
    /* NUL terminate string. */
35528
    out[i * 2] = '\0';
35529
}
35530
35531
#ifndef WOLFSSL_ECC_CURVE_STATIC
35532
/* Convert data to hex string and place in allocated buffer.
35533
 *
35534
 * Big-endian byte array is converted to big-endian hexadecimal string.
35535
 *
35536
 * @param [in]  input     Buffer containing data.
35537
 * @param [in]  inSz      Size of data in buffer.
35538
 * @param [out] out       Allocated buffer holding hex string.
35539
 * @param [in]  heap      Dynamic memory allocation hint.
35540
 * @param [in]  heapType  Type of heap to use.
35541
 * @return  0 on success.
35542
 * @return  MEMORY_E when dynamic memory allocation fails.
35543
 */
35544
static int DataToHexStringAlloc(const byte* input, word32 inSz, char** out,
35545
                                void* heap, int heapType)
35546
{
35547
    int ret = 0;
35548
    char* str;
35549
35550
    /* Allocate for 2 string characters ber byte plus NUL. */
35551
    str = (char*)XMALLOC(inSz * 2 + 1, heap, heapType);
35552
    if (str == NULL) {
35553
        ret = MEMORY_E;
35554
    }
35555
    else {
35556
        /* Convert to hex string. */
35557
        DataToHexString(input, inSz, str);
35558
        *out = str;
35559
    }
35560
35561
    (void)heap;
35562
    (void)heapType;
35563
35564
    return ret;
35565
}
35566
#endif /* WOLFSSL_ECC_CURVE_STATIC */
35567
35568
/* ASN.1 template for SpecifiedECDomain.
35569
 * SEC 1 Ver. 2.0, C.2 - Syntax for Elliptic Curve Domain Parameters
35570
 * NOTE: characteristic-two-field not supported. */
35571
static const ASNItem eccSpecifiedASN[] = {
35572
            /* version */
35573
/* VER        */ { 0, ASN_INTEGER, 0, 0, 0 },
35574
                                     /* fieldID */
35575
/* PRIME_SEQ  */ { 0, ASN_SEQUENCE, 1, 1, 0 },
35576
                                         /* prime-field or characteristic-two-field */
35577
/* PRIME_OID  */     { 1, ASN_OBJECT_ID, 0, 0, 0 },
35578
                                         /* Prime-p */
35579
/* PRIME_P    */     { 1, ASN_INTEGER, 0, 0, 0 },
35580
                                     /* fieldID */
35581
/* PARAM_SEQ, */ { 0, ASN_SEQUENCE, 1, 1, 0 },
35582
                                         /* a */
35583
/* PARAM_A    */     { 1, ASN_OCTET_STRING, 0, 0, 0 },
35584
                                         /* b */
35585
/* PARAM_B    */     { 1, ASN_OCTET_STRING, 0, 0, 0 },
35586
                                         /* seed */
35587
/* PARAM_SEED */     { 1, ASN_BIT_STRING, 0, 0, 1 },
35588
                                     /* base */
35589
/* BASE       */ { 0, ASN_OCTET_STRING, 0, 0, 0 },
35590
                                     /* order */
35591
/* ORDER      */ { 0, ASN_INTEGER, 0, 0, 0 },
35592
                                     /* cofactor */
35593
/* COFACTOR   */ { 0, ASN_INTEGER, 0, 0, 1 },
35594
                                     /* hash */
35595
/* HASH_SEQ   */ { 0, ASN_SEQUENCE, 0, 0, 1 },
35596
};
35597
enum {
35598
    ECCSPECIFIEDASN_IDX_VER = 0,
35599
    ECCSPECIFIEDASN_IDX_PRIME_SEQ,
35600
    ECCSPECIFIEDASN_IDX_PRIME_OID,
35601
    ECCSPECIFIEDASN_IDX_PRIME_P,
35602
    ECCSPECIFIEDASN_IDX_PARAM_SEQ,
35603
    ECCSPECIFIEDASN_IDX_PARAM_A,
35604
    ECCSPECIFIEDASN_IDX_PARAM_B,
35605
    ECCSPECIFIEDASN_IDX_PARAM_SEED,
35606
    ECCSPECIFIEDASN_IDX_BASE,
35607
    ECCSPECIFIEDASN_IDX_ORDER,
35608
    ECCSPECIFIEDASN_IDX_COFACTOR,
35609
    ECCSPECIFIEDASN_IDX_HASH_SEQ
35610
};
35611
35612
/* Number of items in ASN.1 template for SpecifiedECDomain. */
35613
#define eccSpecifiedASN_Length (sizeof(eccSpecifiedASN) / sizeof(ASNItem))
35614
35615
/* OID indicating the prime field is explicitly defined. */
35616
static const byte primeFieldOID[] = {
35617
    0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01
35618
};
35619
static const char ecSetCustomName[] = "Custom";
35620
35621
/* Explicit EC parameter values. */
35622
static int EccSpecifiedECDomainDecode(const byte* input, word32 inSz,
35623
                                      ecc_key* key, void* heap, int* curveSz)
35624
{
35625
    DECL_ASNGETDATA(dataASN, eccSpecifiedASN_Length);
35626
    int ret = 0;
35627
    ecc_set_type* curve = NULL;
35628
    word32 idx = 0;
35629
    byte version = 0;
35630
    byte cofactor = 0;
35631
    const byte *base = NULL;
35632
    word32 baseLen = 0;
35633
35634
    /* Allocate a new parameter set. */
35635
    curve = (ecc_set_type*)XMALLOC(sizeof(*curve), heap,
35636
                DYNAMIC_TYPE_ECC_BUFFER);
35637
    if (curve == NULL) {
35638
        ret = MEMORY_E;
35639
    }
35640
    else {
35641
        /* Clear out parameters and set fields to indicate it is custom. */
35642
        XMEMSET(curve, 0, sizeof(*curve));
35643
    }
35644
35645
    CALLOC_ASNGETDATA(dataASN, eccSpecifiedASN_Length, ret, heap);
35646
35647
    if (ret == 0) {
35648
        /* Set name to be: "Custom" */
35649
    #ifndef WOLFSSL_ECC_CURVE_STATIC
35650
        curve->name = ecSetCustomName;
35651
    #else
35652
        XMEMCPY((void*)curve->name, ecSetCustomName, sizeof(ecSetCustomName));
35653
    #endif
35654
        curve->id = ECC_CURVE_CUSTOM;
35655
35656
        /* Get version, must have prime field OID and get co-factor. */
35657
        GetASN_Int8Bit(&dataASN[ECCSPECIFIEDASN_IDX_VER], &version);
35658
        GetASN_ExpBuffer(&dataASN[ECCSPECIFIEDASN_IDX_PRIME_OID],
35659
                primeFieldOID, sizeof(primeFieldOID));
35660
        GetASN_Int8Bit(&dataASN[ECCSPECIFIEDASN_IDX_COFACTOR], &cofactor);
35661
        /* Decode the explicit parameters. */
35662
        ret = GetASN_Items(eccSpecifiedASN, dataASN, eccSpecifiedASN_Length, 1,
35663
                           input, &idx, inSz);
35664
    }
35665
    /* Version must be 1 or 2 for supporting explicit parameters. */
35666
    if ((ret == 0) && (version < 1 || version > 3)) {
35667
        ret = ASN_PARSE_E;
35668
    }
35669
#ifndef WOLFSSL_NO_ASN_STRICT
35670
    /* Only version 2 and above can have a seed. */
35671
    if (ret == 0) {
35672
        if ((dataASN[ECCSPECIFIEDASN_IDX_PARAM_SEED].tag != 0) &&
35673
            (version < 2)) {
35674
            ret = ASN_PARSE_E;
35675
        }
35676
    }
35677
#endif
35678
    /* Only version 2 and above can have a hash algorithm. */
35679
    if (ret == 0) {
35680
        if ((dataASN[ECCSPECIFIEDASN_IDX_HASH_SEQ].tag != 0) &&
35681
            (version < 2)) {
35682
            ret = ASN_PARSE_E;
35683
        }
35684
    }
35685
    if ((ret == 0) && (dataASN[ECCSPECIFIEDASN_IDX_COFACTOR].tag != 0)) {
35686
        /* Store optional co-factor. */
35687
        curve->cofactor = cofactor;
35688
    }
35689
    if (ret == 0) {
35690
        /* Length of the prime in bytes is the curve size. */
35691
        curve->size =
35692
                (int)dataASN[ECCSPECIFIEDASN_IDX_PRIME_P].data.ref.length;
35693
        /* Base point: 0x04 <x> <y> (must be uncompressed). */
35694
        GetASN_GetConstRef(&dataASN[ECCSPECIFIEDASN_IDX_BASE], &base,
35695
                &baseLen);
35696
        if ((baseLen < (word32)curve->size * 2 + 1) || (base[0] != 0x4)) {
35697
            ret = ASN_PARSE_E;
35698
        }
35699
    }
35700
    /* Put the curve parameters into the set.
35701
     * Convert the big-endian number byte array to a big-endian string.
35702
     */
35703
    #ifndef WOLFSSL_ECC_CURVE_STATIC
35704
    /* Allocate buffer to put hex strings into. */
35705
    if (ret == 0) {
35706
        /* Base X-ordinate */
35707
        ret = DataToHexStringAlloc(base + 1, (word32)curve->size,
35708
                                   (char**)&curve->Gx, heap,
35709
                                   DYNAMIC_TYPE_ECC_BUFFER);
35710
    }
35711
    if (ret == 0) {
35712
        /* Base Y-ordinate */
35713
        ret = DataToHexStringAlloc(base + 1 + curve->size, (word32)curve->size,
35714
                                   (char**)&curve->Gy, heap,
35715
                                   DYNAMIC_TYPE_ECC_BUFFER);
35716
    }
35717
    if (ret == 0) {
35718
        /* Prime */
35719
        ret = DataToHexStringAlloc(
35720
                dataASN[ECCSPECIFIEDASN_IDX_PRIME_P].data.ref.data,
35721
                dataASN[ECCSPECIFIEDASN_IDX_PRIME_P].data.ref.length,
35722
                (char**)&curve->prime, heap, DYNAMIC_TYPE_ECC_BUFFER);
35723
    }
35724
    if (ret == 0) {
35725
        /* Parameter A */
35726
        ret = DataToHexStringAlloc(
35727
                dataASN[ECCSPECIFIEDASN_IDX_PARAM_A].data.ref.data,
35728
                dataASN[ECCSPECIFIEDASN_IDX_PARAM_A].data.ref.length,
35729
                (char**)&curve->Af, heap, DYNAMIC_TYPE_ECC_BUFFER);
35730
    }
35731
    if (ret == 0) {
35732
        /* Parameter B */
35733
        ret = DataToHexStringAlloc(
35734
                dataASN[ECCSPECIFIEDASN_IDX_PARAM_B].data.ref.data,
35735
                dataASN[ECCSPECIFIEDASN_IDX_PARAM_B].data.ref.length,
35736
                (char**)&curve->Bf, heap, DYNAMIC_TYPE_ECC_BUFFER);
35737
    }
35738
    if (ret == 0) {
35739
        /* Order of curve */
35740
        ret = DataToHexStringAlloc(
35741
                dataASN[ECCSPECIFIEDASN_IDX_ORDER].data.ref.data,
35742
                dataASN[ECCSPECIFIEDASN_IDX_ORDER].data.ref.length,
35743
                (char**)&curve->order, heap, DYNAMIC_TYPE_ECC_BUFFER);
35744
    }
35745
    #else
35746
    if (ret == 0) {
35747
        /* Base X-ordinate */
35748
        DataToHexString(base + 1, (word32)curve->size, (char *)curve->Gx);
35749
        /* Base Y-ordinate */
35750
        DataToHexString(base + 1 + curve->size, (word32)curve->size, (char *)curve->Gy);
35751
        /* Prime */
35752
        DataToHexString(dataASN[ECCSPECIFIEDASN_IDX_PRIME_P].data.ref.data,
35753
                        dataASN[ECCSPECIFIEDASN_IDX_PRIME_P].data.ref.length,
35754
                        (char *)curve->prime);
35755
        /* Parameter A */
35756
        DataToHexString(dataASN[ECCSPECIFIEDASN_IDX_PARAM_A].data.ref.data,
35757
                        dataASN[ECCSPECIFIEDASN_IDX_PARAM_A].data.ref.length,
35758
                        (char *)curve->Af);
35759
        /* Parameter B */
35760
        DataToHexString(dataASN[ECCSPECIFIEDASN_IDX_PARAM_B].data.ref.data,
35761
                        dataASN[ECCSPECIFIEDASN_IDX_PARAM_B].data.ref.length,
35762
                        (char *)curve->Bf);
35763
        /* Order of curve */
35764
        DataToHexString(dataASN[ECCSPECIFIEDASN_IDX_ORDER].data.ref.data,
35765
                        dataASN[ECCSPECIFIEDASN_IDX_ORDER].data.ref.length,
35766
                        (char *)curve->order);
35767
    }
35768
    #endif /* WOLFSSL_ECC_CURVE_STATIC */
35769
35770
    if ((ret == 0) && (curveSz)) {
35771
        *curveSz = curve->size;
35772
    }
35773
35774
    if (key) {
35775
        /* Store parameter set in key. */
35776
        if (ret == 0) {
35777
            if (wc_ecc_set_custom_curve(key, curve) < 0) {
35778
                ret = ASN_PARSE_E;
35779
            }
35780
            else {
35781
                /* The parameter set was allocated.. */
35782
                key->deallocSet = 1;
35783
                /* Don't deallocate below. */
35784
                curve = NULL;
35785
            }
35786
        }
35787
    }
35788
35789
    if (curve != NULL) { /* NOLINT(clang-analyzer-unix.Malloc) */
35790
        wc_ecc_free_curve(curve, heap);
35791
    }
35792
35793
    FREE_ASNGETDATA(dataASN, heap);
35794
    return ret;
35795
}
35796
#endif /* WOLFSSL_CUSTOM_CURVES */
35797
#endif /* WOLFSSL_ASN_TEMPLATE */
35798
#ifdef HAVE_ECC
35799
35800
#ifdef WOLFSSL_ASN_TEMPLATE
35801
/* ASN.1 template for ECC private key.
35802
 * SEC.1 Ver 2.0, C.4 - Syntax for Elliptic Curve Private Keys
35803
 */
35804
static const ASNItem eccKeyASN[] = {
35805
/* SEQ         */    { 0, ASN_SEQUENCE, 1, 1, 0 },
35806
                                       /* version */
35807
/* VER         */        { 1, ASN_INTEGER, 0, 0, 0 },
35808
                                       /* privateKey */
35809
/* PKEY        */        { 1, ASN_OCTET_STRING, 0, 0, 0 },
35810
                                       /* parameters */
35811
/* PARAMS      */        { 1, ASN_CONTEXT_SPECIFIC | ASN_ECC_PARAMS, 1, 1, 1 },
35812
                                           /* named */
35813
/* CURVEID     */            { 2, ASN_OBJECT_ID, 0, 0, 2 },
35814
                                           /* specified */
35815
/* CURVEPARAMS */            { 2, ASN_SEQUENCE, 1, 0, 2 },
35816
                                       /* publicKey */
35817
/* PUBKEY      */        { 1, ASN_CONTEXT_SPECIFIC | ASN_ECC_PUBKEY, 1, 1, 1 },
35818
                                           /* Uncompressed point - X9.62. */
35819
/* PUBKEY_VAL, */            { 2, ASN_BIT_STRING, 0, 0, 0 },
35820
};
35821
enum {
35822
    ECCKEYASN_IDX_SEQ = 0,
35823
    ECCKEYASN_IDX_VER,
35824
    ECCKEYASN_IDX_PKEY,
35825
    ECCKEYASN_IDX_PARAMS,
35826
    ECCKEYASN_IDX_CURVEID,
35827
    ECCKEYASN_IDX_CURVEPARAMS,
35828
    ECCKEYASN_IDX_PUBKEY,
35829
    ECCKEYASN_IDX_PUBKEY_VAL
35830
};
35831
35832
/* Number of items in ASN.1 template for ECC private key. */
35833
0
#define eccKeyASN_Length (sizeof(eccKeyASN) / sizeof(ASNItem))
35834
#endif
35835
35836
WOLFSSL_ABI
35837
int wc_EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key,
35838
                        word32 inSz)
35839
0
{
35840
#ifndef WOLFSSL_ASN_TEMPLATE
35841
    word32 oidSum;
35842
    int    version, length;
35843
    int    privSz, pubSz = 0;
35844
    byte   b;
35845
    int    ret = 0;
35846
    int    curve_id = ECC_CURVE_DEF;
35847
#ifdef WOLFSSL_SMALL_STACK
35848
    byte* priv;
35849
    byte* pub = NULL;
35850
#else
35851
    byte priv[ECC_MAXSIZE+1];
35852
    byte pub[2*(ECC_MAXSIZE+1)]; /* public key has two parts plus header */
35853
#endif
35854
    word32 algId = 0;
35855
    byte* pubData = NULL;
35856
35857
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
35858
        return BAD_FUNC_ARG;
35859
35860
    /* if has pkcs8 header skip it */
35861
    if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) {
35862
        /* ignore error, did not have pkcs8 header */
35863
    }
35864
    else {
35865
        curve_id = wc_ecc_get_oid(algId, NULL, NULL);
35866
    }
35867
35868
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
35869
        return ASN_PARSE_E;
35870
35871
    if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
35872
        return ASN_PARSE_E;
35873
35874
    if (*inOutIdx >= inSz)
35875
        return ASN_PARSE_E;
35876
35877
    b = input[*inOutIdx];
35878
    *inOutIdx += 1;
35879
35880
    /* priv type */
35881
    if (b != 4 && b != 6 && b != 7)
35882
        return ASN_PARSE_E;
35883
35884
    if (GetLength(input, inOutIdx, &length, inSz) < 0)
35885
        return ASN_PARSE_E;
35886
    privSz = length;
35887
35888
    if (privSz > ECC_MAXSIZE)
35889
        return BUFFER_E;
35890
35891
#ifdef WOLFSSL_SMALL_STACK
35892
    priv = (byte*)XMALLOC(privSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
35893
    if (priv == NULL)
35894
        return MEMORY_E;
35895
#endif
35896
35897
    /* priv key */
35898
    XMEMCPY(priv, &input[*inOutIdx], (size_t)privSz);
35899
    *inOutIdx += (word32)length;
35900
35901
    if ((*inOutIdx + 1) < inSz) {
35902
        /* prefix 0, may have */
35903
        b = input[*inOutIdx];
35904
        if (b == ECC_PREFIX_0) {
35905
            *inOutIdx += 1;
35906
35907
            if (GetLength(input, inOutIdx, &length, inSz) <= 0)
35908
                ret = ASN_PARSE_E;
35909
            else {
35910
                ret = GetObjectId(input, inOutIdx, &oidSum, oidIgnoreType,
35911
                                  inSz);
35912
                if (ret == 0) {
35913
                    if ((ret = CheckCurve(oidSum)) < 0)
35914
                        ret = ECC_CURVE_OID_E;
35915
                    else {
35916
                        curve_id = ret;
35917
                        ret = 0;
35918
                    }
35919
                }
35920
            }
35921
        }
35922
    }
35923
35924
    if (ret == 0 && (*inOutIdx + 1) < inSz) {
35925
        /* prefix 1 */
35926
        b = input[*inOutIdx];
35927
        *inOutIdx += 1;
35928
35929
        if (b != ECC_PREFIX_1) {
35930
            ret = ASN_ECC_KEY_E;
35931
        }
35932
        else if (GetLength(input, inOutIdx, &length, inSz) <= 0) {
35933
            ret = ASN_PARSE_E;
35934
        }
35935
        else {
35936
            /* key header */
35937
            ret = CheckBitString(input, inOutIdx, &length, inSz, 0, NULL);
35938
            if (ret == 0) {
35939
                /* pub key */
35940
                pubSz = length;
35941
                if (pubSz > 2*(ECC_MAXSIZE+1))
35942
                    ret = BUFFER_E;
35943
                else {
35944
            #ifdef WOLFSSL_SMALL_STACK
35945
                    pub = (byte*)XMALLOC(pubSz, key->heap,
35946
                                         DYNAMIC_TYPE_TMP_BUFFER);
35947
                    if (pub == NULL)
35948
                        ret = MEMORY_E;
35949
                    else
35950
            #endif
35951
                    {
35952
                        XMEMCPY(pub, &input[*inOutIdx], (size_t)pubSz);
35953
                        *inOutIdx += (word32)length;
35954
                        pubData = pub;
35955
                    }
35956
                }
35957
            }
35958
        }
35959
    }
35960
35961
    if (ret == 0) {
35962
        ret = wc_ecc_import_private_key_ex(priv, (word32)privSz, pubData,
35963
            (word32)pubSz, key, curve_id);
35964
    }
35965
35966
#ifdef WOLFSSL_SMALL_STACK
35967
    XFREE(priv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
35968
    XFREE(pub,  key->heap, DYNAMIC_TYPE_TMP_BUFFER);
35969
#endif
35970
35971
    return ret;
35972
#else
35973
0
    DECL_ASNGETDATA(dataASN, eccKeyASN_Length);
35974
0
    byte version = 0;
35975
0
    int ret = 0;
35976
0
    int curve_id = ECC_CURVE_DEF;
35977
0
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12) || defined(WOLFSSL_SM2)
35978
0
    word32 algId = 0;
35979
0
    word32 eccOid = 0;
35980
0
#endif
35981
35982
    /* Validate parameters. */
35983
0
    if ((input == NULL) || (inOutIdx == NULL) || (key == NULL) || (inSz == 0)) {
35984
0
        ret = BAD_FUNC_ARG;
35985
0
    }
35986
35987
0
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12) || defined(WOLFSSL_SM2)
35988
    /* if has pkcs8 header skip it */
35989
0
    if (ToTraditionalInline_ex2(input, inOutIdx, inSz, &algId, &eccOid) < 0) {
35990
        /* ignore error, did not have pkcs8 header */
35991
0
    }
35992
0
    else {
35993
0
        curve_id = wc_ecc_get_oid(eccOid, NULL, NULL);
35994
0
    }
35995
0
#endif
35996
35997
0
    CALLOC_ASNGETDATA(dataASN, eccKeyASN_Length, ret, key->heap);
35998
35999
0
    if (ret == 0) {
36000
        /* Get the version and set the expected OID type. */
36001
0
        GetASN_Int8Bit(&dataASN[ECCKEYASN_IDX_VER], &version);
36002
0
        GetASN_OID(&dataASN[ECCKEYASN_IDX_CURVEID], oidCurveType);
36003
        /* Decode the private ECC key. */
36004
0
        ret = GetASN_Items(eccKeyASN, dataASN, eccKeyASN_Length, 1, input,
36005
0
                           inOutIdx, inSz);
36006
0
    }
36007
    /* Only version 1 supported. */
36008
0
    if (ret == 0) {
36009
0
        if (version != 1) {
36010
0
            ret = ASN_PARSE_E;
36011
0
        }
36012
0
    }
36013
    /* Curve Parameters are optional. */
36014
0
    if ((ret == 0) && (dataASN[ECCKEYASN_IDX_PARAMS].tag != 0)) {
36015
0
        if (dataASN[ECCKEYASN_IDX_CURVEID].tag != 0) {
36016
            /* Named curve - check and get id. */
36017
0
            curve_id = CheckCurve(dataASN[ECCKEYASN_IDX_CURVEID].data.oid.sum);
36018
0
            if (curve_id < 0) {
36019
0
                ret = ECC_CURVE_OID_E;
36020
0
            }
36021
0
        }
36022
0
        else {
36023
    #ifdef WOLFSSL_CUSTOM_CURVES
36024
            /* Parse explicit parameters. */
36025
            ret = EccSpecifiedECDomainDecode(
36026
                    dataASN[ECCKEYASN_IDX_CURVEPARAMS].data.ref.data,
36027
                    dataASN[ECCKEYASN_IDX_CURVEPARAMS].data.ref.length, key,
36028
                    key->heap, NULL);
36029
    #else
36030
            /* Explicit parameters not supported in build configuration. */
36031
0
            ret = ASN_PARSE_E;
36032
0
    #endif
36033
0
        }
36034
0
    }
36035
0
    if (ret == 0) {
36036
        /* Import private key value and public point (may be NULL). */
36037
0
        ret = wc_ecc_import_private_key_ex(
36038
0
                dataASN[ECCKEYASN_IDX_PKEY].data.ref.data,
36039
0
                dataASN[ECCKEYASN_IDX_PKEY].data.ref.length,
36040
0
                dataASN[ECCKEYASN_IDX_PUBKEY_VAL].data.ref.data,
36041
0
                dataASN[ECCKEYASN_IDX_PUBKEY_VAL].data.ref.length,
36042
0
                key, curve_id);
36043
0
    }
36044
36045
0
    FREE_ASNGETDATA(dataASN, key->heap);
36046
0
    return ret;
36047
0
#endif
36048
0
}
36049
36050
36051
#ifdef WOLFSSL_CUSTOM_CURVES
36052
#ifndef WOLFSSL_ASN_TEMPLATE
36053
/* returns 0 on success */
36054
static int ASNToHexString(const byte* input, word32* inOutIdx, char** out,
36055
                          word32 inSz, void* heap, int heapType)
36056
{
36057
    int len;
36058
    int i;
36059
    char* str;
36060
    word32 localIdx;
36061
    byte   tag;
36062
36063
    if (*inOutIdx >= inSz) {
36064
        return BUFFER_E;
36065
    }
36066
36067
    localIdx = *inOutIdx;
36068
    if (GetASNTag(input, &localIdx, &tag, inSz) == 0 && tag == ASN_INTEGER) {
36069
        if (GetASNInt(input, inOutIdx, &len, inSz) < 0)
36070
            return ASN_PARSE_E;
36071
    }
36072
    else {
36073
        if (GetOctetString(input, inOutIdx, &len, inSz) < 0)
36074
            return ASN_PARSE_E;
36075
    }
36076
36077
    str = (char*)XMALLOC((size_t)len * 2 + 1, heap, heapType);
36078
    if (str == NULL) {
36079
        return MEMORY_E;
36080
    }
36081
36082
    for (i=0; i<len; i++)
36083
        ByteToHexStr(input[*inOutIdx + (word32)i], str + i*2);
36084
    str[len*2] = '\0';
36085
36086
    *inOutIdx += (word32)len;
36087
    *out = str;
36088
36089
    (void)heap;
36090
    (void)heapType;
36091
36092
    return 0;
36093
}
36094
36095
static int EccKeyParamCopy(char** dst, char* src, void* heap)
36096
{
36097
    int ret = 0;
36098
#ifdef WOLFSSL_ECC_CURVE_STATIC
36099
    word32 length;
36100
#endif
36101
36102
    if (dst == NULL || src == NULL)
36103
        return BAD_FUNC_ARG;
36104
36105
#ifndef WOLFSSL_ECC_CURVE_STATIC
36106
    *dst = src;
36107
#else
36108
    length = (int)XSTRLEN(src) + 1;
36109
    if (length > MAX_ECC_STRING) {
36110
        WOLFSSL_MSG("ECC Param too large for buffer");
36111
        ret = BUFFER_E;
36112
    }
36113
    else {
36114
        XSTRNCPY(*dst, src, MAX_ECC_STRING);
36115
    }
36116
    XFREE(src, heap, DYNAMIC_TYPE_ECC_BUFFER);
36117
#endif
36118
    (void)heap;
36119
36120
    return ret;
36121
}
36122
#endif /* !WOLFSSL_ASN_TEMPLATE */
36123
#endif /* WOLFSSL_CUSTOM_CURVES */
36124
36125
WOLFSSL_ABI
36126
int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx,
36127
                          ecc_key* key, word32 inSz)
36128
0
{
36129
#ifndef WOLFSSL_ASN_TEMPLATE
36130
    int    ret;
36131
    int    version, length;
36132
    int    curve_id = ECC_CURVE_DEF;
36133
    word32 oidSum, localIdx;
36134
    byte   tag, isPrivFormat = 0;
36135
36136
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
36137
        return BAD_FUNC_ARG;
36138
36139
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
36140
        return ASN_PARSE_E;
36141
36142
    /* Check if ECC private key is being used and skip private portion */
36143
    if (GetMyVersion(input, inOutIdx, &version, inSz) >= 0) {
36144
        isPrivFormat = 1;
36145
36146
        /* Type private key */
36147
        if (*inOutIdx >= inSz)
36148
            return ASN_PARSE_E;
36149
        tag = input[*inOutIdx];
36150
        *inOutIdx += 1;
36151
        if (tag != 4 && tag != 6 && tag != 7)
36152
            return ASN_PARSE_E;
36153
36154
        /* Skip Private Key */
36155
        if (GetLength(input, inOutIdx, &length, inSz) < 0)
36156
            return ASN_PARSE_E;
36157
        if (length > ECC_MAXSIZE)
36158
            return BUFFER_E;
36159
        *inOutIdx += (word32)length;
36160
36161
        /* Private Curve Header */
36162
        if (*inOutIdx >= inSz)
36163
            return ASN_PARSE_E;
36164
        tag = input[*inOutIdx];
36165
        *inOutIdx += 1;
36166
        if (tag != ECC_PREFIX_0)
36167
            return ASN_ECC_KEY_E;
36168
        if (GetLength(input, inOutIdx, &length, inSz) <= 0)
36169
            return ASN_PARSE_E;
36170
    }
36171
    /* Standard ECC public key */
36172
    else {
36173
        if (GetSequence(input, inOutIdx, &length, inSz) < 0)
36174
            return ASN_PARSE_E;
36175
36176
        ret = SkipObjectId(input, inOutIdx, inSz);
36177
        if (ret != 0)
36178
            return ret;
36179
    }
36180
36181
    if (*inOutIdx >= inSz) {
36182
        return BUFFER_E;
36183
    }
36184
36185
    localIdx = *inOutIdx;
36186
    if (GetASNTag(input, &localIdx, &tag, inSz) == 0 &&
36187
            tag == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
36188
#ifdef WOLFSSL_CUSTOM_CURVES
36189
        ecc_set_type* curve;
36190
        int len;
36191
        char* point = NULL;
36192
36193
        ret = 0;
36194
36195
        curve = (ecc_set_type*)XMALLOC(sizeof(*curve), key->heap,
36196
                                                       DYNAMIC_TYPE_ECC_BUFFER);
36197
        if (curve == NULL)
36198
            ret = MEMORY_E;
36199
36200
        if (ret == 0) {
36201
            static const char customName[] = "Custom";
36202
            XMEMSET(curve, 0, sizeof(*curve));
36203
        #ifndef WOLFSSL_ECC_CURVE_STATIC
36204
            curve->name = customName;
36205
        #else
36206
            XMEMCPY((void*)curve->name, customName, sizeof(customName));
36207
        #endif
36208
            curve->id = ECC_CURVE_CUSTOM;
36209
36210
            if (GetSequence(input, inOutIdx, &length, inSz) < 0)
36211
                ret = ASN_PARSE_E;
36212
        }
36213
36214
        if (ret == 0) {
36215
            GetInteger7Bit(input, inOutIdx, inSz);
36216
            if (GetSequence(input, inOutIdx, &length, inSz) < 0)
36217
                ret = ASN_PARSE_E;
36218
        }
36219
        if (ret == 0) {
36220
            char* p = NULL;
36221
            SkipObjectId(input, inOutIdx, inSz);
36222
            ret = ASNToHexString(input, inOutIdx, &p, inSz,
36223
                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
36224
            if (ret == 0) {
36225
#ifndef WOLFSSL_ECC_CURVE_STATIC
36226
                ret = EccKeyParamCopy((char**)&curve->prime, p, key->heap);
36227
#else
36228
                const char *_tmp_ptr = &curve->prime[0];
36229
                ret = EccKeyParamCopy((char**)&_tmp_ptr, p, key->heap);
36230
#endif
36231
            }
36232
        }
36233
        if (ret == 0) {
36234
            curve->size = (int)XSTRLEN(curve->prime) / 2;
36235
36236
            if (GetSequence(input, inOutIdx, &length, inSz) < 0)
36237
                ret = ASN_PARSE_E;
36238
        }
36239
        if (ret == 0) {
36240
            char* af = NULL;
36241
            ret = ASNToHexString(input, inOutIdx, &af, inSz,
36242
                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
36243
            if (ret == 0) {
36244
#ifndef WOLFSSL_ECC_CURVE_STATIC
36245
                ret = EccKeyParamCopy((char**)&curve->Af, af, key->heap);
36246
#else
36247
                const char *_tmp_ptr = &curve->Af[0];
36248
                ret = EccKeyParamCopy((char**)&_tmp_ptr, af, key->heap);
36249
#endif
36250
            }
36251
        }
36252
        if (ret == 0) {
36253
            char* bf = NULL;
36254
            ret = ASNToHexString(input, inOutIdx, &bf, inSz,
36255
                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
36256
            if (ret == 0) {
36257
#ifndef WOLFSSL_ECC_CURVE_STATIC
36258
                ret = EccKeyParamCopy((char**)&curve->Bf, bf, key->heap);
36259
#else
36260
                const char *_tmp_ptr = &curve->Bf[0];
36261
                ret = EccKeyParamCopy((char**)&_tmp_ptr, bf, key->heap);
36262
#endif
36263
            }
36264
        }
36265
        if (ret == 0) {
36266
            localIdx = *inOutIdx;
36267
            if (*inOutIdx < inSz && GetASNTag(input, &localIdx, &tag, inSz)
36268
                    == 0 && tag == ASN_BIT_STRING) {
36269
                len = 0;
36270
                ret = GetASNHeader(input, ASN_BIT_STRING, inOutIdx, &len, inSz);
36271
                if (ret > 0)
36272
                    ret = 0; /* reset on success */
36273
                *inOutIdx += (word32)len;
36274
            }
36275
        }
36276
        if (ret == 0) {
36277
            ret = ASNToHexString(input, inOutIdx, (char**)&point, inSz,
36278
                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
36279
36280
            /* sanity check that point buffer is not smaller than the expected
36281
             * size to hold ( 0 4 || Gx || Gy )
36282
             * where Gx and Gy are each the size of curve->size * 2 */
36283
            if (ret == 0 && (int)XSTRLEN(point) < (curve->size * 4) + 2) {
36284
                XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
36285
                ret = BUFFER_E;
36286
            }
36287
        }
36288
        if (ret == 0) {
36289
        #ifndef WOLFSSL_ECC_CURVE_STATIC
36290
            curve->Gx = (const char*)XMALLOC((size_t)curve->size * 2 + 2,
36291
                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
36292
            curve->Gy = (const char*)XMALLOC((size_t)curve->size * 2 + 2,
36293
                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
36294
            if (curve->Gx == NULL || curve->Gy == NULL) {
36295
                XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
36296
                ret = MEMORY_E;
36297
            }
36298
        #else
36299
            if (curve->size * 2 + 2 > MAX_ECC_STRING) {
36300
                WOLFSSL_MSG("curve size is too large to fit in buffer");
36301
                ret = BUFFER_E;
36302
            }
36303
        #endif
36304
        }
36305
        if (ret == 0) {
36306
            char* o = NULL;
36307
36308
            XMEMCPY((char*)curve->Gx, point + 2, (size_t)curve->size * 2);
36309
            XMEMCPY((char*)curve->Gy, point + curve->size * 2 + 2,
36310
                                                 (size_t)curve->size * 2);
36311
            ((char*)curve->Gx)[curve->size * 2] = '\0';
36312
            ((char*)curve->Gy)[curve->size * 2] = '\0';
36313
            XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
36314
            ret = ASNToHexString(input, inOutIdx, &o, inSz,
36315
                                            key->heap, DYNAMIC_TYPE_ECC_BUFFER);
36316
            if (ret == 0) {
36317
#ifndef WOLFSSL_ECC_CURVE_STATIC
36318
                ret = EccKeyParamCopy((char**)&curve->order, o, key->heap);
36319
#else
36320
                const char *_tmp_ptr = &curve->order[0];
36321
                ret = EccKeyParamCopy((char**)&_tmp_ptr, o, key->heap);
36322
#endif
36323
            }
36324
        }
36325
        if (ret == 0) {
36326
            curve->cofactor = GetInteger7Bit(input, inOutIdx, inSz);
36327
36328
        #ifndef WOLFSSL_ECC_CURVE_STATIC
36329
            curve->oid = NULL;
36330
        #else
36331
            XMEMSET((void*)curve->oid, 0, sizeof(curve->oid));
36332
        #endif
36333
            curve->oidSz = 0;
36334
            curve->oidSum = 0;
36335
36336
            if (wc_ecc_set_custom_curve(key, curve) < 0) {
36337
                ret = ASN_PARSE_E;
36338
            }
36339
36340
            key->deallocSet = 1;
36341
36342
            curve = NULL;
36343
        }
36344
        if (curve != NULL)
36345
            wc_ecc_free_curve(curve, key->heap);
36346
36347
        if (ret < 0)
36348
            return ret;
36349
#else
36350
        return ASN_PARSE_E;
36351
#endif /* WOLFSSL_CUSTOM_CURVES */
36352
    }
36353
    else {
36354
        /* ecc params information */
36355
        ret = GetObjectId(input, inOutIdx, &oidSum, oidIgnoreType, inSz);
36356
        if (ret != 0)
36357
            return ret;
36358
36359
        /* get curve id */
36360
        if ((ret = CheckCurve(oidSum)) < 0)
36361
            return ECC_CURVE_OID_E;
36362
        else {
36363
            curve_id = ret;
36364
        }
36365
    }
36366
36367
    if (isPrivFormat) {
36368
        /* Public Curve Header - skip */
36369
        if (*inOutIdx >= inSz)
36370
            return ASN_PARSE_E;
36371
        tag = input[*inOutIdx];
36372
        *inOutIdx += 1;
36373
        if (tag != ECC_PREFIX_1)
36374
            return ASN_ECC_KEY_E;
36375
        if (GetLength(input, inOutIdx, &length, inSz) <= 0)
36376
            return ASN_PARSE_E;
36377
    }
36378
36379
    /* key header */
36380
    ret = CheckBitString(input, inOutIdx, &length, inSz, 1, NULL);
36381
    if (ret != 0)
36382
        return ret;
36383
36384
    /* This is the raw point data compressed or uncompressed. */
36385
    if (wc_ecc_import_x963_ex(input + *inOutIdx, (word32)length, key,
36386
                                                            curve_id) != 0) {
36387
        return ASN_ECC_KEY_E;
36388
    }
36389
36390
    *inOutIdx += (word32)length;
36391
36392
    return 0;
36393
#else
36394
    /* eccKeyASN is longer than eccPublicKeyASN. */
36395
0
    DECL_ASNGETDATA(dataASN, eccKeyASN_Length);
36396
0
    int ret = 0;
36397
0
    int curve_id = ECC_CURVE_DEF;
36398
0
    int oidIdx = ECCPUBLICKEYASN_IDX_ALGOID_CURVEID;
36399
#ifdef WOLFSSL_CUSTOM_CURVES
36400
    int specIdx = ECCPUBLICKEYASN_IDX_ALGOID_PARAMS;
36401
#endif
36402
0
    int pubIdx = ECCPUBLICKEYASN_IDX_PUBKEY;
36403
36404
0
    if ((input == NULL) || (inOutIdx == NULL) || (key == NULL) || (inSz == 0)) {
36405
0
        ret = BAD_FUNC_ARG;
36406
0
    }
36407
36408
0
    ALLOC_ASNGETDATA(dataASN, eccKeyASN_Length, ret, key->heap);
36409
36410
0
    if (ret == 0) {
36411
        /* Clear dynamic data for ECC public key. */
36412
0
        XMEMSET(dataASN, 0, sizeof(*dataASN) * eccPublicKeyASN_Length);
36413
0
#if !defined(WOLFSSL_SM2) || !defined(WOLFSSL_SM3)
36414
        /* Set required ECDSA OID and ignore the curve OID type. */
36415
0
        GetASN_ExpBuffer(&dataASN[ECCPUBLICKEYASN_IDX_ALGOID_OID], keyEcdsaOid,
36416
0
                sizeof(keyEcdsaOid));
36417
#else
36418
        GetASN_OID(&dataASN[ECCPUBLICKEYASN_IDX_ALGOID_OID], oidKeyType);
36419
#endif
36420
0
        GetASN_OID(&dataASN[oidIdx], oidCurveType);
36421
        /* Decode the public ECC key. */
36422
0
        ret = GetASN_Items(eccPublicKeyASN, dataASN, eccPublicKeyASN_Length, 1,
36423
0
                           input, inOutIdx, inSz);
36424
0
        if (ret != 0) {
36425
0
            oidIdx = ECCKEYASN_IDX_CURVEID;
36426
        #ifdef WOLFSSL_CUSTOM_CURVES
36427
            specIdx = ECCKEYASN_IDX_CURVEPARAMS;
36428
        #endif
36429
0
            pubIdx = ECCKEYASN_IDX_PUBKEY_VAL;
36430
36431
            /* Clear dynamic data for ECC private key. */
36432
0
            XMEMSET(dataASN, 0, sizeof(*dataASN) * eccKeyASN_Length);
36433
            /* Check named curve OID type. */
36434
0
            GetASN_OID(&dataASN[oidIdx], oidCurveType);
36435
            /* Try private key format .*/
36436
0
            ret = GetASN_Items(eccKeyASN, dataASN, eccKeyASN_Length, 1, input,
36437
0
                               inOutIdx, inSz);
36438
0
            if (ret != 0) {
36439
0
                ret = ASN_PARSE_E;
36440
0
            }
36441
0
        }
36442
0
    }
36443
36444
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
36445
    if ((ret == 0) && (oidIdx == ECCPUBLICKEYASN_IDX_ALGOID_CURVEID)) {
36446
        int oidSum = dataASN[ECCPUBLICKEYASN_IDX_ALGOID_OID].data.oid.sum;
36447
        if ((oidSum != ECDSAk) && (oidSum != SM2k)) {
36448
            ret = ASN_PARSE_E;
36449
        }
36450
    }
36451
#endif
36452
0
    if (ret == 0) {
36453
0
        if (dataASN[oidIdx].tag != 0) {
36454
            /* Named curve - check and get id. */
36455
0
            curve_id = CheckCurve(dataASN[oidIdx].data.oid.sum);
36456
0
            if (curve_id < 0) {
36457
0
                ret = ASN_OBJECT_ID_E;
36458
0
            }
36459
0
        }
36460
0
        else {
36461
        #ifdef WOLFSSL_CUSTOM_CURVES
36462
            /* Parse explicit parameters. */
36463
            ret = EccSpecifiedECDomainDecode(dataASN[specIdx].data.ref.data,
36464
                                         dataASN[specIdx].data.ref.length, key,
36465
                                         key->heap, NULL);
36466
        #else
36467
            /* Explicit parameters not supported in build configuration. */
36468
0
            ret = ASN_PARSE_E;
36469
0
        #endif
36470
0
        }
36471
0
    }
36472
0
    if (ret == 0) {
36473
        /* Import public point. */
36474
0
        ret = wc_ecc_import_x963_ex(dataASN[pubIdx].data.ref.data,
36475
0
                dataASN[pubIdx].data.ref.length, key, curve_id);
36476
0
        if (ret != 0) {
36477
0
            ret = ASN_ECC_KEY_E;
36478
0
        }
36479
0
    }
36480
36481
0
    FREE_ASNGETDATA(dataASN, key->heap);
36482
0
    return ret;
36483
0
#endif /* WOLFSSL_ASN_TEMPLATE */
36484
0
}
36485
36486
#ifdef HAVE_ECC_KEY_EXPORT
36487
/* build DER formatted ECC key, include optional public key if requested,
36488
 * return length on success, negative on error */
36489
int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 *inLen,
36490
                             int pubIn, int curveIn)
36491
0
{
36492
#ifndef WOLFSSL_ASN_TEMPLATE
36493
    byte   curve[MAX_ALGO_SZ+2];
36494
    byte   ver[MAX_VERSION_SZ];
36495
    byte   seq[MAX_SEQ_SZ];
36496
    int    ret, curveSz, verSz;
36497
    word32 totalSz;
36498
    int    privHdrSz  = ASN_ECC_HEADER_SZ;
36499
    int    pubHdrSz   = ASN_ECC_CONTEXT_SZ + ASN_ECC_HEADER_SZ;
36500
#ifdef WOLFSSL_NO_MALLOC
36501
    byte   prv[MAX_ECC_BYTES + ASN_ECC_HEADER_SZ + MAX_SEQ_SZ];
36502
    byte   pub[(MAX_ECC_BYTES * 2) + 1 + ASN_ECC_CONTEXT_SZ +
36503
                              ASN_ECC_HEADER_SZ + MAX_SEQ_SZ];
36504
#else
36505
    byte   *prv = NULL, *pub = NULL;
36506
#endif
36507
36508
    word32 idx = 0, prvidx = 0, pubidx = 0, curveidx = 0;
36509
    word32 seqSz, privSz, pubSz = ECC_BUFSIZE;
36510
36511
    if (key == NULL || (output == NULL && inLen == NULL))
36512
        return BAD_FUNC_ARG;
36513
36514
    if (curveIn) {
36515
        /* curve */
36516
        curve[curveidx++] = ECC_PREFIX_0;
36517
        curveidx++ /* to put the size after computation */;
36518
        curveSz = SetCurve(key, curve+curveidx, MAX_ALGO_SZ);
36519
        if (curveSz < 0)
36520
            return curveSz;
36521
        /* set computed size */
36522
        curve[1] = (byte)curveSz;
36523
        curveidx += (word32)curveSz;
36524
    }
36525
36526
    /* private */
36527
    privSz = (word32)key->dp->size;
36528
36529
#ifdef WOLFSSL_QNX_CAAM
36530
    /* check if is a black key, and add MAC size if needed */
36531
    if (key->blackKey > 0 && key->blackKey != CAAM_BLACK_KEY_ECB) {
36532
        privSz = privSz + WC_CAAM_MAC_SZ;
36533
    }
36534
#endif
36535
36536
#ifndef WOLFSSL_NO_MALLOC
36537
    prv = (byte*)XMALLOC(privSz + (word32)privHdrSz + MAX_SEQ_SZ,
36538
                         key->heap, DYNAMIC_TYPE_TMP_BUFFER);
36539
    if (prv == NULL) {
36540
        return MEMORY_E;
36541
    }
36542
#else
36543
    if (sizeof(prv) < privSz + privHdrSz + MAX_SEQ_SZ) {
36544
        return BUFFER_E;
36545
    }
36546
#endif
36547
    if (privSz < ASN_LONG_LENGTH) {
36548
        prvidx += SetOctetString8Bit(privSz, &prv[prvidx]);
36549
    }
36550
    else {
36551
        prvidx += SetOctetString(privSz, &prv[prvidx]);
36552
    }
36553
    ret = wc_ecc_export_private_only(key, prv + prvidx, &privSz);
36554
    if (ret < 0) {
36555
    #ifndef WOLFSSL_NO_MALLOC
36556
        XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
36557
    #endif
36558
        return ret;
36559
    }
36560
    prvidx += privSz;
36561
36562
    /* pubIn */
36563
    if (pubIn) {
36564
        PRIVATE_KEY_UNLOCK();
36565
        ret = wc_ecc_export_x963(key, NULL, &pubSz);
36566
        PRIVATE_KEY_LOCK();
36567
        if (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
36568
        #ifndef WOLFSSL_NO_MALLOC
36569
            XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
36570
        #endif
36571
            return ret;
36572
        }
36573
36574
    #ifndef WOLFSSL_NO_MALLOC
36575
        pub = (byte*)XMALLOC(pubSz + (word32)pubHdrSz + MAX_SEQ_SZ,
36576
                             key->heap, DYNAMIC_TYPE_TMP_BUFFER);
36577
        if (pub == NULL) {
36578
            XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
36579
            return MEMORY_E;
36580
        }
36581
    #else
36582
        if (sizeof(pub) < pubSz + pubHdrSz + MAX_SEQ_SZ) {
36583
            return BUFFER_E;
36584
        }
36585
    #endif
36586
36587
        pub[pubidx++] = ECC_PREFIX_1;
36588
        if (pubSz > 128) /* leading zero + extra size byte */
36589
            pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 2, pub+pubidx);
36590
        else /* leading zero */
36591
            pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 1, pub+pubidx);
36592
36593
        /* SetBitString adds leading zero */
36594
        pubidx += SetBitString(pubSz, 0, pub + pubidx);
36595
        PRIVATE_KEY_UNLOCK();
36596
        ret = wc_ecc_export_x963(key, pub + pubidx, &pubSz);
36597
        PRIVATE_KEY_LOCK();
36598
        if (ret != 0) {
36599
        #ifndef WOLFSSL_NO_MALLOC
36600
            XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
36601
            XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
36602
        #endif
36603
            return ret;
36604
        }
36605
        pubidx += pubSz;
36606
    }
36607
36608
    /* make headers */
36609
    verSz = SetMyVersion(1, ver, FALSE);
36610
    seqSz = SetSequence((word32)verSz + prvidx + pubidx + curveidx, seq);
36611
36612
    totalSz = prvidx + pubidx + curveidx + (word32)verSz + seqSz;
36613
    if (output == NULL) {
36614
        *inLen = totalSz;
36615
    #ifndef WOLFSSL_NO_MALLOC
36616
        XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
36617
        if (pubIn) {
36618
            XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
36619
        }
36620
    #endif
36621
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
36622
    }
36623
    if (inLen != NULL && totalSz > *inLen) {
36624
        #ifndef WOLFSSL_NO_MALLOC
36625
        XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
36626
        if (pubIn) {
36627
            XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
36628
        }
36629
        #endif
36630
        return BAD_FUNC_ARG;
36631
    }
36632
36633
    /* write out */
36634
    /* seq */
36635
    XMEMCPY(output + idx, seq, seqSz);
36636
    idx = seqSz;
36637
36638
    /* ver */
36639
    XMEMCPY(output + idx, ver, (size_t)verSz);
36640
    idx += (word32)verSz;
36641
36642
    /* private */
36643
    XMEMCPY(output + idx, prv, prvidx);
36644
    idx += prvidx;
36645
#ifndef WOLFSSL_NO_MALLOC
36646
    XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
36647
#endif
36648
36649
    /* curve */
36650
    XMEMCPY(output + idx, curve, curveidx);
36651
    idx += curveidx;
36652
36653
    /* pubIn */
36654
    if (pubIn) {
36655
        XMEMCPY(output + idx, pub, pubidx);
36656
        /* idx += pubidx;  not used after write, if more data remove comment */
36657
    #ifndef WOLFSSL_NO_MALLOC
36658
        XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
36659
    #endif
36660
    }
36661
36662
    return (int)totalSz;
36663
#else
36664
0
    DECL_ASNSETDATA(dataASN, eccKeyASN_Length);
36665
0
    word32 privSz = 0;
36666
0
    word32 pubSz = 0;
36667
0
    int sz = 0;
36668
0
    int ret = 0;
36669
0
    int curveIdSz = 0;
36670
36671
    /* Check validity of parameters. */
36672
0
    if ((key == NULL) || ((output == NULL) && (inLen == NULL))) {
36673
0
        ret = BAD_FUNC_ARG;
36674
0
    }
36675
36676
    /* Check key has parameters when encoding curve. */
36677
0
    if ((ret == 0) && curveIn && (key->dp == NULL)) {
36678
0
        ret = BAD_FUNC_ARG;
36679
0
    }
36680
36681
0
    CALLOC_ASNSETDATA(dataASN, eccKeyASN_Length, ret, key->heap);
36682
36683
0
    if (ret == 0) {
36684
        /* Private key size is the curve size. */
36685
0
        privSz = (word32)key->dp->size;
36686
0
        if (pubIn) {
36687
            /* Get the length of the public key. */
36688
0
            PRIVATE_KEY_UNLOCK();
36689
0
            ret = wc_ecc_export_x963(key, NULL, &pubSz);
36690
0
            PRIVATE_KEY_LOCK();
36691
0
            if (ret == WC_NO_ERR_TRACE(LENGTH_ONLY_E))
36692
0
                ret = 0;
36693
0
        }
36694
0
    }
36695
0
    if (ret == 0) {
36696
        /* Version: 1 */
36697
0
        SetASN_Int8Bit(&dataASN[ECCKEYASN_IDX_VER], 1);
36698
        /* Leave space for private key. */
36699
0
        SetASN_Buffer(&dataASN[ECCKEYASN_IDX_PKEY], NULL, privSz);
36700
0
        if (curveIn) {
36701
            /* Get length of the named curve OID to put into the encoding. */
36702
0
            curveIdSz = SetCurve(key, NULL, 0);
36703
0
            if (curveIdSz < 0) {
36704
0
                ret = curveIdSz;
36705
0
            }
36706
            /* Curve OID */
36707
0
            SetASN_ReplaceBuffer(&dataASN[ECCKEYASN_IDX_CURVEID], NULL,
36708
0
                (word32)curveIdSz);
36709
            /* TODO: add support for SpecifiedECDomain curve. */
36710
0
            dataASN[ECCKEYASN_IDX_CURVEPARAMS].noOut = 1;
36711
0
        }
36712
0
        else {
36713
0
            SetASNItem_NoOutNode(dataASN, eccKeyASN, ECCKEYASN_IDX_PARAMS,
36714
0
                    eccKeyASN_Length);
36715
0
        }
36716
0
        if (ret == 0) {
36717
0
            if (pubIn) {
36718
                /* Leave space for public key. */
36719
0
                SetASN_Buffer(&dataASN[ECCKEYASN_IDX_PUBKEY_VAL], NULL, pubSz);
36720
0
            }
36721
0
            else {
36722
                /* Don't write out public key. */
36723
0
                SetASNItem_NoOutNode(dataASN, eccKeyASN, ECCKEYASN_IDX_PUBKEY,
36724
0
                                     eccKeyASN_Length);
36725
0
            }
36726
            /* Calculate size of the private key encoding. */
36727
0
            ret = SizeASN_Items(eccKeyASN, dataASN, eccKeyASN_Length, &sz);
36728
0
        }
36729
0
    }
36730
    /* Return the size if no buffer. */
36731
0
    if ((ret == 0) && (output == NULL)) {
36732
0
        *inLen = (word32)sz;
36733
0
        ret = WC_NO_ERR_TRACE(LENGTH_ONLY_E);
36734
0
    }
36735
    /* Check the buffer is big enough. */
36736
0
    if ((ret == 0) && (inLen != NULL) && (sz > (int)*inLen)) {
36737
0
        ret = BAD_FUNC_ARG;
36738
0
    }
36739
0
    if ((ret == 0) && (output != NULL)) {
36740
        /* Encode the private key. */
36741
0
        SetASN_Items(eccKeyASN, dataASN, eccKeyASN_Length, output);
36742
36743
0
        if (curveIn) {
36744
            /* Put named curve OID data into encoding. */
36745
0
            curveIdSz = SetCurve(key,
36746
0
                (byte*)dataASN[ECCKEYASN_IDX_CURVEID].data.buffer.data,
36747
0
                (size_t)curveIdSz);
36748
0
            if (curveIdSz < 0) {
36749
0
                ret = curveIdSz;
36750
0
            }
36751
0
        }
36752
0
        if (ret == 0) {
36753
            /* Export the private value into the buffer. */
36754
0
            ret = wc_ecc_export_private_only(key,
36755
0
                (byte*)dataASN[ECCKEYASN_IDX_PKEY].data.buffer.data, &privSz);
36756
0
        }
36757
0
        if ((ret == 0) && pubIn) {
36758
            /* Export the public point into the buffer. */
36759
0
            PRIVATE_KEY_UNLOCK();
36760
0
            ret = wc_ecc_export_x963(key,
36761
0
                    (byte*)dataASN[ECCKEYASN_IDX_PUBKEY_VAL].data.buffer.data,
36762
0
                    &pubSz);
36763
0
            PRIVATE_KEY_LOCK();
36764
0
        }
36765
0
    }
36766
0
    if (ret == 0) {
36767
        /* Return the encoding size. */
36768
0
        ret = sz;
36769
0
    }
36770
36771
0
    FREE_ASNSETDATA(dataASN, key->heap);
36772
0
    return ret;
36773
0
#endif
36774
0
}
36775
36776
/* Write a Private ecc key, including public to DER format,
36777
 * length on success else < 0 */
36778
/* Note: use wc_EccKeyDerSize to get length only */
36779
WOLFSSL_ABI
36780
int wc_EccKeyToDer(ecc_key* key, byte* output, word32 inLen)
36781
0
{
36782
0
    return wc_BuildEccKeyDer(key, output, &inLen, 1, 1);
36783
0
}
36784
36785
/* Write only private ecc key to DER format,
36786
 * length on success else < 0 */
36787
int wc_EccKeyDerSize(ecc_key* key, int pub)
36788
0
{
36789
0
    word32 sz = 0;
36790
0
    int ret = wc_BuildEccKeyDer(key, NULL, &sz, pub, 1);
36791
0
    if (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
36792
0
        return ret;
36793
0
    }
36794
0
    return (int)sz;
36795
0
 }
36796
36797
/* Write only private ecc key to DER format,
36798
 * length on success else < 0 */
36799
int wc_EccPrivateKeyToDer(ecc_key* key, byte* output, word32 inLen)
36800
0
{
36801
0
    int ret = wc_BuildEccKeyDer(key, output, &inLen, 0, 1);
36802
0
    if (ret == WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
36803
0
        return (int)inLen;
36804
0
    }
36805
0
    return ret;
36806
0
}
36807
36808
#ifdef HAVE_PKCS8
36809
36810
/* Write only private ecc key or both private and public parts to unencrypted
36811
 * PKCS#8 format.
36812
 *
36813
 * If output is NULL, places required PKCS#8 buffer size in outLen and
36814
 * returns LENGTH_ONLY_E.
36815
 *
36816
 * return length on success else < 0 */
36817
static int eccToPKCS8(ecc_key* key, byte* output, word32* outLen,
36818
        int includePublic)
36819
0
{
36820
0
    int ret;
36821
0
    word32 tmpDerSz;
36822
0
    int algoID = 0;
36823
0
    word32 oidSz = 0;
36824
0
    word32 pkcs8Sz = 0;
36825
0
    const byte* curveOID = NULL;
36826
#ifdef WOLFSSL_NO_MALLOC
36827
    byte  tmpDer[ECC_BUFSIZE];
36828
#else
36829
0
    byte* tmpDer = NULL;
36830
0
#endif
36831
0
    word32 sz = ECC_BUFSIZE;
36832
36833
0
    if (key == NULL || key->dp == NULL || outLen == NULL)
36834
0
        return BAD_FUNC_ARG;
36835
36836
    /* set algoID, get curve OID */
36837
0
    algoID = ECDSAk;
36838
0
    ret = wc_ecc_get_oid(key->dp->oidSum, &curveOID, &oidSz);
36839
0
    if (ret < 0)
36840
0
        return ret;
36841
36842
0
#ifndef WOLFSSL_NO_MALLOC
36843
    /* temp buffer for plain DER key */
36844
0
    tmpDer = (byte*)XMALLOC(ECC_BUFSIZE, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
36845
0
    if (tmpDer == NULL)
36846
0
        return MEMORY_E;
36847
0
#endif
36848
0
    XMEMSET(tmpDer, 0, ECC_BUFSIZE);
36849
36850
0
    ret = wc_BuildEccKeyDer(key, tmpDer, &sz, includePublic, 0);
36851
0
    if (ret < 0) {
36852
0
    #ifndef WOLFSSL_NO_MALLOC
36853
0
        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
36854
0
    #endif
36855
0
        return ret;
36856
0
    }
36857
0
    tmpDerSz = (word32)ret;
36858
36859
    /* get pkcs8 expected output size */
36860
0
    ret = wc_CreatePKCS8Key(NULL, &pkcs8Sz, tmpDer, tmpDerSz, algoID,
36861
0
                            curveOID, oidSz);
36862
0
    if (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
36863
0
    #ifndef WOLFSSL_NO_MALLOC
36864
0
        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
36865
0
    #endif
36866
0
        return ret;
36867
0
    }
36868
36869
0
    if (output == NULL) {
36870
0
    #ifndef WOLFSSL_NO_MALLOC
36871
0
        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
36872
0
    #endif
36873
0
        *outLen = pkcs8Sz;
36874
0
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
36875
36876
0
    }
36877
0
    else if (*outLen < pkcs8Sz) {
36878
0
    #ifndef WOLFSSL_NO_MALLOC
36879
0
        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
36880
0
    #endif
36881
0
        WOLFSSL_MSG("Input buffer too small for ECC PKCS#8 key");
36882
0
        return BUFFER_E;
36883
0
    }
36884
36885
0
    ret = wc_CreatePKCS8Key(output, &pkcs8Sz, tmpDer, tmpDerSz,
36886
0
                            algoID, curveOID, oidSz);
36887
0
    if (ret < 0) {
36888
0
    #ifndef WOLFSSL_NO_MALLOC
36889
0
        XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
36890
0
    #endif
36891
0
        return ret;
36892
0
    }
36893
36894
0
#ifndef WOLFSSL_NO_MALLOC
36895
0
    XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
36896
0
#endif
36897
36898
0
    *outLen = (word32)ret;
36899
0
    return ret;
36900
0
}
36901
36902
/* Write only private ecc key to unencrypted PKCS#8 format.
36903
 *
36904
 * return length on success else < 0 */
36905
int wc_EccPrivateKeyToPKCS8(ecc_key* key, byte* output, word32* outLen)
36906
0
{
36907
0
    return eccToPKCS8(key, output, outLen, 0);
36908
0
}
36909
36910
/* Write both private and public ecc keys to unencrypted PKCS#8 format.
36911
 *
36912
 * return length on success else < 0 */
36913
int wc_EccKeyToPKCS8(ecc_key* key, byte* output,
36914
                     word32* outLen)
36915
0
{
36916
0
    return eccToPKCS8(key, output, outLen, 1);
36917
0
}
36918
#endif /* HAVE_PKCS8 */
36919
#endif /* HAVE_ECC_KEY_EXPORT */
36920
#endif /* HAVE_ECC */
36921
36922
#ifdef WC_ENABLE_ASYM_KEY_IMPORT
36923
#ifdef WOLFSSL_ASN_TEMPLATE
36924
/* ASN.1 template for a general asymmetric private key: Ed25519, Ed448,
36925
 * falcon, dilithium, etc.
36926
 * RFC 8410, 7 - Private Key Format (but public value is EXPLICIT OCTET_STRING)
36927
 */
36928
static const ASNItem privateKeyASN[] = {
36929
/* SEQ            */    { 0, ASN_SEQUENCE, 1, 1, 0 },
36930
                                         /* Version */
36931
/* VER            */        { 1, ASN_INTEGER, 0, 0, 0 },
36932
                                         /* privateKeyAlgorithm */
36933
/* PKEYALGO_SEQ   */        { 1, ASN_SEQUENCE, 1, 1, 0 },
36934
/* PKEYALGO_OID   */            { 2, ASN_OBJECT_ID, 0, 0, 1 },
36935
                                         /* privateKey */
36936
/* PKEY           */        { 1, ASN_OCTET_STRING, 0, 1, 0 },
36937
                                             /* CurvePrivateKey */
36938
/* PKEY_CURVEPKEY */            { 2, ASN_OCTET_STRING, 0, 0, 2 },
36939
/* PKEY_MLDSASEQ  */            { 2, ASN_SEQUENCE, 1, 0, 2 },
36940
                                         /* attributes */
36941
/* ATTRS          */        { 1, ASN_CONTEXT_SPECIFIC | ASN_ASYMKEY_ATTRS, 1, 1, 1 },
36942
                                         /* publicKey */
36943
/* PUBKEY         */        { 1, ASN_CONTEXT_SPECIFIC | ASN_ASYMKEY_PUBKEY, 0, 0, 1 },
36944
};
36945
enum {
36946
    PRIVKEYASN_IDX_SEQ = 0,
36947
    PRIVKEYASN_IDX_VER,
36948
    PRIVKEYASN_IDX_PKEYALGO_SEQ,
36949
    PRIVKEYASN_IDX_PKEYALGO_OID,
36950
    PRIVKEYASN_IDX_PKEY,
36951
    PRIVKEYASN_IDX_PKEY_CURVEPKEY,
36952
    PRIVKEYASN_IDX_PKEY_MLDSASEQ,
36953
    PRIVKEYASN_IDX_ATTRS,
36954
    PRIVKEYASN_IDX_PUBKEY
36955
};
36956
36957
/* Number of items in ASN.1 template for private key. */
36958
#define privateKeyASN_Length (sizeof(privateKeyASN) / sizeof(ASNItem))
36959
#endif /* WOLFSSL_ASN_TEMPLATE */
36960
36961
#if ((defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)) \
36962
    || (defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_KEY_IMPORT)) \
36963
    || (defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)) \
36964
    || (defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_IMPORT)) \
36965
    || defined(HAVE_FALCON) || defined(HAVE_DILITHIUM) || defined(HAVE_SPHINCS))
36966
36967
36968
int DecodeAsymKey_Assign(const byte* input, word32* inOutIdx, word32 inSz,
36969
    const byte** privKey, word32* privKeyLen,
36970
    const byte** pubKey, word32* pubKeyLen, int* inOutKeyType)
36971
{
36972
#ifndef WOLFSSL_ASN_TEMPLATE
36973
    word32 oid;
36974
    int version, length, endKeyIdx, privSz, pubSz;
36975
    const byte* priv;
36976
    const byte* pub;
36977
#else
36978
    int ret = 0;
36979
    DECL_ASNGETDATA(dataASN, privateKeyASN_Length);
36980
    CALLOC_ASNGETDATA(dataASN, privateKeyASN_Length, ret, NULL);
36981
#endif
36982
36983
    if (input == NULL || inOutIdx == NULL || inSz == 0 ||
36984
        privKey == NULL || privKeyLen == NULL || inOutKeyType == NULL) {
36985
    #ifdef WOLFSSL_ASN_TEMPLATE
36986
        FREE_ASNGETDATA(dataASN, NULL);
36987
    #endif
36988
        return BAD_FUNC_ARG;
36989
    }
36990
36991
#ifndef WOLFSSL_ASN_TEMPLATE
36992
    if (GetSequence(input, inOutIdx, &length, inSz) >= 0) {
36993
        endKeyIdx = (int)*inOutIdx + length;
36994
36995
        if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
36996
            return ASN_PARSE_E;
36997
        if (version != 0) {
36998
            WOLFSSL_MSG("Unrecognized version of private key");
36999
            return ASN_PARSE_E;
37000
        }
37001
37002
        if (GetAlgoId(input, inOutIdx, &oid, oidKeyType, inSz) < 0)
37003
            return ASN_PARSE_E;
37004
37005
        /* If user supplies ANONk (0) key type, we want to auto-detect from
37006
         * DER and copy it back to user */
37007
        if (*inOutKeyType == ANONk) {
37008
            *inOutKeyType = oid;
37009
        }
37010
        /* Otherwise strictly validate against the expected type */
37011
        else if (oid != (word32)*inOutKeyType) {
37012
            return ASN_PARSE_E;
37013
        }
37014
37015
        if (GetOctetString(input, inOutIdx, &length, inSz) < 0)
37016
            return ASN_PARSE_E;
37017
37018
        if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0) {
37019
            if (oid != ML_DSA_LEVEL2k && oid != ML_DSA_LEVEL3k &&
37020
                    oid != ML_DSA_LEVEL5k) {
37021
                return ASN_PARSE_E;
37022
            }
37023
            if (GetSequence(input, inOutIdx, &privSz, inSz) < 0) {
37024
                return ASN_PARSE_E;
37025
            }
37026
        }
37027
37028
        priv = input + *inOutIdx;
37029
        *inOutIdx += (word32)privSz;
37030
    }
37031
    else {
37032
        if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0)
37033
            return ASN_PARSE_E;
37034
37035
        priv = input + *inOutIdx;
37036
        *inOutIdx += (word32)privSz;
37037
        endKeyIdx = (int)*inOutIdx;
37038
    }
37039
37040
    if (endKeyIdx == (int)*inOutIdx) {
37041
        *privKeyLen = (word32)privSz;
37042
        *privKey = priv;
37043
        if (pubKeyLen != NULL)
37044
            *pubKeyLen = 0;
37045
    }
37046
    else {
37047
        if (pubKeyLen == NULL) {
37048
            return BAD_FUNC_ARG;
37049
        }
37050
37051
        if (GetASNHeader(input, ASN_CONTEXT_SPECIFIC | ASN_ASYMKEY_PUBKEY | 1,
37052
                         inOutIdx, &pubSz, inSz) < 0) {
37053
            return ASN_PARSE_E;
37054
        }
37055
37056
        pub = input + *inOutIdx;
37057
        *inOutIdx += (word32)pubSz;
37058
37059
        *privKeyLen = (word32)privSz;
37060
        *privKey = priv;
37061
        *pubKeyLen = (word32)pubSz;
37062
        if (pubKey != NULL)
37063
            *pubKey = pub;
37064
    }
37065
    if (endKeyIdx != (int)*inOutIdx)
37066
        return ASN_PARSE_E;
37067
    return 0;
37068
#else
37069
    if (ret == 0) {
37070
        /* If user supplies an expected keyType (algorithm OID sum), attempt to
37071
         * process DER accordingly */
37072
        if (*inOutKeyType != ANONk) {
37073
            word32 oidSz;
37074
            /* Explicit OID check - use expected type */
37075
            const byte* oidDerBytes = OidFromId((word32)*inOutKeyType,
37076
                                                oidKeyType, &oidSz);
37077
            GetASN_ExpBuffer(&dataASN[PRIVKEYASN_IDX_PKEYALGO_OID], oidDerBytes,
37078
                            oidSz);
37079
        }
37080
        else {
37081
            /* Auto-detect OID using template */
37082
            GetASN_OID(&dataASN[PRIVKEYASN_IDX_PKEYALGO_OID], oidKeyType);
37083
        }
37084
37085
        /* Parse full private key. */
37086
        ret = GetASN_Items(privateKeyASN, dataASN, privateKeyASN_Length, 1, input,
37087
                inOutIdx, inSz);
37088
        if (ret != 0) {
37089
            /* Parse just the OCTET_STRING. */
37090
            ret = GetASN_Items(&privateKeyASN[PRIVKEYASN_IDX_PKEY_CURVEPKEY],
37091
                    &dataASN[PRIVKEYASN_IDX_PKEY_CURVEPKEY], 1, 0, input,
37092
                    inOutIdx, inSz);
37093
            if (ret != 0) {
37094
                ret = ASN_PARSE_E;
37095
            }
37096
        }
37097
37098
        /* Store detected OID if requested */
37099
        if (ret == 0 && *inOutKeyType == ANONk) {
37100
            *inOutKeyType =
37101
                (int)dataASN[PRIVKEYASN_IDX_PKEYALGO_OID].data.oid.sum;
37102
        }
37103
    }
37104
    if (ret == 0 && dataASN[PRIVKEYASN_IDX_PKEY_CURVEPKEY].data.ref.length != 0) {
37105
        /* Import private value. */
37106
        *privKeyLen = dataASN[PRIVKEYASN_IDX_PKEY_CURVEPKEY].data.ref.length;
37107
        *privKey = dataASN[PRIVKEYASN_IDX_PKEY_CURVEPKEY].data.ref.data;
37108
    }
37109
    else if (ret == 0 &&
37110
             dataASN[PRIVKEYASN_IDX_PKEY_MLDSASEQ].data.ref.length != 0) {
37111
        if (*inOutKeyType != ML_DSA_LEVEL2k &&
37112
                *inOutKeyType != ML_DSA_LEVEL3k &&
37113
                *inOutKeyType != ML_DSA_LEVEL5k) {
37114
            ret = ASN_PARSE_E;
37115
        }
37116
        else {
37117
            /* Import private value. */
37118
            *privKeyLen = dataASN[PRIVKEYASN_IDX_PKEY_MLDSASEQ].data.ref.length;
37119
            *privKey = dataASN[PRIVKEYASN_IDX_PKEY_MLDSASEQ].data.ref.data;
37120
        }
37121
    }
37122
    if ((ret == 0) && dataASN[PRIVKEYASN_IDX_PUBKEY].tag == 0) {
37123
        /* Set public length to 0 as not seen. */
37124
        if (pubKeyLen != NULL)
37125
            *pubKeyLen = 0;
37126
    }
37127
    else if (ret == 0) {
37128
        /* Import public value. */
37129
        if (pubKeyLen != NULL)
37130
            *pubKeyLen = dataASN[PRIVKEYASN_IDX_PUBKEY].data.ref.length;
37131
        if (pubKey != NULL && pubKeyLen != NULL)
37132
            *pubKey = dataASN[PRIVKEYASN_IDX_PUBKEY].data.ref.data;
37133
    }
37134
37135
    FREE_ASNGETDATA(dataASN, NULL);
37136
    return ret;
37137
#endif /* WOLFSSL_ASN_TEMPLATE */
37138
}
37139
37140
int DecodeAsymKey(const byte* input, word32* inOutIdx, word32 inSz,
37141
    byte* privKey, word32* privKeyLen,
37142
    byte* pubKey, word32* pubKeyLen, int keyType)
37143
{
37144
    int ret = 0;
37145
    const byte* privKeyPtr = NULL;
37146
    const byte* pubKeyPtr = NULL;
37147
    word32 privKeyPtrLen = 0;
37148
    word32 pubKeyPtrLen = 0;
37149
37150
    if (privKey == NULL) {
37151
        ret = BAD_FUNC_ARG;
37152
    }
37153
37154
    if (ret == 0) {
37155
        ret = DecodeAsymKey_Assign(input, inOutIdx, inSz, &privKeyPtr,
37156
            &privKeyPtrLen, &pubKeyPtr, &pubKeyPtrLen, &keyType);
37157
    }
37158
    if ((ret == 0) && (privKeyPtrLen > *privKeyLen)) {
37159
        ret = BUFFER_E;
37160
    }
37161
    if ((ret == 0) && (pubKeyLen != NULL) && (pubKeyPtrLen > *pubKeyLen)) {
37162
        ret = BUFFER_E;
37163
    }
37164
    if ((ret == 0) && (privKeyPtr != NULL)) {
37165
        XMEMCPY(privKey, privKeyPtr, privKeyPtrLen);
37166
        *privKeyLen = privKeyPtrLen;
37167
    }
37168
    if ((ret == 0) && (pubKey != NULL) && (pubKeyPtr != NULL)) {
37169
        XMEMCPY(pubKey, pubKeyPtr, pubKeyPtrLen);
37170
    }
37171
    if ((ret == 0) && (pubKeyLen != NULL)) {
37172
        *pubKeyLen = pubKeyPtrLen;
37173
    }
37174
37175
    return ret;
37176
}
37177
37178
int DecodeAsymKeyPublic_Assign(const byte* input, word32* inOutIdx, word32 inSz,
37179
    const byte** pubKey, word32* pubKeyLen, int *inOutKeyType)
37180
{
37181
    int ret = 0;
37182
#ifndef WOLFSSL_ASN_TEMPLATE
37183
    int length;
37184
    word32 oid;
37185
#else
37186
    word32 len;
37187
    DECL_ASNGETDATA(dataASN, publicKeyASN_Length);
37188
#endif
37189
37190
    if (input == NULL || inSz == 0 || inOutIdx == NULL ||
37191
        pubKey == NULL || pubKeyLen == NULL || inOutKeyType == NULL) {
37192
        return BAD_FUNC_ARG;
37193
    }
37194
37195
#ifndef WOLFSSL_ASN_TEMPLATE
37196
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
37197
        return ASN_PARSE_E;
37198
37199
    if (GetSequence(input, inOutIdx, &length, inSz) < 0)
37200
        return ASN_PARSE_E;
37201
37202
    if (GetObjectId(input, inOutIdx, &oid, oidKeyType, inSz) < 0)
37203
        return ASN_PARSE_E;
37204
37205
    /* If user supplies ANONk (0) key type, we want to auto-detect from
37206
     * DER and copy it back to user */
37207
    if (*inOutKeyType == ANONk) {
37208
        *inOutKeyType = oid;
37209
    }
37210
    /* Otherwise strictly validate against the expected type */
37211
    else if (oid != (word32)*inOutKeyType) {
37212
        return ASN_PARSE_E;
37213
    }
37214
37215
    /* key header */
37216
    ret = CheckBitString(input, inOutIdx, &length, inSz, 1, NULL);
37217
    if (ret != 0)
37218
        return ret;
37219
37220
    /* check that input buffer is exhausted */
37221
    if (*inOutIdx + (word32)length != inSz)
37222
        return ASN_PARSE_E;
37223
37224
    /* This is the raw point data compressed or uncompressed. */
37225
    *pubKeyLen = (word32)length;
37226
    *pubKey = input + *inOutIdx;
37227
#else
37228
    len = inSz - *inOutIdx;
37229
37230
    CALLOC_ASNGETDATA(dataASN, publicKeyASN_Length, ret, NULL);
37231
37232
    if (ret == 0) {
37233
        /* If user supplies an expected keyType (algorithm OID sum), attempt to
37234
         * process DER accordingly */
37235
        if (*inOutKeyType != ANONk) {
37236
            word32 oidSz;
37237
            /* Explicit OID check - use expected type */
37238
            const byte* oidDerBytes = OidFromId((word32)*inOutKeyType,
37239
                                              oidKeyType, &oidSz);
37240
            GetASN_ExpBuffer(&dataASN[PUBKEYASN_IDX_ALGOID_OID], oidDerBytes,
37241
                           oidSz);
37242
        }
37243
        else {
37244
            /* Auto-detect OID using template */
37245
            GetASN_OID(&dataASN[PUBKEYASN_IDX_ALGOID_OID], oidKeyType);
37246
        }
37247
        /* Decode public key. */
37248
        ret = GetASN_Items(publicKeyASN, dataASN, publicKeyASN_Length, 1,
37249
                           input, inOutIdx, inSz);
37250
        if (ret != 0)
37251
            ret = ASN_PARSE_E;
37252
        /* check that input buffer is exhausted */
37253
        if (*inOutIdx != inSz)
37254
            ret = ASN_PARSE_E;
37255
37256
        /* Store detected OID if requested */
37257
        if (ret == 0 && *inOutKeyType == ANONk) {
37258
            *inOutKeyType =
37259
                (int)dataASN[PUBKEYASN_IDX_ALGOID_OID].data.oid.sum;
37260
        }
37261
    }
37262
    /* Check that the all the buffer was used. */
37263
    if ((ret == 0) &&
37264
            (GetASNItem_Length(dataASN[PUBKEYASN_IDX_SEQ], input) != len)) {
37265
        ret = ASN_PARSE_E;
37266
    }
37267
    if (ret == 0) {
37268
        *pubKeyLen = dataASN[PUBKEYASN_IDX_PUBKEY].data.ref.length;
37269
        *pubKey = dataASN[PUBKEYASN_IDX_PUBKEY].data.ref.data;
37270
    }
37271
37272
    FREE_ASNGETDATA(dataASN, NULL);
37273
#endif /* WOLFSSL_ASN_TEMPLATE */
37274
    return ret;
37275
}
37276
37277
int DecodeAsymKeyPublic(const byte* input, word32* inOutIdx, word32 inSz,
37278
    byte* pubKey, word32* pubKeyLen, int keyType)
37279
{
37280
    int ret = 0;
37281
    const byte* pubKeyPtr = NULL;
37282
    word32 pubKeyPtrLen = 0;
37283
37284
    if (pubKey == NULL) {
37285
        ret = BAD_FUNC_ARG;
37286
    }
37287
37288
    if (ret == 0) {
37289
        ret = DecodeAsymKeyPublic_Assign(input, inOutIdx, inSz, &pubKeyPtr,
37290
            &pubKeyPtrLen, &keyType);
37291
    }
37292
    if ((ret == 0) && (pubKeyPtrLen > *pubKeyLen)) {
37293
        ret = BUFFER_E;
37294
    }
37295
    if ((ret == 0) && (pubKeyPtr != NULL)) {
37296
        XMEMCPY(pubKey, pubKeyPtr, pubKeyPtrLen);
37297
        *pubKeyLen = pubKeyPtrLen;
37298
    }
37299
37300
    return ret;
37301
}
37302
#endif /* HAVE_ED25519 || etc... ||  HAVE_DILITHIUM || HAVE_SPHINCS */
37303
#endif /* WC_ENABLE_ASYM_KEY_IMPORT */
37304
37305
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
37306
int wc_Ed25519PrivateKeyDecode(const byte* input, word32* inOutIdx,
37307
                               ed25519_key* key, word32 inSz)
37308
{
37309
    int ret;
37310
    byte privKey[ED25519_KEY_SIZE], pubKey[2*ED25519_PUB_KEY_SIZE+1];
37311
    word32 privKeyLen = (word32)sizeof(privKey);
37312
    word32 pubKeyLen = (word32)sizeof(pubKey);
37313
37314
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
37315
        return BAD_FUNC_ARG;
37316
    }
37317
37318
    ret = DecodeAsymKey(input, inOutIdx, inSz, privKey, &privKeyLen,
37319
        pubKey, &pubKeyLen, ED25519k);
37320
    if (ret == 0) {
37321
        if (pubKeyLen == 0) {
37322
            ret = wc_ed25519_import_private_only(privKey, privKeyLen, key);
37323
        }
37324
        else {
37325
            ret = wc_ed25519_import_private_key(privKey, privKeyLen,
37326
                pubKey, pubKeyLen, key);
37327
        }
37328
    }
37329
    return ret;
37330
}
37331
37332
int wc_Ed25519PublicKeyDecode(const byte* input, word32* inOutIdx,
37333
                              ed25519_key* key, word32 inSz)
37334
{
37335
    int ret;
37336
    byte pubKey[2*ED25519_PUB_KEY_SIZE+1];
37337
    word32 pubKeyLen = (word32)sizeof(pubKey);
37338
37339
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
37340
        return BAD_FUNC_ARG;
37341
    }
37342
37343
    /* init pubKey */
37344
    XMEMSET(pubKey, 0, sizeof(pubKey));
37345
37346
    ret = DecodeAsymKeyPublic(input, inOutIdx, inSz,
37347
        pubKey, &pubKeyLen, ED25519k);
37348
    if (ret == 0) {
37349
        ret = wc_ed25519_import_public(pubKey, pubKeyLen, key);
37350
    }
37351
    return ret;
37352
}
37353
#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT */
37354
37355
#if defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_KEY_IMPORT)
37356
int wc_Curve25519PrivateKeyDecode(const byte* input, word32* inOutIdx,
37357
                               curve25519_key* key, word32 inSz)
37358
{
37359
    int ret;
37360
    byte privKey[CURVE25519_KEYSIZE];
37361
    word32 privKeyLen = CURVE25519_KEYSIZE;
37362
37363
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
37364
        return BAD_FUNC_ARG;
37365
    }
37366
37367
    ret = DecodeAsymKey(input, inOutIdx, inSz, privKey, &privKeyLen,
37368
        NULL, NULL, X25519k);
37369
    if (ret == 0) {
37370
        ret = wc_curve25519_import_private(privKey, privKeyLen, key);
37371
    }
37372
    return ret;
37373
}
37374
37375
int wc_Curve25519PublicKeyDecode(const byte* input, word32* inOutIdx,
37376
                              curve25519_key* key, word32 inSz)
37377
{
37378
    int ret;
37379
    byte pubKey[CURVE25519_KEYSIZE];
37380
    word32 pubKeyLen = (word32)sizeof(pubKey);
37381
37382
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
37383
        return BAD_FUNC_ARG;
37384
    }
37385
37386
    /* init pubKey */
37387
    XMEMSET(pubKey, 0, sizeof(pubKey));
37388
37389
    ret = DecodeAsymKeyPublic(input, inOutIdx, inSz,
37390
        pubKey, &pubKeyLen, X25519k);
37391
    if (ret == 0) {
37392
        ret = wc_curve25519_import_public(pubKey, pubKeyLen, key);
37393
    }
37394
    return ret;
37395
}
37396
37397
/* Decode Curve25519 key from DER format - can handle private only,
37398
 * public only, or private+public key pairs.
37399
 * return 0 on success, negative on error */
37400
int wc_Curve25519KeyDecode(const byte* input, word32* inOutIdx,
37401
                          curve25519_key* key, word32 inSz)
37402
{
37403
    int ret;
37404
    byte privKey[CURVE25519_KEYSIZE];
37405
    byte pubKey[CURVE25519_PUB_KEY_SIZE];
37406
    word32 privKeyLen = CURVE25519_KEYSIZE;
37407
    word32 pubKeyLen = CURVE25519_PUB_KEY_SIZE;
37408
37409
    /* sanity check */
37410
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
37411
        return BAD_FUNC_ARG;
37412
    }
37413
37414
    /* Try to decode as private key first (may include public) */
37415
    ret = DecodeAsymKey(input, inOutIdx, inSz, privKey, &privKeyLen,
37416
                        pubKey, &pubKeyLen, X25519k);
37417
37418
    if (ret == 0) {
37419
        /* Successfully decoded private key */
37420
        if (pubKeyLen > 0) {
37421
            /* Have both private and public */
37422
            ret = wc_curve25519_import_private_raw(privKey, privKeyLen,
37423
                                                   pubKey, pubKeyLen, key);
37424
        }
37425
        else {
37426
            /* Private only */
37427
            ret = wc_curve25519_import_private(privKey, privKeyLen, key);
37428
        }
37429
    }
37430
    else {
37431
        /* Try decoding as public key */
37432
        *inOutIdx = 0; /* Reset index */
37433
        pubKeyLen = CURVE25519_KEYSIZE;
37434
        ret = DecodeAsymKeyPublic(input, inOutIdx, inSz,
37435
                                  pubKey, &pubKeyLen, X25519k);
37436
        if (ret == 0) {
37437
            /* Successfully decoded public key */
37438
            ret = wc_curve25519_import_public(pubKey, pubKeyLen, key);
37439
        }
37440
    }
37441
37442
    return ret;
37443
}
37444
37445
#endif /* HAVE_CURVE25519 && HAVE_ED25519_KEY_IMPORT */
37446
37447
37448
#ifdef WC_ENABLE_ASYM_KEY_EXPORT
37449
37450
/* Build ASN.1 formatted key based on RFC 5958 (Asymmetric Key Packages)
37451
 *
37452
 * Pass NULL for output to get the size of the encoding.
37453
 *
37454
 * @param [in]  privKey      private key buffer
37455
 * @param [in]  privKeyLen   private key buffer length
37456
 * @param [in]  pubKey       public key buffer (optional)
37457
 * @param [in]  pubKeyLen    public key buffer length
37458
 * @param [out] output       Buffer to put encoded data in (optional)
37459
 * @param [in]  outLen       Size of buffer in bytes
37460
 * @param [in]  keyType      is "enum Key_Sum" like ED25519k
37461
 * @return  Size of encoded data in bytes on success
37462
 * @return  BAD_FUNC_ARG when key is NULL.
37463
 * @return  MEMORY_E when dynamic memory allocation failed.
37464
 */
37465
int SetAsymKeyDer(const byte* privKey, word32 privKeyLen,
37466
    const byte* pubKey, word32 pubKeyLen,
37467
    byte* output, word32 outLen, int keyType)
37468
{
37469
    int ret = 0;
37470
#ifndef WOLFSSL_ASN_TEMPLATE
37471
    word32 idx = 0, seqSz, verSz, algoSz, privSz, pubSz = 0, sz;
37472
#else
37473
    DECL_ASNSETDATA(dataASN, privateKeyASN_Length);
37474
    int sz = 0;
37475
#endif
37476
37477
    /* validate parameters */
37478
    if (privKey == NULL) {
37479
        return BAD_FUNC_ARG;
37480
    }
37481
    if (output != NULL && outLen == 0) {
37482
        return BUFFER_E;
37483
    }
37484
37485
#ifndef WOLFSSL_ASN_TEMPLATE
37486
    /* calculate size */
37487
    if (pubKey) {
37488
        pubSz = 2 + pubKeyLen;
37489
    }
37490
    privSz = 2 + 2 + privKeyLen;
37491
    algoSz = SetAlgoID(keyType, NULL, oidKeyType, 0);
37492
    verSz  = 3; /* version is 3 bytes (enum + id + version(byte)) */
37493
    seqSz  = SetSequence(verSz + algoSz + privSz + pubSz, NULL);
37494
    sz = seqSz + verSz + algoSz + privSz + pubSz;
37495
37496
    /* checkout output size */
37497
    if (output != NULL && sz > outLen) {
37498
        ret = BAD_FUNC_ARG;
37499
    }
37500
37501
    if (ret == 0 && output != NULL) {
37502
        /* write out */
37503
        /* seq */
37504
        seqSz = SetSequence(verSz + algoSz + privSz + pubSz, output);
37505
        idx = seqSz;
37506
        /* ver */
37507
        SetMyVersion(0, output + idx, FALSE);
37508
        idx += verSz;
37509
        /* algo */
37510
        algoSz = SetAlgoID(keyType, output + idx, oidKeyType, 0);
37511
        idx += algoSz;
37512
        /* privKey */
37513
        idx += SetOctetString(2 + privKeyLen, output + idx);
37514
        idx += SetOctetString(privKeyLen, output + idx);
37515
        XMEMCPY(output + idx, privKey, privKeyLen);
37516
        idx += privKeyLen;
37517
        /* pubKey */
37518
        if (pubKey) {
37519
            idx += SetHeader(ASN_CONTEXT_SPECIFIC | ASN_ASYMKEY_PUBKEY |
37520
                             1, pubKeyLen, output + idx, 0);
37521
            XMEMCPY(output + idx, pubKey, pubKeyLen);
37522
            idx += pubKeyLen;
37523
        }
37524
        sz = idx;
37525
    }
37526
    if (ret == 0) {
37527
        /* Return size of encoding. */
37528
        ret = (int)sz;
37529
    }
37530
#else
37531
37532
    CALLOC_ASNSETDATA(dataASN, privateKeyASN_Length, ret, NULL);
37533
37534
    if (ret == 0) {
37535
        /* Set version = 0 */
37536
        SetASN_Int8Bit(&dataASN[PRIVKEYASN_IDX_VER], 0);
37537
        /* Set OID. */
37538
        SetASN_OID(&dataASN[PRIVKEYASN_IDX_PKEYALGO_OID], (word32)keyType,
37539
                   oidKeyType);
37540
        /* Leave space for private key. */
37541
        SetASN_Buffer(&dataASN[PRIVKEYASN_IDX_PKEY_CURVEPKEY], NULL, privKeyLen);
37542
        /* Don't write out attributes. */
37543
        dataASN[PRIVKEYASN_IDX_ATTRS].noOut = 1;
37544
        /* Don't write sequence. */
37545
        dataASN[PRIVKEYASN_IDX_PKEY_MLDSASEQ].noOut = 1;
37546
        if (pubKey) {
37547
            /* Leave space for public key. */
37548
            SetASN_Buffer(&dataASN[PRIVKEYASN_IDX_PUBKEY], NULL, pubKeyLen);
37549
        }
37550
        else {
37551
            /* Don't put out public part. */
37552
            SetASNItem_NoOutNode(dataASN, privateKeyASN, PRIVKEYASN_IDX_PUBKEY,
37553
                    privateKeyASN_Length);
37554
        }
37555
37556
        /* Calculate the size of encoding. */
37557
        ret = SizeASN_Items(privateKeyASN, dataASN, privateKeyASN_Length, &sz);
37558
    }
37559
37560
    /* Check buffer is big enough. */
37561
    if ((ret == 0) && (output != NULL) && (sz > (int)outLen)) {
37562
        ret = BAD_FUNC_ARG;
37563
    }
37564
    if ((ret == 0) && (output != NULL)) {
37565
        /* Encode private key. */
37566
        SetASN_Items(privateKeyASN, dataASN, privateKeyASN_Length, output);
37567
37568
        /* Put private value into space provided. */
37569
        XMEMCPY((byte*)dataASN[PRIVKEYASN_IDX_PKEY_CURVEPKEY].data.buffer.data,
37570
                privKey, privKeyLen);
37571
37572
        if (pubKey != NULL) {
37573
            /* Put public value into space provided. */
37574
            XMEMCPY((byte*)dataASN[PRIVKEYASN_IDX_PUBKEY].data.buffer.data,
37575
                    pubKey, pubKeyLen);
37576
        }
37577
    }
37578
    if (ret == 0) {
37579
        /* Return size of encoding. */
37580
        ret = sz;
37581
    }
37582
37583
    FREE_ASNSETDATA(dataASN, NULL);
37584
#endif
37585
    return ret;
37586
}
37587
#endif /* WC_ENABLE_ASYM_KEY_EXPORT */
37588
37589
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
37590
/* Write a Private ED25519 key, including public to DER format,
37591
 * length on success else < 0 */
37592
int wc_Ed25519KeyToDer(ed25519_key* key, byte* output, word32 inLen)
37593
{
37594
    if (key == NULL) {
37595
        return BAD_FUNC_ARG;
37596
    }
37597
    return SetAsymKeyDer(key->k, ED25519_KEY_SIZE,
37598
        key->p, ED25519_PUB_KEY_SIZE, output, inLen, ED25519k);
37599
}
37600
37601
/* Write only private ED25519 key to DER format,
37602
 * length on success else < 0 */
37603
int wc_Ed25519PrivateKeyToDer(ed25519_key* key, byte* output, word32 inLen)
37604
{
37605
    if (key == NULL) {
37606
        return BAD_FUNC_ARG;
37607
    }
37608
    return SetAsymKeyDer(key->k, ED25519_KEY_SIZE,
37609
        NULL, 0, output, inLen, ED25519k);
37610
}
37611
#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_EXPORT */
37612
37613
#if defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_KEY_EXPORT)
37614
/* Write only private Curve25519 key to DER format,
37615
 * length on success else < 0 */
37616
int wc_Curve25519PrivateKeyToDer(curve25519_key* key, byte* output,
37617
                                 word32 inLen)
37618
{
37619
    int    ret;
37620
    byte   privKey[CURVE25519_KEYSIZE];
37621
    word32 privKeyLen = CURVE25519_KEYSIZE;
37622
37623
    if (key == NULL) {
37624
        return BAD_FUNC_ARG;
37625
    }
37626
37627
    ret = wc_curve25519_export_private_raw(key, privKey, &privKeyLen);
37628
    if (ret == 0) {
37629
        ret = SetAsymKeyDer(privKey, privKeyLen, NULL, 0, output, inLen,
37630
            X25519k);
37631
    }
37632
    return ret;
37633
}
37634
37635
/* Write a public Curve25519 key to DER format,
37636
 * length on success else < 0 */
37637
int wc_Curve25519PublicKeyToDer(curve25519_key* key, byte* output, word32 inLen,
37638
                             int withAlg)
37639
{
37640
    int    ret;
37641
    byte   pubKey[CURVE25519_PUB_KEY_SIZE];
37642
    word32 pubKeyLen = (word32)sizeof(pubKey);
37643
37644
    if (key == NULL) {
37645
        return BAD_FUNC_ARG;
37646
    }
37647
37648
    ret = wc_curve25519_export_public(key, pubKey, &pubKeyLen);
37649
    if (ret == 0) {
37650
        ret = SetAsymKeyDerPublic(pubKey, pubKeyLen, output, inLen,
37651
            X25519k, withAlg);
37652
    }
37653
    return ret;
37654
}
37655
37656
/* Export Curve25519 key to DER format - handles private only, public only,
37657
 * or private+public key pairs based on what's set in the key structure.
37658
 * Returns length written on success, negative on error */
37659
int wc_Curve25519KeyToDer(curve25519_key* key, byte* output, word32 inLen,
37660
                          int withAlg)
37661
{
37662
    int ret;
37663
    byte privKey[CURVE25519_KEYSIZE];
37664
    byte pubKey[CURVE25519_PUB_KEY_SIZE];
37665
    word32 privKeyLen = CURVE25519_KEYSIZE;
37666
    word32 pubKeyLen = CURVE25519_PUB_KEY_SIZE;
37667
37668
    if (key == NULL) {
37669
        return BAD_FUNC_ARG;
37670
    }
37671
37672
    /* Check what we have in the key structure */
37673
    if (key->privSet) {
37674
        /* Export private key to buffer */
37675
        ret = wc_curve25519_export_private_raw(key, privKey, &privKeyLen);
37676
        if (ret != 0) {
37677
            return ret;
37678
        }
37679
37680
        if (key->pubSet) {
37681
            /* Export public key if available */
37682
            ret = wc_curve25519_export_public(key, pubKey, &pubKeyLen);
37683
            if (ret != 0) {
37684
                return ret;
37685
            }
37686
            /* Export both private and public */
37687
            ret = SetAsymKeyDer(privKey, privKeyLen,
37688
                                pubKey, pubKeyLen,
37689
                                output, inLen, X25519k);
37690
        }
37691
        else {
37692
            /* Export private only */
37693
            ret = SetAsymKeyDer(privKey, privKeyLen,
37694
                                NULL, 0,
37695
                                output, inLen, X25519k);
37696
        }
37697
    }
37698
    else if (key->pubSet) {
37699
        /* Export public key only */
37700
        ret = wc_curve25519_export_public(key, pubKey, &pubKeyLen);
37701
        if (ret == 0) {
37702
            ret = SetAsymKeyDerPublic(pubKey, pubKeyLen,
37703
                                      output, inLen, X25519k, withAlg);
37704
        }
37705
    }
37706
    else {
37707
        /* Neither public nor private key is set */
37708
        ret = BAD_FUNC_ARG;
37709
    }
37710
37711
    return ret;
37712
}
37713
#endif /* HAVE_CURVE25519 && HAVE_CURVE25519_KEY_EXPORT */
37714
37715
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)
37716
int wc_Ed448PrivateKeyDecode(const byte* input, word32* inOutIdx,
37717
                               ed448_key* key, word32 inSz)
37718
{
37719
    int ret;
37720
    byte privKey[ED448_KEY_SIZE], pubKey[ED448_PUB_KEY_SIZE];
37721
    word32 privKeyLen = (word32)sizeof(privKey);
37722
    word32 pubKeyLen = (word32)sizeof(pubKey);
37723
37724
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
37725
        return BAD_FUNC_ARG;
37726
    }
37727
37728
    ret = DecodeAsymKey(input, inOutIdx, inSz, privKey, &privKeyLen,
37729
        pubKey, &pubKeyLen, ED448k);
37730
    if (ret == 0) {
37731
        if (pubKeyLen == 0) {
37732
            ret = wc_ed448_import_private_only(privKey, privKeyLen, key);
37733
        }
37734
        else {
37735
            ret = wc_ed448_import_private_key(privKey, privKeyLen,
37736
                pubKey, pubKeyLen, key);
37737
        }
37738
    }
37739
    return ret;
37740
}
37741
37742
int wc_Ed448PublicKeyDecode(const byte* input, word32* inOutIdx,
37743
                              ed448_key* key, word32 inSz)
37744
{
37745
    int ret;
37746
    byte pubKey[2 * ED448_PUB_KEY_SIZE + 1];
37747
    word32 pubKeyLen = (word32)sizeof(pubKey);
37748
37749
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
37750
        return BAD_FUNC_ARG;
37751
    }
37752
37753
    ret = DecodeAsymKeyPublic(input, inOutIdx, inSz,
37754
        pubKey, &pubKeyLen, ED448k);
37755
    if (ret == 0) {
37756
        ret = wc_ed448_import_public(pubKey, pubKeyLen, key);
37757
    }
37758
    return ret;
37759
}
37760
#endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT */
37761
37762
#if defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_IMPORT)
37763
int wc_Curve448PrivateKeyDecode(const byte* input, word32* inOutIdx,
37764
                               curve448_key* key, word32 inSz)
37765
{
37766
    int ret;
37767
    byte privKey[CURVE448_KEY_SIZE];
37768
    word32 privKeyLen = CURVE448_KEY_SIZE;
37769
37770
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
37771
        return BAD_FUNC_ARG;
37772
    }
37773
37774
    ret = DecodeAsymKey(input, inOutIdx, inSz, privKey, &privKeyLen,
37775
        NULL, NULL, X448k);
37776
    if (ret == 0) {
37777
        ret = wc_curve448_import_private(privKey, privKeyLen, key);
37778
    }
37779
    return ret;
37780
}
37781
37782
int wc_Curve448PublicKeyDecode(const byte* input, word32* inOutIdx,
37783
                              curve448_key* key, word32 inSz)
37784
{
37785
    int ret;
37786
    byte pubKey[CURVE448_PUB_KEY_SIZE];
37787
    word32 pubKeyLen = (word32)sizeof(pubKey);
37788
37789
    if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
37790
        return BAD_FUNC_ARG;
37791
    }
37792
37793
    /* init pubKey */
37794
    XMEMSET(pubKey, 0, sizeof(pubKey));
37795
37796
    ret = DecodeAsymKeyPublic(input, inOutIdx, inSz,
37797
        pubKey, &pubKeyLen, X448k);
37798
    if (ret == 0) {
37799
        ret = wc_curve448_import_public(pubKey, pubKeyLen, key);
37800
    }
37801
    return ret;
37802
}
37803
#endif /* HAVE_CURVE448 && HAVE_ED448_KEY_IMPORT */
37804
37805
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
37806
/* Write a Private ecc key, including public to DER format,
37807
 * length on success else < 0 */
37808
int wc_Ed448KeyToDer(ed448_key* key, byte* output, word32 inLen)
37809
{
37810
    if (key == NULL) {
37811
        return BAD_FUNC_ARG;
37812
    }
37813
    return SetAsymKeyDer(key->k, ED448_KEY_SIZE,
37814
        key->p, ED448_KEY_SIZE, output, inLen, ED448k);
37815
}
37816
37817
/* Write only private ecc key to DER format,
37818
 * length on success else < 0 */
37819
int wc_Ed448PrivateKeyToDer(ed448_key* key, byte* output, word32 inLen)
37820
{
37821
    if (key == NULL) {
37822
        return BAD_FUNC_ARG;
37823
    }
37824
    return SetAsymKeyDer(key->k, ED448_KEY_SIZE,
37825
        NULL, 0, output, inLen, ED448k);
37826
}
37827
37828
#endif /* HAVE_ED448 && HAVE_ED448_KEY_EXPORT */
37829
37830
#if defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_EXPORT)
37831
/* Write private Curve448 key to DER format,
37832
 * length on success else < 0 */
37833
int wc_Curve448PrivateKeyToDer(curve448_key* key, byte* output, word32 inLen)
37834
{
37835
    int    ret;
37836
    byte   privKey[CURVE448_KEY_SIZE];
37837
    word32 privKeyLen = CURVE448_KEY_SIZE;
37838
37839
    if (key == NULL) {
37840
        return BAD_FUNC_ARG;
37841
    }
37842
37843
    ret = wc_curve448_export_private_raw(key, privKey, &privKeyLen);
37844
    if (ret == 0) {
37845
        ret = SetAsymKeyDer(privKey, privKeyLen, NULL, 0, output, inLen,
37846
            X448k);
37847
    }
37848
    return ret;
37849
}
37850
/* Write a public Curve448 key to DER format,
37851
 * length on success else < 0 */
37852
int wc_Curve448PublicKeyToDer(curve448_key* key, byte* output, word32 inLen,
37853
                             int withAlg)
37854
{
37855
    int    ret;
37856
    byte   pubKey[CURVE448_PUB_KEY_SIZE];
37857
    word32 pubKeyLen = (word32)sizeof(pubKey);
37858
37859
    if (key == NULL) {
37860
        return BAD_FUNC_ARG;
37861
    }
37862
37863
    ret = wc_curve448_export_public(key, pubKey, &pubKeyLen);
37864
    if (ret == 0) {
37865
        ret = SetAsymKeyDerPublic(pubKey, pubKeyLen, output, inLen,
37866
            X448k, withAlg);
37867
    }
37868
    return ret;
37869
}
37870
#endif /* HAVE_CURVE448 && HAVE_CURVE448_KEY_EXPORT */
37871
37872
37873
#ifndef WOLFSSL_ASN_TEMPLATE
37874
#if (defined(HAVE_OCSP) || defined(HAVE_CRL)) && !defined(WOLFCRYPT_ONLY)
37875
37876
/* Get raw Date only, no processing, 0 on success */
37877
static int GetBasicDate(const byte* source, word32* idx, byte* date,
37878
                        byte* format, int maxIdx)
37879
{
37880
    int    ret, length;
37881
    const byte *datePtr = NULL;
37882
37883
    WOLFSSL_ENTER("GetBasicDate");
37884
37885
    ret = GetDateInfo(source, idx, &datePtr, format, &length, maxIdx);
37886
    if (ret < 0)
37887
        return ret;
37888
37889
    XMEMCPY(date, datePtr, length);
37890
37891
    return 0;
37892
}
37893
37894
#endif /* HAVE_OCSP || HAVE_CRL */
37895
#endif /* WOLFSSL_ASN_TEMPLATE */
37896
37897
37898
#if defined(HAVE_OCSP) && !defined(WOLFCRYPT_ONLY)
37899
37900
#ifndef WOLFSSL_ASN_TEMPLATE
37901
static int GetEnumerated(const byte* input, word32* inOutIdx, int *value,
37902
        int sz)
37903
{
37904
    word32 idx = *inOutIdx;
37905
    word32 len;
37906
    byte   tag;
37907
37908
    WOLFSSL_ENTER("GetEnumerated");
37909
37910
    *value = 0;
37911
37912
    if (GetASNTag(input, &idx, &tag, sz) < 0)
37913
        return ASN_PARSE_E;
37914
37915
    if (tag != ASN_ENUMERATED)
37916
        return ASN_PARSE_E;
37917
37918
    if ((int)idx >= sz)
37919
        return BUFFER_E;
37920
37921
    len = input[idx++];
37922
    if (len > 4 || (int)(len + idx) > sz)
37923
        return ASN_PARSE_E;
37924
37925
    while (len--) {
37926
        *value  = *value << 8 | input[idx++];
37927
    }
37928
37929
    *inOutIdx = idx;
37930
37931
    return *value;
37932
}
37933
#endif /* !WOLFSSL_ASN_TEMPLATE */
37934
37935
37936
#ifdef WOLFSSL_ASN_TEMPLATE
37937
/* ASN.1 template for OCSP single response.
37938
 * RFC 6960, 4.2.1 - ASN.1 Specification of the OCSP Response
37939
 */
37940
static const ASNItem singleResponseASN[] = {
37941
/* SEQ                   */ { 0, ASN_SEQUENCE, 1, 1, 0 },
37942
                                                      /* certId */
37943
/* CID_SEQ               */     { 1, ASN_SEQUENCE, 1, 0, 0 },
37944
                                                      /* certStatus - CHOICE */
37945
                                                      /* good              [0] IMPLICIT NULL */
37946
/* CS_GOOD               */     { 1, ASN_CONTEXT_SPECIFIC | 0, 0, 0, 2 },
37947
                                                      /* revoked           [1] IMPLICIT RevokedInfo */
37948
/* CS_REVOKED            */     { 1, ASN_CONTEXT_SPECIFIC | 1, 1, 1, 2 },
37949
                                                          /* revocationTime */
37950
/* CS_REVOKED_TIME       */         { 2, ASN_GENERALIZED_TIME, 0, 0, 0 },
37951
                                                          /* revocationReason  [0] EXPLICIT CRLReason OPTIONAL */
37952
/* CS_REVOKED_REASON     */         { 2, ASN_CONTEXT_SPECIFIC | 0, 1, 1, 1 },
37953
                                                              /* crlReason */
37954
/* CS_REVOKED_REASON_VAL */             { 3, ASN_ENUMERATED, 0, 0, 0 },
37955
                                                      /* unknown           [2] IMPLICIT UnknownInfo ::= NULL */
37956
/* UNKNOWN               */     { 1, ASN_CONTEXT_SPECIFIC | 2, 0, 0, 2 },
37957
37958
                                                      /* thisUpdate */
37959
/* THISUPDATE_GT         */     { 1, ASN_GENERALIZED_TIME, 0, 0, 0 },
37960
                                                      /* nextUpdate */
37961
/* NEXTUPDATE            */     { 1, ASN_CONTEXT_SPECIFIC | 0, 1, 1, 1 },
37962
/* NEXTUPDATE_GT         */         { 2, ASN_GENERALIZED_TIME, 0, 0, 0 },
37963
                                                      /* singleExtensions */
37964
/* EXT                   */     { 1, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 1 },
37965
};
37966
enum {
37967
    SINGLERESPONSEASN_IDX_SEQ = 0,
37968
    SINGLERESPONSEASN_IDX_CID_SEQ,
37969
    SINGLERESPONSEASN_IDX_CS_GOOD,
37970
    SINGLERESPONSEASN_IDX_CS_REVOKED,
37971
    SINGLERESPONSEASN_IDX_CS_REVOKED_TIME,
37972
    SINGLERESPONSEASN_IDX_CS_REVOKED_REASON,
37973
    SINGLERESPONSEASN_IDX_CS_REVOKED_REASON_VAL,
37974
    SINGLERESPONSEASN_IDX_UNKNOWN,
37975
    SINGLERESPONSEASN_IDX_THISUPDATE_GT,
37976
    SINGLERESPONSEASN_IDX_NEXTUPDATE,
37977
    SINGLERESPONSEASN_IDX_NEXTUPDATE_GT,
37978
    SINGLERESPONSEASN_IDX_EXT,
37979
};
37980
37981
/* Number of items in ASN.1 template for OCSP single response. */
37982
#define singleResponseASN_Length (sizeof(singleResponseASN) / sizeof(ASNItem))
37983
37984
static const ASNItem certIDASNItems[] = {
37985
                                                            /* hashAlgorithm */
37986
/* CID_HASHALGO_SEQ      */         { 0, ASN_SEQUENCE, 1, 1, 0 },
37987
/* CID_HASHALGO_OID      */             { 1, ASN_OBJECT_ID, 0, 0, 0 },
37988
/* CID_HASHALGO_NULL     */             { 1, ASN_TAG_NULL, 0, 0, 1 },
37989
                                                          /* issuerNameHash */
37990
/* CID_ISSUERHASH        */         { 0, ASN_OCTET_STRING, 0, 0, 0 },
37991
                                                          /* issuerKeyHash */
37992
/* CID_ISSUERKEYHASH     */         { 0, ASN_OCTET_STRING, 0, 0, 0 },
37993
                                                          /* serialNumber */
37994
/* CID_SERIAL            */         { 0, ASN_INTEGER, 0, 0, 0 },
37995
};
37996
37997
enum {
37998
    CERTIDASN_IDX_CID_HASHALGO_SEQ,
37999
    CERTIDASN_IDX_CID_HASHALGO_OID,
38000
    CERTIDASN_IDX_CID_HASHALGO_NULL,
38001
    CERTIDASN_IDX_CID_ISSUERHASH,
38002
    CERTIDASN_IDX_CID_ISSUERKEYHASH,
38003
    CERTIDASN_IDX_CID_SERIAL,
38004
};
38005
38006
#define certidasn_Length (sizeof(certIDASNItems) / sizeof(ASNItem))
38007
#endif
38008
38009
#ifndef WOLFSSL_ASN_TEMPLATE
38010
static int OcspDecodeCertIDInt(const byte* input, word32* inOutIdx, word32 inSz,
38011
                 OcspEntry* entry)
38012
{
38013
    int length;
38014
    word32 oid;
38015
    int ret;
38016
    /* Hash algorithm */
38017
    ret = GetAlgoId(input, inOutIdx, &oid, oidHashType, inSz);
38018
    if (ret < 0)
38019
        return ret;
38020
    entry->hashAlgoOID = oid;
38021
    /* Save reference to the hash of CN */
38022
    ret = GetOctetString(input, inOutIdx, &length, inSz);
38023
    if (ret < 0)
38024
        return ret;
38025
    if (length != OCSP_DIGEST_SIZE)
38026
        return ASN_PARSE_E;
38027
    XMEMCPY(entry->issuerHash, input + *inOutIdx, length);
38028
    *inOutIdx += length;
38029
    /* Save reference to the hash of the issuer public key */
38030
    ret = GetOctetString(input, inOutIdx, &length, inSz);
38031
    if (ret < 0)
38032
        return ret;
38033
    if (length != OCSP_DIGEST_SIZE)
38034
        return ASN_PARSE_E;
38035
    XMEMCPY(entry->issuerKeyHash, input + *inOutIdx, length);
38036
    *inOutIdx += length;
38037
38038
    /* Get serial number */
38039
    if (wc_GetSerialNumber(input, inOutIdx, entry->status->serial,
38040
                        &entry->status->serialSz, inSz) < 0)
38041
        return ASN_PARSE_E;
38042
    return 0;
38043
}
38044
#else
38045
static int OcspDecodeCertIDInt(const byte* input, word32* inOutIdx, word32 inSz,
38046
                 OcspEntry* entry)
38047
{
38048
    DECL_ASNGETDATA(dataASN, certidasn_Length);
38049
    word32 issuerKeyHashLen = OCSP_DIGEST_SIZE;
38050
    word32 issuerHashLen = OCSP_DIGEST_SIZE;
38051
    word32 serialSz = EXTERNAL_SERIAL_SIZE;
38052
    word32 digestSz;
38053
    int ret = 0;
38054
38055
    WOLFSSL_ENTER("DecodeCertIdTemplate");
38056
    CALLOC_ASNGETDATA(dataASN, certidasn_Length, ret, NULL);
38057
    if (ret != 0)
38058
        return ret;
38059
38060
    GetASN_OID(&dataASN[CERTIDASN_IDX_CID_HASHALGO_OID], oidHashType);
38061
    GetASN_Buffer(&dataASN[CERTIDASN_IDX_CID_ISSUERHASH], entry->issuerHash,
38062
        &issuerHashLen);
38063
    GetASN_Buffer(&dataASN[CERTIDASN_IDX_CID_ISSUERKEYHASH],
38064
        entry->issuerKeyHash, &issuerKeyHashLen);
38065
    GetASN_Buffer(&dataASN[CERTIDASN_IDX_CID_SERIAL], entry->status->serial,
38066
                    &serialSz);
38067
    ret = GetASN_Items(certIDASNItems, dataASN, certidasn_Length,
38068
                1, input, inOutIdx, inSz);
38069
    if (ret != 0) {
38070
       goto out;
38071
    }
38072
    entry->status->serialSz = serialSz;
38073
    entry->hashAlgoOID =
38074
        dataASN[CERTIDASN_IDX_CID_HASHALGO_OID].data.oid.sum;
38075
    digestSz = wc_HashGetDigestSize(wc_OidGetHash(entry->hashAlgoOID));
38076
    if (issuerKeyHashLen != digestSz || issuerHashLen != digestSz) {
38077
        ret = ASN_PARSE_E;
38078
        goto out;
38079
    }
38080
out:
38081
    FREE_ASNGETDATA(dataASN, NULL);
38082
    return ret;
38083
}
38084
#endif
38085
38086
int OcspDecodeCertID(const byte *input, word32 *inOutIdx, word32 inSz,
38087
    OcspEntry *entry)
38088
{
38089
    word32 seqIdx = 0;
38090
    int len = inSz;
38091
    int ret;
38092
38093
#ifndef WOLFSSL_ASN_TEMPLATE
38094
    ret = GetSequence(input, inOutIdx, &len, inSz);
38095
#else
38096
    ret = GetASN_Sequence(input, inOutIdx, &len, inSz, 0);
38097
#endif
38098
    if (ret < 0)
38099
        return ASN_PARSE_E;
38100
    ret = OcspDecodeCertIDInt(input + *inOutIdx, &seqIdx, len, entry);
38101
    if (ret < 0)
38102
        return ASN_PARSE_E;
38103
    if (seqIdx != (word32)len)
38104
        return ASN_PARSE_E;
38105
    *inOutIdx += len;
38106
38107
    return 0;
38108
}
38109
38110
38111
static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size,
38112
                                int wrapperSz, OcspEntry* single)
38113
{
38114
#ifndef WOLFSSL_ASN_TEMPLATE
38115
    word32 idx = *ioIndex, prevIndex, localIdx, certIdIdx;
38116
    int length;
38117
    int ret;
38118
    byte tag;
38119
38120
    WOLFSSL_ENTER("DecodeSingleResponse");
38121
38122
    prevIndex = idx;
38123
38124
    /* Wrapper around the Single Response */
38125
    if (GetSequence(source, &idx, &length, size) < 0)
38126
        return ASN_PARSE_E;
38127
38128
    /* Wrapper around the CertID */
38129
    certIdIdx = idx;
38130
    if (GetSequence(source, &idx, &length, size) < 0)
38131
        return ASN_PARSE_E;
38132
    single->rawCertId = source + certIdIdx;
38133
    ret = OcspDecodeCertIDInt(source, &idx, size, single);
38134
    if (ret < 0)
38135
        return ASN_PARSE_E;
38136
    single->rawCertIdSize = idx - certIdIdx;
38137
38138
    if (idx >= size)
38139
        return BUFFER_E;
38140
38141
    /* CertStatus */
38142
    switch (source[idx++])
38143
    {
38144
        case (ASN_CONTEXT_SPECIFIC | CERT_GOOD):
38145
            single->status->status = CERT_GOOD;
38146
            idx++;
38147
            break;
38148
        case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_REVOKED):
38149
            single->status->status = CERT_REVOKED;
38150
            if (GetLength(source, &idx, &length, size) < 0)
38151
                return ASN_PARSE_E;
38152
            idx += length;
38153
            break;
38154
        case (ASN_CONTEXT_SPECIFIC | CERT_UNKNOWN):
38155
            single->status->status = CERT_UNKNOWN;
38156
            idx++;
38157
            break;
38158
        default:
38159
            return ASN_PARSE_E;
38160
    }
38161
38162
    if (idx >= size)
38163
        return BUFFER_E;
38164
38165
#ifdef WOLFSSL_OCSP_PARSE_STATUS
38166
    single->status->thisDateAsn = source + idx;
38167
    localIdx = 0;
38168
    if (GetDateInfo(single->status->thisDateAsn, &localIdx, NULL,
38169
                    (byte*)&single->status->thisDateParsed.type,
38170
                    &single->status->thisDateParsed.length, size - idx) < 0)
38171
        return ASN_PARSE_E;
38172
38173
    if (idx + localIdx >= size)
38174
        return BUFFER_E;
38175
38176
    XMEMCPY(single->status->thisDateParsed.data,
38177
            single->status->thisDateAsn + localIdx - single->status->thisDateParsed.length,
38178
            single->status->thisDateParsed.length);
38179
#endif
38180
    if (GetBasicDate(source, &idx, single->status->thisDate,
38181
                     &single->status->thisDateFormat, size) < 0)
38182
        return ASN_PARSE_E;
38183
38184
#ifndef NO_ASN_TIME_CHECK
38185
#ifndef WOLFSSL_NO_OCSP_DATE_CHECK
38186
    if ((! AsnSkipDateCheck) && !XVALIDATE_DATE(single->status->thisDate,
38187
        single->status->thisDateFormat, ASN_BEFORE))
38188
        return ASN_BEFORE_DATE_E;
38189
#endif
38190
#endif
38191
38192
    /* The following items are optional. Only check for them if there is more
38193
     * unprocessed data in the singleResponse wrapper. */
38194
    localIdx = idx;
38195
    if (((int)(idx - prevIndex) < wrapperSz) &&
38196
        GetASNTag(source, &localIdx, &tag, size) == 0 &&
38197
        tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
38198
    {
38199
        idx++;
38200
        if (GetLength(source, &idx, &length, size) < 0)
38201
            return ASN_PARSE_E;
38202
#ifdef WOLFSSL_OCSP_PARSE_STATUS
38203
        single->status->nextDateAsn = source + idx;
38204
        localIdx = 0;
38205
        if (GetDateInfo(single->status->nextDateAsn, &localIdx, NULL,
38206
                        (byte*)&single->status->nextDateParsed.type,
38207
                        &single->status->nextDateParsed.length, size - idx) < 0)
38208
            return ASN_PARSE_E;
38209
38210
        if (idx + localIdx >= size)
38211
            return BUFFER_E;
38212
38213
        XMEMCPY(single->status->nextDateParsed.data,
38214
                single->status->nextDateAsn + localIdx - single->status->nextDateParsed.length,
38215
                single->status->nextDateParsed.length);
38216
#endif
38217
        if (GetBasicDate(source, &idx, single->status->nextDate,
38218
                         &single->status->nextDateFormat, size) < 0)
38219
            return ASN_PARSE_E;
38220
38221
#ifndef NO_ASN_TIME_CHECK
38222
#ifndef WOLFSSL_NO_OCSP_DATE_CHECK
38223
        if ((! AsnSkipDateCheck) &&
38224
            !XVALIDATE_DATE(single->status->nextDate,
38225
                            single->status->nextDateFormat, ASN_AFTER))
38226
            return ASN_AFTER_DATE_E;
38227
#endif
38228
#endif
38229
    }
38230
38231
    /* Skip the optional extensions in singleResponse. */
38232
    localIdx = idx;
38233
    if (((int)(idx - prevIndex) < wrapperSz) &&
38234
        GetASNTag(source, &localIdx, &tag, size) == 0 &&
38235
        tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
38236
    {
38237
        idx++;
38238
        if (GetLength(source, &idx, &length, size) < 0)
38239
            return ASN_PARSE_E;
38240
        idx += length;
38241
    }
38242
38243
    *ioIndex = idx;
38244
38245
    return 0;
38246
#else /* WOLFSSL_ASN_TEMPLATE */
38247
    DECL_ASNGETDATA(dataASN, singleResponseASN_Length);
38248
    int ret = 0;
38249
    CertStatus* cs = NULL;
38250
    word32 thisDateLen;
38251
    word32 nextDateLen;
38252
    word32 certIdSeqIdx;
38253
38254
    (void)wrapperSz;
38255
38256
    WOLFSSL_ENTER("DecodeSingleResponse");
38257
38258
    CALLOC_ASNGETDATA(dataASN, singleResponseASN_Length, ret, NULL);
38259
38260
    if (ret == 0) {
38261
        cs = single->status;
38262
        /* Set maximum lengths for data. */
38263
        thisDateLen      = MAX_DATE_SIZE;
38264
        nextDateLen      = MAX_DATE_SIZE;
38265
38266
        /* Set OID type, buffers to hold data and variables to hold size. */
38267
        GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_THISUPDATE_GT],
38268
                cs->thisDate, &thisDateLen);
38269
        GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_NEXTUPDATE_GT],
38270
                cs->nextDate, &nextDateLen);
38271
        /* TODO: decode revoked time and reason. */
38272
        /* Decode OCSP single response. */
38273
        ret = GetASN_Items(singleResponseASN, dataASN, singleResponseASN_Length,
38274
                1, source, ioIndex, size);
38275
    }
38276
    if (ret == 0) {
38277
        certIdSeqIdx = 0;
38278
        ret = OcspDecodeCertIDInt(dataASN[SINGLERESPONSEASN_IDX_CID_SEQ].data.ref.data,
38279
            &certIdSeqIdx, dataASN[SINGLERESPONSEASN_IDX_CID_SEQ].data.ref.length, single);
38280
    }
38281
    if (ret == 0) {
38282
38283
        /* Determine status by which item was found. */
38284
        if (dataASN[SINGLERESPONSEASN_IDX_CS_GOOD].tag != 0) {
38285
            cs->status = CERT_GOOD;
38286
        }
38287
        if (dataASN[SINGLERESPONSEASN_IDX_CS_REVOKED].tag != 0) {
38288
            cs->status = CERT_REVOKED;
38289
        }
38290
        if (dataASN[SINGLERESPONSEASN_IDX_UNKNOWN].tag != 0) {
38291
            cs->status = CERT_UNKNOWN;
38292
        }
38293
38294
        /* Store the thisDate format - only one possible. */
38295
        cs->thisDateFormat = ASN_GENERALIZED_TIME;
38296
    #if !defined(NO_ASN_TIME_CHECK) && !defined(WOLFSSL_NO_OCSP_DATE_CHECK)
38297
        /* Check date is a valid string and ASN_BEFORE now. */
38298
        if ((! AsnSkipDateCheck) &&
38299
            !XVALIDATE_DATE(cs->thisDate, ASN_GENERALIZED_TIME, ASN_BEFORE))
38300
        {
38301
            ret = ASN_BEFORE_DATE_E;
38302
        }
38303
    #endif /* !NO_ASN_TIME_CHECK && !WOLFSSL_NO_OCSP_DATE_CHECK */
38304
    }
38305
#ifdef WOLFSSL_OCSP_PARSE_STATUS
38306
    if (ret == 0) {
38307
        /* Store ASN.1 version of thisDate. */
38308
        WOLFSSL_ASN1_TIME *at;
38309
        cs->thisDateAsn = GetASNItem_Addr(
38310
                dataASN[SINGLERESPONSEASN_IDX_THISUPDATE_GT], source);
38311
        at = &cs->thisDateParsed;
38312
        at->type = ASN_GENERALIZED_TIME;
38313
        XMEMCPY(at->data, cs->thisDate, thisDateLen);
38314
        at->length = (int)thisDateLen;
38315
    }
38316
#endif
38317
    if ((ret == 0) &&
38318
            (dataASN[SINGLERESPONSEASN_IDX_NEXTUPDATE_GT].tag != 0)) {
38319
        /* Store the nextDate format - only one possible. */
38320
        cs->nextDateFormat = ASN_GENERALIZED_TIME;
38321
    #if !defined(NO_ASN_TIME_CHECK) && !defined(WOLFSSL_NO_OCSP_DATE_CHECK)
38322
        /* Check date is a valid string and ASN_AFTER now. */
38323
        if ((! AsnSkipDateCheck) &&
38324
            !XVALIDATE_DATE(cs->nextDate, ASN_GENERALIZED_TIME, ASN_AFTER))
38325
        {
38326
            ret = ASN_AFTER_DATE_E;
38327
        }
38328
    #endif /* !NO_ASN_TIME_CHECK && !WOLFSSL_NO_OCSP_DATE_CHECK */
38329
    }
38330
#ifdef WOLFSSL_OCSP_PARSE_STATUS
38331
    if ((ret == 0) &&
38332
            (dataASN[SINGLERESPONSEASN_IDX_NEXTUPDATE_GT].tag != 0))
38333
    {
38334
        /* Store ASN.1 version of thisDate. */
38335
        WOLFSSL_ASN1_TIME *at;
38336
        cs->nextDateAsn = GetASNItem_Addr(
38337
                dataASN[SINGLERESPONSEASN_IDX_NEXTUPDATE_GT], source);
38338
        at = &cs->nextDateParsed;
38339
        at->type = ASN_GENERALIZED_TIME;
38340
        XMEMCPY(at->data, cs->nextDate, nextDateLen);
38341
        at->length = (int)nextDateLen;
38342
    }
38343
#endif
38344
    if (ret == 0) {
38345
        /* OcspEntry now used. */
38346
        single->used = 1;
38347
    }
38348
38349
    FREE_ASNGETDATA(dataASN, NULL);
38350
    return ret;
38351
#endif /* WOLFSSL_ASN_TEMPLATE */
38352
}
38353
38354
#ifdef WOLFSSL_ASN_TEMPLATE
38355
/* ASN.1 template for OCSP response extension header.
38356
 * RFC 6960, 4.2.1 - ASN.1 Specification of the OCSP Response
38357
 */
38358
static const ASNItem respExtHdrASN[] = {
38359
                                   /* responseExtensions */
38360
/* EXT     */    { 0, ASN_CONTEXT_SPECIFIC | 1, 1, 1, 0 },
38361
                                       /* extensions */
38362
/* EXT_SEQ */        { 1, ASN_SEQUENCE, 1, 1, 0 },
38363
};
38364
enum {
38365
    RESPEXTHDRASN_IDX_EXT = 0,
38366
    RESPEXTHDRASN_IDX_EXT_SEQ,
38367
};
38368
38369
/* Number of items in ASN.1 template for OCSP response extension header. */
38370
#define respExtHdrASN_Length (sizeof(respExtHdrASN) / sizeof(ASNItem))
38371
#endif
38372
38373
static int DecodeOcspRespExtensions(byte* source, word32* ioIndex,
38374
                                    OcspResponse* resp, word32 sz)
38375
{
38376
#ifndef WOLFSSL_ASN_TEMPLATE
38377
    word32 idx = *ioIndex;
38378
    int length;
38379
    int ext_bound; /* boundary index for the sequence of extensions */
38380
    word32 oid;
38381
    int ret;
38382
    byte tag;
38383
38384
    WOLFSSL_ENTER("DecodeOcspRespExtensions");
38385
38386
    if ((idx + 1) > sz)
38387
        return BUFFER_E;
38388
38389
    if (GetASNTag(source, &idx, &tag, sz) < 0)
38390
        return ASN_PARSE_E;
38391
38392
    if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
38393
        return ASN_PARSE_E;
38394
38395
    if (GetLength(source, &idx, &length, sz) < 0)
38396
        return ASN_PARSE_E;
38397
38398
    if (GetSequence(source, &idx, &length, sz) < 0)
38399
        return ASN_PARSE_E;
38400
38401
    ext_bound = idx + length;
38402
38403
    while (idx < (word32)ext_bound) {
38404
        word32 localIdx;
38405
38406
        if (GetSequence(source, &idx, &length, sz) < 0) {
38407
            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
38408
            return ASN_PARSE_E;
38409
        }
38410
38411
        oid = 0;
38412
        if (GetObjectId(source, &idx, &oid, oidOcspType, sz) < 0) {
38413
            WOLFSSL_MSG("\tfail: OBJECT ID");
38414
            return ASN_PARSE_E;
38415
        }
38416
38417
        /* check for critical flag */
38418
        if ((idx + 1) > (word32)sz) {
38419
            WOLFSSL_MSG("\tfail: malformed buffer");
38420
            return BUFFER_E;
38421
        }
38422
38423
        localIdx = idx;
38424
        if (GetASNTag(source, &localIdx, &tag, sz) == 0 && tag == ASN_BOOLEAN) {
38425
            WOLFSSL_MSG("\tfound optional critical flag, moving past");
38426
            ret = GetBoolean(source, &idx, sz);
38427
            if (ret < 0)
38428
                return ret;
38429
        }
38430
38431
        ret = GetOctetString(source, &idx, &length, sz);
38432
        if (ret < 0)
38433
            return ret;
38434
38435
        if (oid == OCSP_NONCE_OID) {
38436
            /* get data inside extra OCTET_STRING */
38437
            ret = GetOctetString(source, &idx, &length, sz);
38438
            if (ret < 0)
38439
                return ret;
38440
38441
            resp->nonce = source + idx;
38442
            resp->nonceSz = length;
38443
        }
38444
38445
        idx += length;
38446
    }
38447
38448
    *ioIndex = idx;
38449
    return 0;
38450
#else
38451
    /* certExtASN_Length is greater than respExtHdrASN_Length */
38452
    DECL_ASNGETDATA(dataASN, certExtASN_Length);
38453
    int ret = 0;
38454
    word32 idx = *ioIndex;
38455
    word32 maxIdx = 0;
38456
38457
    WOLFSSL_ENTER("DecodeOcspRespExtensions");
38458
38459
    CALLOC_ASNGETDATA(dataASN, certExtASN_Length, ret, resp->heap);
38460
38461
    if (ret == 0) {
38462
        /* Check for header and move past. */
38463
        ret = GetASN_Items(respExtHdrASN, dataASN, respExtHdrASN_Length, 0,
38464
            source, &idx, sz);
38465
    }
38466
    if (ret == 0) {
38467
        /* Keep end extensions index for total length check. */
38468
        maxIdx = idx + dataASN[RESPEXTHDRASN_IDX_EXT_SEQ].length;
38469
    }
38470
38471
    /* Step through all extensions. */
38472
    while ((ret == 0) && (idx < maxIdx)) {
38473
        /* Clear dynamic data, set OID type to expect. */
38474
        XMEMSET(dataASN, 0, sizeof(*dataASN) * certExtASN_Length);
38475
        GetASN_OID(&dataASN[CERTEXTASN_IDX_OID], oidOcspType);
38476
        /* TODO: check criticality. */
38477
        /* Decode OCSP response extension. */
38478
        ret = GetASN_Items(certExtASN, dataASN, certExtASN_Length, 0,
38479
                           source, &idx, sz);
38480
        if (ret == 0) {
38481
            word32 oid = dataASN[CERTEXTASN_IDX_OID].data.oid.sum;
38482
            int length = (int)dataASN[CERTEXTASN_IDX_VAL].length;
38483
38484
            if (oid == OCSP_NONCE_OID) {
38485
                /* Extract nonce data. */
38486
                ret = GetOctetString(source, &idx, &length, sz);
38487
                if (ret >= 0) {
38488
                    ret = 0;
38489
                    /* get data inside extra OCTET_STRING */
38490
                    resp->nonce = source + idx;
38491
                    resp->nonceSz = length;
38492
                }
38493
            }
38494
            /* Ignore all other extension types. */
38495
38496
            /* Skip over rest of extension. */
38497
            idx += (word32)length;
38498
        }
38499
    }
38500
38501
    /* Return index after extensions. */
38502
    *ioIndex = idx;
38503
38504
    FREE_ASNGETDATA(dataASN, resp->heap);
38505
    return ret;
38506
#endif
38507
}
38508
38509
#ifdef WOLFSSL_ASN_TEMPLATE
38510
/* ASN.1 template for OCSP ResponseData.
38511
 * RFC 6960, 4.2.1 - ASN.1 Specification of the OCSP Response
38512
 */
38513
static const ASNItem ocspRespDataASN[] = {
38514
/* SEQ         */    { 0, ASN_SEQUENCE, 1, 1, 0 },
38515
                                             /* version DEFAULT v1 */
38516
/* VER_PRESENT */        { 1, ASN_CONTEXT_SPECIFIC | 0, 1, 1, 1 },
38517
/* VER         */            { 2, ASN_INTEGER, 1, 0, 0 },
38518
                                             /* byName */
38519
/* BYNAME      */        { 1, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 2 },
38520
                                             /* byKey */
38521
/* BYKEY       */        { 1, ASN_CONTEXT_SPECIFIC | 2, 1, 1, 2 },
38522
/* BYKEY_OCT   */            { 2, ASN_OCTET_STRING, 0, 0, 0 },
38523
                                             /* producedAt */
38524
/* PA          */        { 1, ASN_GENERALIZED_TIME, 0, 0, 0, },
38525
                                             /* responses */
38526
/* RESP        */        { 1, ASN_SEQUENCE, 1, 0, 0 },
38527
                                             /* responseExtensions */
38528
/* RESPEXT     */        { 1, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 1 }
38529
};
38530
enum {
38531
    OCSPRESPDATAASN_IDX_SEQ = 0,
38532
    OCSPRESPDATAASN_IDX_VER_PRESENT,
38533
    OCSPRESPDATAASN_IDX_VER,
38534
    OCSPRESPDATAASN_IDX_BYNAME,
38535
    OCSPRESPDATAASN_IDX_BYKEY,
38536
    OCSPRESPDATAASN_IDX_BYKEY_OCT,
38537
    OCSPRESPDATAASN_IDX_PA,
38538
    OCSPRESPDATAASN_IDX_RESP,
38539
    OCSPRESPDATAASN_IDX_RESPEXT,
38540
};
38541
38542
/* Number of items in ASN.1 template for OCSP ResponseData. */
38543
#define ocspRespDataASN_Length (sizeof(ocspRespDataASN) / sizeof(ASNItem))
38544
#endif
38545
38546
static int DecodeResponseData(byte* source, word32* ioIndex,
38547
                              OcspResponse* resp, word32 size)
38548
{
38549
#ifndef WOLFSSL_ASN_TEMPLATE
38550
    word32 idx = *ioIndex, prev_idx, localIdx;
38551
    int length;
38552
    int version;
38553
    int ret;
38554
    byte tag;
38555
    int wrapperSz;
38556
    OcspEntry* single;
38557
38558
    WOLFSSL_ENTER("DecodeResponseData");
38559
38560
    resp->response = source + idx;
38561
    prev_idx = idx;
38562
    if (GetSequence(source, &idx, &length, size) < 0)
38563
        return ASN_PARSE_E;
38564
    resp->responseSz = length + idx - prev_idx;
38565
38566
    /* Get version. It is an EXPLICIT[0] DEFAULT(0) value. If this
38567
     * item isn't an EXPLICIT[0], then set version to zero and move
38568
     * onto the next item.
38569
     */
38570
    localIdx = idx;
38571
    if (GetASNTag(source, &localIdx, &tag, size) == 0 &&
38572
            tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
38573
    {
38574
        idx += 2; /* Eat the value and length */
38575
        if (GetMyVersion(source, &idx, &version, size) < 0)
38576
            return ASN_PARSE_E;
38577
    } else
38578
        version = 0;
38579
38580
    localIdx = idx;
38581
    if (GetASNTag(source, &localIdx, &tag, size) != 0)
38582
        return ASN_PARSE_E;
38583
38584
    resp->responderIdType = OCSP_RESPONDER_ID_INVALID;
38585
    /* parse byName */
38586
    if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1))
38587
    {
38588
        idx++; /* advance past ASN tag */
38589
        if (GetLength(source, &idx, &length, size) < 0)
38590
            return ASN_PARSE_E;
38591
        /* compute the hash of the name */
38592
        resp->responderIdType = OCSP_RESPONDER_ID_NAME;
38593
        ret = CalcHashId_ex(source + idx, length,
38594
                resp->responderId.nameHash, OCSP_RESPONDER_ID_HASH_TYPE);
38595
        if (ret != 0)
38596
            return ret;
38597
        idx += length;
38598
    }
38599
    else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2))
38600
    {
38601
        idx++; /* advance past ASN tag */
38602
        if (GetLength(source, &idx, &length, size) < 0)
38603
            return ASN_PARSE_E;
38604
38605
        if (GetOctetString(source, &idx, &length, size) < 0)
38606
            return ASN_PARSE_E;
38607
38608
        if (length != OCSP_RESPONDER_ID_KEY_SZ)
38609
            return ASN_PARSE_E;
38610
        resp->responderIdType = OCSP_RESPONDER_ID_KEY;
38611
        XMEMCPY(resp->responderId.keyHash, source + idx, length);
38612
        idx += length;
38613
    }
38614
    if (resp->responderIdType == OCSP_RESPONDER_ID_INVALID)
38615
        return ASN_PARSE_E;
38616
38617
    /* save pointer to the producedAt time */
38618
    if (GetBasicDate(source, &idx, resp->producedDate,
38619
                                        &resp->producedDateFormat, size) < 0)
38620
        return ASN_PARSE_E;
38621
38622
    /* Outer wrapper of the SEQUENCE OF Single Responses. */
38623
    if (GetSequence(source, &idx, &wrapperSz, size) < 0)
38624
        return ASN_PARSE_E;
38625
38626
    localIdx = idx;
38627
    single = resp->single;
38628
    while (idx - localIdx < (word32)wrapperSz) {
38629
        ret = DecodeSingleResponse(source, &idx, size, wrapperSz, single);
38630
        if (ret < 0)
38631
            return ret; /* ASN_PARSE_E, ASN_BEFORE_DATE_E, ASN_AFTER_DATE_E */
38632
        if (idx - localIdx < (word32)wrapperSz) {
38633
            single->next = (OcspEntry*)XMALLOC(sizeof(OcspEntry), resp->heap,
38634
                DYNAMIC_TYPE_OCSP_ENTRY);
38635
            if (single->next == NULL) {
38636
                return MEMORY_E;
38637
            }
38638
            XMEMSET(single->next, 0, sizeof(OcspEntry));
38639
38640
            single->next->status = (CertStatus*)XMALLOC(sizeof(CertStatus),
38641
                resp->heap, DYNAMIC_TYPE_OCSP_STATUS);
38642
            if (single->next->status == NULL) {
38643
                XFREE(single->next, resp->heap, DYNAMIC_TYPE_OCSP_ENTRY);
38644
                single->next = NULL;
38645
                return MEMORY_E;
38646
            }
38647
            XMEMSET(single->next->status, 0, sizeof(CertStatus));
38648
38649
            single->next->isDynamic = 1;
38650
            single->next->ownStatus = 1;
38651
38652
            single = single->next;
38653
        }
38654
    }
38655
38656
    /*
38657
     * Check the length of the ResponseData against the current index to
38658
     * see if there are extensions, they are optional.
38659
     */
38660
    if (idx - prev_idx < resp->responseSz)
38661
        if (DecodeOcspRespExtensions(source, &idx, resp, size) < 0)
38662
            return ASN_PARSE_E;
38663
38664
    *ioIndex = idx;
38665
    return 0;
38666
#else
38667
    DECL_ASNGETDATA(dataASN, ocspRespDataASN_Length);
38668
    int ret = 0;
38669
    byte version;
38670
    word32 dateSz = 0;
38671
    word32 responderByKeySz = OCSP_RESPONDER_ID_KEY_SZ;
38672
    word32 idx = *ioIndex;
38673
    OcspEntry* single = NULL;
38674
38675
    WOLFSSL_ENTER("DecodeResponseData");
38676
38677
    CALLOC_ASNGETDATA(dataASN, ocspRespDataASN_Length, ret, resp->heap);
38678
38679
    if (ret == 0) {
38680
        resp->response = source + idx;
38681
        /* Default, not present, is v1 = 0. */
38682
        version = 0;
38683
        /* Max size of date supported. */
38684
        dateSz = MAX_DATE_SIZE;
38685
38686
        /* Set the where to put version an produced date. */
38687
        GetASN_Int8Bit(&dataASN[OCSPRESPDATAASN_IDX_VER], &version);
38688
        GetASN_Buffer(&dataASN[OCSPRESPDATAASN_IDX_PA], resp->producedDate,
38689
                &dateSz);
38690
        GetASN_Buffer(&dataASN[OCSPRESPDATAASN_IDX_BYKEY_OCT],
38691
                resp->responderId.keyHash, &responderByKeySz);
38692
        /* Decode the ResponseData. */
38693
        ret = GetASN_Items(ocspRespDataASN, dataASN, ocspRespDataASN_Length,
38694
                1, source, ioIndex, size);
38695
    }
38696
    /* Only support v1 == 0 */
38697
    if (ret == 0) {
38698
        if (version != 0) {
38699
            ret = ASN_PARSE_E;
38700
        }
38701
    }
38702
    /* Ensure date is a minimal size. */
38703
    if (ret == 0) {
38704
        if  (dateSz < MIN_DATE_SIZE) {
38705
            ret = ASN_PARSE_E;
38706
        }
38707
    }
38708
    if (ret == 0) {
38709
        if (dataASN[OCSPRESPDATAASN_IDX_BYNAME].tag != 0) {
38710
            resp->responderIdType = OCSP_RESPONDER_ID_NAME;
38711
            ret = CalcHashId_ex(
38712
                dataASN[OCSPRESPDATAASN_IDX_BYNAME].data.ref.data,
38713
                dataASN[OCSPRESPDATAASN_IDX_BYNAME].data.ref.length,
38714
                resp->responderId.nameHash, OCSP_RESPONDER_ID_HASH_TYPE);
38715
        } else {
38716
            resp->responderIdType = OCSP_RESPONDER_ID_KEY;
38717
            if (dataASN[OCSPRESPDATAASN_IDX_BYKEY_OCT].length
38718
                    != OCSP_RESPONDER_ID_KEY_SZ) {
38719
                ret = ASN_PARSE_E;
38720
            } else {
38721
                resp->responderIdType = OCSP_RESPONDER_ID_KEY;
38722
            }
38723
        }
38724
    }
38725
    if (ret == 0) {
38726
        /* Store size of response. */
38727
        resp->responseSz = *ioIndex - idx;
38728
        /* Store date format/tag. */
38729
        resp->producedDateFormat = dataASN[OCSPRESPDATAASN_IDX_PA].tag;
38730
38731
        /* Get the index of the responses SEQUENCE. */
38732
        idx = GetASNItem_DataIdx(dataASN[OCSPRESPDATAASN_IDX_RESP], source);
38733
        /* Start with the pre-existing OcspEntry. */
38734
        single = resp->single;
38735
    }
38736
    while ((ret == 0) && (idx < dataASN[OCSPRESPDATAASN_IDX_RESPEXT].offset)) {
38737
        /* Allocate and use a new OCSP entry if this is used. */
38738
        if (single->used) {
38739
            single->next = (OcspEntry*)XMALLOC(sizeof(OcspEntry), resp->heap,
38740
                    DYNAMIC_TYPE_OCSP_ENTRY);
38741
            if (single->next == NULL) {
38742
                ret = MEMORY_E;
38743
            }
38744
            else {
38745
                XMEMSET(single->next, 0, sizeof(OcspEntry));
38746
38747
                single->next->status = (CertStatus*)XMALLOC(sizeof(CertStatus),
38748
                    resp->heap, DYNAMIC_TYPE_OCSP_STATUS);
38749
                if (single->next->status == NULL) {
38750
                    XFREE(single->next, resp->heap, DYNAMIC_TYPE_OCSP_ENTRY);
38751
                    single->next = NULL;
38752
                    ret = MEMORY_E;
38753
                }
38754
                else {
38755
                    XMEMSET(single->next->status, 0, sizeof(CertStatus));
38756
38757
                    /* Entry to be freed. */
38758
                    single->next->isDynamic = 1;
38759
                    single->next->ownStatus = 1;
38760
                    /* used will be 0 (false) */
38761
38762
                    single = single->next;
38763
                }
38764
            }
38765
        }
38766
        if (ret == 0) {
38767
            /* Decode SingleResponse into OcspEntry. */
38768
            ret = DecodeSingleResponse(source, &idx,
38769
                dataASN[OCSPRESPDATAASN_IDX_RESPEXT].offset,
38770
                (int)dataASN[OCSPRESPDATAASN_IDX_RESP].length, single);
38771
            /* single->used set on successful decode. */
38772
        }
38773
    }
38774
38775
    /* Check if there were extensions. */
38776
    if ((ret == 0) &&
38777
            (dataASN[OCSPRESPDATAASN_IDX_RESPEXT].data.buffer.data != NULL)) {
38778
        /* Get index of [1] */
38779
        idx = dataASN[OCSPRESPDATAASN_IDX_RESPEXT].offset;
38780
        /* Decode the response extensions. */
38781
        if (DecodeOcspRespExtensions(source, &idx, resp, *ioIndex) < 0) {
38782
            ret = ASN_PARSE_E;
38783
        }
38784
    }
38785
38786
    FREE_ASNGETDATA(dataASN, resp->heap);
38787
    return ret;
38788
#endif
38789
}
38790
38791
38792
#ifndef WOLFSSL_ASN_TEMPLATE
38793
#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
38794
38795
static int DecodeCerts(byte* source,
38796
                            word32* ioIndex, OcspResponse* resp, word32 size)
38797
{
38798
    word32 idx = *ioIndex;
38799
    byte tag;
38800
38801
    WOLFSSL_ENTER("DecodeCerts");
38802
38803
    if (GetASNTag(source, &idx, &tag, size) < 0)
38804
        return ASN_PARSE_E;
38805
38806
    if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
38807
    {
38808
        int length;
38809
38810
        if (GetLength(source, &idx, &length, size) < 0)
38811
            return ASN_PARSE_E;
38812
38813
        if (GetSequence(source, &idx, &length, size) < 0)
38814
            return ASN_PARSE_E;
38815
38816
        resp->cert = source + idx;
38817
        resp->certSz = length;
38818
38819
        idx += length;
38820
    }
38821
    *ioIndex = idx;
38822
    return 0;
38823
}
38824
38825
#endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */
38826
#endif /* !WOLFSSL_ASN_TEMPLATE */
38827
38828
#ifdef WOLFSSL_ASN_TEMPLATE
38829
/* ASN.1 template for BasicOCSPResponse.
38830
 * RFC 6960, 4.2.1 - ASN.1 Specification of the OCSP Response
38831
 */
38832
static const ASNItem ocspBasicRespASN[] = {
38833
/* SEQ          */ { 0, ASN_SEQUENCE, 1, 1, 0 },
38834
                                            /* tbsResponseData */
38835
/* TBS_SEQ      */     { 1, ASN_SEQUENCE, 1, 0, 0, },
38836
                                            /* signatureAlgorithm */
38837
/* SIGALGO      */     { 1, ASN_SEQUENCE, 1, 1, 0, },
38838
/* SIGALGO_OID  */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
38839
/* SIGALGO_NULL */         { 2, ASN_TAG_NULL, 0, 0, 1 },
38840
                                            /* parameters */
38841
#ifdef WC_RSA_PSS
38842
/* SIGALGO_PARAMS      */  { 2, ASN_SEQUENCE, 1, 0, 1 },
38843
#endif
38844
                                            /* signature */
38845
/* SIGNATURE    */     { 1, ASN_BIT_STRING, 0, 0, 0 },
38846
                                            /* certs */
38847
/* CERTS        */     { 1, ASN_CONTEXT_SPECIFIC | 0, 1, 1, 1 },
38848
/* CERTS_SEQ    */         { 2, ASN_SEQUENCE, 1, 0, 0, },
38849
};
38850
enum {
38851
    OCSPBASICRESPASN_IDX_SEQ = 0,
38852
    OCSPBASICRESPASN_IDX_TBS_SEQ,
38853
    OCSPBASICRESPASN_IDX_SIGALGO,
38854
    OCSPBASICRESPASN_IDX_SIGALGO_OID,
38855
    OCSPBASICRESPASN_IDX_SIGALGO_NULL,
38856
#ifdef WC_RSA_PSS
38857
    OCSPBASICRESPASN_IDX_SIGNATURE_PARAMS,
38858
#endif
38859
    OCSPBASICRESPASN_IDX_SIGNATURE,
38860
    OCSPBASICRESPASN_IDX_CERTS,
38861
    OCSPBASICRESPASN_IDX_CERTS_SEQ,
38862
};
38863
38864
/* Number of items in ASN.1 template for BasicOCSPResponse. */
38865
#define ocspBasicRespASN_Length (sizeof(ocspBasicRespASN) / sizeof(ASNItem))
38866
#endif /* WOLFSSL_ASN_TEMPLATE */
38867
38868
static int OcspRespIdMatch(OcspResponse *resp, const byte *NameHash,
38869
    const byte *keyHash)
38870
{
38871
    if (resp->responderIdType == OCSP_RESPONDER_ID_INVALID)
38872
        return 0;
38873
    if (resp->responderIdType == OCSP_RESPONDER_ID_NAME)
38874
        return XMEMCMP(NameHash, resp->responderId.nameHash,
38875
            SIGNER_DIGEST_SIZE) == 0;
38876
    /* OCSP_RESPONDER_ID_KEY */
38877
    return ((int)KEYID_SIZE == OCSP_RESPONDER_ID_KEY_SZ) &&
38878
        XMEMCMP(keyHash, resp->responderId.keyHash, KEYID_SIZE) == 0;
38879
}
38880
38881
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK
38882
static int OcspRespCheck(OcspResponse *resp, Signer *responder)
38883
{
38884
    OcspEntry *s;
38885
38886
    s = resp->single;
38887
    if (s == NULL)
38888
        return -1;
38889
38890
    /* singles responses must have the same issuer */
38891
    for (; s != NULL; s = s->next) {
38892
        if (XMEMCMP(s->issuerKeyHash, responder->subjectKeyHash,
38893
                KEYID_SIZE) != 0)
38894
            return -1;
38895
    }
38896
38897
    return 0;
38898
}
38899
#endif
38900
38901
static Signer *OcspFindSigner(OcspResponse *resp, WOLFSSL_CERT_MANAGER *cm)
38902
{
38903
    Signer *s;
38904
38905
    if (cm == NULL)
38906
        return NULL;
38907
38908
    if (resp->responderIdType == OCSP_RESPONDER_ID_NAME) {
38909
#ifndef NO_SKID
38910
        s = GetCAByName(cm, resp->responderId.nameHash);
38911
#else
38912
        s = GetCA(cm, resp->responderId.nameHash);
38913
#endif
38914
        if (s)
38915
            return s;
38916
    }
38917
    else if ((int)KEYID_SIZE == OCSP_RESPONDER_ID_KEY_SZ) {
38918
        s = GetCAByKeyHash(cm, resp->responderId.keyHash);
38919
        if (s)
38920
            return s;
38921
    }
38922
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
38923
    if (resp->pendingCAs == NULL)
38924
        return NULL;
38925
38926
    if (resp->responderIdType == OCSP_RESPONDER_ID_NAME) {
38927
        s = findSignerByName(resp->pendingCAs, resp->responderId.nameHash);
38928
        if (s)
38929
            return s;
38930
    }
38931
    else {
38932
        s = findSignerByKeyHash(resp->pendingCAs, resp->responderId.keyHash);
38933
        if (s)
38934
            return s;
38935
    }
38936
#endif
38937
    return NULL;
38938
}
38939
38940
static int OcspCheckCert(OcspResponse *resp, int noVerify,
38941
    int noVerifySignature, WOLFSSL_CERT_MANAGER *cm, void *heap)
38942
{
38943
    int ret = 0;
38944
#ifdef WOLFSSL_SMALL_STACK
38945
    DecodedCert *cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
38946
                                              DYNAMIC_TYPE_TMP_BUFFER);
38947
    if (cert == NULL)
38948
        return MEMORY_E;
38949
#else
38950
    DecodedCert cert[1];
38951
#endif
38952
38953
    InitDecodedCert(cert, resp->cert, resp->certSz, heap);
38954
    ret = ParseCertRelative(cert, CERT_TYPE,
38955
                            noVerify ? NO_VERIFY : VERIFY_OCSP_CERT,
38956
                            cm, resp->pendingCAs);
38957
    if (ret < 0) {
38958
        WOLFSSL_MSG("\tOCSP Responder certificate parsing failed");
38959
    }
38960
38961
    if (ret == 0 &&
38962
            OcspRespIdMatch(resp,
38963
                cert->subjectHash, cert->subjectKeyHash) == 0) {
38964
        WOLFSSL_MSG("\tInternal check doesn't match responder ID, ignoring\n");
38965
        ret = BAD_OCSP_RESPONDER;
38966
        goto err;
38967
    }
38968
38969
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK
38970
    if (ret == 0 && !noVerify) {
38971
        ret = CheckOcspResponder(resp, cert, cm);
38972
        if (ret != 0) {
38973
            WOLFSSL_MSG("\tOCSP Responder certificate issuer check failed");
38974
            goto err;
38975
        }
38976
    }
38977
#endif /* WOLFSSL_NO_OCSP_ISSUER_CHECK */
38978
    if (ret == 0 && !noVerifySignature) {
38979
        ret = ConfirmSignature(
38980
            &cert->sigCtx,
38981
            resp->response, resp->responseSz,
38982
            cert->publicKey, cert->pubKeySize, cert->keyOID,
38983
            resp->sig, resp->sigSz, resp->sigOID, resp->sigParams,
38984
            resp->sigParamsSz, NULL);
38985
    }
38986
err:
38987
    FreeDecodedCert(cert);
38988
38989
#ifdef WOLFSSL_SMALL_STACK
38990
    if (cert != NULL) {
38991
        XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
38992
    }
38993
#endif
38994
38995
    return ret;
38996
}
38997
38998
static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
38999
            OcspResponse* resp, word32 size, void* cm, void* heap, int noVerify,
39000
            int noVerifySignature)
39001
{
39002
#ifndef WOLFSSL_ASN_TEMPLATE
39003
    int    length;
39004
    word32 idx = *ioIndex;
39005
    #ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
39006
    word32 end_index;
39007
    #endif
39008
    int    ret;
39009
    int    sigLength;
39010
    int    sigValid = 0;
39011
    WOLFSSL_ENTER("DecodeBasicOcspResponse");
39012
    (void)heap;
39013
39014
    if (GetSequence(source, &idx, &length, size) < 0)
39015
        return ASN_PARSE_E;
39016
39017
    if (idx + length > size)
39018
        return ASN_INPUT_E;
39019
    #ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
39020
    end_index = idx + length;
39021
    #endif
39022
39023
    if ((ret = DecodeResponseData(source, &idx, resp, size)) < 0)
39024
        return ret; /* ASN_PARSE_E, ASN_BEFORE_DATE_E, ASN_AFTER_DATE_E */
39025
39026
    /* Get the signature algorithm */
39027
    if (GetAlgoId(source, &idx, &resp->sigOID, oidSigType, size) < 0) {
39028
        return ASN_PARSE_E;
39029
    }
39030
#ifdef WC_RSA_PSS
39031
    else if (resp->sigOID == CTC_RSASSAPSS) {
39032
        word32 sz;
39033
        int len;
39034
        byte* params;
39035
39036
        sz = idx;
39037
        params = source + idx;
39038
        if (GetSequence(source, &idx, &len, size) < 0)
39039
            return ASN_PARSE_E;
39040
        if (ret == 0) {
39041
            idx += len;
39042
            resp->sigParams = params;
39043
            resp->sigParamsSz = idx - sz;
39044
        }
39045
    }
39046
#endif
39047
39048
    ret = CheckBitString(source, &idx, &sigLength, size, 1, NULL);
39049
    if (ret != 0)
39050
        return ret;
39051
39052
    resp->sigSz = sigLength;
39053
    resp->sig = source + idx;
39054
    idx += sigLength;
39055
39056
    /*
39057
     * Check the length of the BasicOcspResponse against the current index to
39058
     * see if there are certificates, they are optional.
39059
     */
39060
#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
39061
    if (idx < end_index)
39062
    {
39063
        if (DecodeCerts(source, &idx, resp, size) < 0)
39064
            return ASN_PARSE_E;
39065
39066
        ret = OcspCheckCert(resp, noVerify, noVerifySignature,
39067
            (WOLFSSL_CERT_MANAGER*)cm, heap);
39068
        if (ret == 0) {
39069
            sigValid = 1;
39070
        }
39071
        else {
39072
            WOLFSSL_MSG("OCSP Internal cert can't verify the response\n");
39073
            /* try to verify the OCSP response with CA certs */
39074
            ret = 0;
39075
        }
39076
    }
39077
    else
39078
#endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */
39079
    if (!noVerifySignature && !sigValid) {
39080
        Signer* ca;
39081
        SignatureCtx sigCtx;
39082
        ca = OcspFindSigner(resp, (WOLFSSL_CERT_MANAGER*)cm);
39083
        if (ca == NULL)
39084
            return ASN_NO_SIGNER_E;
39085
39086
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK
39087
        if (OcspRespCheck(resp, ca) != 0)
39088
           return BAD_OCSP_RESPONDER;
39089
#endif
39090
        InitSignatureCtx(&sigCtx, heap, INVALID_DEVID);
39091
39092
        /* ConfirmSignature is blocking here */
39093
        sigValid = ConfirmSignature(&sigCtx, resp->response,
39094
            resp->responseSz, ca->publicKey, ca->pubKeySize, ca->keyOID,
39095
            resp->sig, resp->sigSz, resp->sigOID, resp->sigParams,
39096
            resp->sigParamsSz, NULL);
39097
        if (sigValid != 0) {
39098
            WOLFSSL_MSG("\tOCSP Confirm signature failed");
39099
            return ASN_OCSP_CONFIRM_E;
39100
        }
39101
        (void)noVerify;
39102
    }
39103
39104
    *ioIndex = idx;
39105
    return 0;
39106
#else
39107
    DECL_ASNGETDATA(dataASN, ocspBasicRespASN_Length);
39108
    int ret = 0;
39109
    word32 idx = *ioIndex;
39110
    Signer* ca = NULL;
39111
    int sigValid = 0;
39112
39113
    WOLFSSL_ENTER("DecodeBasicOcspResponse");
39114
    (void)heap;
39115
39116
    CALLOC_ASNGETDATA(dataASN, ocspBasicRespASN_Length, ret, heap);
39117
39118
    if (ret == 0) {
39119
        /* Set expecting signature OID. */
39120
        GetASN_OID(&dataASN[OCSPBASICRESPASN_IDX_SIGALGO_OID], oidSigType);
39121
        /* Decode BasicOCSPResponse. */
39122
        ret = GetASN_Items(ocspBasicRespASN, dataASN, ocspBasicRespASN_Length,
39123
                1, source, &idx, size);
39124
    }
39125
    if (ret == 0) {
39126
        word32 dataIdx = 0;
39127
        /* Decode the response data. */
39128
        ret = DecodeResponseData(
39129
                GetASNItem_Addr(dataASN[OCSPBASICRESPASN_IDX_TBS_SEQ], source),
39130
                &dataIdx, resp,
39131
                GetASNItem_Length(dataASN[OCSPBASICRESPASN_IDX_TBS_SEQ], source)
39132
                );
39133
    }
39134
#ifdef WC_RSA_PSS
39135
    if (ret == 0 && (dataASN[OCSPBASICRESPASN_IDX_SIGNATURE_PARAMS].tag != 0)) {
39136
        resp->sigParams = GetASNItem_Addr(
39137
                dataASN[OCSPBASICRESPASN_IDX_SIGNATURE_PARAMS],
39138
                source);
39139
        resp->sigParamsSz =
39140
               GetASNItem_Length(dataASN[OCSPBASICRESPASN_IDX_SIGNATURE_PARAMS],
39141
               source);
39142
    }
39143
#endif
39144
    if (ret == 0) {
39145
        /* Get the signature OID and signature. */
39146
        resp->sigOID = dataASN[OCSPBASICRESPASN_IDX_SIGALGO_OID].data.oid.sum;
39147
        GetASN_GetRef(&dataASN[OCSPBASICRESPASN_IDX_SIGNATURE], &resp->sig,
39148
                &resp->sigSz);
39149
    }
39150
    resp->certSz = 0;
39151
#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
39152
    if ((ret == 0) &&
39153
            (dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data != NULL)) {
39154
        /* TODO: support more than one certificate. */
39155
        /* Store reference to certificate BER data. */
39156
        GetASN_GetRef(&dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ], &resp->cert,
39157
                &resp->certSz);
39158
    }
39159
39160
    if ((ret == 0) && resp->certSz > 0) {
39161
        ret = OcspCheckCert(resp, noVerify, noVerifySignature,
39162
                            (WOLFSSL_CERT_MANAGER*)cm, heap);
39163
        if (ret == 0) {
39164
            sigValid = 1;
39165
        }
39166
        ret = 0; /* try to verify the OCSP response with CA certs */
39167
    }
39168
#endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */
39169
    /* try to verify using cm certs */
39170
    if (ret == 0 && !noVerifySignature && !sigValid)
39171
    {
39172
        ca = OcspFindSigner(resp, (WOLFSSL_CERT_MANAGER*)cm);
39173
        if (ca == NULL)
39174
            ret = ASN_NO_SIGNER_E;
39175
    }
39176
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK
39177
    if (ret == 0 && !noVerifySignature && !sigValid) {
39178
        if (OcspRespCheck(resp, ca) != 0) {
39179
            ret = BAD_OCSP_RESPONDER;
39180
        }
39181
    }
39182
#endif
39183
    if (ret == 0 && !noVerifySignature && !sigValid) {
39184
        SignatureCtx sigCtx;
39185
        /* Initialize the signature context. */
39186
        InitSignatureCtx(&sigCtx, heap, INVALID_DEVID);
39187
39188
        /* TODO: ConfirmSignature is blocking here */
39189
        /* Check the signature of the response CA public key. */
39190
        sigValid = ConfirmSignature(&sigCtx, resp->response,
39191
            resp->responseSz, ca->publicKey, ca->pubKeySize, ca->keyOID,
39192
            resp->sig, resp->sigSz, resp->sigOID, resp->sigParams,
39193
            resp->sigParamsSz, NULL);
39194
        if (sigValid != 0) {
39195
            WOLFSSL_MSG("\tOCSP Confirm signature failed");
39196
            ret = ASN_OCSP_CONFIRM_E;
39197
        }
39198
    }
39199
    if (ret == 0) {
39200
        /* Update the position to after response data. */
39201
        *ioIndex = idx;
39202
    }
39203
39204
    FREE_ASNGETDATA(dataASN, heap);
39205
    return ret;
39206
#endif /* WOLFSSL_ASN_TEMPLATE */
39207
}
39208
39209
39210
void InitOcspResponse(OcspResponse* resp, OcspEntry* single, CertStatus* status,
39211
                      byte* source, word32 inSz, void* heap)
39212
{
39213
    WOLFSSL_ENTER("InitOcspResponse");
39214
39215
    XMEMSET(status, 0, sizeof(CertStatus));
39216
    XMEMSET(single,  0, sizeof(OcspEntry));
39217
    XMEMSET(resp,   0, sizeof(OcspResponse));
39218
39219
    single->status       = status;
39220
    resp->responseStatus = -1;
39221
    resp->single         = single;
39222
    resp->source         = source;
39223
    resp->maxIdx         = inSz;
39224
    resp->heap           = heap;
39225
    resp->pendingCAs     = NULL;
39226
    resp->sigParams      = NULL;
39227
    resp->sigParamsSz    = 0;
39228
    resp->responderIdType = OCSP_RESPONDER_ID_INVALID;
39229
}
39230
39231
void FreeOcspResponse(OcspResponse* resp)
39232
{
39233
    OcspEntry *single, *next;
39234
39235
    if (resp != NULL) {
39236
        for (single = resp->single; single; single = next) {
39237
            next = single->next;
39238
            if (single->isDynamic) {
39239
                XFREE(single->status, resp->heap, DYNAMIC_TYPE_OCSP_STATUS);
39240
                XFREE(single, resp->heap, DYNAMIC_TYPE_OCSP_ENTRY);
39241
            }
39242
        }
39243
    }
39244
}
39245
39246
#ifdef WOLFSSL_ASN_TEMPLATE
39247
/* ASN.1 template for OCSPResponse.
39248
 * RFC 6960, 4.2.1 - ASN.1 Specification of the OCSP Response
39249
 */
39250
static const ASNItem ocspResponseASN[] = {
39251
                                     /* OCSPResponse ::= SEQUENCE */
39252
/* SEQ        */ { 0, ASN_SEQUENCE, 1, 1, 0 },
39253
                                         /* responseStatus      OCSPResponseStatus */
39254
/* STATUS     */     { 1, ASN_ENUMERATED, 0, 0, 0, },
39255
                                         /* responseBytes   [0] EXPLICIT ResponseBytes OPTIONAL */
39256
/* BYTES      */     { 1, ASN_CONTEXT_SPECIFIC | 0, 1, 1, 1 },
39257
                                             /* ResponseBytes ::= SEQUENCE */
39258
/* BYTES_SEQ  */         { 2, ASN_SEQUENCE, 1, 1, 0 },
39259
                                                /* responseType   OBJECT IDENTIFIER */
39260
/* BYTES_TYPE */            { 3, ASN_OBJECT_ID, 0, 0, 0 },
39261
                                                /* response       OCTET STRING */
39262
/* BYTES_VAL  */            { 3, ASN_OCTET_STRING, 0, 0, 0 },
39263
};
39264
enum {
39265
    OCSPRESPONSEASN_IDX_SEQ = 0,
39266
39267
    OCSPRESPONSEASN_IDX_STATUS,
39268
39269
    OCSPRESPONSEASN_IDX_BYTES,
39270
39271
    OCSPRESPONSEASN_IDX_BYTES_SEQ,
39272
39273
    OCSPRESPONSEASN_IDX_BYTES_TYPE,
39274
39275
    OCSPRESPONSEASN_IDX_BYTES_VAL,
39276
};
39277
39278
/* Number of items in ASN.1 template for OCSPResponse. */
39279
#define ocspResponseASN_Length (sizeof(ocspResponseASN) / sizeof(ASNItem))
39280
#endif /* WOLFSSL_ASN_TEMPLATE */
39281
39282
int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap,
39283
    int noVerifyCert, int noVerifySignature)
39284
{
39285
#ifndef WOLFSSL_ASN_TEMPLATE
39286
    int ret;
39287
    int length = 0;
39288
    word32 idx = 0;
39289
    byte* source = resp->source;
39290
    word32 size = resp->maxIdx;
39291
    word32 oid;
39292
    byte   tag;
39293
39294
    WOLFSSL_ENTER("OcspResponseDecode");
39295
39296
    /* peel the outer SEQUENCE wrapper */
39297
    if (GetSequence(source, &idx, &length, size) < 0) {
39298
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
39299
        return ASN_PARSE_E;
39300
    }
39301
39302
    /* First get the responseStatus, an ENUMERATED */
39303
    if (GetEnumerated(source, &idx, &resp->responseStatus, size) < 0) {
39304
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
39305
        return ASN_PARSE_E;
39306
    }
39307
39308
    if (resp->responseStatus != OCSP_SUCCESSFUL) {
39309
        WOLFSSL_LEAVE("OcspResponseDecode", 0);
39310
        return 0;
39311
    }
39312
39313
    /* Next is an EXPLICIT record called ResponseBytes, OPTIONAL */
39314
    if (idx >= size) {
39315
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
39316
        return ASN_PARSE_E;
39317
    }
39318
    if (GetASNTag(source, &idx, &tag, size) < 0) {
39319
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
39320
        return ASN_PARSE_E;
39321
    }
39322
    if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
39323
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
39324
        return ASN_PARSE_E;
39325
    }
39326
    if (GetLength(source, &idx, &length, size) < 0) {
39327
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
39328
        return ASN_PARSE_E;
39329
    }
39330
39331
    /* Get the responseBytes SEQUENCE */
39332
    if (GetSequence(source, &idx, &length, size) < 0) {
39333
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
39334
        return ASN_PARSE_E;
39335
    }
39336
39337
    /* Check ObjectID for the resposeBytes */
39338
    if (GetObjectId(source, &idx, &oid, oidOcspType, size) < 0) {
39339
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
39340
        return ASN_PARSE_E;
39341
    }
39342
    if (oid != OCSP_BASIC_OID) {
39343
        WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
39344
        return ASN_PARSE_E;
39345
    }
39346
    ret = GetOctetString(source, &idx, &length, size);
39347
    if (ret < 0) {
39348
        WOLFSSL_LEAVE("OcspResponseDecode", ret);
39349
        return ret;
39350
    }
39351
39352
    ret = DecodeBasicOcspResponse(source, &idx, resp, size, cm, heap,
39353
         noVerifyCert, noVerifySignature);
39354
    if (ret < 0) {
39355
        WOLFSSL_LEAVE("OcspResponseDecode", ret);
39356
        return ret;
39357
    }
39358
39359
    WOLFSSL_LEAVE("OcspResponseDecode", 0);
39360
    return 0;
39361
#else
39362
    DECL_ASNGETDATA(dataASN, ocspResponseASN_Length);
39363
    int ret = 0;
39364
    word32 idx = 0, size = resp->maxIdx;
39365
    byte* source = resp->source;
39366
    byte status = 0;
39367
    byte* basic;
39368
    word32 basicSz;
39369
39370
    WOLFSSL_ENTER("OcspResponseDecode");
39371
39372
    CALLOC_ASNGETDATA(dataASN, ocspResponseASN_Length, ret, resp->heap);
39373
39374
    if (ret == 0) {
39375
        /* Set variable to put status in and expect OCSP OID. */
39376
        GetASN_Int8Bit(&dataASN[OCSPRESPONSEASN_IDX_STATUS], &status);
39377
        GetASN_OID(&dataASN[OCSPRESPONSEASN_IDX_BYTES_TYPE], oidOcspType);
39378
        /* Decode OCSPResponse (and ResponseBytes). */
39379
        ret = GetASN_Items(ocspResponseASN, dataASN, ocspResponseASN_Length, 1,
39380
            source, &idx, size);
39381
    }
39382
    if (ret == 0) {
39383
        /* Get response. */
39384
        resp->responseStatus = status;
39385
        if (dataASN[OCSPRESPONSEASN_IDX_BYTES_TYPE].data.oid.sum
39386
                == OCSP_BASIC_OID) {
39387
            /* Get reference to BasicOCSPResponse. */
39388
            GetASN_GetRef(&dataASN[OCSPRESPONSEASN_IDX_BYTES_VAL], &basic,
39389
                    &basicSz);
39390
            idx = 0;
39391
            /* Decode BasicOCSPResponse. */
39392
            ret = DecodeBasicOcspResponse(basic, &idx, resp, basicSz, cm, heap,
39393
                noVerifyCert, noVerifySignature);
39394
        }
39395
        /* Only support BasicOCSPResponse. */
39396
        else {
39397
            ret = ASN_PARSE_E;
39398
        }
39399
    }
39400
39401
    FREE_ASNGETDATA(dataASN, resp->heap);
39402
    WOLFSSL_LEAVE("OcspResponseDecode", ret);
39403
    return ret;
39404
#endif /* WOLFSSL_ASN_TEMPLATE */
39405
}
39406
39407
#ifdef WOLFSSL_ASN_TEMPLATE
39408
/* ASN.1 template for OCSP nonce extension.
39409
 * RFC 6960, 4.4.1 - Nonce
39410
 * X.509: RFC 5280, 4.1 - Basic Certificate Fields. (Extension)
39411
 */
39412
static const ASNItem ocspNonceExtASN[] = {
39413
/* SEQ       */ { 0, ASN_SEQUENCE, 1, 1, 0 },
39414
                                     /* Extension */
39415
/* EXT       */     { 1, ASN_SEQUENCE, 1, 1, 0 },
39416
                                        /* extnId */
39417
/* EXT_OID   */        {2, ASN_OBJECT_ID, 0, 0, 0 },
39418
                                        /* critical not encoded. */
39419
                                        /* extnValue */
39420
/* EXT_VAL   */        {2, ASN_OCTET_STRING, 0, 1, 0 },
39421
                                               /* nonce */
39422
/* EXT_NONCE */            {3, ASN_OCTET_STRING, 0, 0, 0 },
39423
};
39424
enum {
39425
    OCSPNONCEEXTASN_IDX_SEQ = 0,
39426
    OCSPNONCEEXTASN_IDX_EXT,
39427
    OCSPNONCEEXTASN_IDX_EXT_OID,
39428
    OCSPNONCEEXTASN_IDX_EXT_VAL,
39429
    OCSPNONCEEXTASN_IDX_EXT_NONCE,
39430
};
39431
39432
/* Number of items in ASN.1 template for OCSP nonce extension. */
39433
#define ocspNonceExtASN_Length (sizeof(ocspNonceExtASN) / sizeof(ASNItem))
39434
#endif /* WOLFSSL_ASN_TEMPLATE */
39435
39436
word32 EncodeOcspRequestExtensions(OcspRequest* req, byte* output, word32 size)
39437
{
39438
    const byte NonceObjId[] = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
39439
                                       0x30, 0x01, 0x02 };
39440
#ifndef WOLFSSL_ASN_TEMPLATE
39441
    byte seqArray[5][MAX_SEQ_SZ];
39442
    word32 seqSz[5], totalSz = (word32)sizeof(NonceObjId);
39443
39444
    WOLFSSL_ENTER("SetOcspReqExtensions");
39445
39446
    if (!req || !output || !req->nonceSz)
39447
        return 0;
39448
39449
    totalSz += req->nonceSz;
39450
    totalSz += seqSz[0] = SetOctetString(req->nonceSz, seqArray[0]);
39451
    totalSz += seqSz[1] = SetOctetString(req->nonceSz + seqSz[0], seqArray[1]);
39452
    totalSz += seqSz[2] = SetObjectId(sizeof(NonceObjId), seqArray[2]);
39453
    totalSz += seqSz[3] = SetSequence(totalSz, seqArray[3]);
39454
    totalSz += seqSz[4] = SetSequence(totalSz, seqArray[4]);
39455
39456
    if (totalSz > size)
39457
        return 0;
39458
39459
    totalSz = 0;
39460
39461
    XMEMCPY(output + totalSz, seqArray[4], seqSz[4]);
39462
    totalSz += seqSz[4];
39463
39464
    XMEMCPY(output + totalSz, seqArray[3], seqSz[3]);
39465
    totalSz += seqSz[3];
39466
39467
    XMEMCPY(output + totalSz, seqArray[2], seqSz[2]);
39468
    totalSz += seqSz[2];
39469
39470
    XMEMCPY(output + totalSz, NonceObjId, sizeof(NonceObjId));
39471
    totalSz += (word32)sizeof(NonceObjId);
39472
39473
    XMEMCPY(output + totalSz, seqArray[1], seqSz[1]);
39474
    totalSz += seqSz[1];
39475
39476
    XMEMCPY(output + totalSz, seqArray[0], seqSz[0]);
39477
    totalSz += seqSz[0];
39478
39479
    XMEMCPY(output + totalSz, req->nonce, req->nonceSz);
39480
    totalSz += req->nonceSz;
39481
39482
    return totalSz;
39483
#else
39484
    int ret = 0;
39485
39486
    WOLFSSL_ENTER("SetOcspReqExtensions");
39487
39488
    /* Check request has nonce to write in extension. */
39489
    if (req != NULL && req->nonceSz != 0) {
39490
        DECL_ASNSETDATA(dataASN, ocspNonceExtASN_Length);
39491
        int sz = 0;
39492
39493
        CALLOC_ASNSETDATA(dataASN, ocspNonceExtASN_Length, ret, req->heap);
39494
39495
        if (ret == 0) {
39496
            /* Set nonce extension OID and nonce. */
39497
            SetASN_Buffer(&dataASN[OCSPNONCEEXTASN_IDX_EXT_OID], NonceObjId,
39498
                    sizeof(NonceObjId));
39499
            SetASN_Buffer(&dataASN[OCSPNONCEEXTASN_IDX_EXT_NONCE], req->nonce,
39500
                    (word32)req->nonceSz);
39501
            /* Calculate size of nonce extension. */
39502
            ret = SizeASN_Items(ocspNonceExtASN, dataASN,
39503
                                ocspNonceExtASN_Length, &sz);
39504
        }
39505
        /* Check buffer big enough for encoding if supplied. */
39506
        if ((ret == 0) && (output != NULL) && (sz > (int)size)) {
39507
            ret = BUFFER_E;
39508
        }
39509
        if ((ret == 0) && (output != NULL)) {
39510
            /* Encode nonce extension. */
39511
            SetASN_Items(ocspNonceExtASN, dataASN, ocspNonceExtASN_Length,
39512
                         output);
39513
        }
39514
        if (ret == 0) {
39515
            /* Return size of encoding. */
39516
            ret = sz;
39517
        }
39518
39519
        FREE_ASNSETDATA(dataASN, req->heap);
39520
    }
39521
39522
    return (word32)ret;
39523
#endif /* WOLFSSL_ASN_TEMPLATE */
39524
}
39525
39526
39527
#ifdef WOLFSSL_ASN_TEMPLATE
39528
/* ASN.1 template for OCSPRequest.
39529
 * RFC 6960, 4.1.1 - ASN.1 Specification of the OCSP Request
39530
 */
39531
static const ASNItem ocspRequestASN[] = {
39532
                                              /* OCSPRequest */
39533
/* SEQ               */    { 0, ASN_SEQUENCE, 1, 1, 0 },
39534
                                                  /* tbsRequest */
39535
/* TBS               */        { 1, ASN_SEQUENCE, 1, 1, 0 },
39536
                                                      /* version not written - v1 */
39537
                                                      /* requestorName not written */
39538
                                                      /* requestList */
39539
/* TBS_SEQ           */            { 2, ASN_SEQUENCE, 1, 1, 0 },
39540
                                                          /* Request */
39541
/* TBS_LIST          */                { 3, ASN_SEQUENCE, 1, 1, 0 },
39542
                                                              /* reqCert */
39543
/* TBS_REQ_CID       */                    { 4, ASN_SEQUENCE, 1, 1, 0 },
39544
                                                                  /* hashAlgorithm */
39545
/* TBS_REQ_HASH      */                        { 5, ASN_SEQUENCE, 1, 1, 0 },
39546
/* TBS_REQ_HASH_OID  */                            { 6, ASN_OBJECT_ID, 0, 0, 0 },
39547
                                                                  /* issuerNameHash */
39548
/* TBS_REQ_ISSUER    */                        { 5, ASN_OCTET_STRING, 0, 0, 0 },
39549
                                                                  /* issuerKeyHash */
39550
/* TBS_REQ_ISSUERKEY */                        { 5, ASN_OCTET_STRING, 0, 0, 0 },
39551
                                                                  /* serialNumber */
39552
/* TBS_REQ_SERIAL    */                        { 5, ASN_INTEGER, 0, 0, 0 },
39553
                                                      /* requestExtensions */
39554
/* TBS_REQEXT        */            { 2, ASN_CONTEXT_SPECIFIC | 2, 1, 0, 0 },
39555
                                                  /* optionalSignature not written. */
39556
};
39557
enum {
39558
    OCSPREQUESTASN_IDX_SEQ = 0,
39559
    OCSPREQUESTASN_IDX_TBS,
39560
    OCSPREQUESTASN_IDX_TBS_SEQ,
39561
    OCSPREQUESTASN_IDX_TBS_LIST,
39562
    OCSPREQUESTASN_IDX_TBS_REQ_CID,
39563
    OCSPREQUESTASN_IDX_TBS_REQ_HASH,
39564
    OCSPREQUESTASN_IDX_TBS_REQ_HASH_OID,
39565
    OCSPREQUESTASN_IDX_TBS_REQ_ISSUER,
39566
    OCSPREQUESTASN_IDX_TBS_REQ_ISSUERKEY,
39567
    OCSPREQUESTASN_IDX_TBS_REQ_SERIAL,
39568
    OCSPREQUESTASN_IDX_TBS_REQEXT,
39569
};
39570
39571
/* Number of items in ASN.1 template for OCSPRequest. */
39572
#define ocspRequestASN_Length (sizeof(ocspRequestASN) / sizeof(ASNItem))
39573
#endif
39574
39575
int EncodeOcspRequest(OcspRequest* req, byte* output, word32 size)
39576
{
39577
#ifndef WOLFSSL_ASN_TEMPLATE
39578
    byte seqArray[5][MAX_SEQ_SZ];
39579
    /* The ASN.1 of the OCSP Request is an onion of sequences */
39580
    byte algoArray[MAX_ALGO_SZ];
39581
    byte issuerArray[MAX_ENCODED_DIG_SZ];
39582
    byte issuerKeyArray[MAX_ENCODED_DIG_SZ];
39583
    byte snArray[MAX_SN_SZ];
39584
    byte extArray[MAX_OCSP_EXT_SZ];
39585
    word32 seqSz[5], algoSz, issuerSz, issuerKeySz, extSz, totalSz;
39586
    int i, snSz;
39587
    int keyIdSz;
39588
39589
    WOLFSSL_ENTER("EncodeOcspRequest");
39590
39591
#ifdef NO_SHA
39592
    algoSz = SetAlgoID(SHA256h, algoArray, oidHashType, 0);
39593
    keyIdSz = WC_SHA256_DIGEST_SIZE;
39594
#else
39595
    algoSz = SetAlgoID(SHAh, algoArray, oidHashType, 0);
39596
    keyIdSz = WC_SHA_DIGEST_SIZE;
39597
#endif
39598
39599
    issuerSz    = SetDigest(req->issuerHash,    keyIdSz,    issuerArray);
39600
    issuerKeySz = SetDigest(req->issuerKeyHash, keyIdSz,    issuerKeyArray);
39601
    snSz        = SetSerialNumber(req->serial,  req->serialSz, snArray,
39602
                                                          MAX_SN_SZ, MAX_SN_SZ);
39603
    extSz       = 0;
39604
39605
    if (snSz < 0)
39606
        return snSz;
39607
39608
    if (req->nonceSz) {
39609
        /* TLS Extensions use this function too - put extensions after
39610
         * ASN.1: Context Specific [2].
39611
         */
39612
        extSz = EncodeOcspRequestExtensions(req, extArray + 2,
39613
                                            OCSP_NONCE_EXT_SZ);
39614
        extSz += SetExplicit(2, extSz, extArray, 0);
39615
    }
39616
39617
    totalSz = algoSz + issuerSz + issuerKeySz + snSz;
39618
    for (i = 4; i >= 0; i--) {
39619
        seqSz[i] = SetSequence(totalSz, seqArray[i]);
39620
        totalSz += seqSz[i];
39621
        if (i == 2) totalSz += extSz;
39622
    }
39623
39624
    if (output == NULL)
39625
        return totalSz;
39626
    if (totalSz > size)
39627
        return BUFFER_E;
39628
39629
    totalSz = 0;
39630
    for (i = 0; i < 5; i++) {
39631
        XMEMCPY(output + totalSz, seqArray[i], seqSz[i]);
39632
        totalSz += seqSz[i];
39633
    }
39634
39635
    XMEMCPY(output + totalSz, algoArray, algoSz);
39636
    totalSz += algoSz;
39637
39638
    XMEMCPY(output + totalSz, issuerArray, issuerSz);
39639
    totalSz += issuerSz;
39640
39641
    XMEMCPY(output + totalSz, issuerKeyArray, issuerKeySz);
39642
    totalSz += issuerKeySz;
39643
39644
    XMEMCPY(output + totalSz, snArray, snSz);
39645
    totalSz += snSz;
39646
39647
    if (extSz != 0) {
39648
        XMEMCPY(output + totalSz, extArray, extSz);
39649
        totalSz += extSz;
39650
    }
39651
39652
    return totalSz;
39653
#else
39654
    DECL_ASNSETDATA(dataASN, ocspRequestASN_Length);
39655
    word32 extSz = 0;
39656
    int sz = 0;
39657
    int ret = 0;
39658
    word32 keyIdSz;
39659
39660
    WOLFSSL_ENTER("EncodeOcspRequest");
39661
39662
    CALLOC_ASNSETDATA(dataASN, ocspRequestASN_Length, ret, req->heap);
39663
39664
    if (ret == 0) {
39665
        /* Set OID of hash algorithm use on issuer and key. */
39666
    #ifdef NO_SHA
39667
        SetASN_OID(&dataASN[OCSPREQUESTASN_IDX_TBS_REQ_HASH_OID], SHA256h,
39668
                oidHashType);
39669
        keyIdSz = WC_SHA256_DIGEST_SIZE;
39670
    #else
39671
        SetASN_OID(&dataASN[OCSPREQUESTASN_IDX_TBS_REQ_HASH_OID], SHAh,
39672
                oidHashType);
39673
        keyIdSz = WC_SHA_DIGEST_SIZE;
39674
    #endif
39675
        /* Set issuer, issuer key hash and serial number of certificate being
39676
         * checked. */
39677
        SetASN_Buffer(&dataASN[OCSPREQUESTASN_IDX_TBS_REQ_ISSUER],
39678
                req->issuerHash, keyIdSz);
39679
        SetASN_Buffer(&dataASN[OCSPREQUESTASN_IDX_TBS_REQ_ISSUERKEY],
39680
                req->issuerKeyHash, keyIdSz);
39681
        SetASN_Buffer(&dataASN[OCSPREQUESTASN_IDX_TBS_REQ_SERIAL],
39682
                req->serial, (word32)req->serialSz);
39683
        /* Only extension to write is nonce - check if one to encode. */
39684
        if (req->nonceSz) {
39685
            /* Get size of extensions and leave space for them in encoding. */
39686
            ret = (int)(extSz = EncodeOcspRequestExtensions(req, NULL, 0));
39687
            SetASN_Buffer(&dataASN[OCSPREQUESTASN_IDX_TBS_REQEXT], NULL, extSz);
39688
            if (ret > 0) {
39689
                ret = 0;
39690
            }
39691
        }
39692
        else {
39693
            /* Don't write out extensions. */
39694
            dataASN[OCSPREQUESTASN_IDX_TBS_REQEXT].noOut = 1;
39695
        }
39696
    }
39697
    if (ret == 0) {
39698
        /* Calculate size of encoding. */
39699
        ret = SizeASN_Items(ocspRequestASN, dataASN, ocspRequestASN_Length,
39700
                &sz);
39701
    }
39702
    /* Check buffer big enough for encoding if supplied. */
39703
    if ((ret == 0) && (output != NULL) && (sz > (int)size)) {
39704
        ret = BUFFER_E;
39705
    }
39706
    if ((ret == 0) && (output != NULL)) {
39707
        /* Encode OCSPRequest. */
39708
        SetASN_Items(ocspRequestASN, dataASN, ocspRequestASN_Length, output);
39709
        if (req->nonceSz) {
39710
            /* Encode extensions into space provided. */
39711
            ret = (int)EncodeOcspRequestExtensions(req,
39712
                (byte*)dataASN[OCSPREQUESTASN_IDX_TBS_REQEXT].data.buffer.data,
39713
                extSz);
39714
            if (ret > 0) {
39715
                ret = 0;
39716
            }
39717
        }
39718
    }
39719
39720
    if (ret == 0) {
39721
        /* Return size of encoding. */
39722
        ret = sz;
39723
    }
39724
39725
    FREE_ASNSETDATA(dataASN, req->heap);
39726
    return ret;
39727
#endif /* WOLFSSL_ASN_TEMPLATE */
39728
}
39729
39730
39731
int InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce,
39732
                                                                     void* heap)
39733
{
39734
    int ret;
39735
39736
    WOLFSSL_ENTER("InitOcspRequest");
39737
39738
    if (req == NULL)
39739
        return BAD_FUNC_ARG;
39740
39741
    XMEMSET(req, 0, sizeof(OcspRequest));
39742
    req->heap = heap;
39743
39744
    if (cert) {
39745
        XMEMCPY(req->issuerHash,    cert->issuerHash,    KEYID_SIZE);
39746
        XMEMCPY(req->issuerKeyHash, cert->issuerKeyHash, KEYID_SIZE);
39747
39748
        req->serial = (byte*)XMALLOC((size_t)cert->serialSz, req->heap,
39749
                                                     DYNAMIC_TYPE_OCSP_REQUEST);
39750
        if (req->serial == NULL)
39751
            return MEMORY_E;
39752
39753
        XMEMCPY(req->serial, cert->serial, (size_t)cert->serialSz);
39754
        req->serialSz = cert->serialSz;
39755
39756
        if (cert->extAuthInfoSz != 0 && cert->extAuthInfo != NULL) {
39757
            req->url = (byte*)XMALLOC((size_t)cert->extAuthInfoSz + 1,
39758
                                          req->heap, DYNAMIC_TYPE_OCSP_REQUEST);
39759
            if (req->url == NULL) {
39760
                XFREE(req->serial, req->heap, DYNAMIC_TYPE_OCSP);
39761
                req->serial = NULL;
39762
                return MEMORY_E;
39763
            }
39764
39765
            XMEMCPY(req->url, cert->extAuthInfo, (size_t)cert->extAuthInfoSz);
39766
            req->urlSz = cert->extAuthInfoSz;
39767
            req->url[req->urlSz] = 0;
39768
        }
39769
    }
39770
39771
    if (useNonce) {
39772
        WC_RNG rng;
39773
39774
    #ifndef HAVE_FIPS
39775
        ret = wc_InitRng_ex(&rng, req->heap, INVALID_DEVID);
39776
    #else
39777
        ret = wc_InitRng(&rng);
39778
    #endif
39779
        if (ret != 0) {
39780
            WOLFSSL_MSG("\tCannot initialize RNG. Skipping the OCSP Nonce.");
39781
        } else {
39782
            if (wc_RNG_GenerateBlock(&rng, req->nonce, MAX_OCSP_NONCE_SZ) != 0)
39783
                WOLFSSL_MSG("\tCannot run RNG. Skipping the OCSP Nonce.");
39784
            else
39785
                req->nonceSz = MAX_OCSP_NONCE_SZ;
39786
39787
            wc_FreeRng(&rng);
39788
        }
39789
    }
39790
39791
    return 0;
39792
}
39793
39794
void FreeOcspRequest(OcspRequest* req)
39795
{
39796
    WOLFSSL_ENTER("FreeOcspRequest");
39797
39798
    if (req) {
39799
        XFREE(req->serial, req->heap, DYNAMIC_TYPE_OCSP_REQUEST);
39800
        req->serial = NULL;
39801
39802
#ifdef OPENSSL_EXTRA
39803
        if (req->serialInt) {
39804
            if (req->serialInt->isDynamic) {
39805
                XFREE(req->serialInt->data, NULL, DYNAMIC_TYPE_OPENSSL);
39806
            }
39807
            XFREE(req->serialInt, NULL, DYNAMIC_TYPE_OPENSSL);
39808
        }
39809
        req->serialInt = NULL;
39810
#endif
39811
39812
        XFREE(req->url, req->heap, DYNAMIC_TYPE_OCSP_REQUEST);
39813
        req->url = NULL;
39814
39815
#ifdef OPENSSL_EXTRA
39816
        if (req->cid != NULL)
39817
            wolfSSL_OCSP_CERTID_free((WOLFSSL_OCSP_CERTID*)req->cid);
39818
        req->cid = NULL;
39819
#endif
39820
    }
39821
}
39822
39823
39824
int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp)
39825
{
39826
    int cmp = -1; /* default as not matching, cmp gets set on each check */
39827
    int ocspDigestSize;
39828
    OcspEntry *single, *next, *prev = NULL, *top;
39829
39830
    WOLFSSL_ENTER("CompareOcspReqResp");
39831
39832
    if (req == NULL) {
39833
        WOLFSSL_MSG("\tReq missing");
39834
        return -1;
39835
    }
39836
    if (resp == NULL || resp->single == NULL) {
39837
        WOLFSSL_MSG("\tResp missing");
39838
        return 1;
39839
    }
39840
39841
    /* Nonces are not critical. The responder may not necessarily add
39842
     * the nonce to the response. */
39843
    if (req->nonceSz && resp->nonce != NULL
39844
#ifndef WOLFSSL_FORCE_OCSP_NONCE_CHECK
39845
            && resp->nonceSz != 0
39846
#endif
39847
    ) {
39848
        cmp = req->nonceSz - resp->nonceSz;
39849
        if (cmp != 0) {
39850
            WOLFSSL_MSG("\tnonceSz mismatch");
39851
            return cmp;
39852
        }
39853
39854
        cmp = XMEMCMP(req->nonce, resp->nonce, (size_t)req->nonceSz);
39855
        if (cmp != 0) {
39856
            WOLFSSL_MSG("\tnonce mismatch");
39857
            return cmp;
39858
        }
39859
    }
39860
39861
    /* match based on found status and return */
39862
    for (single = resp->single; single; single = next) {
39863
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
39864
        ocspDigestSize = wc_HashGetDigestSize(
39865
            wc_OidGetHash(single->hashAlgoOID));
39866
    #else
39867
        ocspDigestSize = OCSP_DIGEST_SIZE;
39868
    #endif
39869
        cmp = req->serialSz - single->status->serialSz;
39870
        if (cmp == 0) {
39871
            cmp = XMEMCMP(req->serial, single->status->serial,
39872
                                                          (size_t)req->serialSz)
39873
               || XMEMCMP(req->issuerHash, single->issuerHash,
39874
                                                         (size_t)ocspDigestSize)
39875
               || XMEMCMP(req->issuerKeyHash, single->issuerKeyHash,
39876
                                                        (size_t)ocspDigestSize);
39877
            if (cmp == 0) {
39878
                /* match found */
39879
                if (resp->single != single && prev) {
39880
                    /* move to top of list */
39881
                    top = resp->single;
39882
                    resp->single = single;
39883
                    prev->next = single->next;
39884
                    single->next = top;
39885
                }
39886
                break;
39887
            }
39888
        }
39889
        next = single->next;
39890
        prev = single;
39891
    }
39892
39893
    if (cmp != 0) {
39894
        WOLFSSL_MSG("\trequest and response mismatch");
39895
        return cmp;
39896
    }
39897
39898
    return 0;
39899
}
39900
39901
#endif /* HAVE_OCSP */
39902
39903
39904
#ifdef WOLFSSL_ASN_TEMPLATE
39905
/* ASN.1 template for certificate name hash. */
39906
static const ASNItem nameHashASN[] = {
39907
/* OID  */ { 0, ASN_OBJECT_ID, 0, 0, 1 },
39908
/* NAME */ { 0, ASN_SEQUENCE, 1, 0, 0 },
39909
};
39910
enum {
39911
    NAMEHASHASN_IDX_OID = 0,
39912
    NAMEHASHASN_IDX_NAME
39913
};
39914
39915
/* Number of items in ASN.1 template for certificate name hash. */
39916
0
#define nameHashASN_Length (sizeof(nameHashASN) / sizeof(ASNItem))
39917
#endif /* WOLFSSL_ASN_TEMPLATE */
39918
39919
/* store WC_SHA hash of NAME */
39920
int GetNameHash(const byte* source, word32* idx, byte* hash, int maxIdx)
39921
0
{
39922
    /* Use summy signature OID. */
39923
0
    return GetNameHash_ex(source, idx, hash, maxIdx, 0);
39924
0
}
39925
39926
/* store WC_SHA hash of NAME */
39927
int GetNameHash_ex(const byte* source, word32* idx, byte* hash, int maxIdx,
39928
    word32 sigOID)
39929
0
{
39930
#ifndef WOLFSSL_ASN_TEMPLATE
39931
    int    length;  /* length of all distinguished names */
39932
    int    ret;
39933
    word32 dummy;
39934
    byte   tag;
39935
39936
    WOLFSSL_ENTER("GetNameHash");
39937
39938
    dummy = *idx;
39939
    if (GetASNTag(source, &dummy, &tag, (word32)maxIdx) == 0 &&
39940
            tag == ASN_OBJECT_ID) {
39941
        WOLFSSL_MSG("Trying optional prefix...");
39942
39943
        if (GetLength(source, idx, &length, (word32)maxIdx) < 0)
39944
            return ASN_PARSE_E;
39945
39946
        *idx += (word32)length;
39947
        WOLFSSL_MSG("Got optional prefix");
39948
    }
39949
39950
    /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
39951
     * calculated over the entire DER encoding of the Name field, including
39952
     * the tag and length. */
39953
    dummy = *idx;
39954
    if (GetSequence(source, idx, &length, (word32)maxIdx) < 0)
39955
        return ASN_PARSE_E;
39956
39957
    ret = CalcHashId_ex(source + dummy, (word32)length + *idx - dummy, hash,
39958
        HashIdAlg(sigOID));
39959
39960
    *idx += (word32)length;
39961
39962
    return ret;
39963
#else
39964
0
    ASNGetData dataASN[nameHashASN_Length];
39965
0
    int ret;
39966
39967
0
    XMEMSET(dataASN, 0, sizeof(dataASN));
39968
    /* Ignore the OID even when present. */
39969
0
    GetASN_OID(&dataASN[NAMEHASHASN_IDX_OID], oidIgnoreType);
39970
    /* Decode certificate name. */
39971
0
    ret = GetASN_Items(nameHashASN, dataASN, nameHashASN_Length, 0, source, idx,
39972
0
           (word32)maxIdx);
39973
0
    if (ret == 0) {
39974
        /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
39975
         * calculated over the entire DER encoding of the Name field, including
39976
         * the tag and length. */
39977
        /* Calculate hash of complete name including SEQUENCE. */
39978
0
        ret = CalcHashId_ex(
39979
0
                GetASNItem_Addr(dataASN[NAMEHASHASN_IDX_NAME], source),
39980
0
                GetASNItem_Length(dataASN[NAMEHASHASN_IDX_NAME], source),
39981
0
                hash, HashIdAlg(sigOID));
39982
0
    }
39983
39984
0
    return ret;
39985
0
#endif /* WOLFSSL_ASN_TEMPLATE */
39986
0
}
39987
39988
#if defined(HAVE_CRL) && !defined(WOLFCRYPT_ONLY)
39989
39990
#ifdef OPENSSL_EXTRA
39991
static char* GetNameFromDer(const byte* source, int sz)
39992
{
39993
    char* out;
39994
39995
    out = (char*)XMALLOC((size_t)sz, NULL, DYNAMIC_TYPE_OPENSSL);
39996
    if (out == NULL) {
39997
        WOLFSSL_MSG("Name malloc failed");
39998
        return NULL;
39999
    }
40000
40001
    XMEMCPY(out, source, (size_t)sz);
40002
40003
    return out;
40004
}
40005
#endif
40006
40007
/* initialize decoded CRL */
40008
void InitDecodedCRL(DecodedCRL* dcrl, void* heap)
40009
{
40010
    WOLFSSL_MSG("InitDecodedCRL");
40011
40012
    XMEMSET(dcrl, 0, sizeof(DecodedCRL));
40013
    dcrl->heap = heap;
40014
#ifdef WOLFSSL_HEAP_TEST
40015
    dcrl->heap = (void*)WOLFSSL_HEAP_TEST;
40016
#endif
40017
}
40018
40019
40020
/* free decoded CRL resources */
40021
void FreeDecodedCRL(DecodedCRL* dcrl)
40022
{
40023
    RevokedCert* tmp = dcrl->certs;
40024
40025
    WOLFSSL_MSG("FreeDecodedCRL");
40026
40027
    while(tmp) {
40028
        RevokedCert* next = tmp->next;
40029
        XFREE(tmp, dcrl->heap, DYNAMIC_TYPE_REVOKED);
40030
        tmp = next;
40031
    }
40032
#ifdef OPENSSL_EXTRA
40033
    XFREE(dcrl->issuer, NULL, DYNAMIC_TYPE_OPENSSL);
40034
#endif
40035
}
40036
40037
40038
#ifdef WOLFSSL_ASN_TEMPLATE
40039
/* ASN.1 template for revoked certificates.
40040
 * X.509: RFC 5280, 5.1 - CRL Fields
40041
 */
40042
static const ASNItem revokedASN[] = {
40043
/* SEQ      */    { 0, ASN_SEQUENCE, 1, 1, 0 },
40044
                                     /* userCertificate    CertificateSerialNumber */
40045
/* CERT     */        { 1, ASN_INTEGER, 0, 0, 0 },
40046
                                     /* revocationDate     Time */
40047
/* TIME_UTC */        { 1, ASN_UTC_TIME, 0, 0, 2 },
40048
/* TIME_GT  */        { 1, ASN_GENERALIZED_TIME, 0, 0, 2 },
40049
                                     /* crlEntryExensions  Extensions */
40050
/* TIME_EXT */        { 1, ASN_SEQUENCE, 1, 0, 1 },
40051
};
40052
enum {
40053
    REVOKEDASN_IDX_SEQ = 0,
40054
    REVOKEDASN_IDX_CERT,
40055
    REVOKEDASN_IDX_TIME_UTC,
40056
    REVOKEDASN_IDX_TIME_GT,
40057
    REVOKEDASN_IDX_TIME_EXT,
40058
};
40059
40060
/* Number of items in ASN.1 template for revoked certificates. */
40061
#define revokedASN_Length (sizeof(revokedASN) / sizeof(ASNItem))
40062
#endif
40063
40064
/* Get Revoked Cert list, 0 on success */
40065
static int GetRevoked(RevokedCert* rcert, const byte* buff, word32* idx,
40066
                      DecodedCRL* dcrl, word32 maxIdx)
40067
{
40068
#ifndef WOLFSSL_ASN_TEMPLATE
40069
    int ret;
40070
    int len;
40071
    word32 end;
40072
    RevokedCert* rc;
40073
#ifdef CRL_STATIC_REVOKED_LIST
40074
    int totalCerts = 0;
40075
#endif
40076
    WOLFSSL_ENTER("GetRevoked");
40077
40078
    if (GetSequence(buff, idx, &len, maxIdx) < 0)
40079
        return ASN_PARSE_E;
40080
40081
    end = *idx + len;
40082
40083
#ifdef CRL_STATIC_REVOKED_LIST
40084
    totalCerts = dcrl->totalCerts;
40085
40086
    if (totalCerts >= CRL_MAX_REVOKED_CERTS) {
40087
        return MEMORY_E;
40088
    }
40089
40090
    rc = &rcert[totalCerts];
40091
    ret = wc_GetSerialNumber(buff, idx, rc->serialNumber, &rc->serialSz,maxIdx);
40092
    if (ret < 0) {
40093
        WOLFSSL_MSG("wc_GetSerialNumber error");
40094
        return ret;
40095
    }
40096
#else
40097
40098
    rc = (RevokedCert*)XMALLOC(sizeof(RevokedCert), dcrl->heap,
40099
                                                          DYNAMIC_TYPE_REVOKED);
40100
    if (rc == NULL) {
40101
        WOLFSSL_MSG("Alloc Revoked Cert failed");
40102
        return MEMORY_E;
40103
    }
40104
    ret = wc_GetSerialNumber(buff, idx, rc->serialNumber, &rc->serialSz,maxIdx);
40105
    if (ret < 0) {
40106
        WOLFSSL_MSG("wc_GetSerialNumber error");
40107
        XFREE(rc, dcrl->heap, DYNAMIC_TYPE_REVOKED);
40108
        return ret;
40109
    }
40110
    /* add to list */
40111
    rc->next = dcrl->certs;
40112
    dcrl->certs = rc;
40113
40114
    (void)rcert;
40115
#endif /* CRL_STATIC_REVOKED_LIST */
40116
    dcrl->totalCerts++;
40117
    /* get date */
40118
#ifndef NO_ASN_TIME
40119
    ret = GetBasicDate(buff, idx, rc->revDate, &rc->revDateFormat, maxIdx);
40120
    if (ret < 0) {
40121
        WOLFSSL_MSG("Expecting Date");
40122
        return ret;
40123
    }
40124
#endif
40125
    /* skip extensions */
40126
    *idx = end;
40127
40128
    return 0;
40129
#else
40130
    DECL_ASNGETDATA(dataASN, revokedASN_Length);
40131
    int ret = 0;
40132
    word32 serialSz = EXTERNAL_SERIAL_SIZE;
40133
    word32 revDateSz = MAX_DATE_SIZE;
40134
    RevokedCert* rc;
40135
#ifdef CRL_STATIC_REVOKED_LIST
40136
    int totalCerts = dcrl->totalCerts;
40137
40138
    if (totalCerts >= CRL_MAX_REVOKED_CERTS) {
40139
        return MEMORY_E;
40140
    }
40141
40142
    rc = &rcert[totalCerts];
40143
40144
#else
40145
    /* Allocate a new revoked certificate object. */
40146
    rc = (RevokedCert*)XMALLOC(sizeof(RevokedCert), dcrl->heap,
40147
            DYNAMIC_TYPE_CRL);
40148
    if (rc == NULL) {
40149
        ret = MEMORY_E;
40150
    }
40151
#endif /* CRL_STATIC_REVOKED_LIST */
40152
40153
    CALLOC_ASNGETDATA(dataASN, revokedASN_Length, ret, dcrl->heap);
40154
40155
    if (ret == 0) {
40156
        /* Set buffer to place serial number into. */
40157
        GetASN_Buffer(&dataASN[REVOKEDASN_IDX_CERT], rc->serialNumber,
40158
                &serialSz);
40159
        /* Set buffer to store revocation date. */
40160
        GetASN_Buffer(&dataASN[REVOKEDASN_IDX_TIME_UTC], rc->revDate,
40161
                &revDateSz);
40162
        GetASN_Buffer(&dataASN[REVOKEDASN_IDX_TIME_GT], rc->revDate,
40163
                &revDateSz);
40164
        /* Decode the Revoked */
40165
        ret = GetASN_Items(revokedASN, dataASN, revokedASN_Length, 1, buff, idx,
40166
                maxIdx);
40167
    }
40168
    if (ret == 0) {
40169
        /* Store size of serial number. */
40170
        rc->serialSz = (int)serialSz;
40171
        rc->revDateFormat = (dataASN[REVOKEDASN_IDX_TIME_UTC].tag != 0)
40172
                ? dataASN[REVOKEDASN_IDX_TIME_UTC].tag
40173
                : dataASN[REVOKEDASN_IDX_TIME_GT].tag;
40174
40175
        /* TODO: use extensions, only v2 */
40176
        /* Add revoked certificate to chain. */
40177
#ifndef CRL_STATIC_REVOKED_LIST
40178
        rc->next = dcrl->certs;
40179
        dcrl->certs = rc;
40180
#endif
40181
        dcrl->totalCerts++;
40182
    }
40183
40184
    FREE_ASNGETDATA(dataASN, dcrl->heap);
40185
#ifndef CRL_STATIC_REVOKED_LIST
40186
    if ((ret != 0) && (rc != NULL)) {
40187
        XFREE(rc, dcrl->heap, DYNAMIC_TYPE_CRL);
40188
    }
40189
    (void)rcert;
40190
#endif
40191
    return ret;
40192
#endif /* WOLFSSL_ASN_TEMPLATE */
40193
}
40194
40195
#ifdef WOLFSSL_ASN_TEMPLATE
40196
/* Parse the revoked certificates of a CRL.
40197
 *
40198
 * @param [in] dcrl    Decoded CRL object.
40199
 * @param [in] buff    Buffer holding CRL.
40200
 * @param [in] idx     Index into buffer of revoked certificates.
40201
 * @param [in] maxIdx  Maximum index of revoked cartificates data.
40202
 * @return  0 on success.
40203
 * @return  ASN_PARSE_E on failure.
40204
 */
40205
static int ParseCRL_RevokedCerts(RevokedCert* rcert, DecodedCRL* dcrl,
40206
                                 const byte* buff, word32 idx, word32 maxIdx)
40207
{
40208
    int ret = 0;
40209
40210
    /* Parse each revoked certificate. */
40211
    while ((ret == 0) && (idx < maxIdx)) {
40212
        /* Parse a revoked certificate. */
40213
        if (GetRevoked(rcert, buff, &idx, dcrl, maxIdx) < 0) {
40214
            ret = ASN_PARSE_E;
40215
        }
40216
    }
40217
40218
    return ret;
40219
}
40220
#endif /* WOLFSSL_ASN_TEMPLATE */
40221
40222
#ifndef WOLFSSL_ASN_TEMPLATE
40223
/* Get CRL Signature, 0 on success */
40224
static int GetCRL_Signature(const byte* source, word32* idx, DecodedCRL* dcrl,
40225
                            int maxIdx)
40226
{
40227
    int    length;
40228
    int    ret;
40229
40230
    WOLFSSL_ENTER("GetCRL_Signature");
40231
40232
    ret = CheckBitString(source, idx, &length, maxIdx, 1, NULL);
40233
    if (ret != 0)
40234
        return ret;
40235
    dcrl->sigLength = length;
40236
40237
    dcrl->signature = (byte*)&source[*idx];
40238
    *idx += dcrl->sigLength;
40239
40240
    return 0;
40241
}
40242
#endif /* !WOLFSSL_ASN_TEMPLATE */
40243
40244
int VerifyCRL_Signature(SignatureCtx* sigCtx, const byte* toBeSigned,
40245
                        word32 tbsSz, const byte* signature, word32 sigSz,
40246
                        word32 signatureOID, const byte* sigParams,
40247
                        int sigParamsSz, Signer *ca, void* heap)
40248
{
40249
    /* try to confirm/verify signature */
40250
#ifndef IGNORE_KEY_EXTENSIONS
40251
    if ((ca->keyUsage & KEYUSE_CRL_SIGN) == 0) {
40252
        WOLFSSL_MSG("CA cannot sign CRLs");
40253
        WOLFSSL_ERROR_VERBOSE(ASN_CRL_NO_SIGNER_E);
40254
        return ASN_CRL_NO_SIGNER_E;
40255
    }
40256
#endif /* IGNORE_KEY_EXTENSIONS */
40257
40258
    InitSignatureCtx(sigCtx, heap, INVALID_DEVID);
40259
    if (ConfirmSignature(sigCtx, toBeSigned, tbsSz, ca->publicKey,
40260
                         ca->pubKeySize, ca->keyOID, signature, sigSz,
40261
                         signatureOID, sigParams, (word32)sigParamsSz, NULL) != 0) {
40262
        WOLFSSL_MSG("CRL Confirm signature failed");
40263
        WOLFSSL_ERROR_VERBOSE(ASN_CRL_CONFIRM_E);
40264
        return ASN_CRL_CONFIRM_E;
40265
    }
40266
40267
    return 0;
40268
}
40269
40270
#ifdef WOLFSSL_ASN_TEMPLATE
40271
/* Find the signer for the CRL and verify the signature.
40272
 *
40273
 * @param [in] dcrl  Decoded CRL object.
40274
 * @param [in] buff  Buffer holding CRL.
40275
 * @param [in] cm    Certificate manager object.
40276
 * @return  0 on success.
40277
 * @return  ASN_CRL_NO_SIGNER_E when no signer found.
40278
 * @return  ASN_CRL_CONFIRM_E when signature did not verify.
40279
 */
40280
static int PaseCRL_CheckSignature(DecodedCRL* dcrl, const byte* sigParams,
40281
    int sigParamsSz, const byte* buff, void* cm)
40282
{
40283
    int ret = 0;
40284
    Signer* ca = NULL;
40285
    SignatureCtx sigCtx;
40286
40287
    /* OpenSSL doesn't add skid by default for CRLs cause firefox chokes.
40288
     * If experiencing issues uncomment NO_SKID define in CRL section of
40289
     * wolfssl/wolfcrypt/settings.h */
40290
#ifndef NO_SKID
40291
    if (dcrl->extAuthKeyIdSet) {
40292
        /* more unique than issuerHash */
40293
        ca = GetCA(cm, dcrl->extAuthKeyId);
40294
    }
40295
    /* Check issuerHash matched CA's subjectNameHash. */
40296
    if ((ca != NULL) && (XMEMCMP(dcrl->issuerHash, ca->subjectNameHash,
40297
            KEYID_SIZE) != 0)) {
40298
        ca = NULL;
40299
    }
40300
    if (ca == NULL) {
40301
        ca = GetCAByName(cm, dcrl->issuerHash); /* last resort */
40302
        /* If AKID is available then this CA doesn't have the public
40303
         * key required */
40304
        if (ca && dcrl->extAuthKeyIdSet) {
40305
            WOLFSSL_MSG("CA SKID doesn't match AKID");
40306
            ca = NULL;
40307
        }
40308
    }
40309
#else
40310
    ca = GetCA(cm, dcrl->issuerHash);
40311
#endif /* !NO_SKID */
40312
    WOLFSSL_MSG("About to verify CRL signature");
40313
40314
    if (ca == NULL) {
40315
        WOLFSSL_MSG("Did NOT find CRL issuer CA");
40316
        ret = ASN_CRL_NO_SIGNER_E;
40317
        WOLFSSL_ERROR_VERBOSE(ret);
40318
    }
40319
40320
    if (ret == 0) {
40321
        WOLFSSL_MSG("Found CRL issuer CA");
40322
        /* Verify CRL signature with CA. */
40323
        ret = VerifyCRL_Signature(&sigCtx, buff + dcrl->certBegin,
40324
           dcrl->sigIndex - dcrl->certBegin, dcrl->signature, dcrl->sigLength,
40325
           dcrl->signatureOID, sigParams, sigParamsSz, ca, dcrl->heap);
40326
    }
40327
40328
    return ret;
40329
}
40330
#endif
40331
40332
#ifndef WOLFSSL_ASN_TEMPLATE
40333
static int ParseCRL_CertList(RevokedCert* rcert, DecodedCRL* dcrl,
40334
                           const byte* buf,word32* inOutIdx, int sz, int verify)
40335
{
40336
    word32 oid, dateIdx, idx, checkIdx;
40337
    int length;
40338
#ifdef WOLFSSL_NO_CRL_NEXT_DATE
40339
    int doNextDate = 1;
40340
#endif
40341
    byte tag;
40342
40343
    if (dcrl == NULL || inOutIdx == NULL || buf == NULL) {
40344
        return BAD_FUNC_ARG;
40345
    }
40346
40347
    /* may have version */
40348
    idx = *inOutIdx;
40349
40350
    checkIdx = idx;
40351
    if (GetASNTag(buf, &checkIdx, &tag, sz) == 0 && tag == ASN_INTEGER) {
40352
        if (GetMyVersion(buf, &idx, &dcrl->version, sz) < 0)
40353
            return ASN_PARSE_E;
40354
        dcrl->version++;
40355
    }
40356
40357
    if (GetAlgoId(buf, &idx, &oid, oidIgnoreType, sz) < 0) {
40358
        return ASN_PARSE_E;
40359
    }
40360
#ifdef WC_RSA_PSS
40361
    else if (oid == CTC_RSASSAPSS) {
40362
        word32 tmpSz;
40363
        int len;
40364
40365
        tmpSz = idx;
40366
        dcrl->sigParamsIndex = idx;
40367
        if (GetSequence(buf, &idx, &len, sz) < 0) {
40368
            dcrl->sigParamsIndex = 0;
40369
            return ASN_PARSE_E;
40370
        }
40371
        idx += len;
40372
        dcrl->sigParamsLength = idx - tmpSz;
40373
    }
40374
#endif
40375
40376
    checkIdx = idx;
40377
    if (GetSequence(buf, &checkIdx, &length, sz) < 0) {
40378
        return ASN_PARSE_E;
40379
    }
40380
#ifdef OPENSSL_EXTRA
40381
    dcrl->issuerSz = length + (checkIdx - idx);
40382
    dcrl->issuer   = (byte*)GetNameFromDer(buf + idx, (int)dcrl->issuerSz);
40383
#endif
40384
40385
    if (GetNameHash_ex(buf, &idx, dcrl->issuerHash, sz, oid) < 0)
40386
        return ASN_PARSE_E;
40387
40388
    if (GetBasicDate(buf, &idx, dcrl->lastDate, &dcrl->lastDateFormat, sz) < 0)
40389
        return ASN_PARSE_E;
40390
40391
    dateIdx = idx;
40392
40393
    if (GetBasicDate(buf, &idx, dcrl->nextDate, &dcrl->nextDateFormat, sz) < 0)
40394
    {
40395
#ifndef WOLFSSL_NO_CRL_NEXT_DATE
40396
        (void)dateIdx;
40397
        return ASN_PARSE_E;
40398
#else
40399
        dcrl->nextDateFormat = ASN_OTHER_TYPE;  /* skip flag */
40400
        doNextDate = 0;
40401
        idx = dateIdx;
40402
#endif
40403
    }
40404
40405
#ifdef WOLFSSL_NO_CRL_NEXT_DATE
40406
    if (doNextDate)
40407
#endif
40408
    {
40409
#if !defined(NO_ASN_TIME) && !defined(WOLFSSL_NO_CRL_DATE_CHECK)
40410
        if (verify != NO_VERIFY &&
40411
            (! AsnSkipDateCheck) &&
40412
            !XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, ASN_AFTER)) {
40413
            WOLFSSL_MSG("CRL after date is no longer valid");
40414
            WOLFSSL_ERROR_VERBOSE(CRL_CERT_DATE_ERR);
40415
            return CRL_CERT_DATE_ERR;
40416
        }
40417
#else
40418
        (void)verify;
40419
#endif
40420
    }
40421
40422
    checkIdx = idx;
40423
    if (idx != dcrl->sigIndex &&
40424
           GetASNTag(buf, &checkIdx, &tag, sz) == 0 && tag != CRL_EXTENSIONS) {
40425
40426
        int len;
40427
40428
        if (GetSequence(buf, &idx, &len, sz) < 0)
40429
            return ASN_PARSE_E;
40430
        len += idx;
40431
40432
        while (idx < (word32)len) {
40433
            if (GetRevoked(rcert, buf, &idx, dcrl, len) < 0)
40434
                return ASN_PARSE_E;
40435
        }
40436
    }
40437
40438
    *inOutIdx = idx;
40439
40440
    return 0;
40441
}
40442
#endif /* !WOLFSSL_ASN_TEMPLATE */
40443
40444
40445
#ifndef NO_SKID
40446
static int ParseCRL_AuthKeyIdExt(const byte* input, int sz, DecodedCRL* dcrl)
40447
{
40448
#ifndef WOLFSSL_ASN_TEMPLATE
40449
    word32 idx = 0;
40450
    int length = 0, ret = 0;
40451
    byte tag;
40452
40453
    WOLFSSL_ENTER("ParseCRL_AuthKeyIdExt");
40454
40455
    if (GetSequence(input, &idx, &length, sz) < 0) {
40456
        WOLFSSL_MSG("\tfail: should be a SEQUENCE");
40457
        return ASN_PARSE_E;
40458
    }
40459
40460
    if (GetASNTag(input, &idx, &tag, sz) < 0) {
40461
        return ASN_PARSE_E;
40462
    }
40463
40464
    if (tag != (ASN_CONTEXT_SPECIFIC | 0)) {
40465
        WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available");
40466
        return 0;
40467
    }
40468
40469
    if (GetLength(input, &idx, &length, sz) <= 0) {
40470
        WOLFSSL_MSG("\tfail: extension data length");
40471
        return ASN_PARSE_E;
40472
    }
40473
40474
    dcrl->extAuthKeyIdSet = 1;
40475
40476
    /* Get the hash or hash of the hash if wrong size. */
40477
    ret = GetHashId(input + idx, length, dcrl->extAuthKeyId,
40478
        HashIdAlg(dcrl->signatureOID));
40479
40480
    return ret;
40481
#else
40482
    DECL_ASNGETDATA(dataASN, authKeyIdASN_Length);
40483
    int ret = 0;
40484
    word32 idx = 0;
40485
40486
    WOLFSSL_ENTER("ParseCRL_AuthKeyIdExt");
40487
40488
    CALLOC_ASNGETDATA(dataASN, authKeyIdASN_Length, ret, dcrl->heap);
40489
40490
    if (ret == 0) {
40491
        /* Parse an authority key identifier. */
40492
        ret = GetASN_Items(authKeyIdASN, dataASN, authKeyIdASN_Length, 1, input,
40493
                           &idx, (word32)sz);
40494
    }
40495
    if (ret == 0) {
40496
        /* Key id is optional. */
40497
        if (dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data == NULL) {
40498
            WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available");
40499
        }
40500
        else {
40501
            dcrl->extAuthKeyIdSet = 1;
40502
40503
            /* Get the hash or hash of the hash if wrong size. */
40504
            ret = GetHashId(dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data,
40505
                (int)dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.length,
40506
                dcrl->extAuthKeyId, HashIdAlg(dcrl->signatureOID));
40507
        }
40508
    }
40509
40510
    FREE_ASNGETDATA(dataASN, dcrl->heap);
40511
    return ret;
40512
#endif /* WOLFSSL_ASN_TEMPLATE */
40513
}
40514
#endif
40515
40516
#ifndef WOLFSSL_ASN_TEMPLATE
40517
static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf,
40518
        word32* inOutIdx, word32 sz)
40519
{
40520
    int length;
40521
    word32 idx;
40522
    word32 ext_bound; /* boundary index for the sequence of extensions */
40523
    word32 oid;
40524
    byte tag;
40525
40526
    WOLFSSL_ENTER("ParseCRL_Extensions");
40527
    (void)dcrl;
40528
40529
    if (inOutIdx == NULL)
40530
        return BAD_FUNC_ARG;
40531
40532
    idx = *inOutIdx;
40533
40534
    /* CRL Extensions are optional */
40535
    if ((idx + 1) > sz)
40536
        return 0;
40537
40538
    /* CRL Extensions are optional */
40539
    if (GetASNTag(buf, &idx, &tag, sz) < 0)
40540
        return 0;
40541
40542
    /* CRL Extensions are optional */
40543
    if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
40544
        return 0;
40545
40546
    if (GetLength(buf, &idx, &length, sz) < 0)
40547
        return ASN_PARSE_E;
40548
40549
    if (GetSequence(buf, &idx, &length, sz) < 0)
40550
        return ASN_PARSE_E;
40551
40552
    ext_bound = idx + length;
40553
40554
    while (idx < (word32)ext_bound) {
40555
        word32 localIdx;
40556
        int ret;
40557
40558
        if (GetSequence(buf, &idx, &length, sz) < 0) {
40559
            WOLFSSL_MSG("\tfail: should be a SEQUENCE");
40560
            return ASN_PARSE_E;
40561
        }
40562
40563
        oid = 0;
40564
        if (GetObjectId(buf, &idx, &oid, oidCrlExtType, sz) < 0) {
40565
            WOLFSSL_MSG("\tfail: OBJECT ID");
40566
            return ASN_PARSE_E;
40567
        }
40568
40569
        /* check for critical flag */
40570
        if ((idx + 1) > (word32)sz) {
40571
            WOLFSSL_MSG("\tfail: malformed buffer");
40572
            return BUFFER_E;
40573
        }
40574
40575
        localIdx = idx;
40576
        if (GetASNTag(buf, &localIdx, &tag, sz) == 0 && tag == ASN_BOOLEAN) {
40577
            WOLFSSL_MSG("\tfound optional critical flag, moving past");
40578
            ret = GetBoolean(buf, &idx, sz);
40579
            if (ret < 0)
40580
                return ret;
40581
        }
40582
40583
        ret = GetOctetString(buf, &idx, &length, sz);
40584
        if (ret < 0)
40585
            return ret;
40586
40587
        if (oid == AUTH_KEY_OID) {
40588
        #ifndef NO_SKID
40589
            ret = ParseCRL_AuthKeyIdExt(buf + idx, length, dcrl);
40590
            if (ret < 0) {
40591
                WOLFSSL_MSG("\tcouldn't parse AuthKeyId extension");
40592
                return ret;
40593
            }
40594
        #endif
40595
        }
40596
        else if (oid == CRL_NUMBER_OID) {
40597
            localIdx = idx;
40598
            if (GetASNTag(buf, &localIdx, &tag, sz) == 0 &&
40599
                    tag == ASN_INTEGER) {
40600
                ret = GetASNInt(buf, &idx, &length, sz);
40601
                if (ret < 0) {
40602
                    WOLFSSL_MSG("\tcouldn't parse CRL number extension");
40603
                    return ret;
40604
                }
40605
                else {
40606
                    DECL_MP_INT_SIZE_DYN(m, CRL_MAX_NUM_SZ * CHAR_BIT,
40607
                                   CRL_MAX_NUM_SZ * CHAR_BIT);
40608
                    NEW_MP_INT_SIZE(m, CRL_MAX_NUM_SZ * CHAR_BIT, NULL,
40609
                                   DYNAMIC_TYPE_TMP_BUFFER);
40610
                #ifdef MP_INT_SIZE_CHECK_NULL
40611
                    if (m == NULL) {
40612
                        ret = MEMORY_E;
40613
                    }
40614
                #endif
40615
40616
                    if (ret == 0 && ((ret = INIT_MP_INT_SIZE(m, CRL_MAX_NUM_SZ
40617
                                    * CHAR_BIT)) != MP_OKAY)) {
40618
                        ret = MP_INIT_E;
40619
                    }
40620
40621
                    if (ret == MP_OKAY)
40622
                        ret = mp_read_unsigned_bin(m, buf + idx, length);
40623
40624
                    if (ret != MP_OKAY)
40625
                        ret = BUFFER_E;
40626
40627
                    if (ret == MP_OKAY && mp_toradix(m, (char*)dcrl->crlNumber,
40628
                                MP_RADIX_HEX) != MP_OKAY)
40629
                        ret = BUFFER_E;
40630
40631
                    if (ret == MP_OKAY) {
40632
                        dcrl->crlNumberSet = 1;
40633
                    }
40634
40635
                    FREE_MP_INT_SIZE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER);
40636
40637
                    if (ret != MP_OKAY)
40638
                        return ret;
40639
                }
40640
            }
40641
        }
40642
40643
        idx += length;
40644
    }
40645
40646
    *inOutIdx = idx;
40647
40648
    return 0;
40649
}
40650
#else
40651
/* Parse the extensions of a CRL.
40652
 *
40653
 * @param [in] dcrl    Decoded CRL object.
40654
 * @param [in] buff    Buffer holding CRL.
40655
 * @param [in] idx     Index into buffer of extensions.
40656
 * @param [in] maxIdx  Maximum index of extension data.
40657
 * @return  0 on success.
40658
 * @return  ASN_PARSE_E on failure.
40659
 */
40660
static int ParseCRL_Extensions(DecodedCRL* dcrl, const byte* buf, word32 idx,
40661
        word32 maxIdx)
40662
{
40663
    DECL_ASNGETDATA(dataASN, certExtASN_Length);
40664
    int ret = 0;
40665
    /* Track if we've seen these extensions already */
40666
    word32 seenAuthKey = 0;
40667
    word32 seenCrlNum = 0;
40668
40669
    ALLOC_ASNGETDATA(dataASN, certExtASN_Length, ret, dcrl->heap);
40670
40671
    while ((ret == 0) && (idx < maxIdx)) {
40672
        byte critical = 0;
40673
40674
        /* Clear dynamic data. */
40675
        XMEMSET(dataASN, 0, sizeof(*dataASN) * certExtASN_Length);
40676
        /* Ensure OID is an extension type. */
40677
        GetASN_OID(&dataASN[CERTEXTASN_IDX_OID], oidCertExtType);
40678
        /* Set criticality variable. */
40679
        GetASN_Int8Bit(&dataASN[CERTEXTASN_IDX_CRIT], &critical);
40680
        /* Parse extension wrapper. */
40681
        ret = GetASN_Items(certExtASN, dataASN, certExtASN_Length, 0, buf, &idx,
40682
                maxIdx);
40683
        if (ret == 0) {
40684
            word32 localIdx = idx;
40685
            /* OID in extension. */
40686
            word32 oid = dataASN[CERTEXTASN_IDX_OID].data.oid.sum;
40687
            /* Length of extension data. */
40688
            int length = (int)dataASN[CERTEXTASN_IDX_VAL].length;
40689
40690
            /* Check for duplicate extension. RFC 5280 Section 4.2 states that
40691
             * a certificate must not include more than one instance of a
40692
             * particular extension. Note that the same guidance does not appear
40693
             * for CRLs but the same reasoning should apply. */
40694
            if ((oid == AUTH_KEY_OID && seenAuthKey) ||
40695
                (oid == CRL_NUMBER_OID && seenCrlNum)) {
40696
                WOLFSSL_MSG("Duplicate CRL extension found");
40697
                /* Gating !WOLFSSL_NO_ASN_STRICT will allow wolfCLU to have same
40698
                 * behaviour as OpenSSL */
40699
#ifndef WOLFSSL_NO_ASN_STRICT
40700
                ret = ASN_PARSE_E;
40701
#endif
40702
            }
40703
40704
            /* Track this extension if no duplicate found */
40705
            if (ret == 0) {
40706
                if (oid == AUTH_KEY_OID)
40707
                    seenAuthKey = 1;
40708
                else if (oid == CRL_NUMBER_OID)
40709
                    seenCrlNum = 1;
40710
            }
40711
40712
            if (ret == 0) {
40713
                if (oid == AUTH_KEY_OID) {
40714
                #ifndef NO_SKID
40715
                    /* Parse Authority Key Id extension.
40716
                     * idx is at start of OCTET_STRING data. */
40717
                    ret = ParseCRL_AuthKeyIdExt(buf + localIdx, length, dcrl);
40718
                    if (ret != 0) {
40719
                        WOLFSSL_MSG("\tcouldn't parse AuthKeyId extension");
40720
                    }
40721
                #endif
40722
                }
40723
                else if (oid == CRL_NUMBER_OID) {
40724
                    DECL_MP_INT_SIZE_DYN(m, CRL_MAX_NUM_SZ * CHAR_BIT,
40725
                                   CRL_MAX_NUM_SZ * CHAR_BIT);
40726
                    NEW_MP_INT_SIZE(m, CRL_MAX_NUM_SZ * CHAR_BIT, NULL,
40727
                                   DYNAMIC_TYPE_TMP_BUFFER);
40728
40729
                #ifdef MP_INT_SIZE_CHECK_NULL
40730
                    if (m == NULL) {
40731
                        ret = MEMORY_E;
40732
                    }
40733
                #endif
40734
40735
                    if (ret == 0 && (INIT_MP_INT_SIZE(m, CRL_MAX_NUM_SZ *
40736
                        CHAR_BIT) != MP_OKAY)) {
40737
                        ret = MP_INIT_E;
40738
                    }
40739
40740
                    if (ret == 0) {
40741
                        ret = GetInt(m, buf, &localIdx, maxIdx);
40742
                    }
40743
40744
                    if (ret == 0 && mp_toradix(m, (char*)dcrl->crlNumber,
40745
                                 MP_RADIX_HEX) != MP_OKAY)
40746
                        ret = BUFFER_E;
40747
40748
                    if (ret == 0) {
40749
                        dcrl->crlNumberSet = 1;
40750
                    }
40751
40752
                    mp_free(m);
40753
                    FREE_MP_INT_SIZE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER);
40754
                }
40755
            }
40756
            /* TODO: check criticality */
40757
            /* Move index on to next extension. */
40758
            idx += (word32)length;
40759
        }
40760
    }
40761
40762
    if (ret < 0) {
40763
        ret = ASN_PARSE_E;
40764
    }
40765
40766
    FREE_ASNGETDATA(dataASN, dcrl->heap);
40767
40768
    return ret;
40769
}
40770
#endif /* !WOLFSSL_ASN_TEMPLATE */
40771
40772
40773
#ifdef WOLFSSL_ASN_TEMPLATE
40774
/* ASN.1 template for a CRL- CertificateList.
40775
 * X.509: RFC 5280, 5.1 - CRL Fields
40776
 */
40777
static const ASNItem crlASN[] = {
40778
                                       /* CertificateList */
40779
/* SEQ                */    { 0, ASN_SEQUENCE, 1, 1, 0 },
40780
                                           /* tbsCertList */
40781
/* TBS                */        { 1, ASN_SEQUENCE, 1, 1, 0 },
40782
                                               /* version     Version OPTIONAL if present must be v2 */
40783
/* TBS_VER            */            { 2, ASN_INTEGER, 0, 0, 1 },
40784
                                               /* signature */
40785
/* TBS_SIGALGO        */            { 2, ASN_SEQUENCE, 1, 1, 0 },
40786
/* TBS_SIGALGO_OID    */                { 3, ASN_OBJECT_ID, 0, 0, 0 },
40787
/* TBS_SIGALGO_NULL   */                { 3, ASN_TAG_NULL, 0, 0, 1 },
40788
                                               /* issuer */
40789
#ifdef WC_RSA_PSS
40790
/* TBS_SIGALGO_P_SEQ  */                { 3, ASN_SEQUENCE, 1, 0, 2 },
40791
#endif
40792
/* TBS_ISSUER         */            { 2, ASN_SEQUENCE, 1, 0, 0 },
40793
                                               /* thisUpdate */
40794
/* TBS_THISUPDATE_UTC */            { 2, ASN_UTC_TIME, 0, 0, 2 },
40795
/* TBS_THISUPDATE_GT  */            { 2, ASN_GENERALIZED_TIME, 0, 0, 2 },
40796
                                               /* nextUpdate */
40797
/* TBS_NEXTUPDATE_UTC */            { 2, ASN_UTC_TIME, 0, 0, 3 },
40798
/* TBS_NEXTUPDATE_GT  */            { 2, ASN_GENERALIZED_TIME, 0, 0, 3 },
40799
                                               /* revokedCertificates */
40800
/* TBS_REVOKEDCERTS   */            { 2, ASN_SEQUENCE, 1, 0, 1 },
40801
                                               /* crlExtensions */
40802
/* TBS_EXT            */            { 2, ASN_CONTEXT_SPECIFIC | 0, 1, 1, 1 },
40803
/* TBS_EXT_SEQ        */                { 3, ASN_SEQUENCE, 1, 0, 0 },
40804
                                           /* signatureAlgorithm */
40805
/* SIGALGO            */        { 1, ASN_SEQUENCE, 1, 1, 0 },
40806
/* SIGALGO_OID        */            { 2, ASN_OBJECT_ID, 0, 0, 0 },
40807
/* SIGALGO_NULL       */            { 2, ASN_TAG_NULL, 0, 0, 1 },
40808
#ifdef WC_RSA_PSS
40809
/* SIGALGO_PARAMS     */            { 2, ASN_SEQUENCE, 1, 0, 2 },
40810
#endif
40811
                                           /* signatureValue */
40812
/* SIGNATURE          */        { 1, ASN_BIT_STRING, 0, 0, 0 },
40813
};
40814
enum {
40815
    CRLASN_IDX_SEQ = 0,
40816
    CRLASN_IDX_TBS,
40817
    CRLASN_IDX_TBS_VER,
40818
    CRLASN_IDX_TBS_SIGALGO,
40819
    CRLASN_IDX_TBS_SIGALGO_OID,
40820
    CRLASN_IDX_TBS_SIGALGO_NULL,
40821
#ifdef WC_RSA_PSS
40822
    CRLASN_IDX_TBS_SIGALGO_PARAMS,
40823
#endif
40824
    CRLASN_IDX_TBS_ISSUER,
40825
    CRLASN_IDX_TBS_THISUPDATE_UTC,
40826
    CRLASN_IDX_TBS_THISUPDATE_GT,
40827
    CRLASN_IDX_TBS_NEXTUPDATE_UTC,
40828
    CRLASN_IDX_TBS_NEXTUPDATE_GT,
40829
    CRLASN_IDX_TBS_REVOKEDCERTS,
40830
    CRLASN_IDX_TBS_EXT,
40831
    CRLASN_IDX_TBS_EXT_SEQ,
40832
    CRLASN_IDX_SIGALGO,
40833
    CRLASN_IDX_SIGALGO_OID,
40834
    CRLASN_IDX_SIGALGO_NULL,
40835
#ifdef WC_RSA_PSS
40836
    CRLASN_IDX_SIGALGO_PARAMS,
40837
#endif
40838
    CRLASN_IDX_SIGNATURE,
40839
};
40840
40841
/* Number of items in ASN.1 template for a CRL- CertificateList. */
40842
#define crlASN_Length (sizeof(crlASN) / sizeof(ASNItem))
40843
#endif
40844
40845
/* parse crl buffer into decoded state, 0 on success */
40846
int ParseCRL(RevokedCert* rcert, DecodedCRL* dcrl, const byte* buff, word32 sz,
40847
             int verify, void* cm)
40848
{
40849
#ifndef WOLFSSL_ASN_TEMPLATE
40850
    Signer*      ca = NULL;
40851
    SignatureCtx sigCtx;
40852
    int          ret = 0;
40853
    int          len;
40854
    word32       idx = 0;
40855
    const byte* sigParams = NULL;
40856
    int sigParamsSz = 0;
40857
40858
    WOLFSSL_MSG("ParseCRL");
40859
40860
    /* raw crl hash */
40861
    /* hash here if needed for optimized comparisons
40862
     * wc_Sha sha;
40863
     * wc_InitSha(&sha);
40864
     * wc_ShaUpdate(&sha, buff, sz);
40865
     * wc_ShaFinal(&sha, dcrl->crlHash); */
40866
40867
    if (GetSequence(buff, &idx, &len, sz) < 0)
40868
        return ASN_PARSE_E;
40869
40870
    dcrl->certBegin = idx;
40871
    /* Normalize sz for the length inside the outer sequence. */
40872
    sz = len + idx;
40873
40874
    if (GetSequence(buff, &idx, &len, sz) < 0)
40875
        return ASN_PARSE_E;
40876
    dcrl->sigIndex = len + idx;
40877
40878
    if (ParseCRL_CertList(rcert, dcrl, buff, &idx, dcrl->sigIndex, verify) < 0)
40879
        return ASN_PARSE_E;
40880
40881
    if (ParseCRL_Extensions(dcrl, buff, &idx, dcrl->sigIndex) < 0)
40882
        return ASN_PARSE_E;
40883
40884
    idx = dcrl->sigIndex;
40885
40886
    if (GetAlgoId(buff, &idx, &dcrl->signatureOID, oidSigType, sz) < 0) {
40887
        return ASN_PARSE_E;
40888
    }
40889
#ifdef WC_RSA_PSS
40890
    else if (dcrl->signatureOID == CTC_RSASSAPSS) {
40891
        word32 tmpSz;
40892
        const byte* params;
40893
40894
        tmpSz = idx;
40895
        params = buff + idx;
40896
        if (GetSequence(buff, &idx, &len, sz) < 0) {
40897
            return ASN_PARSE_E;
40898
        }
40899
        idx += len;
40900
        sigParams = params;
40901
        sigParamsSz = idx - tmpSz;
40902
    }
40903
#endif
40904
40905
    if (GetCRL_Signature(buff, &idx, dcrl, sz) < 0)
40906
        return ASN_PARSE_E;
40907
40908
    /* openssl doesn't add skid by default for CRLs cause firefox chokes
40909
       if experiencing issues uncomment NO_SKID define in CRL section of
40910
       wolfssl/wolfcrypt/settings.h */
40911
#ifndef NO_SKID
40912
    if (dcrl->extAuthKeyIdSet) {
40913
        ca = GetCA(cm, dcrl->extAuthKeyId); /* more unique than issuerHash */
40914
    }
40915
    if (ca != NULL && XMEMCMP(dcrl->issuerHash, ca->subjectNameHash,
40916
            KEYID_SIZE) != 0) {
40917
        ca = NULL;
40918
    }
40919
    if (ca == NULL) {
40920
        ca = GetCAByName(cm, dcrl->issuerHash); /* last resort */
40921
        /* If AKID is available then this CA doesn't have the public
40922
         * key required */
40923
        if (ca && dcrl->extAuthKeyIdSet) {
40924
            WOLFSSL_MSG("CA SKID doesn't match AKID");
40925
            ca = NULL;
40926
        }
40927
    }
40928
#else
40929
    ca = GetCA(cm, dcrl->issuerHash);
40930
#endif /* !NO_SKID */
40931
    WOLFSSL_MSG("About to verify CRL signature");
40932
40933
    if (ca == NULL) {
40934
        WOLFSSL_MSG("Did NOT find CRL issuer CA");
40935
        ret = ASN_CRL_NO_SIGNER_E;
40936
        WOLFSSL_ERROR_VERBOSE(ret);
40937
        goto end;
40938
    }
40939
40940
    WOLFSSL_MSG("Found CRL issuer CA");
40941
    ret = VerifyCRL_Signature(&sigCtx, buff + dcrl->certBegin,
40942
           dcrl->sigIndex - dcrl->certBegin, dcrl->signature, dcrl->sigLength,
40943
           dcrl->signatureOID, sigParams, sigParamsSz, ca, dcrl->heap);
40944
40945
end:
40946
    return ret;
40947
#else
40948
    DECL_ASNGETDATA(dataASN, crlASN_Length);
40949
    int ret = 0;
40950
    /* Default version - v1 = 0 */
40951
    byte version = 0;
40952
    word32 idx = 0;
40953
    /* Size of buffer for date. */
40954
    word32 lastDateSz = MAX_DATE_SIZE;
40955
    word32 nextDateSz = MAX_DATE_SIZE;
40956
    const byte* sigParams = NULL;
40957
    int   sigParamsSz = 0;
40958
#ifdef WC_RSA_PSS
40959
    const byte* tbsParams = NULL;
40960
    int   tbsParamsSz = 0;
40961
#endif
40962
40963
    /* When NO_ASN_TIME is defined, verify not used. */
40964
    (void)verify;
40965
40966
    WOLFSSL_MSG("ParseCRL");
40967
40968
    CALLOC_ASNGETDATA(dataASN, crlASN_Length, ret, dcrl->heap);
40969
40970
    if (ret == 0) {
40971
        /* Set variable to store version. */
40972
        GetASN_Int8Bit(&dataASN[CRLASN_IDX_TBS_VER], &version);
40973
        /* Set expecting signature OID. */
40974
        GetASN_OID(&dataASN[CRLASN_IDX_TBS_SIGALGO_OID], oidSigType);
40975
        /* Set buffer to put last and next date into. */
40976
        GetASN_Buffer(&dataASN[CRLASN_IDX_TBS_THISUPDATE_UTC], dcrl->lastDate,
40977
                &lastDateSz);
40978
        GetASN_Buffer(&dataASN[CRLASN_IDX_TBS_THISUPDATE_GT], dcrl->lastDate,
40979
                &lastDateSz);
40980
        GetASN_Buffer(&dataASN[CRLASN_IDX_TBS_NEXTUPDATE_UTC], dcrl->nextDate,
40981
                &nextDateSz);
40982
        GetASN_Buffer(&dataASN[CRLASN_IDX_TBS_NEXTUPDATE_GT], dcrl->nextDate,
40983
                &nextDateSz);
40984
        /* Set expecting signature OID. */
40985
        GetASN_OID(&dataASN[CRLASN_IDX_SIGALGO_OID], oidSigType);
40986
        /* Decode the CRL. */
40987
        ret = GetASN_Items(crlASN, dataASN, crlASN_Length, 1, buff, &idx, sz);
40988
    }
40989
    /* Version must be v2 = 1 if present. */
40990
    if ((ret == 0) && (dataASN[CRLASN_IDX_TBS_VER].tag != 0) &&
40991
            (version != 1)) {
40992
        ret = ASN_PARSE_E;
40993
    }
40994
    /* Check minimum size of last date. */
40995
    if ((ret == 0) && (lastDateSz < MIN_DATE_SIZE)) {
40996
        ret = ASN_PARSE_E;
40997
    }
40998
    /* Check minimum size of next date. */
40999
    if ((ret == 0) && (nextDateSz < MIN_DATE_SIZE)) {
41000
        ret = ASN_PARSE_E;
41001
    }
41002
    /* 'signatureAlgorithm' OID must be the same as 'signature' OID. */
41003
    if ((ret == 0) && (dataASN[CRLASN_IDX_SIGALGO_OID].data.oid.sum !=
41004
            dataASN[CRLASN_IDX_TBS_SIGALGO_OID].data.oid.sum)) {
41005
        ret = ASN_PARSE_E;
41006
    }
41007
    if (ret == 0) {
41008
        /* Store version */
41009
        dcrl->version = ++version;
41010
        /* Store offset of to be signed part. */
41011
        dcrl->certBegin = dataASN[CRLASN_IDX_TBS].offset;
41012
        /* Store index of signature. */
41013
        dcrl->sigIndex = dataASN[CRLASN_IDX_SIGALGO].offset;
41014
41015
    #ifdef WC_RSA_PSS
41016
        /* get TBS and Signature parameters for PSS */
41017
        if (dataASN[CRLASN_IDX_TBS_SIGALGO_PARAMS].tag != 0) {
41018
            tbsParams =
41019
                GetASNItem_Addr(dataASN[CRLASN_IDX_TBS_SIGALGO_PARAMS],
41020
                    buff);
41021
            tbsParamsSz =(int)
41022
                GetASNItem_Length(dataASN[CRLASN_IDX_TBS_SIGALGO_PARAMS],
41023
                    buff);
41024
        }
41025
        if (dataASN[CRLASN_IDX_SIGALGO_PARAMS].tag != 0) {
41026
            sigParams =
41027
                GetASNItem_Addr(dataASN[CRLASN_IDX_SIGALGO_PARAMS],
41028
                    buff);
41029
            sigParamsSz = (int)
41030
                GetASNItem_Length(dataASN[CRLASN_IDX_SIGALGO_PARAMS],
41031
                    buff);
41032
            dcrl->sigParamsIndex =
41033
                dataASN[CRLASN_IDX_SIGALGO_PARAMS].offset;
41034
            dcrl->sigParamsLength = (word32)sigParamsSz;
41035
        }
41036
    #endif
41037
41038
        /* Store address and length of signature data. */
41039
        GetASN_GetRef(&dataASN[CRLASN_IDX_SIGNATURE], &dcrl->signature,
41040
                &dcrl->sigLength);
41041
        /* Get the signature OID. */
41042
        dcrl->signatureOID = dataASN[CRLASN_IDX_SIGALGO_OID].data.oid.sum;
41043
41044
    #ifdef WC_RSA_PSS
41045
        /* Sanity check on parameters found */
41046
        if (tbsParamsSz != sigParamsSz) {
41047
            WOLFSSL_MSG("CRL TBS and signature parameter sizes mismatch");
41048
            ret = ASN_PARSE_E;
41049
        }
41050
        else if ((tbsParamsSz > 0) &&
41051
          (dataASN[CRLASN_IDX_TBS_SIGALGO_OID].data.oid.sum != CTC_RSASSAPSS)) {
41052
            WOLFSSL_MSG("CRL unexpected signature parameters found");
41053
            ret = ASN_PARSE_E;
41054
        }
41055
        else if ((tbsParamsSz > 0) &&
41056
                 (XMEMCMP(tbsParams, sigParams, (word32)tbsParamsSz) != 0)) {
41057
            WOLFSSL_MSG("CRL TBS and signature parameter mismatch");
41058
            ret = ASN_PARSE_E;
41059
        }
41060
    #endif
41061
41062
        /* Get the format/tag of the last and next date. */
41063
        dcrl->lastDateFormat = (dataASN[CRLASN_IDX_TBS_THISUPDATE_UTC].tag != 0)
41064
                ? dataASN[CRLASN_IDX_TBS_THISUPDATE_UTC].tag
41065
                : dataASN[CRLASN_IDX_TBS_THISUPDATE_GT].tag;
41066
        dcrl->nextDateFormat = (dataASN[CRLASN_IDX_TBS_NEXTUPDATE_UTC].tag != 0)
41067
                ? dataASN[CRLASN_IDX_TBS_NEXTUPDATE_UTC].tag
41068
                : dataASN[CRLASN_IDX_TBS_NEXTUPDATE_GT].tag;
41069
    #if !defined(NO_ASN_TIME) && !defined(WOLFSSL_NO_CRL_DATE_CHECK)
41070
        if (dcrl->nextDateFormat != 0) {
41071
            /* Next date was set, so validate it. */
41072
            if (verify != NO_VERIFY &&
41073
                (! AsnSkipDateCheck) &&
41074
                 !XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, ASN_AFTER)) {
41075
                WOLFSSL_MSG("CRL after date is no longer valid");
41076
                ret = CRL_CERT_DATE_ERR;
41077
                WOLFSSL_ERROR_VERBOSE(ret);
41078
            }
41079
        }
41080
    }
41081
    if (ret == 0) { /* in "no time" cases above "ret" is not set */
41082
    #endif /* !NO_ASN_TIME && !WOLFSSL_NO_CRL_DATE_CHECK */
41083
    #ifdef OPENSSL_EXTRA
41084
        /* Parse and store the issuer name. */
41085
        dcrl->issuerSz = GetASNItem_Length(dataASN[CRLASN_IDX_TBS_ISSUER],
41086
                            buff);
41087
        dcrl->issuer   = (byte*)GetNameFromDer((byte*)GetASNItem_Addr(
41088
                            dataASN[CRLASN_IDX_TBS_ISSUER], buff),
41089
                            (int)dcrl->issuerSz);
41090
    #endif
41091
        /* Calculate the Hash id from the issuer name. */
41092
        ret = CalcHashId_ex(
41093
                GetASNItem_Addr(dataASN[CRLASN_IDX_TBS_ISSUER], buff),
41094
                GetASNItem_Length(dataASN[CRLASN_IDX_TBS_ISSUER], buff),
41095
                dcrl->issuerHash, HashIdAlg(dcrl->signatureOID));
41096
        if (ret < 0) {
41097
            ret = ASN_PARSE_E;
41098
        }
41099
    }
41100
41101
    if ((ret == 0) && (dataASN[CRLASN_IDX_TBS_REVOKEDCERTS].tag != 0)) {
41102
        /* Parse revoked certificates - starting after SEQUENCE OF. */
41103
        ret = ParseCRL_RevokedCerts(rcert, dcrl, buff,
41104
            GetASNItem_DataIdx(dataASN[CRLASN_IDX_TBS_REVOKEDCERTS], buff),
41105
            GetASNItem_EndIdx(dataASN[CRLASN_IDX_TBS_REVOKEDCERTS], buff));
41106
    }
41107
    if (ret == 0) {
41108
        /* Parse the extensions - starting after SEQUENCE OF. */
41109
        ret = ParseCRL_Extensions(dcrl, buff,
41110
            GetASNItem_DataIdx(dataASN[CRLASN_IDX_TBS_EXT_SEQ], buff),
41111
            GetASNItem_EndIdx(dataASN[CRLASN_IDX_TBS_EXT_SEQ], buff));
41112
    }
41113
    if (ret == 0) {
41114
        /* Find signer and verify signature. */
41115
        ret = PaseCRL_CheckSignature(dcrl, sigParams, sigParamsSz, buff, cm);
41116
    }
41117
41118
    FREE_ASNGETDATA(dataASN, dcrl->heap);
41119
    return ret;
41120
#endif /* WOLFSSL_ASN_TEMPLATE */
41121
}
41122
41123
#endif /* HAVE_CRL */
41124
41125
41126
41127
#ifdef WOLFSSL_CERT_PIV
41128
41129
#ifdef WOLFSSL_ASN_TEMPLATE
41130
/* Template for PIV. */
41131
static const ASNItem pivASN[] = {
41132
/* CERT        */ { 0, ASN_PIV_CERT, 0, 0, 0 },
41133
/* NONCE       */ { 0, ASN_PIV_NONCE, 0, 0, 1 },
41134
/* SIGNEDNONCE */ { 0, ASN_PIV_SIGNED_NONCE, 0, 0, 1 },
41135
};
41136
enum {
41137
    PIVASN_IDX_CERT = 0,
41138
    PIVASN_IDX_NONCE,
41139
    PIVASN_IDX_SIGNEDNONCE,
41140
};
41141
41142
#define pivASN_Length (sizeof(pivASN) / sizeof(ASNItem))
41143
41144
static const ASNItem pivCertASN[] = {
41145
                          /* 0x53 = 0x40 | 0x13 */
41146
/* CERT */ { 1, ASN_APPLICATION | 0x13, 0, 1, 0 },
41147
                               /* 0x70 = 0x40 | 0x10 + 0x20 (CONSTRUCTED) */
41148
/* X509 */      { 2, ASN_APPLICATION | 0x10, 1, 0, 0 },
41149
                               /* 0x71 = 0x40 | 0x11 + 0x20 (CONSTRUCTED) */
41150
/* INFO */      { 2, ASN_APPLICATION | 0x11, 1, 0, 1 },
41151
                               /* 0xFE = 0xC0 | 0x1E + 0x20 (CONSTRUCTED) */
41152
/* ERR */      { 2, ASN_PRIVATE | 0x1e, 1, 0, 1 },
41153
};
41154
enum {
41155
    PIVCERTASN_IDX_CERT,
41156
    PIVCERTASN_IDX_X509,
41157
    PIVCERTASN_IDX_INFO,
41158
    PIVCERTASN_IDX_ERR,
41159
};
41160
41161
#define pivCertASN_Length (sizeof(pivCertASN) / sizeof(ASNItem))
41162
#endif
41163
41164
int wc_ParseCertPIV(wc_CertPIV* piv, const byte* buf, word32 totalSz)
41165
{
41166
#ifndef WOLFSSL_ASN_TEMPLATE
41167
    int length = 0;
41168
    word32 idx = 0;
41169
41170
    WOLFSSL_ENTER("wc_ParseCertPIV");
41171
41172
    if (piv == NULL || buf == NULL || totalSz == 0)
41173
        return BAD_FUNC_ARG;
41174
41175
    XMEMSET(piv, 0, sizeof(wc_CertPIV));
41176
41177
    /* Detect Identiv PIV (with 0x0A, 0x0B and 0x0C sections) */
41178
    /* Certificate (0A 82 05FA) */
41179
    if (GetASNHeader(buf, ASN_PIV_CERT, &idx, &length, totalSz) >= 0) {
41180
        /* Identiv Type PIV card */
41181
        piv->isIdentiv = 1;
41182
41183
        piv->cert =   &buf[idx];
41184
        piv->certSz = length;
41185
        idx += length;
41186
41187
        /* Nonce (0B 14) */
41188
        if (GetASNHeader(buf, ASN_PIV_NONCE, &idx, &length, totalSz) >= 0) {
41189
            piv->nonce =   &buf[idx];
41190
            piv->nonceSz = length;
41191
            idx += length;
41192
        }
41193
41194
        /* Signed Nonce (0C 82 0100) */
41195
        if (GetASNHeader(buf, ASN_PIV_SIGNED_NONCE, &idx, &length, totalSz) >= 0) {
41196
            piv->signedNonce =   &buf[idx];
41197
            piv->signedNonceSz = length;
41198
        }
41199
41200
        idx = 0;
41201
        buf = piv->cert;
41202
        totalSz = piv->certSz;
41203
    }
41204
41205
    /* Certificate Buffer Total Size (53 82 05F6) */
41206
    if (GetASNHeader(buf, ASN_APPLICATION | ASN_PRINTABLE_STRING, &idx,
41207
                                                   &length, totalSz) < 0) {
41208
        return ASN_PARSE_E;
41209
    }
41210
    /* PIV Certificate (70 82 05ED) */
41211
    if (GetASNHeader(buf, ASN_PIV_TAG_CERT, &idx, &length,
41212
                                                         totalSz) < 0) {
41213
        return ASN_PARSE_E;
41214
    }
41215
41216
    /* Capture certificate buffer pointer and length */
41217
    piv->cert =   &buf[idx];
41218
    piv->certSz = length;
41219
    idx += length;
41220
41221
    /* PIV Certificate Info (71 01 00) */
41222
    if (GetASNHeader(buf, ASN_PIV_TAG_CERT_INFO, &idx, &length,
41223
                                                        totalSz) >= 0) {
41224
        if (length >= 1) {
41225
            piv->compression = (buf[idx] & ASN_PIV_CERT_INFO_COMPRESSED);
41226
            piv->isX509 =      ((buf[idx] & ASN_PIV_CERT_INFO_ISX509) != 0);
41227
        }
41228
        idx += length;
41229
    }
41230
41231
    /* PIV Error Detection (FE 00) */
41232
    if (GetASNHeader(buf, ASN_PIV_TAG_ERR_DET, &idx, &length,
41233
                                                        totalSz) >= 0) {
41234
        piv->certErrDet =   &buf[idx];
41235
        piv->certErrDetSz = length;
41236
        idx += length;
41237
    }
41238
41239
    return 0;
41240
#else
41241
    /* pivCertASN_Length is longer than pivASN_Length */
41242
    DECL_ASNGETDATA(dataASN, pivCertASN_Length);
41243
    int ret = 0;
41244
    word32 idx;
41245
    byte info;
41246
41247
    WOLFSSL_ENTER("wc_ParseCertPIV");
41248
41249
    ALLOC_ASNGETDATA(dataASN, pivCertASN_Length, ret, NULL);
41250
41251
    if (ret == 0) {
41252
        /* Clear dynamic data. */
41253
        XMEMSET(dataASN, 0, sizeof(*dataASN) * pivASN_Length);
41254
        /* Start parsing from start of buffer. */
41255
        idx = 0;
41256
        /* Parse Identiv wrapper. */
41257
        ret = GetASN_Items(pivASN, dataASN, pivASN_Length, 1, buf, &idx,
41258
                totalSz);
41259
        if (ret == 0) {
41260
            /* Identiv wrapper found. */
41261
            piv->isIdentiv = 1;
41262
            /* Get nonce reference. */
41263
            if (dataASN[PIVASN_IDX_NONCE].tag != 0) {
41264
                GetASN_GetConstRef(&dataASN[PIVASN_IDX_NONCE], &piv->nonce,
41265
                        &piv->nonceSz);
41266
            }
41267
            /* Get signedNonce reference. */
41268
            if (dataASN[PIVASN_IDX_SIGNEDNONCE].tag != 0) {
41269
                GetASN_GetConstRef(&dataASN[PIVASN_IDX_SIGNEDNONCE],
41270
                        &piv->signedNonce, &piv->signedNonceSz);
41271
            }
41272
            /* Get the certificate data for parsing. */
41273
            GetASN_GetConstRef(&dataASN[PIVASN_IDX_CERT], &buf, &totalSz);
41274
        }
41275
        ret = 0;
41276
    }
41277
    if (ret == 0) {
41278
        /* Clear dynamic data and set variable to put cert info into. */
41279
        XMEMSET(dataASN, 0, sizeof(*dataASN) * pivCertASN_Length);
41280
        GetASN_Int8Bit(&dataASN[PIVCERTASN_IDX_INFO], &info);
41281
        /* Start parsing from start of buffer. */
41282
        idx = 0;
41283
        /* Parse PIV certificate data. */
41284
        ret = GetASN_Items(pivCertASN, dataASN, pivCertASN_Length, 1, buf, &idx,
41285
                totalSz);
41286
        if (ret == 0) {
41287
            /* Get X.509 certificate reference. */
41288
            GetASN_GetConstRef(&dataASN[PIVCERTASN_IDX_X509], &piv->cert,
41289
                    &piv->certSz);
41290
            /* Set the certificate info if available. */
41291
            if (dataASN[PIVCERTASN_IDX_INFO].tag != 0) {
41292
                /* Bits 1 and 2 are compression. */
41293
                piv->compression = info & ASN_PIV_CERT_INFO_COMPRESSED;
41294
                /* Bits 3 is X509 flag. */
41295
                piv->isX509 = ((info & ASN_PIV_CERT_INFO_ISX509) != 0);
41296
            }
41297
            /* Get X.509 certificate error detection reference. */
41298
            GetASN_GetConstRef(&dataASN[PIVCERTASN_IDX_ERR], &piv->certErrDet,
41299
                     &piv->certErrDetSz);
41300
        }
41301
        ret = 0;
41302
    }
41303
41304
    FREE_ASNGETDATA(dataASN, NULL);
41305
    return ret;
41306
#endif /* WOLFSSL_ASN_TEMPLATE */
41307
}
41308
41309
#endif /* WOLFSSL_CERT_PIV */
41310
41311
41312
41313
#ifdef HAVE_SMIME
41314
41315
/*****************************************************************************
41316
* wc_MIME_parse_headers - Reads the char array in and parses out MIME headers
41317
* and parameters into headers.  Will continue until in has no more content.
41318
*
41319
* RETURNS:
41320
* returns zero on success, non-zero on error.
41321
*/
41322
int wc_MIME_parse_headers(char* in, int inLen, MimeHdr** headers)
41323
{
41324
    MimeHdr* nextHdr = NULL;
41325
    MimeHdr* curHdr = NULL;
41326
    MimeParam* nextParam = NULL;
41327
    size_t start = 0;
41328
    size_t end = 0;
41329
    char* nameAttr = NULL;
41330
    char* bodyVal = NULL;
41331
    MimeTypes mimeType = MIME_HDR;
41332
    MimeStatus mimeStatus = MIME_NAMEATTR;
41333
    int ret = -1;
41334
    size_t pos = 0;
41335
    size_t lineLen = 0;
41336
    char* curLine = NULL;
41337
    char* ptr = NULL;
41338
41339
    if (in == NULL || inLen <= 0 || in[inLen] != '\0' || headers == NULL) {
41340
        ret = BAD_FUNC_ARG;
41341
        goto error;
41342
    }
41343
    nextHdr = (MimeHdr*)XMALLOC(sizeof(MimeHdr), NULL, DYNAMIC_TYPE_PKCS7);
41344
    if (nextHdr == NULL) {
41345
        ret = MEMORY_E;
41346
        goto error;
41347
    }
41348
    XMEMSET(nextHdr, 0, sizeof(MimeHdr));
41349
    nextParam = (MimeParam*)XMALLOC(sizeof(MimeParam), NULL,
41350
                                    DYNAMIC_TYPE_PKCS7);
41351
    if (nextParam == NULL) {
41352
        ret = MEMORY_E;
41353
        goto error;
41354
    }
41355
    XMEMSET(nextParam, 0, sizeof(MimeParam));
41356
41357
    curLine = XSTRTOK(in, "\r\n", &ptr);
41358
    if (curLine == NULL) {
41359
        ret = ASN_PARSE_E;
41360
        goto error;
41361
    }
41362
41363
    while (curLine != NULL) {
41364
        /* Leftover from previous line, add params to previous header. */
41365
        if (curLine[0] == ' ' && curHdr) {
41366
            mimeType = MIME_PARAM;
41367
        }
41368
        else {
41369
            mimeType = MIME_HDR;
41370
        }
41371
        start = 0;
41372
        lineLen = XSTRLEN(curLine);
41373
        if (lineLen == 0) {
41374
            ret = BAD_FUNC_ARG;
41375
            goto error;
41376
        }
41377
41378
        for (pos = 0; pos < lineLen; pos++) {
41379
            char cur = curLine[pos];
41380
41381
            if (mimeStatus == MIME_NAMEATTR && ((cur == ':' &&
41382
                mimeType == MIME_HDR) || (cur == '=' &&
41383
                mimeType == MIME_PARAM)) && pos >= 1) {
41384
                mimeStatus = MIME_BODYVAL;
41385
                end = pos-1;
41386
                XFREE(nameAttr, NULL, DYNAMIC_TYPE_PKCS7);
41387
                nameAttr = NULL;
41388
                ret = wc_MIME_header_strip(curLine, &nameAttr, start, end);
41389
                if (ret) {
41390
                    goto error;
41391
                }
41392
                start = pos+1;
41393
            }
41394
            else if (mimeStatus == MIME_BODYVAL && cur == ';' && pos >= 1) {
41395
                end = pos-1;
41396
                XFREE(bodyVal, NULL, DYNAMIC_TYPE_PKCS7);
41397
                bodyVal = NULL;
41398
                ret = wc_MIME_header_strip(curLine, &bodyVal, start, end);
41399
                if (ret) {
41400
                    goto error;
41401
                }
41402
                if (mimeType == MIME_HDR) {
41403
                    nextHdr->name = nameAttr;
41404
                    nameAttr = NULL;
41405
                    nextHdr->body = bodyVal;
41406
                    bodyVal = NULL;
41407
                    nextHdr->next = curHdr;
41408
                    curHdr = nextHdr;
41409
                    nextHdr = (MimeHdr*)XMALLOC(sizeof(MimeHdr), NULL,
41410
                                                DYNAMIC_TYPE_PKCS7);
41411
                    if (nextHdr == NULL) {
41412
                        ret = MEMORY_E;
41413
                        goto error;
41414
                    }
41415
                    XMEMSET(nextHdr, 0, sizeof(MimeHdr));
41416
                }
41417
                else {
41418
                    nextParam->attribute = nameAttr;
41419
                    nameAttr = NULL;
41420
                    nextParam->value = bodyVal;
41421
                    bodyVal = NULL;
41422
                    nextParam->next = curHdr->params;
41423
                    curHdr->params = nextParam;
41424
                    nextParam = (MimeParam*)XMALLOC(sizeof(MimeParam), NULL,
41425
                                                    DYNAMIC_TYPE_PKCS7);
41426
                    if (nextParam == NULL) {
41427
                        ret = MEMORY_E;
41428
                        goto error;
41429
                    }
41430
                    XMEMSET(nextParam, 0, sizeof(MimeParam));
41431
                }
41432
                mimeType = MIME_PARAM;
41433
                mimeStatus = MIME_NAMEATTR;
41434
                start = pos+1;
41435
            }
41436
        }
41437
41438
        end = lineLen-1;
41439
        /* Omit newline characters. */
41440
        while ((curLine[end] == '\r' || curLine[end] == '\n') && end > 0) {
41441
            end--;
41442
        }
41443
        if (end >= start && mimeStatus == MIME_BODYVAL) {
41444
            ret = wc_MIME_header_strip(curLine, &bodyVal, start, end);
41445
            if (ret) {
41446
                goto error;
41447
            }
41448
            if (mimeType == MIME_HDR) {
41449
                nextHdr->name = nameAttr;
41450
                nameAttr = NULL;
41451
                nextHdr->body = bodyVal;
41452
                bodyVal = NULL;
41453
                nextHdr->next = curHdr;
41454
                curHdr = nextHdr;
41455
                nextHdr = (MimeHdr*)XMALLOC(sizeof(MimeHdr), NULL,
41456
                                            DYNAMIC_TYPE_PKCS7);
41457
                if (nextHdr == NULL) {
41458
                    ret = MEMORY_E;
41459
                    goto error;
41460
                }
41461
                XMEMSET(nextHdr, 0, sizeof(MimeHdr));
41462
            } else {
41463
                nextParam->attribute = nameAttr;
41464
                nameAttr = NULL;
41465
                nextParam->value = bodyVal;
41466
                bodyVal = NULL;
41467
                nextParam->next = curHdr->params;
41468
                curHdr->params = nextParam;
41469
                nextParam = (MimeParam*)XMALLOC(sizeof(MimeParam), NULL,
41470
                                                DYNAMIC_TYPE_PKCS7);
41471
                if (nextParam == NULL) {
41472
                    ret = MEMORY_E;
41473
                    goto error;
41474
                }
41475
                XMEMSET(nextParam, 0, sizeof(MimeParam));
41476
            }
41477
        }
41478
41479
        curLine = XSTRTOK(NULL, "\r\n", &ptr);
41480
        mimeStatus = MIME_NAMEATTR;
41481
    }
41482
41483
    *headers = curHdr;
41484
    ret = 0; /* success if at this point */
41485
41486
error:
41487
    if (ret != 0)
41488
        wc_MIME_free_hdrs(curHdr);
41489
    wc_MIME_free_hdrs(nextHdr);
41490
    XFREE(nameAttr, NULL, DYNAMIC_TYPE_PKCS7);
41491
    XFREE(bodyVal, NULL, DYNAMIC_TYPE_PKCS7);
41492
    XFREE(nextParam, NULL, DYNAMIC_TYPE_PKCS7);
41493
41494
    return ret;
41495
}
41496
41497
/*****************************************************************************
41498
* wc_MIME_header_strip - Reads the string in from indices start to end, strips
41499
* out disallowed/separator characters and places the rest into *out.
41500
*
41501
* RETURNS:
41502
* returns zero on success, non-zero on error.
41503
*/
41504
int wc_MIME_header_strip(char* in, char** out, size_t start, size_t end)
41505
{
41506
    size_t inPos = start;
41507
    size_t outPos = 0;
41508
    size_t inLen = 0;
41509
41510
    if (end < start || in == NULL || out == NULL) {
41511
        return BAD_FUNC_ARG;
41512
    }
41513
41514
    inLen = XSTRLEN(in);
41515
    if (start > inLen || end > inLen) {
41516
        return BAD_FUNC_ARG;
41517
    }
41518
41519
    *out = (char*)XMALLOC(((end-start)+2)*sizeof(char), NULL,
41520
                          DYNAMIC_TYPE_PKCS7);
41521
    if (*out == NULL) {
41522
        return MEMORY_E;
41523
    }
41524
41525
    while (inPos <= end) {
41526
        if (in[inPos] >= MIME_HEADER_ASCII_MIN && in[inPos] <=
41527
            MIME_HEADER_ASCII_MAX && in[inPos] != ';' && in[inPos] != '\"') {
41528
            (*out)[outPos] = in[inPos];
41529
            outPos++;
41530
        }
41531
        inPos++;
41532
    }
41533
    (*out)[outPos] = '\0';
41534
41535
    return 0;
41536
}
41537
41538
/*****************************************************************************
41539
* wc_MIME_find_header_name - Searches through all given headers until a header
41540
* with a name matching the provided name is found.
41541
*
41542
* RETURNS:
41543
* returns a pointer to the found header, if no match was found, returns NULL.
41544
*/
41545
MimeHdr* wc_MIME_find_header_name(const char* name, MimeHdr* header)
41546
{
41547
    while (header) {
41548
        if (!XSTRCMP(name, header->name)) {
41549
            return header;
41550
        }
41551
        header = header->next;
41552
    }
41553
41554
    return header;
41555
}
41556
41557
/*****************************************************************************
41558
* wc_MIME_find_param_attr - Searches through all parameters until a parameter
41559
* with a attribute matching the provided attribute is found.
41560
*
41561
* RETURNS:
41562
* returns a pointer to the found parameter, if no match was found,
41563
* returns NULL.
41564
*/
41565
MimeParam* wc_MIME_find_param_attr(const char* attribute,
41566
                                    MimeParam* param)
41567
{
41568
    while (param) {
41569
        if (!XSTRCMP(attribute, param->attribute)) {
41570
            return param;
41571
        }
41572
        param = param->next;
41573
    }
41574
41575
    return param;
41576
}
41577
41578
/*****************************************************************************
41579
* wc_MIME_single_canonicalize - Canonicalize a line by converting the trailing
41580
* line ending to CRLF.
41581
*
41582
* line - input line to canonicalize
41583
* len  - length of line in chars on input, length of output array on return
41584
*
41585
* RETURNS:
41586
* returns a pointer to a canonicalized line on success, NULL on error.
41587
*/
41588
char* wc_MIME_single_canonicalize(const char* line, word32* len)
41589
{
41590
    size_t end = 0;
41591
    char* canonLine = NULL;
41592
41593
    if (line == NULL || len == NULL || *len == 0) {
41594
        return NULL;
41595
    }
41596
41597
    end = *len;
41598
    while (end >= 1 && ((line[end-1] == '\r') || (line[end-1] == '\n'))) {
41599
        end--;
41600
    }
41601
41602
    /* Need 2 chars for \r\n and 1 for EOL */
41603
    canonLine = (char*)XMALLOC((end+3)*sizeof(char), NULL, DYNAMIC_TYPE_PKCS7);
41604
    if (canonLine == NULL) {
41605
        return NULL;
41606
    }
41607
41608
    XMEMCPY(canonLine, line, end);
41609
    canonLine[end] = '\r';
41610
    canonLine[end+1] = '\n';
41611
    canonLine[end+2] = '\0';
41612
    *len = (word32)(end + 3);
41613
41614
    return canonLine;
41615
}
41616
41617
/*****************************************************************************
41618
* wc_MIME_free_hdrs - Frees all MIME headers, parameters and strings starting
41619
* from the provided header pointer.
41620
*
41621
* RETURNS:
41622
* returns zero on success, non-zero on error.
41623
*/
41624
int wc_MIME_free_hdrs(MimeHdr* head)
41625
{
41626
    MimeHdr* curHdr = NULL;
41627
    MimeParam* curParam = NULL;
41628
41629
    while (head) {
41630
        while (head->params) {
41631
            curParam = head->params;
41632
            head->params = head->params->next;
41633
            XFREE(curParam->attribute, NULL, DYNAMIC_TYPE_PKCS7);
41634
            XFREE(curParam->value, NULL, DYNAMIC_TYPE_PKCS7);
41635
            XFREE(curParam, NULL, DYNAMIC_TYPE_PKCS7);
41636
        }
41637
        curHdr = head;
41638
        head = head->next;
41639
        XFREE(curHdr->name, NULL, DYNAMIC_TYPE_PKCS7);
41640
        XFREE(curHdr->body, NULL, DYNAMIC_TYPE_PKCS7);
41641
        XFREE(curHdr, NULL, DYNAMIC_TYPE_PKCS7);
41642
    }
41643
41644
    return 0;
41645
}
41646
41647
#endif /* HAVE_SMIME */
41648
41649
41650
#undef ERROR_OUT
41651
41652
41653
#ifdef WOLFSSL_ASN_PRINT
41654
41655
/*******************************************************************************
41656
 * ASN.1 Parsing and Printing Implementation
41657
 ******************************************************************************/
41658
41659
/* Initialize ASN.1 print options.
41660
 *
41661
 * @param [in, out] opts  ASN.1 options for printing.
41662
 * @return  0 on success.
41663
 * @return  BAD_FUNC_ARG when asn1 is NULL.
41664
 */
41665
int wc_Asn1PrintOptions_Init(Asn1PrintOptions* opts)
41666
0
{
41667
0
    int ret = 0;
41668
41669
0
    if (opts == NULL) {
41670
0
        ret = BAD_FUNC_ARG;
41671
0
    }
41672
0
    else {
41673
0
        XMEMSET(opts, 0, sizeof(*opts));
41674
0
    }
41675
41676
0
    return ret;
41677
0
}
41678
41679
/* Set a print option into Asn1PrintOptions object.
41680
 *
41681
 * @param [in, out] opts  ASN.1 options for printing.
41682
 * @param [in]      opt   Option to set value of.
41683
 * @param [in]      val   Value to set for option.
41684
 * @return  0 on success.
41685
 * @return  BAD_FUNC_ARG when asn1 is NULL.
41686
 * @return  BAD_FUNC_ARG when val is out of range for option.
41687
 */
41688
int wc_Asn1PrintOptions_Set(Asn1PrintOptions* opts, enum Asn1PrintOpt opt,
41689
    word32 val)
41690
0
{
41691
0
    int ret = 0;
41692
41693
    /* Validate parameters. */
41694
0
    if (opts == NULL) {
41695
0
        ret = BAD_FUNC_ARG;
41696
0
    }
41697
41698
0
    if (ret == 0) {
41699
0
        switch (opt) {
41700
        /* Offset into DER/BER data to start decoding from. */
41701
0
        case ASN1_PRINT_OPT_OFFSET:
41702
0
            opts->offset = val;
41703
0
            break;
41704
        /* Length of DER/BER encoding to parse. */
41705
0
        case ASN1_PRINT_OPT_LENGTH:
41706
0
            opts->length = val;
41707
0
            break;
41708
        /* Number of spaces to indent for each change in depth. */
41709
0
        case ASN1_PRINT_OPT_INDENT:
41710
            /* Only 4 bits allowed for value. */
41711
0
            if (val >= (1 << 4)) {
41712
0
                ret = BAD_FUNC_ARG;
41713
0
            }
41714
0
            else {
41715
0
                opts->indent = (word8)val;
41716
0
            }
41717
0
            break;
41718
        /* Draw branches instead of indenting. */
41719
0
        case ASN1_PRINT_OPT_DRAW_BRANCH:
41720
            /* Boolean value. */
41721
0
            opts->draw_branch = (val > 0);
41722
0
            break;
41723
        /* Show raw data of primitive types as octets. */
41724
0
        case ASN1_PRINT_OPT_SHOW_DATA:
41725
            /* Boolean value. */
41726
0
            opts->show_data = (val > 0);
41727
0
            break;
41728
        /* Show header data as octets. */
41729
0
        case ASN1_PRINT_OPT_SHOW_HEADER_DATA:
41730
            /* Boolean value. */
41731
0
            opts->show_header_data = (val > 0);
41732
0
            break;
41733
        /* Show the wolfSSL OID value for OBJECT_ID. */
41734
0
        case ASN1_PRINT_OPT_SHOW_OID:
41735
            /* Boolean value. */
41736
0
            opts->show_oid = (val > 0);
41737
0
            break;
41738
        /* Don't show text representations of primitive types. */
41739
0
        case ASN1_PRINT_OPT_SHOW_NO_TEXT:
41740
            /* Boolean value. */
41741
0
            opts->show_no_text = (val > 0);
41742
0
            break;
41743
        /* Don't show dump text representations of primitive types. */
41744
0
        case ASN1_PRINT_OPT_SHOW_NO_DUMP_TEXT:
41745
            /* Boolean value. */
41746
0
            opts->show_no_dump_text = (val > 0);
41747
0
            break;
41748
0
        }
41749
0
    }
41750
41751
0
    return ret;
41752
0
}
41753
41754
/* Initialize an ASN.1 parse object.
41755
 *
41756
 * @param [in, out] asn1  ASN.1 parse object.
41757
 * @return  0 on success.
41758
 * @return  BAD_FUNC_ARG when asn1 is NULL.
41759
 */
41760
int wc_Asn1_Init(Asn1* asn1)
41761
0
{
41762
0
    int ret = 0;
41763
41764
0
    if (asn1 == NULL) {
41765
0
        ret = BAD_FUNC_ARG;
41766
0
    }
41767
0
    else {
41768
0
        XMEMSET(asn1, 0, sizeof(*asn1));
41769
0
        asn1->file = XBADFILE;
41770
0
    }
41771
41772
0
    return ret;
41773
0
}
41774
41775
/* Set the file to use when printing.
41776
 *
41777
 * @param [in, out] asn1  ASN.1 parse object.
41778
 * @param [in]      file  File to print to.
41779
 * @return  0 on success.
41780
 * @return  BAD_FUNC_ARG when asn1 is NULL.
41781
 * @return  BAD_FUNC_ARG when file is XBADFILE.
41782
 */
41783
int wc_Asn1_SetFile(Asn1* asn1, XFILE file)
41784
0
{
41785
0
    int ret = 0;
41786
41787
0
    if ((asn1 == NULL) || (file == XBADFILE)) {
41788
0
        ret = BAD_FUNC_ARG;
41789
0
    }
41790
0
    else {
41791
0
        asn1->file = file;
41792
0
    }
41793
41794
0
    return ret;
41795
0
}
41796
41797
/* Set the OID name callback to use when printing.
41798
 *
41799
 * @param [in, out] asn1    ASN.1 parse object.
41800
 * @param [in]      nameCb  OID name callback.
41801
 * @return  0 on success.
41802
 * @return  BAD_FUNC_ARG when asn1 is NULL.
41803
 * @return  BAD_FUNC_ARG when nameCb is NULL.
41804
 */
41805
int wc_Asn1_SetOidToNameCb(Asn1* asn1, Asn1OidToNameCb nameCb)
41806
0
{
41807
0
    int ret = 0;
41808
41809
0
    if ((asn1 == NULL) || (nameCb == NULL)) {
41810
0
        ret = BAD_FUNC_ARG;
41811
0
    }
41812
0
    else {
41813
0
        asn1->nameCb = nameCb;
41814
0
    }
41815
41816
0
    return ret;
41817
0
}
41818
41819
/* Encode dotted form of OID into byte array version.
41820
 *
41821
 * @param [in]      in     Byte array containing OID.
41822
 * @param [in]      inSz   Size of OID in bytes.
41823
 * @param [in]      out    Array to hold dotted form of OID.
41824
 * @param [in, out] outSz  On in, number of elements in array.
41825
 *                         On out, count of numbers in dotted form.
41826
 * @return  0 on success
41827
 * @return  BAD_FUNC_ARG when in or outSz is NULL.
41828
 * @return  BUFFER_E when dotted form buffer too small.
41829
 */
41830
static int EncodedDottedForm(const byte* in, word32 inSz, word32* out,
41831
    word32* outSz)
41832
0
{
41833
0
    int x = 0, y = 0;
41834
0
    word32 t = 0;
41835
41836
    /* check args */
41837
0
    if (in == NULL || outSz == NULL) {
41838
0
        return BAD_FUNC_ARG;
41839
0
    }
41840
41841
    /* decode bytes */
41842
0
    while (inSz--) {
41843
0
        t = (t << 7) | (in[x] & 0x7F);
41844
0
        if (!(in[x] & 0x80)) {
41845
0
            if (y >= (int)*outSz) {
41846
0
                return BUFFER_E;
41847
0
            }
41848
0
            if (y == 0) {
41849
0
                out[0] = (word16)(t / 40);
41850
0
                out[1] = (word16)(t % 40);
41851
0
                y = 2;
41852
0
            }
41853
0
            else {
41854
0
                out[y++] = t;
41855
0
            }
41856
0
            t = 0; /* reset tmp */
41857
0
        }
41858
0
        x++;
41859
0
    }
41860
41861
    /* return length */
41862
0
    *outSz = (word32)y;
41863
41864
0
    return 0;
41865
0
}
41866
/* Print OID in dotted form or as hex bytes.
41867
 *
41868
 * @param [in]  file        File pointer to write to.
41869
 * @param [in]  oid         OBJECT_ID data.
41870
 * @param [in]  oid_len     Length of OBJECT_ID data.
41871
 */
41872
static void PrintObjectIdNum(XFILE file, unsigned char* oid, word32 len)
41873
0
{
41874
0
    word32 dotted_nums[ASN1_OID_DOTTED_MAX_SZ];
41875
0
    word32 num = ASN1_OID_DOTTED_MAX_SZ;
41876
0
    word32 i;
41877
41878
    /* Decode OBJECT_ID into dotted form array. */
41879
0
    if (EncodedDottedForm(oid, len, dotted_nums, &num) == 0) {
41880
        /* Print out each number of dotted form. */
41881
0
        for (i = 0; i < num; i++) {
41882
0
            XFPRINTF(file, "%d", dotted_nums[i]);
41883
            /* Add separator. */
41884
0
            if (i < num - 1) {
41885
0
                XFPRINTF(file, ".");
41886
0
            }
41887
0
        }
41888
0
    }
41889
0
    else {
41890
        /* Print out bytes as we couldn't decode. */
41891
0
        for (i = 0; i < len; i++) {
41892
0
            XFPRINTF(file, "%02x", oid[i]);
41893
            /* Add separator. */
41894
0
            if (i < len - 1) {
41895
0
                XFPRINTF(file, ":");
41896
0
            }
41897
0
        }
41898
0
    }
41899
0
}
41900
41901
/* OID value to name mapping. */
41902
typedef struct OidName {
41903
    /* wolfSSL OID value. */
41904
    word32 oid;
41905
    /* Long name to print when OID seen. */
41906
    const char* name;
41907
} OidName;
41908
41909
/* Extra OID to name mappings. */
41910
static const OidName extraOids[] = {
41911
    { 0x005c, "commonName" },
41912
    { 0x005d, "surname" },
41913
    { 0x005e, "serialNumber" },
41914
    { 0x005f, "countryName" },
41915
    { 0x0060, "localityName" },
41916
    { 0x0061, "stateOrProvinceName" },
41917
    { 0x0062, "streetAddress" },
41918
    { 0x0063, "organizationName" },
41919
    { 0x0064, "organizationUnitName" },
41920
    { 0x0065, "title" },
41921
    { 0x0086, "certificateExtension" },
41922
    { 0x028d, "emailAddress" },
41923
    { 0x0293, "challengePassword" },
41924
    { 0x029a, "extensionReq" },
41925
};
41926
/* Length of table of extra OID to name mappings. */
41927
0
#define EXTRA_OIDS_LEN   ((int)(sizeof(extraOids) / sizeof(*extraOids)))
41928
41929
/* Convert OID value to long name.
41930
 *
41931
 * @param [in]  oid   OID value.
41932
 * @param [out] name  Long name for OID when known.
41933
 * @return  1 when OID known.
41934
 * @return  0 when OID not known.
41935
 */
41936
static int Oid2LongName(word32 oid, const char** name)
41937
0
{
41938
0
    int ret = 0;
41939
0
    int i;
41940
41941
    /* Step through each entry in table. */
41942
0
    for (i = 0; i < EXTRA_OIDS_LEN; i++) {
41943
0
        if (extraOids[i].oid == oid) {
41944
            /* Return the name associated with the OID value. */
41945
0
            *name = extraOids[i].name;
41946
0
            ret = 1;
41947
0
            break;
41948
0
        }
41949
0
    }
41950
41951
0
    return ret;
41952
0
}
41953
41954
/* Print the text version of the OBJECT_ID.
41955
 *
41956
 * @param [in] asn1  ASN.1 parse object.
41957
 * @param [in] opts  ASN.1 options for printing.
41958
 */
41959
static void PrintObjectIdText(Asn1* asn1, Asn1PrintOptions* opts)
41960
0
{
41961
0
    word32 oid = (word32)-1;
41962
#if !defined(WOLFCRYPT_ONLY) && defined(OPENSSL_EXTRA)
41963
    int nid;
41964
#endif
41965
0
    const char* ln = NULL;
41966
0
    word32 idx = 0;
41967
0
    int known = 1;
41968
41969
    /* Get the OID value for the OBJECT_ID. */
41970
0
    if (GetObjectId(asn1->data + asn1->offset, &idx, &oid, oidIgnoreType,
41971
0
            asn1->item.len + 2) == WC_NO_ERR_TRACE(ASN_PARSE_E)) {
41972
0
        known = 0;
41973
0
    }
41974
0
    else
41975
#if !defined(WOLFCRYPT_ONLY) && defined(OPENSSL_EXTRA)
41976
    /* Lookup NID for OID value. */
41977
    if ((nid = oid2nid(oid, oidIgnoreType)) != -1) {
41978
        /* Lookup long name for NID. */
41979
        ln = wolfSSL_OBJ_nid2ln(nid);
41980
    }
41981
    else
41982
#endif
41983
    /* Lookup long name for extra known OID values. */
41984
0
    if (Oid2LongName(oid, &ln) != 0) {
41985
0
    }
41986
0
    else if ((asn1->nameCb != NULL) && (idx >= 2) &&
41987
0
             ((ln = asn1->nameCb(asn1->data + asn1->offset + 2,
41988
0
                                 idx - 2))) != NULL) {
41989
0
    }
41990
0
    else {
41991
        /* Unknown OID value. */
41992
0
        ln = NULL;
41993
0
        known = 0;
41994
0
    }
41995
0
    XFPRINTF(asn1->file, ":");
41996
    /* Show OID value if not known or asked to. */
41997
0
    if ((!known) || opts->show_oid) {
41998
0
        XFPRINTF(asn1->file, "(0x%x) ", oid);
41999
0
    }
42000
0
    if (ln != NULL) {
42001
        /* Print long name. */
42002
0
        XFPRINTF(asn1->file, "%s", ln);
42003
0
    }
42004
0
    else {
42005
        /* Print out as numbers - either dotted or hex values. */
42006
0
        PrintObjectIdNum(asn1->file, asn1->data + asn1->item.data_idx,
42007
0
            asn1->item.len);
42008
0
    }
42009
0
}
42010
42011
/* Print ASN.1 data as a character string.
42012
 *
42013
 * @param [in] asn1  ASN.1 parse object.
42014
 */
42015
static void PrintText(Asn1* asn1)
42016
0
{
42017
0
    word32 i;
42018
42019
0
    XFPRINTF(asn1->file, ":");
42020
    /* Print all data bytes as characters. */
42021
0
    for (i = 0; i < asn1->item.len; i++) {
42022
0
        XFPRINTF(asn1->file, "%c", asn1->data[asn1->item.data_idx + i]);
42023
0
    }
42024
0
}
42025
42026
/* Print data as a hex bytes.
42027
 *
42028
 * @param [in] file  File pointer to write to.
42029
 * @param [in] data  Data to print.
42030
 * @param [in] len   Number of bytes to print.
42031
 */
42032
static void PrintHex(XFILE file, unsigned char* data, word32 len)
42033
0
{
42034
0
    word32 i;
42035
42036
    /* Print data bytes as hex numbers. */
42037
0
    for (i = 0; i < len; i++) {
42038
0
        XFPRINTF(file, "%02x", data[i]);
42039
0
    }
42040
0
}
42041
42042
/* Print ASN.1 data as a hex bytes.
42043
 *
42044
 * @param [in] asn1  ASN.1 parse object.
42045
 */
42046
static void PrintHexText(Asn1* asn1)
42047
0
{
42048
0
    XFPRINTF(asn1->file, ":");
42049
0
    PrintHex(asn1->file, asn1->data + asn1->item.data_idx, asn1->item.len);
42050
0
}
42051
42052
/* Print ASN.1 BIT_STRING data as hex bytes noting special first byte.
42053
 *
42054
 * @param [in] asn1  ASN.1 parse object.
42055
 */
42056
static void PrintBitStringText(Asn1* asn1)
42057
0
{
42058
0
    if (asn1->item.len > 0) {
42059
0
        XFPRINTF(asn1->file, ":[%02x]", asn1->data[asn1->item.data_idx]);
42060
0
        PrintHex(asn1->file, asn1->data + asn1->item.data_idx + 1,
42061
0
            asn1->item.len - 1);
42062
0
    }
42063
0
}
42064
42065
/* Print ASN.1 BOOLEAN data as text with value.
42066
 *
42067
 * @param [in] asn1  ASN.1 parse object.
42068
 */
42069
static void PrintBooleanText(Asn1* asn1)
42070
0
{
42071
    /* Booleans should be 1 byte of data. */
42072
0
    if (asn1->item.len == 1) {
42073
0
        XFPRINTF(asn1->file, ":%s (%d)",
42074
0
            (asn1->data[asn1->item.data_idx] == 0) ? "FALSE" : "TRUE",
42075
0
            asn1->data[asn1->item.data_idx]);
42076
0
    }
42077
0
}
42078
42079
/* Print ASN.1 data as single byte +/- number.
42080
 *
42081
 * @param [in] asn1  ASN.1 parse object.
42082
 */
42083
static void PrintNumberText(Asn1* asn1)
42084
0
{
42085
    /* Only supporting 1 byte of data for now. */
42086
0
    if (asn1->item.len == 1) {
42087
0
       int num = asn1->data[asn1->item.data_idx];
42088
42089
0
       XFPRINTF(asn1->file, ":%d", num >= 0x80 ? num - 0x100 : num);
42090
0
    }
42091
0
}
42092
42093
/* Print ASN.1 data as a text based on the tag.
42094
 *
42095
 * TODO: handle more tags.
42096
 *
42097
 * @param [in] asn1  ASN.1 parse object.
42098
 * @param [in] opts  ASN.1 options for printing.
42099
 */
42100
static void PrintAsn1Text(Asn1* asn1, Asn1PrintOptions* opts)
42101
0
{
42102
    /* Get the long name for OBJECT_ID where possible. */
42103
0
    if (asn1->item.tag == ASN_OBJECT_ID) {
42104
0
        PrintObjectIdText(asn1, opts);
42105
0
    }
42106
    /* Data is an array of printable characters. */
42107
0
    else if ((asn1->item.tag == ASN_UTF8STRING) ||
42108
0
             (asn1->item.tag == ASN_IA5_STRING) ||
42109
0
             (asn1->item.tag == ASN_PRINTABLE_STRING) ||
42110
0
             (asn1->item.tag == ASN_T61STRING) ||
42111
0
             (asn1->item.tag == ASN_BMPSTRING) ||
42112
0
             (asn1->item.tag == ASN_UTC_TIME) ||
42113
0
             (asn1->item.tag == ASN_GENERALIZED_TIME) ||
42114
0
             (asn1->item.tag == ASN_UNIVERSALSTRING) ||
42115
0
             (asn1->item.tag == ASN_OBJECT_DESC) ||
42116
0
             (asn1->item.tag == ASN_CHARACTER_STRING)) {
42117
0
        PrintText(asn1);
42118
0
    }
42119
    /* Show TRUE and FALSE with number. */
42120
0
    else if (asn1->item.tag == ASN_BOOLEAN) {
42121
0
        PrintBooleanText(asn1);
42122
0
    }
42123
    /* Show number. */
42124
0
    else if (asn1->item.tag == ASN_ENUMERATED) {
42125
0
        PrintNumberText(asn1);
42126
0
    }
42127
    /* Dumping potentially long string of hex digites. */
42128
0
    else if (!opts->show_no_dump_text) {
42129
        /* Dump all bytes. */
42130
0
        if ((asn1->item.tag == ASN_INTEGER) ||
42131
0
            (asn1->item.tag == ASN_OCTET_STRING) ||
42132
0
            ((asn1->item.tag > ASN_APPLICATION) && (asn1->item.cons))) {
42133
0
            PrintHexText(asn1);
42134
0
        }
42135
        /* First byte is number of unused bits in last byte.
42136
         * Print first specially and dump rest of the bytes. */
42137
0
        else if (asn1->item.tag == ASN_BIT_STRING) {
42138
0
            PrintBitStringText(asn1);
42139
0
        }
42140
0
    }
42141
0
}
42142
42143
0
#define HexToChar(n) ((((n) >= 32) && ((n) < 127)) ? (n) : '.')
42144
42145
/* Dump data as hex bytes.
42146
 *
42147
 * @param [in] file  File pointer to write to.
42148
 * @param [in] data  Data to print.
42149
 * @param [in] len   Number of bytes to print.
42150
 */
42151
static void DumpData(XFILE file, unsigned char* data, word32 len)
42152
0
{
42153
0
    word32 i;
42154
0
    word32 j;
42155
42156
0
    for (i = 0; i < len; i += j) {
42157
        /* Print offset. */
42158
0
        XFPRINTF(file, "       %04x:", i);
42159
0
        for (j = 0; (j < 16) && (i + j < len); j++) {
42160
            /* Print byte as hex number. */
42161
0
            XFPRINTF(file, "%s%02x", (j == 8) ? "  " : " ", data[i + j]);
42162
0
        }
42163
        /* Print spaces between hex and characters. */
42164
0
        XFPRINTF(file, "   %*s", (16 - j) * 3 + ((j < 8) ? 1 : 0), "");
42165
0
        for (j = 0; (j < 16) && (i + j < len); j++) {
42166
            /* Print byte as hex number. */
42167
0
            XFPRINTF(file, "%c", HexToChar(data[i + j]));
42168
0
        }
42169
0
        XFPRINTF(file, "\n");
42170
0
    }
42171
0
}
42172
42173
/* Update current depth based on the current position.
42174
 *
42175
 * @param [in, out] asn1  ASN.1 parse object.
42176
 */
42177
static void UpdateDepth(Asn1* asn1)
42178
0
{
42179
    /* If current index is greater than or equal end index then it is done. */
42180
0
    while ((asn1->depth > 0) &&
42181
0
           (asn1->end_idx[asn1->depth-1] <= asn1->curr)) {
42182
        /* Move up a depth. */
42183
0
        asn1->depth--;
42184
0
    }
42185
0
}
42186
42187
/* Check validity of end index of constructed ASN.1 items.
42188
 *
42189
 * @param [in, out] asn1  ASN.1 parse object.
42190
 * @return  0 on success.
42191
 * @return  ASN_DEPTH_E when end offset invalid.
42192
 */
42193
static int CheckDepth(Asn1* asn1)
42194
0
{
42195
0
    int ret = 0;
42196
0
    int i;
42197
0
    word32 curr_end = asn1->curr + asn1->item.len;
42198
42199
0
    for (i = 0; (ret == 0) && (i < asn1->depth); i++) {
42200
        /* Each end index must be at least as large as the current one. */
42201
0
        if (asn1->end_idx[i] < asn1->end_idx[asn1->depth]) {
42202
0
            ret = ASN_DEPTH_E;
42203
0
        }
42204
        /* Each end index must be at least as large as current index. */
42205
0
        if (asn1->end_idx[i] < curr_end) {
42206
0
            ret = ASN_DEPTH_E;
42207
0
        }
42208
0
    }
42209
42210
0
    return ret;
42211
0
}
42212
42213
/* Draw branching based on depth for an ASN.1 item.
42214
 *
42215
 * @param [in] asn1  ASN.1 parse object.
42216
 */
42217
static void DrawBranch(Asn1* asn1)
42218
0
{
42219
0
    int i;
42220
0
    word32 end = asn1->curr + asn1->item.len;
42221
42222
    /* Write out the character for all depths but current. */
42223
0
    for (i = 0; i < asn1->depth; i++) {
42224
0
        if (asn1->item.cons || (end < asn1->end_idx[i])) {
42225
0
            if (i < asn1->depth - 1) {
42226
                /* Constructed or not end index and not current depth: | */
42227
0
                XFPRINTF(asn1->file, "\xe2\x94\x82");
42228
0
            }
42229
0
            else {
42230
                /* Constructed or not end index and current depth: |- */
42231
0
                XFPRINTF(asn1->file, "\xe2\x94\x9c");
42232
0
            }
42233
0
        }
42234
0
        else if ((i > 1) && (end >= asn1->end_idx[i-1])) {
42235
            /* End index for previous: _|_ (in top half) */
42236
0
            XFPRINTF(asn1->file, "\xe2\x94\xb4");
42237
0
        }
42238
0
        else {
42239
            /* End index but not for previous: L (in top half) */
42240
0
            XFPRINTF(asn1->file, "\xe2\x94\x94");
42241
0
        }
42242
0
    }
42243
    /* Prefix to tag name. */
42244
0
    if (asn1->item.cons) {
42245
0
        if (asn1->depth > 0) {
42246
            /* Have other line to connect to: T (in bottom half) */
42247
0
            XFPRINTF(asn1->file, "\xe2\x94\xac");
42248
0
        }
42249
0
        else {
42250
            /* Have no other line to connect to: r */
42251
0
            XFPRINTF(asn1->file, "\xe2\x94\x8c");
42252
0
        }
42253
0
    }
42254
0
    else {
42255
        /* In a sequence: - */
42256
0
        XFPRINTF(asn1->file, "\xe2\x94\x80");
42257
0
    }
42258
0
}
42259
42260
/* Print data as hex bytes separated by space.
42261
 *
42262
 * @param [in] file  File pointer to write to.
42263
 * @param [in] data  Data to print.
42264
 * @param [in] len   Number of bytes to print.
42265
 */
42266
static void PrintHexBytes(XFILE file, unsigned char* data, word32 len)
42267
0
{
42268
0
    word32 i;
42269
42270
0
    for (i = 0; i < len; i++) {
42271
0
        XFPRINTF(file, " %02x", data[i]);
42272
0
    }
42273
0
}
42274
42275
/* Dump header data.
42276
 *
42277
 * @param [in] asn1  ASN.1 parse object.
42278
 * @param [in] opts  ASN.1 options for printing.
42279
 */
42280
static void DumpHeader(Asn1* asn1, Asn1PrintOptions* opts)
42281
0
{
42282
    /* Put on same line when not showing data too and not showing text data. */
42283
0
    if ((!opts->show_data) && opts->show_no_text) {
42284
0
        XFPRINTF(asn1->file, "%10s", "");
42285
0
    }
42286
0
    else {
42287
        /* Align with start of data. */
42288
0
        XFPRINTF(asn1->file, "\n%12s", "");
42289
0
    }
42290
0
    XFPRINTF(asn1->file, " %02x", asn1->item.tag);
42291
0
    if (asn1->curr >= asn1->offset + 1) {
42292
        /* Print the header bytes as hex bytes separated by a space. */
42293
0
        PrintHexBytes(asn1->file, asn1->data + asn1->offset + 1,
42294
0
            asn1->curr - (asn1->offset + 1));
42295
0
    }
42296
0
}
42297
42298
/* Print ASN.1 item info based on header and indices.
42299
 *
42300
 * @param [in] asn1  ASN.1 parse object.
42301
 * @param [in] opts  ASN.1 options for printing.
42302
 */
42303
static void PrintInfo(Asn1* asn1, Asn1PrintOptions* opts)
42304
0
{
42305
    /* Print offset of this ASN.1 item. */
42306
0
    XFPRINTF(asn1->file, "%4d: ", asn1->offset);
42307
    /* Print length of header. */
42308
0
    XFPRINTF(asn1->file, "%1d ", asn1->curr - asn1->offset);
42309
    /* Print data length. */
42310
0
    XFPRINTF(asn1->file, "%c%4d%c", asn1->item.cons ? '[' : '+', asn1->item.len,
42311
0
                      asn1->item.cons ? ']' : ' ');
42312
    /* Print depth. */
42313
0
    XFPRINTF(asn1->file, " %s(%d)", (asn1->depth < 10) ? " " : "", asn1->depth);
42314
0
    if (!opts->draw_branch) {
42315
        /* Indent to depth as required. */
42316
0
        XFPRINTF(asn1->file, "%*s ", asn1->depth * opts->indent, "");
42317
0
        if (!opts->indent) {
42318
            /* Indicate constructed if no indent. */
42319
0
            XFPRINTF(asn1->file, "%c", asn1->item.cons ? '+' : ' ');
42320
0
        }
42321
0
    }
42322
0
    else {
42323
        /* Draw branch structure for ASN.1 item. */
42324
0
        XFPRINTF(asn1->file, " ");
42325
0
        DrawBranch(asn1);
42326
0
    }
42327
    /* Print tag name. */
42328
0
    XFPRINTF(asn1->file, "%-16s", TagString(asn1->item.tag));
42329
0
}
42330
42331
/* Expecting tag part of ASN.1 item. */
42332
0
#define ASN_PART_TAG        0
42333
/* Expecting length part of ASN.1 item. */
42334
0
#define ASN_PART_LENGTH     1
42335
/* Expecting data part of ASN.1 item. */
42336
0
#define ASN_PART_DATA       2
42337
42338
/* Print next ASN.1 item.
42339
 *
42340
 * @param [in, out] asn1  ASN.1 parse object.
42341
 * @param [in]      opts  ASN.1 print options.
42342
 * @return  0 on success.
42343
 * @return  BAD_FUNC_ARG when asn1 or opts is NULL.
42344
 * @return  ASN_LEN_E when ASN.1 item's length too long.
42345
 * @return  ASN_DEPTH_E when end offset invalid.
42346
 */
42347
static int wc_Asn1_Print(Asn1* asn1, Asn1PrintOptions* opts)
42348
0
{
42349
0
    int ret = 0;
42350
42351
    /* Process tag. */
42352
0
    if (asn1->part == ASN_PART_TAG) {
42353
        /* Recalculate which depth we are at. */
42354
0
        UpdateDepth(asn1);
42355
        /* Get tag. */
42356
0
        asn1->item.tag = asn1->data[asn1->curr] & (byte)~ASN_CONSTRUCTED;
42357
        /* Store whether tag indicates constructed. */
42358
0
        asn1->item.cons = (asn1->data[asn1->curr] & ASN_CONSTRUCTED) ==
42359
0
                     ASN_CONSTRUCTED;
42360
        /* Start of ASN.1 item is current index. */
42361
0
        asn1->offset = asn1->curr;
42362
        /* Step over tag. */
42363
0
        asn1->curr++;
42364
        /* Next part is length. */
42365
0
        asn1->part = ASN_PART_LENGTH;
42366
0
    }
42367
    /* Process length. */
42368
0
    if (asn1->part == ASN_PART_LENGTH) {
42369
0
        int len;
42370
42371
        /* Decode length and step over it. */
42372
0
        if (GetLength(asn1->data, &asn1->curr, &len, asn1->max) < 0) {
42373
0
            ret = ASN_LEN_E;
42374
0
        }
42375
0
        else {
42376
            /* Store ASN.1 item data offset. */
42377
0
            asn1->item.data_idx = asn1->curr;
42378
            /* Store ASN.1 item data length. */
42379
0
            asn1->item.len = (word32)len;
42380
42381
            /* Print info about ASN.1 item. */
42382
0
            PrintInfo(asn1, opts);
42383
42384
0
            if (!asn1->item.cons) {
42385
                /* Move on to print data. */
42386
0
                asn1->part = ASN_PART_DATA;
42387
0
            }
42388
0
            else {
42389
                /* Print header now if not printing data. */
42390
0
                if (opts->show_header_data) {
42391
0
                    DumpHeader(asn1, opts);
42392
0
                }
42393
0
                XFPRINTF(asn1->file, "\n");
42394
                /* Record end offset for this depth. */
42395
0
                asn1->end_idx[asn1->depth++] = asn1->curr + asn1->item.len;
42396
                /* Done with this ASN.1 item. */
42397
0
                asn1->part = ASN_PART_TAG;
42398
0
            }
42399
            /* Check end indices are valid. */
42400
0
            ret = CheckDepth(asn1);
42401
0
        }
42402
0
    }
42403
    /* Process data. */
42404
0
    if ((ret == 0) && (asn1->part == ASN_PART_DATA)) {
42405
0
        if (!opts->show_no_text) {
42406
            /* Print text representation of data. */
42407
0
            PrintAsn1Text(asn1, opts);
42408
0
        }
42409
0
        if (opts->show_header_data) {
42410
            /* Dump header bytes. */
42411
0
            DumpHeader(asn1, opts);
42412
0
        }
42413
0
        XFPRINTF(asn1->file, "\n");
42414
0
        if (opts->show_data) {
42415
            /* Dump data bytes. */
42416
0
            DumpData(asn1->file, asn1->data + asn1->item.data_idx,
42417
0
                asn1->item.len);
42418
0
        }
42419
        /* Step past data to next ASN.1 item. */
42420
0
        asn1->curr += asn1->item.len;
42421
        /* Update the depth based on end indices. */
42422
0
        UpdateDepth(asn1);
42423
        /* Done with this ASN.1 item. */
42424
0
        asn1->part = ASN_PART_TAG;
42425
0
    }
42426
42427
    /* Make ASN.1 item printing go out. */
42428
0
    fflush(asn1->file);
42429
42430
0
    return ret;
42431
0
}
42432
42433
/* Print all ASN.1 items.
42434
 *
42435
 * @param [in, out] asn1  ASN.1 parse object.
42436
 * @param [in]      opts  ASN.1 print options.
42437
 * @param [in]      data  BER/DER data to print.
42438
 * @param [in]      len   Length of data to print in bytes.
42439
 * @return  0 on success.
42440
 * @return  BAD_FUNC_ARG when asn1, opts or data is NULL.
42441
 * @return  ASN_LEN_E when ASN.1 item's length too long.
42442
 * @return  ASN_DEPTH_E when end offset invalid.
42443
 * @return  ASN_PARSE_E when not all of an ASN.1 item parsed.
42444
 */
42445
int wc_Asn1_PrintAll(Asn1* asn1, Asn1PrintOptions* opts, unsigned char* data,
42446
    word32 len)
42447
0
{
42448
0
    int ret = 0;
42449
42450
0
    if ((asn1 == NULL) || (opts == NULL) || (data == NULL)) {
42451
0
        ret = BAD_FUNC_ARG;
42452
0
    }
42453
42454
0
    if (ret == 0) {
42455
        /* Initialize start position. */
42456
0
        asn1->curr = 0;
42457
        /* Start parsing at tag. */
42458
0
        asn1->part = ASN_PART_TAG;
42459
        /* Start depth at 0. */
42460
0
        asn1->depth = 0;
42461
42462
        /* Store the starting point of the data to parse. */
42463
0
        asn1->data = data + opts->offset;
42464
0
        if (opts->length > 0) {
42465
            /* Use user specified maximum length. */
42466
0
            asn1->max = opts->length;
42467
0
        }
42468
0
        else {
42469
            /* Maximum length is up to end from offset. */
42470
0
            asn1->max = len - opts->offset;
42471
0
        }
42472
42473
        /* Keep going while no error and have data to parse. */
42474
0
        while ((ret == 0) && (asn1->curr < asn1->max)) {
42475
            /* Print an ASN.1 item. */
42476
0
            ret = wc_Asn1_Print(asn1, opts);
42477
0
        }
42478
0
    }
42479
0
    if ((ret == 0) && (asn1->part != ASN_PART_TAG)) {
42480
        /* Stopped before finishing ASN.1 item. */
42481
0
        ret = ASN_PARSE_E;
42482
0
    }
42483
0
    if ((ret == 0) && (asn1->depth != 0)) {
42484
        /* Stopped without seeing all items in a constructed item. */
42485
0
        ret = ASN_DEPTH_E;
42486
0
    }
42487
42488
0
    return ret;
42489
0
}
42490
42491
#endif /* WOLFSSL_ASN_PRINT */
42492
#endif /* !NO_ASN */
42493
42494
/* Functions that parse, but are not using ASN.1 */
42495
#if !defined(NO_RSA) && (!defined(NO_BIG_INT) || defined(WOLFSSL_SP_MATH))
42496
/* import RSA public key elements (n, e) into RsaKey structure (key) */
42497
/* this function does not use any ASN.1 parsing */
42498
int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e,
42499
                             word32 eSz, RsaKey* key)
42500
0
{
42501
0
    if (n == NULL || e == NULL || key == NULL)
42502
0
        return BAD_FUNC_ARG;
42503
42504
0
    key->type = RSA_PUBLIC;
42505
42506
0
    if (mp_init(&key->n) != MP_OKAY)
42507
0
        return MP_INIT_E;
42508
42509
0
    if (mp_read_unsigned_bin(&key->n, n, nSz) != 0) {
42510
0
        mp_clear(&key->n);
42511
0
        return ASN_GETINT_E;
42512
0
    }
42513
#ifdef HAVE_WOLF_BIGINT
42514
    if ((int)nSz > 0 && wc_bigint_from_unsigned_bin(&key->n.raw, n, nSz) != 0) {
42515
        mp_clear(&key->n);
42516
        return ASN_GETINT_E;
42517
    }
42518
#endif /* HAVE_WOLF_BIGINT */
42519
42520
0
    if (mp_init(&key->e) != MP_OKAY) {
42521
0
        mp_clear(&key->n);
42522
0
        return MP_INIT_E;
42523
0
    }
42524
42525
0
    if (mp_read_unsigned_bin(&key->e, e, eSz) != 0) {
42526
0
        mp_clear(&key->n);
42527
0
        mp_clear(&key->e);
42528
0
        return ASN_GETINT_E;
42529
0
    }
42530
#ifdef HAVE_WOLF_BIGINT
42531
    if ((int)eSz > 0 && wc_bigint_from_unsigned_bin(&key->e.raw, e, eSz) != 0) {
42532
        mp_clear(&key->n);
42533
        mp_clear(&key->e);
42534
        return ASN_GETINT_E;
42535
    }
42536
#endif /* HAVE_WOLF_BIGINT */
42537
42538
#ifdef WOLFSSL_XILINX_CRYPT
42539
    if (wc_InitRsaHw(key) != 0) {
42540
        return BAD_STATE_E;
42541
    }
42542
#endif
42543
42544
0
    return 0;
42545
0
}
42546
#endif /* !NO_RSA && (!NO_BIG_INT || WOLFSSL_SP_MATH) */
42547
42548
#if defined(WOLFSSL_ACERT) && defined(WOLFSSL_ASN_TEMPLATE)
42549
/* Initialize decoded attribute certificate object with buffer of DER encoding.
42550
 *
42551
 * @param [in, out] acert   Decoded attribute certificate object.
42552
 * @param [in]      source  Buffer containing DER encoded certificate.
42553
 * @param [in]      inSz    Size of DER data in buffer in bytes.
42554
 * @param [in]      heap    Dynamic memory hint.
42555
 */
42556
void InitDecodedAcert(DecodedAcert* acert, const byte* source, word32 inSz,
42557
                      void* heap)
42558
{
42559
    WOLFSSL_MSG("InitDecodedAcert");
42560
42561
    if (acert == NULL) {
42562
        return;
42563
    }
42564
42565
    XMEMSET(acert, 0, sizeof(DecodedAcert));
42566
    acert->heap = heap;
42567
    acert->source = source;  /* don't own */
42568
    acert->maxIdx = inSz;    /* can't go over this index */
42569
    acert->heap = heap;
42570
42571
    InitSignatureCtx(&acert->sigCtx, heap, INVALID_DEVID);
42572
42573
    return;
42574
}
42575
42576
/* Free the decoded attribute cert object's dynamic data.
42577
 *
42578
 * @param [in, out] acert   Decoded attribute certificate object.
42579
 */
42580
void FreeDecodedAcert(DecodedAcert * acert)
42581
{
42582
    WOLFSSL_MSG("FreeDecodedAcert");
42583
42584
    if (acert == NULL) {
42585
        return;
42586
    }
42587
42588
    if (acert->holderIssuerName) {
42589
        FreeAltNames(acert->holderIssuerName, acert->heap);
42590
        acert->holderIssuerName = NULL;
42591
    }
42592
42593
    if (acert->holderEntityName) {
42594
        FreeAltNames(acert->holderEntityName, acert->heap);
42595
        acert->holderEntityName = NULL;
42596
    }
42597
42598
    if (acert->AttCertIssuerName) {
42599
        FreeAltNames(acert->AttCertIssuerName, acert->heap);
42600
        acert->AttCertIssuerName = NULL;
42601
    }
42602
42603
    FreeSignatureCtx(&acert->sigCtx);
42604
42605
    XMEMSET(acert, 0, sizeof(DecodedAcert));
42606
    return;
42607
}
42608
42609
/* Decode an Attribute Cert GeneralName field.
42610
 *
42611
 * @param [in]      input     Buffer containing encoded OtherName.
42612
 * @param [in, out] inOutIdx  On in, the index of the start of the OtherName.
42613
 *                            On out, index after OtherName.
42614
 * @param [in]      len       Length of data in buffer.
42615
 * @param [in]      acert     Decoded attribute certificate object.
42616
 * @param [in, out] entries   Linked list of DNS name entries.
42617
 *
42618
 * @return  0 on success.
42619
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
42620
 *          is invalid.
42621
 * @return  BUFFER_E when data in buffer is too small.
42622
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
42623
 * @return  MEMORY_E when dynamic memory allocation fails.
42624
 */
42625
static int DecodeAcertGeneralName(const byte* input, word32* inOutIdx,
42626
                                  byte tag, int len, DecodedAcert* acert,
42627
                                  DNS_entry** entries)
42628
{
42629
    int    ret = 0;
42630
    word32 idx = *inOutIdx;
42631
42632
    /* GeneralName choice: dnsName */
42633
    if (tag == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) {
42634
        ret = SetDNSEntry(acert->heap, (const char*)(input + idx), len,
42635
                          ASN_DNS_TYPE, entries);
42636
        if (ret == 0) {
42637
            idx += (word32)len;
42638
        }
42639
    }
42640
#ifndef IGNORE_NAME_CONSTRAINTS
42641
    /* GeneralName choice: directoryName */
42642
    else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_DIR_TYPE)) {
42643
        int    strLen = 0;
42644
        word32 idxDir = idx;
42645
42646
        /* Expecting a SEQUENCE using up all data. */
42647
        if (GetASN_Sequence(input, &idxDir, &strLen, idx + (word32)len, 1) < 0)
42648
        {
42649
            WOLFSSL_MSG("\tfail: seq length");
42650
            return ASN_PARSE_E;
42651
        }
42652
42653
        ret = SetDNSEntry(acert->heap, (const char*)(input + idxDir), strLen,
42654
                          ASN_DIR_TYPE, entries);
42655
        if (ret == 0) {
42656
            idx += (word32)len;
42657
        }
42658
    }
42659
    /* GeneralName choice: rfc822Name */
42660
    else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE)) {
42661
        ret = SetDNSEntry(acert->heap, (const char*)(input + idx), len,
42662
                ASN_RFC822_TYPE, entries);
42663
        if (ret == 0) {
42664
            idx += (word32)len;
42665
        }
42666
    }
42667
    /* GeneralName choice: uniformResourceIdentifier */
42668
    else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_URI_TYPE)) {
42669
        WOLFSSL_MSG("\tPutting URI into list but not using");
42670
42671
    #if !defined(WOLFSSL_NO_ASN_STRICT) && !defined(WOLFSSL_FPKI)
42672
        /* Verify RFC 5280 Sec 4.2.1.6 rule:
42673
           "The name MUST NOT be a relative URI"
42674
           As per RFC 3986 Sec 4.3, an absolute URI is only required to contain
42675
           a scheme and hier-part.  So the only strict requirement is a ':'
42676
           being present after the scheme.  If a '/' is present as part of the
42677
           hier-part, it must come after the ':' (see RFC 3986 Sec 3). */
42678
        {
42679
            int i = 0;
42680
42681
            /* skip past scheme (i.e http,ftp,...) finding first ':' char */
42682
            for (i = 0; i < len; i++) {
42683
                if (input[idx + (word32)i] == ':') {
42684
                    break;
42685
                }
42686
                if (input[idx + (word32)i] == '/') {
42687
                    i = len; /* error, found relative path since '/' was
42688
                              * encountered before ':'. Returning error
42689
                              * value in next if statement. */
42690
                }
42691
            }
42692
42693
            /* test hier-part is empty */
42694
            if (i == 0 || i == len) {
42695
                WOLFSSL_MSG("\tEmpty or malformed URI");
42696
                WOLFSSL_ERROR_VERBOSE(ASN_ALT_NAME_E);
42697
                return ASN_ALT_NAME_E;
42698
            }
42699
42700
            /* test if scheme is missing  */
42701
            if (input[idx + (word32)i] != ':') {
42702
                WOLFSSL_MSG("\tAlt Name must be absolute URI");
42703
                WOLFSSL_ERROR_VERBOSE(ASN_ALT_NAME_E);
42704
                return ASN_ALT_NAME_E;
42705
            }
42706
        }
42707
    #endif
42708
42709
        ret = SetDNSEntry(acert->heap, (const char*)(input + idx), len,
42710
                          ASN_URI_TYPE, entries);
42711
        if (ret == 0) {
42712
            idx += (word32)len;
42713
        }
42714
    }
42715
    #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || \
42716
                                            defined(WOLFSSL_IP_ALT_NAME)
42717
    /* GeneralName choice: iPAddress */
42718
    else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_IP_TYPE)) {
42719
        ret = SetDNSEntry(acert->heap, (const char*)(input + idx), len,
42720
                          ASN_IP_TYPE, entries);
42721
        if (ret == 0) {
42722
            idx += (word32)len;
42723
        }
42724
    }
42725
    #endif /* WOLFSSL_QT || OPENSSL_ALL */
42726
42727
    #ifdef OPENSSL_ALL
42728
    /* GeneralName choice: registeredID */
42729
    else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_RID_TYPE)) {
42730
        ret = SetDNSEntry(acert->heap, (const char*)(input + idx), len,
42731
                ASN_RID_TYPE, entries);
42732
        if (ret == 0) {
42733
            idx += (word32)len;
42734
        }
42735
    }
42736
    #endif
42737
#endif /* IGNORE_NAME_CONSTRAINTS */
42738
    /* GeneralName choice: dNSName, x400Address, ediPartyName */
42739
    else {
42740
        WOLFSSL_MSG("\tUnsupported name type, skipping");
42741
        idx += (word32)len;
42742
    }
42743
42744
    if (ret == 0) {
42745
        /* Return index of next encoded byte. */
42746
        *inOutIdx = idx;
42747
    }
42748
    return ret;
42749
}
42750
42751
/* Decode General Names from an ACERT input.
42752
 *
42753
 * @param [in]      input    Buffer holding encoded data.
42754
 * @param [in]      sz       Size of encoded data in bytes.
42755
 * @param [in]      tag      ASN.1 tag value expected in header.
42756
 * @param [in, out] acert    Decoded attribute certificate object.
42757
 * @param [in, out] entries  Linked list of DNS name entries.
42758
 *
42759
 * @return  0 on success.
42760
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
42761
 *          is invalid.
42762
 * @return  BUFFER_E when data in buffer is too small.
42763
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
42764
 * @return  MEMORY_E when dynamic memory allocation fails.
42765
 */
42766
static int DecodeAcertGeneralNames(const byte* input, word32 sz,
42767
                                   byte tag, DecodedAcert* acert,
42768
                                   DNS_entry** entries)
42769
{
42770
    word32 idx = 0;
42771
    int    length = 0;
42772
    int    ret = 0;
42773
    word32 numNames = 0;
42774
42775
    if (GetASNHeader(input, tag, &idx, &length, sz) <= 0) {
42776
        WOLFSSL_MSG("error: acert general names: bad header");
42777
        return ASN_PARSE_E;
42778
    }
42779
42780
    if (length == 0) {
42781
        WOLFSSL_MSG("error: acert general names: zero length");
42782
        return ASN_PARSE_E;
42783
    }
42784
42785
    if ((word32)length + idx != sz) {
42786
        #ifdef DEBUG_WOLFSSL
42787
        WOLFSSL_MSG_EX("error: acert general names: got %d, expected %d",
42788
                       (word32)length + idx, sz);
42789
        #endif
42790
        return ASN_PARSE_E;
42791
    }
42792
42793
    while ((ret == 0) && (idx < sz)) {
42794
        ASNGetData dataASN[altNameASN_Length];
42795
42796
        /* Not sure what a reasonable max would be for attribute certs,
42797
         * therefore observing WOLFSSL_MAX_ALT_NAMES limit. */
42798
        numNames++;
42799
        if (numNames > WOLFSSL_MAX_ALT_NAMES) {
42800
            #ifdef DEBUG_WOLFSSL
42801
            WOLFSSL_MSG_EX("error: acert general names: too many names, %d",
42802
                           numNames);
42803
            #endif
42804
            ret = ASN_ALT_NAME_E;
42805
            break;
42806
        }
42807
42808
        /* Clear dynamic data items. */
42809
        XMEMSET(dataASN, 0, sizeof(dataASN));
42810
        /* Parse GeneralName with the choices supported. */
42811
        GetASN_Choice(&dataASN[ALTNAMEASN_IDX_GN], generalNameChoice);
42812
        /* Decode a GeneralName choice. */
42813
        ret = GetASN_Items(altNameASN, dataASN, altNameASN_Length, 0, input,
42814
                           &idx, sz);
42815
42816
        if (ret != 0) {
42817
            break;
42818
        }
42819
42820
        ret = DecodeAcertGeneralName(input, &idx,
42821
                                     dataASN[ALTNAMEASN_IDX_GN].tag,
42822
                                     (int)dataASN[ALTNAMEASN_IDX_GN].length,
42823
                                     acert, entries);
42824
    }
42825
42826
    return ret;
42827
}
42828
42829
/* Holder has three potential forms:
42830
 *   Holder ::= SEQUENCE {
42831
 *     baseCertificateID   [0] IssuerSerial OPTIONAL,
42832
 *         -- the issuer and serial number of
42833
 *         -- the holder's Public Key Certificate
42834
 *     entityName          [1] GeneralNames OPTIONAL,
42835
 *         -- the name of the claimant or role
42836
 *     objectDigestInfo    [2] ObjectDigestInfo OPTIONAL
42837
 *         -- used to directly authenticate the holder,
42838
 *         -- for example, an executable
42839
 *   }
42840
 *
42841
 * where IssuerSerial is:
42842
 *   IssuerSerial  ::=  SEQUENCE {
42843
 *     issuer         GeneralNames,
42844
 *     serial         CertificateSerialNumber,
42845
 *     issuerUID      UniqueIdentifier OPTIONAL
42846
 *   }
42847
 *
42848
 * Note:
42849
 *   - Holder Option 2 objectDigestInfo is not mandatory
42850
 *     for the spec and is not implemented here yet.
42851
 *
42852
 *   - issuerUniqueID not supported yet.
42853
 * */
42854
static const ASNItem HolderASN[] =
42855
{
42856
                     /* Holder root sequence. */
42857
/* HOLDER_SEQ  */    { 0, ASN_SEQUENCE, 1, 1, 0 },
42858
                         /* Holder Option 0:*/
42859
                         /* baseCertificateID   [0] IssuerSerial OPTIONAL */
42860
/* ISSUERSERIAL_SEQ  */  { 1, ASN_CONTEXT_SPECIFIC | 0, 1, 1, 2 },
42861
                             /* issuer         GeneralNames, */
42862
/* GN_SEQ  */                { 2, ASN_SEQUENCE, 1, 0, 0 },
42863
                             /* serial     CertificateSerialNumber */
42864
/* SERIAL_INT  */            { 2, ASN_INTEGER, 0, 0, 0 },
42865
                         /* Holder Option 1: */
42866
                         /* entityName          [1] GeneralNames OPTIONAL */
42867
/* ENTITYNAME_SEQ  */  { 1, ASN_CONTEXT_SPECIFIC | 1, 1, 1, 2 },
42868
};
42869
42870
enum {
42871
    HOLDER_IDX_SEQ = 0,
42872
    HOLDER_IDX_ISSUERSERIAL_SEQ,
42873
    HOLDER_IDX_GN_SEQ,
42874
    HOLDER_IDX_SERIAL_INT,
42875
    HOLDER_IDX_GN_SEQ_OPT1
42876
};
42877
42878
/* Number of items in ASN template for an X509 Acert. */
42879
#define HolderASN_Length (sizeof(HolderASN) / sizeof(ASNItem))
42880
42881
/* Decode the Holder field of an x509 attribute certificate.
42882
 *
42883
 * @param [in]      input     Buffer containing encoded Holder field.
42884
 * @param [in]      len       Length of Holder field.
42885
 * @param [in, out] acert     Decoded attribute certificate object.
42886
 *
42887
 * @return  0 on success.
42888
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
42889
 *          is invalid.
42890
 * @return  BUFFER_E when data in buffer is too small.
42891
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
42892
 * @return  MEMORY_E when dynamic memory allocation fails.
42893
 * */
42894
static int DecodeHolder(const byte* input, word32 len, DecodedAcert* acert)
42895
{
42896
    DECL_ASNGETDATA(dataASN, HolderASN_Length);
42897
    int    ret = 0;
42898
    word32 idx = 0;
42899
    word32 holderSerialSz = 0;
42900
42901
    if (input == NULL || len <= 0 || acert == NULL) {
42902
        return BUFFER_E;
42903
    }
42904
42905
    #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
42906
    printf("debug: decode holder: holder len: %d\n", len);
42907
    #endif /* WOLFSSL_DEBUG_ASN_TEMPLATE */
42908
42909
    CALLOC_ASNGETDATA(dataASN, HolderASN_Length, ret, acert->heap);
42910
42911
    if (ret != 0) {
42912
        FREE_ASNGETDATA(dataASN, acert->heap);
42913
        return MEMORY_E;
42914
    }
42915
42916
    holderSerialSz = EXTERNAL_SERIAL_SIZE;
42917
42918
    GetASN_Buffer(&dataASN[HOLDER_IDX_SERIAL_INT], acert->holderSerial,
42919
                  &holderSerialSz);
42920
42921
    ret = GetASN_Items(HolderASN, dataASN, HolderASN_Length, 0, input,
42922
                       &idx, len);
42923
42924
    if (ret != 0) {
42925
        WOLFSSL_MSG("error: Holder: GetASN_Items failed");
42926
        FREE_ASNGETDATA(dataASN, acert->heap);
42927
        return ret;
42928
    }
42929
42930
    if (dataASN[HOLDER_IDX_SERIAL_INT].tag != 0) {
42931
        acert->holderSerialSz = (int)holderSerialSz;
42932
    }
42933
    else {
42934
        acert->holderSerialSz = 0;
42935
    }
42936
42937
    {
42938
        /* Now parse the GeneralNames field.
42939
         * Use the HOLDER_IDX_GN_SEQ offset for input. */
42940
        const byte * gn_input = NULL;
42941
        word32       gn_len = 0;
42942
        byte         tag = 0x00;
42943
42944
        /* Determine which tag was seen. */
42945
        if (dataASN[HOLDER_IDX_GN_SEQ].tag != 0) {
42946
            gn_input = input + dataASN[HOLDER_IDX_GN_SEQ].offset;
42947
            gn_len = dataASN[HOLDER_IDX_GN_SEQ].length;
42948
            tag = dataASN[HOLDER_IDX_GN_SEQ].tag;
42949
42950
            if (gn_len >= ASN_LONG_LENGTH) {
42951
                gn_len += 3;
42952
            }
42953
            else {
42954
                gn_len += 2;
42955
            }
42956
42957
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
42958
            printf("debug: decode holder: holder index: %d\n",
42959
                   HOLDER_IDX_GN_SEQ);
42960
            #endif /* WOLFSSL_DEBUG_ASN_TEMPLATE */
42961
42962
            ret = DecodeAcertGeneralNames(gn_input, gn_len, tag, acert,
42963
                                          &acert->holderIssuerName);
42964
        }
42965
42966
        if (dataASN[HOLDER_IDX_GN_SEQ_OPT1].tag != 0) {
42967
            gn_input = input + dataASN[HOLDER_IDX_GN_SEQ_OPT1].offset;
42968
            gn_len = dataASN[HOLDER_IDX_GN_SEQ_OPT1].length;
42969
            tag = dataASN[HOLDER_IDX_GN_SEQ_OPT1].tag;
42970
42971
            if (gn_len >= ASN_LONG_LENGTH) {
42972
                gn_len += 3;
42973
            }
42974
            else {
42975
                gn_len += 2;
42976
            }
42977
42978
            #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
42979
            printf("debug: decode holder: holder index: %d\n",
42980
                   HOLDER_IDX_GN_SEQ_OPT1);
42981
            #endif /* WOLFSSL_DEBUG_ASN_TEMPLATE */
42982
42983
            ret = DecodeAcertGeneralNames(gn_input, gn_len, tag, acert,
42984
                                          &acert->holderEntityName);
42985
        }
42986
42987
        if (ret != 0) {
42988
            WOLFSSL_MSG("error: Holder: DecodeAcertGeneralNames failed");
42989
            FREE_ASNGETDATA(dataASN, acert->heap);
42990
            return ret;
42991
        }
42992
    }
42993
42994
    FREE_ASNGETDATA(dataASN, acert->heap);
42995
    return 0;
42996
}
42997
42998
/* Note on AttCertIssuer field. ACERTs are supposed to follow
42999
 * v2form, but some (acert_bc1.pem) follow v1form. Because
43000
 * of the limited set of example ACERTs, the v1form will be
43001
 * tolerated for now but the field will not be parsed.
43002
 *
43003
 * More info from RFC below:
43004
 *
43005
 * From RFC 5755.
43006
 * 4.2.3.  Issuer
43007
 *
43008
 * ACs conforming to this profile MUST use the v2Form choice, which MUST
43009
 * contain one and only one GeneralName in the issuerName, which MUST
43010
 * contain a non-empty distinguished name in the directoryName field.
43011
 * This means that all AC issuers MUST have non-empty distinguished
43012
 * names.  ACs conforming to this profile MUST omit the
43013
 * baseCertificateID and objectDigestInfo fields.
43014
 *
43015
 * 4.1.  X.509 Attribute Certificate Definition
43016
 *
43017
 * AttCertIssuer ::= CHOICE {
43018
 *   v1Form      GeneralNames,  -- MUST NOT be used in this
43019
 *                              -- profile
43020
 *   v2Form  [0] V2Form         -- v2 only
43021
 * }
43022
 *
43023
 * V2Form ::= SEQUENCE {
43024
 *   issuerName             GeneralNames  OPTIONAL,
43025
 *   baseCertificateID  [0] IssuerSerial  OPTIONAL,
43026
 *   objectDigestInfo   [1] ObjectDigestInfo  OPTIONAL
43027
 *          -- issuerName MUST be present in this profile
43028
 *          -- baseCertificateID and objectDigestInfo MUST
43029
 *          -- NOT be present in this profile
43030
 * }
43031
 * */
43032
static const ASNItem AttCertIssuerASN[] =
43033
{
43034
                           /* V2Form ::= SEQUENCE { */
43035
/* AttCertIssuer_GN_SEQ */ { 0, ASN_SEQUENCE, 1, 0, 0 },
43036
};
43037
43038
enum {
43039
    ATTCERTISSUER_IDX_GN_SEQ
43040
};
43041
43042
/* Number of items in ASN template for an X509 Acert. */
43043
#define AttCertIssuerASN_Length (sizeof(AttCertIssuerASN) / sizeof(ASNItem))
43044
43045
/* Decode the AttCertIssuer Field of an x509 attribute certificate.
43046
 *
43047
 * @param [in]      input     Buffer containing encoded AttCertIssuer field.
43048
 * @param [in]      len       Length of Holder field.
43049
 * @param [in,out]  acert     Decoded attribute certificate object.
43050
 *
43051
 * @return  0 on success.
43052
 * @return  ASN_PARSE_E when BER encoded data does not match ASN.1 items or
43053
 *          is invalid.
43054
 * @return  BUFFER_E when data in buffer is too small.
43055
 * @return  ASN_UNKNOWN_OID_E when the OID cannot be verified.
43056
 * @return  MEMORY_E when dynamic memory allocation fails.
43057
 * */
43058
static int DecodeAttCertIssuer(const byte* input, word32 len,
43059
                               DecodedAcert* cert)
43060
{
43061
    DECL_ASNGETDATA(dataASN, AttCertIssuerASN_Length);
43062
    int          ret = 0;
43063
    word32       idx = 0;
43064
    const byte * gn_input = NULL;
43065
    word32       gn_len = 0;
43066
    byte         tag = 0x00;
43067
43068
    if (input == NULL || len <= 0 || cert == NULL) {
43069
        return BUFFER_E;
43070
    }
43071
43072
    CALLOC_ASNGETDATA(dataASN, AttCertIssuerASN_Length, ret, cert->heap);
43073
43074
    if (ret != 0) {
43075
        return MEMORY_E;
43076
    }
43077
43078
    ret = GetASN_Items(AttCertIssuerASN, dataASN, AttCertIssuerASN_Length,
43079
                       0, input, &idx, len);
43080
43081
    if (ret != 0) {
43082
        FREE_ASNGETDATA(dataASN, cert->heap);
43083
        WOLFSSL_MSG("error: AttCertIssuer: GetASN_Items failed");
43084
        return ret;
43085
    }
43086
43087
    /* Now parse the GeneralNames field.
43088
     * Use the HOLDER_IDX_GN_SEQ offset for input. */
43089
    gn_input = input + dataASN[ATTCERTISSUER_IDX_GN_SEQ].offset;
43090
    gn_len = dataASN[ATTCERTISSUER_IDX_GN_SEQ].length;
43091
    tag = dataASN[ATTCERTISSUER_IDX_GN_SEQ].tag;
43092
43093
    if (gn_len >= ASN_LONG_LENGTH) {
43094
        gn_len += 3;
43095
    }
43096
    else {
43097
        gn_len += 2;
43098
    }
43099
43100
    ret = DecodeAcertGeneralNames(gn_input, gn_len, tag, cert,
43101
                                  &cert->AttCertIssuerName);
43102
43103
    if (ret != 0) {
43104
        FREE_ASNGETDATA(dataASN, cert->heap);
43105
        WOLFSSL_MSG("error: AttCertIssuer: DecodeAcertGeneralNames failed");
43106
        return ret;
43107
    }
43108
43109
    FREE_ASNGETDATA(dataASN, cert->heap);
43110
    return 0;
43111
}
43112
43113
43114
/* ASN template for an X509 Attribute Certificate,
43115
 * from RFC 5755
43116
 */
43117
static const ASNItem AcertASN[] =
43118
{
43119
                          /* AttributeCertificate ::= SEQUENCE */
43120
/* SEQ                */  { 0, ASN_SEQUENCE, 1, 1, 0 },
43121
                              /* AttributeCertificateInfo ::= SEQUENCE  */
43122
/* ACINFO_SEQ         */      { 1, ASN_SEQUENCE, 1, 1, 0 },
43123
                                  /* AttCertVersion ::= INTEGER { v2(1) } */
43124
/* ACINFO_VER_INT     */          { 2, ASN_INTEGER, 0, 0, 0 },
43125
                                  /* holder   Holder */
43126
/* ACINFO_HOLDER_SEQ  */          { 2, ASN_SEQUENCE, 1, 0, 0 },
43127
                                  /* issuer   AttCertIssuer */
43128
                                  /* v2Form   [0] V2Form  */
43129
/* ACINFO_ISSUER_V2FORM */        { 2, ASN_CONTEXT_SPECIFIC | 0, 1, 0, 2 },
43130
                                  /* v1Form   GeneralNames */
43131
/* ACINFO_ISSUER_V1FORM  */       { 2, ASN_SEQUENCE, 1, 0, 2 },
43132
                                  /* signature    AlgorithmIdentifier */
43133
                                  /* AlgorithmIdentifier ::= SEQUENCE */
43134
/* ACINFO_ALGOID_SEQ */           { 2, ASN_SEQUENCE, 1, 1, 0 },
43135
                                      /* Algorithm    OBJECT IDENTIFIER */
43136
/* ACINFO_ALGOID_OID */               { 3, ASN_OBJECT_ID, 0, 0, 0 },
43137
                                      /* parameters */
43138
/* ACINFO_ALGOID_PARAMS_NULL */       { 3, ASN_TAG_NULL, 0, 0, 2 },
43139
#ifdef WC_RSA_PSS
43140
/* ACINFO_ALGOID_PARAMS */            { 3, ASN_SEQUENCE, 1, 0, 2 },
43141
#endif
43142
                                  /* CertificateSerialNumber ::= INTEGER */
43143
/* ACINFO_SERIAL        */        { 2, ASN_INTEGER, 0, 0, 0 },
43144
                                  /* Validity ::= SEQUENCE */
43145
/* ACINFO_VALIDITY_SEQ      */    { 2, ASN_SEQUENCE, 1, 1, 0 },
43146
                                      /* notBeforeTime  GeneralizedTime,  */
43147
/* ACINFO_VALIDITY_NOTB_GT  */        { 3, ASN_GENERALIZED_TIME, 0, 0, 2 },
43148
                                      /* notAfterTime   GeneralizedTime */
43149
/* ACINFO_VALIDITY_NOTA_GT  */        { 3, ASN_GENERALIZED_TIME, 0, 0, 3 },
43150
                                  /* attributes        SEQUENCE OF Attribute */
43151
/* ACINFO_ATTRIBUTES_SEQ    */    { 2, ASN_SEQUENCE, 1, 0, 0 },
43152
                                  /* issuerUniqueID    OPTIONAL, */
43153
/* ACINFO_UNIQUE_ID         */    { 2, ASN_CONTEXT_SPECIFIC | 1, 0, 0, 1 },
43154
                                  /* extensions        OPTIONAL */
43155
/* ACINFO_EXT               */    { 2, ASN_CONTEXT_SPECIFIC | 2, 1, 1, 1 },
43156
/* ACINFO_EXT_SEQ           */    { 2, ASN_SEQUENCE, 1, 0, 1 },
43157
                              /* signature    AlgorithmIdentifier */
43158
                              /* AlgorithmIdentifier ::= SEQUENCE */
43159
/* SIGALGO_SEQ         */     { 1, ASN_SEQUENCE, 1, 1, 0 },
43160
                                  /* Algorithm    OBJECT IDENTIFIER */
43161
/* SIGALGO_OID         */         { 2, ASN_OBJECT_ID, 0, 0, 0 },
43162
                                  /* parameters */
43163
/* SIGALGO_PARAMS_NULL */         { 2, ASN_TAG_NULL, 0, 0, 2 },
43164
#ifdef WC_RSA_PSS
43165
/* SIGALGO_PARAMS      */         { 2, ASN_SEQUENCE, 1, 0, 2 },
43166
#endif
43167
                              /* signature    BIT STRING */
43168
/* SIGNATURE           */     { 1, ASN_BIT_STRING, 0, 0, 0 },
43169
};
43170
43171
enum {
43172
    ACERT_IDX_SEQ = 0,
43173
    ACERT_IDX_ACINFO_SEQ,
43174
    ACERT_IDX_ACINFO_VER_INT,
43175
    /* ACINFO holder and issuer */
43176
    ACERT_IDX_ACINFO_HOLDER_SEQ,
43177
    /* The issuer should be in V2 form, but tolerate V1 for now. */
43178
    ACERT_IDX_ACINFO_ISSUER_V2,
43179
    ACERT_IDX_ACINFO_ISSUER_V1,
43180
    /* ACINFO sig alg*/
43181
    ACERT_IDX_ACINFO_ALGOID_SEQ,
43182
    ACERT_IDX_ACINFO_ALGOID_OID,
43183
    ACERT_IDX_ACINFO_ALGOID_PARAMS_NULL,
43184
#ifdef WC_RSA_PSS
43185
    /* Additional RSA-PSS params. */
43186
    ACERT_IDX_ACINFO_ALGOID_PARAMS,
43187
#endif
43188
    /* serial number */
43189
    ACERT_IDX_ACINFO_SERIAL,
43190
    /* validity time */
43191
    ACERT_IDX_ACINFO_VALIDITY_SEQ,
43192
    ACERT_IDX_ACINFO_VALIDITY_NOTB_GT,
43193
    ACERT_IDX_ACINFO_VALIDITY_NOTA_GT,
43194
    /* attributes */
43195
    ACERT_IDX_ACINFO_ATTRIBUTES_SEQ,
43196
    /* unique identifier */
43197
    ACERT_IDX_ACINFO_UNIQUE_ID,
43198
    /* extensions */
43199
    ACERT_ACINFO_EXT,
43200
    ACERT_ACINFO_EXT_SEQ,
43201
    /* sig alg */
43202
    ACERT_IDX_SIGALGO_SEQ,
43203
    ACERT_IDX_SIGALGO_OID,
43204
    ACERT_IDX_SIGALGO_PARAMS_NULL,
43205
#ifdef WC_RSA_PSS
43206
    /* Additional RSA-PSS params. */
43207
    ACERT_IDX_SIGALGO_PARAMS,
43208
#endif
43209
    /* signature */
43210
    ACERT_IDX_SIGNATURE,
43211
    WOLF_ENUM_DUMMY_LAST_ELEMENT(ACERT_IDX)
43212
};
43213
43214
/* Number of items in ASN template for an X509 Acert. */
43215
#define AcertASN_Length (sizeof(AcertASN) / sizeof(ASNItem))
43216
43217
/* Initial implementation for parsing and verifying an
43218
 * X509 Attribute Certificate (RFC 5755).
43219
 *
43220
 * At present these fields are NOT parsed:
43221
 *   - issuerUniqueID
43222
 *   - extensions
43223
 *   - attributes
43224
 *
43225
 * @param [in, out] acert   Decoded attribute certificate object.
43226
 * @param [in]      verify  Whether to verify dates.
43227
 * @return  0 on success.
43228
 * @return  negative error code on error/fail.
43229
 * */
43230
int ParseX509Acert(DecodedAcert* acert, int verify)
43231
{
43232
    DECL_ASNGETDATA(dataASN, AcertASN_Length);
43233
    int    ret = 0;
43234
    word32 idx = 0;
43235
    int    badDate = 0;
43236
    byte   version = 0;
43237
    word32 serialSz = EXTERNAL_SERIAL_SIZE;
43238
43239
    WOLFSSL_MSG("ParseX509Acert");
43240
43241
    if (acert == NULL) {
43242
        return BAD_FUNC_ARG;
43243
    }
43244
43245
    CALLOC_ASNGETDATA(dataASN, AcertASN_Length, ret, acert->heap);
43246
43247
    if (ret != 0) {
43248
        return MEMORY_E;
43249
    }
43250
43251
    /* Get the version and put the serial number into the buffer. */
43252
    GetASN_Int8Bit(&dataASN[ACERT_IDX_ACINFO_VER_INT], &version);
43253
43254
    GetASN_Buffer(&dataASN[ACERT_IDX_ACINFO_SERIAL], acert->serial,
43255
                  &serialSz);
43256
43257
    /* Check OID types for signature algorithm. */
43258
    GetASN_OID(&dataASN[ACERT_IDX_ACINFO_ALGOID_OID], oidSigType);
43259
    GetASN_OID(&dataASN[ACERT_IDX_SIGALGO_OID], oidSigType);
43260
43261
    /* Parse the X509 certificate. */
43262
    ret = GetASN_Items(AcertASN, dataASN, AcertASN_Length, 1,
43263
                       acert->source, &acert->srcIdx, acert->maxIdx);
43264
43265
    if (ret != 0) {
43266
        FREE_ASNGETDATA(dataASN, acert->heap);
43267
        return ret;
43268
    }
43269
43270
    /* Check version is valid/supported - can't be negative. */
43271
    if (version > MAX_X509_VERSION) {
43272
        FREE_ASNGETDATA(dataASN, acert->heap);
43273
        WOLFSSL_MSG("Unexpected attribute certificate version");
43274
        WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
43275
        return ASN_PARSE_E;
43276
    }
43277
43278
    acert->version = version;
43279
    acert->serialSz = (int)serialSz;
43280
43281
    acert->signatureOID = dataASN[ACERT_IDX_ACINFO_ALGOID_OID].data.oid.sum;
43282
    acert->certBegin = dataASN[ACERT_IDX_ACINFO_SEQ].offset;
43283
43284
    /* check BEFORE date. */
43285
    idx = ACERT_IDX_ACINFO_VALIDITY_NOTB_GT;
43286
    if (CheckDate(&dataASN[idx], BEFORE) < 0) {
43287
        if ((verify != NO_VERIFY) && (verify != VERIFY_SKIP_DATE) &&
43288
            (! AsnSkipDateCheck))
43289
        {
43290
            badDate = ASN_BEFORE_DATE_E;
43291
        }
43292
    }
43293
43294
    /* Store reference to BEFORE date. */
43295
    acert->beforeDate = GetASNItem_Addr(dataASN[idx], acert->source);
43296
    acert->beforeDateLen = (int)GetASNItem_Length(dataASN[idx], acert->source);
43297
43298
    /* check AFTER date. */
43299
    idx = ACERT_IDX_ACINFO_VALIDITY_NOTA_GT;
43300
    if (CheckDate(&dataASN[idx], AFTER) < 0) {
43301
        if ((verify != NO_VERIFY) && (verify != VERIFY_SKIP_DATE) &&
43302
            (! AsnSkipDateCheck))
43303
        {
43304
            badDate = ASN_BEFORE_DATE_E;
43305
        }
43306
    }
43307
43308
    /* Store reference to AFTER date. */
43309
    acert->afterDate = GetASNItem_Addr(dataASN[idx], acert->source);
43310
    acert->afterDateLen = (int)GetASNItem_Length(dataASN[idx], acert->source);
43311
43312
    /* Store the signature information. */
43313
    acert->sigIndex = dataASN[ACERT_IDX_SIGALGO_SEQ].offset;
43314
    GetASN_GetConstRef(&dataASN[ACERT_IDX_SIGNATURE],
43315
                       &acert->signature, &acert->sigLength);
43316
43317
    /* Make sure 'signature' and 'signatureAlgorithm' are the same. */
43318
    if (dataASN[ACERT_IDX_SIGALGO_OID].data.oid.sum != acert->signatureOID) {
43319
        FREE_ASNGETDATA(dataASN, acert->heap);
43320
        WOLFSSL_ERROR_VERBOSE(ASN_SIG_OID_E);
43321
        return ASN_SIG_OID_E;
43322
    }
43323
43324
    /* Parameters not allowed after ECDSA or EdDSA algorithm OID. */
43325
    if (IsSigAlgoECC(acert->signatureOID)) {
43326
        if ((dataASN[ACERT_IDX_SIGALGO_PARAMS_NULL].tag != 0)
43327
    #ifdef WC_RSA_PSS
43328
            || (dataASN[ACERT_IDX_SIGALGO_PARAMS].tag != 0)
43329
    #endif
43330
            ) {
43331
            FREE_ASNGETDATA(dataASN, acert->heap);
43332
            WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
43333
            return ASN_PARSE_E;
43334
        }
43335
    }
43336
43337
    #ifdef WC_RSA_PSS
43338
    /* Check parameters starting with a SEQUENCE. */
43339
    if (dataASN[ACERT_IDX_SIGALGO_PARAMS].tag != 0) {
43340
        word32       oid = dataASN[ACERT_IDX_SIGALGO_OID].data.oid.sum;
43341
        word32       sigAlgParamsSz = 0;
43342
        const byte * acParams = NULL;
43343
        word32       acParamsSz = 0;
43344
        const byte * sigAlgParams = NULL;
43345
43346
        /* Parameters only with RSA PSS. */
43347
        if (oid != CTC_RSASSAPSS) {
43348
            FREE_ASNGETDATA(dataASN, acert->heap);
43349
            WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
43350
            return ASN_PARSE_E;
43351
        }
43352
43353
        /* Check RSA PSS parameters are the same. */
43354
        acParams = GetASNItem_Addr(dataASN[ACERT_IDX_ACINFO_ALGOID_PARAMS],
43355
                                   acert->source);
43356
        acParamsSz = GetASNItem_Length(dataASN[ACERT_IDX_ACINFO_ALGOID_PARAMS],
43357
                                       acert->source);
43358
        sigAlgParams = GetASNItem_Addr(dataASN[ACERT_IDX_SIGALGO_PARAMS],
43359
                                       acert->source);
43360
        sigAlgParamsSz = GetASNItem_Length(dataASN[ACERT_IDX_SIGALGO_PARAMS],
43361
                                           acert->source);
43362
43363
        if ((acParamsSz != sigAlgParamsSz) ||
43364
            (XMEMCMP(acParams, sigAlgParams, acParamsSz) != 0)) {
43365
43366
            FREE_ASNGETDATA(dataASN, acert->heap);
43367
            WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
43368
            return ASN_PARSE_E;
43369
        }
43370
43371
        /* Store RSA PSS parameters for use in signature verification. */
43372
        acert->sigParamsIndex = dataASN[ACERT_IDX_SIGALGO_PARAMS].offset;
43373
        acert->sigParamsLength = sigAlgParamsSz;
43374
    }
43375
    #endif
43376
43377
    /* Store the raw Attributes field. */
43378
    GetASN_GetConstRef(&dataASN[ACERT_IDX_ACINFO_ATTRIBUTES_SEQ],
43379
                       &acert->rawAttr, &acert->rawAttrLen);
43380
43381
    {
43382
        /* Now parse the Holder and AttCertIssuer fields.
43383
         * Use the ACINFO holder and issuer sequence offset for input. */
43384
        const byte * holder_input = NULL;
43385
        word32       holder_len = 0;
43386
        const byte * issuer_input = NULL;
43387
        word32       issuer_len = 0;
43388
        word32       i_holder = ACERT_IDX_ACINFO_HOLDER_SEQ;
43389
        word32       i_issuer = 0;
43390
43391
        /* Determine which issuer tag was seen. We need this to determine
43392
         * the holder_input. */
43393
        i_issuer = (dataASN[ACERT_IDX_ACINFO_ISSUER_V2].tag != 0) ?
43394
                    ACERT_IDX_ACINFO_ISSUER_V2 : ACERT_IDX_ACINFO_ISSUER_V1;
43395
43396
        #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
43397
        printf("debug: parse acert: issuer index: %d\n", i_issuer);
43398
        printf("debug: parse acert: issuer seq offset: %d\n",
43399
               dataASN[i_issuer].offset);
43400
        #endif /* WOLFSSL_DEBUG_ASN_TEMPLATE */
43401
43402
        holder_input = acert->source + dataASN[i_holder].offset;
43403
        holder_len = dataASN[i_issuer].offset - dataASN[i_holder].offset;
43404
43405
        ret = DecodeHolder(holder_input, holder_len, acert);
43406
43407
        if (ret != 0) {
43408
            FREE_ASNGETDATA(dataASN, acert->heap);
43409
            return ret;
43410
        }
43411
43412
        GetASN_GetConstRef(&dataASN[i_issuer], &issuer_input, &issuer_len);
43413
43414
        if (i_issuer == ACERT_IDX_ACINFO_ISSUER_V2 && issuer_len > 0) {
43415
            /* Try to decode the AttCertIssuer as well. */
43416
            ret = DecodeAttCertIssuer(issuer_input, issuer_len, acert);
43417
43418
            if (ret != 0) {
43419
                FREE_ASNGETDATA(dataASN, acert->heap);
43420
                return ret;
43421
            }
43422
        }
43423
        #ifdef WOLFSSL_DEBUG_ASN_TEMPLATE
43424
        else {
43425
            printf("debug: parse acert: unsupported issuer format: %d, %d\n",
43426
                   i_issuer, issuer_len);
43427
        }
43428
        #endif /* WOLFSSL_DEBUG_ASN_TEMPLATE */
43429
    }
43430
43431
    if (badDate) {
43432
        if ((verify != NO_VERIFY) && (verify != VERIFY_SKIP_DATE)) {
43433
            ret = badDate;
43434
        }
43435
    }
43436
43437
    FREE_ASNGETDATA(dataASN, acert->heap);
43438
    return ret;
43439
}
43440
43441
/* Given the parsed attribute cert info, verify the signature.
43442
 * The sigCtx is alloced and freed here.
43443
 *
43444
 * @param [in]      acinfo        the parsed acinfo sequence
43445
 * @param [in]      acinfoSz      the parsed acinfo sequence length
43446
 * @param [in]      pubKey        public key
43447
 * @param [in]      pubKeySz      public key length
43448
 * @param [in]      pubKeyOID     public key oid
43449
 * @param [in]      sig           the parsed signature
43450
 * @param [in]      sigSz         the parsed signature length
43451
 * @param [in]      sigOID        the parsed signature OID
43452
 * @param [in]      sigParams     the parsed signature RSA-PSS params
43453
 * @param [in]      sigParamsSz   the parsed signature RSA-PSS params length
43454
 * @param [in]      heap          heap hint
43455
 *
43456
 * @return  0   on verify success
43457
 * @return  < 0 on error
43458
 * */
43459
static int acert_sig_verify(const byte * acinfo, word32 acinfoSz,
43460
                            const byte * pubKey, word32 pubKeySz,
43461
                            int pubKeyOID, const byte * sig, word32 sigSz,
43462
                            word32 sigOID, const byte * sigParams,
43463
                            word32 sigParamsSz, void * heap)
43464
{
43465
#ifndef WOLFSSL_SMALL_STACK
43466
    SignatureCtx   sigCtx[1];
43467
#else
43468
    SignatureCtx * sigCtx = NULL;
43469
#endif
43470
    int            ret = 0;
43471
43472
    #ifdef WOLFSSL_SMALL_STACK
43473
    sigCtx = (SignatureCtx*)XMALLOC(sizeof(*sigCtx), heap,
43474
                                    DYNAMIC_TYPE_SIGNATURE);
43475
    if (sigCtx == NULL) {
43476
        WOLFSSL_MSG("error: VerifyX509Acert: malloc sigCtx failed");
43477
        return MEMORY_E;
43478
    }
43479
    #endif
43480
43481
    InitSignatureCtx(sigCtx, heap, INVALID_DEVID);
43482
43483
    /* Check x509 acert signature. */
43484
    ret = ConfirmSignature(sigCtx, acinfo, acinfoSz, pubKey, pubKeySz,
43485
                           (word32)pubKeyOID, sig, sigSz, sigOID,
43486
                           sigParams, sigParamsSz, NULL);
43487
43488
    if (ret == WC_NO_ERR_TRACE(ASN_SIG_CONFIRM_E)) {
43489
        WOLFSSL_MSG("info: VerifyX509Acert: confirm signature failed");
43490
    }
43491
43492
    FreeSignatureCtx(sigCtx);
43493
    #ifdef WOLFSSL_SMALL_STACK
43494
    XFREE(sigCtx, heap, DYNAMIC_TYPE_SIGNATURE);
43495
    sigCtx = NULL;
43496
    #endif
43497
43498
    return ret;
43499
}
43500
43501
/* Verify the X509 ACERT signature, using the given pubkey.
43502
 *
43503
 * @param [in]      der         input acert in der format
43504
 * @param [in]      derSz       acert length
43505
 * @param [in]      pubKey      public key
43506
 * @param [in]      pubKeySz    public key length
43507
 * @param [in]      pubKeyOID   public key oid
43508
 * @param [in]      heap        heap hint
43509
 *
43510
 * @return  0   on success
43511
 * @return  < 0 on error
43512
 * */
43513
int VerifyX509Acert(const byte* der, word32 derSz,
43514
                    const byte* pubKey, word32 pubKeySz, int pubKeyOID,
43515
                    void * heap)
43516
{
43517
    DECL_ASNGETDATA(dataASN, AcertASN_Length);
43518
    word32         idx = 0;
43519
    int            ret = 0;
43520
    const byte *   acinfo = NULL; /* The acinfo sequence. */
43521
    word32         acinfoSz = 0;  /* The acinfo sequence length. */
43522
#ifdef WC_RSA_PSS
43523
    const byte *   acParams = NULL;
43524
    word32         acParamsSz = 0;
43525
#endif
43526
    const byte *   sig = NULL;
43527
    word32         sigSz = 0;
43528
    word32         sigOID = 0;
43529
    const byte *   sigParams = NULL;
43530
    word32         sigParamsSz = 0;
43531
43532
    WOLFSSL_MSG("VerifyX509Acert");
43533
43534
    if (der == NULL || pubKey == NULL || derSz == 0 || pubKeySz == 0) {
43535
        WOLFSSL_MSG("error: VerifyX509Acert: bad args");
43536
        return BAD_FUNC_ARG;
43537
    }
43538
43539
    CALLOC_ASNGETDATA(dataASN, AcertASN_Length, ret, heap);
43540
43541
    if (ret != 0) {
43542
        WOLFSSL_MSG("error: VerifyX509Acert: calloc dataASN failed");
43543
        return MEMORY_E;
43544
    }
43545
43546
    /* Check OID types for signature algorithm. */
43547
    GetASN_OID(&dataASN[ACERT_IDX_ACINFO_ALGOID_OID], oidSigType);
43548
    GetASN_OID(&dataASN[ACERT_IDX_SIGALGO_OID], oidSigType);
43549
43550
    /* Parse the X509 certificate. */
43551
    ret = GetASN_Items(AcertASN, dataASN, AcertASN_Length, 1,
43552
                       der, &idx, derSz);
43553
43554
    if (ret != 0) {
43555
        WOLFSSL_MSG("error: VerifyX509Acert: GetASN_Items failed");
43556
        FREE_ASNGETDATA(dataASN, heap);
43557
        return ret;
43558
    }
43559
43560
    /* Check signature OIDs match. */
43561
    if (dataASN[ACERT_IDX_ACINFO_ALGOID_OID].data.oid.sum
43562
        != dataASN[ACERT_IDX_SIGALGO_OID].data.oid.sum) {
43563
        WOLFSSL_MSG("error: VerifyX509Acert: sig OID mismatch");
43564
        FREE_ASNGETDATA(dataASN, heap);
43565
        return ASN_SIG_OID_E;
43566
    }
43567
43568
    /* Get the attribute certificate info. */
43569
    acinfo = GetASNItem_Addr(dataASN[ACERT_IDX_ACINFO_SEQ], der);
43570
    acinfoSz = GetASNItem_Length(dataASN[ACERT_IDX_ACINFO_SEQ], der);
43571
43572
    if (acinfo == NULL || acinfoSz == 0) {
43573
        WOLFSSL_MSG("error: VerifyX509Acert: empty acinfo");
43574
        FREE_ASNGETDATA(dataASN, heap);
43575
        return ASN_PARSE_E;
43576
    }
43577
43578
    /* Get acert signature and sig info. */
43579
    sigOID = dataASN[ACERT_IDX_ACINFO_ALGOID_OID].data.oid.sum;
43580
    #ifdef WC_RSA_PSS
43581
    if (dataASN[ACERT_IDX_ACINFO_ALGOID_PARAMS].tag != 0) {
43582
        acParams = GetASNItem_Addr(dataASN[ACERT_IDX_ACINFO_ALGOID_PARAMS],
43583
                                  der);
43584
        acParamsSz = GetASNItem_Length(dataASN[ACERT_IDX_ACINFO_ALGOID_PARAMS],
43585
                                       der);
43586
    }
43587
    if (dataASN[ACERT_IDX_SIGALGO_PARAMS].tag != 0) {
43588
        sigParams = GetASNItem_Addr(dataASN[ACERT_IDX_SIGALGO_PARAMS], der);
43589
        sigParamsSz = GetASNItem_Length(dataASN[ACERT_IDX_SIGALGO_PARAMS],
43590
                                        der);
43591
    }
43592
    #endif
43593
43594
    GetASN_GetConstRef(&dataASN[ACERT_IDX_SIGNATURE], &sig, &sigSz);
43595
43596
    #ifdef WC_RSA_PSS
43597
    if (acParamsSz != sigParamsSz) {
43598
        ret = ASN_PARSE_E;
43599
    }
43600
    else if ((acParamsSz > 0) && (sigOID != CTC_RSASSAPSS)) {
43601
        ret = ASN_PARSE_E;
43602
    }
43603
    else if ((acParamsSz > 0) &&
43604
             (XMEMCMP(acParams, sigParams, acParamsSz) != 0)) {
43605
        ret = ASN_PARSE_E;
43606
    }
43607
    #endif
43608
43609
    if (ret == 0) {
43610
        /* Finally, do the verification. */
43611
        ret = acert_sig_verify(acinfo, acinfoSz,
43612
                               pubKey, pubKeySz, pubKeyOID,
43613
                               sig, sigSz, sigOID, sigParams, sigParamsSz,
43614
                               heap);
43615
    }
43616
43617
    FREE_ASNGETDATA(dataASN, heap);
43618
    return ret;
43619
}
43620
43621
/**
43622
 * Wrapper API to expose Acert ASN functions. See Acert ASN functions
43623
 * for comments.
43624
 * */
43625
void wc_InitDecodedAcert(DecodedAcert* acert, const byte* source, word32 inSz,
43626
                         void* heap)
43627
{
43628
    InitDecodedAcert(acert, source, inSz, heap);
43629
}
43630
43631
void wc_FreeDecodedAcert(DecodedAcert * acert)
43632
{
43633
    FreeDecodedAcert(acert);
43634
}
43635
43636
int wc_ParseX509Acert(DecodedAcert* acert, int verify)
43637
{
43638
    return ParseX509Acert(acert, verify);
43639
}
43640
43641
int wc_VerifyX509Acert(const byte* acert, word32 acertSz,
43642
                       const byte* pubKey, word32 pubKeySz,
43643
                       int pubKeyOID, void * heap)
43644
{
43645
    return VerifyX509Acert(acert, acertSz, pubKey, pubKeySz,
43646
                           pubKeyOID, heap);
43647
}
43648
43649
#endif /* WOLFSSL_ACERT && WOLFSSL_ASN_TEMPLATE */
43650
43651
#ifdef WOLFSSL_SEP
43652
43653
43654
#endif /* WOLFSSL_SEP */